From 931635a7b53bb0b24891ca179931c1e3ec3e6d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sun, 20 Apr 2014 13:00:24 +0200 Subject: [PATCH] AS3 direct editation - indices, various bugfixes --- .../parser/script/AVM2SourceGenerator.java | 37 ++-- .../parser/script/ActionScriptParser.java | 102 ++++++----- .../abc/avm2/parser/script/CallAVM2Item.java | 8 +- .../abc/avm2/parser/script/IndexAVM2Item.java | 162 ++++++++++++++++++ .../parser/script/NamespacedAVM2Item.java | 20 +-- .../avm2/parser/script/PropertyAVM2Item.java | 29 ++-- .../parser/script/UnresolvedAVM2Item.java | 72 ++++---- .../decompiler/flash/gui/abc/ABCPanel.java | 4 +- 8 files changed, 303 insertions(+), 131 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index ba783b27a..600e410c9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -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(), localData.callStack)); + localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abc, allABCs, new ArrayList(), 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 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 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(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); + String fullClass = localData.currentClass==null?null:(localData.pkg.equals("")?localData.currentClass:localData.pkg+"."+localData.currentClass); + type = ((UnresolvedAVM2Item) type).resolve(new TypeItem(fullClass),new ArrayList(), new ArrayList(), abc, allABCs, new ArrayList(), new ArrayList()); } 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 openedNamespaces, SourceGeneratorLocalData localData) { if (custom != null) { - PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, null, abc, allABCs, openedNamespaces, new ArrayList()); + PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList()); Reference value = new Reference<>(null); prop.resolve(localData, new Reference(""), new Reference(""), new Reference(0), value); namespace = value.getVal().value_index; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index 0ca6083c7..be98993e5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -185,38 +185,47 @@ public class ActionScriptParser { private GraphTargetItem member(Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List 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(), 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(), 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()); + } 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()); - } - 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(false), importedClasses, openedNamespaces, new HashMap(), false, false, true, isStatic||isConst?sinitVariables:constrVariables); + value = expression(new Reference(false), importedClasses, openedNamespaces, new HashMap(), false, false, true, isStatic || isConst ? sinitVariables : constrVariables); s = lex(); } GraphTargetItem tar; @@ -767,7 +789,7 @@ public class ActionScriptParser { List indices = new ArrayList<>(); List names = new ArrayList<>(); List namespaces = new ArrayList<>(); - AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())), abc), indices, names, namespaces); + AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())), 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(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); + ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), 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(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); + ui.resolve(null, new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), variables); } catch (CompilationException ex) { //ignore } @@ -1528,7 +1550,7 @@ public class ActionScriptParser { private GraphTargetItem expressionRemainder(Reference needsActivation, List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, ParseException { GraphTargetItem ret = null; ParsedSymbol s = lex(); - + if (ret == null) { switch (s.type) { case AS: diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java index 70043f2e8..ddad04c06 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java @@ -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()); + PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList()); 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()); + PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList()); 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]) ); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java new file mode 100644 index 000000000..e9c600f5c --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java @@ -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 . + */ + +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 openedNamespaces; + public GraphTargetItem object; + public GraphTargetItem index; + public boolean attr; + + public IndexAVM2Item(boolean attr,GraphTargetItem object, GraphTargetItem index, GraphTargetItem storeValue,List 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 toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) throws CompilationException { + Reference obj_temp=new Reference<>(-1); + Reference index_temp=new Reference<>(-1); + Reference 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()), 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 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()), true); + Reference 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 toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSource(localData, generator, true); + } + + @Override + public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSource(localData, generator, false); + } + + + + + +} diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java index 274329508..b0bca8805 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java @@ -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 openedNamespaces; - public NamespacedAVM2Item(GraphTargetItem index, GraphTargetItem ns, String name, GraphTargetItem obj, boolean attr, List openedNamespaces, GraphTargetItem storeValue) { + public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem obj, boolean attr, List 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 ns_temp = new Reference<>(-1); Reference name_temp = new Reference<>(-1); Reference 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()), 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()), 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()), 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()), 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()), 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()), 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()), 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()), 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()), 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()), true)), needsReturn ? null : ins(new PopIns()), killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp)) ); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java index bbf98e4ee..539af5799 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java @@ -60,23 +60,21 @@ public class PropertyAVM2Item extends AssignableAVM2Item { public GraphTargetItem object; public ABC abc; public List otherABCs; - public GraphTargetItem index; private List openedNamespaces; private List callStack; public List scopeStack = new ArrayList(); @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 otherABCs, List openedNamespaces, List callStack) { + public PropertyAVM2Item(GraphTargetItem object, String propertyName, ABC abc, List otherABCs, List openedNamespaces, List 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 objType = new Reference<>(""); Reference propType = new Reference<>(""); Reference 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 ret_temp = new Reference<>(-1); Reference obj_temp = new Reference<>(-1); - Reference index_temp = new Reference<>(-1); boolean isInteger = propType.getVal().equals("int"); - List ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), index, index != null ? dupSetTemp(localData, generator, index_temp) : null, + List 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; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index 5a5fd8bae..71648451c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -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 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 paramTypes, List paramNames, ABC abc, List otherAbcs, List callStack, List variables) throws CompilationException { + public GraphTargetItem resolve(GraphTargetItem thisType,List paramTypes, List paramNames, ABC abc, List otherAbcs, List callStack, List variables) throws CompilationException { List 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()); + resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList()); 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(), 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()); + resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList()); 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(), 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()); + resolved = new PropertyAVM2Item(resolved, parts.get(j), abc, otherAbcs, openedNamespaces, new ArrayList()); 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(), 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()); + resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList()); 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()); + 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()); + resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList()); 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(), 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; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 975278141..8d591d2c5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -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 }