소스 검색

Remove some eval optimizations (#6998)

* [eval] remove some optimizations

* [eval] remove function specializations

* [eval] remove block optimizations

* [eval] remove enum optimizations

* [eval] remove loop optimizations

* [eval] remove local optimizations

* [eval] remove switch optimizations

* [eval] remove Increment/Decrement optimizations
Simon Krajewski 7 년 전
부모
커밋
ce49e8a701

+ 5 - 61
src/macro/eval/evalContext.ml

@@ -60,7 +60,6 @@ type env = {
 	env_debug : env_debug;
 	mutable env_leave_pmin : int;
 	mutable env_leave_pmax : int;
-	mutable env_in_use : bool;
 	env_locals : value array;
 	env_captures : value ref array;
 }
@@ -122,7 +121,6 @@ type eval = {
 type context = {
 	ctx_id : int;
 	is_macro : bool;
-	record_stack : bool;
 	detail_times : bool;
 	builtins : builtins;
 	debug : debug;
@@ -171,29 +169,7 @@ let vstring s =
 let vstring_direct (r,s) =
 	VString(r,s)
 
-let call_function f vl = match f,vl with
-	| Fun0 f,_ -> f()
-	| Fun1 f,[] -> f vnull
-	| Fun1 f,(a :: _) -> f a
-	| Fun2 f,[] -> f vnull vnull
-	| Fun2 f,[a] -> f a vnull
-	| Fun2 f,(a :: b :: _) -> f a b
-	| Fun3 f,[] -> f vnull vnull vnull
-	| Fun3 f,[a] -> f a vnull vnull
-	| Fun3 f,[a;b] -> f a b vnull
-	| Fun3 f,(a :: b :: c :: _) -> f a b c
-	| Fun4 f,[] -> f vnull vnull vnull vnull
-	| Fun4 f,[a] -> f a vnull vnull vnull
-	| Fun4 f,[a;b] -> f a b vnull vnull
-	| Fun4 f,[a;b;c] -> f a b c vnull
-	| Fun4 f,(a :: b :: c :: d :: _) -> f a b c d
-	| Fun5 f,[] -> f vnull vnull vnull vnull vnull
-	| Fun5 f,[a] -> f a vnull vnull vnull vnull
-	| Fun5 f,[a;b] -> f a b vnull vnull vnull
-	| Fun5 f,[a;b;c] -> f a b c vnull vnull
-	| Fun5 f,[a;b;c;d] -> f a b c d vnull
-	| Fun5 f,(a :: b :: c :: d :: e :: _) -> f a b c d e
-	| FunN f,_ -> f vl
+let call_function f vl = f vl
 
 let object_fields o =
 	let fields = IntMap.fold (fun key vvalue acc -> (key,vvalue) :: acc) o.oextra [] in
@@ -217,15 +193,12 @@ let proto_fields proto =
 exception RunTimeException of value * env list * pos
 
 let call_stack ctx =
-	if not ctx.record_stack then
-		[]
-	else
-		List.rev (DynArray.to_list (DynArray.sub ctx.eval.environments 0 ctx.eval.environment_offset))
+	List.rev (DynArray.to_list (DynArray.sub ctx.eval.environments 0 ctx.eval.environment_offset))
 
 let throw v p =
 	let ctx = get_ctx() in
 	let eval = get_eval ctx in
-	if ctx.record_stack && eval.environment_offset > 0 then begin
+	if eval.environment_offset > 0 then begin
 		let env = DynArray.get eval.environments (eval.environment_offset - 1) in
 		env.env_leave_pmin <- p.pmin;
 		env.env_leave_pmax <- p.pmax;
@@ -248,13 +221,6 @@ let no_timer = fun () -> ()
 let empty_array = [||]
 let no_expr = mk (TConst TNull) t_dynamic null_pos
 
-let no_debug = {
-	timer = no_timer;
-	scopes = [];
-	line = 0;
-	expr = no_expr
-}
-
 let create_env_info static pfile kind capture_infos =
 	let info = {
 		static = static;
@@ -275,7 +241,6 @@ let push_environment_debug ctx info num_locals num_captures =
 		env_info = info;
 		env_leave_pmin = 0;
 		env_leave_pmax = 0;
-		env_in_use = false;
 		env_debug = {
 			timer = timer;
 			scopes = [];
@@ -292,17 +257,6 @@ let push_environment_debug ctx info num_locals num_captures =
 	eval.environment_offset <- eval.environment_offset + 1;
 	env
 
-let create_default_environment ctx info num_locals =
-	{
-		env_info = info;
-		env_leave_pmin = 0;
-		env_leave_pmax = 0;
-		env_in_use = false;
-		env_debug = no_debug;
-		env_locals = Array.make num_locals vnull;
-		env_captures = empty_array;
-	}
-
 let pop_environment_debug ctx env =
 	let eval = get_eval ctx in
 	eval.environment_offset <- eval.environment_offset - 1;
@@ -310,21 +264,11 @@ let pop_environment_debug ctx env =
 	()
 
 let push_environment ctx info num_locals num_captures =
-	if ctx.record_stack then
-		push_environment_debug ctx info num_locals num_captures
-	else {
-		env_info = info;
-		env_leave_pmin = 0;
-		env_leave_pmax = 0;
-		env_in_use = false;
-		env_debug = no_debug;
-		env_locals = Array.make num_locals vnull;
-		env_captures = Array.make num_captures (ref vnull);
-	}
+	push_environment_debug ctx info num_locals num_captures
 [@@inline]
 
 let pop_environment ctx env =
-	if ctx.record_stack then pop_environment_debug ctx env else ()
+	pop_environment_debug ctx env
 [@@inline]
 
 (* Prototypes *)

+ 34 - 777
src/macro/eval/evalEmitter.ml

@@ -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

+ 84 - 12
src/macro/eval/evalEncode.ml

@@ -25,18 +25,90 @@ open EvalHash
 
 (* Functions *)
 
-let vifun0 f = vfunction (Fun1 (fun a -> f a))
-let vifun1 f = vfunction (Fun2 (fun a b -> f a b))
-let vifun2 f = vfunction (Fun3 (fun a b c -> f a b c))
-let vifun3 f = vfunction (Fun4 (fun a b c d -> f a b c d))
-let vifun4 f = vfunction (Fun5 (fun a b c d e -> f a b c d e))
-
-let vfun0 f = vstatic_function (Fun0 (fun vl -> f ()))
-let vfun1 f = vstatic_function (Fun1 (fun a -> f a))
-let vfun2 f = vstatic_function (Fun2 (fun a b -> f a b))
-let vfun3 f = vstatic_function (Fun3 (fun a b c -> f a b c))
-let vfun4 f = vstatic_function (Fun4 (fun a b c d -> f a b c d))
-let vfun5 f = vstatic_function (Fun5 (fun a b c d e -> f a b c d e))
+let vifun0 f = vfunction (fun vl -> match vl with
+	| [] -> f vnull
+	| [v0] -> f v0
+	| _ -> invalid_call_arg_number 1 (List.length  vl
+))
+
+let vifun1 f = vfunction (fun vl -> match vl with
+	| [] -> f vnull vnull
+	| [v0] -> f v0 vnull
+	| [v0;v1] -> f v0 v1
+	| _ -> invalid_call_arg_number 2 (List.length  vl
+))
+
+let vifun2 f = vfunction (fun vl -> match vl with
+	| [] -> f vnull vnull vnull
+	| [v0] -> f v0 vnull vnull
+	| [v0;v1] -> f v0 v1 vnull
+	| [v0;v1;v2] -> f v0 v1 v2
+	| _ -> invalid_call_arg_number 3 (List.length  vl
+))
+
+let vifun3 f = vfunction (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3
+	| _ -> invalid_call_arg_number 4 (List.length  vl
+))
+
+let vifun4 f = vfunction (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3 vnull
+	| [v0;v1;v2;v3;v4] -> f v0 v1 v2 v3 v4
+	| _ -> invalid_call_arg_number 4 (List.length  vl
+))
+
+let vfun0 f = vstatic_function (fun vl -> match vl with
+	| [] -> f ()
+	| _ -> invalid_call_arg_number 1 (List.length  vl
+))
+
+let vfun1 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull
+	| [v0] -> f v0
+	| _ -> invalid_call_arg_number 1 (List.length  vl
+))
+
+let vfun2 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull
+	| [v0] -> f v0 vnull
+	| [v0;v1] -> f v0 v1
+	| _ -> invalid_call_arg_number 2 (List.length  vl
+))
+
+let vfun3 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull vnull
+	| [v0] -> f v0 vnull vnull
+	| [v0;v1] -> f v0 v1 vnull
+	| [v0;v1;v2] -> f v0 v1 v2
+	| _ -> invalid_call_arg_number 3 (List.length  vl
+))
+
+let vfun4 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3
+	| _ -> invalid_call_arg_number 4 (List.length  vl
+))
+
+let vfun5 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3 vnull
+	| [v0;v1;v2;v3;v4] -> f v0 v1 v2 v3 v4
+	| _ -> invalid_call_arg_number 4 (List.length  vl
+))
 
 (* Objects *)
 

+ 2 - 4
src/macro/eval/evalExceptions.ml

@@ -93,17 +93,15 @@ let get_exc_error_message ctx v stack p =
 	let pl = List.filter (fun p -> p <> null_pos) pl in
 	match pl with
 	| [] ->
-		let extra = if ctx.record_stack then "" else "\nNo stack information available, consider compiling with -D eval-stack" in
-		uncaught_exception_string v p extra
+		uncaught_exception_string v p ""
 	| _ ->
 		let sstack = String.concat "\n" (List.map (fun p -> Printf.sprintf "%s : Called from here" (format_pos p)) pl) in
 		Printf.sprintf "%s : Uncaught exception %s\n%s" (format_pos p) (value_string v) sstack
 
 let build_exception_stack ctx environment_offset =
 	let eval = get_eval ctx in
-	let d = if not ctx.record_stack then [] else DynArray.to_list (DynArray.sub eval.environments environment_offset (eval.environment_offset - environment_offset)) in
+	let d = DynArray.to_list (DynArray.sub eval.environments environment_offset (eval.environment_offset - environment_offset)) in
 	ctx.exception_stack <- List.map (fun env ->
-		env.env_in_use <- false;
 		env.env_debug.timer();
 		{pfile = rev_file_hash env.env_info.pfile;pmin = env.env_leave_pmin; pmax = env.env_leave_pmax},env.env_info.kind
 	) d

+ 44 - 307
src/macro/eval/evalJit.ml

@@ -103,29 +103,15 @@ let rec op_assign ctx jit e1 e2 = match e1.eexpr with
 	| TArray(ea1,ea2) ->
 		begin match (follow ea1.etype) with
 			| TInst({cl_path=(["eval"],"Vector")}, _) ->
-				begin match ea1.eexpr with
-					| TLocal var when not var.v_capture ->
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_vector_local_write (get_slot jit var.v_id ea1.epos) exec2 exec3 ea2.epos
-					| _ ->
-						let exec1 = jit_expr jit false ea1 in
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_vector_write exec1 exec2 exec3 ea2.epos
-				end
+				let exec1 = jit_expr jit false ea1 in
+				let exec2 = jit_expr jit false ea2 in
+				let exec3 = jit_expr jit false e2 in
+				emit_vector_write exec1 exec2 exec3 ea2.epos
 			| _ ->
-				begin match ea1.eexpr with
-					| TLocal var when not var.v_capture ->
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_array_local_write (get_slot jit var.v_id ea1.epos) exec2 exec3 ea2.epos
-					| _ ->
-						let exec1 = jit_expr jit false ea1 in
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_array_write exec1 exec2 exec3 ea2.epos
-				end
+				let exec1 = jit_expr jit false ea1 in
+				let exec2 = jit_expr jit false ea2 in
+				let exec3 = jit_expr jit false e2 in
+				emit_array_write exec1 exec2 exec3 ea2.epos
 		end
 
 	| _ ->
@@ -154,54 +140,24 @@ and op_assign_op jit op e1 e2 prefix = match e1.eexpr with
 	| TArray(ea1,ea2) ->
 		begin match (follow ea1.etype) with
 			| TInst({cl_path=(["eval"],"Vector")}, _) ->
-				begin match ea1.eexpr with
-					| TLocal var when not var.v_capture ->
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_vector_local_read_write (get_slot jit var.v_id ea1.epos) exec2 exec3 op prefix ea2.epos
-					| _ ->
-						let exec1 = jit_expr jit false ea1 in
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_vector_read_write exec1 exec2 exec3 op prefix ea2.epos
-				end
+				let exec1 = jit_expr jit false ea1 in
+				let exec2 = jit_expr jit false ea2 in
+				let exec3 = jit_expr jit false e2 in
+				emit_vector_read_write exec1 exec2 exec3 op prefix ea2.epos
 			| _ ->
-				begin match ea1.eexpr with
-					| TLocal var when not var.v_capture ->
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_array_local_read_write (get_slot jit var.v_id ea1.epos) exec2 exec3 op prefix ea2.epos
-					| _ ->
-						let exec1 = jit_expr jit false ea1 in
-						let exec2 = jit_expr jit false ea2 in
-						let exec3 = jit_expr jit false e2 in
-						emit_array_read_write exec1 exec2 exec3 op prefix ea2.epos
-				end
+				let exec1 = jit_expr jit false ea1 in
+				let exec2 = jit_expr jit false ea2 in
+				let exec3 = jit_expr jit false e2 in
+				emit_array_read_write exec1 exec2 exec3 op prefix ea2.epos
 		end
 	| _ ->
 		assert false
 
-and op_incr jit e1 prefix p = match e1.eexpr with
-	| TLocal var ->
-		begin match var.v_capture,prefix with
-			| true,true -> emit_capture_incr_prefix (get_capture_slot jit var.v_id)
-			| true,false -> emit_capture_incr_postfix (get_capture_slot jit var.v_id)
-			| false,true -> emit_local_incr_prefix (get_slot jit var.v_id e1.epos)
-			| false,false -> emit_local_incr_postfix (get_slot jit var.v_id e1.epos)
-		end
-	| _ ->
-		op_assign_op jit (get_binop_fun OpAdd p) e1 eone prefix
+and op_incr jit e1 prefix p =
+	op_assign_op jit (get_binop_fun OpAdd p) e1 eone prefix
 
-and op_decr jit e1 prefix p = match e1.eexpr with
-	| TLocal var ->
-		begin match var.v_capture,prefix with
-			| true,true -> emit_capture_decr_prefix (get_capture_slot jit var.v_id)
-			| true,false -> emit_capture_decr_postfix (get_capture_slot jit var.v_id)
-			| false,true -> emit_local_decr_prefix (get_slot jit var.v_id e1.epos)
-			| false,false -> emit_local_decr_postfix (get_slot jit var.v_id e1.epos)
-		end
-	| _ ->
-		op_assign_op jit (get_binop_fun OpSub p) e1 eone prefix
+and op_decr jit e1 prefix p =
+	op_assign_op jit (get_binop_fun OpSub p) e1 eone prefix
 
 and unop jit op flag e1 p =
 	match op with
@@ -275,69 +231,16 @@ and jit_expr jit return e =
 			| Some e -> jit_expr jit return e
 		in
 		emit_if exec_cond exec_then exec_else
-	| TSwitch(e1,cases,def) when is_int e1.etype ->
-		let exec = jit_expr jit false e1 in
-		let h = ref IntMap.empty in
-		let max = ref 0 in
-		let shift = ref 0 in
-		List.iter (fun (el,e) ->
-			push_scope jit e.epos;
-			let exec = jit_expr jit return e in
-			List.iter (fun e -> match e.eexpr with
-				| TConst (TInt i32) ->
-					let i = Int32.to_int i32 in
-					h := IntMap.add i exec !h;
-					if i > !max then max := i
-					else if i < !shift then shift := i
-				| _ -> assert false
-			) el;
-			pop_scope jit;
-		) cases;
-		let exec_def = match def with
-			| None -> emit_null
-			| Some e ->
-				push_scope jit e.epos;
-				let exec = jit_expr jit return e in
-				pop_scope jit;
-				exec
-		in
-		let l = !max - !shift + 1 in
-		if l < 256 then begin
-			let cases = Array.init l (fun i -> try IntMap.find (i + !shift) !h with Not_found -> exec_def) in
-			if !shift = 0 then begin match (Texpr.skip e1).eexpr with
-				| TEnumIndex e1 ->
-					let exec = jit_expr jit false e1 in
-					emit_enum_switch_array exec cases exec_def e1.epos
-				| _ ->
-					emit_int_switch_array exec cases exec_def e1.epos
-			end else
-				emit_int_switch_array_shift (- !shift) exec cases exec_def e1.epos
-		end else
-			emit_int_switch_map exec !h exec_def e1.epos
 	| TSwitch(e1,cases,def) ->
 		let exec = jit_expr jit false e1 in
 		let execs = DynArray.create () in
-		let constants = DynArray.create () in
-		let patterns = DynArray.create () in
-		let is_complex = ref false in
-		(* This is slightly insane... *)
-		List.iter (fun (el,e) ->
+		let patterns = List.map (fun (el,e) ->
 			push_scope jit e.epos;
-			begin try
-				if !is_complex then raise Exit;
-				let el = List.map (fun e -> match e.eexpr with
-					| TConst ct -> eval_const ct
-					| _ -> raise Exit
-				) el in
-				DynArray.add constants el
-			with Exit ->
-				is_complex := true;
-				let el = List.map (jit_expr jit false) el in
-				DynArray.add patterns el
-			end;
+			let el = List.map (jit_expr jit false) el in
 			DynArray.add execs (jit_expr jit return e);
 			pop_scope jit;
-		) cases;
+			el
+		) cases in
 		let exec_def = match def with
 			| None ->
 				emit_null
@@ -347,68 +250,15 @@ and jit_expr jit return e =
 				pop_scope jit;
 				exec
 		in
-		if !is_complex then begin
-			let l = DynArray.length constants in
-			let all_patterns = Array.init (l + DynArray.length patterns) (fun i ->
-				if i >= l then DynArray.get patterns (i - l) else (List.map (fun ct -> fun _ -> ct) (DynArray.get constants i))
-			) in
-			emit_switch exec (DynArray.to_array execs) all_patterns exec_def
-		end else begin
-			emit_constant_switch exec (DynArray.to_array execs) (DynArray.to_array constants) exec_def
-		end
+		emit_switch exec (DynArray.to_array execs) (Array.of_list patterns) exec_def
 	| TWhile({eexpr = TParenthesis e1},e2,flag) ->
 		loop {e with eexpr = TWhile(e1,e2,flag)}
-	| TWhile({eexpr = TBinop(OpLt,{eexpr = TLocal v;epos=pv},eto)},e2,NormalWhile) when (Meta.has Meta.ForLoopVariable v.v_meta) ->
-		let has_break = ref false in
-		let has_continue = ref false in
-		let rec loop e = match e.eexpr with
-			| TUnop(Increment,_,({eexpr = TLocal v'} as e1)) when v == v' -> e1
-			| TWhile _ | TFor _ -> e
-			| TBreak -> has_break := true; e
-			| TContinue -> has_continue := true; e
-			| _ -> Type.map_expr loop e
-		in
-		let e2 = loop e2 in
-		let slot = get_slot jit v.v_id pv in
-		let exec1 = jit_expr jit false eto in
-		let exec2 = jit_expr jit false e2 in
-		begin match !has_break,!has_continue with
-			| false,false -> emit_int_iterator slot exec1 exec2 pv eto.epos
-			| true,false -> emit_int_iterator_break slot exec1 exec2 pv eto.epos
-			| false,true -> emit_int_iterator_continue slot exec1 exec2 pv eto.epos
-			| true,true -> emit_int_iterator_break_continue slot exec1 exec2 pv eto.epos
-		end
 	| TWhile(e1,e2,flag) ->
-		let has_break = ref false in
-		let has_continue = ref false in
-		let rec loop e = match e.eexpr with
-			| TContinue -> has_continue := true; if !has_break then raise Exit
-			| TBreak -> has_break := true; if !has_continue then raise Exit
-			| TFunction _ | TWhile _ | TFor _ -> ()
-			| _ -> Type.iter loop e
-		in
-		(try loop e2 with Exit -> ());
-		begin match e1.eexpr with
-			| TBinop(OpGte,e1,{eexpr = TConst (TFloat s)}) when not !has_break && not !has_continue && flag = NormalWhile ->
-				let f = float_of_string s in
-				let exec1 = jit_expr jit false e1 in
-				let exec2 = jit_expr jit false e2 in
-				emit_while_gte exec1 f exec2
-			| _ ->
-				let exec_cond = jit_expr jit false e1 in
-				let exec_body = jit_expr jit false e2 in
-				(* This is a bit moronic, but it does avoid run-time branching and setting up some exception
-					handlers for break/continue, so it might be worth it... *)
-				begin match flag,!has_break,!has_continue with
-					| NormalWhile,false,false -> emit_while exec_cond exec_body
-					| NormalWhile,true,false -> emit_while_break exec_cond exec_body
-					| NormalWhile,false,true -> emit_while_continue exec_cond exec_body
-					| NormalWhile,true,true -> emit_while_break_continue exec_cond exec_body
-					| DoWhile,false,false -> emit_do_while exec_cond exec_body
-					| DoWhile,true,false -> emit_do_while_break exec_cond exec_body
-					| DoWhile,false,true -> emit_do_while_continue exec_cond exec_body
-					| DoWhile,true,true -> emit_do_while_break_continue exec_cond exec_body
-				end
+		let exec_cond = jit_expr jit false e1 in
+		let exec_body = jit_expr jit false e2 in
+		begin match flag with
+			| NormalWhile -> emit_while_break_continue exec_cond exec_body
+			| DoWhile -> emit_do_while_break_continue exec_cond exec_body
 		end
 	| TTry(e1,catches) ->
 		let exec = jit_expr jit return e1 in
@@ -424,7 +274,7 @@ and jit_expr jit return e =
 	(* control flow *)
 	| TBlock [] ->
 		emit_null
-	| TBlock el when ctx.debug.support_debugger ->
+	| TBlock el ->
 		let e1,el = match List.rev el with
 			| e1 :: el -> e1,List.rev el
 			| [] -> assert false
@@ -434,81 +284,6 @@ and jit_expr jit return e =
 		let exec1 = jit_expr jit return e1 in
 		pop_scope jit;
 		emit_block (Array.of_list (execs @ [exec1]))
-	| TBlock [e1] ->
-		push_scope jit e.epos;
-		let f = loop e1 in
-		pop_scope jit;
-		f
-	| TBlock [e1;e2] ->
-		push_scope jit e.epos;
-		let exec1 = jit_expr jit false e1 in
-		let exec2 = jit_expr jit return e2 in
-		pop_scope jit;
-		emit_block2 exec1 exec2
-	| TBlock [e1;e2;e3] ->
-		push_scope jit e.epos;
-		let exec1 = jit_expr jit false e1 in
-		let exec2 = jit_expr jit false e2 in
-		let exec3 = jit_expr jit return e3 in
-		pop_scope jit;
-		emit_block3 exec1 exec2 exec3
-	| TBlock [e1;e2;e3;e4] ->
-		push_scope jit e.epos;
-		let exec1 = jit_expr jit false e1 in
-		let exec2 = jit_expr jit false e2 in
-		let exec3 = jit_expr jit false e3 in
-		let exec4 = jit_expr jit return e4 in
-		pop_scope jit;
-		emit_block4 exec1 exec2 exec3 exec4
-	| TBlock [e1;e2;e3;e4;e5] ->
-		push_scope jit e.epos;
-		let exec1 = jit_expr jit false e1 in
-		let exec2 = jit_expr jit false e2 in
-		let exec3 = jit_expr jit false e3 in
-		let exec4 = jit_expr jit false e4 in
-		let exec5 = jit_expr jit return e5 in
-		pop_scope jit;
-		emit_block5 exec1 exec2 exec3 exec4 exec5
-	| TBlock el ->
-		let d = DynArray.create () in
-		let add = DynArray.add d in
-		let rec loop el = match el with
-			| e1 :: e2 :: e3 :: e4 :: e5 :: el ->
-				let exec1 = jit_expr jit false e1 in
-				let exec2 = jit_expr jit false e2 in
-				let exec3 = jit_expr jit false e3 in
-				let exec4 = jit_expr jit false e4 in
-				let exec5 = jit_expr jit (return && el = []) e5 in
-				add (emit_block5 exec1 exec2 exec3 exec4 exec5);
-				loop el
-			| e1 :: e2 :: e3 :: e4 :: el ->
-				let exec1 = jit_expr jit false e1 in
-				let exec2 = jit_expr jit false e2 in
-				let exec3 = jit_expr jit false e3 in
-				let exec4 = jit_expr jit (return && el = []) e4 in
-				add (emit_block4 exec1 exec2 exec3 exec4);
-				loop el
-			| e1 :: e2 :: e3 :: el ->
-				let exec1 = jit_expr jit false e1 in
-				let exec2 = jit_expr jit false e2 in
-				let exec3 = jit_expr jit (return && el = []) e3 in
-				add (emit_block3 exec1 exec2 exec3);
-				loop el
-			| e1 :: e2 :: el ->
-				let exec1 = jit_expr jit false e1 in
-				let exec2 = jit_expr jit (return && el = []) e2 in
-				add (emit_block2 exec1 exec2);
-				loop el
-			| [e1] ->
-				let exec1 = jit_expr jit return e1 in
-				add (emit_block1 exec1);
-			| [] ->
-				()
-		in
-		push_scope jit e.epos;
-		loop el;
-		pop_scope jit;
-		emit_block (DynArray.to_array d)
 	| TReturn None ->
 		if return then emit_null
 		else begin
@@ -576,15 +351,7 @@ and jit_expr jit return e =
 				| FEnum({e_path=path},ef) ->
 					let key = path_hash path in
 					let pos = Some ef.ef_pos in
-					begin match execs with
-						| [] -> emit_enum_construction0 key ef.ef_index pos
-						| [exec1] -> emit_enum_construction1 key ef.ef_index exec1 pos
-						| [exec1;exec2] -> emit_enum_construction2 key ef.ef_index exec1 exec2 pos
-						| [exec1;exec2;exec3] -> emit_enum_construction3 key ef.ef_index exec1 exec2 exec3 pos
-						| [exec1;exec2;exec3;exec4] -> emit_enum_construction4 key ef.ef_index exec1 exec2 exec3 exec4 pos
-						| [exec1;exec2;exec3;exec4;exec5] -> emit_enum_construction5 key ef.ef_index exec1 exec2 exec3 exec4 exec5 pos
-						| _ -> emit_enum_construction key ef.ef_index (Array.of_list execs) pos
-					end
+					emit_enum_construction key ef.ef_index (Array.of_list execs) pos
 				| FStatic({cl_path=path},cf) when is_proper_method cf ->
 					let proto = get_static_prototype ctx (path_hash path) ef.epos in
 					let i = get_proto_field_index proto name in
@@ -636,14 +403,7 @@ and jit_expr jit return e =
 			| _ ->
 				let exec = jit_expr jit false e1 in
 				let execs = List.map (jit_expr jit false) el in
-				begin match execs with
-					| [] -> emit_call0 exec e.epos
-					| [exec1] -> emit_call1 exec exec1 e.epos
-					| [exec1;exec2] -> emit_call2 exec exec1 exec2 e.epos
-					| [exec1;exec2;exec3] -> emit_call3 exec exec1 exec2 exec3 e.epos
-					| [exec1;exec2;exec3;exec4] -> emit_call4 exec exec1 exec2 exec3 exec4 e.epos
-					| _ -> emit_call exec execs e.epos
-				end
+				emit_call exec execs e.epos
 		end
 	| TNew({cl_path=[],"Array"},_,_) ->
 		emit_new_array
@@ -682,20 +442,14 @@ and jit_expr jit return e =
 			| FInstance(c,_,_) when not c.cl_interface ->
 				let proto = get_instance_prototype ctx (path_hash c.cl_path) e1.epos in
 				let i = get_instance_field_index proto name e1.epos in
-				begin match e1.eexpr with
-					| TLocal var when not var.v_capture -> emit_instance_local_field_read (get_slot jit var.v_id e1.epos) i
-					| _ -> emit_instance_field_read (jit_expr jit false e1) i
-				end
+				emit_instance_field_read (jit_expr jit false e1) i
 			| FAnon _ ->
 				begin match follow e1.etype with
 					| TAnon an ->
 						let l = PMap.foldi (fun k _ acc -> (hash_s k,()) :: acc) an.a_fields [] in
 						let proto,_ = ctx.get_object_prototype ctx l in
 						let i = get_instance_field_index proto name e1.epos in
-						begin match e1.eexpr with
-							| TLocal var when not var.v_capture -> emit_anon_local_field_read (get_slot jit var.v_id e1.epos) proto i name e1.epos
-							| _ -> emit_anon_field_read (jit_expr jit false e1) proto i name e1.epos
-						end
+						emit_anon_field_read (jit_expr jit false e1) proto i name e1.epos
 					| _ ->
 						emit_field_read (jit_expr jit false e1) name e1.epos
 				end
@@ -709,23 +463,13 @@ and jit_expr jit return e =
 	| TArray(e1,e2) ->
 		begin match (follow e1.etype) with
 			| TInst({cl_path=(["eval"],"Vector")}, _) ->
-				begin match e1.eexpr with
-					| TLocal var when not var.v_capture ->
-						emit_vector_local_read (get_slot jit var.v_id e1.epos) (jit_expr jit false e2) e2.epos
-					| _ ->
-						let exec1 = jit_expr jit false e1 in
-						let exec2 = jit_expr jit false e2 in
-						emit_vector_read exec1 exec2 e2.epos
-				end
+				let exec1 = jit_expr jit false e1 in
+				let exec2 = jit_expr jit false e2 in
+				emit_vector_read exec1 exec2 e2.epos
 			| _ ->
-				begin match e1.eexpr with
-					| TLocal var when not var.v_capture ->
-						emit_array_local_read (get_slot jit var.v_id e1.epos) (jit_expr jit false e2) e2.epos
-					| _ ->
-						let exec1 = jit_expr jit false e1 in
-						let exec2 = jit_expr jit false e2 in
-						emit_array_read exec1 exec2 e2.epos
-				end
+				let exec1 = jit_expr jit false e1 in
+				let exec2 = jit_expr jit false e2 in
+				emit_array_read exec1 exec2 e2.epos
 		end
 	| TEnumParameter(e1,_,i) ->
 		let exec = jit_expr jit false e1 in
@@ -825,16 +569,9 @@ and get_env jit static file info =
 	let num_locals = jit.max_num_locals in
 	let num_captures = Hashtbl.length jit.captures in
 	let info = create_env_info static file info jit.capture_infos in
-	if ctx.record_stack || num_captures > 0 then begin
-		match info.kind with
-		| EKLocalFunction _ -> get_closure_env ctx info num_locals num_captures
-		| _ -> get_normal_env ctx info num_locals num_captures
-	end else begin
-		let default_env = create_default_environment ctx info num_locals in
-		match info.kind with
-		| EKLocalFunction _ -> get_closure_env_opt ctx default_env info num_locals num_captures
-		| _ -> get_normal_env_opt ctx default_env info num_locals num_captures
-	end
+	match info.kind with
+	| EKLocalFunction _ -> get_closure_env ctx info num_locals num_captures
+	| _ -> get_normal_env ctx info num_locals num_captures
 
 (* Creates a [EvalValue.vfunc] of function [tf], which can be [static] or not. *)
 let jit_tfunction ctx key_type key_field tf static pos =

+ 1 - 11
src/macro/eval/evalMain.ml

@@ -95,7 +95,6 @@ let create com api is_macro =
 			debug
 	in
 	let detail_times = Common.defined com Define.EvalTimes in
-	let record_stack = debug.support_debugger || detail_times || Common.defined com Define.EvalStack in
 	let evals = DynArray.create () in
 	let eval = {
 		environments = DynArray.make 32;
@@ -106,7 +105,6 @@ let create com api is_macro =
 		ctx_id = !sid;
 		is_macro = is_macro;
 		debug = debug;
-		record_stack = record_stack;
 		detail_times = detail_times;
 		curapi = api;
 		builtins = builtins;
@@ -339,15 +337,7 @@ let setup get_api =
 	let api = get_api (fun() -> (get_ctx()).curapi.get_com()) (fun() -> (get_ctx()).curapi) in
 	List.iter (fun (n,v) -> match v with
 		| VFunction(f,b) ->
-			let v = match f with
-				| Fun0 f -> VFunction (Fun0 (fun () -> try f () with Sys_error msg | Failure msg -> exc_string msg),b)
-				| Fun1 f -> VFunction (Fun1 (fun a -> try f a with Sys_error msg | Failure msg -> exc_string msg),b)
-				| Fun2 f -> VFunction (Fun2 (fun a b -> try f a b with Sys_error msg | Failure msg -> exc_string msg),b)
-				| Fun3 f -> VFunction (Fun3 (fun a b c -> try f a b c with Sys_error msg | Failure msg -> exc_string msg),b)
-				| Fun4 f -> VFunction (Fun4 (fun a b c d -> try f a b c d with Sys_error msg | Failure msg -> exc_string msg),b)
-				| Fun5 f -> VFunction (Fun5 (fun a b c d e -> try f a b c d e with Sys_error msg | Failure msg -> exc_string msg),b)
-				| FunN f -> VFunction (FunN (fun vl -> try f vl with Sys_error msg | Failure msg -> exc_string msg),b)
-			in
+			let v = VFunction ((fun vl -> try f vl with Sys_error msg | Failure msg -> exc_string msg),b) in
 			Hashtbl.replace EvalStdLib.macro_lib n v
 		| _ -> assert false
 	) api;

+ 1 - 6
src/macro/eval/evalPrinting.ml

@@ -101,12 +101,7 @@ and s_value depth v =
 		let s = Numeric.float_repres f in
 		let len = String.length s in
 		of_string (if String.unsafe_get s (len - 1) = '.' then String.sub s 0 (len - 1) else s)
-	| VFunction (f,_) ->
-		let s = match num_args f with
-			| -1 -> ""
-			| i -> string_of_int i
-		in
-		concat2 rfun (Rope.of_string (s))
+	| VFunction (f,_) -> concat2 rfun (Rope.of_string (""))
 	| VFieldClosure _ -> rclosure
 	| VEnumValue ve -> s_enum_value depth ve
 	| VString(s,_) -> s

+ 1 - 9
src/macro/eval/evalPrototype.ml

@@ -209,15 +209,7 @@ let create_static_prototype ctx mt =
 		let pctx = PrototypeBuilder.create ctx key None (PEnum en.e_names) meta in
 		let enum_field_value ef = match follow ef.ef_type with
 			| TFun(args,_) ->
-				let f = match args with
-					| [] -> Fun0 (fun () -> encode_enum_value key ef.ef_index [||] (Some ef.ef_pos))
-					| [_] -> Fun1 (fun a -> encode_enum_value key ef.ef_index [|a|] (Some ef.ef_pos))
-					| [_;_] -> Fun2 (fun a b -> encode_enum_value key ef.ef_index [|a;b|] (Some ef.ef_pos))
-					| [_;_;_] -> Fun3 (fun a b c -> encode_enum_value key ef.ef_index [|a;b;c|] (Some ef.ef_pos))
-					| [_;_;_;_] -> Fun4 (fun a b c d -> encode_enum_value key ef.ef_index [|a;b;c;d|] (Some ef.ef_pos))
-					| [_;_;_;_;_] -> Fun5 (fun a b c d e -> encode_enum_value key ef.ef_index [|a;b;c;d;e|] (Some ef.ef_pos))
-					| _ -> FunN (fun vl -> encode_enum_value key ef.ef_index (Array.of_list vl) (Some ef.ef_pos))
-				in
+				let f = (fun vl -> encode_enum_value key ef.ef_index (Array.of_list vl) (Some ef.ef_pos)) in
 				vstatic_function f
 			| _ -> encode_enum_value key ef.ef_index [||] (Some ef.ef_pos)
 		in

+ 5 - 21
src/macro/eval/evalStdLib.ml

@@ -81,17 +81,9 @@ module StdEvalVector = struct
 		let this = this vthis in
 		let a = match f with
 			| VFunction(f,_) ->
-				begin match f with
-					| Fun1 f -> Array.map (fun v -> f v) this
-					| FunN f -> Array.map (fun v -> f [v]) this
-					| _ -> invalid_call_arg_number 1 (num_args f)
-				end
+				Array.map (fun v -> f [v]) this
 			| VFieldClosure(v1,f) ->
-				begin match f with
-					| Fun2 f -> Array.map (fun v -> f v1 v) this
-					| FunN f -> Array.map (fun v -> f [v1;v]) this
-					| _ -> invalid_call_arg_number 2 (num_args f)
-				end
+				Array.map (fun v -> f (v1 :: [v])) this
 			| _ -> exc_string ("Cannot call " ^ (value_string f))
 		in
 		encode_vector_instance a
@@ -167,17 +159,9 @@ module StdArray = struct
 		let this = this vthis in
 		let a = match f with
 			| VFunction(f,_) ->
-				begin match f with
-					| Fun1 f -> EvalArray.map this (fun v -> f v)
-					| FunN f -> EvalArray.map this (fun v -> f [v])
-					| _ -> invalid_call_arg_number 1 (num_args f)
-				end
+				EvalArray.map this (fun v -> f [v])
 			| VFieldClosure(v1,f) ->
-				begin match f with
-					| Fun2 f -> EvalArray.map this (fun v -> f v1 v)
-					| FunN f -> EvalArray.map this (fun v -> f [v1;v])
-					| _ -> invalid_call_arg_number 2 (num_args f)
-				end
+				EvalArray.map this (fun v -> f (v1 :: [v]))
 			| _ -> exc_string ("Cannot call " ^ (value_string f))
 		in
 		encode_array_instance a
@@ -1664,7 +1648,7 @@ module StdReflect = struct
 	)
 
 	let makeVarArgs = vfun1 (fun f ->
-		vstatic_function (FunN (fun vl -> call_value f [encode_array vl]))
+		vstatic_function ((fun vl -> call_value f [encode_array vl]))
 	)
 
 	let setField = vfun3 (fun o name v ->

+ 2 - 18
src/macro/eval/evalValue.ml

@@ -70,14 +70,7 @@ type value =
 	| VFunction of vfunc * bool
 	| VFieldClosure of value * vfunc
 
-and vfunc =
-	| Fun0 of (unit -> value)
-	| Fun1 of (value -> value)
-	| Fun2 of (value -> value -> value)
-	| Fun3 of (value -> value -> value -> value)
-	| Fun4 of (value -> value -> value -> value -> value)
-	| Fun5 of (value -> value -> value -> value -> value -> value)
-	| FunN of (value list -> value)
+and vfunc = value list -> value
 
 and vobject = {
 	(* The fields of the object known when it is created. *)
@@ -201,13 +194,4 @@ let vint32 i = VInt32 i
 let vfloat f = VFloat f
 let venum_value e = VEnumValue e
 
-let s_expr_pretty e = (Type.s_expr_pretty false "" false (Type.s_type (Type.print_context())) e)
-
-let num_args = function
-	| Fun0 _ -> 0
-	| Fun1 _ -> 1
-	| Fun2 _ -> 2
-	| Fun3 _ -> 3
-	| Fun4 _ -> 4
-	| Fun5 _ -> 5
-	| FunN _ -> -1
+let s_expr_pretty e = (Type.s_expr_pretty false "" false (Type.s_type (Type.print_context())) e)