6 method_info: Abc.method_info list;
7 method_body: Abc.method_body list;
8 class_info: Abc.class_info list;
9 instance_info: Abc.instance_info list
13 name = Cpool.make_qname "<default-method>";
25 let make_meth ?(args=[]) name body =
27 body @ [ReturnValue] in
28 { name = Cpool.make_qname name;
38 let make_proc ?(args=[]) name body =
40 body @ [ReturnVoid] in
41 { name = Cpool.make_qname name;
52 - meth contains instruction list.
53 - instruction contains meth list.
55 Thus, meth create multi-tree like structure.
56 [fold_method f init meth] is folding this tree by [f].
58 let rec fold_method f init meth =
60 (fun a inst -> List.fold_left (fold_method f) a (get_config inst).meth)
64 (** [fold_instruction f init meth] is recursively folding all-instruction by [f]. *)
65 let fold_instruction f init =
67 (fun init' {instructions=insts}-> List.fold_left f init' insts)
70 (**{6 Collecting some information}*)
72 (** [collect_const meth] returns all constant value which contained by [meth]. *)
73 let collect_const meth=
77 (fun cpool i-> Cpool.append cpool (get_config i).const)
81 (** [collect_klass meth] returns all class which contained by [meth]. *)
82 let collect_klass meth =
83 meth.instructions +> HList.concat_map
85 match (get_config i).klass with
89 (** [collect_method meth] return all methods which contained by [meth]. *)
91 Set.to_list $ fold_method (flip Set.add) Set.empty
93 (** {6 Assemble meth} *)
95 let add (max,current) n =
98 if max < current' then
103 let asm_method map index m =
107 List.map get_config m.instructions in
108 let (max_stack,_),(max_scope,_),local_count,bytes =
111 (stack,scope,count,bytes)
112 {op=op;prefix=prefix;args=args;stack=st;scope=sc;count=c} ->
118 add stack st,add scope sc,max count c,by::bytes)
119 (zero,zero,1,[]) configs in
121 { Abc.params=m.params;
123 Abc.name=Cpool.multiname_nget m.name map.cpool;
124 Abc.flags=m.flags } in
126 { Abc.method_sig=index;
127 Abc.max_stack=max_stack;
128 Abc.local_count=List.length m.params+1;
129 Abc.init_scope_depth=0;
130 Abc.max_scope_depth=max_scope;
131 Abc.code=List.concat @@ List.rev bytes;
136 let asm_klass {cpool=cpool; meths=meths; klasses=klasses} klass =
138 Abc.cinit = index klass.cinit meths;
144 | Interface -> Abc.Interface
145 | ProtectedNs ns -> Abc.ProtectedNs (Cpool.namespace_nget ns cpool) in
146 let method_trait m = {
147 Abc.t_name = Cpool.multiname_nget m.name cpool;
148 data = Abc.MethodTrait (0,index m meths) } in
149 let attr_trait id attr = {
150 Abc.t_name = Cpool.multiname_nget attr cpool;
151 data = Abc.SlotTrait (id,0,0,0) } in
152 let instance_info = {
153 Abc.name_i = Cpool.multiname_nget klass.cname cpool;
154 super_name = Cpool.multiname_nget klass.sname cpool;
155 flags_i = List.map flag klass.flags_k;
156 interface = List.map (flip index klasses) klass.interface;
157 iinit = index klass.iinit meths;
158 trait_i = (List.map method_trait klass.methods) @ (ExtList.List.mapi attr_trait klass.attributes)
160 class_info,instance_info
165 {cpool = collect_const meth;
166 meths = collect_method meth;
167 klasses = collect_klass meth} in
169 List.split @@ ExtList.List.mapi (asm_method context) context.meths in
170 let class_info,instance_info =
171 List.split @@ List.map (asm_klass context) context.klasses in
172 {abc_cpool = Cpool.to_abc context.cpool;
175 class_info = class_info;
176 instance_info = instance_info}