mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-03 15:35:10 +00:00
#1145 AS3 better declaration type detection,
better convert_x instruction handling
This commit is contained in:
@@ -243,14 +243,18 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.DXNSLateIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXAttrIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.EscXElemIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
@@ -284,10 +288,15 @@ import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.BinaryOpItem;
|
||||
import com.jpexs.decompiler.graph.model.DoWhileItem;
|
||||
import com.jpexs.decompiler.graph.model.ExitItem;
|
||||
import com.jpexs.decompiler.graph.model.IfItem;
|
||||
import com.jpexs.decompiler.graph.model.ScriptEndItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.stat.Statistics;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -1812,63 +1821,115 @@ public class AVM2Code implements Cloneable {
|
||||
toSourceCount = 0;
|
||||
}
|
||||
|
||||
private void injectDeclarations(List<GraphTargetItem> list, boolean[] declaredRegisters, List<Slot> declaredSlots, ABC abc, MethodBody body) {
|
||||
private GraphTargetItem handleDeclareReg(int minreg, GraphTargetItem assignment, DeclarationAVM2Item[] declaredRegisters, int reg) {
|
||||
|
||||
//do not add declarations for reserved local registers like function arguments
|
||||
if (reg < minreg) {
|
||||
return assignment;
|
||||
}
|
||||
GraphTargetItem vtype = TypeItem.UNBOUNDED;
|
||||
if (assignment.value instanceof ConvertAVM2Item) {
|
||||
vtype = ((ConvertAVM2Item) assignment.value).type;
|
||||
}
|
||||
|
||||
if (vtype.equals(TypeItem.UNBOUNDED) && (assignment.value instanceof CoerceAVM2Item)) {
|
||||
vtype = ((CoerceAVM2Item) assignment.value).typeObj;
|
||||
}
|
||||
if (vtype.equals(TypeItem.UNBOUNDED) && (assignment.value instanceof SimpleValue) && ((SimpleValue) assignment.value).isSimpleValue()) {
|
||||
vtype = assignment.value.returnType();
|
||||
}
|
||||
|
||||
if (declaredRegisters[reg] == null) {
|
||||
declaredRegisters[reg] = new DeclarationAVM2Item(assignment, vtype);
|
||||
if (assignment instanceof SetTypeAVM2Item) {
|
||||
((SetTypeAVM2Item) assignment).setDeclaration(declaredRegisters[reg]);
|
||||
}
|
||||
return declaredRegisters[reg];
|
||||
}
|
||||
|
||||
if (declaredRegisters[reg].type == TypeItem.UNBOUNDED) {
|
||||
|
||||
} else if (!declaredRegisters[reg].type.equals(vtype)) { //already declared with different type
|
||||
declaredRegisters[reg].type = TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
if (assignment instanceof SetTypeAVM2Item) {
|
||||
((SetTypeAVM2Item) assignment).setDeclaration(declaredRegisters[reg]);
|
||||
}
|
||||
|
||||
return assignment;
|
||||
}
|
||||
|
||||
private GraphTargetItem injectDeclarations(int minreg, GraphTargetItem ti, DeclarationAVM2Item[] declaredRegisters, List<Slot> declaredSlots, ABC abc, MethodBody body) {
|
||||
if (ti.value != null) {
|
||||
ti.value = injectDeclarations(minreg, ti.value, declaredRegisters, declaredSlots, abc, body);
|
||||
}
|
||||
//TODO: walk whole tree... some walker?
|
||||
if (ti instanceof IfItem) {
|
||||
((IfItem) ti).expression = injectDeclarations(minreg, ((IfItem) ti).expression, declaredRegisters, declaredSlots, abc, body);
|
||||
}
|
||||
if (ti instanceof BinaryOpItem) {
|
||||
((BinaryOpItem) ti).leftSide = injectDeclarations(minreg, ((BinaryOpItem) ti).leftSide, declaredRegisters, declaredSlots, abc, body);
|
||||
((BinaryOpItem) ti).rightSide = injectDeclarations(minreg, ((BinaryOpItem) ti).rightSide, declaredRegisters, declaredSlots, abc, body);
|
||||
}
|
||||
if (ti instanceof ForEachInAVM2Item) {
|
||||
ForEachInAVM2Item fei = (ForEachInAVM2Item) ti;
|
||||
if (fei.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex;
|
||||
if (declaredRegisters[reg] == null) {
|
||||
fei.expression.object = handleDeclareReg(minreg, fei.expression.object, declaredRegisters, reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ti instanceof ForInAVM2Item) {
|
||||
ForInAVM2Item fi = (ForInAVM2Item) ti;
|
||||
if (fi.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex;
|
||||
fi.expression.object = handleDeclareReg(minreg, fi.expression.object, declaredRegisters, reg);
|
||||
//nowdeclaredRegs.add(reg);
|
||||
|
||||
}
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
Block bl = (Block) ti;
|
||||
for (List<GraphTargetItem> s : bl.getSubs()) {
|
||||
injectDeclarations(minreg, s, declaredRegisters, declaredSlots, abc, body);
|
||||
}
|
||||
}
|
||||
if (ti instanceof SetLocalAVM2Item) {
|
||||
int reg = ((SetLocalAVM2Item) ti).regIndex;
|
||||
ti = handleDeclareReg(minreg, ti, declaredRegisters, reg);
|
||||
return ti;
|
||||
}
|
||||
if (ti instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti;
|
||||
Slot sl = new Slot(ssti.scope, ssti.slotName);
|
||||
if (!declaredSlots.contains(sl)) {
|
||||
GraphTargetItem type = TypeItem.UNBOUNDED;
|
||||
for (int t = 0; t < body.traits.traits.size(); t++) {
|
||||
if (body.traits.traits.get(t).getName(abc) == sl.multiname) {
|
||||
if (body.traits.traits.get(t) instanceof TraitSlotConst) {
|
||||
type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
ti = new DeclarationAVM2Item(ti, type);
|
||||
declaredSlots.add(sl);
|
||||
return ti;
|
||||
//nowdeclaredSlots.add(sl);
|
||||
}
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
private void injectDeclarations(int minreg, List<GraphTargetItem> list, DeclarationAVM2Item[] declaredRegisters, List<Slot> declaredSlots, ABC abc, MethodBody body) {
|
||||
//List<Integer> nowdeclaredRegs=new ArrayList<>();
|
||||
//List<Slot> nowdeclaredSlots=new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
GraphTargetItem ti = list.get(i);
|
||||
if (ti instanceof ForEachInAVM2Item) {
|
||||
ForEachInAVM2Item fei = (ForEachInAVM2Item) ti;
|
||||
if (fei.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex;
|
||||
if (!declaredRegisters[reg]) {
|
||||
fei.expression.object = new DeclarationAVM2Item(fei.expression.object);
|
||||
declaredRegisters[reg] = true;
|
||||
//nowdeclaredRegs.add(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ti instanceof ForInAVM2Item) {
|
||||
ForInAVM2Item fi = (ForInAVM2Item) ti;
|
||||
if (fi.expression.object instanceof LocalRegAVM2Item) {
|
||||
int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex;
|
||||
if (!declaredRegisters[reg]) {
|
||||
fi.expression.object = new DeclarationAVM2Item(fi.expression.object);
|
||||
declaredRegisters[reg] = true;
|
||||
//nowdeclaredRegs.add(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
Block bl = (Block) ti;
|
||||
for (List<GraphTargetItem> s : bl.getSubs()) {
|
||||
injectDeclarations(s, declaredRegisters, declaredSlots, abc, body);
|
||||
}
|
||||
}
|
||||
if (ti instanceof SetLocalAVM2Item) {
|
||||
int reg = ((SetLocalAVM2Item) ti).regIndex;
|
||||
if (!declaredRegisters[reg]) {
|
||||
list.set(i, new DeclarationAVM2Item(ti));
|
||||
declaredRegisters[reg] = true;
|
||||
//nowdeclaredRegs.add(reg);
|
||||
}
|
||||
}
|
||||
if (ti instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti;
|
||||
Slot sl = new Slot(ssti.scope, ssti.slotName);
|
||||
if (!declaredSlots.contains(sl)) {
|
||||
GraphTargetItem type = TypeItem.UNBOUNDED;
|
||||
for (int t = 0; t < body.traits.traits.size(); t++) {
|
||||
if (body.traits.traits.get(t).getName(abc) == sl.multiname) {
|
||||
if (body.traits.traits.get(t) instanceof TraitSlotConst) {
|
||||
type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
list.set(i, new DeclarationAVM2Item(ti, type));
|
||||
declaredSlots.add(sl);
|
||||
//nowdeclaredSlots.add(sl);
|
||||
}
|
||||
GraphTargetItem ti2 = injectDeclarations(minreg, ti, declaredRegisters, declaredSlots, abc, body);
|
||||
if (ti != ti2) {
|
||||
list.set(i, ti2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1958,7 +2019,39 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
// Declarations
|
||||
injectDeclarations(list, new boolean[regCount], new ArrayList<>(), abc, body);
|
||||
|
||||
DeclarationAVM2Item d[] = new DeclarationAVM2Item[regCount];
|
||||
|
||||
int param_types[] = abc.method_info.get(body.method_info).param_types;
|
||||
int r = 1;
|
||||
for (int i = 0; i < param_types.length; i++) {
|
||||
GraphTargetItem type;
|
||||
if (param_types[i] == 0) {
|
||||
type = TypeItem.UNBOUNDED;
|
||||
} else {
|
||||
type = new TypeItem(abc.constants.getMultiname(param_types[i]).getNameWithNamespace(abc.constants));
|
||||
}
|
||||
if (d.length > r) {
|
||||
d[r] = new DeclarationAVM2Item(new SetLocalAVM2Item(null, null, r, new NullAVM2Item(null, null)), type);
|
||||
}
|
||||
r++;
|
||||
}
|
||||
if (abc.method_info.get(body.method_info).flagNeed_arguments()) {
|
||||
if (d.length > r) {
|
||||
d[r] = new DeclarationAVM2Item(new SetLocalAVM2Item(null, null, r, new NullAVM2Item(null, null)), TypeItem.ARRAY /*?*/);
|
||||
}
|
||||
r++;
|
||||
}
|
||||
if (abc.method_info.get(body.method_info).flagNeed_rest()) {
|
||||
if (d.length > r) {
|
||||
d[r] = new DeclarationAVM2Item(new SetLocalAVM2Item(null, null, r, new NullAVM2Item(null, null)), TypeItem.ARRAY/*?*/);
|
||||
}
|
||||
r++;
|
||||
}
|
||||
//
|
||||
|
||||
//int minreg = abc.method_info.get(body.method_info).getMaxReservedReg() + 1;
|
||||
injectDeclarations(1, list, d, new ArrayList<>(), abc, body);
|
||||
|
||||
int lastPos = list.size() - 1;
|
||||
if (lastPos < 0) {
|
||||
@@ -1993,7 +2086,8 @@ public class AVM2Code implements Cloneable {
|
||||
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
|
||||
}
|
||||
}*/ //Faster, but not so universal
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
{
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
long target = ins.getTargetAddress();
|
||||
try {
|
||||
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
|
||||
@@ -2001,6 +2095,7 @@ public class AVM2Code implements Cloneable {
|
||||
throw new ConvertException("Invalid offset (" + ins + ")", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
ins.setAddress(updater.updateInstructionOffset(ins.getAddress()));
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ public class ConvertAVM2Item extends AVM2Item {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
return value.toString(writer, localData);
|
||||
type.toString(writer, localData).append("(");
|
||||
value.toString(writer, localData);
|
||||
writer.append(")");
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -33,6 +34,17 @@ public class InitPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, A
|
||||
|
||||
public FullMultinameAVM2Item propertyName;
|
||||
|
||||
public DeclarationAVM2Item declaration;
|
||||
|
||||
@Override
|
||||
public DeclarationAVM2Item getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(DeclarationAVM2Item declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public InitPropertyAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, FullMultinameAVM2Item propertyName, GraphTargetItem value) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_ASSIGMENT, value);
|
||||
this.object = object;
|
||||
|
||||
@@ -37,7 +37,7 @@ public class NameValuePair extends AVM2Item {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
name.toString(writer, localData);
|
||||
name.toStringString(writer, localData);
|
||||
writer.append(":");
|
||||
if (value instanceof TernarOpItem) { //Ternar operator contains ":"
|
||||
writer.append("(");
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -33,7 +34,7 @@ import java.util.List;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class NanAVM2Item extends AVM2Item {
|
||||
public class NanAVM2Item extends AVM2Item implements SimpleValue {
|
||||
|
||||
public NanAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns) {
|
||||
super(instruction, lineStartIns, NOPRECEDENCE);
|
||||
@@ -60,4 +61,9 @@ public class NanAVM2Item extends AVM2Item {
|
||||
public boolean hasReturnValue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimpleValue() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
@@ -37,6 +38,17 @@ public class SetLocalAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assig
|
||||
|
||||
public int regIndex;
|
||||
|
||||
public DeclarationAVM2Item declaration;
|
||||
|
||||
@Override
|
||||
public DeclarationAVM2Item getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(DeclarationAVM2Item declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public SetLocalAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex, GraphTargetItem value) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_ASSIGMENT, value);
|
||||
this.regIndex = regIndex;
|
||||
@@ -47,6 +59,9 @@ public class SetLocalAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assig
|
||||
String localName = localRegName(localData.localRegNames, regIndex);
|
||||
getSrcData().localName = localName;
|
||||
writer.append(localName).append(" = ");
|
||||
if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
@@ -41,6 +42,17 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As
|
||||
|
||||
public GraphTargetItem propertyName;
|
||||
|
||||
public DeclarationAVM2Item declaration;
|
||||
|
||||
@Override
|
||||
public DeclarationAVM2Item getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(DeclarationAVM2Item declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphPart getFirstPart() {
|
||||
return value.getFirstPart();
|
||||
@@ -57,6 +69,9 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
formatProperty(writer, object, propertyName, localData);
|
||||
writer.append(" = ");
|
||||
if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
@@ -35,6 +36,17 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign
|
||||
|
||||
public GraphTargetItem scope;
|
||||
|
||||
public DeclarationAVM2Item declaration;
|
||||
|
||||
@Override
|
||||
public DeclarationAVM2Item getDeclaration() {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public void setDeclaration(DeclarationAVM2Item declaration) {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
public SetSlotAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem scope, Multiname slotName, GraphTargetItem value) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_ASSIGMENT, value);
|
||||
this.slotName = slotName;
|
||||
@@ -55,6 +67,9 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign
|
||||
}
|
||||
getName(writer, localData);
|
||||
writer.append(" = ");
|
||||
if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) {
|
||||
return value.value.toString(writer, localData);
|
||||
}
|
||||
return value.toString(writer, localData);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
|
||||
/**
|
||||
@@ -27,4 +28,8 @@ public interface SetTypeAVM2Item {
|
||||
public GraphTargetItem getObject();
|
||||
|
||||
public GraphTargetItem getValue();
|
||||
|
||||
public DeclarationAVM2Item getDeclaration();
|
||||
|
||||
public void setDeclaration(DeclarationAVM2Item dec);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -35,7 +36,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UndefinedAVM2Item extends AVM2Item {
|
||||
public class UndefinedAVM2Item extends AVM2Item implements SimpleValue {
|
||||
|
||||
public UndefinedAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
@@ -58,7 +59,7 @@ public class UndefinedAVM2Item extends AVM2Item {
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return new TypeItem(DottedChain.UNDEFINED);
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,4 +73,9 @@ public class UndefinedAVM2Item extends AVM2Item {
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUndefined, null)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimpleValue() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
srcData.declaration = true;
|
||||
srcData.regIndex = lti.regIndex;
|
||||
|
||||
GraphTargetItem val = lti.value;
|
||||
GraphTargetItem coerType = TypeItem.UNBOUNDED;
|
||||
if (lti.value instanceof CoerceAVM2Item) {
|
||||
coerType = ((CoerceAVM2Item) lti.value).typeObj;
|
||||
@@ -92,13 +93,17 @@ public class DeclarationAVM2Item extends AVM2Item {
|
||||
if (lti.value instanceof ConvertAVM2Item) {
|
||||
coerType = ((ConvertAVM2Item) lti.value).type;
|
||||
}
|
||||
//strip coerce if its declared as this type
|
||||
if (coerType.equals(type) && !coerType.equals(TypeItem.UNBOUNDED)) {
|
||||
val = val.value;
|
||||
}
|
||||
srcData.declaredType = (coerType instanceof TypeItem) ? ((TypeItem) coerType).fullTypeName : DottedChain.ALL;
|
||||
writer.append("var ");
|
||||
writer.append(localName);
|
||||
writer.append(":");
|
||||
coerType.appendTry(writer, localData);
|
||||
type.appendTry(writer, localData);
|
||||
writer.append(" = ");
|
||||
return lti.value.toString(writer, localData);
|
||||
return val.toString(writer, localData);
|
||||
}
|
||||
if (assignment instanceof SetSlotAVM2Item) {
|
||||
SetSlotAVM2Item ssti = (SetSlotAVM2Item) assignment;
|
||||
|
||||
@@ -303,6 +303,10 @@ public class MethodInfo {
|
||||
return constants.getString(name_index);
|
||||
}
|
||||
|
||||
public int getMaxReservedReg() {
|
||||
return param_types.length + (flagNeed_rest() ? 1 : 0) + (flagNeed_arguments() ? 1 : 0);
|
||||
}
|
||||
|
||||
public GraphTextWriter getParamStr(GraphTextWriter writer, AVM2ConstantPool constants, MethodBody body, ABC abc, List<DottedChain> fullyQualifiedNames) {
|
||||
Map<Integer, String> localRegNames = new HashMap<>();
|
||||
if (body != null && Configuration.getLocalNamesFromDebugInfo.get()) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair;
|
||||
@@ -331,7 +332,14 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
|
||||
|
||||
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData, String implicitCoerce) throws InterruptedException {
|
||||
GraphTargetItem t = this;
|
||||
if (!implicitCoerce.isEmpty() && Configuration.autoDeobfuscate.get()) {
|
||||
if (!implicitCoerce.isEmpty()) { //if implicit coerce equals explicit
|
||||
if (t instanceof ConvertAVM2Item) {
|
||||
if (implicitCoerce.equals((((ConvertAVM2Item) t).type.toString()))) {
|
||||
t = t.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!implicitCoerce.isEmpty() && Configuration._simplifyExpressions.get()) {
|
||||
t = t.simplify(implicitCoerce);
|
||||
}
|
||||
return t.appendTo(writer, localData);
|
||||
|
||||
@@ -50,6 +50,9 @@ public class DoWhileItem extends LoopItem implements Block {
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
if (expression != null) {
|
||||
ret.add(expression);
|
||||
}
|
||||
if (commands != null) {
|
||||
ret.add(commands);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,9 @@ public class WhileItem extends LoopItem implements Block {
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
if (expression != null) {
|
||||
ret.add(expression);
|
||||
}
|
||||
if (commands != null) {
|
||||
ret.add(commands);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user