mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 16:10:45 +00:00
AS3 parser: try..catch, activation, slots
This commit is contained in:
@@ -32,19 +32,9 @@ public class SourceGeneratorLocalData implements Serializable {
|
||||
public Integer inFunction;
|
||||
public Boolean inMethod;
|
||||
public Integer forInLevel;
|
||||
//public List<String> openedNamespaces = new ArrayList<>();
|
||||
//public List<Integer> openedNamespacesKinds = new ArrayList<>();
|
||||
public List<ABCException> exceptions = new ArrayList<>();
|
||||
public String currentClass;
|
||||
/*
|
||||
public void addNamespace(int kind, String ns) {
|
||||
addNamespace(kind, ns, openedNamespaces.size() - 1);
|
||||
}
|
||||
|
||||
public void addNamespace(int kind, String ns, int index) {
|
||||
openedNamespaces.add(index, ns);
|
||||
openedNamespacesKinds.add(index, kind);
|
||||
}*/
|
||||
public int activationReg = 0;
|
||||
|
||||
public SourceGeneratorLocalData(HashMap<String, Integer> registerVars, Integer inFunction, Boolean inMethod, Integer forInLevel) {
|
||||
this.registerVars = registerVars;
|
||||
|
||||
@@ -1934,15 +1934,33 @@ public class AVM2Code implements Serializable {
|
||||
if (!walkCode(stats, 0, 0, initScope, abc)) {
|
||||
return null;
|
||||
}
|
||||
int scopePos = -1;
|
||||
for (ABCException ex : body.exceptions) {
|
||||
try {
|
||||
int exStart = adr2pos(ex.start);
|
||||
if (!walkCode(stats, adr2pos(ex.target), stats.instructionStats[exStart].stackpos, stats.instructionStats[exStart].scopepos, abc)) {
|
||||
if(scopePos==-1){
|
||||
scopePos=stats.instructionStats[adr2pos(ex.end)-1].scopepos;
|
||||
}
|
||||
List<Integer> visited = new ArrayList<>();
|
||||
for(int i=0;i<stats.instructionStats.length;i++){
|
||||
if(stats.instructionStats[i].seen){
|
||||
visited.add(i);
|
||||
}
|
||||
}
|
||||
if (!walkCode(stats, adr2pos(ex.target), 1/*exception*/, scopePos, abc)) {
|
||||
return null;
|
||||
}
|
||||
int maxIp = 0;
|
||||
//searching for visited instruction in second run which has maximum position
|
||||
for(int i=0;i<stats.instructionStats.length;i++){
|
||||
if(stats.instructionStats[i].seen && !visited.contains(i)){
|
||||
maxIp = i;
|
||||
}
|
||||
}
|
||||
scopePos = stats.instructionStats[maxIp].scopepos;
|
||||
} catch (ConvertException ex1) {
|
||||
}
|
||||
}
|
||||
//stats.maxscope+=initScope;
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model.clauses;
|
||||
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.NameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -148,4 +152,11 @@ public class TryAVM2Item extends AVM2Item implements Block {
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) {
|
||||
return ((AVM2SourceGenerator)generator).generate(localData, this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+295
-88
@@ -24,6 +24,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructSuperIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewActivationIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewClassIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfFalseIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictNeIns;
|
||||
@@ -43,16 +45,19 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextNameIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NextValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item;
|
||||
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.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
|
||||
@@ -101,6 +106,7 @@ import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -117,6 +123,10 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
public final ABC abc;
|
||||
public List<ABC> allABCs;
|
||||
|
||||
public static final int MARK_E_START = 0;
|
||||
public static final int MARK_E_END = 1;
|
||||
public static final int MARK_E_TARGET = 2;
|
||||
|
||||
private AVM2Instruction ins(InstructionDefinition def, int... operands) {
|
||||
return new AVM2Instruction(0, def, operands, new byte[0]);
|
||||
}
|
||||
@@ -560,15 +570,76 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
private List<AVM2Instruction> shiftExc(List<AVM2Instruction> list,int shift){
|
||||
for(AVM2Instruction ins:list){
|
||||
if(ins instanceof ExceptionMarkAVM2Instruction){
|
||||
ExceptionMarkAVM2Instruction e=(ExceptionMarkAVM2Instruction)ins;
|
||||
e.exceptionId+=shift;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, TryAVM2Item item) {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
int firstId = 0;
|
||||
List<ABCException> newex=new ArrayList<>();
|
||||
for (NameAVM2Item e : item.catchExceptions2) {
|
||||
ABCException aex = new ABCException();
|
||||
aex.name_index = str(e.getVariableName());
|
||||
aex.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(e.getVariableName(), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0,0,new ArrayList<Integer>()),true);
|
||||
aex.type_index = typeName(localData, e.type);
|
||||
localData.exceptions.add(aex);
|
||||
//TODO
|
||||
newex.add(aex);
|
||||
}
|
||||
|
||||
List<AVM2Instruction> tryCmds=generateToActionList(localData, item.tryCommands);
|
||||
List<List<AVM2Instruction>> catchCmds=new ArrayList<>();
|
||||
for(int c=0;c<item.catchCommands.size();c++){
|
||||
catchCmds.add(generateToActionList(localData, item.catchCommands.get(c)));
|
||||
}
|
||||
|
||||
firstId = localData.exceptions.size();
|
||||
|
||||
|
||||
for (int i=firstId;i<firstId+item.catchExceptions2.size();i++) {
|
||||
ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_START));
|
||||
}
|
||||
|
||||
ret.addAll(tryCmds);
|
||||
|
||||
for (int i=firstId;i<firstId+item.catchExceptions2.size();i++) {
|
||||
ret.add(new ExceptionMarkAVM2Instruction(i, MARK_E_END));
|
||||
}
|
||||
|
||||
|
||||
int i=firstId+item.catchCommands.size()-1;
|
||||
List<AVM2Instruction> catches=new ArrayList<>();
|
||||
Reference<Integer> tempReg=new Reference<>(0);
|
||||
for (int c=item.catchCommands.size()-1;c>=0;c--) {
|
||||
List<AVM2Instruction> preCatches=new ArrayList<>();
|
||||
preCatches.add(ins(new GetLocal0Ins()));
|
||||
preCatches.add(ins(new PushScopeIns()));
|
||||
preCatches.add(AssignableAVM2Item.generateGetLoc(localData.activationReg));
|
||||
preCatches.add(ins(new PushScopeIns()));
|
||||
preCatches.add(ins(new NewCatchIns(),i));
|
||||
preCatches.addAll(toInsList(AssignableAVM2Item.dupSetTemp(localData, this, tempReg)));
|
||||
preCatches.add(ins(new DupIns()));
|
||||
preCatches.add(ins(new PushScopeIns()));
|
||||
preCatches.add(ins(new SwapIns()));
|
||||
preCatches.add(ins(new SetSlotIns(),1));
|
||||
preCatches.addAll(catchCmds.get(c));
|
||||
preCatches.add(ins(new PopScopeIns()));
|
||||
preCatches.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempReg))));
|
||||
catches.addAll(0,preCatches);
|
||||
catches.add(0,new ExceptionMarkAVM2Instruction(i, MARK_E_TARGET));
|
||||
i--;
|
||||
catches.add(0,ins(new JumpIns(), insToBytes(catches).length));
|
||||
}
|
||||
ret.addAll(catches);
|
||||
localData.exceptions.addAll(newex);
|
||||
//TODO: finally
|
||||
return ret;
|
||||
}
|
||||
@@ -664,12 +735,10 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
generateTraitsPhase2(initScope, pkg, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it);
|
||||
generateTraitsPhase2(initScope, pkg, name, superName, true, localData, traitItems, classInfo.static_traits, st);
|
||||
if (constructor == null) {
|
||||
instanceInfo.iinit_index = method(initScope + 1, false, false, 0, name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), new ArrayList<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), TypeItem.UNBOUNDED/*?? FIXME*/);
|
||||
instanceInfo.iinit_index = method(pkg.packageName,false,new ArrayList<NameAVM2Item>(),initScope + 1, false, 0, name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), new ArrayList<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), TypeItem.UNBOUNDED/*?? FIXME*/);
|
||||
} else {
|
||||
MethodAVM2Item m = (MethodAVM2Item) constructor;
|
||||
Reference<Boolean> hasArgs = new Reference<>(Boolean.FALSE);
|
||||
calcRegisters(localData, m, hasArgs);
|
||||
instanceInfo.iinit_index = method(initScope + 1, m.hasRest, hasArgs.getVal(), m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/);
|
||||
instanceInfo.iinit_index = method(pkg.packageName,m.needsActivation,m.subvariables,initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/);
|
||||
}
|
||||
|
||||
//Class initializer
|
||||
@@ -759,6 +828,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
|
||||
String pkg = "";
|
||||
String name = type.toString();
|
||||
if("*".equals(name)){
|
||||
return 0;
|
||||
}
|
||||
TypeItem nameItem = (TypeItem) type;
|
||||
if (name.contains(".")) {
|
||||
pkg = name.substring(0, name.lastIndexOf('.'));
|
||||
@@ -847,26 +919,175 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int method(int initScope, boolean hasRest, boolean hasArguments, int line, String className, String superType, boolean constructor, SourceGeneratorLocalData localData, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, GraphTargetItem retType) throws ParseException {
|
||||
public int method(String pkg,boolean needsActivation,List<NameAVM2Item> subvariables,int initScope, boolean hasRest, int line, String className, String superType, boolean constructor, SourceGeneratorLocalData localData, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, GraphTargetItem retType) throws ParseException {
|
||||
//Reference<Boolean> hasArgs = new Reference<>(Boolean.FALSE);
|
||||
//calcRegisters(localData,needsActivation,paramNames,subvariables,body, hasArgs);
|
||||
localData.activationReg = 0;
|
||||
|
||||
for (NameAVM2Item n : subvariables) {
|
||||
if (n.unresolved) {
|
||||
GraphTargetItem resolved = null;
|
||||
List<ABC> abcs = new ArrayList<>();
|
||||
abcs.add(abc);
|
||||
abcs.addAll(allABCs);
|
||||
|
||||
for (int i = 0; i < n.openedNamespaces.size(); i++) {
|
||||
int nsIndex = n.openedNamespaces.get(i);
|
||||
Namespace ns = abc.constants.constant_namespace.get(nsIndex);
|
||||
int nsKind = ns.kind;
|
||||
loopabc:
|
||||
for (ABC a : abcs) {
|
||||
for (int h = 0; h < a.instance_info.size(); h++) {
|
||||
InstanceInfo ii = a.instance_info.get(h);
|
||||
Multiname nm = a.constants.constant_multiname.get(ii.name_index);
|
||||
if (nm.getNamespace(a.constants).getName(a.constants).equals(ns.getName(abc.constants)) && nm.getNamespace(a.constants).kind == nsKind) {
|
||||
|
||||
//found opened class
|
||||
Reference<String> outName = new Reference<>("");
|
||||
Reference<String> outNs = new Reference<>("");
|
||||
Reference<String> outPropNs = new Reference<>("");
|
||||
Reference<Integer> outPropNsKind = new Reference<>(1);
|
||||
Reference<String> outPropType = new Reference<>("");
|
||||
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nm.getNamespace(a.constants).getName(a.constants), nm.getName(a.constants, new ArrayList<String>()), n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) {
|
||||
resolved = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), abc, allABCs, n.openedNamespaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.redirect = resolved;
|
||||
if (resolved == null) {
|
||||
throw new ParseException("Unknown variable or property:" + n.getVariableName(), n.line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean hasArguments = false;
|
||||
List<String> slotNames = new ArrayList<>();
|
||||
List<String> slotTypes = new ArrayList<>();
|
||||
slotNames.add("--first");
|
||||
slotTypes.add("-");
|
||||
|
||||
List<String> registerNames = new ArrayList<>();
|
||||
List<String> registerTypes = new ArrayList<>();
|
||||
registerTypes.add(pkg.equals("")?className:pkg+"."+className);
|
||||
registerNames.add("this");
|
||||
for(GraphTargetItem t:paramTypes){
|
||||
registerTypes.add(t.toString());
|
||||
slotTypes.add(t.toString());
|
||||
}
|
||||
registerNames.addAll(paramNames);
|
||||
slotNames.addAll(paramNames);
|
||||
localData.registerVars.clear();
|
||||
for (NameAVM2Item n : subvariables) {
|
||||
if (n.getVariableName().equals("arguments") & !n.isDefinition()) {
|
||||
registerNames.add("arguments");
|
||||
registerTypes.add("Object");
|
||||
hasArguments = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int paramRegCount = registerNames.size();
|
||||
|
||||
if(needsActivation){
|
||||
registerNames.add("+$activation");
|
||||
localData.activationReg = registerNames.size()-1;
|
||||
registerTypes.add("Object");
|
||||
}
|
||||
for (NameAVM2Item n : subvariables) {
|
||||
if (n.isDefinition()) {
|
||||
if(!needsActivation || (n.getSlotScope()<=0)){
|
||||
registerNames.add(n.getVariableName());
|
||||
registerTypes.add(n.type.toString());
|
||||
slotNames.add(n.getVariableName());
|
||||
slotTypes.add(n.type.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int slotScope = 1; //?
|
||||
|
||||
for (NameAVM2Item n : subvariables) {
|
||||
if (n.getVariableName() != null) {
|
||||
if(needsActivation){
|
||||
if(n.getSlotNumber() <= 0){
|
||||
n.setSlotNumber(slotNames.indexOf(n.getVariableName()));
|
||||
n.setSlotScope(slotScope);
|
||||
}
|
||||
}else{
|
||||
n.setRegNumber(registerNames.indexOf(n.getVariableName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < registerNames.size(); i++) {
|
||||
if(needsActivation && i>localData.activationReg){
|
||||
break;
|
||||
}
|
||||
localData.registerVars.put(registerNames.get(i), i);
|
||||
}
|
||||
List<NameAVM2Item> declarations=new ArrayList<>();
|
||||
loopn:for (NameAVM2Item n : subvariables) {
|
||||
if(!n.isDefinition()){
|
||||
continue;
|
||||
}
|
||||
if(n.getSlotScope()!=slotScope){
|
||||
continue;
|
||||
}
|
||||
for(NameAVM2Item d:declarations){
|
||||
if(n.getVariableName()!=null && n.getVariableName().equals(d.getVariableName())){
|
||||
continue loopn;
|
||||
}
|
||||
}
|
||||
for(GraphTargetItem it:body){ //search first level of commands
|
||||
if(it instanceof NameAVM2Item){
|
||||
NameAVM2Item n2=(NameAVM2Item)it;
|
||||
if(n2.isDefinition() && n2.getAssignedValue()!=null && n2.getVariableName().equals(n.getVariableName())){
|
||||
continue loopn;
|
||||
}
|
||||
if(!n2.isDefinition() && n2.getVariableName()!=null && n2.getVariableName().equals(n.getVariableName())){ //used earlier than defined
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
NameAVM2Item d=new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue(""+n.type), true, n.openedNamespaces);
|
||||
if(needsActivation){
|
||||
if(d.getSlotNumber() <= 0)
|
||||
{
|
||||
d.setSlotNumber(n.getSlotNumber());
|
||||
d.setSlotScope(n.getSlotScope());
|
||||
}
|
||||
}else{
|
||||
d.setRegNumber(n.getRegNumber());
|
||||
}
|
||||
declarations.add(d);
|
||||
}
|
||||
|
||||
|
||||
int param_types[] = new int[paramTypes.size()];
|
||||
ValueKind optional[] = new ValueKind[paramValues.size()];
|
||||
int param_names[] = new int[paramNames.size()];
|
||||
//int param_names[] = new int[paramNames.size()];
|
||||
for (int i = 0; i < paramTypes.size(); i++) {
|
||||
param_types[i] = typeName(localData, paramTypes.get(i));
|
||||
param_names[i] = str(paramNames.get(i));
|
||||
//param_names[i] = str(paramNames.get(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramValues.size(); i++) {
|
||||
optional[i] = getValueKind(Namespace.KIND_NAMESPACE/*FIXME*/, paramTypes.get(paramTypes.size() - paramValues.size() + i), paramTypes.get(i));
|
||||
}
|
||||
|
||||
MethodInfo mi = new MethodInfo(param_types, constructor ? 0 : typeName(localData, retType), 0/*name_index*/, 0, optional, param_names);
|
||||
MethodInfo mi = new MethodInfo(param_types, constructor ? 0 : typeName(localData, retType), 0/*name_index*/, 0, optional, new int[0]/*no param_names*/);
|
||||
if (hasArguments) {
|
||||
mi.setFlagNeed_Arguments();
|
||||
}
|
||||
//No param names like in official
|
||||
/*
|
||||
if (!paramNames.isEmpty()) {
|
||||
mi.setFlagHas_paramnames();
|
||||
}
|
||||
}*/
|
||||
if (!paramValues.isEmpty()) {
|
||||
mi.setFlagHas_optional();
|
||||
}
|
||||
@@ -876,10 +1097,47 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
|
||||
MethodBody mbody = new MethodBody();
|
||||
mbody.method_info = abc.addMethodInfo(mi);
|
||||
|
||||
mbody.traits = new Traits();
|
||||
int slotId = 1;
|
||||
for(int i=1;i<slotNames.size();i++){
|
||||
TraitSlotConst tsc = new TraitSlotConst();
|
||||
tsc.slot_id = slotId++;
|
||||
tsc.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(slotNames.get(i), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true), 0,0, new ArrayList<Integer>()), true);
|
||||
tsc.type_index = typeName(localData, new TypeItem(slotTypes.get(i)));
|
||||
mbody.traits.traits.add(tsc);
|
||||
}
|
||||
|
||||
if(needsActivation){
|
||||
for(int i=1;i<paramRegCount;i++){
|
||||
NameAVM2Item param=new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), null, false, new ArrayList<Integer>());
|
||||
param.setRegNumber(i);
|
||||
NameAVM2Item d=new NameAVM2Item(new TypeItem(registerTypes.get(i)), 0, registerNames.get(i), param, true, new ArrayList<Integer>());
|
||||
d.setSlotScope(slotScope);
|
||||
d.setSlotNumber(slotNames.indexOf(registerNames.get(i)));
|
||||
declarations.add(d);
|
||||
}
|
||||
}
|
||||
body.addAll(0,declarations);
|
||||
|
||||
localData.exceptions = new ArrayList<>();
|
||||
List<GraphSourceItem> src = generate(localData, body);
|
||||
mbody.code = new AVM2Code();
|
||||
mbody.code.code = toInsList(src);
|
||||
|
||||
if(needsActivation){
|
||||
List<AVM2Instruction> acts=new ArrayList<>();
|
||||
acts.add(ins(new NewActivationIns()));
|
||||
acts.add(ins(new DupIns()));
|
||||
acts.add(AssignableAVM2Item.generateSetLoc(localData.activationReg));
|
||||
acts.add(ins(new PushScopeIns()));
|
||||
|
||||
|
||||
|
||||
|
||||
mbody.code.code.addAll(0,acts);
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
List<ABC> abcs = new ArrayList<>();
|
||||
abcs.add(abc);
|
||||
@@ -927,6 +1185,26 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
mbody.code.code.add(new AVM2Instruction(0, new ReturnValueIns(), new int[]{}, new byte[0]));
|
||||
}
|
||||
}
|
||||
mbody.exceptions = localData.exceptions.toArray(new ABCException[localData.exceptions.size()]);
|
||||
int offset = 0;
|
||||
for (AVM2Instruction ins : mbody.code.code) {
|
||||
if(ins instanceof ExceptionMarkAVM2Instruction){
|
||||
ExceptionMarkAVM2Instruction m=(ExceptionMarkAVM2Instruction)ins;
|
||||
switch(m.markType){
|
||||
case MARK_E_START:
|
||||
mbody.exceptions[m.exceptionId].start = offset;
|
||||
break;
|
||||
case MARK_E_END:
|
||||
mbody.exceptions[m.exceptionId].end = offset;
|
||||
break;
|
||||
case MARK_E_TARGET:
|
||||
mbody.exceptions[m.exceptionId].target = offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset+=ins.getBytes().length;
|
||||
}
|
||||
|
||||
mbody.autoFillStats(abc, initScope);
|
||||
|
||||
abc.addMethodBody(mbody);
|
||||
@@ -998,14 +1276,10 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
if (mai.isStatic() != generateStatic) {
|
||||
continue;
|
||||
}
|
||||
Reference<Boolean> hasArgs = new Reference<>(Boolean.FALSE);
|
||||
calcRegisters(localData, mai, hasArgs);
|
||||
((TraitMethodGetterSetter) traits[k]).method_info = method(initScope + 1/*class scope*/, mai.hasRest, hasArgs.getVal(), mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType);
|
||||
((TraitMethodGetterSetter) traits[k]).method_info = method(pkg.packageName,mai.needsActivation,mai.subvariables,initScope + 1/*class scope*/, mai.hasRest,mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType);
|
||||
} else if (item instanceof FunctionAVM2Item) {
|
||||
FunctionAVM2Item fai = (FunctionAVM2Item) item;
|
||||
Reference<Boolean> hasArgs = new Reference<>(Boolean.FALSE);
|
||||
calcRegisters(localData, fai, hasArgs);
|
||||
((TraitFunction) traits[k]).method_info = method(initScope, fai.hasRest, hasArgs.getVal(), fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType);
|
||||
((TraitFunction) traits[k]).method_info = method(pkg.packageName,fai.needsActivation,fai.subvariables,initScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1318,76 +1592,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
public void calcRegisters(SourceGeneratorLocalData localData, FunctionAVM2Item fun, Reference<Boolean> hasArguments) throws ParseException {
|
||||
List<String> registerNames = new ArrayList<>();
|
||||
registerNames.add("this");
|
||||
registerNames.addAll(fun.paramNames);
|
||||
localData.registerVars.clear();
|
||||
for (NameAVM2Item n : fun.subvariables) {
|
||||
if (n.getVariableName().equals("arguments") & !n.isDefinition()) {
|
||||
registerNames.add("arguments");
|
||||
hasArguments.setVal(Boolean.TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (NameAVM2Item n : fun.subvariables) {
|
||||
if (n.isDefinition()) {
|
||||
registerNames.add(n.getVariableName());
|
||||
}
|
||||
}
|
||||
for (NameAVM2Item n : fun.subvariables) {
|
||||
if (n.unresolved) {
|
||||
GraphTargetItem resolved = null;
|
||||
List<ABC> abcs = new ArrayList<>();
|
||||
abcs.add(abc);
|
||||
abcs.addAll(allABCs);
|
||||
|
||||
for (int i = 0; i < n.openedNamespaces.size(); i++) {
|
||||
int nsIndex = n.openedNamespaces.get(i);
|
||||
Namespace ns = abc.constants.constant_namespace.get(nsIndex);
|
||||
int nsKind = ns.kind;
|
||||
loopabc:
|
||||
for (ABC a : abcs) {
|
||||
for (int h = 0; h < a.instance_info.size(); h++) {
|
||||
InstanceInfo ii = a.instance_info.get(h);
|
||||
Multiname nm = a.constants.constant_multiname.get(ii.name_index);
|
||||
if (nm.getNamespace(a.constants).getName(a.constants).equals(ns.getName(abc.constants)) && nm.getNamespace(a.constants).kind == nsKind) {
|
||||
|
||||
//found opened class
|
||||
Reference<String> outName = new Reference<>("");
|
||||
Reference<String> outNs = new Reference<>("");
|
||||
Reference<String> outPropNs = new Reference<>("");
|
||||
Reference<Integer> outPropNsKind = new Reference<>(1);
|
||||
Reference<String> outPropType = new Reference<>("");
|
||||
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nm.getNamespace(a.constants).getName(a.constants), nm.getName(a.constants, new ArrayList<String>()), n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) {
|
||||
resolved = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), abc, allABCs, n.openedNamespaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.redirect = resolved;
|
||||
if (resolved == null) {
|
||||
throw new ParseException("Unknown variable or property:" + n.getVariableName(), n.line);
|
||||
}
|
||||
}
|
||||
if (n.getVariableName() != null) {
|
||||
n.setRegNumber(registerNames.indexOf(n.getVariableName()));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < registerNames.size(); i++) {
|
||||
localData.registerVars.put(registerNames.get(i), i);
|
||||
}
|
||||
List<NameAVM2Item> declarations=new ArrayList<>();
|
||||
for (NameAVM2Item n : fun.subvariables) {
|
||||
if(n.isDefinition() && n.getAssignedValue() == null){
|
||||
NameAVM2Item d=new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue(""+n.type), true, n.openedNamespaces);
|
||||
d.setRegNumber(n.getRegNumber());
|
||||
declarations.add(d);
|
||||
}
|
||||
}
|
||||
fun.body.addAll(0,declarations);
|
||||
}
|
||||
/* public void calcRegisters(Reference<Integer> activationReg, SourceGeneratorLocalData localData, boolean needsActivation, List<String> funParamNames,List<NameAVM2Item> funSubVariables,List<GraphTargetItem> funBody, Reference<Boolean> hasArguments) throws ParseException {
|
||||
|
||||
}*/
|
||||
|
||||
public int resolveType(String objType) {
|
||||
if (objType.equals("*")) {
|
||||
|
||||
+48
-34
@@ -42,6 +42,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ThrowAVM2Item;
|
||||
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.ExceptionAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.TryAVM2Item;
|
||||
@@ -128,13 +129,13 @@ public class ActionScriptParser {
|
||||
return uniqLast;
|
||||
}
|
||||
|
||||
private List<GraphTargetItem> commands(List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
private List<GraphTargetItem> commands(Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
if (debugMode) {
|
||||
System.out.println("commands:");
|
||||
}
|
||||
GraphTargetItem cmd = null;
|
||||
while ((cmd = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) {
|
||||
while ((cmd = command(needsActivation,importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) {
|
||||
ret.add(cmd);
|
||||
}
|
||||
if (debugMode) {
|
||||
@@ -400,7 +401,7 @@ public class ActionScriptParser {
|
||||
|
||||
private MethodAVM2Item method(List<String> importedClasses, boolean override, boolean isFinal, GraphTargetItem thisType, List<Integer> openedNamespaces, boolean isStatic, int namespace, boolean withBody, String functionName, boolean isMethod, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
FunctionAVM2Item f = function(importedClasses, namespace, thisType, openedNamespaces, withBody, functionName, isMethod, variables);
|
||||
return new MethodAVM2Item(f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType);
|
||||
return new MethodAVM2Item(f.needsActivation,f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType);
|
||||
}
|
||||
|
||||
private FunctionAVM2Item function(List<String> importedClasses, int namespace, GraphTargetItem thisType, List<Integer> openedNamespaces, boolean withBody, String functionName, boolean isMethod, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
@@ -464,17 +465,17 @@ public class ActionScriptParser {
|
||||
}
|
||||
subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces));
|
||||
int parCnt = subvariables.size();
|
||||
Reference<Boolean> needsActivation = new Reference<>(false);
|
||||
if (withBody) {
|
||||
expectedType(SymbolType.CURLY_OPEN);
|
||||
|
||||
body = commands(importedClasses, openedNamespaces, new Stack<Loop>(), new HashMap<Loop, String>(), new HashMap<String, Integer>(), true, isMethod, 0, subvariables);
|
||||
expectedType(SymbolType.CURLY_OPEN);
|
||||
body = commands(needsActivation, importedClasses, openedNamespaces, new Stack<Loop>(), new HashMap<Loop, String>(), new HashMap<String, Integer>(), true, isMethod, 0, subvariables);
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < parCnt; i++) {
|
||||
subvariables.remove(0);
|
||||
}
|
||||
return new FunctionAVM2Item(namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
return new FunctionAVM2Item(needsActivation.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
}
|
||||
|
||||
private GraphTargetItem traits(List<String> importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List<Integer> openedNamespaces, String packageName, String classNameStr, boolean isInterface, List<GraphTargetItem> traits) throws ParseException, IOException {
|
||||
@@ -662,13 +663,13 @@ public class ActionScriptParser {
|
||||
if (!ft.paramTypes.isEmpty()) {
|
||||
throw new ParseException("Getter can't have any parameters", lexer.yyline());
|
||||
}
|
||||
GetterAVM2Item g = new GetterAVM2Item(ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType);
|
||||
GetterAVM2Item g = new GetterAVM2Item(ft.needsActivation,ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType);
|
||||
t = g;
|
||||
} else if (isSetter) {
|
||||
if (ft.paramTypes.size() != 1) {
|
||||
throw new ParseException("Getter must have exactly one parameter", lexer.yyline());
|
||||
}
|
||||
SetterAVM2Item st = new SetterAVM2Item(ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType);
|
||||
SetterAVM2Item st = new SetterAVM2Item(ft.needsActivation,ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType);
|
||||
t = st;
|
||||
} else {
|
||||
t = ft;
|
||||
@@ -831,7 +832,7 @@ public class ActionScriptParser {
|
||||
//return ret;
|
||||
}
|
||||
|
||||
private GraphTargetItem command(List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
private GraphTargetItem command(Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
LexBufferer buf = new LexBufferer();
|
||||
lexer.addListener(buf);
|
||||
GraphTargetItem ret = null;
|
||||
@@ -868,7 +869,7 @@ public class ActionScriptParser {
|
||||
}
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
expectedType(SymbolType.CURLY_OPEN);
|
||||
List<GraphTargetItem> wcmd = commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
List<GraphTargetItem> wcmd = commands(needsActivation,importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
ret = new WithAVM2Item(null, wvar, wcmd);
|
||||
break;
|
||||
@@ -916,7 +917,7 @@ public class ActionScriptParser {
|
||||
}
|
||||
break;
|
||||
case CURLY_OPEN:
|
||||
ret = new BlockItem(null, commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
ret = new BlockItem(null, commands(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
break;
|
||||
/*case INCREMENT: //preincrement
|
||||
@@ -945,14 +946,14 @@ public class ActionScriptParser {
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
GraphTargetItem ifExpr = (expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables));
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
GraphTargetItem onTrue = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables);
|
||||
GraphTargetItem onTrue = command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables);
|
||||
List<GraphTargetItem> onTrueList = new ArrayList<>();
|
||||
onTrueList.add(onTrue);
|
||||
s = lex();
|
||||
List<GraphTargetItem> onFalseList = null;
|
||||
if (s.type == SymbolType.ELSE) {
|
||||
onFalseList = new ArrayList<>();
|
||||
onFalseList.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
onFalseList.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
} else {
|
||||
lexer.pushback(s);
|
||||
}
|
||||
@@ -961,7 +962,7 @@ public class ActionScriptParser {
|
||||
case WHILE:
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
List<GraphTargetItem> whileExpr = new ArrayList<>();
|
||||
whileExpr.add(commaExpression(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
whileExpr.add(commaExpression(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
List<GraphTargetItem> whileBody = new ArrayList<>();
|
||||
Loop wloop = new Loop(uniqId(), null, null);
|
||||
@@ -969,7 +970,7 @@ public class ActionScriptParser {
|
||||
loopLabels.put(wloop, loopLabel);
|
||||
}
|
||||
loops.push(wloop);
|
||||
whileBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
whileBody.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
ret = new WhileItem(null, wloop, whileExpr, whileBody);
|
||||
break;
|
||||
case DO:
|
||||
@@ -979,11 +980,11 @@ public class ActionScriptParser {
|
||||
if (loopLabel != null) {
|
||||
loopLabels.put(dloop, loopLabel);
|
||||
}
|
||||
doBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
doBody.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
expectedType(SymbolType.WHILE);
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
List<GraphTargetItem> doExpr = new ArrayList<>();
|
||||
doExpr.add(commaExpression(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
doExpr.add(commaExpression(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables));
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
ret = new DoWhileItem(null, dloop, doBody, doExpr);
|
||||
break;
|
||||
@@ -998,7 +999,7 @@ public class ActionScriptParser {
|
||||
s = lex();
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolType.PARENT_OPEN);
|
||||
GraphTargetItem firstCommand=command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables);
|
||||
GraphTargetItem firstCommand=command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables);
|
||||
if(firstCommand instanceof NameAVM2Item){
|
||||
NameAVM2Item nai=(NameAVM2Item)firstCommand;
|
||||
if(nai.isDefinition() && nai.getAssignedValue() == null){
|
||||
@@ -1024,17 +1025,17 @@ public class ActionScriptParser {
|
||||
GraphTargetItem forExpr = null;
|
||||
List<GraphTargetItem> forFirstCommands = new ArrayList<>();
|
||||
if (!forin) {
|
||||
//GraphTargetItem firstCommand = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables);
|
||||
//GraphTargetItem firstCommand = command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables);
|
||||
if (firstCommand != null) { //can be empty command
|
||||
forFirstCommands.add(firstCommand);
|
||||
}
|
||||
forExpr = (expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables));
|
||||
expectedType(SymbolType.SEMICOLON);
|
||||
forFinalCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
forFinalCommands.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
}
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
List<GraphTargetItem> forBody = new ArrayList<>();
|
||||
forBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables));
|
||||
forBody.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables));
|
||||
if (forin) {
|
||||
if (each) {
|
||||
ret = new ForEachInAVM2Item(null, floop, inexpr, forBody);
|
||||
@@ -1083,14 +1084,14 @@ public class ActionScriptParser {
|
||||
}
|
||||
pos++;
|
||||
lexer.pushback(s);
|
||||
List<GraphTargetItem> caseCmd = commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
List<GraphTargetItem> caseCmd = commands(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
caseCmds.add(caseCmd);
|
||||
s = lex();
|
||||
}
|
||||
List<GraphTargetItem> defCmd = new ArrayList<>();
|
||||
if (s.type == SymbolType.DEFAULT) {
|
||||
expectedType(SymbolType.COLON);
|
||||
defCmd = commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
defCmd = commands(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables);
|
||||
s = lexer.lex();
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE);
|
||||
@@ -1163,13 +1164,15 @@ public class ActionScriptParser {
|
||||
}
|
||||
break;
|
||||
case TRY:
|
||||
needsActivation.setVal(true);
|
||||
List<GraphTargetItem> tryCommands = new ArrayList<>();
|
||||
tryCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
tryCommands.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
s = lex();
|
||||
boolean found = false;
|
||||
List<List<GraphTargetItem>> catchCommands = null;
|
||||
List<List<GraphTargetItem>> catchCommands = new ArrayList<>();
|
||||
List<NameAVM2Item> catchExceptions = new ArrayList<>();
|
||||
if (s.type == SymbolType.CATCH) {
|
||||
int varCnt = variables.size();
|
||||
while (s.type == SymbolType.CATCH) {
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP);
|
||||
@@ -1177,20 +1180,31 @@ public class ActionScriptParser {
|
||||
String enamestr = s.value.toString();
|
||||
expectedType(SymbolType.COLON);
|
||||
GraphTargetItem etype = type(importedClasses, openedNamespaces, variables);
|
||||
NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, null, false/*?*/, openedNamespaces);
|
||||
NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces);
|
||||
variables.add(e);
|
||||
catchExceptions.add(e);
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
catchCommands = new ArrayList<>();
|
||||
e.setSlotNumber(1);
|
||||
e.setSlotScope(2); //?
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
List<GraphTargetItem> cc = new ArrayList<>();
|
||||
cc.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
cc.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
catchCommands.add(cc);
|
||||
s = lex();
|
||||
found = true;
|
||||
}
|
||||
for(int i=varCnt;i<variables.size();i++){
|
||||
for(NameAVM2Item e:catchExceptions){
|
||||
if(variables.get(i).getVariableName().equals(e.getVariableName())){
|
||||
variables.get(i).setSlotNumber(e.getSlotNumber());
|
||||
variables.get(i).setSlotScope(e.getSlotScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphTargetItem> finallyCommands = null;
|
||||
if (s.type == SymbolType.FINALLY) {
|
||||
finallyCommands = new ArrayList<>();
|
||||
finallyCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
finallyCommands.add(command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables));
|
||||
found = true;
|
||||
s = lex();
|
||||
}
|
||||
@@ -1513,12 +1527,12 @@ public class ActionScriptParser {
|
||||
return arrCnt;
|
||||
}
|
||||
|
||||
private GraphTargetItem commaExpression(List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forInLevel, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
private GraphTargetItem commaExpression(Reference<Boolean> needsActivation,List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forInLevel, List<NameAVM2Item> variables) throws IOException, ParseException {
|
||||
GraphTargetItem cmd = null;
|
||||
List<GraphTargetItem> expr = new ArrayList<>();
|
||||
ParsedSymbol s;
|
||||
do {
|
||||
cmd = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables);
|
||||
cmd = command(needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables);
|
||||
if (cmd != null) {
|
||||
expr.add(cmd);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal1Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
@@ -113,6 +116,8 @@ public abstract class AssignableAVM2Item extends AVM2Item {
|
||||
|
||||
public static AVM2Instruction generateSetLoc(int regNumber) {
|
||||
switch (regNumber) {
|
||||
case -1:
|
||||
return null;
|
||||
case 0:
|
||||
return ins(new SetLocal0Ins());
|
||||
case 1:
|
||||
@@ -128,6 +133,8 @@ public abstract class AssignableAVM2Item extends AVM2Item {
|
||||
|
||||
public static AVM2Instruction generateGetLoc(int regNumber) {
|
||||
switch (regNumber) {
|
||||
case -1:
|
||||
return null;
|
||||
case 0:
|
||||
return ins(new GetLocal0Ins());
|
||||
case 1:
|
||||
@@ -140,5 +147,25 @@ public abstract class AssignableAVM2Item extends AVM2Item {
|
||||
return ins(new GetLocalIns(), regNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<GraphSourceItem> generateGetSlot(int slotScope,int slotNumber){
|
||||
if(slotNumber==-1){
|
||||
return null;
|
||||
}
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.add(ins(new GetScopeObjectIns(),slotScope));
|
||||
ret.add(ins(new GetSlotIns(),slotNumber));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static List<GraphSourceItem> generateSetSlot(SourceGeneratorLocalData localData,SourceGenerator generator, GraphTargetItem val,int slotScope,int slotNumber){
|
||||
if(slotNumber==-1){
|
||||
return null;
|
||||
}
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
ret.add(ins(new GetScopeObjectIns(),slotScope));
|
||||
ret.addAll(val.toSource(localData, generator));
|
||||
ret.add(ins(new SetSlotIns(),slotNumber));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,6 +32,7 @@ public class ExceptionMarkAVM2Instruction extends AVM2Instruction {
|
||||
super(0, null, new int[0], new byte[0]);
|
||||
this.markType = markType;
|
||||
this.exceptionId = exceptionId;
|
||||
this.definition = new InstructionDefinition(0, "--mark", new int[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,9 +39,11 @@ public class FunctionAVM2Item extends AVM2Item {
|
||||
public GraphTargetItem retType;
|
||||
public int line;
|
||||
public boolean hasRest;
|
||||
public boolean needsActivation;
|
||||
|
||||
public FunctionAVM2Item(int namespace, boolean hasRest, int line, String functionName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
public FunctionAVM2Item(boolean needsActivation, int namespace, boolean hasRest, int line, String functionName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(null, NOPRECEDENCE);
|
||||
this.needsActivation = needsActivation;
|
||||
this.namespace = namespace;
|
||||
this.paramNames = paramNames;
|
||||
this.body = body;
|
||||
|
||||
@@ -25,8 +25,8 @@ import java.util.List;
|
||||
*/
|
||||
public class GetterAVM2Item extends MethodAVM2Item {
|
||||
|
||||
public GetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
public GetterAVM2Item(boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(needsActivation,hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public class MethodAVM2Item extends FunctionAVM2Item {
|
||||
private boolean isFinal;
|
||||
private boolean override;
|
||||
|
||||
public MethodAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
public MethodAVM2Item(boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(needsActivation,namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
this.isStatic = isStatic;
|
||||
this.override = override;
|
||||
this.isFinal = isFinal;
|
||||
|
||||
@@ -27,7 +27,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
|
||||
@@ -36,6 +38,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns;
|
||||
import static com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item.ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
|
||||
@@ -69,6 +72,8 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
private GraphTargetItem ns = null;
|
||||
private int regNumber = -1;
|
||||
public boolean unresolved = false;
|
||||
private int slotNumber = -1;
|
||||
private int slotScope = 0;
|
||||
|
||||
public GraphTargetItem redirect;
|
||||
|
||||
@@ -82,6 +87,17 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
c.setIndex(index);
|
||||
return c;
|
||||
}
|
||||
|
||||
public void setSlotScope(int slotScope) {
|
||||
this.slotScope = slotScope;
|
||||
}
|
||||
|
||||
public int getSlotScope() {
|
||||
return slotScope;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -93,6 +109,14 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
this.regNumber = regNumber;
|
||||
}
|
||||
|
||||
public int getSlotNumber() {
|
||||
return slotNumber;
|
||||
}
|
||||
|
||||
public void setSlotNumber(int slotNumber) {
|
||||
this.slotNumber = slotNumber;
|
||||
}
|
||||
|
||||
public int getRegNumber() {
|
||||
return regNumber;
|
||||
}
|
||||
@@ -199,8 +223,8 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
}
|
||||
|
||||
private List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) {
|
||||
if (variableName != null && regNumber == -1 && ns == null) {
|
||||
throw new RuntimeException("No register set for " + variableName);
|
||||
if (variableName != null && regNumber == -1 && slotNumber == -1 && ns == null) {
|
||||
throw new RuntimeException("No register or slot set for " + variableName);
|
||||
}
|
||||
if (definition && assignedValue == null) {
|
||||
return new ArrayList<GraphSourceItem>();
|
||||
@@ -252,7 +276,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
if (index != null) {
|
||||
if (assignedValue != null) {
|
||||
return toSourceMerge(localData, generator,
|
||||
generateGetLoc(regNumber), index, assignedValue,
|
||||
generateGetLoc(regNumber),generateGetSlot(slotScope,slotNumber), index, assignedValue,
|
||||
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
|
||||
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
|
||||
needsReturn ? getTemp(localData, generator, ret_temp) : null,
|
||||
@@ -269,10 +293,24 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
if (assignedValue != null) {
|
||||
List<String> basicTypes = Arrays.asList("int","Number");
|
||||
if(slotNumber>-1)
|
||||
{
|
||||
return toSourceMerge(localData, generator,
|
||||
ins(new GetScopeObjectIns(),slotScope),
|
||||
assignedValue, !((""+assignedValue.returnType()).equals(""+type)&&(basicTypes.contains(""+type))) ? generateCoerce(generator, "" + type) : null, needsReturn
|
||||
? dupSetTemp(localData, generator, ret_temp) : null, generateSetLoc(regNumber),slotNumber>-1?
|
||||
ins(new SetSlotIns(),slotNumber)
|
||||
:null,
|
||||
needsReturn?getTemp(localData, generator, ret_temp):null,
|
||||
killTemp(localData, generator, Arrays.asList(ret_temp)));
|
||||
}
|
||||
else{
|
||||
|
||||
return toSourceMerge(localData, generator, assignedValue, !((""+assignedValue.returnType()).equals(""+type)&&(basicTypes.contains(""+type))) ? generateCoerce(generator, "" + type) : null, needsReturn
|
||||
? ins(new DupIns()) : null, generateSetLoc(regNumber));
|
||||
}
|
||||
} else {
|
||||
return toSourceMerge(localData, generator, generateGetLoc(regNumber),
|
||||
return toSourceMerge(localData, generator, generateGetLoc(regNumber),generateGetSlot(slotScope,slotNumber),
|
||||
needsReturn ? null : ins(new PopIns()));
|
||||
}
|
||||
}
|
||||
@@ -393,7 +431,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
|
||||
if (index != null) {
|
||||
return toSourceMerge(localData, generator,
|
||||
generateGetLoc(regNumber), dupSetTemp(localData, generator, name_temp), index, dupSetTemp(localData, generator, index_temp),
|
||||
generateGetLoc(regNumber),generateGetSlot(slotScope,slotNumber), dupSetTemp(localData, generator, name_temp), index, dupSetTemp(localData, generator, index_temp),
|
||||
//Start get original
|
||||
//generateGetLoc(regNumber), getTemp(localData, generator, index_temp),
|
||||
ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
|
||||
@@ -412,19 +450,31 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
}
|
||||
|
||||
if(!needsReturn){
|
||||
return toSourceMerge(localData, generator,
|
||||
ins(isInteger?new IncLocalIIns():new IncLocalIns(),regNumber));
|
||||
if(slotNumber>-1){
|
||||
return toSourceMerge(localData, generator,
|
||||
ins(new GetScopeObjectIns(),slotScope),
|
||||
generateGetSlot(slotScope,slotNumber),
|
||||
(decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())),
|
||||
ins(new SetSlotIns(),slotNumber)
|
||||
);
|
||||
}else{
|
||||
return toSourceMerge(localData, generator,
|
||||
ins(isInteger?new IncLocalIIns():new IncLocalIns(),regNumber));
|
||||
}
|
||||
}
|
||||
return toSourceMerge(localData, generator,
|
||||
slotNumber>-1?ins(new GetScopeObjectIns(),slotScope):null,
|
||||
//Start get original
|
||||
generateGetLoc(regNumber),
|
||||
generateGetLoc(regNumber),generateGetSlot(slotScope,slotNumber),
|
||||
//End get original
|
||||
!isInteger ? ins(new ConvertDIns()) : null,
|
||||
//End get original
|
||||
(!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
|
||||
needsReturn ? ins(new DupIns()) : null,
|
||||
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
|
||||
generateSetLoc(regNumber));
|
||||
generateSetLoc(regNumber),
|
||||
slotNumber>-1?ins(new SetSlotIns(),slotNumber):null
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import java.util.List;
|
||||
*/
|
||||
public class SetterAVM2Item extends MethodAVM2Item {
|
||||
|
||||
public SetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
public SetterAVM2Item(boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
|
||||
super(needsActivation,hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
TODO List for AS3 parser/compiler:
|
||||
------------------------------
|
||||
- exceptions (try/catch)
|
||||
- finally clause
|
||||
- E4X (XML)
|
||||
- typenames (Vectors)
|
||||
- inner functions (activation, slots, etc.)
|
||||
- with
|
||||
- with (+ in catch clause)
|
||||
- delete property
|
||||
- default xml namespace
|
||||
- custom namespace modifiers
|
||||
@@ -224,8 +224,11 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
if (stats == null) {
|
||||
return false;
|
||||
}
|
||||
if(stats.has_activation){
|
||||
initScope++;
|
||||
}
|
||||
max_stack = stats.maxstack;
|
||||
max_scope_depth = init_scope_depth + stats.maxscope;
|
||||
max_scope_depth = stats.maxscope+(stats.has_activation?1:0);
|
||||
max_regs = stats.maxlocal;
|
||||
init_scope_depth = initScope;
|
||||
abc.method_info.get(method_info).setFlagSetsdxns(stats.has_set_dxns);
|
||||
|
||||
Reference in New Issue
Block a user