AS3 direct editation - indices, various bugfixes

This commit is contained in:
Jindra Pet��k
2014-04-20 13:00:24 +02:00
parent 9a90572312
commit 931635a7b5
8 changed files with 303 additions and 131 deletions
@@ -683,7 +683,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
ret.add(ins(new NewObjectIns(), 0));
ret.add(ins(new PushWithIns()));
scope = localData.scopeStack.size();
localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, null, abc, allABCs, new ArrayList<Integer>(), localData.callStack));
localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abc, allABCs, new ArrayList<Integer>(), localData.callStack));
}
ret.add(ins(new NewFunctionIns(), method(localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, null, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType)));
if (!item.functionName.isEmpty()) {
@@ -1188,25 +1188,19 @@ public class AVM2SourceGenerator implements SourceGenerator {
SlotAVM2Item si = (SlotAVM2Item) ti;
if (si.isStatic() && si.value!=null) {
sinitcode.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var)));
List<GraphTargetItem> tis = new ArrayList<>();
tis.add(si.value);
sinitcode.addAll(toInsList(generate(localData, tis)));
sinitcode.add(ins(new InitPropertyIns(), traitName(namespace, si.var)));
sinitcode.addAll(toInsList(si.value.toSource(localData, this)));
sinitcode.add(ins(new InitPropertyIns(), traitName(si.getNamespace(), si.var)));
}
if (!si.isStatic() && si.value!=null) {
initcode.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var)));
List<GraphTargetItem> tis = new ArrayList<>();
tis.add(si.value);
initcode.addAll(toInsList(generate(localData, tis)));
initcode.add(ins(new InitPropertyIns(), traitName(namespace, si.var)));
initcode.add(ins(new GetLocal0Ins()));
initcode.addAll(toInsList(si.value.toSource(localData, this)));
initcode.add(ins(new InitPropertyIns(), traitName(si.getNamespace(), si.var)));
}
}
}
MethodBody initBody=abc.findBody(init);
if(initBody.code.code.get(initBody.code.code.size()-1).definition instanceof ReturnVoidIns){
initBody.code.code.addAll(initBody.code.code.size()-1,initcode);
}
initBody.code.code.addAll(constructor==null?0:2,initcode);//after getlocal0,pushscope
if(sinitBody.code.code.get(sinitBody.code.code.size()-1).definition instanceof ReturnVoidIns){
sinitBody.code.code.addAll(sinitBody.code.code.size()-1,sinitcode);
@@ -1214,6 +1208,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
sinitBody.markOffsets();
sinitBody.autoFillStats(abc, initScope);
classInfo.cinit_index = staticMi;
initBody.autoFillStats(abc, initScope + 1);
instanceInfo.interfaces = new int[implementsStr.size()];
for (int i = 0; i < implementsStr.size(); i++) {
@@ -1274,7 +1269,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
if (type instanceof UnresolvedAVM2Item) {
type = ((UnresolvedAVM2Item) type).resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, allABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>());
String fullClass = localData.currentClass==null?null:(localData.pkg.equals("")?localData.currentClass:localData.pkg+"."+localData.currentClass);
type = ((UnresolvedAVM2Item) type).resolve(new TypeItem(fullClass),new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, allABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>());
}
String pkg = "";
@@ -1372,7 +1368,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (an instanceof UnresolvedAVM2Item) {
UnresolvedAVM2Item n = (UnresolvedAVM2Item) an;
if (n.resolved == null) {
GraphTargetItem res = n.resolve(paramTypes, paramNames, abc, allABCs, callStack, subvariables);
String fullClass = localData.currentClass==null?null:(localData.pkg.equals("")?localData.currentClass:localData.pkg+"."+localData.currentClass);
GraphTargetItem res = n.resolve(new TypeItem(fullClass),paramTypes, paramNames, abc, allABCs, callStack, subvariables);
if (res instanceof AssignableAVM2Item) {
subvariables.set(i, (AssignableAVM2Item) res);
} else {
@@ -1447,7 +1444,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (an instanceof NameAVM2Item) {
NameAVM2Item n = (NameAVM2Item) an;
if (n.getVariableName() != null) {
if (needsActivation) {
if (!n.getVariableName().equals("this") && needsActivation) {
if (n.getSlotNumber() <= 0) {
n.setSlotNumber(slotNames.indexOf(n.getVariableName()));
n.setSlotScope(slotScope);
@@ -1506,7 +1503,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (n.getNs() != null) {
continue;
}
if("this".equals(n.getVariableName()) || paramNames.contains(n.getVariableName())||"argmuments".equals(n.getVariableName())){
continue;
}
NameAVM2Item d = new NameAVM2Item(n.type, n.line, n.getVariableName(), NameAVM2Item.getDefaultValue("" + n.type), true, n.openedNamespaces);
//no index
if (needsActivation) {
@@ -1739,7 +1740,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
private int genNs(String custom, int namespace, List<Integer> openedNamespaces, SourceGeneratorLocalData localData) {
if (custom != null) {
PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, null, abc, allABCs, openedNamespaces, new ArrayList<MethodBody>());
PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList<MethodBody>());
Reference<ValueKind> value = new Reference<>(null);
prop.resolve(localData, new Reference<String>(""), new Reference<String>(""), new Reference<Integer>(0), value);
namespace = value.getVal().value_index;
@@ -185,38 +185,47 @@ public class ActionScriptParser {
private GraphTargetItem member(Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, GraphTargetItem obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, ParseException {
GraphTargetItem ret = obj;
ParsedSymbol s = lex();
while (s.isType(SymbolType.DOT)) {
s = lex();
while (s.isType(SymbolType.DOT, SymbolType.BRACKET_OPEN)) {
ParsedSymbol s2 = lex();
boolean attr = false;
if (s.type == SymbolType.ATTRIBUTE) {
attr = true;
s = lex();
if(s.type == SymbolType.DOT){
if(s2.type == SymbolType.ATTRIBUTE){
attr = true;
s = lex();
}else{
lexer.pushback(s2);
}
}else{
lexer.pushback(s2);
}
expected(s, lexer.yyline(), SymbolType.IDENTIFIER);
String propName = s.value.toString();
s = lex();
GraphTargetItem ns = null;
if (s.type == SymbolType.NAMESPACE_OP) {
if (s.type == SymbolType.BRACKET_OPEN) {
GraphTargetItem index = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.BRACKET_CLOSE);
ret = new IndexAVM2Item(attr, ret, index, null, openedNamespaces);
s = lex();
} else {
s = lex();
expected(s, lexer.yyline(), SymbolType.IDENTIFIER);
ns = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces);
variables.add((UnresolvedAVM2Item) ns);
propName = s.value.toString();
String propName = s.value.toString();
s = lex();
GraphTargetItem ns = null;
if (s.type == SymbolType.NAMESPACE_OP) {
s = lex();
expected(s, lexer.yyline(), SymbolType.IDENTIFIER);
ns = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces);
variables.add((UnresolvedAVM2Item) ns);
propName = s.value.toString();
}else{
lexer.pushback(s);
}
if (ns != null) {
ret = new NamespacedAVM2Item(ns, propName, ret, attr, openedNamespaces, null);
} else {
ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abc, otherABCs, openedNamespaces, new ArrayList<MethodBody>());
}
s = lex();
}
GraphTargetItem index = null;
if (s.type == SymbolType.BRACKET_OPEN) {
index = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.BRACKET_CLOSE);
} else {
lexer.pushback(s);
}
if (ns != null) {
ret = new NamespacedAVM2Item(index, ns, propName, ret, attr, openedNamespaces, null);
} else {
ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, index, abc, otherABCs, openedNamespaces, new ArrayList<MethodBody>());
}
s = lex();
}
lexer.pushback(s);
return ret;
@@ -232,6 +241,7 @@ public class ActionScriptParser {
expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP);
name += s.value.toString();
s = lex();
boolean attrBracket = false;
while (s.isType(SymbolType.DOT)) {
name += s.value.toString(); //. or ::
@@ -245,6 +255,7 @@ public class ActionScriptParser {
if (s.type != SymbolType.BRACKET_OPEN) {
throw new ParseException("Attribute identifier or bracket expected", lexer.yyline());
}
attrBracket = true;
continue;
}
} else {
@@ -298,18 +309,19 @@ public class ActionScriptParser {
openedNamespaces.add(AS3vecNs);
} */
}
GraphTargetItem index = null;
if (s.type == SymbolType.BRACKET_OPEN) {
index = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.BRACKET_CLOSE);
} else {
lexer.pushback(s);
}
/*GraphTargetItem index = null;
if (s.type == SymbolType.BRACKET_OPEN) {
index = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.BRACKET_CLOSE);
} else {
lexer.pushback(s);
}*/
// lexer.pushback(s);
GraphTargetItem ret = null;
if (name != null) {
UnresolvedAVM2Item unr = new UnresolvedAVM2Item(params, importedClasses, typeOnly, null, lexer.yyline(), name, null, openedNamespaces);
unr.setIndex(index);
//unr.setIndex(index);
variables.add(unr);
ret = unr;
}
@@ -320,7 +332,17 @@ public class ActionScriptParser {
}
UnresolvedAVM2Item ns = new UnresolvedAVM2Item(params, importedClasses, typeOnly, null, lexer.yyline(), nsname, null, openedNamespaces);
variables.add(ns);
ret = new NamespacedAVM2Item(index, ns, nsprop, ret, attr, openedNamespaces, null);
ret = new NamespacedAVM2Item(ns, nsprop, ret, attr, openedNamespaces, null);
}
if (s.type == SymbolType.BRACKET_OPEN) {
lexer.pushback(s);
if(attrBracket){
lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE,"@"));
lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT,"."));
}
ret = member(needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables);
}else{
lexer.pushback(s);
}
return ret;
}
@@ -721,7 +743,7 @@ public class ActionScriptParser {
GraphTargetItem value = null;
if (s.type == SymbolType.ASSIGN) {
value = expression(new Reference<Boolean>(false), importedClasses, openedNamespaces, new HashMap<String, Integer>(), false, false, true, isStatic||isConst?sinitVariables:constrVariables);
value = expression(new Reference<Boolean>(false), importedClasses, openedNamespaces, new HashMap<String, Integer>(), false, false, true, isStatic || isConst ? sinitVariables : constrVariables);
s = lex();
}
GraphTargetItem tar;
@@ -767,7 +789,7 @@ public class ActionScriptParser {
List<Integer> indices = new ArrayList<>();
List<String> names = new ArrayList<>();
List<String> namespaces = new ArrayList<>();
AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>())), abc), indices, names, namespaces);
AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>())), abc), indices, names, namespaces);
for (int i = 0; i < names.size(); i++) {
if (namespaces.get(i).isEmpty()) {
continue;
@@ -1417,7 +1439,7 @@ public class ActionScriptParser {
UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a;
if (ui.getVariableName().equals(e.getVariableName())) {
try {
ui.resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), variables);
ui.resolve(null, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), variables);
} catch (CompilationException ex) {
//ignore
}
@@ -1440,7 +1462,7 @@ public class ActionScriptParser {
for (NameAVM2Item e : catchExceptions) {
if (ui.getVariableName().equals(e.getVariableName())) {
try {
ui.resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), variables);
ui.resolve(null, new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), variables);
} catch (CompilationException ex) {
//ignore
}
@@ -1528,7 +1550,7 @@ public class ActionScriptParser {
private GraphTargetItem expressionRemainder(Reference<Boolean> needsActivation, List<Integer> openedNamespaces, GraphTargetItem expr, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables, List<String> importedClasses) throws IOException, ParseException {
GraphTargetItem ret = null;
ParsedSymbol s = lex();
if (ret == null) {
switch (s.type) {
case AS:
@@ -89,7 +89,7 @@ public class CallAVM2Item extends AVM2Item {
nobj.setRegNumber(0);
obj = nobj;
}
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList<MethodBody>());
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList<MethodBody>());
p.setAssignedValue(n.getAssignedValue());
callable = p;
}
@@ -123,7 +123,7 @@ public class CallAVM2Item extends AVM2Item {
obj = new AVM2Instruction(0, new FindPropertyStrictIns(), new int[]{prop.resolveProperty(localData)}, new byte[0]);
}
}
return toSourceMerge(localData, generator, obj, prop.index, arguments,
return toSourceMerge(localData, generator, obj, arguments,
new AVM2Instruction(0, new CallPropertyIns(), new int[]{prop.resolveProperty(localData), arguments.size()}, new byte[0])
);
}
@@ -142,7 +142,7 @@ public class CallAVM2Item extends AVM2Item {
if (callable instanceof NameAVM2Item) {
NameAVM2Item n = (NameAVM2Item) callable;
PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList<MethodBody>());
PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList<MethodBody>());
p.setAssignedValue(n.getAssignedValue());
callable = p;
}
@@ -153,7 +153,7 @@ public class CallAVM2Item extends AVM2Item {
if (obj == null) {
obj = new AVM2Instruction(0, new FindPropertyStrictIns(), new int[]{prop.resolveProperty(localData)}, new byte[0]);
}
return toSourceMerge(localData, generator, obj, prop.index, arguments,
return toSourceMerge(localData, generator, obj, arguments,
new AVM2Instruction(0, new CallPropVoidIns(), new int[]{prop.resolveProperty(localData), arguments.size()}, new byte[0])
);
}
@@ -0,0 +1,162 @@
/*
* Copyright (C) 2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import static com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item.ins;
import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.dupSetTemp;
import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.getTemp;
import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.killTemp;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import static com.jpexs.decompiler.graph.GraphTargetItem.toSourceMerge;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IndexAVM2Item extends AssignableAVM2Item {
private List<Integer> openedNamespaces;
public GraphTargetItem object;
public GraphTargetItem index;
public boolean attr;
public IndexAVM2Item(boolean attr,GraphTargetItem object, GraphTargetItem index, GraphTargetItem storeValue,List<Integer> openedNamespaces) {
super(storeValue);
this.object = object;
this.index = index;
this.openedNamespaces = openedNamespaces;
this.attr = attr;
}
private int allNsSet(ABC abc) {
int nssa[] = new int[openedNamespaces.size()];
for (int i = 0; i < openedNamespaces.size(); i++) {
nssa[i] = openedNamespaces.get(i);
}
return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true);
}
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return null;
}
@Override
public boolean hasReturnValue() {
return true;
}
@Override
public GraphTargetItem returnType() {
return TypeItem.UNBOUNDED;
}
@Override
public AssignableAVM2Item copy() {
return new IndexAVM2Item(attr,object,index,assignedValue,openedNamespaces);
}
@Override
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) throws CompilationException {
Reference<Integer> obj_temp=new Reference<>(-1);
Reference<Integer> index_temp=new Reference<>(-1);
Reference<Integer> val_temp = new Reference<>(-1);
AVM2SourceGenerator g=(AVM2SourceGenerator)generator;
int indexPropIndex = g.abc.constants.getMultinameId(new Multiname(attr?Multiname.MULTINAMELA:Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true);
return toSourceMerge(localData, generator,
object,dupSetTemp(localData, generator, obj_temp),
index,dupSetTemp(localData, generator, index_temp),
ins(new GetPropertyIns(),indexPropIndex),
ins(new ConvertDIns()),
(!post)?(decrement?ins(new DecrementIns()):ins(new IncrementIns())):null,
needsReturn?ins(new DupIns()):null,
post?(decrement?ins(new DecrementIns()):ins(new IncrementIns())):null,
setTemp(localData, generator, val_temp),
getTemp(localData, generator, obj_temp),
getTemp(localData, generator, index_temp),
getTemp(localData, generator, val_temp),
ins(new SetPropertyIns(),indexPropIndex),
killTemp(localData, generator, Arrays.asList(val_temp,obj_temp,index_temp))
);
}
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException {
AVM2SourceGenerator g = (AVM2SourceGenerator)generator;
int indexPropIndex = g.abc.constants.getMultinameId(new Multiname(attr?Multiname.MULTINAMELA:Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true);
Reference<Integer> ret_temp = new Reference<>(-1);
if(assignedValue!=null){
return toSourceMerge(localData, generator,
object,
index,
assignedValue,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), indexPropIndex),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ret_temp)));
}else{
return toSourceMerge(localData, generator,
object,
index,
ins(new GetPropertyIns(), indexPropIndex));
}
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
return toSource(localData, generator, true);
}
@Override
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
return toSource(localData, generator, false);
}
}
@@ -55,16 +55,14 @@ import java.util.List;
*/
public class NamespacedAVM2Item extends AssignableAVM2Item {
public GraphTargetItem index;
public GraphTargetItem ns;
public String name;
public GraphTargetItem obj;
public boolean attr;
public List<Integer> openedNamespaces;
public NamespacedAVM2Item(GraphTargetItem index, GraphTargetItem ns, String name, GraphTargetItem obj, boolean attr, List<Integer> openedNamespaces, GraphTargetItem storeValue) {
public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem obj, boolean attr, List<Integer> openedNamespaces, GraphTargetItem storeValue) {
super(storeValue);
this.index = index;
this.ns = ns;
this.name = name;
this.obj = obj;
@@ -82,7 +80,7 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
@Override
public AssignableAVM2Item copy() {
return new NamespacedAVM2Item(index, ns, name, obj, attr, openedNamespaces, assignedValue);
return new NamespacedAVM2Item(ns, name, obj, attr, openedNamespaces, assignedValue);
}
@Override
@@ -92,7 +90,7 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
Reference<Integer> ns_temp = new Reference<>(-1);
Reference<Integer> name_temp = new Reference<>(-1);
Reference<Integer> ret_temp = new Reference<>(-1);
if (name == null && index != null) {
/*if (name == null && index != null) {
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, new TypeItem("Namespace")), index, ins(new ConvertSIns()),
ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
@@ -111,7 +109,9 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, ns_temp)));
} else if (name != null && index == null) {
} else
*/
if (name != null) {
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, new TypeItem("Namespace")),
ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<Integer>()), true)),
@@ -162,8 +162,8 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
if (name == null) {
if (assignedValue != null) {
return toSourceMerge(localData, generator,
obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, obj == null ? index : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, new TypeItem("Namespace")), index, ins(new ConvertSIns()), assignedValue,
obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, new TypeItem("Namespace")), ins(new ConvertSIns()), assignedValue,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
@@ -171,8 +171,8 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
);
} else {
return toSourceMerge(localData, generator,
obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, obj == null ? index : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, new TypeItem("Namespace")), index, ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, new TypeItem("Namespace")), ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? null : ins(new PopIns()),
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
@@ -60,23 +60,21 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
public GraphTargetItem object;
public ABC abc;
public List<ABC> otherABCs;
public GraphTargetItem index;
private List<Integer> openedNamespaces;
private List<MethodBody> callStack;
public List<GraphTargetItem> scopeStack = new ArrayList<GraphTargetItem>();
@Override
public AssignableAVM2Item copy() {
PropertyAVM2Item p = new PropertyAVM2Item(object, propertyName, index, abc, otherABCs, openedNamespaces, callStack);
PropertyAVM2Item p = new PropertyAVM2Item(object, propertyName, abc, otherABCs, openedNamespaces, callStack);
return p;
}
public PropertyAVM2Item(GraphTargetItem object, String propertyName, GraphTargetItem index, ABC abc, List<ABC> otherABCs, List<Integer> openedNamespaces, List<MethodBody> callStack) {
public PropertyAVM2Item(GraphTargetItem object, String propertyName, ABC abc, List<ABC> otherABCs, List<Integer> openedNamespaces, List<MethodBody> callStack) {
this.propertyName = propertyName;
this.object = object;
this.otherABCs = otherABCs;
this.abc = abc;
this.index = index;
this.openedNamespaces = openedNamespaces;
this.callStack = callStack;
}
@@ -485,9 +483,6 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
}*/
@Override
public GraphTargetItem returnType() {
if (index != null) {
return TypeItem.UNBOUNDED;
}
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
@@ -511,23 +506,23 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
if (assignedValue != null) {
String targetType = propType.getVal();
String srcType = assignedValue.returnType().toString();
GraphTargetItem st = assignedValue;
GraphTargetItem coerced = assignedValue;
if (!targetType.equals(srcType) && !propertyName.startsWith("@")) {
st = new CoerceAVM2Item(null, assignedValue, targetType);
coerced = new CoerceAVM2Item(null, assignedValue, targetType);
}
return toSourceMerge(localData, generator, obj, index, st,
return toSourceMerge(localData, generator, obj, coerced,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), propertyId),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ret_temp)));
} else {
if (obj instanceof AVM2Instruction && (((AVM2Instruction) obj).definition instanceof FindPropertyStrictIns) && index == null) {
if (obj instanceof AVM2Instruction && (((AVM2Instruction) obj).definition instanceof FindPropertyStrictIns)) {
return toSourceMerge(localData, generator, ins(new GetLexIns(), propertyId),
needsReturn ? null : ins(new PopIns())
);
}
return toSourceMerge(localData, generator, obj, index,
ins(new GetPropertyIns(), propertyId),
return toSourceMerge(localData, generator, obj, ins(new GetPropertyIns(), propertyId),
needsReturn ? null : ins(new PopIns())
);
}
@@ -603,11 +598,10 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
Reference<Integer> ret_temp = new Reference<>(-1);
Reference<Integer> obj_temp = new Reference<>(-1);
Reference<Integer> index_temp = new Reference<>(-1);
boolean isInteger = propType.getVal().equals("int");
List<GraphSourceItem> ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), index, index != null ? dupSetTemp(localData, generator, index_temp) : null,
List<GraphSourceItem> ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp),
//Start get original
//getTemp(localData, generator, obj_temp),
//index!=null?getTemp(localData, generator, index_temp):null,
@@ -618,12 +612,11 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
needsReturn ? ins(new DupIns()) : null,
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
setTemp(localData, generator, ret_temp),
getTemp(localData, generator, obj_temp),
index != null ? getTemp(localData, generator, index_temp) : null,
getTemp(localData, generator, obj_temp),
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), propertyId),
//needsReturn?getTemp(localData, generator, ret_temp):null,
killTemp(localData, generator, Arrays.asList(ret_temp, obj_temp, index_temp)));
killTemp(localData, generator, Arrays.asList(ret_temp, obj_temp)));
return ret;
}
@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns;
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.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
@@ -51,7 +52,6 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
private String name;
private GraphTargetItem index;
private int nsKind = -1;
public List<Integer> openedNamespaces;
public int line;
@@ -68,7 +68,6 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
UnresolvedAVM2Item c = new UnresolvedAVM2Item(subtypes, importedClasses, mustBeType, type, line, name, assignedValue, openedNamespaces);
//c.setNs(ns);
c.nsKind = nsKind;
c.setIndex(index);
c.resolved = resolved;
return c;
}
@@ -130,13 +129,6 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
}
public void setIndex(GraphTargetItem index) {
this.index = index;
}
public GraphTargetItem getIndex() {
return index;
}
public void setNsKind(int nsKind) {
this.nsKind = nsKind;
@@ -270,9 +262,6 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
@Override
public GraphTargetItem returnType() {
if (index != null) {
return TypeItem.UNBOUNDED;
}
if (type == null) {
return TypeItem.UNBOUNDED;
}
@@ -290,7 +279,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
throw new RuntimeException("Cannot assign");
}
public GraphTargetItem resolve(List<GraphTargetItem> paramTypes, List<String> paramNames, ABC abc, List<ABC> otherAbcs, List<MethodBody> callStack, List<AssignableAVM2Item> variables) throws CompilationException {
public GraphTargetItem resolve(GraphTargetItem thisType,List<GraphTargetItem> paramTypes, List<String> paramNames, ABC abc, List<ABC> otherAbcs, List<MethodBody> callStack, List<AssignableAVM2Item> variables) throws CompilationException {
List<String> parts = new ArrayList<>();
if (name.contains(".")) {
String partsArr[] = name.split("\\.");
@@ -312,14 +301,12 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
ret.setRegNumber(n.getRegNumber());
resolved = ret;
for (int i = 1; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), null, abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (i == parts.size() - 1) {
((PropertyAVM2Item) resolved).index = index;
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == 1) {
ret.setIndex(index);
ret.setAssignedValue(assignedValue);
}
ret.setNs(n.getNs());
@@ -343,7 +330,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
continue;
}
UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, true, null, line, s, null, openedNamespaces);
su.resolve(paramTypes, paramNames, abc, otherAbcs, callStack, variables);
su.resolve(thisType,paramTypes, paramNames, abc, otherAbcs, callStack, variables);
if (!(su.resolved instanceof TypeItem)) {
throw new CompilationException("Not a type", line);
}
@@ -352,15 +339,11 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
resolved = ret;
for (int i = 1; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), null, abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (i == parts.size() - 1) {
((PropertyAVM2Item) resolved).index = index;
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == 1 && index != null) {
throw new CompilationException("Types do not have indices", line);
}
if (parts.size() == 1 && assignedValue != null) {
throw new CompilationException("Cannot assign type", line);
}
@@ -383,7 +366,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
TypeItem ret = new TypeItem(fname);
for (String s : subtypes) {
UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, true, null, line, s, null, openedNamespaces);
su.resolve(paramTypes, paramNames, abc, otherAbcs, callStack, variables);
su.resolve(thisType,paramTypes, paramNames, abc, otherAbcs, callStack, variables);
if (!(su.resolved instanceof TypeItem)) {
throw new CompilationException("Not a type", line);
}
@@ -392,15 +375,11 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
resolved = ret;
for (int j = i + 1; j < parts.size(); j++) {
resolved = new PropertyAVM2Item(resolved, parts.get(j), null, abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
resolved = new PropertyAVM2Item(resolved, parts.get(j), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (j == parts.size() - 1) {
((PropertyAVM2Item) resolved).index = index;
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == i + 1 && index != null) {
throw new CompilationException("Types do not have indices", line);
}
}
if (parts.size() == i + 1 && assignedValue != null) {
throw new CompilationException("Cannot assign type", line);
}
@@ -425,7 +404,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
TypeItem ret = new TypeItem(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants));
for (String s : subtypes) {
UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, true, null, line, s, null, openedNamespaces);
su.resolve(paramTypes, paramNames, abc, otherAbcs, callStack, variables);
su.resolve(thisType,paramTypes, paramNames, abc, otherAbcs, callStack, variables);
if (!(su.resolved instanceof TypeItem)) {
throw new CompilationException("Not a type", line);
}
@@ -434,15 +413,11 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
resolved = ret;
for (int i = 1; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), null, abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (i == parts.size() - 1) {
((PropertyAVM2Item) resolved).index = index;
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == 1 && index != null) {
throw new CompilationException("Types do not have indices", line);
}
if (parts.size() == 1 && assignedValue != null) {
throw new CompilationException("Cannot assign type", line);
}
@@ -454,20 +429,37 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
}
if(parts.get(0).equals("this") ){
if(thisType == null){
throw new CompilationException("Cannot use this in that context", line);
}
GraphTargetItem ret = new NameAVM2Item(thisType, line, parts.get(0), null, false, openedNamespaces);
resolved = ret;
for (int i = 1; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (i == parts.size() - 1) {
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == 1) {
((NameAVM2Item) ret).setAssignedValue(assignedValue);
}
return ret;
}
if (paramNames.contains(parts.get(0)) || parts.get(0).equals("arguments")) {
int ind = paramNames.indexOf(parts.get(0));
GraphTargetItem ret = new NameAVM2Item(ind == -1 ? TypeItem.UNBOUNDED : paramTypes.get(ind), line, parts.get(0), null, false, openedNamespaces);
resolved = ret;
for (int i = 1; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), null, abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<MethodBody>());
if (i == parts.size() - 1) {
((PropertyAVM2Item) resolved).index = index;
((PropertyAVM2Item) resolved).assignedValue = assignedValue;
}
}
if (parts.size() == 1) {
((NameAVM2Item) ret).setIndex(index);
((NameAVM2Item) ret).setAssignedValue(assignedValue);
}
return ret;
@@ -477,7 +469,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
TypeItem ret = new TypeItem("__AS3__.vec.Vector");
for (String s : subtypes) {
UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<String>(), importedClasses, true, null, line, s, null, openedNamespaces);
su.resolve(paramTypes, paramNames, abc, otherAbcs, callStack, variables);
su.resolve(thisType,paramTypes, paramNames, abc, otherAbcs, callStack, variables);
if (!(su.resolved instanceof TypeItem)) {
throw new CompilationException("Not a type", line);
}
@@ -494,7 +486,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
resolved = null;
GraphTargetItem ret = null;
for (int i = 0; i < parts.size(); i++) {
resolved = new PropertyAVM2Item(resolved, parts.get(i), (i == parts.size() - 1) ? index : null, abc, otherAbcs, openedNamespaces, callStack);
resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, callStack);
if (ret == null) {
((PropertyAVM2Item) resolved).scopeStack = scopeStack;
ret = resolved;
@@ -696,11 +696,13 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
setDecompiledEditMode(false);
reload();
} catch (ParseException ex) {
//ex.printStackTrace();
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
decompiledTextArea.gotoLine((int)ex.line);
} catch (CompilationException ex) {
//ex.printStackTrace();
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", "" + ex.line), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
decompiledTextArea.gotoLine((int)ex.line);
decompiledTextArea.gotoLine((int)ex.line);
} catch (IOException|InterruptedException ex) {
//ignore
}