as3code.ml 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. (*
  2. * This file is part of SwfLib
  3. * Copyright (c)2004-2006 Nicolas Cannasse
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *)
  19. open IO
  20. open As3
  21. let s = Printf.sprintf
  22. let f_int_length : (int -> int) ref = ref (fun _ -> assert false)
  23. let f_int_read : (IO.input -> int) ref = ref (fun _ -> assert false)
  24. let f_int_write : (unit IO.output -> int -> unit) ref = ref (fun _ _ -> assert false)
  25. let int_length i = (!f_int_length) i
  26. let read_int ch = (!f_int_read) ch
  27. let write_int (ch : 'a IO.output) i = (!f_int_write) (Obj.magic ch) i
  28. let int_index (x : 'a index) : int = Obj.magic x
  29. let index_int (x : int) : 'a index = Obj.magic x
  30. let int_index_nz (x : 'a index_nz) : int = Obj.magic x
  31. let index_nz_int (x : int) : 'a index_nz = Obj.magic x
  32. let read_index ch = index_int (read_int ch)
  33. let write_index ch i = write_int ch (int_index i)
  34. let read_index_nz ch = index_nz_int (read_int ch)
  35. let write_index_nz ch i = write_int ch (int_index_nz i)
  36. let iget (t : 'a array) (i : 'a index) : 'a =
  37. t.(Obj.magic i - 1)
  38. let write_signed_byte = write_byte
  39. let max_i24 = 1 lsl 23 - 1
  40. let read_i24 ch =
  41. let a = read_byte ch in
  42. let b = read_byte ch in
  43. let c = read_byte ch in
  44. let n = a lor (b lsl 8) lor (c lsl 16) in
  45. if c land 128 <> 0 then
  46. n - (1 lsl 24)
  47. else
  48. n
  49. let rec write_i24 ch n =
  50. if n < -max_i24 || n > max_i24 then assert false;
  51. let n = (if n land (1 lsl 23) <> 0 then n + (1 lsl 24) else n) in
  52. write_byte ch n;
  53. write_byte ch (n lsr 8);
  54. write_byte ch (n lsr 16)
  55. let ops , ops_ids =
  56. let h = Hashtbl.create 0 in
  57. let h2 = Hashtbl.create 0 in
  58. List.iter (fun (o,b) -> Hashtbl.add h b o; Hashtbl.add h2 o b)
  59. [
  60. A3OAs, 0x87;
  61. A3ONeg, 0x90;
  62. A3OIncr, 0x91;
  63. (* 0x92 : REGINCR *)
  64. A3ODecr, 0x93;
  65. (* 0x94 : REGDECR *)
  66. (* 0x95 : TYPEOF *)
  67. A3ONot, 0x96;
  68. A3OBitNot, 0x97;
  69. A3OAdd, 0xA0;
  70. A3OSub, 0xA1;
  71. A3OMul, 0xA2;
  72. A3ODiv, 0xA3;
  73. A3OMod, 0xA4;
  74. A3OShl, 0xA5;
  75. A3OShr, 0xA6;
  76. A3OUShr, 0xA7;
  77. A3OAnd, 0xA8;
  78. A3OOr, 0xA9;
  79. A3OXor, 0xAA;
  80. A3OEq, 0xAB;
  81. A3OPhysEq, 0xAC;
  82. A3OLt, 0xAD;
  83. A3OLte, 0xAE;
  84. A3OGt, 0xAF;
  85. A3OGte, 0xB0;
  86. A3OIs, 0xB3;
  87. A3OIn, 0xB4;
  88. A3OIIncr, 0xC0;
  89. A3OIDecr, 0xC1;
  90. A3OINeg, 0xC4;
  91. A3OIAdd, 0xC5;
  92. A3OISub, 0xC6;
  93. A3OIMul, 0xC7;
  94. A3OMemGet8, 0x35;
  95. A3OMemGet16, 0x36;
  96. A3OMemGet32, 0x37;
  97. A3OMemGetFloat, 0x38;
  98. A3OMemGetDouble, 0x39;
  99. A3OMemSet8, 0x3A;
  100. A3OMemSet16, 0x3B;
  101. A3OMemSet32, 0x3C;
  102. A3OMemSetFloat, 0x3D;
  103. A3OMemSetDouble, 0x3E;
  104. A3OSign1, 0x50;
  105. A3OSign8, 0x51;
  106. A3OSign16, 0x52;
  107. ];
  108. h , h2
  109. let length = function
  110. | A3SmallInt _ -> 2
  111. | A3Construct n
  112. | A3Object n
  113. | A3RegKill n
  114. | A3Catch n
  115. | A3IncrReg n
  116. | A3DecrReg n
  117. | A3IncrIReg n
  118. | A3DecrIReg n
  119. | A3Array n
  120. | A3Int n
  121. | A3CallStack n
  122. | A3ConstructSuper n
  123. | A3BreakPointLine n
  124. | A3ApplyType n
  125. | A3DebugLine n ->
  126. 1 + int_length n
  127. | A3GetSlot s
  128. | A3SetSlot s ->
  129. 1 + int_length s
  130. | A3ClassDef n ->
  131. 1 + int_length (int_index_nz n)
  132. | A3DxNs f
  133. | A3String f
  134. | A3DebugFile f ->
  135. 1 + int_length (int_index f)
  136. | A3IntRef f ->
  137. 1 + int_length (int_index f)
  138. | A3UIntRef f ->
  139. 1 + int_length (int_index f)
  140. | A3Float f ->
  141. 1 + int_length (int_index f)
  142. | A3Function f ->
  143. 1 + int_length (int_index_nz f)
  144. | A3Namespace f ->
  145. 1 + int_length (int_index f)
  146. | A3GetProp f
  147. | A3InitProp f
  148. | A3DeleteProp f
  149. | A3FindPropStrict f
  150. | A3FindProp f
  151. | A3FindDefinition f
  152. | A3GetLex f
  153. | A3SetProp f
  154. | A3Cast f
  155. | A3GetSuper f
  156. | A3GetDescendants f
  157. | A3SetSuper f ->
  158. 1 + int_length (int_index f)
  159. | A3Op _
  160. | A3Undefined
  161. | A3Null
  162. | A3True
  163. | A3False
  164. | A3NaN
  165. | A3RetVoid
  166. | A3Ret
  167. | A3Pop
  168. | A3Dup
  169. | A3Swap
  170. | A3AsAny
  171. | A3ToString
  172. | A3ToXml
  173. | A3ToXmlAttr
  174. | A3ToInt
  175. | A3ToUInt
  176. | A3ToNumber
  177. | A3ToBool
  178. | A3ToObject
  179. | A3AsString
  180. | A3AsObject
  181. | A3This
  182. | A3Throw
  183. | A3Nop
  184. | A3Typeof
  185. | A3InstanceOf
  186. | A3Scope
  187. | A3ForIn
  188. | A3NewBlock
  189. | A3ForEach
  190. | A3PopScope
  191. | A3CheckIsXml
  192. | A3Label
  193. | A3BreakPoint
  194. | A3PushWith
  195. | A3HasNext
  196. | A3SetThis
  197. | A3Timestamp
  198. | A3DxNsLate
  199. | A3Unk _ -> 1
  200. | A3AsType n | A3IsType n ->
  201. 1 + int_length (int_index n)
  202. | A3DebugReg (name,reg,line) -> 1 + 1 + int_length (int_index name) + 1 + int_length line
  203. | A3GetGlobalScope -> 1
  204. | A3GetScope n -> 1 + int_length n
  205. | A3Reg n | A3SetReg n -> if n >= 1 && n <= 3 then 1 else (1 + int_length n)
  206. | A3CallSuper (f,n) | A3CallProperty (f,n) | A3ConstructProperty (f,n) | A3CallPropLex (f,n) | A3CallPropVoid (f,n) | A3CallSuperVoid (f,n) ->
  207. 1 + int_length n + int_length (int_index f)
  208. | A3CallMethod (f,n) ->
  209. 1 + int_length n + int_length f
  210. | A3CallStatic (f,n) ->
  211. 1 + int_length n + int_length (int_index f)
  212. | A3Jump _ -> 4
  213. | A3Next (a,b) -> 1 + int_length a + int_length b
  214. | A3Switch (_,cases) ->
  215. let ncases = List.length cases in
  216. 1 + 3 + int_length (ncases - 1) + 3 * ncases
  217. let jump ch kind =
  218. A3Jump (kind,read_i24 ch)
  219. let opcode ch =
  220. let op = (try read_byte ch with IO.No_more_input -> raise Exit) in
  221. match op with
  222. | 0x01 -> A3BreakPoint
  223. | 0x02 -> A3Nop
  224. | 0x03 -> A3Throw
  225. | 0x04 -> A3GetSuper (read_index ch)
  226. | 0x05 -> A3SetSuper (read_index ch)
  227. | 0x06 -> A3DxNs (read_index ch)
  228. | 0x07 -> A3DxNsLate
  229. | 0x08 -> A3RegKill (read_int ch)
  230. | 0x09 -> A3Label
  231. (* 0x0A -> NONE *)
  232. (* 0x0B -> NONE *)
  233. | 0x0C -> jump ch J3NotLt
  234. | 0x0D -> jump ch J3NotLte
  235. | 0x0E -> jump ch J3NotGt
  236. | 0x0F -> jump ch J3NotGte
  237. | 0x10 -> jump ch J3Always
  238. | 0x11 -> jump ch J3True
  239. | 0x12 -> jump ch J3False
  240. | 0x13 -> jump ch J3Eq
  241. | 0x14 -> jump ch J3Neq
  242. | 0x15 -> jump ch J3Lt
  243. | 0x16 -> jump ch J3Lte
  244. | 0x17 -> jump ch J3Gt
  245. | 0x18 -> jump ch J3Gte
  246. | 0x19 -> jump ch J3PhysEq
  247. | 0x1A -> jump ch J3PhysNeq
  248. | 0x1B ->
  249. let def = read_i24 ch in
  250. let rec loop n =
  251. if n = 0 then
  252. []
  253. else
  254. let j = read_i24 ch in
  255. j :: loop (n - 1)
  256. in
  257. let cases = loop (read_int ch + 1) in
  258. A3Switch (def,cases)
  259. | 0x1C -> A3PushWith
  260. | 0x1D -> A3PopScope
  261. | 0x1E -> A3ForIn
  262. | 0x1F -> A3HasNext
  263. | 0x20 -> A3Null
  264. | 0x21 -> A3Undefined
  265. (* 0x22 -> NONE *)
  266. | 0x23 -> A3ForEach
  267. | 0x24 -> A3SmallInt (read_signed_byte ch)
  268. | 0x25 -> A3Int (read_int ch)
  269. | 0x26 -> A3True
  270. | 0x27 -> A3False
  271. | 0x28 -> A3NaN
  272. | 0x29 -> A3Pop
  273. | 0x2A -> A3Dup
  274. | 0x2B -> A3Swap
  275. | 0x2C -> A3String (read_index ch)
  276. | 0x2D -> A3IntRef (read_index ch)
  277. | 0x2E -> A3UIntRef (read_index ch)
  278. | 0x2F -> A3Float (read_index ch)
  279. | 0x30 -> A3Scope
  280. | 0x31 -> A3Namespace (read_index ch)
  281. | 0x32 ->
  282. let r1 = read_int ch in
  283. let r2 = read_int ch in
  284. A3Next (r1,r2)
  285. (* 0x33 - 0x3F -> NONE *)
  286. | 0x40 -> A3Function (read_index_nz ch)
  287. | 0x41 -> A3CallStack (read_int ch)
  288. | 0x42 -> A3Construct (read_int ch)
  289. | 0x43 ->
  290. let id = read_int ch in
  291. let nargs = read_int ch in
  292. A3CallMethod (id,nargs)
  293. | 0x44 ->
  294. let id = read_index ch in
  295. let nargs = read_int ch in
  296. A3CallStatic (id,nargs)
  297. | 0x45 ->
  298. let id = read_index ch in
  299. let nargs = read_int ch in
  300. A3CallSuper (id,nargs)
  301. | 0x46 ->
  302. let id = read_index ch in
  303. let nargs = read_int ch in
  304. A3CallProperty (id,nargs)
  305. | 0x47 -> A3RetVoid
  306. | 0x48 -> A3Ret
  307. | 0x49 -> A3ConstructSuper (read_int ch)
  308. | 0x4A ->
  309. let id = read_index ch in
  310. let nargs = read_int ch in
  311. A3ConstructProperty (id,nargs)
  312. (* 0x4B -> NONE *)
  313. | 0x4C ->
  314. let id = read_index ch in
  315. let nargs = read_int ch in
  316. A3CallPropLex (id,nargs)
  317. (* 0x4D -> NONE *)
  318. | 0x4E ->
  319. let id = read_index ch in
  320. let nargs = read_int ch in
  321. A3CallSuperVoid (id,nargs)
  322. | 0x4F ->
  323. let id = read_index ch in
  324. let nargs = read_int ch in
  325. A3CallPropVoid (id,nargs)
  326. (* 0x50 - 0x52 -> NONE *)
  327. | 0x53 -> A3ApplyType (read_int ch)
  328. (* 0x54 -> NONE *)
  329. | 0x55 -> A3Object (read_int ch)
  330. | 0x56 -> A3Array (read_int ch)
  331. | 0x57 -> A3NewBlock
  332. | 0x58 -> A3ClassDef (read_index_nz ch)
  333. | 0x59 -> A3GetDescendants (read_index ch)
  334. | 0x5A -> A3Catch (read_int ch)
  335. (* 0x5B -> NONE *)
  336. (* 0x5C -> NONE *)
  337. | 0x5D -> A3FindPropStrict (read_index ch)
  338. | 0x5E -> A3FindProp (read_index ch)
  339. | 0x5F -> A3FindDefinition (read_index ch)
  340. | 0x60 -> A3GetLex (read_index ch)
  341. | 0x61 -> A3SetProp (read_index ch)
  342. | 0x62 -> A3Reg (read_int ch)
  343. | 0x63 -> A3SetReg (read_int ch)
  344. | 0x64 -> A3GetGlobalScope
  345. | 0x65 -> A3GetScope (IO.read_byte ch)
  346. | 0x66 -> A3GetProp (read_index ch)
  347. (* 0x67 -> NONE *)
  348. | 0x68 -> A3InitProp (read_index ch)
  349. (* 0x69 -> NONE *)
  350. | 0x6A -> A3DeleteProp (read_index ch)
  351. (* 0x6B -> NONE *)
  352. | 0x6C -> A3GetSlot (read_int ch)
  353. | 0x6D -> A3SetSlot (read_int ch)
  354. (* 0x6E -> DEPRECATED getglobalslot *)
  355. (* 0x6F -> DEPRECATED setglobalslot *)
  356. | 0x70 -> A3ToString
  357. | 0x71 -> A3ToXml
  358. | 0x72 -> A3ToXmlAttr
  359. | 0x73 -> A3ToInt
  360. | 0x74 -> A3ToUInt
  361. | 0x75 -> A3ToNumber
  362. | 0x76 -> A3ToBool
  363. | 0x77 -> A3ToObject
  364. | 0x78 -> A3CheckIsXml
  365. (* 0x79 -> NONE *)
  366. | 0x80 -> A3Cast (read_index ch)
  367. (* 0x81 -> DEPRECATED asbool *)
  368. | 0x82 -> A3AsAny
  369. (* 0x83 -> DEPRECATED asint *)
  370. (* 0x84 -> DEPRECATED asnumber *)
  371. | 0x85 -> A3AsString
  372. | 0x86 -> A3AsType (read_index ch)
  373. (* 0x87 -> OP *)
  374. (* 0x88 -> DEPRECATED asuint *)
  375. | 0x89 -> A3AsObject
  376. (* 0x8A - 0x8F -> NONE *)
  377. (* 0x90 - 0x91 -> OP *)
  378. | 0x92 -> A3IncrReg (read_int ch)
  379. (* 0x93 -> OP *)
  380. | 0x94 -> A3DecrReg (read_int ch)
  381. | 0x95 -> A3Typeof
  382. (* 0x96 -> OP *)
  383. (* 0x97 -> OP *)
  384. (* 0x98 - 0x9F -> NONE *)
  385. (* 0xA0 - 0xB0 -> OP *)
  386. | 0xB1 -> A3InstanceOf
  387. | 0xB2 -> A3IsType (read_index ch)
  388. (* 0xB3 -> OP *)
  389. (* 0xB4 -> OP *)
  390. (* 0xB5 - 0xBF -> NONE *)
  391. (* 0xC0 -> OP *)
  392. (* 0xC1 -> OP *)
  393. | 0xC2 -> A3IncrIReg (read_int ch)
  394. | 0xC3 -> A3DecrIReg (read_int ch)
  395. (* 0xC4 - 0xC7 -> OP *)
  396. (* 0xC8 - 0xCF -> NONE *)
  397. | 0xD0 -> A3This
  398. | 0xD1 -> A3Reg 1
  399. | 0xD2 -> A3Reg 2
  400. | 0xD3 -> A3Reg 3
  401. | 0xD4 -> A3SetThis
  402. | 0xD5 -> A3SetReg 1
  403. | 0xD6 -> A3SetReg 2
  404. | 0xD7 -> A3SetReg 3
  405. (* 0xD8 - 0xEE -> NONE *)
  406. | 0xEF ->
  407. if IO.read_byte ch <> 1 then assert false;
  408. let name = read_index ch in
  409. let reg = read_byte ch + 1 in
  410. let line = read_int ch in
  411. A3DebugReg (name,reg,line)
  412. | 0xF0 -> A3DebugLine (read_int ch)
  413. | 0xF1 -> A3DebugFile (read_index ch)
  414. | 0xF2 -> A3BreakPointLine (read_int ch)
  415. | 0xF3 -> A3Timestamp
  416. (* 0xF4 - 0xFF -> NONE *)
  417. | _ ->
  418. try
  419. A3Op (Hashtbl.find ops op)
  420. with Not_found ->
  421. Printf.printf "Unknown opcode 0x%.2X\n" op;
  422. A3Unk (char_of_int op)
  423. let parse ch len =
  424. let data = nread_string ch len in
  425. let ch = input_string data in
  426. let a = MultiArray.create() in
  427. let rec loop() =
  428. MultiArray.add a (opcode ch);
  429. loop();
  430. in
  431. (try loop() with Exit -> ());
  432. a
  433. let write ch = function
  434. | A3BreakPoint ->
  435. write_byte ch 0x01
  436. | A3Nop ->
  437. write_byte ch 0x02
  438. | A3Throw ->
  439. write_byte ch 0x03
  440. | A3GetSuper f ->
  441. write_byte ch 0x04;
  442. write_index ch f
  443. | A3SetSuper f ->
  444. write_byte ch 0x05;
  445. write_index ch f
  446. | A3DxNs i ->
  447. write_byte ch 0x06;
  448. write_index ch i
  449. | A3DxNsLate ->
  450. write_byte ch 0x07
  451. | A3RegKill n ->
  452. write_byte ch 0x08;
  453. write_int ch n
  454. | A3Label ->
  455. write_byte ch 0x09
  456. | A3Jump (k,n) ->
  457. write_byte ch (match k with
  458. | J3NotLt -> 0x0C
  459. | J3NotLte -> 0x0D
  460. | J3NotGt -> 0x0E
  461. | J3NotGte -> 0x0F
  462. | J3Always -> 0x10
  463. | J3True -> 0x11
  464. | J3False -> 0x12
  465. | J3Eq -> 0x13
  466. | J3Neq -> 0x14
  467. | J3Lt -> 0x15
  468. | J3Lte -> 0x16
  469. | J3Gt -> 0x17
  470. | J3Gte -> 0x18
  471. | J3PhysEq -> 0x19
  472. | J3PhysNeq -> 0x1A
  473. );
  474. write_i24 ch n
  475. | A3Switch (def,cases) ->
  476. write_byte ch 0x1B;
  477. write_i24 ch def;
  478. write_int ch (List.length cases - 1);
  479. List.iter (write_i24 ch) cases
  480. | A3PushWith ->
  481. write_byte ch 0x1C
  482. | A3PopScope ->
  483. write_byte ch 0x1D
  484. | A3ForIn ->
  485. write_byte ch 0x1E
  486. | A3HasNext ->
  487. write_byte ch 0x1F
  488. | A3Null ->
  489. write_byte ch 0x20
  490. | A3Undefined ->
  491. write_byte ch 0x21
  492. | A3ForEach ->
  493. write_byte ch 0x23
  494. | A3SmallInt b ->
  495. write_byte ch 0x24;
  496. write_signed_byte ch b
  497. | A3Int i ->
  498. write_byte ch 0x25;
  499. write_int ch i
  500. | A3True ->
  501. write_byte ch 0x26
  502. | A3False ->
  503. write_byte ch 0x27
  504. | A3NaN ->
  505. write_byte ch 0x28
  506. | A3Pop ->
  507. write_byte ch 0x29
  508. | A3Dup ->
  509. write_byte ch 0x2A
  510. | A3Swap ->
  511. write_byte ch 0x2B
  512. | A3String s ->
  513. write_byte ch 0x2C;
  514. write_index ch s
  515. | A3IntRef i ->
  516. write_byte ch 0x2D;
  517. write_index ch i
  518. | A3UIntRef i ->
  519. write_byte ch 0x2E;
  520. write_index ch i
  521. | A3Float f ->
  522. write_byte ch 0x2F;
  523. write_index ch f
  524. | A3Scope ->
  525. write_byte ch 0x30
  526. | A3Namespace f ->
  527. write_byte ch 0x31;
  528. write_index ch f
  529. | A3Next (r1,r2) ->
  530. write_byte ch 0x32;
  531. write_int ch r1;
  532. write_int ch r2
  533. | A3Function f ->
  534. write_byte ch 0x40;
  535. write_index_nz ch f
  536. | A3CallStack n ->
  537. write_byte ch 0x41;
  538. write_int ch n
  539. | A3Construct n ->
  540. write_byte ch 0x42;
  541. write_int ch n
  542. | A3CallMethod (f,n) ->
  543. write_byte ch 0x43;
  544. write_int ch f;
  545. write_int ch n
  546. | A3CallStatic (f,n) ->
  547. write_byte ch 0x44;
  548. write_index ch f;
  549. write_int ch n
  550. | A3CallSuper (f,n) ->
  551. write_byte ch 0x45;
  552. write_index ch f;
  553. write_int ch n
  554. | A3CallProperty (f,n) ->
  555. write_byte ch 0x46;
  556. write_index ch f;
  557. write_int ch n
  558. | A3RetVoid ->
  559. write_byte ch 0x47
  560. | A3Ret ->
  561. write_byte ch 0x48
  562. | A3ConstructSuper n ->
  563. write_byte ch 0x49;
  564. write_int ch n
  565. | A3ConstructProperty (f,n) ->
  566. write_byte ch 0x4A;
  567. write_index ch f;
  568. write_int ch n
  569. | A3CallPropLex (f,n) ->
  570. write_byte ch 0x4C;
  571. write_index ch f;
  572. write_int ch n
  573. | A3CallSuperVoid (f,n) ->
  574. write_byte ch 0x4E;
  575. write_index ch f;
  576. write_int ch n
  577. | A3CallPropVoid (f,n) ->
  578. write_byte ch 0x4F;
  579. write_index ch f;
  580. write_int ch n
  581. | A3ApplyType n ->
  582. write_byte ch 0x53;
  583. write_int ch n
  584. | A3Object n ->
  585. write_byte ch 0x55;
  586. write_int ch n
  587. | A3Array n ->
  588. write_byte ch 0x56;
  589. write_int ch n
  590. | A3NewBlock ->
  591. write_byte ch 0x57
  592. | A3ClassDef f ->
  593. write_byte ch 0x58;
  594. write_index_nz ch f
  595. | A3GetDescendants f ->
  596. write_byte ch 0x59;
  597. write_index ch f
  598. | A3Catch n ->
  599. write_byte ch 0x5A;
  600. write_int ch n
  601. | A3FindPropStrict f ->
  602. write_byte ch 0x5D;
  603. write_index ch f
  604. | A3FindProp f ->
  605. write_byte ch 0x5E;
  606. write_index ch f
  607. | A3FindDefinition f ->
  608. write_byte ch 0x5F;
  609. write_index ch f
  610. | A3GetLex f ->
  611. write_byte ch 0x60;
  612. write_index ch f
  613. | A3SetProp f ->
  614. write_byte ch 0x61;
  615. write_index ch f
  616. | A3Reg n ->
  617. if n >= 0 && n < 4 then
  618. write_byte ch (0xD0 + n)
  619. else begin
  620. write_byte ch 0x62;
  621. write_int ch n
  622. end
  623. | A3SetReg n ->
  624. if n >= 0 && n < 4 then
  625. write_byte ch (0xD4 + n)
  626. else begin
  627. write_byte ch 0x63;
  628. write_int ch n
  629. end
  630. | A3GetGlobalScope ->
  631. write_byte ch 0x64
  632. | A3GetScope n ->
  633. write_byte ch 0x65;
  634. write_byte ch n
  635. | A3GetProp f ->
  636. write_byte ch 0x66;
  637. write_index ch f
  638. | A3InitProp f ->
  639. write_byte ch 0x68;
  640. write_index ch f
  641. | A3DeleteProp f ->
  642. write_byte ch 0x6A;
  643. write_index ch f
  644. | A3GetSlot n ->
  645. write_byte ch 0x6C;
  646. write_int ch n
  647. | A3SetSlot n ->
  648. write_byte ch 0x6D;
  649. write_int ch n
  650. | A3ToString ->
  651. write_byte ch 0x70
  652. | A3ToXml ->
  653. write_byte ch 0x71
  654. | A3ToXmlAttr ->
  655. write_byte ch 0x72
  656. | A3ToInt ->
  657. write_byte ch 0x73
  658. | A3ToUInt ->
  659. write_byte ch 0x74
  660. | A3ToNumber ->
  661. write_byte ch 0x75
  662. | A3ToBool ->
  663. write_byte ch 0x76
  664. | A3ToObject ->
  665. write_byte ch 0x77
  666. | A3CheckIsXml ->
  667. write_byte ch 0x78
  668. | A3Cast f ->
  669. write_byte ch 0x80;
  670. write_index ch f
  671. | A3AsAny ->
  672. write_byte ch 0x82
  673. | A3AsString ->
  674. write_byte ch 0x85
  675. | A3AsType n ->
  676. write_byte ch 0x86;
  677. write_index ch n
  678. | A3AsObject ->
  679. write_byte ch 0x89
  680. | A3IncrReg r ->
  681. write_byte ch 0x92;
  682. write_int ch r
  683. | A3DecrReg r ->
  684. write_byte ch 0x94;
  685. write_int ch r
  686. | A3Typeof ->
  687. write_byte ch 0x95
  688. | A3InstanceOf ->
  689. write_byte ch 0xB1
  690. | A3IsType n ->
  691. write_byte ch 0xB2;
  692. write_index ch n
  693. | A3IncrIReg r ->
  694. write_byte ch 0xC2;
  695. write_int ch r
  696. | A3DecrIReg r ->
  697. write_byte ch 0xC3;
  698. write_int ch r
  699. | A3This ->
  700. write_byte ch 0xD0
  701. | A3SetThis ->
  702. write_byte ch 0xD4
  703. | A3DebugReg (name,reg,line) ->
  704. write_byte ch 0xEF;
  705. write_byte ch 0x01;
  706. write_index ch name;
  707. write_byte ch (reg - 1);
  708. write_int ch line;
  709. | A3DebugLine f ->
  710. write_byte ch 0xF0;
  711. write_int ch f;
  712. | A3DebugFile f ->
  713. write_byte ch 0xF1;
  714. write_index ch f;
  715. | A3BreakPointLine l ->
  716. write_byte ch 0xF2;
  717. write_int ch l
  718. | A3Timestamp ->
  719. write_byte ch 0xF3
  720. | A3Op op ->
  721. write_byte ch (try Hashtbl.find ops_ids op with Not_found -> assert false)
  722. | A3Unk x ->
  723. write ch x
  724. let dump_op = function
  725. | A3OAs -> "as"
  726. | A3ONeg -> "neg"
  727. | A3OIncr -> "incr"
  728. | A3ODecr -> "decr"
  729. | A3ONot -> "not"
  730. | A3OBitNot -> "bitnot"
  731. | A3OAdd -> "add"
  732. | A3OSub -> "sub"
  733. | A3OMul -> "mul"
  734. | A3ODiv -> "div"
  735. | A3OMod -> "mod"
  736. | A3OShl -> "shl"
  737. | A3OShr -> "shr"
  738. | A3OUShr -> "ushr"
  739. | A3OAnd -> "and"
  740. | A3OOr -> "or"
  741. | A3OXor -> "xor"
  742. | A3OEq -> "eq"
  743. | A3OPhysEq -> "physeq"
  744. | A3OLt -> "lt"
  745. | A3OLte -> "lte"
  746. | A3OGt -> "gt"
  747. | A3OGte -> "gte"
  748. | A3OIs -> "is"
  749. | A3OIn -> "in"
  750. | A3OIIncr -> "iincr"
  751. | A3OIDecr -> "idecr"
  752. | A3OINeg -> "ineg"
  753. | A3OIAdd -> "iadd"
  754. | A3OISub -> "isub"
  755. | A3OIMul -> "imul"
  756. | A3OMemSet8 -> "mset8"
  757. | A3OMemSet16 -> "set16"
  758. | A3OMemSet32 -> "mset32"
  759. | A3OMemSetFloat -> "msetfloat"
  760. | A3OMemSetDouble -> "msetdouble"
  761. | A3OMemGet8 -> "mget8"
  762. | A3OMemGet16 -> "mget16"
  763. | A3OMemGet32 -> "mget32"
  764. | A3OMemGetFloat -> "mgetfloat"
  765. | A3OMemGetDouble -> "mgetdouble"
  766. | A3OSign1 -> "sign1"
  767. | A3OSign8 -> "sign8"
  768. | A3OSign16 -> "sign16"
  769. let dump_jump = function
  770. | J3NotLt -> "-nlt"
  771. | J3NotLte -> "-nlte"
  772. | J3NotGt -> "-ngt"
  773. | J3NotGte -> "-ngte"
  774. | J3Always -> ""
  775. | J3True -> "-if"
  776. | J3False -> "-ifnot"
  777. | J3Eq -> "-eq"
  778. | J3Neq -> "-neq"
  779. | J3Lt -> "-lt"
  780. | J3Lte -> "-lte"
  781. | J3Gt -> "-gt"
  782. | J3Gte -> "-gte"
  783. | J3PhysEq -> "-peq"
  784. | J3PhysNeq -> "-pneq"
  785. let dump ctx op =
  786. let ident n = ctx.as3_idents.(int_index n - 1) in
  787. let rec field n =
  788. let t = ctx.as3_names.(int_index n - 1) in
  789. match t with
  790. | A3MMultiName (Some ident,_) -> "[" ^ iget ctx.as3_idents ident ^ "]"
  791. | A3MName (ident,_) -> iget ctx.as3_idents ident
  792. | A3MMultiNameLate idx -> "~array"
  793. | A3MParams (t,params) -> field t ^ "<" ^ String.concat "." (List.map field params) ^ ">"
  794. | _ -> "???"
  795. in
  796. match op with
  797. | A3BreakPoint -> "bkpt"
  798. | A3Nop -> "nop"
  799. | A3Throw -> "throw"
  800. | A3GetSuper f -> s "getsuper %s" (field f)
  801. | A3SetSuper f -> s "setsuper %s" (field f)
  802. | A3DxNs i -> s "dxns %s" (ident i)
  803. | A3DxNsLate -> "dxnslate"
  804. | A3RegKill n -> s "kill %d" n
  805. | A3Label -> "label"
  806. | A3Jump (k,n) -> s "jump%s %d" (dump_jump k) n
  807. | A3Switch (def,cases) -> s "switch %d [%s]" def (String.concat "," (List.map (s "%d") cases))
  808. | A3PushWith -> "pushwith"
  809. | A3PopScope -> "popscope"
  810. | A3ForIn -> "forin"
  811. | A3HasNext -> "hasnext"
  812. | A3Null -> "null"
  813. | A3Undefined -> "undefined"
  814. | A3ForEach -> "foreach"
  815. | A3SmallInt b -> s "int %d" b
  816. | A3Int n -> s "int %d" n
  817. | A3True -> "true"
  818. | A3False -> "false"
  819. | A3NaN -> "nan"
  820. | A3Pop -> "pop"
  821. | A3Dup -> "dup"
  822. | A3Swap -> "swap"
  823. | A3String n -> s "string [%s]" (ident n)
  824. | A3IntRef n -> s "int [%ld]" ctx.as3_ints.(int_index n - 1)
  825. | A3UIntRef n -> s "uint [%ld]" ctx.as3_uints.(int_index n - 1)
  826. | A3Float n -> s "float [%f]" ctx.as3_floats.(int_index n - 1)
  827. | A3Scope -> "scope"
  828. | A3Namespace f -> s "namespace [%d]" (int_index f)
  829. | A3Next (r1,r2) -> s "next %d %d" r1 r2
  830. | A3Function f -> s "function #%d" (int_index_nz f)
  831. | A3CallStack n -> s "callstack (%d)" n
  832. | A3Construct n -> s "construct (%d)" n
  833. | A3CallMethod (f,n) -> s "callmethod %d (%d)" f n
  834. | A3CallStatic (f,n) -> s "callstatic %d (%d)" (int_index f) n
  835. | A3CallSuper (f,n) -> s "callsuper %s (%d)" (field f) n
  836. | A3CallProperty (f,n) -> s "callprop %s (%d)" (field f) n
  837. | A3RetVoid -> "retvoid"
  838. | A3Ret -> "ret"
  839. | A3ConstructSuper n -> s "constructsuper %d" n
  840. | A3ConstructProperty (f,n) -> s "constructprop %s (%d)" (field f) n
  841. | A3CallPropLex (f,n) -> s "callproplex %s (%d)" (field f) n
  842. | A3CallSuperVoid (f,n) -> s "callsupervoid %s (%d)" (field f) n
  843. | A3CallPropVoid (f,n) -> s "callpropvoid %s (%d)" (field f) n
  844. | A3ApplyType n -> s "applytype %d" n
  845. | A3Object n -> s "object %d" n
  846. | A3Array n -> s "array %d" n
  847. | A3NewBlock -> "newblock"
  848. | A3ClassDef n -> s "classdef %d" (int_index_nz n)
  849. | A3GetDescendants f -> s "getdescendants %s" (field f)
  850. | A3Catch n -> s "catch %d" n
  851. | A3FindPropStrict f -> s "findpropstrict %s" (field f)
  852. | A3FindProp f -> s "findprop %s" (field f)
  853. | A3FindDefinition f -> s "finddefinition %s" (field f)
  854. | A3GetLex f -> s "getlex %s" (field f)
  855. | A3SetProp f -> s "setprop %s" (field f)
  856. | A3Reg n -> s "reg %d" n
  857. | A3SetReg n -> s "setreg %d" n
  858. | A3GetGlobalScope -> "getglobalscope"
  859. | A3GetScope n -> s "getscope %d" n
  860. | A3GetProp f -> s "getprop %s" (field f)
  861. | A3InitProp f -> s "initprop %s" (field f)
  862. | A3DeleteProp f -> s "deleteprop %s" (field f)
  863. | A3GetSlot n -> s "getslot %d" n
  864. | A3SetSlot n -> s "setslot %d" n
  865. | A3ToString -> "tostring"
  866. | A3ToXml -> "toxml"
  867. | A3ToXmlAttr -> "toxmlattr"
  868. | A3ToInt -> "toint"
  869. | A3ToUInt -> "touint"
  870. | A3ToNumber -> "tonumber"
  871. | A3ToBool -> "tobool"
  872. | A3ToObject -> "toobject"
  873. | A3CheckIsXml -> "checkisxml"
  874. | A3Cast f -> s "cast %s" (field f)
  875. | A3AsAny -> "asany"
  876. | A3AsString -> "asstring"
  877. | A3AsType f -> s "astype %s" (field f)
  878. | A3AsObject -> "asobject"
  879. | A3IncrReg r -> s "incrreg %d" r
  880. | A3DecrReg r -> s "decrreg %d" r
  881. | A3Typeof -> "typeof"
  882. | A3InstanceOf -> "instanceof"
  883. | A3IsType f -> s "istype %s" (field f)
  884. | A3IncrIReg r -> s "incrireg %d" r
  885. | A3DecrIReg r -> s "decrireg %d" r
  886. | A3This -> "this"
  887. | A3SetThis -> "setthis"
  888. | A3DebugReg (name,reg,line) -> s ".reg %d:%s line:%d" reg (ident name) line
  889. | A3DebugLine l -> s ".line %d" l
  890. | A3DebugFile f -> s ".file %s" (ident f)
  891. | A3BreakPointLine l -> s ".bkptline %d" l
  892. | A3Timestamp -> ".time"
  893. | A3Op o -> dump_op o
  894. | A3Unk x -> s "??? 0x%X" (int_of_char x)