我有这个奇怪的问题,这段代码:
private function initLevel():void { var levelMap:Array = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ]; for (var y:* in levelMap) { for (var x:* in levelMap[y]) { trace(y, x); trace(levelMap[y, x]); } } }
在flashdevelop中产生这个丑陋的怪物:
typecheck Level/initLevel() outer-scope = [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ flash.display::MovieClip$ Level$] [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {} () 0:debugfile "L:\svntest\flashgame\src;com\thom\TD;Level.as" [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {} () 2:debugline 66 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {} () 4:getlocal0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {} (Level[O]) 5:pushscope [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 6:pushundefined [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (void[A]) 7:coerce_a [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (*[A]) 8:setlocal2 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 9:pushundefined [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (void[A]) 10:coerce_a [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (*[A]) 11:setlocal3 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 12:debug [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 17:debug [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 22:debugline 69 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} () 24:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I]) 26:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I]) 28:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I]) 30:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I]) 32:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I]) 34:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I]) 36:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 38:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 40:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 42:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 44:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 46:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 48:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 50:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 52:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 54:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 56:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 58:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 60:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 62:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 64:newarray 20 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O]) 66:debugline 70 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O]) 68:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I]) 70:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I]) 72:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I]) 74:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I]) 76:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I]) 78:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I]) 80:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 82:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 84:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 86:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 88:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 90:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 92:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 94:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 96:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 98:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 100:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 102:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 104:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 106:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...10: int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 108:newarray 20 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O]) 110:debugline 71 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O]) 112:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I]) 114:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I]) 116:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I]) 118:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I]) 120:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I]) 122:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I]) 124:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 126:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 128:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 130:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 132:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 134:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 136:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 138:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 140:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 142:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 144:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 146:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 148:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...10: Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 150:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...11: int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 152:newarray 20 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O]) 154:debugline 72 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O]) 156:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I]) 158:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I]) 160:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I]) 162:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I]) 164:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I]) 166:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I]) 168:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 170:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 172:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 174:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 176:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 178:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 180:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 182:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 184:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 186:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 188:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 190:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...10: Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 192:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...11: Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 194:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...12: int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 196:newarray 20 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O]) 198:debugline 73 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O]) 200:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I]) 202:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I]) 204:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I]) 206:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I]) 208:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I]) 210:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I]) 212:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 214:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 216:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 218:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 220:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 222:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 224:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 226:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 228:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 230:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (Array[O] Array[O] Array[O] Array[O] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I] int[I]) 232:pushbyte 0 [Level[O] *[A] *[A] *[A] *[A] *[A] *[A] *[A]] {Level[O]} (...10: Array[O] //SIXTY THOUSAND CHAR SNIP 804:callproperty trace 1 [Level[O] Array[O] *[A] *[A] int[I] *[A] int[I] *[A]] {Level[O]} (global[O] *[A]) 807:pop [Level[O] Array[O] *[A] *[A] int[I] *[A] int[I] *[A]] {Level[O]} (global[O]) ------------------------------------ MERGE CURRENT 808: [Level[O] Array[O] *[A] *[A] int[I] *[A] int[I] *[A]] {Level[O]} (global[O]) MERGE TARGET B808: [Level[O] Array[O] *[A] *[A] int[I] *[A] int[I] *[A]] {Level[O]} () [Fault] exception, information=VerifyError: Error #1030: Stack depth is unbalanced. 1 != 0.
我认为它与范围或类似的东西有关,但我很难过.
在此先感谢您的帮助
AI在之前的评论中说,我认为这是一个编译器错误,基于编译器生成非法字节码的简单事实,并且播放器能够捕获这个格式错误的字节码并相应地抛出VerifyError
.
然而,经过一些调查,我发现了一些有趣的事情.
首先,Joony的研究结果使我走上正轨.显然,正如他的代码所示,您可以欺骗编译器将方括号之间的内容翻译为属性访问.
所以这:
foo[foo,'length']
相当于:
foo["length"]
这里有一个问题,但我会在一秒钟内解释一下.
你也可以调用方法,如下所示:
var foo:Array = []; foo[foo,'push'](1); trace(foo);
这将有效地推1
入foo
除了一些额外的技巧,你可以链接所有这些来获得这个讨厌的野兽:
var inner:Array = [10]; var outter:Array = [1,2,inner]; (inner[outter, 'pop']).call(null)[inner,'push'].call(null,20); trace(inner); trace(outter);
这相当于:
var inner:Array = [10]; var outter:Array = [1,2,inner]; outter.pop().push(20);
也就是说,我们inner
从中弹出outter
,然后推动20
它.
我开始注意到这里
inner[outter, 'pop']
inner
未使用.
实际上,您可以将其更改为:
null[outter,'pop']
甚至
(void)[outter,'pop']
并且编译器不会抱怨它(玩家也不会).我怀疑上面是有效的Actionscript sinitctically(在这种情况下编译器应该拒绝编译它),但我不是100%肯定.但是,这个未使用的对象是问题的根源.(以下需要一些关于闪存装配或任何其他基于堆栈的装配如何工作的基本知识,但我希望我能够解释它,以便可以在不假设过多的情况下理解它.)
我反汇编了这个actionscript代码生成的字节码:
var arr:Array = [10]; null[arr,'length'];
反汇编代码:
function private::initLevel():void /* disp_id 0*/ { // local_count=2 max_scope=1 max_stack=3 code_len=17 0 getlocal0 1 pushscope 2 pushbyte 10 4 newarray [1] 6 coerce Array 8 setlocal1 9 pushnull 10 getlocal1 11 pushstring "length" 13 getproperty null 15 pop 16 returnvoid }
我们一步一步走吧.instr
是指令的偏移量; stack_state
执行指令后显示堆栈的当前状态; comments
是不言自明的;)
instr stack_state comments ------------------------------------------------------------------------------------------- 0 this "this" is always passed in local register 0 to instance methods 1 "this" is added to the scope chain and popped 2 10 now, we have 10 on the stack 4 [10] an array is created and initialized taking 1 element from the stack 6 [10] this is sort of like doing [10] as Array 8 the array is assigned to local variable 1 9 null null is pushed. That is the null in this line: null[arr,'length'] HERE BEGINS THE PROBLEM! 10 null,local1 local 1 is pushed 11 null,local1,"length" the string constant "length" is pushed 13 null,local1["length"] getproperty null is used for dynamic lookup (object["prop"]). Both operands are popped from the stack 15 null in the previous step, the result of local1["lengtht"] was pushed. But we dind't use it, so it's discarded 16 null here the method returns. The stack should be empty, but it's not. The generated code should have popped the null pushed at #9, or it shouldn't have pushed it in the first place
问题是在离开方法之后,应该弹出通过该方法推入堆栈的所有对象.情况并非如此,因为null
在方法返回后,常量仍保留在堆栈中.换句话说,我们有一个不平衡的堆栈.现在,玩家显然不介意或不检查.我认为它应该,并且不应该运行此代码,因为如果它变得足够大,这可能(至少可能)导致堆栈溢出.
现在,如果我们将有问题的代码部分更改为包含在跳转块中(例如在条件跳转之后到达的块if
),则播放器将使用以下消息拒绝代码:
VerifyError: Error #1030: Stack depth is unbalanced. 1 != 0.
与OP相同.因此,似乎分支的存在会触发对播放器中的堆栈完整性的某种检查.此时,应该注意的是,Actionscript循环(任何类型的循环)在字节码级别实现为条件跳转,就像一个ìf
.所以,即使我们在下面的代码中没有循环(if
产生更短且更易于分析的代码),因为它会在播放器中触发此检查,出于我们的目的,它与循环相同,如同OP做到了.
在AS代码中:
var dummy:int = 1; var arr:Array = [10]; if(dummy != 0) { null[arr,'length']; }
拆解:
function private::initLevel():void /* disp_id 0*/ { // local_count=3 max_scope=1 max_stack=3 code_len=27 0 getlocal0 1 pushscope 2 pushbyte 1 4 setlocal1 5 pushbyte 10 7 newarray [1] 9 coerce Array 11 setlocal2 12 getlocal1 13 pushbyte 0 15 ifeq L1 19 pushnull 20 getlocal2 21 pushstring "length" 23 getproperty null 25 pop L1: 26 returnvoid }
一步步:
instr stack_state comments ------------------------------------------------------------------------------------------- 0 this "this" is always passed in local register 0 to instance methods 1 "this" is added to the scope chain and popped 2 1 now, we have 1 on the stack 4 1 is popped and assigned to the local variable 1 (the dummy var in the code) 5 10 10 is pushed 7 [10] an array is created and initialized taking 1 element from the stack 9 [10] this is sort of like doing [10] as Array 11 the array is assigned to local variable 2 (the arr var in the code) 12 local1 local1 (dummy) is pushed 13 local1,0 0 is pushed 15 this instruction consumes (pops) both local1 and 0 to compare them If this condition is satisfied, it jumps to the label L1 If it is not, it falls-through to the next instruction (the same as a case label in a switch statement that does not have a break, in Actionscript code) 19 null null is pushed. That is the null in this line: null[arr,'length'] Again, HERE BEGINS THE PROBLEM! 20 null,local2 local2 is pushed 21 null,local2,"length" the string constant "length" is pushed 23 null,local2["length"] getproperty null is used for dynamic lookup (object["prop"]). Both operands are popped from the stack 25 null the value returned by local2["length"] is discarded 26 null the method returns, but null is not properly popped from the stack!
因此,null
在方法返回后,仍然在堆栈中; 堆栈是不平衡的.但这一次,玩家检查这个,发现问题,抛出VerifyError
并中止代码.
无论如何,要结束它,我的结论是:编译器在两种情况下都会生成非法的字节码.我认为这是一个错误.如果能够检测到该代码,则播放器会拒绝该代码.但是,如果有问题的代码在跳转块内(它看起来像一个bug),它似乎只能检测到它.
附录:
Joony在评论中提到"如果你在跳跃之前立即返回那么没有错误".这是真的.原因是if中但返回后的代码是"死代码",因此编译器将其从字节码中剥离.
因此,跳跃本身并不是导致玩家检查堆栈完整性的原因.我google了一下,在haxe网站上发现了这个.
这是堆栈不平衡错误.这意味着Jump的两个分支在返回时会产生不同的堆栈大小.导致给定位置的所有跳转或代码应该导致相同的堆栈大小.
这让事情变得更加清晰.
在上面的第二个代码示例中,这就是实际发生的事情.
如果代码遵循指令15处的跳转,则它直接落在最后一条指令(26)上以返回到调用者.null
没有被推,堆栈上没有别的东西,所以我们到达这一点的堆栈大小为0.
如果代码没有跳转和掉落,null
则会被推(19)而不会弹出.因此,此路径将到达null
堆栈上的最后一条指令(26),这意味着堆栈大小为1.最后一条指令是两个分支连接的点,但是在一个分支之后,堆栈大小为0,同时遵循另一方面,它是1.这就是导致玩家抱怨不平衡堆栈的原因.