|
@@ -623,7 +623,21 @@ let type_ident_raise ?(imported_enums=true) ctx i p mode =
|
|
| _ ->
|
|
| _ ->
|
|
try
|
|
try
|
|
let v = PMap.find i ctx.locals in
|
|
let v = PMap.find i ctx.locals in
|
|
- AKExpr (mk (TLocal v) v.v_type p)
|
|
|
|
|
|
+ (match v.v_extra with
|
|
|
|
+ | Some (params,e) ->
|
|
|
|
+ let t = monomorphs params v.v_type in
|
|
|
|
+ (match e with
|
|
|
|
+ | Some ({ eexpr = TFunction f } as e) ->
|
|
|
|
+ (* create a fake class with a fake field to emulate inlining *)
|
|
|
|
+ let c = mk_class ctx.current (["local"],v.v_name) e.epos in
|
|
|
|
+ let cf = { (mk_field v.v_name v.v_type e.epos) with cf_params = params; cf_expr = Some e; cf_kind = Method MethInline } in
|
|
|
|
+ c.cl_extern <- true;
|
|
|
|
+ c.cl_fields <- PMap.add cf.cf_name cf PMap.empty;
|
|
|
|
+ AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, t)
|
|
|
|
+ | _ ->
|
|
|
|
+ AKExpr (mk (TLocal v) t p))
|
|
|
|
+ | _ ->
|
|
|
|
+ AKExpr (mk (TLocal v) v.v_type p))
|
|
with Not_found -> try
|
|
with Not_found -> try
|
|
(* member variable lookup *)
|
|
(* member variable lookup *)
|
|
if ctx.curfun = FStatic then raise Not_found;
|
|
if ctx.curfun = FStatic then raise Not_found;
|
|
@@ -1877,6 +1891,9 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
| EUnop (op,flag,e) ->
|
|
| EUnop (op,flag,e) ->
|
|
type_unop ctx op flag e p
|
|
type_unop ctx op flag e p
|
|
| EFunction (name,f) ->
|
|
| EFunction (name,f) ->
|
|
|
|
+ let params = Typeload.type_function_params ctx f "localfun" [] p in
|
|
|
|
+ let old = ctx.type_params in
|
|
|
|
+ ctx.type_params <- params @ ctx.type_params;
|
|
let rt = Typeload.load_type_opt ctx p f.f_type in
|
|
let rt = Typeload.load_type_opt ctx p f.f_type in
|
|
let args = List.map (fun (s,opt,t,c) ->
|
|
let args = List.map (fun (s,opt,t,c) ->
|
|
let t = Typeload.load_type_opt ctx p t in
|
|
let t = Typeload.load_type_opt ctx p t in
|
|
@@ -1896,20 +1913,23 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
) args args2;
|
|
) args args2;
|
|
| _ -> ());
|
|
| _ -> ());
|
|
let ft = TFun (fun_args args,rt) in
|
|
let ft = TFun (fun_args args,rt) in
|
|
- let vname = (match name with
|
|
|
|
- | None -> None
|
|
|
|
- | Some v -> Some (add_local ctx v ft)
|
|
|
|
|
|
+ let inline, v = (match name with
|
|
|
|
+ | None -> false, None
|
|
|
|
+ | Some v when ExtString.String.starts_with v "inline_" -> true, Some (add_local ctx (String.sub v 7 (String.length v - 7)) ft)
|
|
|
|
+ | Some v -> false, Some (add_local ctx v ft)
|
|
) in
|
|
) in
|
|
let e , fargs = Typeload.type_function ctx args rt (match ctx.curfun with FStatic -> FStatic | _ -> FMemberLocal) f p in
|
|
let e , fargs = Typeload.type_function ctx args rt (match ctx.curfun with FStatic -> FStatic | _ -> FMemberLocal) f p in
|
|
|
|
+ ctx.type_params <- old;
|
|
let f = {
|
|
let f = {
|
|
tf_args = fargs;
|
|
tf_args = fargs;
|
|
tf_type = rt;
|
|
tf_type = rt;
|
|
tf_expr = e;
|
|
tf_expr = e;
|
|
} in
|
|
} in
|
|
let e = mk (TFunction f) ft p in
|
|
let e = mk (TFunction f) ft p in
|
|
- (match vname with
|
|
|
|
|
|
+ (match v with
|
|
| None -> e
|
|
| None -> e
|
|
| Some v ->
|
|
| Some v ->
|
|
|
|
+ if params <> [] || inline then v.v_extra <- Some (params,if inline then Some e else None);
|
|
let rec loop = function
|
|
let rec loop = function
|
|
| Codegen.Block f | Codegen.Loop f | Codegen.Function f -> f loop
|
|
| Codegen.Block f | Codegen.Loop f | Codegen.Function f -> f loop
|
|
| Codegen.Use v2 when v == v2 -> raise Exit
|
|
| Codegen.Use v2 when v == v2 -> raise Exit
|
|
@@ -1917,13 +1937,16 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
in
|
|
in
|
|
let is_rec = (try Codegen.local_usage loop e; false with Exit -> true) in
|
|
let is_rec = (try Codegen.local_usage loop e; false with Exit -> true) in
|
|
if is_rec then begin
|
|
if is_rec then begin
|
|
|
|
+ if inline then display_error ctx "Inline function cannot be recursive" e.epos;
|
|
let vnew = add_local ctx v.v_name ft in
|
|
let vnew = add_local ctx v.v_name ft in
|
|
mk (TVars [vnew,Some (mk (TBlock [
|
|
mk (TVars [vnew,Some (mk (TBlock [
|
|
mk (TVars [v,Some (mk (TConst TNull) ft p)]) ctx.t.tvoid p;
|
|
mk (TVars [v,Some (mk (TConst TNull) ft p)]) ctx.t.tvoid p;
|
|
mk (TBinop (OpAssign,mk (TLocal v) ft p,e)) ft p;
|
|
mk (TBinop (OpAssign,mk (TLocal v) ft p,e)) ft p;
|
|
mk (TLocal v) ft p
|
|
mk (TLocal v) ft p
|
|
]) ft p)]) ctx.t.tvoid p
|
|
]) ft p)]) ctx.t.tvoid p
|
|
- end else
|
|
|
|
|
|
+ end else if inline then
|
|
|
|
+ mk (TBlock []) ctx.t.tvoid p (* do not add variable since it will be inlined *)
|
|
|
|
+ else
|
|
mk (TVars [v,Some e]) ctx.t.tvoid p)
|
|
mk (TVars [v,Some e]) ctx.t.tvoid p)
|
|
| EUntyped e ->
|
|
| EUntyped e ->
|
|
let old = ctx.untyped in
|
|
let old = ctx.untyped in
|