2
0

as3code.ml 22 KB

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