AVM2 execution fixes

This commit is contained in:
honfika@gmail.com
2016-12-30 21:19:48 +01:00
parent f786c34910
commit cf58f71f10
11 changed files with 189 additions and 38 deletions

View File

@@ -274,8 +274,6 @@ import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
@@ -746,7 +744,9 @@ public class AVM2Code implements Cloneable {
lda.runtimeInfo = runtimeInfo;
for (AVM2Instruction ins : code) {
ins.definition.verify(lda, constants, ins);
if (!(ins.definition instanceof CallSuperVoidIns)) {
ins.definition.verify(lda, constants, ins);
}
}
while (pos < code.size()) {
@@ -2129,7 +2129,6 @@ public class AVM2Code implements Cloneable {
public void updateInstructionByteCountByAddr(long instructionAddress, int byteDelta, MethodBody body) {
if (byteDelta != 0) {
updateOffsets(new OffsetUpdater() {
@Override
public long updateInstructionOffset(long address) {
if (address > instructionAddress) {
@@ -2200,7 +2199,6 @@ public class AVM2Code implements Cloneable {
final List<Long> insAddrToRemove = new ArrayList<>();
final long endOffset = getEndOffset();
updateOffsets(new OffsetUpdater() {
@Override
public long updateInstructionOffset(long address) {
return address;
@@ -2213,7 +2211,6 @@ public class AVM2Code implements Cloneable {
}
return offset;
}
}, body);
boolean someIgnored = false;
@@ -2232,7 +2229,6 @@ public class AVM2Code implements Cloneable {
public void checkValidOffsets(MethodBody body) {
updateOffsets(new OffsetUpdater() {
@Override
public long updateInstructionOffset(long address) {
adr2pos(address);
@@ -2247,7 +2243,6 @@ public class AVM2Code implements Cloneable {
adr2pos(targetAddress);
return offset;
}
}, body);
}
@@ -2329,7 +2324,6 @@ public class AVM2Code implements Cloneable {
if (byteDelta != 0) {
updateOffsets(new OffsetUpdater() {
@Override
public long updateInstructionOffset(long address) {
if (address > instruction.getAddress()) {
@@ -2380,7 +2374,6 @@ public class AVM2Code implements Cloneable {
}
final long x = instruction.getAddress();
updateOffsets(new OffsetUpdater() {
@Override
public long updateInstructionOffset(long offset) {
if (offset >= x) {
@@ -2612,6 +2605,27 @@ public class AVM2Code implements Cloneable {
return stats;
}
// simplified varions of getStats. This method calculates only the maxlocal value
public CodeStats getMaxLocal() {
CodeStats stats = new CodeStats();
for (AVM2Instruction ins : code) {
if (ins.definition instanceof SetLocalTypeIns) {
handleRegister(stats, ((SetLocalTypeIns) ins.definition).getRegisterId(ins));
} else if (ins.definition instanceof GetLocalTypeIns) {
handleRegister(stats, ((GetLocalTypeIns) ins.definition).getRegisterId(ins));
} else {
for (int i = 0; i < ins.definition.operands.length; i++) {
int op = ins.definition.operands[i];
if (op == DAT_LOCAL_REG_INDEX) {
handleRegister(stats, ins.operands[i]);
}
}
}
}
return stats;
}
private void visitCode(int ip, int lastIp, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
List<Integer> toVisit = new ArrayList<>();
List<Integer> toVisitLast = new ArrayList<>();

View File

@@ -57,6 +57,9 @@ public class CodeStats {
return writer;
}
public CodeStats() {
}
public CodeStats(AVM2Code code) {
instructionStats = new InstructionStats[code.code.size()];
for (int i = 0; i < code.code.size(); i++) {

View File

@@ -34,9 +34,11 @@ import com.jpexs.decompiler.flash.abc.avm2.model.RegExpAvm2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
@@ -49,18 +51,28 @@ public class ConstructIns extends InstructionDefinition {
super(0x42, "construct", new int[]{AVM2Code.DAT_ARG_COUNT}, true);
}
@Override
public boolean isNotCompileTimeSupported() {
return true;
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
/*int argCount = ins.getParamAsLong(constants, 0).intValue();
List<Object> passArguments = new ArrayList<Object>();
for (int i = argCount - 1; i >= 0; i--) {
passArguments.set(i, lda.operandStack.pop());
}
Object obj = lda.operandStack.pop();*/
int argCount = ins.getParamAsLong(constants, 0).intValue();
List<Object> passArguments = new ArrayList<Object>();
for (int i = argCount - 1; i >= 0; i--) {
passArguments.set(i, lda.operandStack.pop());
}
Object obj = lda.operandStack.pop();
//lda.executionException = "Cannot call constructor";
return false;
//call construct property of obj
ObjectType result = new ObjectType(new HashMap<>());
//todo: call construct property of obj
//push new instance
lda.operandStack.push(result);
return true;
}
public static boolean walkXML(GraphTargetItem item, List<GraphTargetItem> list) {

View File

@@ -39,18 +39,25 @@ public class ConstructSuperIns extends InstructionDefinition {
super(0x49, "constructsuper", new int[]{AVM2Code.DAT_ARG_COUNT}, true);
}
@Override
public boolean isNotCompileTimeSupported() {
return true;
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
/*int argCount = ins.getParamAsLong(constants, 0).intValue();
List<Object> passArguments = new ArrayList<Object>();
for (int i = argCount - 1; i >= 0; i--) {
passArguments.set(i, lda.operandStack.pop());
}
Object obj = lda.operandStack.pop();*/
int argCount = ins.getParamAsLong(constants, 0).intValue();
List<Object> passArguments = new ArrayList<Object>();
for (int i = argCount - 1; i >= 0; i--) {
passArguments.set(i, lda.operandStack.pop());
}
Object obj = lda.operandStack.pop();
//lda.executionException = "Cannot call super constructor";
return false;
//call construct property of obj
//todo: call construct property of obj
//do not push anything
return true;
}
@Override

View File

@@ -41,6 +41,11 @@ public class AsTypeIns extends InstructionDefinition {
super(0x86, "astype", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true);
}
@Override
public boolean isNotCompileTimeSupported() {
return true;
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
//Long typeIndex = ins.getParamAsLong(constants, 0);

View File

@@ -38,6 +38,11 @@ public class AsTypeLateIns extends InstructionDefinition {
super(0x87, "astypelate", new int[]{}, true);
}
@Override
public boolean isNotCompileTimeSupported() {
return true;
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
//Object objClass = lda.operandStack.pop();

View File

@@ -449,7 +449,6 @@ public class AVM2SourceGenerator implements SourceGenerator {
));
GraphTargetItem assigned = new GraphTargetItem() {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return null;
@@ -2125,11 +2124,17 @@ public class AVM2SourceGenerator implements SourceGenerator {
continue;
}
if (item instanceof InterfaceAVM2Item) {
generateClass(((InterfaceAVM2Item) item).pkg.getCpoolIndex(abcIndex), abcIndex.getSelectedAbc().class_info.get(((TraitClass) traits[k]).class_info), abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((InterfaceAVM2Item) item).pkg.name, localData, (InterfaceAVM2Item) item, class_index);
ABC abc = abcIndex.getSelectedAbc();
TraitClass trait = (TraitClass) traits[k];
InterfaceAVM2Item iitem = (InterfaceAVM2Item) item;
generateClass(iitem.pkg.getCpoolIndex(abcIndex), abc.class_info.get(trait.class_info), abc.instance_info.get(trait.class_info), initScopes.get(trait), iitem.pkg.name, localData, iitem, class_index);
}
if (item instanceof ClassAVM2Item) {
generateClass(((ClassAVM2Item) item).pkg.getCpoolIndex(abcIndex), abcIndex.getSelectedAbc().class_info.get(((TraitClass) traits[k]).class_info), abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((ClassAVM2Item) item).pkg.name, localData, (ClassAVM2Item) item, class_index);
ABC abc = abcIndex.getSelectedAbc();
TraitClass trait = (TraitClass) traits[k];
ClassAVM2Item citem = (ClassAVM2Item) item;
generateClass(citem.pkg.getCpoolIndex(abcIndex), abc.class_info.get(trait.class_info), abc.instance_info.get(trait.class_info), initScopes.get(trait), citem.pkg.name, localData, citem, class_index);
}
if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) {
MethodAVM2Item mai = (MethodAVM2Item) item;
@@ -2713,5 +2718,4 @@ public class AVM2SourceGenerator implements SourceGenerator {
List<GraphSourceItem> ret = new ArrayList<>();
return ret;
}
}

View File

@@ -475,4 +475,19 @@ public final class MethodBody implements Cloneable {
}
return true;
}
public boolean autoFillMaxRegs(ABC abc) {
CodeStats stats = getCode().getMaxLocal();
if (stats == null) {
return false;
}
max_regs = stats.maxlocal;
MethodInfo mi = abc.method_info.get(method_info);
int min_regs = mi.param_types.length + 1 + (mi.flagNeed_rest() ? 1 : 0);
if (max_regs < min_regs) {
max_regs = min_regs;
}
return true;
}
}