123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679 |
- (*
- * This file is part of SwfLib
- * Copyright (c)2004 Nicolas Cannasse
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
- open Swf
- open IO
- open Printf
- let push_item_length = function
- | PString s -> String.length s + 1
- | PFloat _ -> 4
- | PNull -> 0
- | PUndefined -> 0
- | PReg _ -> 1
- | PBool _ -> 1
- | PDouble _ -> 8
- | PInt _ -> 4
- | PStack _ -> 1
- | PStack2 _ -> 2
- let push_item_id = function
- | PString s -> 0
- | PFloat _ -> 1
- | PNull -> 2
- | PUndefined -> 3
- | PReg _ -> 4
- | PBool _ -> 5
- | PDouble _ -> 6
- | PInt _ -> 7
- | PStack _ -> 8
- | PStack2 _ -> 9
- let opcodes = Hashtbl.create 0
- let opcodes_rev = Hashtbl.create 0
- let opcodes_names = Hashtbl.create 0
- let ( => ) code (op,name) =
- Hashtbl.add opcodes op code;
- Hashtbl.add opcodes_rev code op;
- Hashtbl.add opcodes_names op name
- let short_op_codes = begin
- 0x00 => (AEnd,"END");
- 0x04 => (ANextFrame,"NEXTFRAME");
- 0x05 => (APrevFrame,"PREVFRAME");
- 0x06 => (APlay,"PLAY");
- 0x07 => (AStop,"STOP");
- 0x08 => (AToggleHighQuality,"TGLHIGHQULTY");
- 0x09 => (AStopSounds,"STOPSOUNDS");
- 0x0A => (AAddNum,"ADDNUM");
- 0x0B => (ASubtract,"SUB");
- 0x0C => (AMultiply,"MULT");
- 0x0D => (ADivide,"DIV");
- 0x0E => (ACompareNum,"CMP");
- 0x0F => (AEqualNum,"EQNUM");
- 0x10 => (ALogicalAnd,"LAND");
- 0x11 => (ALogicalOr,"LOR");
- 0x12 => (ANot,"NOT");
- 0x13 => (AStringEqual,"STREQ");
- 0x14 => (AStringLength,"STRLEN");
- 0x15 => (ASubString,"SUBSTR");
- 0x17 => (APop,"POP");
- 0x18 => (AToInt,"TOINT");
- 0x1C => (AEval,"EVAL");
- 0x1D => (ASet,"SET");
- 0x20 => (ATellTarget,"TELLTARGET");
- 0x21 => (AStringAdd,"STRADD");
- 0x22 => (AGetProperty,"GETPROP");
- 0x23 => (ASetProperty,"SETPROP");
- 0x24 => (ADuplicateMC,"DUPLICATEMC");
- 0x25 => (ARemoveMC,"REMOVEMC");
- 0x26 => (ATrace,"TRACE");
- 0x27 => (AStartDrag,"STARTDRAG");
- 0x28 => (AStopDrag,"STOPDRAG");
- 0x2A => (AThrow,"THROW");
- 0x2B => (ACast,"CAST");
- 0x2C => (AImplements,"IMPLEMENTS");
- 0x2D => (AFSCommand2,"FSCOMMAND2");
- 0x30 => (ARandom,"RANDOM");
- 0x31 => (AMBStringLength,"MBSTRLEN");
- 0x32 => (AOrd,"ORD");
- 0x33 => (AChr,"CHR");
- 0x34 => (AGetTimer,"GETTIMER");
- 0x35 => (AMBStringSub,"MBSTRSUB");
- 0x36 => (AMBOrd,"MBORD");
- 0x37 => (AMBChr,"MBCHR");
- 0x3A => (ADeleteObj,"DELETEOBJ");
- 0x3B => (ADelete,"DELETE");
- 0x3C => (ALocalAssign,"VARSET");
- 0x3D => (ACall,"CALL");
- 0x3E => (AReturn,"RET");
- 0x3F => (AMod,"MOD");
- 0x40 => (ANew,"NEW");
- 0x41 => (ALocalVar,"VAR");
- 0x42 => (AInitArray,"ARRAY");
- 0x43 => (AObject,"OBJECT");
- 0x44 => (ATypeOf,"TYPEOF");
- 0x45 => (ATargetPath,"TARGETPATH");
- 0x46 => (AEnum,"ENUM");
- 0x47 => (AAdd,"ADD");
- 0x48 => (ACompare,"CMP");
- 0x49 => (AEqual,"EQ");
- 0x4A => (AToNumber,"TONUMBER");
- 0x4B => (AToString,"TOSTRING");
- 0x4C => (ADup,"DUP");
- 0x4D => (ASwap,"SWAP");
- 0x4E => (AObjGet,"OBJGET");
- 0x4F => (AObjSet,"OBJSET");
- 0x50 => (AIncrement,"INCR");
- 0x51 => (ADecrement,"DECR");
- 0x52 => (AObjCall,"OBJCALL");
- 0x53 => (ANewMethod,"NEWMETHOD");
- 0x54 => (AInstanceOf,"INSTANCEOF");
- 0x55 => (AEnum2,"ENUM2");
- 0x60 => (AAnd,"AND");
- 0x61 => (AOr,"OR");
- 0x62 => (AXor,"XOR");
- 0x63 => (AShl,"SHL");
- 0x64 => (AShr,"SHR");
- 0x65 => (AAsr,"ASR");
- 0x66 => (APhysEqual,"PHYSEQ");
- 0x67 => (AGreater,"GT");
- 0x68 => (AStringGreater,"STRGT");
- 0x69 => (AExtends,"EXTENDS");
- 0x9E => (ACallFrame,"CALLFRAME"); (* special case *)
- end
- let action_id = function
- | AGotoFrame _ -> 0x81
- | AGetURL _ -> 0x83
- | ASetReg _ -> 0x87
- | AStringPool _ -> 0x88
- | AWaitForFrame _ -> 0x8A
- | ASetTarget _ -> 0x8B
- | AGotoLabel _ -> 0x8C
- | AWaitForFrame2 _ -> 0x8D
- | AFunction2 _ -> 0x8E
- | ATry _ -> 0x8F
- | AWith _ -> 0x94
- | APush _ -> 0x96
- | AJump _ -> 0x99
- | AGetURL2 _ -> 0x9A
- | AFunction _ -> 0x9B
- | ACondJump _ -> 0x9D
- | AGotoFrame2 _ -> 0x9F
- | AUnknown (id,_) -> id
- | op ->
- try
- Hashtbl.find opcodes op
- with
- Not_found -> error "Unknown opcode id"
- let action_data_length = function
- | AGotoFrame _ ->
- 2
- | AGetURL (url,target) ->
- 2 + String.length url + String.length target
- | ASetReg _ ->
- 1
- | AStringPool strs ->
- List.fold_left (fun acc item -> acc + 1 + String.length item) 2 strs
- | AWaitForFrame _ ->
- 3
- | AFunction2 f ->
- let base = String.length f.f2_name + 1 + 2 + 1 + 2 + 2 in
- List.fold_left (fun acc (_,s) -> acc + 2 + String.length s) base f.f2_args
- | ASetTarget target ->
- String.length target + 1
- | AGotoLabel label ->
- String.length label + 1
- | AWaitForFrame2 _ ->
- 1
- | ATry t ->
- 1 + 6 + (match t.tr_style with TryVariable n -> String.length n + 1 | TryRegister _ -> 1)
- | AWith _ ->
- 2 (* the string does not count in length *)
- | APush items ->
- List.fold_left (fun acc item -> acc + 1 + push_item_length item) 0 items
- | AJump _ ->
- 2
- | AGetURL2 _ ->
- 1
- | AFunction f ->
- List.fold_left (fun acc s -> acc + 1 + String.length s) 4 (f.f_name :: f.f_args)
- | ACondJump _ ->
- 2
- | AGotoFrame2 (_,id) ->
- 1 + (if id = None then 0 else 2)
- | AUnknown (_,data) ->
- String.length data
- | _ ->
- 0
- let action_length a =
- let len = (if action_id a >= 0x80 then 3 else 1) in
- len + action_data_length a
- let actions_length acts =
- DynArray.fold_left (fun acc a -> acc + action_length a) (action_length AEnd) acts
- let read_mm_double ch =
- let i1 = Int64.of_int32 (read_real_i32 ch) in
- let i2 = Int64.of_int32 (read_real_i32 ch) in
- let i2 = (if i2 < Int64.zero then Int64.add i2 (Int64.shift_left Int64.one 32) else i2) in
- Int64.float_of_bits (Int64.logor i2 (Int64.shift_left i1 32))
- let write_mm_double ch f =
- let i64 = Int64.bits_of_float f in
- write_real_i32 ch (Int64.to_int32 (Int64.shift_right_logical i64 32));
- write_real_i32 ch (Int64.to_int32 i64)
- let read_string_max ch len =
- let b = Buffer.create 0 in
- let rec loop l =
- if l = 0 then begin
- let s = Buffer.contents b in
- String.sub s 0 (String.length s - 1)
- end else
- let c = read ch in
- if c = '\000' then
- Buffer.contents b
- else begin
- Buffer.add_char b c;
- loop (l - 1)
- end;
- in
- loop len
- let parse_push_item ch len =
- let id = read_byte ch in
- match id with
- | 0 -> PString (read_string_max ch len)
- | 1 -> PFloat (read_real_i32 ch)
- | 2 -> PNull
- | 3 -> PUndefined
- | 4 -> PReg (read_byte ch)
- | 5 -> PBool (read_byte ch <> 0)
- | 6 -> PDouble (read_mm_double ch)
- | 7 -> PInt (read_real_i32 ch)
- | 8 -> PStack (read_byte ch)
- | 9 -> PStack2 (read_ui16 ch)
- | _ -> error (sprintf "Unknown PUSH item id : %d" id)
- let rec parse_push_items ch len =
- if len < 0 then error "PUSH parse overflow";
- if len = 0 then
- []
- else
- let item = parse_push_item ch len in
- item :: parse_push_items ch (len - 1 - push_item_length item)
- let rec read_strings ch n =
- if n = 0 then
- []
- else
- let s = read_string ch in
- s :: read_strings ch (n-1)
- let parse_function_decl ch =
- let name = read_string ch in
- let nargs = read_ui16 ch in
- let args = read_strings ch nargs in
- let clen = read_ui16 ch in
- {
- f_name = name;
- f_args = args;
- f_codelen = clen;
- }
- let parse_f2_flags n =
- let flags = ref [] in
- let v = ref 1 in
- let add_flag f =
- if n land !v <> 0 then flags := f :: !flags;
- v := !v lsl 1
- in
- List.iter add_flag
- [ThisRegister; ThisNoVar; ArgumentsRegister; ArgumentsNoVar; SuperRegister;
- SuperNoVar; RootRegister; ParentRegister; GlobalRegister];
- !flags
- let parse_function_decl2 ch =
- let name = read_string ch in
- let nargs = read_ui16 ch in
- let nregs = read_byte ch in
- let flags = parse_f2_flags (read_ui16 ch) in
- let rec loop n =
- if n = 0 then
- []
- else
- let r = read_byte ch in
- let s = read_string ch in
- (r,s) :: loop (n-1)
- in
- let args = loop nargs in
- let clen = read_ui16 ch in
- {
- f2_name = name;
- f2_args = args;
- f2_flags = flags;
- f2_codelen = clen;
- f2_nregs = nregs;
- }
- let parse_action ch =
- let id = read_byte ch in
- let len = (if id >= 0x80 then read_ui16 ch else 0) in
- let len = (if len = 0xFFFF then 0 else len) in
- let act =
- (match id with
- | 0x81 ->
- AGotoFrame (read_ui16 ch)
- | 0x83 ->
- let url = read_string ch in
- let target = read_string ch in
- AGetURL (url,target)
- | 0x87 ->
- ASetReg (read_byte ch)
- | 0x88 ->
- let nstrs = read_ui16 ch in
- AStringPool (read_strings ch nstrs)
- | 0x8A ->
- let frame = read_ui16 ch in
- let skip = read_byte ch in
- AWaitForFrame (frame,skip)
- | 0x8B ->
- ASetTarget (read_string ch)
- | 0x8C ->
- AGotoLabel (read_string ch)
- | 0x8D ->
- AWaitForFrame2 (read_byte ch)
- | 0x8E ->
- AFunction2 (parse_function_decl2 ch)
- | 0x8F ->
- let flags = read_byte ch in
- let tsize = read_ui16 ch in
- let csize = read_ui16 ch in
- let fsize = read_ui16 ch in
- let tstyle = (if flags land 4 == 0 then TryVariable (read_string ch) else TryRegister (read_byte ch)) in
- ATry {
- tr_style = tstyle;
- tr_trylen = tsize;
- tr_catchlen = (if flags land 1 == 0 then None else Some csize);
- tr_finallylen = (if flags land 2 == 0 then None else Some fsize);
- }
- | 0x94 ->
- let size = read_ui16 ch in
- AWith size
- | 0x96 ->
- APush (parse_push_items ch len)
- | 0x99 ->
- AJump (read_i16 ch)
- | 0x9A ->
- AGetURL2 (read_byte ch)
- | 0x9B ->
- AFunction (parse_function_decl ch)
- | 0x9D ->
- ACondJump (read_i16 ch)
- | 0x9E ->
- ACallFrame
- | 0x9F ->
- let flags = read_byte ch in
- let play = flags land 1 <> 0 in
- let delta = (if flags land 2 == 0 then None else Some (read_ui16 ch)) in
- AGotoFrame2 (play,delta)
- | _ ->
- try
- Hashtbl.find opcodes_rev id
- with
- Not_found ->
- printf "Unknown Action 0x%.2X (%d)\n" id len;
- AUnknown (id,nread_string ch len)
- ) in
- (* let len2 = action_data_length act in
- if len <> len2 then error (sprintf "Datalen mismatch for action 0x%.2X (%d != %d)" id len len2);
- *) act
- let size_to_jump_index acts curindex size =
- let delta = ref 0 in
- let size = ref size in
- if !size >= 0 then begin
- while !size > 0 do
- incr delta;
- size := !size - action_length (DynArray.get acts (curindex + !delta));
- if !size < 0 then error "Unaligned code";
- done;
- end else begin
- while !size < 0 do
- size := !size + action_length (DynArray.get acts (curindex + !delta));
- if !size > 0 then error "Unaligned code";
- decr delta;
- done;
- end;
- !delta
- let parse_actions ch =
- let acts = DynArray.create() in
- let rec loop() =
- match parse_action ch with
- | AEnd -> ()
- | AUnknown (0xFF,"") ->
- DynArray.add acts APlay;
- DynArray.add acts APlay;
- DynArray.add acts APlay;
- loop()
- | a ->
- DynArray.add acts a;
- loop();
- in
- loop();
- (* process jump indexes *)
- let process_jump curindex = function
- | AJump size ->
- let index = size_to_jump_index acts curindex size in
- DynArray.set acts curindex (AJump index)
- | ACondJump size ->
- let index = size_to_jump_index acts curindex size in
- DynArray.set acts curindex (ACondJump index)
- | AFunction f ->
- let index = size_to_jump_index acts curindex f.f_codelen in
- DynArray.set acts curindex (AFunction { f with f_codelen = index })
- | AFunction2 f ->
- let index = size_to_jump_index acts curindex f.f2_codelen in
- DynArray.set acts curindex (AFunction2 { f with f2_codelen = index })
- | AWith size ->
- let index = size_to_jump_index acts curindex size in
- DynArray.set acts curindex (AWith index)
- | ATry t ->
- let tindex = size_to_jump_index acts curindex t.tr_trylen in
- let cindex = (match t.tr_catchlen with None -> None | Some size -> Some (size_to_jump_index acts (curindex + tindex) size)) in
- let findex = (match t.tr_finallylen with None -> None | Some size -> Some (size_to_jump_index acts (curindex + tindex + (match cindex with None -> 0 | Some i -> i)) size)) in
- DynArray.set acts curindex (ATry { t with tr_trylen = tindex; tr_catchlen = cindex; tr_finallylen = findex })
- | _ ->
- ()
- in
- DynArray.iteri process_jump acts;
- acts
- let jump_index_to_size acts curindex target =
- let size = ref 0 in
- if target >= 0 then begin
- for i = 1 to target do
- size := !size + action_length (DynArray.get acts (curindex + i));
- done;
- end else begin
- for i = 0 downto target+1 do
- size := !size - action_length (DynArray.get acts (curindex + i));
- done;
- end;
- !size
- let rec write_strings ch = function
- | [] -> ()
- | s :: l ->
- write_string ch s;
- write_strings ch l
- let write_push_item_data ch = function
- | PString s -> write_string ch s
- | PFloat f -> write_real_i32 ch f
- | PNull -> ()
- | PUndefined -> ()
- | PReg r -> write_byte ch r
- | PBool b -> write_byte ch (if b then 1 else 0)
- | PDouble f -> write_mm_double ch f
- | PInt n -> write_real_i32 ch n
- | PStack index -> write_byte ch index
- | PStack2 index -> write_ui16 ch index
- let f2_flags_value flags =
- let fval = function
- | ThisRegister -> 1
- | ThisNoVar -> 2
- | ArgumentsRegister -> 4
- | ArgumentsNoVar -> 8
- | SuperRegister -> 16
- | SuperNoVar -> 32
- | RootRegister -> 64
- | ParentRegister -> 128
- | GlobalRegister -> 256
- in
- List.fold_left (fun n f -> n lor (fval f)) 0 flags
- let write_action_data acts curindex ch = function
- | AGotoFrame frame ->
- write_ui16 ch frame
- | AGetURL (url,target) ->
- write_string ch url;
- write_string ch target
- | ASetReg reg ->
- write_byte ch reg
- | AStringPool strs ->
- write_ui16 ch (List.length strs);
- write_strings ch strs
- | AWaitForFrame (frame,skip) ->
- write_ui16 ch frame;
- write_byte ch skip
- | ASetTarget target ->
- write_string ch target
- | AGotoLabel label ->
- write_string ch label
- | AWaitForFrame2 n ->
- write_byte ch n
- | AFunction2 f ->
- write_string ch f.f2_name;
- write_ui16 ch (List.length f.f2_args);
- write_byte ch f.f2_nregs;
- write_ui16 ch (f2_flags_value f.f2_flags);
- List.iter (fun (r,s) ->
- write_byte ch r;
- write_string ch s;
- ) f.f2_args;
- let size = jump_index_to_size acts curindex f.f2_codelen in
- write_ui16 ch size;
- | ATry t ->
- let tsize = jump_index_to_size acts curindex t.tr_trylen in
- let csize = (match t.tr_catchlen with None -> 0 | Some idx -> jump_index_to_size acts (curindex + t.tr_trylen) idx) in
- let fsize = (match t.tr_finallylen with None -> 0 | Some idx -> jump_index_to_size acts (curindex + t.tr_trylen + (match t.tr_catchlen with None -> 0 | Some n -> n)) idx) in
- let flags = (if t.tr_catchlen <> None then 1 else 0) lor (if t.tr_finallylen <> None then 2 else 0) lor (match t.tr_style with TryRegister _ -> 4 | TryVariable _ -> 0) in
- write_byte ch flags;
- write_ui16 ch tsize;
- write_ui16 ch csize;
- write_ui16 ch fsize;
- (match t.tr_style with
- | TryVariable v -> write_string ch v
- | TryRegister r -> write_byte ch r)
- | AWith target ->
- let size = jump_index_to_size acts curindex target in
- write_ui16 ch size
- | APush items ->
- List.iter (fun item ->
- write_byte ch (push_item_id item);
- write_push_item_data ch item
- ) items
- | AJump target ->
- let size = jump_index_to_size acts curindex target in
- write_i16 ch size
- | AGetURL2 n ->
- write_byte ch n
- | AFunction f ->
- write_string ch f.f_name;
- write_ui16 ch (List.length f.f_args);
- write_strings ch f.f_args;
- let size = jump_index_to_size acts curindex f.f_codelen in
- write_ui16 ch size;
- | ACondJump target ->
- let size = jump_index_to_size acts curindex target in
- write_i16 ch size;
- | AGotoFrame2 (play,None) ->
- write_byte ch (if play then 1 else 0)
- | AGotoFrame2 (play,Some delta) ->
- write_byte ch (if play then 3 else 2);
- write_ui16 ch delta;
- | ACallFrame ->
- ()
- | AUnknown (_,data) ->
- nwrite_string ch data
- | _ ->
- assert false
- let write_action acts curindex ch a =
- let id = action_id a in
- let len = action_data_length a in
- if id < 0x80 && len > 0 then error "Invalid Action Written";
- write_byte ch id;
- if len > 0 || id >= 0x80 then begin
- write_ui16 ch len;
- write_action_data acts curindex ch a;
- end
- let write_actions ch acts =
- DynArray.iteri (fun index act -> write_action acts index ch act) acts;
- write_action acts (DynArray.length acts) ch AEnd
- let sprintf = Printf.sprintf
- let action_string get_ident pos = function
- | AGotoFrame n -> sprintf "GOTOFRAME %d" n
- | AGetURL (a,b) -> sprintf "GETURL '%s' '%s'" a b
- | ASetReg n -> sprintf "SETREG %d" n
- | AStringPool strlist ->
- let b = Buffer.create 0 in
- Buffer.add_string b "STRINGS ";
- let p = ref 0 in
- List.iter (fun s ->
- Buffer.add_string b (string_of_int !p);
- incr p;
- Buffer.add_char b ':';
- Buffer.add_string b s;
- Buffer.add_char b ' ';
- ) strlist;
- Buffer.contents b
- | AWaitForFrame (i,j) -> sprintf "WAITFORFRAME %d %d" i j
- | ASetTarget s -> sprintf "SETTARGET %s" s
- | AGotoLabel s -> sprintf "GOTOLABEL %s" s
- | AWaitForFrame2 n -> sprintf "WAITFORFRAME2 %d" n
- | AFunction2 f ->
- let b = Buffer.create 0 in
- Buffer.add_string b "FUNCTION2 ";
- Buffer.add_string b f.f2_name;
- Buffer.add_char b '(';
- Buffer.add_string b (String.concat "," (List.map (fun (n,str) -> sprintf "%d:%s" n str) f.f2_args));
- Buffer.add_char b ')';
- Buffer.add_string b (sprintf " nregs:%d flags:%d " f.f2_nregs (f2_flags_value f.f2_flags));
- Buffer.add_string b (sprintf "0x%.4X" (pos + 1 + f.f2_codelen));
- Buffer.contents b
- | APush pl ->
- let b = Buffer.create 0 in
- Buffer.add_string b "PUSH";
- List.iter (fun it ->
- Buffer.add_char b ' ';
- match it with
- | PString s ->
- Buffer.add_char b '"';
- Buffer.add_string b s;
- Buffer.add_char b '"'
- | PFloat _ ->
- Buffer.add_string b "<float>"
- | PNull ->
- Buffer.add_string b "null"
- | PUndefined ->
- Buffer.add_string b "undefined"
- | PReg n ->
- Buffer.add_string b (sprintf "reg:%d" n)
- | PBool fl ->
- Buffer.add_string b (if fl then "true" else "false")
- | PDouble _ ->
- Buffer.add_string b "<double>"
- | PInt i ->
- Buffer.add_string b (Int32.to_string i)
- | PStack n
- | PStack2 n ->
- Buffer.add_char b '[';
- Buffer.add_string b (string_of_int n);
- Buffer.add_char b ':';
- Buffer.add_string b (get_ident n);
- Buffer.add_char b ']';
- ) pl;
- Buffer.contents b
- | ATry _ -> sprintf "TRY"
- | AWith n -> sprintf "WITH %d" n
- | AJump n -> sprintf "JUMP 0x%.4X" (n + pos + 1)
- | AGetURL2 n -> sprintf "GETURL2 %d" n
- | AFunction f ->
- let b = Buffer.create 0 in
- Buffer.add_string b "FUNCTION ";
- Buffer.add_string b f.f_name;
- Buffer.add_char b '(';
- Buffer.add_string b (String.concat "," f.f_args);
- Buffer.add_char b ')';
- Buffer.add_string b (sprintf " 0x%.4X" (pos + 1 + f.f_codelen));
- Buffer.contents b
- | ACondJump n -> sprintf "CJMP 0x%.4X" (n + pos + 1)
- | AGotoFrame2 (b,None) -> sprintf "GOTOFRAME2 %b" b
- | AGotoFrame2 (b,Some i) -> sprintf "GOTOFRAME2 %b %d" b i
- | AUnknown (tag,_) -> sprintf "??? 0x%.2X" tag
- | op ->
- try
- Hashtbl.find opcodes_names op
- with
- Not_found -> assert false
|