2
* This file is part of SwfLib
3
* Copyright (c)2004-2008 Nicolas Cannasse
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
mutable namespaces : hl_namespace array;
25
mutable nsets : hl_ns_set array;
26
mutable names : hl_name array;
27
mutable methods : hl_method array;
28
mutable classes : hl_class array;
29
mutable jumps : (int * int) list;
33
let get = As3parse.iget
34
let no_nz = As3parse.no_nz
35
let idx n = As3parse.index_int n - 1
37
let ident ctx i = get ctx.as3.as3_idents i
38
let name ctx n = ctx.names.(idx n)
39
let method_type ctx n = ctx.methods.(idx (no_nz n))
40
let getclass ctx n = ctx.classes.(idx (no_nz n))
42
let global_mark = ref 0
48
let opt f ctx = function
50
| Some x -> Some (f ctx x)
52
let stack_delta = function
56
| HGetSuper _ -> 1 (* ??? *)
57
| HSetSuper _ -> -1 (* ??? *)
90
| HCallStack n -> -(n + 1)
92
| HCallMethod (_,n) -> -n
93
| HCallStatic (_,n) -> -n
94
| HCallSuper (_,n) -> -n
95
| HCallProperty (_,n) -> -n
98
| HConstructSuper n -> -(n + 1)
99
| HConstructProperty (_,n) -> -n
100
| HCallPropLex (_,n) -> -n
101
| HCallSuperVoid (_,n) -> -(n + 1)
102
| HCallPropVoid (_,n) -> -(n + 1)
103
| HObject n -> -(n * 2) + 1
108
| HFindPropStrict _ -> 1
110
| HFindDefinition _ -> 1
114
| HSetReg _ | HSetThis -> -1
115
| HGetGlobalScope | HGetScope _ -> 1
118
| HDeleteProp _ -> -1 (* true/false *)
138
| HIncrReg _ | HDecrReg _ | HIncrIReg _ | HDecrIReg _ -> 0
147
| A3ONeg | A3OINeg | A3OIncr | A3ODecr | A3ONot | A3OBitNot | A3OIIncr | A3OIDecr -> 0
149
| HUnk _ -> assert false
151
let parse_opcode ctx i = function
152
| A3BreakPoint -> HBreakPoint
155
| A3GetSuper n -> HGetSuper (name ctx n)
156
| A3SetSuper n -> HSetSuper (name ctx n)
157
| A3RegKill r -> HRegKill r
160
ctx.jumps <- (i,ctx.pos) :: ctx.jumps;
162
| A3Switch (n,infos) as op ->
163
ctx.jumps <- (i,ctx.pos - As3code.length op) :: ctx.jumps;
165
| A3PushWith -> HPushWith
166
| A3PopScope -> HPopScope
168
| A3HasNext -> HHasNext
170
| A3Undefined -> HUndefined
171
| A3ForEach -> HForEach
172
| A3SmallInt n -> HSmallInt n
180
| A3String i -> HString (ident ctx i)
181
| A3IntRef i -> HIntRef (get ctx.as3.as3_ints i)
182
| A3UIntRef i -> HUIntRef (get ctx.as3.as3_uints i)
183
| A3Float f -> HFloat (get ctx.as3.as3_floats f)
185
| A3Namespace n -> HNamespace ctx.namespaces.(idx n)
186
| A3Next (r1,r2) -> HNext (r1,r2)
187
| A3Function f -> HFunction (method_type ctx f)
188
| A3CallStack n -> HCallStack n
189
| A3Construct n -> HConstruct n
190
| A3CallMethod (s,n) -> HCallMethod (s,n)
191
| A3CallStatic (m,n) -> HCallStatic (ctx.methods.(idx m),n)
192
| A3CallSuper (p,n) -> HCallSuper (name ctx p,n)
193
| A3CallProperty (p,n) -> HCallProperty (name ctx p,n)
194
| A3RetVoid -> HRetVoid
196
| A3ConstructSuper n -> HConstructSuper n
197
| A3ConstructProperty (p,n) -> HConstructProperty (name ctx p,n)
198
| A3CallPropLex (p,n) -> HCallPropLex (name ctx p,n)
199
| A3CallSuperVoid (p,n) -> HCallSuperVoid (name ctx p,n)
200
| A3CallPropVoid (p,n) -> HCallPropVoid (name ctx p,n)
201
| A3Object n -> HObject n
202
| A3Array n -> HArray n
203
| A3NewBlock -> HNewBlock
204
| A3ClassDef n -> HClassDef (getclass ctx n)
205
| A3Catch n -> HCatch n
206
| A3FindPropStrict p -> HFindPropStrict (name ctx p)
207
| A3FindProp p -> HFindProp (name ctx p)
208
| A3FindDefinition p -> HFindDefinition (name ctx p)
209
| A3GetLex p -> HGetLex (name ctx p)
210
| A3SetProp p -> HSetProp (name ctx p)
212
| A3SetReg r -> HSetReg r
213
| A3GetGlobalScope -> HGetGlobalScope
214
| A3GetScope n -> HGetScope n
215
| A3GetProp p -> HGetProp (name ctx p)
216
| A3InitProp p -> HInitProp (name ctx p)
217
| A3DeleteProp p -> HDeleteProp (name ctx p)
218
| A3GetSlot n -> HGetSlot n
219
| A3SetSlot n -> HSetSlot n
220
| A3ToString -> HToString
222
| A3ToXmlAttr -> HToXmlAttr
224
| A3ToUInt -> HToUInt
225
| A3ToNumber -> HToNumber
226
| A3ToBool -> HToBool
227
| A3ToObject -> HToObject
228
| A3CheckIsXml -> HCheckIsXml
229
| A3Cast p -> HCast (name ctx p)
231
| A3AsString -> HAsString
232
| A3AsType p -> HAsType (name ctx p)
233
| A3AsObject -> HAsObject
234
| A3IncrReg r -> HIncrReg r
235
| A3DecrReg r -> HDecrReg r
236
| A3Typeof -> HTypeof
237
| A3InstanceOf -> HInstanceOf
238
| A3IsType p -> HIsType (name ctx p)
239
| A3IncrIReg r -> HIncrIReg r
240
| A3DecrIReg r -> HDecrIReg r
242
| A3SetThis -> HSetThis
243
| A3DebugReg (id,r,n) -> HDebugReg (ident ctx id,r,n)
244
| A3DebugLine n -> HDebugLine n
245
| A3DebugFile p -> HDebugFile (ident ctx p)
246
| A3BreakPointLine n -> HBreakPointLine n
247
| A3Timestamp -> HTimestamp
251
let parse_code ctx f trys =
252
let code = f.fun3_code in
253
let old = ctx.pos , ctx.jumps in
254
let indexes = DynArray.create() in
257
let codepos pos delta =
258
let id = (try DynArray.get indexes (pos + delta) with _ -> -1) in
259
if id = -1 then begin
260
Printf.eprintf "MISALIGNED JUMP AT %d %c %d IN #%d\n" pos (if delta < 0 then '-' else '+') (if delta < 0 then -delta else delta) (idx (no_nz f.fun3_id));
261
DynArray.get indexes pos; (* jump 0 *)
265
let hcode = Array.mapi (fun i op ->
266
let len = As3code.length op in
267
DynArray.add indexes i;
268
for k = 2 to len do DynArray.add indexes (-1); done;
269
ctx.pos <- ctx.pos + len;
270
parse_opcode ctx i op
272
(* in case we have a dead-jump at the end of code *)
273
DynArray.add indexes (Array.length code);
275
List.iter (fun (j,pos) ->
276
Array.set hcode j (match Array.get hcode j with
278
HJump (jc,codepos pos n - j)
279
| HSwitch (n,infos) ->
280
HSwitch (codepos pos n - j, List.map (fun n -> codepos pos n - j) infos)
283
(* patch try/catches *)
284
Array.iteri (fun i t ->
286
hltc_start = codepos 0 t.hltc_start;
287
hltc_end = codepos 0 t.hltc_end;
288
hltc_handle = codepos 0 t.hltc_handle;
289
hltc_type = t.hltc_type;
290
hltc_name = t.hltc_name;
294
ctx.jumps <- snd old;
297
let parse_metadata ctx m =
299
hlmeta_name = ident ctx m.meta3_name;
300
hlmeta_data = Array.map (fun (i1,i2) -> opt ident ctx i1, ident ctx i2) m.meta3_data;
303
let parse_method ctx m =
305
hlm_type = method_type ctx m.m3_type;
306
hlm_final = m.m3_final;
307
hlm_override = m.m3_override;
308
hlm_kind = m.m3_kind;
311
let parse_value ctx = function
314
| A3VBool b -> HVBool b
315
| A3VString s -> HVString (ident ctx s)
316
| A3VInt i -> HVInt (get ctx.as3.as3_ints i)
317
| A3VUInt i -> HVUInt (get ctx.as3.as3_uints i)
318
| A3VFloat f -> HVFloat (get ctx.as3.as3_floats f)
319
| A3VNamespace (n,ns) -> HVNamespace (n,ctx.namespaces.(idx ns))
321
let parse_var ctx v =
323
hlv_type = opt name ctx v.v3_type;
324
hlv_value = parse_value ctx v.v3_value;
325
hlv_const = v.v3_const;
328
let parse_field_kind ctx = function
329
| A3FMethod m -> HFMethod (parse_method ctx m)
330
| A3FVar v -> HFVar (parse_var ctx v)
331
| A3FFunction f -> HFFunction (method_type ctx f)
332
| A3FClass c -> HFClass (getclass ctx c)
334
let parse_field ctx f =
336
hlf_name = name ctx f.f3_name;
337
hlf_slot = f.f3_slot;
338
hlf_kind = parse_field_kind ctx f.f3_kind;
340
match f.f3_metas with
343
Some (Array.map (fun i ->
344
parse_metadata ctx (get ctx.as3.as3_metadatas (no_nz i))
348
let parse_static ctx s =
350
hls_method = method_type ctx s.st3_method;
351
hls_fields = Array.map (parse_field ctx) s.st3_fields;
354
let parse_namespace ctx = function
355
| A3NPrivate id -> HNPrivate (opt ident ctx id)
356
| A3NPublic id -> HNPublic (opt ident ctx id)
357
| A3NInternal id -> HNInternal (opt ident ctx id)
358
| A3NProtected id -> HNProtected (ident ctx id)
359
| A3NNamespace id -> HNNamespace (ident ctx id)
360
| A3NExplicit id -> HNExplicit (ident ctx id)
361
| A3NStaticProtected id -> HNStaticProtected (opt ident ctx id)
363
let parse_nset ctx l = List.map (fun n -> ctx.namespaces.(idx n)) l
365
let rec parse_name ctx = function
367
(match ctx.namespaces.(idx ns) with
369
let pack = (match p with None -> [] | Some i -> ExtString.String.nsplit i ".") in
370
HMPath (pack, ident ctx id)
372
HMName (ident ctx id, ns))
373
| A3MMultiName (id,ns) -> HMMultiName (opt ident ctx id,ctx.nsets.(idx ns))
374
| A3MRuntimeName id -> HMRuntimeName (ident ctx id)
375
| A3MRuntimeNameLate -> HMRuntimeNameLate
376
| A3MMultiNameLate ns -> HMMultiNameLate ctx.nsets.(idx ns)
377
| A3MAttrib multi -> HMAttrib (parse_name ctx multi)
379
let parse_try_catch ctx t =
381
hltc_start = t.tc3_start;
382
hltc_end = t.tc3_end;
383
hltc_handle = t.tc3_handle;
384
hltc_type = opt name ctx t.tc3_type;
385
hltc_name = opt name ctx t.tc3_name;
388
let parse_function ctx f =
390
hlf_stack_size = f.fun3_stack_size;
391
hlf_nregs = f.fun3_nregs;
392
hlf_init_scope = f.fun3_init_scope;
393
hlf_max_scope = f.fun3_max_scope;
394
hlf_code = [||]; (* keep for later *)
395
hlf_trys = Array.map (parse_try_catch ctx) f.fun3_trys;
396
hlf_locals = Array.map (fun f ->
397
if f.f3_metas <> None then assert false;
400
if v.v3_const then assert false;
401
(* v3_value can be <> None if it's a fun parameter with a default value
402
- which looks like a bug of the AS3 compiler *)
403
name ctx f.f3_name , opt name ctx v.v3_type , f.f3_slot
408
let parse_method_type ctx m f =
410
hlmt_mark = alloc_mark();
411
hlmt_ret = opt name ctx m.mt3_ret;
412
hlmt_args = List.map (opt name ctx) m.mt3_args;
413
hlmt_native = m.mt3_native;
414
hlmt_var_args = m.mt3_var_args;
415
hlmt_arguments_defined = m.mt3_arguments_defined;
416
hlmt_uses_dxns = m.mt3_uses_dxns;
417
hlmt_new_block = m.mt3_new_block;
418
hlmt_unused_flag = m.mt3_unused_flag;
419
hlmt_debug_name = opt ident ctx m.mt3_debug_name;
420
hlmt_dparams = opt (fun ctx -> List.map (parse_value ctx)) ctx m.mt3_dparams;
421
hlmt_pnames = opt (fun ctx -> List.map (opt ident ctx)) ctx m.mt3_pnames;
422
hlmt_function = opt parse_function ctx f;
425
let parse_class ctx c s =
427
hlc_name = name ctx c.cl3_name;
428
hlc_super = opt name ctx c.cl3_super;
429
hlc_sealed = c.cl3_sealed;
430
hlc_final = c.cl3_final;
431
hlc_interface = c.cl3_interface;
432
hlc_namespace = opt (fun ctx i -> ctx.namespaces.(idx i)) ctx c.cl3_namespace;
433
hlc_implements = Array.map (name ctx) c.cl3_implements;
434
hlc_construct = method_type ctx c.cl3_construct;
435
hlc_fields = Array.map (parse_field ctx) c.cl3_fields;
436
hlc_static_construct = method_type ctx s.st3_method;
437
hlc_static_fields = Array.map (parse_field ctx) s.st3_fields;
440
let parse_static ctx s =
442
hls_method = method_type ctx s.st3_method;
443
hls_fields = Array.map (parse_field ctx) s.st3_fields;
457
ctx.namespaces <- Array.map (parse_namespace ctx) t.as3_namespaces;
458
ctx.nsets <- Array.map (parse_nset ctx) t.as3_nsets;
459
ctx.names <- Array.map (parse_name ctx) t.as3_names;
460
let hfunctions = Hashtbl.create 0 in
461
Array.iter (fun f -> Hashtbl.add hfunctions (idx (no_nz f.fun3_id)) f) t.as3_functions;
462
ctx.methods <- Array.mapi (fun i m ->
463
parse_method_type ctx t.as3_method_types.(i) (try Some (Hashtbl.find hfunctions i) with Not_found -> None);
464
) t.as3_method_types;
465
ctx.classes <- Array.mapi (fun i c ->
466
parse_class ctx c t.as3_statics.(i)
468
let inits = List.map (parse_static ctx) (Array.to_list t.as3_inits) in
470
match (method_type ctx f.fun3_id).hlmt_function with
471
| None -> assert false
472
| Some fl -> fl.hlf_code <- parse_code ctx f fl.hlf_trys
476
(* ************************************************************************ *)
478
(* ************************************************************************ *)
480
type ('hl,'item,'key) gen_lookup = {
481
h : ('key,int) Hashtbl.t;
482
a : 'item DynArray.t;
483
f : flatten_ctx -> 'hl -> 'item;
487
and ('hl,'item) lookup = ('hl,'item,'hl) gen_lookup
490
fints : (hl_int,as3_int) lookup;
491
fuints : (hl_uint,as3_uint) lookup;
492
ffloats : (hl_float,as3_float) lookup;
493
fidents : (hl_ident,as3_ident) lookup;
494
fnamespaces : (hl_namespace,as3_namespace) lookup;
495
fnsets : (hl_ns_set,as3_ns_set) lookup;
496
fnames : (hl_name,as3_multi_name) lookup;
497
fmetas : (hl_metadata,as3_metadata) lookup;
498
fmethods : (hl_method,as3_method_type,int) gen_lookup;
499
fclasses : (hl_class,as3_class * as3_static,hl_name) gen_lookup;
500
mutable ffunctions : as3_function list;
501
mutable fjumps : int list;
504
let new_gen_lookup f k =
506
h = Hashtbl.create 0;
507
a = DynArray.create();
512
let new_lookup f = new_gen_lookup f (fun x -> x)
514
let lookup_array l = DynArray.to_array l.a
516
let lookup ctx (l:('a,'b,'k) gen_lookup) item : 'b index =
517
let key = l.k item in
521
let idx = DynArray.length l.a in
522
(* set dummy value for recursion *)
523
DynArray.add l.a (Obj.magic 0);
524
Hashtbl.add l.h key (idx + 1);
525
DynArray.set l.a idx (l.f ctx item);
528
As3parse.magic_index idx
530
let lookup_nz ctx l item =
531
As3parse.magic_index_nz (As3parse.index_int (lookup ctx l item) - 1)
533
let lookup_ident ctx i = lookup ctx ctx.fidents i
535
let lookup_name ctx n = lookup ctx ctx.fnames n
537
let lookup_method ctx m : as3_method_type index_nz =
538
lookup_nz ctx ctx.fmethods m
540
let lookup_class ctx c : as3_class index_nz =
541
lookup_nz ctx ctx.fclasses c
543
let flatten_namespace ctx = function
544
| HNPrivate i -> A3NPrivate (opt lookup_ident ctx i)
545
| HNPublic i -> A3NPublic (opt lookup_ident ctx i)
546
| HNInternal i -> A3NInternal (opt lookup_ident ctx i)
547
| HNProtected i -> A3NProtected (lookup_ident ctx i)
548
| HNNamespace i -> A3NNamespace (lookup_ident ctx i)
549
| HNExplicit i -> A3NExplicit (lookup_ident ctx i)
550
| HNStaticProtected i -> A3NStaticProtected (opt lookup_ident ctx i)
552
let flatten_ns_set ctx n =
553
List.map (lookup ctx ctx.fnamespaces) n
555
let rec flatten_name ctx = function
557
let ns = HNPublic (match pack with [] -> None | l -> Some (String.concat "." l)) in
558
A3MName (lookup_ident ctx i,lookup ctx ctx.fnamespaces ns)
559
| HMName (i,n) -> A3MName (lookup_ident ctx i,lookup ctx ctx.fnamespaces n)
560
| HMMultiName (i,ns) -> A3MMultiName (opt lookup_ident ctx i,lookup ctx ctx.fnsets ns)
561
| HMRuntimeName i -> A3MRuntimeName (lookup_ident ctx i)
562
| HMRuntimeNameLate -> A3MRuntimeNameLate
563
| HMMultiNameLate ns -> A3MMultiNameLate (lookup ctx ctx.fnsets ns)
564
| HMAttrib n -> A3MAttrib (flatten_name ctx n)
566
let flatten_meta ctx m =
568
meta3_name = lookup_ident ctx m.hlmeta_name;
569
meta3_data = Array.map (fun (i,i2) -> opt lookup_ident ctx i, lookup_ident ctx i2) m.hlmeta_data;
572
let flatten_value ctx = function
575
| HVBool b -> A3VBool b
576
| HVString s -> A3VString (lookup_ident ctx s)
577
| HVInt i -> A3VInt (lookup ctx ctx.fints i)
578
| HVUInt i -> A3VUInt (lookup ctx ctx.fuints i)
579
| HVFloat f -> A3VFloat (lookup ctx ctx.ffloats f)
580
| HVNamespace (n,ns) -> A3VNamespace (n,lookup ctx ctx.fnamespaces ns)
582
let flatten_field ctx f =
584
f3_name = lookup_name ctx f.hlf_name;
585
f3_slot = f.hlf_slot;
586
f3_kind = (match f.hlf_kind with
589
m3_type = lookup_method ctx m.hlm_type;
590
m3_final = m.hlm_final;
591
m3_override = m.hlm_override;
592
m3_kind = m.hlm_kind;
596
v3_type = opt lookup_name ctx v.hlv_type;
597
v3_value = flatten_value ctx v.hlv_value;
598
v3_const = v.hlv_const;
601
A3FFunction (lookup_method ctx f)
603
A3FClass (lookup_class ctx c)
605
f3_metas = opt (fun ctx -> Array.map (fun m -> lookup_nz ctx ctx.fmetas m)) ctx f.hlf_metas;
608
let flatten_class ctx c =
610
cl3_name = lookup_name ctx c.hlc_name;
611
cl3_super = opt lookup_name ctx c.hlc_super;
612
cl3_sealed = c.hlc_sealed;
613
cl3_final = c.hlc_final;
614
cl3_interface = c.hlc_interface;
615
cl3_namespace = opt (fun ctx -> lookup ctx ctx.fnamespaces) ctx c.hlc_namespace;
616
cl3_implements = Array.map (lookup_name ctx) c.hlc_implements;
617
cl3_construct = lookup_method ctx c.hlc_construct;
618
cl3_fields = Array.map (flatten_field ctx) c.hlc_fields;
621
st3_method = lookup_method ctx c.hlc_static_construct;
622
st3_fields = Array.map (flatten_field ctx) c.hlc_static_fields;
625
let flatten_opcode ctx i = function
626
| HBreakPoint -> A3BreakPoint
629
| HGetSuper n -> A3GetSuper (lookup_name ctx n)
630
| HSetSuper n -> A3SetSuper (lookup_name ctx n)
631
| HRegKill r -> A3RegKill r
634
ctx.fjumps <- i :: ctx.fjumps;
637
ctx.fjumps <- i :: ctx.fjumps;
639
| HPushWith -> A3PushWith
640
| HPopScope -> A3PopScope
642
| HHasNext -> A3HasNext
644
| HUndefined -> A3Undefined
645
| HForEach -> A3ForEach
646
| HSmallInt n -> A3SmallInt n
654
| HString s -> A3String (lookup_ident ctx s)
655
| HIntRef i -> A3IntRef (lookup ctx ctx.fints i)
656
| HUIntRef i -> A3UIntRef (lookup ctx ctx.fuints i)
657
| HFloat f -> A3Float (lookup ctx ctx.ffloats f)
659
| HNamespace n -> A3Namespace (lookup ctx ctx.fnamespaces n)
660
| HNext (r1,r2) -> A3Next (r1,r2)
661
| HFunction m -> A3Function (lookup_method ctx m)
662
| HCallStack n -> A3CallStack n
663
| HConstruct n -> A3Construct n
664
| HCallMethod (s,n) -> A3CallMethod (s,n)
665
| HCallStatic (m,n) -> A3CallStatic (no_nz (lookup_method ctx m),n)
666
| HCallSuper (i,n) -> A3CallSuper (lookup_name ctx i,n)
667
| HCallProperty (i,n) -> A3CallProperty (lookup_name ctx i,n)
668
| HRetVoid -> A3RetVoid
670
| HConstructSuper n -> A3ConstructSuper n
671
| HConstructProperty (i,n) -> A3ConstructProperty (lookup_name ctx i,n)
672
| HCallPropLex (i,n) -> A3CallPropLex (lookup_name ctx i,n)
673
| HCallSuperVoid (i,n) -> A3CallSuperVoid (lookup_name ctx i,n)
674
| HCallPropVoid (i,n)-> A3CallPropVoid (lookup_name ctx i,n)
675
| HObject n -> A3Object n
676
| HArray n -> A3Array n
677
| HNewBlock -> A3NewBlock
678
| HClassDef c -> A3ClassDef (As3parse.magic_index_nz (As3parse.index_nz_int (lookup_class ctx c)))
679
| HCatch n -> A3Catch n
680
| HFindPropStrict i -> A3FindPropStrict (lookup_name ctx i)
681
| HFindProp i -> A3FindProp (lookup_name ctx i)
682
| HFindDefinition i -> A3FindDefinition (lookup_name ctx i)
683
| HGetLex i -> A3GetLex (lookup_name ctx i)
684
| HSetProp i -> A3SetProp (lookup_name ctx i)
686
| HSetReg r -> A3SetReg r
687
| HGetGlobalScope -> A3GetGlobalScope
688
| HGetScope n -> A3GetScope n
689
| HGetProp n -> A3GetProp (lookup_name ctx n)
690
| HInitProp n -> A3InitProp (lookup_name ctx n)
691
| HDeleteProp n -> A3DeleteProp (lookup_name ctx n)
692
| HGetSlot s -> A3GetSlot s
693
| HSetSlot s -> A3SetSlot s
694
| HToString -> A3ToString
696
| HToXmlAttr -> A3ToXmlAttr
698
| HToUInt -> A3ToUInt
699
| HToNumber -> A3ToNumber
700
| HToBool -> A3ToBool
701
| HToObject -> A3ToObject
702
| HCheckIsXml -> A3CheckIsXml
703
| HCast n -> A3Cast (lookup_name ctx n)
705
| HAsString -> A3AsString
706
| HAsType n -> A3AsType (lookup_name ctx n)
707
| HAsObject -> A3AsObject
708
| HIncrReg r -> A3IncrReg r
709
| HDecrReg r -> A3DecrReg r
710
| HTypeof -> A3Typeof
711
| HInstanceOf -> A3InstanceOf
712
| HIsType t -> A3IsType (lookup_name ctx t)
713
| HIncrIReg r -> A3IncrIReg r
714
| HDecrIReg r -> A3DecrIReg r
716
| HSetThis -> A3SetThis
717
| HDebugReg (i,r,l) -> A3DebugReg (lookup_ident ctx i,r,l)
718
| HDebugLine l -> A3DebugLine l
719
| HDebugFile f -> A3DebugFile (lookup_ident ctx f)
720
| HBreakPointLine n -> A3BreakPointLine n
721
| HTimestamp -> A3Timestamp
725
let flatten_code ctx hcode trys =
726
let positions = Array.create (Array.length hcode + 1) 0 in
728
let old = ctx.fjumps in
730
let code = Array.mapi (fun i op ->
731
let op = flatten_opcode ctx i op in
732
pos := !pos + As3code.length op;
733
Array.set positions (i + 1) !pos;
738
Array.set code j (match Array.get code j with
740
A3Jump (jc,positions.(j+n) - positions.(j+1))
741
| A3Switch (n,infos) ->
742
A3Switch (positions.(j+n) - positions.(j),List.map (fun n -> positions.(j+n) - positions.(j)) infos)
743
| _ -> assert false);
746
let trys = Array.mapi (fun i t ->
748
tc3_start = positions.(t.hltc_start);
749
tc3_end = positions.(t.hltc_end);
750
tc3_handle = positions.(t.hltc_handle);
751
tc3_type = opt lookup_name ctx t.hltc_type;
752
tc3_name = opt lookup_name ctx t.hltc_name;
758
let flatten_function ctx f mid =
759
let code, trys = flatten_code ctx f.hlf_code f.hlf_trys in
762
fun3_stack_size = f.hlf_stack_size;
763
fun3_nregs = f.hlf_nregs;
764
fun3_init_scope = f.hlf_init_scope;
765
fun3_max_scope = f.hlf_max_scope;
768
fun3_locals = Array.map (fun (n,t,s) ->
770
f3_name = lookup_name ctx n;
772
f3_kind = A3FVar { v3_type = opt lookup_name ctx t; v3_value = A3VNone; v3_const = false };
778
let flatten_method ctx m =
779
let mid = lookup_method ctx m in
780
(match m.hlmt_function with
782
| Some f -> ctx.ffunctions <- flatten_function ctx f mid :: ctx.ffunctions);
784
mt3_ret = opt lookup_name ctx m.hlmt_ret;
785
mt3_args = List.map (opt lookup_name ctx) m.hlmt_args;
786
mt3_native = m.hlmt_native;
787
mt3_var_args = m.hlmt_var_args;
788
mt3_arguments_defined = m.hlmt_arguments_defined;
789
mt3_uses_dxns = m.hlmt_uses_dxns;
790
mt3_new_block = m.hlmt_new_block;
791
mt3_unused_flag = m.hlmt_unused_flag;
792
mt3_debug_name = opt lookup_ident ctx m.hlmt_debug_name;
793
mt3_dparams = opt (fun ctx -> List.map (flatten_value ctx)) ctx m.hlmt_dparams;
794
mt3_pnames = opt (fun ctx -> List.map (opt lookup_ident ctx)) ctx m.hlmt_pnames;
797
let flatten_static ctx s =
799
st3_method = lookup_method ctx s.hls_method;
800
st3_fields = Array.map (flatten_field ctx) s.hls_fields;
806
fints = new_lookup id;
807
fuints = new_lookup id;
808
ffloats = new_lookup id;
809
fidents = new_lookup id;
810
fnamespaces = new_lookup flatten_namespace;
811
fnsets = new_lookup flatten_ns_set;
812
fnames = new_lookup flatten_name;
813
fmetas = new_lookup flatten_meta;
814
fmethods = new_gen_lookup flatten_method (fun m -> m.hlmt_mark);
815
fclasses = new_gen_lookup flatten_class (fun c -> c.hlc_name);
819
ignore(lookup_ident ctx "");
820
let inits = List.map (flatten_static ctx) t in
822
as3_ints = lookup_array ctx.fints;
823
as3_uints = lookup_array ctx.fuints;
824
as3_floats = lookup_array ctx.ffloats;
825
as3_idents = lookup_array ctx.fidents;
826
as3_namespaces = lookup_array ctx.fnamespaces;
827
as3_nsets = lookup_array ctx.fnsets;
828
as3_names = lookup_array ctx.fnames;
829
as3_metadatas = lookup_array ctx.fmetas;
830
as3_method_types = lookup_array ctx.fmethods;
831
as3_classes = Array.map fst (lookup_array ctx.fclasses);
832
as3_statics = Array.map snd (lookup_array ctx.fclasses);
833
as3_functions = Array.of_list (List.rev ctx.ffunctions);
834
as3_inits = Array.of_list inits;