mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-26 23:05:34 +00:00
Fixed AS3 Debugging - activation object was not visible in locals
This commit is contained in:
@@ -225,7 +225,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
if (bodyIndex != -1 && (isSimple || traitIndices.isEmpty())) {
|
||||
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
|
||||
writer.startTrait(GraphTextWriter.TRAIT_SCRIPT_INITIALIZER);
|
||||
writer.startMethod(script_init);
|
||||
writer.startMethod(script_init, null);
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
@@ -398,8 +398,10 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
Map<Integer, Map<Integer, Integer>> bodyLineToPos = new HashMap<>();
|
||||
Map<Integer, Map<Integer, String>> bodyToRegToName = new HashMap<>();
|
||||
Map<Integer, Map<Integer, Integer>> bodyToRegToLine = new HashMap<>();
|
||||
|
||||
Map<Integer, Integer> bodyToActivationReg = new HashMap<>();
|
||||
Set<Integer> lonelyBody = new HashSet<>();
|
||||
Map<Integer, Integer> bodyLines = new HashMap<>();
|
||||
Map<Integer, String> bodyToFunctionName = new HashMap<>();
|
||||
try {
|
||||
HighlightedText decompiled = SWF.getCached(this);
|
||||
int line = 1;
|
||||
@@ -437,6 +439,14 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
if (bodyIndex == -1) {
|
||||
break blk;
|
||||
}
|
||||
if (!bodyLines.containsKey(bodyIndex)) {
|
||||
bodyLines.put(bodyIndex, line);
|
||||
}
|
||||
if (!bodyToFunctionName.containsKey(bodyIndex)) {
|
||||
bodyToFunctionName.put(bodyIndex, method.getProperties().localName);
|
||||
}
|
||||
|
||||
bodyToActivationReg.put(bodyIndex, method.getProperties().activationRegIndex);
|
||||
int pos = -1;
|
||||
int regIndex = -1;
|
||||
String regName = null;
|
||||
@@ -550,21 +560,34 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
delIns.add(ins);
|
||||
}
|
||||
}
|
||||
List<Object> code2 = new ArrayList<>();
|
||||
|
||||
int dpos = 0;
|
||||
b.insertInstruction(0, new AVM2Instruction(0, AVM2Instructions.DebugFile, new int[]{abc.constants.getStringId(filename, true)}), true);
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.DebugFile, new int[]{abc.constants.getStringId(filename, true)}));
|
||||
dpos++;
|
||||
Set<Integer> regs = bodyToRegToName.containsKey(bodyIndex) ? bodyToRegToName.get(bodyIndex).keySet() : new TreeSet<>();
|
||||
for (int r : regs) {
|
||||
String name = bodyToRegToName.get(bodyIndex).get(r);
|
||||
int line = bodyToRegToLine.get(bodyIndex).get(r);
|
||||
b.insertInstruction(dpos++, new AVM2Instruction(0, AVM2Instructions.Debug, new int[]{1, abc.constants.getStringId(name, true), r - 1, line}));
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.Debug, new int[]{1, abc.constants.getStringId(name, true), r - 1, line}));
|
||||
}
|
||||
int activationReg = -1;
|
||||
if (bodyToActivationReg.containsKey(bodyIndex)) {
|
||||
activationReg = bodyToActivationReg.get(bodyIndex);
|
||||
}
|
||||
if (activationReg > -1) {
|
||||
int bodyLine = bodyLines.containsKey(bodyIndex) ? bodyLines.get(bodyIndex) : 0;
|
||||
String activationRegName = "anonymous$0";
|
||||
if (bodyToFunctionName.containsKey(bodyIndex) && bodyToFunctionName.get(bodyIndex) != null) {
|
||||
activationRegName = bodyToFunctionName.get(bodyIndex) + "$0";
|
||||
}
|
||||
code2.add(new AVM2Instruction(0, AVM2Instructions.Debug, new int[]{1, abc.constants.getStringId(activationRegName, true), activationReg - 1, bodyLine}));
|
||||
}
|
||||
List<Integer> pos = new ArrayList<>(bodyToPosToLine.get(bodyIndex).keySet());
|
||||
Collections.sort(pos);
|
||||
Collections.reverse(pos);
|
||||
Set<Integer> addedLines = new HashSet<>();
|
||||
Set<Long> importantOffsets = b.getCode().getImportantOffsets(b, true);
|
||||
List<Object> code2 = new ArrayList<>();
|
||||
Map<Integer, Integer> origPosToNewPos = new HashMap<>();
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
long adr = b.getCode().pos2adr(i);
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.StoreNewActivationAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -73,6 +74,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
localData.localRegAssignmentIps.put(regId, localData.localRegAssignmentIps.get(regId) + 1);
|
||||
//localRegsAssignmentIps.put(regId, ip);
|
||||
if (value.getThroughDuplicate() instanceof NewActivationAVM2Item) {
|
||||
output.add(new StoreNewActivationAVM2Item(ins, localData.lineStartInstruction, regId));
|
||||
return;
|
||||
}
|
||||
if (value instanceof FindPropertyAVM2Item) {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class NewFunctionAVM2Item extends AVM2Item {
|
||||
}
|
||||
MethodBody body = abc.findBody(methodIndex);
|
||||
writer.append("function");
|
||||
writer.startMethod(methodIndex);
|
||||
writer.startMethod(methodIndex, null);
|
||||
writer.append((!functionName.isEmpty() ? " " + functionName : ""));
|
||||
writer.appendNoHilight("(");
|
||||
abc.method_info.get(methodIndex).getParamStr(writer, abc.constants, body, abc, localData.fullyQualifiedNames);
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2023 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightData;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
|
||||
/**
|
||||
* Store new Activation object. This exists just for the purpose of passing
|
||||
* activation register to the GraphTextWriter to correctly be read
|
||||
* by debug info injector.
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class StoreNewActivationAVM2Item extends AVM2Item {
|
||||
|
||||
public int regIndex;
|
||||
|
||||
public StoreNewActivationAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
this.regIndex = regIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsNewLine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
HighlightData hd = new HighlightData();
|
||||
hd.activationRegIndex = regIndex;
|
||||
writer.addCurrentMethodData(hd);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
int bodyIndex = abc.findBodyIndex(classInfo.cinit_index);
|
||||
if (bodyIndex != -1) {
|
||||
writer.startTrait(GraphTextWriter.TRAIT_CLASS_INITIALIZER);
|
||||
writer.startMethod(classInfo.cinit_index);
|
||||
writer.startMethod(classInfo.cinit_index, "cinit");
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!classInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
@@ -218,7 +218,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
|
||||
writer.newLine();
|
||||
writer.startTrait(GraphTextWriter.TRAIT_INSTANCE_INITIALIZER);
|
||||
writer.startMethod(instanceInfo.iinit_index);
|
||||
writer.startMethod(instanceInfo.iinit_index, "iinit");
|
||||
writer.appendNoHilight(modifier);
|
||||
writer.appendNoHilight("function ");
|
||||
writer.appendNoHilight(m.getName(abc.constants, null/*do not want full names here*/, false, true));
|
||||
|
||||
@@ -86,7 +86,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
|
||||
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
getMetaData(parent, convertData, abc, writer);
|
||||
writer.startMethod(method_info);
|
||||
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
|
||||
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
|
||||
|
||||
writer.startBlock();
|
||||
@@ -108,7 +108,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
|
||||
fullyQualifiedNames = new ArrayList<>();
|
||||
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writer.startMethod(method_info);
|
||||
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
|
||||
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
if (bodyIndex != -1) {
|
||||
|
||||
@@ -108,7 +108,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
if (classIndex < 0) {
|
||||
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
}
|
||||
writer.startMethod(method_info);
|
||||
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
|
||||
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
|
||||
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
@@ -136,7 +136,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
}
|
||||
getMetaData(parent, convertData, abc, writer);
|
||||
writer.startMethod(method_info);
|
||||
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
|
||||
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
|
||||
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
|
||||
@@ -119,7 +119,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
|
||||
AssignedValue assignment = convertData.assignedValues.get(this);
|
||||
writer.startTrait(assignment.initializer);
|
||||
writer.startMethod(assignment.method);
|
||||
writer.startMethod(assignment.method, null);
|
||||
if (Configuration.showMethodBodyId.get()) {
|
||||
writer.appendNoHilight("// method body index: ");
|
||||
writer.appendNoHilight(abc.findBodyIndex(assignment.method));
|
||||
|
||||
@@ -75,9 +75,10 @@ public abstract class GraphTextWriter {
|
||||
* Highlights specified text as method
|
||||
*
|
||||
* @param index MethodInfo index
|
||||
* @param name
|
||||
* @return GraphTextWriter
|
||||
*/
|
||||
public GraphTextWriter startMethod(long index) {
|
||||
public GraphTextWriter startMethod(long index, String name) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -250,4 +251,8 @@ public abstract class GraphTextWriter {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public GraphTextWriter addCurrentMethodData(HighlightData data) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,9 +116,10 @@ public class HighlightedTextWriter extends GraphTextWriter {
|
||||
* @return HighlightedTextWriter
|
||||
*/
|
||||
@Override
|
||||
public HighlightedTextWriter startMethod(long index) {
|
||||
public HighlightedTextWriter startMethod(long index, String name) {
|
||||
HighlightData data = new HighlightData();
|
||||
data.index = index;
|
||||
data.localName = name;
|
||||
return start(data, HighlightType.METHOD);
|
||||
}
|
||||
|
||||
@@ -309,7 +310,7 @@ public class HighlightedTextWriter extends GraphTextWriter {
|
||||
private HighlightedTextWriter start(HighlightData data, HighlightType type) {
|
||||
if (hilight) {
|
||||
Highlighting h = new Highlighting(sb.length() - newLineCount, data, type, null);
|
||||
hilightStack.add(h);
|
||||
hilightStack.add(h);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -377,4 +378,16 @@ public class HighlightedTextWriter extends GraphTextWriter {
|
||||
appendNoHilight(formatting.indentString);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter addCurrentMethodData(HighlightData data) {
|
||||
for (int i = hilightStack.size() - 1; i >= 0; i--) {
|
||||
Highlighting h = hilightStack.get(i);
|
||||
if (h.type == HighlightType.METHOD) {
|
||||
h.getProperties().merge(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ public class HighlightData implements Cloneable, Serializable {
|
||||
public int regIndex = -1;
|
||||
|
||||
public int namespaceIndex = -1;
|
||||
|
||||
public int activationRegIndex = -1;
|
||||
|
||||
public boolean isStatic = false;
|
||||
|
||||
@@ -60,7 +62,8 @@ public class HighlightData implements Cloneable, Serializable {
|
||||
&& fileOffset == -1
|
||||
&& namespaceIndex == -1
|
||||
&& propertyType == null
|
||||
&& propertySubType == null;
|
||||
&& propertySubType == null
|
||||
&& activationRegIndex == -1;
|
||||
}
|
||||
|
||||
public void merge(HighlightData data) {
|
||||
@@ -109,6 +112,9 @@ public class HighlightData implements Cloneable, Serializable {
|
||||
if (data.propertySubType != null) {
|
||||
propertySubType = data.propertySubType;
|
||||
}
|
||||
if (data.activationRegIndex != -1) {
|
||||
activationRegIndex = data.activationRegIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user