|
@@ -366,6 +366,9 @@ let fake_tnull =
|
|
|
a_params = [mk_type_param null_class TPHType None None];
|
|
a_params = [mk_type_param null_class TPHType None None];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+let is_excluded c =
|
|
|
|
|
+ has_class_flag c CExcluded
|
|
|
|
|
+
|
|
|
let get_rec_cache ctx t none_callback not_found_callback =
|
|
let get_rec_cache ctx t none_callback not_found_callback =
|
|
|
try
|
|
try
|
|
|
match !(List.assq t ctx.rec_cache) with
|
|
match !(List.assq t ctx.rec_cache) with
|
|
@@ -3439,32 +3442,33 @@ and make_fun ?gen_content ctx name fidx f cthis cparent =
|
|
|
op ctx (OSetEnumField (ctx.m.mcaptreg, index, alloc_var ctx v false)));
|
|
op ctx (OSetEnumField (ctx.m.mcaptreg, index, alloc_var ctx v false)));
|
|
|
) f.tf_args;
|
|
) f.tf_args;
|
|
|
|
|
|
|
|
|
|
+ let tret = to_type ctx f.tf_type in
|
|
|
(match gen_content with
|
|
(match gen_content with
|
|
|
- | None -> ()
|
|
|
|
|
- | Some f -> f());
|
|
|
|
|
|
|
+ | None ->
|
|
|
|
|
+ ignore(eval_expr ctx f.tf_expr);
|
|
|
|
|
+ let rec has_final_jump e =
|
|
|
|
|
+ (* prevents a jump outside function bounds error *)
|
|
|
|
|
+ match e.eexpr with
|
|
|
|
|
+ | TBlock el -> (match List.rev el with e :: _ -> has_final_jump e | [] -> false)
|
|
|
|
|
+ | TParenthesis e -> has_final_jump e
|
|
|
|
|
+ | TReturn _ -> false
|
|
|
|
|
+ | _ -> true
|
|
|
|
|
+ in
|
|
|
|
|
+ set_curpos ctx (max_pos f.tf_expr);
|
|
|
|
|
+ if tret = HVoid then
|
|
|
|
|
+ op ctx (ORet (alloc_tmp ctx HVoid))
|
|
|
|
|
+ else if has_final_jump f.tf_expr then begin
|
|
|
|
|
+ let r = alloc_tmp ctx tret in
|
|
|
|
|
+ (match tret with
|
|
|
|
|
+ | HI32 | HUI8 | HUI16 | HI64 -> op ctx (OInt (r,alloc_i32 ctx 0l))
|
|
|
|
|
+ | HF32 | HF64 -> op ctx (OFloat (r,alloc_float ctx 0.))
|
|
|
|
|
+ | HBool -> op ctx (OBool (r,false))
|
|
|
|
|
+ | _ -> op ctx (ONull r));
|
|
|
|
|
+ op ctx (ORet r)
|
|
|
|
|
+ end;
|
|
|
|
|
+ | Some f ->
|
|
|
|
|
+ f());
|
|
|
|
|
|
|
|
- ignore(eval_expr ctx f.tf_expr);
|
|
|
|
|
- let tret = to_type ctx f.tf_type in
|
|
|
|
|
- let rec has_final_jump e =
|
|
|
|
|
- (* prevents a jump outside function bounds error *)
|
|
|
|
|
- match e.eexpr with
|
|
|
|
|
- | TBlock el -> (match List.rev el with e :: _ -> has_final_jump e | [] -> false)
|
|
|
|
|
- | TParenthesis e -> has_final_jump e
|
|
|
|
|
- | TReturn _ -> false
|
|
|
|
|
- | _ -> true
|
|
|
|
|
- in
|
|
|
|
|
- set_curpos ctx (max_pos f.tf_expr);
|
|
|
|
|
- if tret = HVoid then
|
|
|
|
|
- op ctx (ORet (alloc_tmp ctx HVoid))
|
|
|
|
|
- else if has_final_jump f.tf_expr then begin
|
|
|
|
|
- let r = alloc_tmp ctx tret in
|
|
|
|
|
- (match tret with
|
|
|
|
|
- | HI32 | HUI8 | HUI16 | HI64 -> op ctx (OInt (r,alloc_i32 ctx 0l))
|
|
|
|
|
- | HF32 | HF64 -> op ctx (OFloat (r,alloc_float ctx 0.))
|
|
|
|
|
- | HBool -> op ctx (OBool (r,false))
|
|
|
|
|
- | _ -> op ctx (ONull r));
|
|
|
|
|
- op ctx (ORet r)
|
|
|
|
|
- end;
|
|
|
|
|
let fargs = (match tthis with None -> [] | Some t -> [t]) @ (match rcapt with None -> [] | Some r -> [rtype ctx r]) @ args in
|
|
let fargs = (match tthis with None -> [] | Some t -> [t]) @ (match rcapt with None -> [] | Some r -> [rtype ctx r]) @ args in
|
|
|
let hlf = {
|
|
let hlf = {
|
|
|
fpath = name;
|
|
fpath = name;
|
|
@@ -3516,8 +3520,9 @@ let generate_static ctx c f =
|
|
|
| (Meta.HlNative,_ ,p) :: _ ->
|
|
| (Meta.HlNative,_ ,p) :: _ ->
|
|
|
abort "Invalid @:hlNative decl" p
|
|
abort "Invalid @:hlNative decl" p
|
|
|
| [] ->
|
|
| [] ->
|
|
|
|
|
+ let gen_content = if is_excluded c then Some (fun() -> op ctx (OAssert 0)) else None in
|
|
|
(match f.cf_expr with
|
|
(match f.cf_expr with
|
|
|
- | Some { eexpr = TFunction fn } -> ignore(make_fun ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) fn None None)
|
|
|
|
|
|
|
+ | Some { eexpr = TFunction fn } -> ignore(make_fun ?gen_content ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) fn None None)
|
|
|
| _ -> if not (Meta.has Meta.NoExpr f.cf_meta) then abort "Missing function body" f.cf_pos)
|
|
| _ -> if not (Meta.has Meta.NoExpr f.cf_meta) then abort "Missing function body" f.cf_pos)
|
|
|
| _ :: l ->
|
|
| _ :: l ->
|
|
|
loop l
|
|
loop l
|
|
@@ -3530,7 +3535,25 @@ let generate_member ctx c f =
|
|
|
| Var _ -> ()
|
|
| Var _ -> ()
|
|
|
| _ when is_extern_field f -> ()
|
|
| _ when is_extern_field f -> ()
|
|
|
| Method m ->
|
|
| Method m ->
|
|
|
- let gen_content = if f.cf_name <> "new" then None else Some (fun() ->
|
|
|
|
|
|
|
+ let ff = match f.cf_expr with
|
|
|
|
|
+ | Some { eexpr = TFunction f } -> f
|
|
|
|
|
+ | None when has_class_field_flag f CfAbstract ->
|
|
|
|
|
+ let tl,tr = match follow f.cf_type with
|
|
|
|
|
+ | TFun(tl,tr) -> tl,tr
|
|
|
|
|
+ | _ -> die "" __LOC__
|
|
|
|
|
+ in
|
|
|
|
|
+ let args = List.map (fun (n,_,t) ->
|
|
|
|
|
+ let v = Type.alloc_var VGenerated n t null_pos in
|
|
|
|
|
+ (v,None)
|
|
|
|
|
+ ) tl in
|
|
|
|
|
+ {
|
|
|
|
|
+ tf_args = args;
|
|
|
|
|
+ tf_type = tr;
|
|
|
|
|
+ tf_expr = mk (TThrow (mk (TConst TNull) t_dynamic null_pos)) t_dynamic null_pos;
|
|
|
|
|
+ }
|
|
|
|
|
+ | _ -> abort "Missing function body" f.cf_pos
|
|
|
|
|
+ in
|
|
|
|
|
+ let gen_content = if is_excluded c then Some (fun() -> op ctx (OAssert 0)) else if f.cf_name <> "new" then None else Some (fun() ->
|
|
|
|
|
|
|
|
let o = (match class_type ctx c (extract_param_types c.cl_params) false with
|
|
let o = (match class_type ctx c (extract_param_types c.cl_params) false with
|
|
|
| HObj o | HStruct o -> o
|
|
| HObj o | HStruct o -> o
|
|
@@ -3551,25 +3574,9 @@ let generate_member ctx c f =
|
|
|
op ctx (OSetThis (fid,r));
|
|
op ctx (OSetThis (fid,r));
|
|
|
| _ -> ()
|
|
| _ -> ()
|
|
|
) c.cl_ordered_fields;
|
|
) c.cl_ordered_fields;
|
|
|
|
|
+ ignore(eval_expr ctx ff.tf_expr);
|
|
|
|
|
+ op ctx (ORet (alloc_tmp ctx HVoid))
|
|
|
) in
|
|
) in
|
|
|
- let ff = match f.cf_expr with
|
|
|
|
|
- | Some { eexpr = TFunction f } -> f
|
|
|
|
|
- | None when has_class_field_flag f CfAbstract ->
|
|
|
|
|
- let tl,tr = match follow f.cf_type with
|
|
|
|
|
- | TFun(tl,tr) -> tl,tr
|
|
|
|
|
- | _ -> die "" __LOC__
|
|
|
|
|
- in
|
|
|
|
|
- let args = List.map (fun (n,_,t) ->
|
|
|
|
|
- let v = Type.alloc_var VGenerated n t null_pos in
|
|
|
|
|
- (v,None)
|
|
|
|
|
- ) tl in
|
|
|
|
|
- {
|
|
|
|
|
- tf_args = args;
|
|
|
|
|
- tf_type = tr;
|
|
|
|
|
- tf_expr = mk (TThrow (mk (TConst TNull) t_dynamic null_pos)) t_dynamic null_pos;
|
|
|
|
|
- }
|
|
|
|
|
- | _ -> abort "Missing function body" f.cf_pos
|
|
|
|
|
- in
|
|
|
|
|
ignore(make_fun ?gen_content ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) ff (Some c) None);
|
|
ignore(make_fun ?gen_content ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) ff (Some c) None);
|
|
|
if f.cf_name = "toString" && not (has_class_field_flag f CfOverride) && not (PMap.mem "__string" c.cl_fields) && is_to_string f.cf_type then begin
|
|
if f.cf_name = "toString" && not (has_class_field_flag f CfOverride) && not (PMap.mem "__string" c.cl_fields) && is_to_string f.cf_type then begin
|
|
|
let p = {f.cf_pos with pmax = f.cf_pos.pmin} in
|
|
let p = {f.cf_pos with pmax = f.cf_pos.pmin} in
|
|
@@ -3624,200 +3631,201 @@ let generate_type ctx t =
|
|
|
| TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ ->
|
|
| TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ ->
|
|
|
()
|
|
()
|
|
|
|
|
|
|
|
-let generate_static_init ctx types main =
|
|
|
|
|
- let exprs = ref [] in
|
|
|
|
|
- let t_void = ctx.com.basic.tvoid in
|
|
|
|
|
|
|
+let generate_static_content ctx types f =
|
|
|
|
|
+ let is_init = alloc_tmp ctx HBool in
|
|
|
|
|
+ op ctx (OCall0 (is_init, alloc_fun_path ctx ([],"Type") "init"));
|
|
|
|
|
+ hold ctx is_init;
|
|
|
|
|
|
|
|
- let gen_content() =
|
|
|
|
|
-
|
|
|
|
|
- let is_init = alloc_tmp ctx HBool in
|
|
|
|
|
- op ctx (OCall0 (is_init, alloc_fun_path ctx ([],"Type") "init"));
|
|
|
|
|
- hold ctx is_init;
|
|
|
|
|
-
|
|
|
|
|
- (* init class values *)
|
|
|
|
|
- List.iter (fun t ->
|
|
|
|
|
- match t with
|
|
|
|
|
- | TClassDecl c when not (has_class_flag c CExtern) && not (is_array_class (s_type_path c.cl_path) && snd c.cl_path <> "ArrayDyn") && c != ctx.core_type && c != ctx.core_enum ->
|
|
|
|
|
|
|
+ (* init class values *)
|
|
|
|
|
+ List.iter (fun t ->
|
|
|
|
|
+ match t with
|
|
|
|
|
+ | TClassDecl c when not (has_class_flag c CExtern) && not (is_array_class (s_type_path c.cl_path) && snd c.cl_path <> "ArrayDyn") && c != ctx.core_type && c != ctx.core_enum ->
|
|
|
|
|
|
|
|
- let path = if c == ctx.array_impl.abase then [],"Array" else if c == ctx.base_class then [],"Class" else c.cl_path in
|
|
|
|
|
|
|
+ let path = if c == ctx.array_impl.abase then [],"Array" else if c == ctx.base_class then [],"Class" else c.cl_path in
|
|
|
|
|
|
|
|
- let g, ct = class_global ~resolve:false ctx c in
|
|
|
|
|
- let ctype = if c == ctx.array_impl.abase then ctx.array_impl.aall else c in
|
|
|
|
|
- let t = class_type ctx ctype (extract_param_types ctype.cl_params) false in
|
|
|
|
|
|
|
+ let g, ct = class_global ~resolve:false ctx c in
|
|
|
|
|
+ let ctype = if c == ctx.array_impl.abase then ctx.array_impl.aall else c in
|
|
|
|
|
+ let t = class_type ctx ctype (extract_param_types ctype.cl_params) false in
|
|
|
|
|
|
|
|
- let index name =
|
|
|
|
|
- match ct with
|
|
|
|
|
- | HObj o ->
|
|
|
|
|
- fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
|
|
|
- | _ ->
|
|
|
|
|
- die "" __LOC__
|
|
|
|
|
- in
|
|
|
|
|
|
|
+ let index name =
|
|
|
|
|
+ match ct with
|
|
|
|
|
+ | HObj o ->
|
|
|
|
|
+ fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
|
|
|
+ | _ ->
|
|
|
|
|
+ die "" __LOC__
|
|
|
|
|
+ in
|
|
|
|
|
|
|
|
- let rc = (match t with
|
|
|
|
|
- | HObj o when (match o.pclassglobal with None -> -1 | Some i -> i) <> g ->
|
|
|
|
|
- (* manual registration for objects with prototype tricks (Array) *)
|
|
|
|
|
|
|
+ let rc = (match t with
|
|
|
|
|
+ | HObj o when (match o.pclassglobal with None -> -1 | Some i -> i) <> g ->
|
|
|
|
|
+ (* manual registration for objects with prototype tricks (Array) *)
|
|
|
|
|
|
|
|
- let rc = alloc_tmp ctx ct in
|
|
|
|
|
- op ctx (ONew rc);
|
|
|
|
|
- op ctx (OSetGlobal (g,rc));
|
|
|
|
|
- hold ctx rc;
|
|
|
|
|
|
|
+ let rc = alloc_tmp ctx ct in
|
|
|
|
|
+ op ctx (ONew rc);
|
|
|
|
|
+ op ctx (OSetGlobal (g,rc));
|
|
|
|
|
+ hold ctx rc;
|
|
|
|
|
|
|
|
- let rt = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (rt, t));
|
|
|
|
|
- op ctx (OSetField (rc,index "__type__",rt));
|
|
|
|
|
- op ctx (OSetField (rc,index "__name__",eval_expr ctx { eexpr = TConst (TString (s_type_path path)); epos = c.cl_pos; etype = ctx.com.basic.tstring }));
|
|
|
|
|
|
|
+ let rt = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (rt, t));
|
|
|
|
|
+ op ctx (OSetField (rc,index "__type__",rt));
|
|
|
|
|
+ op ctx (OSetField (rc,index "__name__",eval_expr ctx { eexpr = TConst (TString (s_type_path path)); epos = c.cl_pos; etype = ctx.com.basic.tstring }));
|
|
|
|
|
|
|
|
- let rname = alloc_tmp ctx HBytes in
|
|
|
|
|
- op ctx (OString (rname, alloc_string ctx (s_type_path path)));
|
|
|
|
|
- op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",rname,rc));
|
|
|
|
|
- rc
|
|
|
|
|
|
|
+ let rname = alloc_tmp ctx HBytes in
|
|
|
|
|
+ op ctx (OString (rname, alloc_string ctx (s_type_path path)));
|
|
|
|
|
+ op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",rname,rc));
|
|
|
|
|
+ rc
|
|
|
|
|
|
|
|
- | _ ->
|
|
|
|
|
|
|
+ | _ ->
|
|
|
|
|
|
|
|
- let rct = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (rct, ct));
|
|
|
|
|
- hold ctx rct;
|
|
|
|
|
|
|
+ let rct = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (rct, ct));
|
|
|
|
|
+ hold ctx rct;
|
|
|
|
|
|
|
|
- let rt = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (rt, t));
|
|
|
|
|
|
|
+ let rt = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (rt, t));
|
|
|
|
|
|
|
|
- let rname = alloc_tmp ctx HBytes in
|
|
|
|
|
- op ctx (OString (rname, alloc_string ctx (s_type_path path)));
|
|
|
|
|
|
|
+ let rname = alloc_tmp ctx HBytes in
|
|
|
|
|
+ op ctx (OString (rname, alloc_string ctx (s_type_path path)));
|
|
|
|
|
|
|
|
- let rc = alloc_tmp ctx (class_type ctx ctx.base_class [] false) in
|
|
|
|
|
- op ctx (OCall3 (rc, alloc_fun_path ctx ([],"Type") "initClass", rct, rt, rname));
|
|
|
|
|
- hold ctx rc;
|
|
|
|
|
- free ctx rct;
|
|
|
|
|
- rc
|
|
|
|
|
- ) in
|
|
|
|
|
|
|
+ let rc = alloc_tmp ctx (class_type ctx ctx.base_class [] false) in
|
|
|
|
|
+ op ctx (OCall3 (rc, alloc_fun_path ctx ([],"Type") (if is_excluded c then "loadClass" else "initClass"), rct, rt, rname));
|
|
|
|
|
+ hold ctx rc;
|
|
|
|
|
+ free ctx rct;
|
|
|
|
|
+ rc
|
|
|
|
|
+ ) in
|
|
|
|
|
|
|
|
- let gather_implements() =
|
|
|
|
|
- let classes = ref [] in
|
|
|
|
|
- let rec lookup cv =
|
|
|
|
|
- List.exists (fun (i,_) -> i == c || lookup i) cv.cl_implements
|
|
|
|
|
- in
|
|
|
|
|
- let check = function
|
|
|
|
|
- | TClassDecl c when (has_class_flag c CInterface) = false && not (has_class_flag c CExtern) -> if lookup c then classes := c :: !classes
|
|
|
|
|
- | _ -> ()
|
|
|
|
|
- in
|
|
|
|
|
- List.iter check ctx.com.types;
|
|
|
|
|
- !classes
|
|
|
|
|
|
|
+ let gather_implements() =
|
|
|
|
|
+ let classes = ref [] in
|
|
|
|
|
+ let rec lookup cv =
|
|
|
|
|
+ List.exists (fun (i,_) -> i == c || lookup i) cv.cl_implements
|
|
|
in
|
|
in
|
|
|
- if (has_class_flag c CInterface) then begin
|
|
|
|
|
- let l = gather_implements() in
|
|
|
|
|
- let rt = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (rt, HType));
|
|
|
|
|
- let ra = alloc_array ctx (reg_int ctx (List.length l)) HType in
|
|
|
|
|
- list_iteri (fun i intf ->
|
|
|
|
|
- op ctx (OType (rt, to_type ctx (TInst (intf,[]))));
|
|
|
|
|
- op ctx (OSetArray (ra, reg_int ctx i, rt));
|
|
|
|
|
- ) l;
|
|
|
|
|
- op ctx (OSetField (rc,index "__implementedBy__",ra));
|
|
|
|
|
-
|
|
|
|
|
- (* TODO : use a plain class for interface object since we don't allow statics *)
|
|
|
|
|
- let rt = alloc_tmp ctx ct in
|
|
|
|
|
- op ctx (OSafeCast (rt, rc));
|
|
|
|
|
- op ctx (OSetGlobal (g, rt));
|
|
|
|
|
- end;
|
|
|
|
|
|
|
+ let check = function
|
|
|
|
|
+ | TClassDecl c when (has_class_flag c CInterface) = false && not (has_class_flag c CExtern) -> if lookup c then classes := c :: !classes
|
|
|
|
|
+ | _ -> ()
|
|
|
|
|
+ in
|
|
|
|
|
+ List.iter check ctx.com.types;
|
|
|
|
|
+ !classes
|
|
|
|
|
+ in
|
|
|
|
|
+ if (has_class_flag c CInterface) then begin
|
|
|
|
|
+ let l = gather_implements() in
|
|
|
|
|
+ let rt = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (rt, HType));
|
|
|
|
|
+ let ra = alloc_array ctx (reg_int ctx (List.length l)) HType in
|
|
|
|
|
+ list_iteri (fun i intf ->
|
|
|
|
|
+ op ctx (OType (rt, to_type ctx (TInst (intf,[]))));
|
|
|
|
|
+ op ctx (OSetArray (ra, reg_int ctx i, rt));
|
|
|
|
|
+ ) l;
|
|
|
|
|
+ op ctx (OSetField (rc,index "__implementedBy__",ra));
|
|
|
|
|
+
|
|
|
|
|
+ (* TODO : use a plain class for interface object since we don't allow statics *)
|
|
|
|
|
+ let rt = alloc_tmp ctx ct in
|
|
|
|
|
+ op ctx (OSafeCast (rt, rc));
|
|
|
|
|
+ op ctx (OSetGlobal (g, rt));
|
|
|
|
|
+ end;
|
|
|
|
|
|
|
|
- (match Texpr.build_metadata ctx.com.basic (TClassDecl c) with
|
|
|
|
|
- | None -> ()
|
|
|
|
|
- | Some e ->
|
|
|
|
|
- let r = eval_to ctx e HDyn in
|
|
|
|
|
- op ctx (OSetField (rc,index "__meta__",r)));
|
|
|
|
|
|
|
+ (match Texpr.build_metadata ctx.com.basic (TClassDecl c) with
|
|
|
|
|
+ | None -> ()
|
|
|
|
|
+ | Some e ->
|
|
|
|
|
+ let r = eval_to ctx e HDyn in
|
|
|
|
|
+ op ctx (OSetField (rc,index "__meta__",r)));
|
|
|
|
|
+
|
|
|
|
|
+ free ctx rc;
|
|
|
|
|
+
|
|
|
|
|
+ | TEnumDecl e when not (has_enum_flag e EnExtern) ->
|
|
|
|
|
+
|
|
|
|
|
+ let et = enum_class ctx e in
|
|
|
|
|
+ let t = enum_type ctx e in
|
|
|
|
|
+
|
|
|
|
|
+ let ret = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (ret, et));
|
|
|
|
|
+ hold ctx ret;
|
|
|
|
|
+ let rt = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (OType (rt, t));
|
|
|
|
|
+ let r = alloc_tmp ctx (class_type ctx ctx.base_enum [] false) in
|
|
|
|
|
+ let etr = alloc_tmp ctx et in
|
|
|
|
|
+ op ctx (OCall2 (r, alloc_fun_path ctx ([],"Type") "initEnum", ret, rt));
|
|
|
|
|
+ free ctx ret;
|
|
|
|
|
+ op ctx (OSafeCast (etr, r));
|
|
|
|
|
+
|
|
|
|
|
+ let index name =
|
|
|
|
|
+ match et with
|
|
|
|
|
+ | HObj o ->
|
|
|
|
|
+ fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
|
|
|
+ | _ ->
|
|
|
|
|
+ die "" __LOC__
|
|
|
|
|
+ in
|
|
|
|
|
|
|
|
- free ctx rc;
|
|
|
|
|
|
|
+ let avalues = alloc_tmp ctx (HArray t) in
|
|
|
|
|
+ op ctx (OField (avalues, r, index "__evalues__"));
|
|
|
|
|
|
|
|
- | TEnumDecl e when not (has_enum_flag e EnExtern) ->
|
|
|
|
|
|
|
+ List.iter (fun n ->
|
|
|
|
|
+ let f = PMap.find n e.e_constrs in
|
|
|
|
|
+ match follow f.ef_type with
|
|
|
|
|
+ | TFun _ -> ()
|
|
|
|
|
+ | _ ->
|
|
|
|
|
+ let g = alloc_global ctx (efield_name e f) t in
|
|
|
|
|
+ let r = alloc_tmp ctx t in
|
|
|
|
|
+ let rd = alloc_tmp ctx HDyn in
|
|
|
|
|
+ op ctx (OGetArray (rd,avalues, reg_int ctx f.ef_index));
|
|
|
|
|
+ op ctx (OSafeCast (r, rd));
|
|
|
|
|
+ op ctx (OSetGlobal (g,r));
|
|
|
|
|
+ op ctx (OSetField (etr, index f.ef_name ,r));
|
|
|
|
|
+ ) e.e_names;
|
|
|
|
|
|
|
|
- let et = enum_class ctx e in
|
|
|
|
|
- let t = enum_type ctx e in
|
|
|
|
|
|
|
+ (match Texpr.build_metadata ctx.com.basic (TEnumDecl e) with
|
|
|
|
|
+ | None -> ()
|
|
|
|
|
+ | Some e -> op ctx (OSetField (r,index "__meta__",eval_to ctx e HDyn)));
|
|
|
|
|
|
|
|
- let ret = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (ret, et));
|
|
|
|
|
- hold ctx ret;
|
|
|
|
|
- let rt = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (OType (rt, t));
|
|
|
|
|
- let r = alloc_tmp ctx (class_type ctx ctx.base_enum [] false) in
|
|
|
|
|
- let etr = alloc_tmp ctx et in
|
|
|
|
|
- op ctx (OCall2 (r, alloc_fun_path ctx ([],"Type") "initEnum", ret, rt));
|
|
|
|
|
- free ctx ret;
|
|
|
|
|
- op ctx (OSafeCast (etr, r));
|
|
|
|
|
|
|
+
|
|
|
|
|
+ | TAbstractDecl { a_path = [], name; a_pos = pos } ->
|
|
|
|
|
+ (match name with
|
|
|
|
|
+ | "Int" | "Float" | "Dynamic" | "Bool" ->
|
|
|
|
|
+ let is_bool = name = "Bool" in
|
|
|
|
|
+ let t = class_type ctx (if is_bool then ctx.core_enum else ctx.core_type) [] false in
|
|
|
|
|
|
|
|
let index name =
|
|
let index name =
|
|
|
- match et with
|
|
|
|
|
|
|
+ match t with
|
|
|
| HObj o ->
|
|
| HObj o ->
|
|
|
fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
|
| _ ->
|
|
| _ ->
|
|
|
die "" __LOC__
|
|
die "" __LOC__
|
|
|
in
|
|
in
|
|
|
|
|
|
|
|
- let avalues = alloc_tmp ctx (HArray t) in
|
|
|
|
|
- op ctx (OField (avalues, r, index "__evalues__"));
|
|
|
|
|
|
|
+ let g = alloc_global ctx ("$" ^ name) t in
|
|
|
|
|
+ let r = alloc_tmp ctx t in
|
|
|
|
|
+ let rt = alloc_tmp ctx HType in
|
|
|
|
|
+ op ctx (ONew r);
|
|
|
|
|
+ op ctx (OType (rt,(match name with "Int" -> HI32 | "Float" -> HF64 | "Dynamic" -> HDyn | "Bool" -> HBool | _ -> die "" __LOC__)));
|
|
|
|
|
+ op ctx (OSetField (r,index "__type__",rt));
|
|
|
|
|
+ op ctx (OSetField (r,index (if is_bool then "__ename__" else "__name__"),make_string ctx name pos));
|
|
|
|
|
+ op ctx (OSetGlobal (g,r));
|
|
|
|
|
|
|
|
- List.iter (fun n ->
|
|
|
|
|
- let f = PMap.find n e.e_constrs in
|
|
|
|
|
- match follow f.ef_type with
|
|
|
|
|
- | TFun _ -> ()
|
|
|
|
|
- | _ ->
|
|
|
|
|
- let g = alloc_global ctx (efield_name e f) t in
|
|
|
|
|
- let r = alloc_tmp ctx t in
|
|
|
|
|
- let rd = alloc_tmp ctx HDyn in
|
|
|
|
|
- op ctx (OGetArray (rd,avalues, reg_int ctx f.ef_index));
|
|
|
|
|
- op ctx (OSafeCast (r, rd));
|
|
|
|
|
- op ctx (OSetGlobal (g,r));
|
|
|
|
|
- op ctx (OSetField (etr, index f.ef_name ,r));
|
|
|
|
|
- ) e.e_names;
|
|
|
|
|
-
|
|
|
|
|
- (match Texpr.build_metadata ctx.com.basic (TEnumDecl e) with
|
|
|
|
|
- | None -> ()
|
|
|
|
|
- | Some e -> op ctx (OSetField (r,index "__meta__",eval_to ctx e HDyn)));
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- | TAbstractDecl { a_path = [], name; a_pos = pos } ->
|
|
|
|
|
- (match name with
|
|
|
|
|
- | "Int" | "Float" | "Dynamic" | "Bool" ->
|
|
|
|
|
- let is_bool = name = "Bool" in
|
|
|
|
|
- let t = class_type ctx (if is_bool then ctx.core_enum else ctx.core_type) [] false in
|
|
|
|
|
-
|
|
|
|
|
- let index name =
|
|
|
|
|
- match t with
|
|
|
|
|
- | HObj o ->
|
|
|
|
|
- fst (try get_index name o with Not_found -> die "" __LOC__)
|
|
|
|
|
- | _ ->
|
|
|
|
|
- die "" __LOC__
|
|
|
|
|
- in
|
|
|
|
|
|
|
+ let bytes = alloc_tmp ctx HBytes in
|
|
|
|
|
+ op ctx (OString (bytes, alloc_string ctx name));
|
|
|
|
|
+ op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",bytes,r));
|
|
|
|
|
+ | _ ->
|
|
|
|
|
+ ())
|
|
|
|
|
+ | _ ->
|
|
|
|
|
+ ()
|
|
|
|
|
|
|
|
- let g = alloc_global ctx ("$" ^ name) t in
|
|
|
|
|
- let r = alloc_tmp ctx t in
|
|
|
|
|
- let rt = alloc_tmp ctx HType in
|
|
|
|
|
- op ctx (ONew r);
|
|
|
|
|
- op ctx (OType (rt,(match name with "Int" -> HI32 | "Float" -> HF64 | "Dynamic" -> HDyn | "Bool" -> HBool | _ -> die "" __LOC__)));
|
|
|
|
|
- op ctx (OSetField (r,index "__type__",rt));
|
|
|
|
|
- op ctx (OSetField (r,index (if is_bool then "__ename__" else "__name__"),make_string ctx name pos));
|
|
|
|
|
- op ctx (OSetGlobal (g,r));
|
|
|
|
|
|
|
+ ) types;
|
|
|
|
|
|
|
|
- let bytes = alloc_tmp ctx HBytes in
|
|
|
|
|
- op ctx (OString (bytes, alloc_string ctx name));
|
|
|
|
|
- op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",bytes,r));
|
|
|
|
|
- | _ ->
|
|
|
|
|
- ())
|
|
|
|
|
- | _ ->
|
|
|
|
|
- ()
|
|
|
|
|
|
|
+ let j = jump ctx (fun d -> OJTrue (is_init,d)) in
|
|
|
|
|
+ op ctx (ORet (alloc_tmp ctx HVoid));
|
|
|
|
|
+ j();
|
|
|
|
|
+ free ctx is_init;
|
|
|
|
|
+ ignore(eval_expr ctx f.tf_expr);
|
|
|
|
|
+ op ctx (ORet (alloc_tmp ctx HVoid))
|
|
|
|
|
|
|
|
- ) types;
|
|
|
|
|
|
|
+let generate_static_init ctx types main =
|
|
|
|
|
+ let exprs = ref [] in
|
|
|
|
|
+ let t_void = ctx.com.basic.tvoid in
|
|
|
|
|
|
|
|
- let j = jump ctx (fun d -> OJTrue (is_init,d)) in
|
|
|
|
|
- op ctx (ORet (alloc_tmp ctx HVoid));
|
|
|
|
|
- j();
|
|
|
|
|
- free ctx is_init;
|
|
|
|
|
- in
|
|
|
|
|
(* init class statics *)
|
|
(* init class statics *)
|
|
|
let init_exprs = ref [] in
|
|
let init_exprs = ref [] in
|
|
|
List.iter (fun t ->
|
|
List.iter (fun t ->
|
|
|
- (match t with TClassDecl { cl_init = Some {cf_expr = Some e} } -> init_exprs := e :: !init_exprs | _ -> ());
|
|
|
|
|
|
|
+ (match t with TClassDecl ({ cl_init = Some {cf_expr = Some e} } as c) when not (is_excluded c) -> init_exprs := e :: !init_exprs | _ -> ());
|
|
|
match t with
|
|
match t with
|
|
|
- | TClassDecl c when not (has_class_flag c CExtern) ->
|
|
|
|
|
|
|
+ | TClassDecl c when not (has_class_flag c CExtern) && not (is_excluded c) ->
|
|
|
List.iter (fun f ->
|
|
List.iter (fun f ->
|
|
|
match f.cf_kind, f.cf_expr with
|
|
match f.cf_kind, f.cf_expr with
|
|
|
| Var _, Some e ->
|
|
| Var _, Some e ->
|
|
@@ -3836,7 +3844,9 @@ let generate_static_init ctx types main =
|
|
|
let fid = lookup_alloc ctx.cfids () in
|
|
let fid = lookup_alloc ctx.cfids () in
|
|
|
let exprs = List.rev !init_exprs @ List.rev !exprs in
|
|
let exprs = List.rev !init_exprs @ List.rev !exprs in
|
|
|
let initpos = fake_pos "fun$init" in
|
|
let initpos = fake_pos "fun$init" in
|
|
|
- ignore(make_fun ~gen_content ctx ("","") fid { tf_expr = mk (TBlock exprs) t_void initpos; tf_args = []; tf_type = t_void } None None);
|
|
|
|
|
|
|
+ let f = { tf_expr = mk (TBlock exprs) t_void initpos; tf_args = []; tf_type = t_void } in
|
|
|
|
|
+ let gen_content() = generate_static_content ctx types f in
|
|
|
|
|
+ ignore(make_fun ~gen_content ctx ("","") fid f None None);
|
|
|
fid
|
|
fid
|
|
|
|
|
|
|
|
(* --------------------------------------------------------------------------------------------------------------------- *)
|
|
(* --------------------------------------------------------------------------------------------------------------------- *)
|