From 730868a996880c4db4cce03551e27b453ecb0e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 30 Sep 2023 18:00:18 +0200 Subject: [PATCH] Fixed Float/Float4 ABC format support --- CHANGELOG.md | 1 + .../com/jpexs/decompiler/flash/abc/ABC.java | 2 +- .../decompiler/flash/abc/avm2/AVM2Code.java | 2 +- .../flash/abc/types/MethodInfo.java | 26 +++---- .../decompiler/flash/abc/types/ValueKind.java | 67 +++++++++++++------ .../abc/types/traits/TraitSlotConst.java | 6 +- .../flash/gui/abc/ABCExplorerDialog.java | 41 +++++++++--- .../flash/gui/abc/ASMSourceEditorPane.java | 2 +- 8 files changed, 96 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fa726772..07c13a63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ All notable changes to this project will be documented in this file. - AS3 Nullpointer on getting multiname which is out of bounds - Exceptions on cancelling file loading - Switching between openables on session load and on view type change +- Float/Float4 ABC format support ### Changed - [#2070] String values inside SWF to XML export are backslash escaped diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index e0c00d473..6b91ab904 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -1137,7 +1137,7 @@ public class ABC implements Openable { output = new Utf8PrintWriter(os); constants.dump(output); for (int i = 0; i < method_info.size(); i++) { - output.println("MethodInfo[" + i + "]:" + method_info.get(i).toString(constants, new ArrayList<>())); + output.println("MethodInfo[" + i + "]:" + method_info.get(i).toString(this, new ArrayList<>())); } for (int i = 0; i < metadata_info.size(); i++) { output.println("MetadataInfo[" + i + "]:" + metadata_info.get(i).toString(constants)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 7564b10e7..c3b24cf6c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1204,7 +1204,7 @@ public class AVM2Code implements Cloneable { } writer.newLine(); - info.toASMSource(constants, writer); + info.toASMSource(abc, writer); } writer.newLine(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java index 57d8e560d..4e848bc25 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java @@ -253,7 +253,7 @@ public class MethodInfo { return ret.toString(); } - public String toString(AVM2ConstantPool constants, List fullyQualifiedNames) { + public String toString(ABC abc, List fullyQualifiedNames) { StringBuilder optionalStr = new StringBuilder(); optionalStr.append("["); if (optional != null) { @@ -261,7 +261,7 @@ public class MethodInfo { if (i > 0) { optionalStr.append(","); } - optionalStr.append(optional[i].toString(constants)); + optionalStr.append(optional[i].toString(abc)); } } optionalStr.append("]"); @@ -274,7 +274,7 @@ public class MethodInfo { if (param_types[i] == 0) { param_typesStr.append("*"); } else { - param_typesStr.append(constants.getMultiname(param_types[i]).toString(constants, fullyQualifiedNames)); + param_typesStr.append(abc.constants.getMultiname(param_types[i]).toString(abc.constants, fullyQualifiedNames)); } } @@ -283,17 +283,17 @@ public class MethodInfo { if (i > 0) { paramNamesStr.append(","); } - paramNamesStr.append(constants.getString(paramNames[i])); + paramNamesStr.append(abc.constants.getString(paramNames[i])); } String ret_typeStr; if (ret_type == 0) { ret_typeStr = "*"; } else { - ret_typeStr = constants.getMultiname(ret_type).toString(constants, fullyQualifiedNames); + ret_typeStr = abc.constants.getMultiname(ret_type).toString(abc.constants, fullyQualifiedNames); } - return "param_types=" + param_typesStr + " ret_type=" + ret_typeStr + " name=\"" + constants.getString(name_index) + "\" flags=" + flags + " optional=" + optionalStr + " paramNames=" + paramNamesStr; + return "param_types=" + param_typesStr + " ret_type=" + ret_typeStr + " name=\"" + abc.constants.getString(name_index) + "\" flags=" + flags + " optional=" + optionalStr + " paramNames=" + paramNamesStr; } public String getName(AVM2ConstantPool constants) { @@ -346,7 +346,7 @@ public class MethodInfo { if (i >= param_types.length - optional.length) { int optionalIndex = i - (param_types.length - optional.length); writer.appendNoHilight(" = "); - writer.hilightSpecial(optional[optionalIndex].toString(constants), HighlightSpecialType.OPTIONAL, optionalIndex); + writer.hilightSpecial(optional[optionalIndex].toString(abc), HighlightSpecialType.OPTIONAL, optionalIndex); } } } @@ -400,9 +400,9 @@ public class MethodInfo { return rname; } - public void toASMSource(AVM2ConstantPool constants, GraphTextWriter writer) { + public void toASMSource(ABC abc, GraphTextWriter writer) { writer.appendNoHilight("name "); - writer.hilightSpecial(name_index == 0 ? "null" : "\"" + Helper.escapeActionScriptString(getName(constants)) + "\"", HighlightSpecialType.METHOD_NAME); + writer.hilightSpecial(name_index == 0 ? "null" : "\"" + Helper.escapeActionScriptString(getName(abc.constants)) + "\"", HighlightSpecialType.METHOD_NAME); writer.newLine(); if (flagNative()) { writer.appendNoHilight("flag "); @@ -446,7 +446,7 @@ public class MethodInfo { } for (int p = 0; p < param_types.length; p++) { writer.appendNoHilight("param "); - writer.hilightSpecial(constants.multinameToString(param_types[p]), HighlightSpecialType.PARAM, p); + writer.hilightSpecial(abc.constants.multinameToString(param_types[p]), HighlightSpecialType.PARAM, p); writer.newLine(); } if (flagHas_paramnames()) { @@ -456,7 +456,7 @@ public class MethodInfo { writer.appendNoHilight("null"); } else { writer.appendNoHilight("\""); - writer.appendNoHilight(constants.getString(n)); + writer.appendNoHilight(abc.constants.getString(n)); writer.appendNoHilight("\""); } writer.newLine(); @@ -466,12 +466,12 @@ public class MethodInfo { for (int i = 0; i < optional.length; i++) { ValueKind vk = optional[i]; writer.appendNoHilight("optional "); - writer.hilightSpecial(vk.toASMString(constants), HighlightSpecialType.OPTIONAL, i); + writer.hilightSpecial(vk.toASMString(abc), HighlightSpecialType.OPTIONAL, i); writer.newLine(); } } writer.appendNoHilight("returns "); - writer.hilightSpecial(constants.multinameToString(ret_type), HighlightSpecialType.RETURNS); + writer.hilightSpecial(abc.constants.multinameToString(ret_type), HighlightSpecialType.RETURNS); writer.newLine(); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ValueKind.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ValueKind.java index 91cbf941a..043ceedb5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ValueKind.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/ValueKind.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.types; +import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.helpers.Helper; @@ -60,9 +61,9 @@ public class ValueKind { public static final int CONSTANT_Float4 = 0x1E;// float4 - private static final int[] optionalKinds = new int[]{0x03, 0x04, 0x06, 0x02, 0x01, 0x0B, 0x0A, 0x0C, 0x00, 0x08, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x05}; + private static final int[] optionalKinds = new int[]{0x03, 0x04, 0x06, 0x02, 0x01, 0x0B, 0x0A, 0x0C, 0x00, 0x08, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x05, 0x1E}; - private static final String[] optionalKindNames = new String[]{"Int", "UInt", "Double", "Decimal", "Utf8", "True", "False", "Null", "Undefined", "Namespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs", "PrivateNamespace"}; + private static final String[] optionalKindNames = new String[]{"Int", "UInt", "Double", "Decimal/Float", "Utf8", "True", "False", "Null", "Undefined", "Namespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs", "PrivateNamespace", "Float4"}; public int value_index; @@ -128,23 +129,34 @@ public class ValueKind { } } - public String toString(AVM2ConstantPool constants) { + public String toString(ABC abc) { String ret = "?"; switch (value_kind) { case CONSTANT_Int: - ret = EcmaScript.toString(constants.getInt(value_index)); + ret = EcmaScript.toString(abc.constants.getInt(value_index)); break; case CONSTANT_UInt: - ret = EcmaScript.toString(constants.getUInt(value_index)); + ret = EcmaScript.toString(abc.constants.getUInt(value_index)); break; case CONSTANT_Double: - ret = EcmaScript.toString(constants.getDouble(value_index)); + ret = EcmaScript.toString(abc.constants.getDouble(value_index)); break; case CONSTANT_DecimalOrFloat: - ret = "" + constants.getDecimal(value_index); + if (abc.hasDecimalSupport()) { + ret = "" + abc.constants.getDecimal(value_index); + } else { + ret = "" + EcmaScript.toString(abc.constants.getFloat(value_index)); + } + break; + case CONSTANT_Float4: + Float4 f4 = abc.constants.getFloat4(value_index); + ret = "[" + EcmaScript.toString(f4.values[0]) + ", " + + EcmaScript.toString(f4.values[1]) + ", " + + EcmaScript.toString(f4.values[2]) + ", " + + EcmaScript.toString(f4.values[3]) + "]"; break; case CONSTANT_Utf8: - ret = "\"" + Helper.escapeActionScriptString(constants.getString(value_index)) + "\""; + ret = "\"" + Helper.escapeActionScriptString(abc.constants.getString(value_index)) + "\""; break; case CONSTANT_True: ret = "true"; @@ -158,35 +170,46 @@ public class ValueKind { case CONSTANT_Undefined: ret = "undefined"; break; - case CONSTANT_Namespace: + case CONSTANT_Namespace: case CONSTANT_PackageInternalNs: case CONSTANT_ProtectedNamespace: case CONSTANT_ExplicitNamespace: case CONSTANT_StaticProtectedNs: case CONSTANT_PrivateNs: - ret = "\"" + constants.getNamespace(value_index).getName(constants).toRawString() + "\""; //assume not null name + ret = "\"" + abc.constants.getNamespace(value_index).getName(abc.constants).toRawString() + "\""; //assume not null name break; } return ret; } - public String toASMString(AVM2ConstantPool constants) { + public String toASMString(ABC abc) { String ret = "?"; switch (value_kind) { case CONSTANT_Int: - ret = "Integer(" + constants.getInt(value_index) + ")"; + ret = "Integer(" + abc.constants.getInt(value_index) + ")"; break; case CONSTANT_UInt: - ret = "UInteger(" + constants.getUInt(value_index) + ")"; + ret = "UInteger(" + abc.constants.getUInt(value_index) + ")"; break; case CONSTANT_Double: - ret = "Double(" + EcmaScript.toString(constants.getDouble(value_index)) + ")"; + ret = "Double(" + EcmaScript.toString(abc.constants.getDouble(value_index)) + ")"; break; - case CONSTANT_DecimalOrFloat: - ret = "Decimal(" + constants.getDecimal(value_index) + ")"; + case CONSTANT_DecimalOrFloat: + if (abc.hasDecimalSupport()) { + ret = "Decimal(" + abc.constants.getDecimal(value_index) + ")"; + } else { + ret = "Float(" + EcmaScript.toString(abc.constants.getFloat(value_index)) + ")"; + } + break; + case CONSTANT_Float4: + Float4 f4 = abc.constants.getFloat4(value_index); + ret = "Float4(" + EcmaScript.toString(f4.values[0]) + ", " + + EcmaScript.toString(f4.values[1]) + ", " + + EcmaScript.toString(f4.values[2]) + ", " + + EcmaScript.toString(f4.values[3]) + ")"; break; case CONSTANT_Utf8: - ret = "Utf8(\"" + Helper.escapePCodeString(constants.getString(value_index)) + "\")"; + ret = "Utf8(\"" + Helper.escapePCodeString(abc.constants.getString(value_index)) + "\")"; break; case CONSTANT_True: ret = "True()"; @@ -200,16 +223,16 @@ public class ValueKind { case CONSTANT_Undefined: ret = "Undefined()"; //"Void()" is also synonym break; - case CONSTANT_Namespace: + case CONSTANT_Namespace: case CONSTANT_PackageInternalNs: case CONSTANT_ProtectedNamespace: case CONSTANT_ExplicitNamespace: case CONSTANT_StaticProtectedNs: - case CONSTANT_PrivateNs: - String nsVal = constants.getNamespace(value_index).getKindStr() + "(\"" + constants.getNamespace(value_index).getName(constants).toRawString() + "\")"; //assume not null name - + case CONSTANT_PrivateNs: + String nsVal = abc.constants.getNamespace(value_index).getKindStr() + "(\"" + abc.constants.getNamespace(value_index).getName(abc.constants).toRawString() + "\")"; //assume not null name + switch (value_kind) { - case CONSTANT_Namespace: + case CONSTANT_Namespace: ret = "Namespace(" + nsVal + ")"; break; case CONSTANT_PackageInternalNs: diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index 93982eefc..236f84082 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -77,7 +77,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { if (type_index > 0) { typeStr = abc.constants.getMultiname(type_index).toString(abc.constants, fullyQualifiedNames); } - return "0x" + Helper.formatAddress(fileOffset) + " " + Helper.byteArrToString(bytes) + " SlotConst " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " type=" + typeStr + " value=" + (new ValueKind(value_index, value_kind)).toString(abc.constants) + " metadata=" + Helper.intArrToString(metadata); + return "0x" + Helper.formatAddress(fileOffset) + " " + Helper.byteArrToString(bytes) + " SlotConst " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " type=" + typeStr + " value=" + (new ValueKind(value_index, value_kind)).toString(abc) + " metadata=" + Helper.intArrToString(metadata); } public String getType(AVM2ConstantPool constants, List fullyQualifiedNames) { @@ -150,7 +150,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { if (value_kind != 0) { ValueKind val = new ValueKind(value_index, value_kind); - writer.hilightSpecial(val.toString(abc.constants), HighlightSpecialType.TRAIT_VALUE); + writer.hilightSpecial(val.toString(abc), HighlightSpecialType.TRAIT_VALUE); } } @@ -265,7 +265,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { writer.newLine(); if (value_kind != ValueKind.CONSTANT_Undefined) { writer.appendNoHilight("value "); - writer.hilightSpecial((new ValueKind(value_index, value_kind).toASMString(abc.constants)), HighlightSpecialType.TRAIT_VALUE); + writer.hilightSpecial((new ValueKind(value_index, value_kind).toASMString(abc)), HighlightSpecialType.TRAIT_VALUE); writer.newLine(); } return writer; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java index 621564fe6..ba4c5e5e4 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCExplorerDialog.java @@ -1385,8 +1385,13 @@ public class ABCExplorerDialog extends AppDialog { return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_UINT, "value_index"); case ValueKind.CONSTANT_Double: return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_DOUBLE, "value_index"); - case ValueKind.CONSTANT_DecimalOrFloat: //?? or float ?? - return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_DECIMAL, "value_index"); + case ValueKind.CONSTANT_DecimalOrFloat: + if (abc.hasDecimalSupport()) { + return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_DECIMAL, "value_index"); + } + return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_FLOAT, "value_index"); + case ValueKind.CONSTANT_Float4: + return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_FLOAT_4, "value_index"); case ValueKind.CONSTANT_Utf8: return createValueWithIndex(parent, index, tsc.value_index, TreeType.CONSTANT_STRING, "value_index"); case ValueKind.CONSTANT_True: @@ -1410,8 +1415,13 @@ public class ABCExplorerDialog extends AppDialog { return new SimpleValue(parent, index, "value_kind", "UInteger", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_Double: return new SimpleValue(parent, index, "value_kind", "Double", TreeIcon.VALUE_KIND); - case ValueKind.CONSTANT_DecimalOrFloat: //?? or float ?? - return new SimpleValue(parent, index, "value_kind", "Decimal", TreeIcon.VALUE_KIND); + case ValueKind.CONSTANT_DecimalOrFloat: + if (abc.hasDecimalSupport()) { + return new SimpleValue(parent, index, "value_kind", "Decimal", TreeIcon.VALUE_KIND); + } + return new SimpleValue(parent, index, "value_kind", "Float", TreeIcon.VALUE_KIND); + case ValueKind.CONSTANT_Float4: + return new SimpleValue(parent, index, "value_kind", "Float4", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_Utf8: return new SimpleValue(parent, index, "value_kind", "String", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_True: @@ -1751,8 +1761,13 @@ public class ABCExplorerDialog extends AppDialog { return new SimpleValue(parent, index, "value_kind", "UInteger", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_Double: return new SimpleValue(parent, index, "value_kind", "Double", TreeIcon.VALUE_KIND); - case ValueKind.CONSTANT_DecimalOrFloat: //?? or float ?? - return new SimpleValue(parent, index, "value_kind", "Decimal", TreeIcon.VALUE_KIND); + case ValueKind.CONSTANT_DecimalOrFloat: + if (abc.hasDecimalSupport()) { + return new SimpleValue(parent, index, "value_kind", "Decimal", TreeIcon.VALUE_KIND); + } + return new SimpleValue(parent, index, "value_kind", "Float", TreeIcon.VALUE_KIND); + case ValueKind.CONSTANT_Float4: + return new SimpleValue(parent, index, "value_kind", "Float4", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_Utf8: return new SimpleValue(parent, index, "value_kind", "String", TreeIcon.VALUE_KIND); case ValueKind.CONSTANT_True: @@ -1786,8 +1801,13 @@ public class ABCExplorerDialog extends AppDialog { return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_UINT, "value_index"); case ValueKind.CONSTANT_Double: return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_DOUBLE, "value_index"); - case ValueKind.CONSTANT_DecimalOrFloat: //?? or float ?? - return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_DECIMAL, "value_index"); + case ValueKind.CONSTANT_DecimalOrFloat: + if (abc.hasDecimalSupport()) { + return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_DECIMAL, "value_index"); + } + return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_FLOAT, "value_index"); + case ValueKind.CONSTANT_Float4: + return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_FLOAT_4, "value_index"); case ValueKind.CONSTANT_Utf8: return createValueWithIndex(parent, index, value_index, TreeType.CONSTANT_STRING, "value_index"); case ValueKind.CONSTANT_True: @@ -1808,7 +1828,7 @@ public class ABCExplorerDialog extends AppDialog { } } } else { - return new SubValue(parent, index, index, mi, "optional", "op" + index, mi.optional[index].toASMString(abc.constants), TreeIcon.OPTIONAL_SUB); + return new SubValue(parent, index, index, mi, "optional", "op" + index, mi.optional[index].toASMString(abc), TreeIcon.OPTIONAL_SUB); } case "param_names": return createValueWithIndex(parent, index, mi.paramNames[index], TreeType.CONSTANT_STRING, "pn" + index); @@ -2019,7 +2039,8 @@ public class ABCExplorerDialog extends AppDialog { case ValueKind.CONSTANT_Int: case ValueKind.CONSTANT_UInt: case ValueKind.CONSTANT_Double: - case ValueKind.CONSTANT_DecimalOrFloat: //?? or float ?? + case ValueKind.CONSTANT_DecimalOrFloat: + case ValueKind.CONSTANT_Float4: case ValueKind.CONSTANT_Utf8: case ValueKind.CONSTANT_Namespace: case ValueKind.CONSTANT_PackageInternalNs: diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 9f0042fd5..6284d632a 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -138,7 +138,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi } writer.newLine(); - abc.method_info.get(methodIndex).toASMSource(abc.constants, writer); + abc.method_info.get(methodIndex).toASMSource(abc, writer); if (Configuration.indentAs3PCode.get()) { writer.unindent();