Fixed: #2486 decompilation timeout on infinite loop

This commit is contained in:
Jindra Petřík
2025-07-17 22:42:32 +02:00
parent 415a10502c
commit b471b48ba7
18 changed files with 344 additions and 266 deletions

View File

@@ -242,7 +242,7 @@ auxiliary.show.customizer.message=<message>
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
<compilation-unit>
<package-root>src</package-root>
<classpath mode="compile">../../src;lib/LZMA.jar;lib/avi.jar;lib/cmykjpeg.jar;lib/ddsreader.jar;lib/gif.jar;lib/gnujpdf.jar;lib/jlayer-1.0.2.jar;lib/jpacker.jar;lib/nellymoser.jar;lib/sfntly.jar;lib/tga.jar;lib/ttf.jar;lib/vlcj-4.7.3.jar;lib/vlcj-natives-4.7.0.jar;lib/flashdebugger.jar;lib/jna-3.5.1.jar;lib/jna-platform-3.5.1.jar;lib/gifreader.jar;lib/miterstroke.jar;lib/decimal.jar;lib/flacomdoc.jar;lib/tomlj-1.1.1.jar</classpath>
<classpath mode="compile">../../src;lib/LZMA.jar;lib/avi.jar;lib/cmykjpeg.jar;lib/ddsreader.jar;lib/gif.jar;lib/gnujpdf.jar;lib/jlayer-1.0.2.jar;lib/jpacker.jar;lib/nellymoser.jar;lib/sfntly.jar;lib/tga.jar;lib/ttf.jar;lib/vlcj-4.7.3.jar;lib/vlcj-natives-4.7.0.jar;lib/flashdebugger.jar;lib/jna-3.5.1.jar;lib/jna-platform-3.5.1.jar;lib/gifreader.jar;lib/miterstroke.jar;lib/decimal.jar;lib/flacomdoc.jar;lib/tomlj-1.1.1.jar;lib/decimal.jar</classpath>
<built-to>build</built-to>
<built-to>reports</built-to>
<built-to>dist</built-to>
@@ -251,7 +251,7 @@ auxiliary.show.customizer.message=<message>
<compilation-unit>
<package-root>test</package-root>
<unit-tests/>
<classpath mode="compile">../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jl1.0.1.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;antlib/testng-6.8.jar;src</classpath>
<classpath mode="compile">../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jl1.0.1.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;antlib/testng-6.8.jar;src;../../lib/decimal.jar</classpath>
<source-level>1.8</source-level>
</compilation-unit>
</java-data>

View File

@@ -3652,6 +3652,13 @@ public class AVM2Code implements Cloneable {
cnt++;
}
}
if ((ins.definition instanceof LabelIns) || (ins.definition instanceof DebugLineIns)) {
ins.setIgnored(true, 0);
if (minChangedIp == -1 || minChangedIp > i) {
minChangedIp = i;
}
cnt++;
}
}
removeIgnored(body);
@@ -3660,6 +3667,25 @@ public class AVM2Code implements Cloneable {
return cnt;
}
/**
* Removes label and debugline instructions
* @param body Method body
* @return Number of removed instructions
* @throws InterruptedException
*/
public int removeLabelsAndDebugLine(MethodBody body) throws InterruptedException {
int cnt = 0;
for (int i = code.size() - 1; i >= 0; i--) {
AVM2Instruction ins = code.get(i);
if ((ins.definition instanceof LabelIns) || (ins.definition instanceof DebugLineIns)) {
ins.setIgnored(true, 0);
cnt++;
}
}
removeIgnored(body);
return cnt;
}
/**
* Replaces jumps to exit instructions (return, throw) with exit

View File

@@ -3263,39 +3263,5 @@ public class AVM2Graph extends Graph {
}
return ternar;
}
@Override
protected int checkIp(int ip) {
if (true) {
//return ip;
}
/*
Ignore label instructions
<pre>
locA:
label
locB:
pushbyte 1
=>
locAB:
pushbyte 1
</pre>
*/
while (ip < code.size()) {
GraphSourceItem ins = code.get(ip);
if (!(ins instanceof AVM2Instruction)) {
break;
}
AVM2Instruction ains = (AVM2Instruction) ins;
if (!(ains.definition instanceof LabelIns)) {
break;
}
ip++;
}
return ip;
}
}
}

View File

@@ -631,6 +631,7 @@ public final class MethodBody implements Cloneable {
if (deobfuscate) {
try {
code.removeTraps(trait, method_info, body, abc, scriptIndex, classIndex, isStatic, path);
code.removeLabelsAndDebugLine(body);
} catch (ThreadDeath | InterruptedException ex) {
throw ex;
} catch (Throwable ex) {

View File

@@ -4125,6 +4125,9 @@ public class Graph {
}
GraphPart nextPart = part.nextParts.get(0);
if (nextPart == part) {
continue;
}
for (GraphPart r : part.refs) {
while (true) {

View File

@@ -17,32 +17,49 @@
package com.jpexs.decompiler.flash;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorGroupParts;
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorJumps;
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser;
import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.MissingSymbolHandler;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3Parser;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.Float4;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerAdapter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.ScopeStack;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeoutException;
import macromedia.asc.util.Decimal128;
import org.testng.Assert;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@@ -65,9 +82,98 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase {
Configuration.padAs3PCodeInstructionName.set(false);
Configuration.useOldStyleGetSetLocalsAs3PCode.set(false);
Configuration.labelOnSeparateLineAs3PCode.set(true);
Configuration.decompilationTimeoutSingleMethod.set(5);
swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/as3/as3.swf")), false);
}
private void decompilePCode(String pCode, String expected) throws Exception {
pCode = "code\r\n"
+ "getlocal0\r\n"
+ "pushscope\r\n"
+ pCode
+ "returnvoid\r\n";
final ABC abc = new ABC(new ABCContainerTag() {
@Override
public ABC getABC() {
return null;
}
@Override
public SWF getSwf() {
return swf;
}
@Override
public int compareTo(ABCContainerTag o) {
return 0;
}
@Override
public void setABC(ABC abc) {
}
});
MethodBody b = new MethodBody(abc, new Traits(), new byte[0], new ABCException[0]);
AVM2Code code = ASM3Parser.parse(abc, new StringReader(pCode), null, new MissingSymbolHandler() {
//no longer ask for adding new constants
@Override
public boolean missingString(String value) {
return true;
}
@Override
public boolean missingInt(long value) {
return true;
}
@Override
public boolean missingUInt(long value) {
return true;
}
@Override
public boolean missingDouble(double value) {
return true;
}
@Override
public boolean missingDecimal(Decimal128 value) {
return true;
}
@Override
public boolean missingFloat(float value) {
return true;
}
@Override
public boolean missingFloat4(Float4 value) {
return true;
}
}, b, new MethodInfo());
b.setCode(code);
abc.addMethodBody(b);
abc.addMethodInfo(new MethodInfo(new int[]{0}, 0, 0, 0, new ValueKind[0], new int[0]));
ClassInfo ci = new ClassInfo();
InstanceInfo ii = new InstanceInfo();
ii.name_index = abc.constants.addMultiname(
Multiname.createQName(
false,
abc.constants.getStringId("Test", true),
abc.constants.getNamespaceId(Namespace.KIND_PACKAGE, "", 0, true)
));
abc.addClass(ci, ii, 0);
ScriptInfo si = new ScriptInfo(new Traits());
abc.script_info.add(si);
code.removeTraps(null, 0, b, abc, 0, -1, true, pCode);
code.removeLabelsAndDebugLine(b);
HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false);
String actual = b.toSource(10, new ArrayList<>(), swf.getAbcIndex(), 0, new HashSet<>());
actual = actual.replace("\r\n", "\n");
assertEquals(actual, expected);
}
private String recompilePCode(String str, SWFDecompilerAdapter deobfuscator) throws IOException, AVM2ParseException, InterruptedException {
str = "code\r\n"
+ "getlocal0\r\n"
@@ -316,6 +422,158 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase {
+ "returnvoid\r\n");
}
@Test
public void testIgnoreLabels() throws Exception {
decompilePCode("getlocal1\n"
+ " setlocal2\n"
+ " pushfalse\n"
+ " setlocal3\n"
+ " pushbyte 0\n"
+ " convert_u\n"
+ " setlocal 4\n"
+ " jump ofs00a4\n"
+ " ofs000f:\n"
+ " label\n"
+ " jump ofs001d\n"
+ " ofs0014:\n"
+ " label\n"
+ " getlocal2\n"
+ " pushstring \"C\"\n"
+ " ifne ofs001d\n"
+ " ofs001c:\n"
+ " label\n" //this label critical to be removed
+ " ofs001d:\n"
+ " returnvoid\n"
+ " pushtrue\n"
+ " iftrue ofs0023\n"
+ " ofs0023:\n"
+ " label\n"
+ " getlocal0\n"
+ " getlocal1\n"
+ " callpropvoid QName(PackageNamespace(\"\"),\"trace\"), 1\n"
+ " jump ofs002d\n"
+ " ofs002d:\n"
+ " label\n"
+ " jump ofs000f\n"
+ " getlocal0\n"
+ " getproperty QName(PackageNamespace(\"\"),\"trace\")\n"
+ " getlocal1\n"
+ " callpropvoid QName(Namespace(\"http://adobe.com/AS3/2006/builtin\"),\"push\"), 1\n"
+ " jump ofs003d\n"
+ " ofs003d:\n"
+ " label\n"
+ " getlocal 4\n"
+ " increment\n"
+ " convert_u\n"
+ " setlocal 4\n"
+ " jump ofs0048\n"
+ " ofs0048:\n"
+ " label\n"
+ " jump ofs002d\n"
+ " label\n"
+ " getlocal1\n"
+ " getlocal0\n"
+ " getproperty QName(PackageNamespace(\"\"),\"xxx\")\n"
+ " getlocal 4\n"
+ " getproperty QName(PackageNamespace(\"\"),\"xxx\")\n"
+ " ifne ofs005c\n"
+ " ofs005c:\n"
+ " pushtrue\n"
+ " setlocal3\n"
+ " jump ofs0062\n"
+ " ofs0062:\n"
+ " label\n"
+ " jump ofs001c\n"
+ " ofs0067:\n"
+ " label\n"
+ " getlocal2\n"
+ " pushstring \"B\"\n"
+ " ifne ofs0014\n"
+ " pushbyte 0\n"
+ " convert_u\n"
+ " setlocal 4\n"
+ " jump ofs0048\n"
+ " ofs0078:\n"
+ " label\n"
+ " findproperty QName(PackageNamespace(\"\"),\"trace\")\n"
+ " getlocal1\n"
+ " callpropvoid QName(PackageNamespace(\"\"),\"trace\"), 1\n"
+ " jump ofs0062\n"
+ " ofs0083:\n"
+ " label\n"
+ " getlocal3\n"
+ " pushfalse\n"
+ " ifne ofs0062\n"
+ " jump ofs0078\n"
+ " label\n"
+ " getlocal 4\n"
+ " increment\n"
+ " convert_u\n"
+ " setlocal 4\n"
+ " jump ofs0099\n"
+ " ofs0099:\n"
+ " label\n"
+ " jump ofs0083\n"
+ " pushtrue\n"
+ " setlocal3\n"
+ " jump ofs00a4\n"
+ " ofs00a4:\n"
+ " getlocal2\n"
+ " pushstring \"A\"\n"
+ " ifne ofs0067\n"
+ " pushbyte 0\n"
+ " convert_u\n"
+ " setlocal 4\n"
+ " jump ofs0099\n", " var _loc2_:* = param1;\n"
+ " var _loc4_:uint = 0;\n"
+ " if(_loc2_ == \"A\")\n"
+ " {\n"
+ " _loc4_ = 0;\n"
+ " trace(param1);\n"
+ " }\n"
+ " else if(_loc2_ == \"B\")\n"
+ " {\n"
+ " _loc4_ = 0;\n"
+ " }\n"
+ " else if(_loc2_ == \"C\")\n"
+ " {\n"
+ " }\n");
}
@Test
public void testWhileTrue() throws Exception {
decompilePCode(
" getlex QName(PackageNamespace(\"\"),\"Math\")\n" +
" getlex QName(PackageNamespace(\"\"),\"Math\")\n" +
" debugline 8\n" +
" callproperty QName(PackageNamespace(\"\"),\"random\"), 0\n" +
" pushbyte 6\n" +
" multiply\n" +
" callproperty QName(PackageNamespace(\"\"),\"floor\"), 1\n" +
" convert_i\n" +
" setlocal1\n" +
" getlocal1\n" +
" debugline 10\n" +
" pushbyte 4\n" +
" ifngt ofs0034\n" +
" jump ofs0030\n" +
" ofs002d:\n" +
" label\n" +
" debugline 11\n" +
" ofs0030:\n" +
" jump ofs002d\n" +
" ofs0034:\n" +
" ", " param1 = Math.floor(Math.random() * 6);\n" +
" if(param1 <= 4)\n" +
" {\n" +
" return;\n" +
" }\n" +
" while(true)\n" +
" {\n" +
" }\n");
}
// TODO: JPEXS @Test
public void testNotRemoveParams() throws Exception {
String res = recompile("function tst(p1,p2){"

View File

@@ -284,29 +284,6 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
false);
}
@Test
public void testLabel() {
decompileMethod("assembled", "testLabel", "var _loc2_:String = param1.substr(0,1);\r\n"
+ "var _loc3_:Boolean = false;\r\n"
+ "var _loc4_:uint = 0;\r\n"
+ "if(_loc2_ == \"E\")\r\n"
+ "{\r\n"
+ "_loc4_ = 0;\r\n"
+ "if(_loc3_ == false)\r\n"
+ "{\r\n"
+ "trace(param1);\r\n"
+ "}\r\n"
+ "}\r\n"
+ "else if(_loc2_ == \"A\")\r\n"
+ "{\r\n"
+ "_loc4_ = 0;\r\n"
+ "}\r\n"
+ "else if(_loc2_ == \"L\")\r\n"
+ "{\r\n"
+ "}\r\n",
false);
}
@Test
public void testLocalRegIf() {
decompileMethod("assembled", "testLocalRegIf", "var _loc1_:int = 8;\r\n"
@@ -463,33 +440,33 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
+ "case 1:\r\n"
+ "case 6:\r\n"
+ "trace(\"1-6\");\r\n"
+ "addr0121:\r\n"
+ "addr0120:\r\n"
+ "trace(\"F\");\r\n"
+ "break;\r\n"
+ "case 5:\r\n"
+ "trace(\"5\");\r\n"
+ "addr011a:\r\n"
+ "addr0119:\r\n"
+ "trace(\"E\");\r\n"
+ "§§goto(addr0121);\r\n"
+ "§§goto(addr0120);\r\n"
+ "case 7:\r\n"
+ "trace(\"7\");\r\n"
+ "addr0113:\r\n"
+ "addr0112:\r\n"
+ "trace(\"D\");\r\n"
+ "§§goto(addr011a);\r\n"
+ "§§goto(addr0119);\r\n"
+ "case 2:\r\n"
+ "trace(\"2\");\r\n"
+ "addr010c:\r\n"
+ "addr010b:\r\n"
+ "trace(\"C\");\r\n"
+ "§§goto(addr0113);\r\n"
+ "§§goto(addr0112);\r\n"
+ "case 8:\r\n"
+ "trace(\"8\");\r\n"
+ "addr0105:\r\n"
+ "addr0104:\r\n"
+ "trace(\"B\");\r\n"
+ "§§goto(addr010c);\r\n"
+ "§§goto(addr010b);\r\n"
+ "default:\r\n"
+ "trace(\"def\");\r\n"
+ "trace(\"A\");\r\n"
+ "§§goto(addr0105);\r\n"
+ "§§goto(addr0104);\r\n"
+ "}\r\n"
+ "trace(\"G\");\r\n"
+ "return null;\r\n",

View File

@@ -425,8 +425,8 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
decompileMethod("classic_air", "testDefaultNotLastGrouped", "var k:int = 10;\r\n"
+ "switch(k)\r\n"
+ "{\r\n"
+ "case \"six\":\r\n"
+ "default:\r\n"
+ "case \"six\":\r\n"
+ "trace(\"def and 6\");\r\n"
+ "case \"five\":\r\n"
+ "trace(\"def and 6 and 5\");\r\n"
@@ -2423,6 +2423,19 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
false);
}
@Test
public void testWhileTrue() {
decompileMethod("classic_air", "testWhileTrue", "var a:int = Math.floor(Math.random() * 6);\r\n"
+ "if(a <= 4)\r\n"
+ "{\r\n"
+ "return;\r\n"
+ "}\r\n"
+ "while(true)\r\n"
+ "{\r\n"
+ "}\r\n",
false);
}
@Test
public void testWhileTry() {
decompileMethod("classic_air", "testWhileTry", "while(true)\r\n"

View File

@@ -2416,6 +2416,18 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
false);
}
@Test
public void testWhileTrue() {
decompileMethod("classic", "testWhileTrue", "var a:int = Math.floor(Math.random() * 6);\r\n"
+ "if(a > 4)\r\n"
+ "{\r\n"
+ "while(true)\r\n"
+ "{\r\n"
+ "}\r\n"
+ "}\r\n",
false);
}
@Test
public void testWhileTry() {
decompileMethod("classic", "testWhileTry", "while(true)\r\n"

View File

@@ -39,6 +39,5 @@ program
#include "tests/TestGoto2.script.asasm"
#include "tests/TestAlwaysBreak.script.asasm"
#include "tests/TestAlwaysBreak2.script.asasm"
#include "tests/TestLabel.script.asasm"
; place to add next
end ; program

View File

@@ -1,165 +0,0 @@
class
refid "tests:TestLabel"
instance QName(PackageNamespace("tests"), "TestLabel")
extends QName(PackageNamespace(""), "Object")
flag SEALED
flag PROTECTEDNS
protectedns ProtectedNamespace("tests:TestLabel")
iinit
refid "tests:TestLabel/instance/init"
body
maxstack 1
localcount 1
initscopedepth 4
maxscopedepth 5
code
getlocal0
pushscope
getlocal0
constructsuper 0
returnvoid
end ; code
end ; body
end ; method
trait method QName(PackageNamespace(""), "run")
method
param QName(PackageNamespace(""),"String")
refid "tests:TestLabel/instance/run"
returns QName(PackageNamespace(""), "void")
body
maxstack 2
localcount 4
initscopedepth 4
maxscopedepth 5
code
getlocal0
pushscope
getlocal1
pushbyte 0
pushbyte 1
callproperty QName(Namespace("http://adobe.com/AS3/2006/builtin"),"substr"), 2
coerce_s
setlocal2
pushfalse
setlocal3
pushbyte 0
convert_u
setlocal 4
jump ofs00aa
ofs0017:
label
jump ofs0025
ofs001c:
label
getlocal2
pushstring "L"
ifne ofs0025
ofs0024:
label
ofs0025:
returnvoid
pushtrue
iftrue ofs002b
ofs002b:
label
getlocal0
getlocal1
callpropvoid QName(PrivateNamespace(""),"_-9m"), 1
jump ofs0035
ofs0035:
label
jump ofs0017
getlocal0
getproperty QName(PackageNamespace(""),"_-J0")
getlocal1
callpropvoid QName(Namespace("http://adobe.com/AS3/2006/builtin"),"push"), 1
jump ofs0045
ofs0045:
label
getlocal 4
increment
convert_u
setlocal 4
jump ofs0050
ofs0050:
label
jump ofs0035
label
getlocal1
getlocal0
getproperty QName(PackageNamespace(""),"_-J0")
getlocal 4
getproperty MultinameL([PrivateNamespace("","1"),PackageNamespace(""),PrivateNamespace("","2"),PackageInternalNs(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("flash.display"),PackageNamespace("flash.events"),PackageNamespace("flash.system"),PackageNamespace("flash.text"),PackageNamespace("_-Pz"),PackageNamespace("com.newgrounds"),PackageNamespace("Playtomic"),PackageNamespace("flash.net"),PackageNamespace("flash.xml"),PackageNamespace("_-P2"),ProtectedNamespace("Main"),StaticProtectedNs("Main"),StaticProtectedNs("flash.display:MovieClip"),StaticProtectedNs("flash.display:Sprite"),StaticProtectedNs("flash.display:DisplayObjectContainer"),StaticProtectedNs("flash.display:InteractiveObject"),StaticProtectedNs("flash.display:DisplayObject"),StaticProtectedNs("flash.events:EventDispatcher"),StaticProtectedNs("Object")])
ifne ofs0062
ofs0062:
pushtrue
setlocal3
jump ofs0068
ofs0068:
label
jump ofs0024
ofs006d:
label
getlocal2
pushstring "A"
ifne ofs001c
pushbyte 0
convert_u
setlocal 4
jump ofs0050
ofs007e:
label
findproperty QName(PackageNamespace(""),"trace")
getlocal1
callpropvoid QName(PackageNamespace(""),"trace"), 1
jump ofs0068
ofs0089:
label
getlocal3
pushfalse
ifne ofs0068
jump ofs007e
label
getlocal 4
increment
convert_u
setlocal 4
jump ofs009f
ofs009f:
label
jump ofs0089
pushtrue
setlocal3
jump ofs00aa
ofs00aa:
getlocal2
pushstring "E"
ifne ofs006d
pushbyte 0
convert_u
setlocal 4
jump ofs009f
returnvoid
end ; code
end ; body
end ; method
end ; trait
end ; instance
cinit
refid "tests:TestLabel/class/init"
body
maxstack 1
localcount 1
initscopedepth 3
maxscopedepth 4
code
getlocal0
pushscope
returnvoid
end ; code
end ; body
end ; method
end ; class

View File

@@ -1,29 +0,0 @@
script
sinit
refid "tests:TestLabel/init"
body
maxstack 2
localcount 1
initscopedepth 1
maxscopedepth 3
code
getlocal0
pushscope
findpropstrict Multiname("TestLabel", [PackageNamespace("tests")])
getlex QName(PackageNamespace(""), "Object")
pushscope
getlex Multiname("Object", [PrivateNamespace(null, "tests:TestLabel"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")])
newclass "tests:TestLabel"
popscope
initproperty QName(PackageNamespace("tests"), "TestLabel")
returnvoid
end ; code
end ; body
end ; method
trait class QName(PackageNamespace("tests"), "TestLabel")
#include "TestLabel.class.asasm"
end ; trait
end ; script

View File

@@ -140,6 +140,7 @@ package
TestWhileContinue;
TestWhileDoWhile;
TestWhileSwitch;
TestWhileTrue;
TestWhileTry;
TestWhileTry2;
TestXml;

View File

@@ -0,0 +1,16 @@
package tests
{
public class TestWhileTrue
{
public function run():*
{
var a:int = Math.floor(Math.random( ) * 6);
if (a > 4) {
while(true) {
}
}
}
}
}