mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-22 15:35:33 +00:00
AS3 parser: XML filter
This commit is contained in:
@@ -70,7 +70,7 @@ public class AVM2Instruction implements Serializable, GraphSourceItem {
|
||||
case AVM2Code.OPT_S24:
|
||||
aos.writeS24(operands[i]);
|
||||
break;
|
||||
case AVM2Code.OPT_U30:
|
||||
case AVM2Code.OPT_U30:
|
||||
aos.writeU30(operands[i]);
|
||||
break;
|
||||
case AVM2Code.OPT_U8:
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
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.construction.ConstructIns;
|
||||
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;
|
||||
@@ -55,10 +56,12 @@ 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.PushStringIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushWithIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.xml.CheckFilterIns;
|
||||
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;
|
||||
@@ -262,6 +265,75 @@ public class AVM2SourceGenerator implements SourceGenerator {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, XMLFilterAVM2Item item) throws CompilationException {
|
||||
List<GraphSourceItem> ret = new ArrayList<>();
|
||||
final Reference<Integer> counterReg = new Reference<>(0);
|
||||
final Reference<Integer> collectionReg = new Reference<>(0);
|
||||
final Reference<Integer> xmlListReg = new Reference<>(0);
|
||||
List<GraphSourceItem> xmlListSetTemp = AssignableAVM2Item.setTemp(localData, this, xmlListReg);
|
||||
ret.addAll(GraphTargetItem.toSourceMerge(localData, this,
|
||||
ins(new PushByteIns(), 0),
|
||||
AssignableAVM2Item.setTemp(localData, this, counterReg),
|
||||
item.object,
|
||||
ins(new CheckFilterIns()),
|
||||
NameAVM2Item.generateCoerce(this, TypeItem.UNBOUNDED),
|
||||
AssignableAVM2Item.setTemp(localData, this, collectionReg),
|
||||
ins(new GetLexIns(),abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId("XMLList", true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<Integer>()), true)),
|
||||
ins(new PushStringIns(),abc.constants.getStringId("", true)),
|
||||
ins(new ConstructIns(),1),
|
||||
xmlListSetTemp
|
||||
));
|
||||
final Reference<Integer> tempVal1 = new Reference<>(0);
|
||||
final Reference<Integer> tempVal2 = new Reference<>(0);
|
||||
|
||||
List<AVM2Instruction> forBody = toInsList(GraphTargetItem.toSourceMerge(localData, this,
|
||||
ins(new LabelIns()),
|
||||
AssignableAVM2Item.getTemp(localData, this, collectionReg),
|
||||
AssignableAVM2Item.getTemp(localData, this, counterReg),
|
||||
ins(new NextValueIns()),
|
||||
AssignableAVM2Item.dupSetTemp(localData, this, tempVal1),
|
||||
AssignableAVM2Item.dupSetTemp(localData, this, tempVal2),
|
||||
ins(new PushWithIns())
|
||||
));
|
||||
localData.scopeStack.add(new LocalRegAVM2Item(null, tempVal2.getVal(), null));
|
||||
forBody.addAll(toInsList(item.value.toSource(localData, this)));
|
||||
List<AVM2Instruction> trueBody = new ArrayList<>();
|
||||
trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, xmlListReg)));
|
||||
trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, counterReg)));
|
||||
trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempVal1)));
|
||||
int nss[] = new int[item.openedNamespaces.size()];
|
||||
for(int i=0;i<item.openedNamespaces.size();i++){
|
||||
nss[i] = item.openedNamespaces.get(i);
|
||||
}
|
||||
trueBody.add(ins(new SetPropertyIns(),abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList<Integer>()), true)));
|
||||
forBody.add(ins(new IfFalseIns(),insToBytes(trueBody).length));
|
||||
forBody.addAll(trueBody);
|
||||
forBody.add(ins(new PopScopeIns()));
|
||||
localData.scopeStack.remove(localData.scopeStack.size()-1);
|
||||
forBody.addAll(toInsList(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(tempVal2,tempVal1))));
|
||||
|
||||
|
||||
|
||||
int forBodyLen = insToBytes(forBody).length;
|
||||
AVM2Instruction forwardJump = ins(new JumpIns(), forBodyLen);
|
||||
ret.add(forwardJump);
|
||||
|
||||
List<AVM2Instruction> expr = new ArrayList<>();
|
||||
expr.add(ins(new HasNext2Ins(), collectionReg.getVal(), counterReg.getVal()));
|
||||
AVM2Instruction backIf = ins(new IfTrueIns(), 0);
|
||||
expr.add(backIf);
|
||||
|
||||
int exprLen = insToBytes(expr).length;
|
||||
backIf.operands[0] = -(exprLen + forBodyLen);
|
||||
|
||||
ret.addAll(forBody);
|
||||
ret.addAll(expr);
|
||||
ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(collectionReg, counterReg)));
|
||||
ret.addAll(AssignableAVM2Item.getTemp(localData, this, xmlListReg));
|
||||
ret.addAll(AssignableAVM2Item.killTemp(localData, this, Arrays.asList(xmlListReg)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, IfItem item) throws CompilationException {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -121,7 +121,7 @@ import java.util.logging.Logger;
|
||||
public class ActionScriptParser {
|
||||
|
||||
private long uniqLast = 0;
|
||||
private final boolean debugMode = true;
|
||||
private final boolean debugMode = false;
|
||||
private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin";
|
||||
|
||||
private ABC abc;
|
||||
@@ -202,8 +202,13 @@ public class ActionScriptParser {
|
||||
|
||||
private GraphTargetItem name(Reference<Boolean> needsActivation, boolean typeOnly, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables, List<String> importedClasses) throws IOException, ParseException {
|
||||
ParsedSymbol s = lex();
|
||||
String name = "";
|
||||
if(s.type == SymbolType.ATTRIBUTE){
|
||||
name += "@";
|
||||
s = lex();
|
||||
}
|
||||
expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP);
|
||||
String name = s.value.toString();
|
||||
name += s.value.toString();
|
||||
s = lex();
|
||||
while (s.type == SymbolType.DOT) {
|
||||
s = lex();
|
||||
@@ -1440,6 +1445,12 @@ public class ActionScriptParser {
|
||||
GraphTargetItem ret = null;
|
||||
ParsedSymbol s = lex();
|
||||
switch (s.type) {
|
||||
case FILTER:
|
||||
needsActivation.setVal(true);
|
||||
ret = new XMLFilterAVM2Item(expr,expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables), openedNamespaces);
|
||||
expectedType(SymbolType.PARENT_CLOSE);
|
||||
allowRemainder = true;
|
||||
break;
|
||||
case NAMESPACE_OP:
|
||||
s = lex();
|
||||
if (s.type == SymbolType.BRACKET_OPEN) {
|
||||
@@ -1885,6 +1896,7 @@ public class ActionScriptParser {
|
||||
case IDENTIFIER:
|
||||
case THIS:
|
||||
case SUPER:
|
||||
case ATTRIBUTE:
|
||||
lexer.pushback(s);
|
||||
GraphTargetItem var = name(needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses);
|
||||
var = memberOrCall(needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables);
|
||||
|
||||
@@ -200,5 +200,6 @@ public enum SymbolType {
|
||||
XML_ATTRVALVAR_BEGIN, // aaa={
|
||||
XML_INSTRATTRNAMEVAR_BEGIN, // {...}=
|
||||
XML_INSTRATTRVALVAR_BEGIN, // aaa={
|
||||
XML_INSTRVARTAG_BEGIN // <?{
|
||||
XML_INSTRVARTAG_BEGIN, // <?{
|
||||
FILTER
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.avm2.model.AVM2Item;
|
||||
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 com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class XMLFilterAVM2Item extends AVM2Item
|
||||
{
|
||||
|
||||
public List<Integer> openedNamespaces;
|
||||
public GraphTargetItem object;
|
||||
public XMLFilterAVM2Item(GraphTargetItem object, GraphTargetItem value,List<Integer> openedNamespaces) {
|
||||
super(null, NOPRECEDENCE);
|
||||
this.value = value;
|
||||
this.openedNamespaces = openedNamespaces;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return new TypeItem("String");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return ((AVM2SourceGenerator)generator).generate(localData, this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -313,6 +313,7 @@ SingleCharacter = [^\r\n\'\\]
|
||||
"typeof" { return new ParsedSymbol(SymbolGroup.OPERATOR,SymbolType.TYPEOF,yytext()); }
|
||||
"void" { return new ParsedSymbol(SymbolGroup.OPERATOR,SymbolType.VOID,yytext()); }
|
||||
"@" { return new ParsedSymbol(SymbolGroup.OPERATOR,SymbolType.ATTRIBUTE,yytext()); }
|
||||
".(" { return new ParsedSymbol(SymbolGroup.OPERATOR,SymbolType.FILTER,yytext()); }
|
||||
|
||||
/* string literal */
|
||||
\" {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
TODO List for AS3 parser/compiler:
|
||||
------------------------------
|
||||
- XML filter - .(
|
||||
- default xml namespace
|
||||
Reference in New Issue
Block a user