|
@@ -107,39 +107,6 @@ let emit_mk_pos exec1 exec2 exec3 env =
|
|
|
let max = exec3 env in
|
|
|
encode_pos { pfile = decode_string file; pmin = decode_int min; pmax = decode_int max }
|
|
|
|
|
|
-let emit_enum_construction0 key i p env =
|
|
|
- encode_enum_value key i [||] p
|
|
|
-
|
|
|
-let emit_enum_construction1 key i exec1 p env =
|
|
|
- let v1 = exec1 env in
|
|
|
- encode_enum_value key i [|v1|] p
|
|
|
-
|
|
|
-let emit_enum_construction2 key i exec1 exec2 p env =
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- encode_enum_value key i [|v1;v2|] p
|
|
|
-
|
|
|
-let emit_enum_construction3 key i exec1 exec2 exec3 p env =
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- encode_enum_value key i [|v1;v2;v3|] p
|
|
|
-
|
|
|
-let emit_enum_construction4 key i exec1 exec2 exec3 exec4 p env =
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- encode_enum_value key i [|v1;v2;v3;v4|] p
|
|
|
-
|
|
|
-let emit_enum_construction5 key i exec1 exec2 exec3 exec4 exec5 p env =
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- let v5 = exec5 env in
|
|
|
- encode_enum_value key i [|v1;v2;v3;v4;v5|] p
|
|
|
-
|
|
|
let emit_enum_construction key i execs p env =
|
|
|
encode_enum_value key i (Array.map (fun exec -> exec env) execs) p
|
|
|
|
|
@@ -150,56 +117,6 @@ let emit_if exec_cond exec_then exec_else env =
|
|
|
| VTrue -> exec_then env
|
|
|
| _ -> exec_else env
|
|
|
|
|
|
-let emit_enum_switch_array exec cases exec_def p env = match exec env with
|
|
|
- | VEnumValue ev ->
|
|
|
- let i = ev.eindex in
|
|
|
- if i >= Array.length cases || i < 0 then exec_def env
|
|
|
- else (Array.unsafe_get cases i) env
|
|
|
- | v ->
|
|
|
- unexpected_value_p v "enum value" p
|
|
|
-
|
|
|
-let emit_int_switch_array exec cases exec_def p env = match exec env with
|
|
|
- | VInt32 i32 ->
|
|
|
- let i = Int32.to_int i32 in
|
|
|
- if i >= Array.length cases || i < 0 then exec_def env
|
|
|
- else (Array.unsafe_get cases i) env
|
|
|
- | VNull ->
|
|
|
- exec_def env
|
|
|
- | v ->
|
|
|
- unexpected_value_p v "int" p
|
|
|
-
|
|
|
-let emit_int_switch_array_shift shift exec cases exec_def p env = match exec env with
|
|
|
- | VInt32 i32 ->
|
|
|
- let i = Int32.to_int i32 + shift in
|
|
|
- if i >= Array.length cases || i < 0 then exec_def env
|
|
|
- else (Array.unsafe_get cases i) env
|
|
|
- | VNull ->
|
|
|
- exec_def env
|
|
|
- | v ->
|
|
|
- unexpected_value_p v "int" p
|
|
|
-
|
|
|
-let emit_int_switch_map exec cases exec_def p env = match exec env with
|
|
|
- | VInt32 i32 ->
|
|
|
- let i = Int32.to_int i32 in
|
|
|
- begin try
|
|
|
- (IntMap.find i cases) env
|
|
|
- with Not_found ->
|
|
|
- exec_def env
|
|
|
- end
|
|
|
- | v ->
|
|
|
- unexpected_value_p v "int" p
|
|
|
-
|
|
|
-let emit_constant_switch exec execs constants exec_def env =
|
|
|
- let v1 = exec env in
|
|
|
- let rec loop v1 i =
|
|
|
- if i >= Array.length constants then exec_def env
|
|
|
- else if List.exists (fun v2 -> equals v1 v2) (Array.unsafe_get constants i) then
|
|
|
- (Array.unsafe_get execs i) env
|
|
|
- else
|
|
|
- loop v1 (i + 1)
|
|
|
- in
|
|
|
- loop v1 0
|
|
|
-
|
|
|
let emit_switch exec execs patterns exec_def env =
|
|
|
let v1 = exec env in
|
|
|
let rec loop v1 i =
|
|
@@ -211,99 +128,16 @@ let emit_switch exec execs patterns exec_def env =
|
|
|
in
|
|
|
loop v1 0
|
|
|
|
|
|
-let emit_int_iterator slot exec1 exec2 p1 p2 env =
|
|
|
- let i1 = decode_int_p (env.env_locals.(slot)) p1 in
|
|
|
- let i2 = decode_int_p (exec1 env) p2 in
|
|
|
- for i = i1 to i2 - 1 do
|
|
|
- env.env_locals.(slot) <- vint i;
|
|
|
- ignore(exec2 env);
|
|
|
- done;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_int_iterator_continue slot exec1 exec2 p1 p2 env =
|
|
|
- let i1 = decode_int_p (env.env_locals.(slot)) p1 in
|
|
|
- let i2 = decode_int_p (exec1 env) p2 in
|
|
|
- for i = i1 to i2 - 1 do
|
|
|
- env.env_locals.(slot) <- vint i;
|
|
|
- (try ignore(exec2 env) with Continue -> ())
|
|
|
- done;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_int_iterator_break slot exec1 exec2 p1 p2 env =
|
|
|
- let i1 = decode_int_p (env.env_locals.(slot)) p1 in
|
|
|
- let i2 = decode_int_p (exec1 env) p2 in
|
|
|
- begin try
|
|
|
- for i = i1 to i2 - 1 do
|
|
|
- env.env_locals.(slot) <- vint i;
|
|
|
- ignore(exec2 env);
|
|
|
- done;
|
|
|
- with Break ->
|
|
|
- ()
|
|
|
- end;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_int_iterator_break_continue slot exec1 exec2 p1 p2 env =
|
|
|
- let i1 = decode_int_p (env.env_locals.(slot)) p1 in
|
|
|
- let i2 = decode_int_p (exec1 env) p1 in
|
|
|
- begin try
|
|
|
- for i = i1 to i2 - 1 do
|
|
|
- env.env_locals.(slot) <- vint i;
|
|
|
- (try ignore(exec2 env) with Continue -> ())
|
|
|
- done;
|
|
|
- with Break ->
|
|
|
- ()
|
|
|
- end;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_while_gte exec1 f exec2 env =
|
|
|
- while (num (exec1 env) >= f) do exec2 env done;
|
|
|
- vnull
|
|
|
-
|
|
|
let rec run_while_continue exec_cond exec_body env =
|
|
|
try
|
|
|
while is_true (exec_cond env) do exec_body env done;
|
|
|
with Continue ->
|
|
|
run_while_continue exec_cond exec_body env
|
|
|
|
|
|
-let emit_while exec_cond exec_body env =
|
|
|
- while is_true (exec_cond env) do exec_body env done;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_while_break exec_cond exec_body env =
|
|
|
- begin try
|
|
|
- while is_true (exec_cond env) do exec_body env done;
|
|
|
- with Break ->
|
|
|
- ()
|
|
|
- end;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_while_continue exec_cond exec_body env =
|
|
|
- run_while_continue exec_cond exec_body env;
|
|
|
- vnull
|
|
|
-
|
|
|
let emit_while_break_continue exec_cond exec_body env =
|
|
|
(try run_while_continue exec_cond exec_body env with Break -> ());
|
|
|
vnull
|
|
|
|
|
|
-let emit_do_while exec_cond exec_body env =
|
|
|
- ignore(exec_body env);
|
|
|
- while is_true (exec_cond env) do exec_body env done;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_do_while_break exec_cond exec_body env =
|
|
|
- begin try
|
|
|
- ignore(exec_body env);
|
|
|
- while is_true (exec_cond env) do exec_body env done;
|
|
|
- with Break ->
|
|
|
- ()
|
|
|
- end;
|
|
|
- vnull
|
|
|
-
|
|
|
-let emit_do_while_continue exec_cond exec_body env =
|
|
|
- (try ignore(exec_body env) with Continue -> ());
|
|
|
- run_while_continue exec_cond exec_body env;
|
|
|
- vnull
|
|
|
-
|
|
|
let emit_do_while_break_continue exec_cond exec_body env =
|
|
|
begin try
|
|
|
ignore(exec_body env); run_while_continue exec_cond exec_body env
|
|
@@ -347,31 +181,6 @@ let emit_try exec catches env =
|
|
|
|
|
|
(* Control flow *)
|
|
|
|
|
|
-let emit_block1 exec1 env =
|
|
|
- exec1 env
|
|
|
-
|
|
|
-let emit_block2 exec1 exec2 env =
|
|
|
- ignore(exec1 env);
|
|
|
- exec2 env
|
|
|
-
|
|
|
-let emit_block3 exec1 exec2 exec3 env =
|
|
|
- ignore(exec1 env);
|
|
|
- ignore(exec2 env);
|
|
|
- exec3 env
|
|
|
-
|
|
|
-let emit_block4 exec1 exec2 exec3 exec4 env =
|
|
|
- ignore(exec1 env);
|
|
|
- ignore(exec2 env);
|
|
|
- ignore(exec3 env);
|
|
|
- exec4 env
|
|
|
-
|
|
|
-let emit_block5 exec1 exec2 exec3 exec4 exec5 env =
|
|
|
- ignore(exec1 env);
|
|
|
- ignore(exec2 env);
|
|
|
- ignore(exec3 env);
|
|
|
- ignore(exec4 env);
|
|
|
- exec5 env
|
|
|
-
|
|
|
let emit_block execs env =
|
|
|
let l = Array.length execs in
|
|
|
for i = 0 to l - 2 do
|
|
@@ -409,134 +218,15 @@ let emit_super_field_call slot proto i execs p env =
|
|
|
|
|
|
(* Type.call() - immediate *)
|
|
|
|
|
|
-let call0 v p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun0 f,_) -> f ()
|
|
|
- | VFunction (FunN f,_) -> f []
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0]
|
|
|
- | VInstance {ikind = ILazyType(_,get)} -> get()
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
-let call1 v v1 p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun1 f,_) -> f v1
|
|
|
- | VFunction (FunN f,_) -> f [v1]
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0;v1]
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
-let call2 v v1 v2 p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun2 f,_) -> f v1 v2
|
|
|
- | VFunction (FunN f,_) -> f [v1;v2]
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0;v1;v2]
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
-let call3 v v1 v2 v3 p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun3 f,_) -> f v1 v2 v3
|
|
|
- | VFunction (FunN f,_) -> f [v1;v2;v3]
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0;v1;v2;v3]
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
-let call4 v v1 v2 v3 v4 p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun4 f,_) -> f v1 v2 v3 v4
|
|
|
- | VFunction (FunN f,_) -> f [v1;v2;v3;v4]
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0;v1;v2;v3;v4]
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
-let call5 v v1 v2 v3 v4 v5 p env =
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- match v with
|
|
|
- | VFunction (Fun5 f,_) -> f v1 v2 v3 v4 v5
|
|
|
- | VFunction (FunN f,_) -> f [v1;v2;v3;v4;v5]
|
|
|
- | VFieldClosure(v0,f) -> call_function f [v0;v1;v2;v3;v4;v5]
|
|
|
- | _ -> cannot_call v p
|
|
|
-
|
|
|
let emit_proto_field_call proto i execs p =
|
|
|
- match execs with
|
|
|
- | [] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun0 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- (Lazy.force vf) ()
|
|
|
- )
|
|
|
- | [exec1] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun1 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let v1 = exec1 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f v1
|
|
|
- )
|
|
|
- | [exec1;exec2] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun2 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f v1 v2
|
|
|
- )
|
|
|
- | [exec1;exec2;exec3] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun3 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f v1 v2 v3
|
|
|
- )
|
|
|
- | [exec1;exec2;exec3;exec4] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun4 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f v1 v2 v3 v4
|
|
|
- )
|
|
|
- | [exec1;exec2;exec3;exec4;exec5] ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (Fun5 f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- let v5 = exec5 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f v1 v2 v3 v4 v5
|
|
|
- )
|
|
|
- | _ ->
|
|
|
- let vf = lazy (match proto.pfields.(i) with VFunction (FunN f,_) -> f | v -> cannot_call v p) in
|
|
|
- (fun env ->
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vl = List.map (fun exec -> exec env) execs in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- f vl
|
|
|
- )
|
|
|
+ let vf = lazy (match proto.pfields.(i) with VFunction (f,_) -> f | v -> cannot_call v p) in
|
|
|
+ (fun env ->
|
|
|
+ let f = Lazy.force vf in
|
|
|
+ let vl = List.map (fun exec -> exec env) execs in
|
|
|
+ env.env_leave_pmin <- p.pmin;
|
|
|
+ env.env_leave_pmax <- p.pmax;
|
|
|
+ f vl
|
|
|
+ )
|
|
|
|
|
|
(* instance.call() where call is overridden - dynamic dispatch *)
|
|
|
|
|
@@ -548,56 +238,14 @@ let emit_method_call exec name execs p =
|
|
|
| VVector _ -> proto_field_raise (get_ctx()).vector_prototype name
|
|
|
| _ -> unexpected_value_p vthis "instance" p
|
|
|
in
|
|
|
- match execs with
|
|
|
- | [] ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- call1 vf vthis p env
|
|
|
- )
|
|
|
- | [exec1] ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- let v1 = exec1 env in
|
|
|
- call2 vf vthis v1 p env
|
|
|
- )
|
|
|
- | [exec1;exec2] ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- call3 vf vthis v1 v2 p env
|
|
|
- )
|
|
|
- | [exec1;exec2;exec3] ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- call4 vf vthis v1 v2 v3 p env
|
|
|
- )
|
|
|
- | [exec1;exec2;exec3;exec4] ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- call5 vf vthis v1 v2 v3 v4 p env
|
|
|
- )
|
|
|
- | _ ->
|
|
|
- (fun env ->
|
|
|
- let vthis = exec env in
|
|
|
- let vf = vf vthis in
|
|
|
- let vl = List.map (apply env) execs in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- call_value_on vthis vf vl
|
|
|
- )
|
|
|
+ (fun env ->
|
|
|
+ let vthis = exec env in
|
|
|
+ let vf = vf vthis in
|
|
|
+ let vl = List.map (apply env) execs in
|
|
|
+ env.env_leave_pmin <- p.pmin;
|
|
|
+ env.env_leave_pmax <- p.pmax;
|
|
|
+ call_value_on vthis vf vl
|
|
|
+ )
|
|
|
|
|
|
(* instance.call() where call is not a method - lookup + this-binding *)
|
|
|
|
|
@@ -610,55 +258,6 @@ let emit_field_call exec name execs p env =
|
|
|
|
|
|
(* new() - immediate + this-binding *)
|
|
|
|
|
|
-let emit_constructor_call0 proto vf p env =
|
|
|
- let vthis = create_instance_direct proto in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore((Lazy.force vf) vthis);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_constructor_call1 proto vf exec1 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = create_instance_direct proto in
|
|
|
- let v1 = exec1 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_constructor_call2 proto vf exec1 exec2 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = create_instance_direct proto in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_constructor_call3 proto vf exec1 exec2 exec3 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = create_instance_direct proto in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2 v3);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_constructor_call4 proto vf exec1 exec2 exec3 exec4 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = create_instance_direct proto in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2 v3 v4);
|
|
|
- vthis
|
|
|
-
|
|
|
let emit_constructor_callN proto vf execs p env =
|
|
|
let f = Lazy.force vf in
|
|
|
let vthis = create_instance_direct proto in
|
|
@@ -669,77 +268,11 @@ let emit_constructor_callN proto vf execs p env =
|
|
|
vthis
|
|
|
|
|
|
let emit_constructor_call proto fnew execs p =
|
|
|
- match execs with
|
|
|
- | [] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun1 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_call0 proto vf p
|
|
|
- | [exec1] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun2 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_call1 proto vf exec1 p
|
|
|
- | [exec1;exec2] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun3 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_call2 proto vf exec1 exec2 p
|
|
|
- | [exec1;exec2;exec3] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun4 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_call3 proto vf exec1 exec2 exec3 p
|
|
|
- | [exec1;exec2;exec3;exec4] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun5 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_call4 proto vf exec1 exec2 exec3 exec4 p
|
|
|
- | _ ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (FunN f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_constructor_callN proto vf execs p
|
|
|
+ let vf = lazy (match Lazy.force fnew with VFunction (f,_) -> f | v -> cannot_call v p) in
|
|
|
+ emit_constructor_callN proto vf execs p
|
|
|
|
|
|
(* super() - immediate + this-binding *)
|
|
|
|
|
|
-let emit_super_call0 vf p env =
|
|
|
- let vthis = env.env_locals.(0) in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore((Lazy.force vf) vthis);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_super_call1 vf exec1 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = env.env_locals.(0) in
|
|
|
- let v1 = exec1 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_super_call2 vf exec1 exec2 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = env.env_locals.(0) in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_super_call3 vf exec1 exec2 exec3 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = env.env_locals.(0) in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2 v3);
|
|
|
- vthis
|
|
|
-
|
|
|
-let emit_super_call4 vf exec1 exec2 exec3 exec4 p env =
|
|
|
- let f = Lazy.force vf in
|
|
|
- let vthis = env.env_locals.(0) in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- env.env_leave_pmin <- p.pmin;
|
|
|
- env.env_leave_pmax <- p.pmax;
|
|
|
- ignore(f vthis v1 v2 v3 v4);
|
|
|
- vthis
|
|
|
-
|
|
|
let emit_super_callN vf execs p env =
|
|
|
let f = Lazy.force vf in
|
|
|
let vthis = env.env_locals.(0) in
|
|
@@ -761,66 +294,11 @@ let emit_special_super_call fnew execs env =
|
|
|
vnull
|
|
|
|
|
|
let emit_super_call fnew execs p =
|
|
|
- match execs with
|
|
|
- | [] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun1 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_call0 vf p
|
|
|
- | [exec1] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun2 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_call1 vf exec1 p
|
|
|
- | [exec1;exec2] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun3 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_call2 vf exec1 exec2 p
|
|
|
- | [exec1;exec2;exec3] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun4 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_call3 vf exec1 exec2 exec3 p
|
|
|
- | [exec1;exec2;exec3;exec4] ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (Fun5 f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_call4 vf exec1 exec2 exec3 exec4 p
|
|
|
- | _ ->
|
|
|
- let vf = lazy (match Lazy.force fnew with VFunction (FunN f,_) -> f | v -> cannot_call v p) in
|
|
|
- emit_super_callN vf execs p
|
|
|
+ let vf = lazy (match Lazy.force fnew with VFunction (f,_) -> f | v -> cannot_call v p) in
|
|
|
+ emit_super_callN vf execs p
|
|
|
|
|
|
(* unknown call - full lookup *)
|
|
|
|
|
|
-let emit_call0 exec p env =
|
|
|
- call0 (exec env) p env
|
|
|
-
|
|
|
-let emit_call1 exec exec1 p env =
|
|
|
- let v0 = exec env in
|
|
|
- let v1 = exec1 env in
|
|
|
- call1 v0 v1 p env
|
|
|
-
|
|
|
-let emit_call2 exec exec1 exec2 p env =
|
|
|
- let v0 = exec env in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- call2 v0 v1 v2 p env
|
|
|
-
|
|
|
-let emit_call3 exec exec1 exec2 exec3 p env =
|
|
|
- let v0 = exec env in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- call3 v0 v1 v2 v3 p env
|
|
|
-
|
|
|
-let emit_call4 exec exec1 exec2 exec3 exec4 p env =
|
|
|
- let v0 = exec env in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- call4 v0 v1 v2 v3 v4 p env
|
|
|
-
|
|
|
-let emit_call5 exec exec1 exec2 exec3 exec4 exec5 p env =
|
|
|
- let v0 = exec env in
|
|
|
- let v1 = exec1 env in
|
|
|
- let v2 = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let v4 = exec4 env in
|
|
|
- let v5 = exec5 env in
|
|
|
- call5 v0 v1 v2 v3 v4 v5 p env
|
|
|
-
|
|
|
let emit_call exec execs p env =
|
|
|
let v1 = exec env in
|
|
|
env.env_leave_pmin <- p.pmin;
|
|
@@ -848,11 +326,6 @@ let emit_bytes_length_read exec env = match exec env with
|
|
|
let emit_proto_field_read proto i env =
|
|
|
proto.pfields.(i)
|
|
|
|
|
|
-let emit_instance_local_field_read iv i env = match env.env_locals.(iv) with
|
|
|
- | VInstance vi -> vi.ifields.(i)
|
|
|
- | VString(_,s) -> vint (String.length (Lazy.force s))
|
|
|
- | v -> unexpected_value v "instance"
|
|
|
-
|
|
|
let emit_instance_field_read exec i env = match exec env with
|
|
|
| VInstance vi -> vi.ifields.(i)
|
|
|
| VString(_,s) -> vint (String.length (Lazy.force s))
|
|
@@ -862,14 +335,6 @@ let emit_field_closure exec name env =
|
|
|
let v = exec env in
|
|
|
dynamic_field v name
|
|
|
|
|
|
-let emit_anon_local_field_read iv proto i name p env =
|
|
|
- match env.env_locals.(iv) with
|
|
|
- | VObject o ->
|
|
|
- if proto == o.oproto then o.ofields.(i)
|
|
|
- else object_field o name
|
|
|
- | VNull -> throw_string "field access on null" p
|
|
|
- | v -> field v name
|
|
|
-
|
|
|
let emit_anon_field_read exec proto i name p env =
|
|
|
match exec env with
|
|
|
| VObject o ->
|
|
@@ -882,13 +347,6 @@ let emit_field_read exec name p env = match exec env with
|
|
|
| VNull -> throw_string "field access on null" p
|
|
|
| v -> field v name
|
|
|
|
|
|
-let emit_array_local_read i exec2 p env =
|
|
|
- let va = env.env_locals.(i) in
|
|
|
- let vi = exec2 env in
|
|
|
- let i = decode_int_p vi p in
|
|
|
- if i < 0 then vnull
|
|
|
- else EvalArray.get (decode_varray va) i
|
|
|
-
|
|
|
let emit_array_read exec1 exec2 p env =
|
|
|
let va = exec1 env in
|
|
|
let vi = exec2 env in
|
|
@@ -896,13 +354,6 @@ let emit_array_read exec1 exec2 p env =
|
|
|
if i < 0 then vnull
|
|
|
else EvalArray.get (decode_varray va) i
|
|
|
|
|
|
-let emit_vector_local_read i exec2 p env =
|
|
|
- let vv = env.env_locals.(i) in
|
|
|
- let vi = exec2 env in
|
|
|
- let i = decode_int_p vi p in
|
|
|
- if i < 0 then vnull
|
|
|
- else Array.unsafe_get (decode_vector vv) i
|
|
|
-
|
|
|
let emit_vector_read exec1 exec2 p env =
|
|
|
let vv = exec1 env in
|
|
|
let vi = exec2 env in
|
|
@@ -974,15 +425,6 @@ let emit_field_write exec1 name exec2 env =
|
|
|
set_field v1 name v2;
|
|
|
v2
|
|
|
|
|
|
-let emit_array_local_write i exec2 exec3 p env =
|
|
|
- let va = env.env_locals.(i) in
|
|
|
- let vi = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let i = decode_int_p vi p in
|
|
|
- if i < 0 then throw_string (Printf.sprintf "Negative array index: %i" i) p;
|
|
|
- EvalArray.set (decode_varray va) i v3;
|
|
|
- v3
|
|
|
-
|
|
|
let emit_array_write exec1 exec2 exec3 p env =
|
|
|
let va = exec1 env in
|
|
|
let vi = exec2 env in
|
|
@@ -992,15 +434,6 @@ let emit_array_write exec1 exec2 exec3 p env =
|
|
|
EvalArray.set (decode_varray va) i v3;
|
|
|
v3
|
|
|
|
|
|
-let emit_vector_local_write i exec2 exec3 p env =
|
|
|
- let vv = env.env_locals.(i) in
|
|
|
- let vi = exec2 env in
|
|
|
- let v3 = exec3 env in
|
|
|
- let i = decode_int_p vi p in
|
|
|
- if i < 0 then throw_string (Printf.sprintf "Negative vector index: %i" i) p;
|
|
|
- Array.unsafe_set (decode_vector vv) i v3;
|
|
|
- v3
|
|
|
-
|
|
|
let emit_vector_write exec1 exec2 exec3 p env =
|
|
|
let vv = exec1 env in
|
|
|
let vi = exec2 env in
|
|
@@ -1019,28 +452,6 @@ let emit_local_read_write slot exec fop prefix env =
|
|
|
env.env_locals.(slot) <- v;
|
|
|
if prefix then v else v1
|
|
|
|
|
|
-let emit_local_incr_postfix slot env =
|
|
|
- let vi = env.env_locals.(slot) in
|
|
|
- env.env_locals.(slot) <- vint32 (Int32.succ (decode_i32 vi));
|
|
|
- vi
|
|
|
-
|
|
|
-let emit_local_incr_prefix slot env =
|
|
|
- let vi = env.env_locals.(slot) in
|
|
|
- let v = vint32 (Int32.succ (decode_i32 vi)) in
|
|
|
- env.env_locals.(slot) <- v;
|
|
|
- v
|
|
|
-
|
|
|
-let emit_local_decr_postfix slot env =
|
|
|
- let vi = env.env_locals.(slot) in
|
|
|
- env.env_locals.(slot) <- vint32 (Int32.pred (decode_i32 vi));
|
|
|
- vi
|
|
|
-
|
|
|
-let emit_local_decr_prefix slot env =
|
|
|
- let vi = env.env_locals.(slot) in
|
|
|
- let v = vint32 (Int32.pred (decode_i32 vi)) in
|
|
|
- env.env_locals.(slot) <- v;
|
|
|
- v
|
|
|
-
|
|
|
let emit_capture_read_write slot exec fop prefix env =
|
|
|
let v1 = !(env.env_captures.(slot)) in
|
|
|
let v2 = exec env in
|
|
@@ -1048,28 +459,6 @@ let emit_capture_read_write slot exec fop prefix env =
|
|
|
env.env_captures.(slot) := v;
|
|
|
if prefix then v else v1
|
|
|
|
|
|
-let emit_capture_incr_postfix slot env =
|
|
|
- let vi = !(env.env_captures.(slot)) in
|
|
|
- env.env_captures.(slot) := vint32 (Int32.succ (decode_i32 vi));
|
|
|
- vi
|
|
|
-
|
|
|
-let emit_capture_incr_prefix slot env =
|
|
|
- let vi = !(env.env_captures.(slot)) in
|
|
|
- let v = vint32 (Int32.succ (decode_i32 vi)) in
|
|
|
- env.env_captures.(slot) := v;
|
|
|
- v
|
|
|
-
|
|
|
-let emit_capture_decr_postfix slot env =
|
|
|
- let vi = !(env.env_captures.(slot)) in
|
|
|
- env.env_captures.(slot) := vint32 (Int32.pred (decode_i32 vi));
|
|
|
- vi
|
|
|
-
|
|
|
-let emit_capture_decr_prefix slot env =
|
|
|
- let vi = !(env.env_captures.(slot)) in
|
|
|
- let v = vint32 (Int32.pred (decode_i32 vi)) in
|
|
|
- env.env_captures.(slot) := v;
|
|
|
- v
|
|
|
-
|
|
|
let emit_proto_field_read_write proto i exec2 fop prefix env =
|
|
|
let vf = proto.pfields.(i) in
|
|
|
let v2 = exec2 env in
|
|
@@ -1110,18 +499,6 @@ let emit_field_read_write exec1 name exec2 fop prefix env =
|
|
|
set_field v1 name v;
|
|
|
if prefix then v else vf
|
|
|
|
|
|
-let emit_array_local_read_write i exec2 exec3 fop prefix p env =
|
|
|
- let va1 = env.env_locals.(i) in
|
|
|
- let va2 = exec2 env in
|
|
|
- let va = decode_varray va1 in
|
|
|
- let i = decode_int_p va2 p in
|
|
|
- if i < 0 then throw_string (Printf.sprintf "Negative array index: %i" i) p;
|
|
|
- let v = EvalArray.get va i in
|
|
|
- let v2 = exec3 env in
|
|
|
- let v3 = fop v v2 in
|
|
|
- EvalArray.set va i v3;
|
|
|
- if prefix then v3 else v
|
|
|
-
|
|
|
let emit_array_read_write exec1 exec2 exec3 fop prefix p env =
|
|
|
let va1 = exec1 env in
|
|
|
let va2 = exec2 env in
|
|
@@ -1134,18 +511,6 @@ let emit_array_read_write exec1 exec2 exec3 fop prefix p env =
|
|
|
EvalArray.set va i v3;
|
|
|
if prefix then v3 else v
|
|
|
|
|
|
-let emit_vector_local_read_write i exec2 exec3 fop prefix p env =
|
|
|
- let va1 = env.env_locals.(i) in
|
|
|
- let va2 = exec2 env in
|
|
|
- let va = decode_vector va1 in
|
|
|
- let i = decode_int_p va2 p in
|
|
|
- if i < 0 then throw_string (Printf.sprintf "Negative vector index: %i" i) p;
|
|
|
- let v = Array.unsafe_get va i in
|
|
|
- let v2 = exec3 env in
|
|
|
- let v3 = fop v v2 in
|
|
|
- Array.unsafe_set va i v3;
|
|
|
- if prefix then v3 else v
|
|
|
-
|
|
|
let emit_vector_read_write exec1 exec2 exec3 fop prefix p env =
|
|
|
let va1 = exec1 env in
|
|
|
let va2 = exec2 env in
|
|
@@ -1356,14 +721,12 @@ let run_function ctx exec env =
|
|
|
with
|
|
|
| Return v -> v
|
|
|
in
|
|
|
- env.env_in_use <- false;
|
|
|
pop_environment ctx env;
|
|
|
v
|
|
|
[@@inline]
|
|
|
|
|
|
let run_function_noret ctx exec env =
|
|
|
let v = exec env in
|
|
|
- env.env_in_use <- false;
|
|
|
pop_environment ctx env;
|
|
|
v
|
|
|
[@@inline]
|
|
@@ -1376,127 +739,21 @@ let get_closure_env ctx info num_locals num_captures refs =
|
|
|
Array.iteri (fun i vr -> env.env_captures.(i) <- vr) refs;
|
|
|
env
|
|
|
|
|
|
-let get_normal_env_opt ctx default_env info num_locals num_captures _ =
|
|
|
- if default_env.env_in_use then begin
|
|
|
- push_environment ctx info num_locals num_captures
|
|
|
- end else begin
|
|
|
- default_env.env_in_use <- true;
|
|
|
- default_env
|
|
|
- end
|
|
|
-
|
|
|
-let get_closure_env_opt ctx default_env info num_locals num_captures refs =
|
|
|
- let env = if default_env.env_in_use then begin
|
|
|
- push_environment ctx info num_locals num_captures
|
|
|
- end else begin
|
|
|
- default_env.env_in_use <- true;
|
|
|
- default_env
|
|
|
- end in
|
|
|
- Array.iteri (fun i vr -> env.env_captures.(i) <- vr) refs;
|
|
|
- env
|
|
|
-
|
|
|
let create_function ctx num_args get_env hasret refs exec =
|
|
|
- match num_args with
|
|
|
- | 0 ->
|
|
|
- if hasret then Fun0 (fun () ->
|
|
|
- let env = get_env refs in
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun0 (fun () ->
|
|
|
- let env = get_env refs in
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | 1 ->
|
|
|
- if hasret then Fun1 (fun v1 ->
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun1 (fun v1 ->
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | 2 ->
|
|
|
- let run v1 v2 =
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- env.env_locals.(1) <- v2;
|
|
|
- env
|
|
|
- in
|
|
|
- if hasret then Fun2 (fun v1 v2 ->
|
|
|
- let env = run v1 v2 in
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun2 (fun v1 v2 ->
|
|
|
- let env = run v1 v2 in
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | 3 ->
|
|
|
- let run v1 v2 v3 =
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- env.env_locals.(1) <- v2;
|
|
|
- env.env_locals.(2) <- v3;
|
|
|
- env
|
|
|
- in
|
|
|
- if hasret then Fun3 (fun v1 v2 v3 ->
|
|
|
- let env = run v1 v2 v3 in
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun3 (fun v1 v2 v3 ->
|
|
|
- let env = run v1 v2 v3 in
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | 4 ->
|
|
|
- let run v1 v2 v3 v4 =
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- env.env_locals.(1) <- v2;
|
|
|
- env.env_locals.(2) <- v3;
|
|
|
- env.env_locals.(3) <- v4;
|
|
|
- env
|
|
|
- in
|
|
|
- if hasret then Fun4 (fun v1 v2 v3 v4 ->
|
|
|
- let env = run v1 v2 v3 v4 in
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun4 (fun v1 v2 v3 v4 ->
|
|
|
- let env = run v1 v2 v3 v4 in
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | 5 ->
|
|
|
- let run v1 v2 v3 v4 v5 =
|
|
|
- let env = get_env refs in
|
|
|
- env.env_locals.(0) <- v1;
|
|
|
- env.env_locals.(1) <- v2;
|
|
|
- env.env_locals.(2) <- v3;
|
|
|
- env.env_locals.(3) <- v4;
|
|
|
- env.env_locals.(4) <- v5;
|
|
|
- env
|
|
|
- in
|
|
|
- if hasret then Fun5 (fun v1 v2 v3 v4 v5 ->
|
|
|
- let env = run v1 v2 v3 v4 v5 in
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else Fun5 (fun v1 v2 v3 v4 v5 ->
|
|
|
- let env = run v1 v2 v3 v4 v5 in
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
- | _ ->
|
|
|
- if hasret then FunN (fun vl ->
|
|
|
- let env = get_env refs in
|
|
|
- List.iteri (fun i v ->
|
|
|
- env.env_locals.(i) <- v
|
|
|
- ) vl;
|
|
|
- run_function ctx exec env
|
|
|
- )
|
|
|
- else FunN (fun vl ->
|
|
|
- let env = get_env refs in
|
|
|
- List.iteri (fun i v ->
|
|
|
- env.env_locals.(i) <- v
|
|
|
- ) vl;
|
|
|
- run_function_noret ctx exec env
|
|
|
- )
|
|
|
+ if hasret then (fun vl ->
|
|
|
+ let env = get_env refs in
|
|
|
+ List.iteri (fun i v ->
|
|
|
+ env.env_locals.(i) <- v
|
|
|
+ ) vl;
|
|
|
+ run_function ctx exec env
|
|
|
+ )
|
|
|
+ else (fun vl ->
|
|
|
+ let env = get_env refs in
|
|
|
+ List.iteri (fun i v ->
|
|
|
+ env.env_locals.(i) <- v
|
|
|
+ ) vl;
|
|
|
+ run_function_noret ctx exec env
|
|
|
+ )
|
|
|
|
|
|
let emit_closure ctx num_captures num_args get_env hasret exec env =
|
|
|
let refs = Array.sub env.env_captures 0 num_captures in
|