2
0
Эх сурвалжийг харах

[eval] remove null_env, use option instead

What was I thinking...
Simon Krajewski 6 жил өмнө
parent
commit
49feff5873

+ 19 - 36
src/macro/eval/evalContext.ml

@@ -46,7 +46,6 @@ type env_kind =
 	| EKLocalFunction of int
 	| EKLocalFunction of int
 	| EKMethod of int * int
 	| EKMethod of int * int
 	| EKEntrypoint
 	| EKEntrypoint
-	| EKToplevel
 
 
 (* Compile-time information for environments. This information is static for all
 (* Compile-time information for environments. This information is static for all
    environments of the same kind, e.g. all environments of a specific method. *)
    environments of the same kind, e.g. all environments of a specific method. *)
@@ -94,13 +93,13 @@ type env = {
 	env_captures : value ref array;
 	env_captures : value ref array;
 	(* Map of extra variables added while debugging. Keys are hashed variable names. *)
 	(* Map of extra variables added while debugging. Keys are hashed variable names. *)
 	mutable env_extra_locals : value IntMap.t;
 	mutable env_extra_locals : value IntMap.t;
-	(* The parent of the current environment, if exists. All environments except EKToplevel have a parent. *)
+	(* The parent of the current environment, if exists. *)
 	env_parent : env option;
 	env_parent : env option;
 	env_eval : eval;
 	env_eval : eval;
 }
 }
 
 
 and eval = {
 and eval = {
-	mutable env : env;
+	mutable env : env option;
 	thread : vthread;
 	thread : vthread;
 	(* The threads current debug state *)
 	(* The threads current debug state *)
 	mutable debug_state : debug_state;
 	mutable debug_state : debug_state;
@@ -292,10 +291,10 @@ let rec kind_name eval kind =
 			| None -> "entrypoint"
 			| None -> "entrypoint"
 			| Some env -> rev_hash env.env_info.pfile
 			| Some env -> rev_hash env.env_info.pfile
 			end
 			end
-		| EKToplevel ->
-			"toplevel"
 	in
 	in
-	loop kind (Some eval.env)
+	match eval.env with
+	| None -> "toplevel"
+	| Some env -> loop kind (Some env)
 
 
 let call_function f vl = f vl
 let call_function f vl = f vl
 
 
@@ -322,18 +321,23 @@ let call_stack eval =
 	let rec loop acc env =
 	let rec loop acc env =
 		let acc = env :: acc in
 		let acc = env :: acc in
 		match env.env_parent with
 		match env.env_parent with
-		| Some env when env.env_info.kind <> EKToplevel -> loop acc env
+		| Some env -> loop acc env
 		| _ -> List.rev acc
 		| _ -> List.rev acc
 	in
 	in
-	loop [] eval.env
+	match eval.env with
+	| None -> []
+	| Some env -> loop [] env
 
 
 let throw v p =
 let throw v p =
 	let ctx = get_ctx() in
 	let ctx = get_ctx() in
 	let eval = get_eval ctx in
 	let eval = get_eval ctx in
-	let env = eval.env in
-	env.env_leave_pmin <- p.pmin;
-	env.env_leave_pmax <- p.pmax;
-	raise_notrace (RunTimeException(v,call_stack eval,p))
+	match eval.env with
+	| Some env ->
+		env.env_leave_pmin <- p.pmin;
+		env.env_leave_pmax <- p.pmax;
+		raise_notrace (RunTimeException(v,call_stack eval,p))
+	| None ->
+		assert false
 
 
 let exc v = throw v null_pos
 let exc v = throw v null_pos
 
 
@@ -358,24 +362,6 @@ let no_debug = {
 	expr = no_expr;
 	expr = no_expr;
 }
 }
 
 
-let null_env = {
-	env_info = {
-		static = true;
-		pfile = EvalHash.hash "null-env";
-		pfile_unique = EvalHash.hash "null-env";
-		kind = EKToplevel;
-		capture_infos = Hashtbl.create 0;
-	};
-	env_debug = no_debug;
-	env_leave_pmin = 0;
-	env_leave_pmax = 0;
-	env_locals = [||];
-	env_captures = [||];
-	env_extra_locals = IntMap.empty;
-	env_parent = None;
-	env_eval = Obj.magic ();
-}
-
 let create_env_info static pfile kind capture_infos =
 let create_env_info static pfile kind capture_infos =
 	let info = {
 	let info = {
 		static = static;
 		static = static;
@@ -416,10 +402,10 @@ let push_environment ctx info num_locals num_captures =
 		env_locals = locals;
 		env_locals = locals;
 		env_captures = captures;
 		env_captures = captures;
 		env_extra_locals = IntMap.empty;
 		env_extra_locals = IntMap.empty;
-		env_parent = Some eval.env;
+		env_parent = eval.env;
 		env_eval = eval;
 		env_eval = eval;
 	} in
 	} in
-	eval.env <- env;
+	eval.env <- Some env;
 	begin match ctx.debug.debug_socket,env.env_info.kind with
 	begin match ctx.debug.debug_socket,env.env_info.kind with
 		| Some socket,EKMethod(key_type,key_field) ->
 		| Some socket,EKMethod(key_type,key_field) ->
 			begin try
 			begin try
@@ -437,10 +423,7 @@ let push_environment ctx info num_locals num_captures =
 
 
 let pop_environment ctx env =
 let pop_environment ctx env =
 	let eval = env.env_eval in
 	let eval = env.env_eval in
-	begin match env.env_parent with
-		| Some env -> eval.env <- env
-		| None -> assert false
-	end;
+	eval.env <- env.env_parent;
 	env.env_debug.timer();
 	env.env_debug.timer();
 	()
 	()
 
 

+ 1 - 1
src/macro/eval/evalDebugMisc.ml

@@ -146,7 +146,7 @@ let resolve_ident ctx env s =
 					| Some env -> loop env
 					| Some env -> loop env
 				end
 				end
 			| EKMethod _ -> env
 			| EKMethod _ -> env
-			| EKToplevel | EKEntrypoint ->
+			| EKEntrypoint ->
 				(* This can happen due to threads. Have to check what we can do here... *)
 				(* This can happen due to threads. Have to check what we can do here... *)
 				raise Not_found
 				raise Not_found
 		in
 		in

+ 6 - 7
src/macro/eval/evalDebugSocket.ml

@@ -128,7 +128,6 @@ let output_call_stack ctx eval p =
 		let artificial,name = match kind with
 		let artificial,name = match kind with
 			| EKMethod _ | EKLocalFunction _ -> false,kind_name eval kind
 			| EKMethod _ | EKLocalFunction _ -> false,kind_name eval kind
 			| EKEntrypoint -> true,p.pfile
 			| EKEntrypoint -> true,p.pfile
-			| EKToplevel -> true,kind_name eval kind
 		in
 		in
 		let source = if Sys.file_exists path then JString path else JNull in
 		let source = if Sys.file_exists path then JString path else JNull in
 		JObject [
 		JObject [
@@ -477,7 +476,7 @@ let handler =
 		let column = j#get_opt_param (fun () -> BPColumn (j#get_int_field "column" "column" obj)) BPAny in
 		let column = j#get_opt_param (fun () -> BPColumn (j#get_int_field "column" "column" obj)) BPAny in
 		let condition = j#get_opt_param (fun () ->
 		let condition = j#get_opt_param (fun () ->
 			let s = j#get_string_field "condition" "condition" obj in
 			let s = j#get_string_field "condition" "condition" obj in
-			let env = hctx.ctx.eval.env in (* Use the main env, we only care about the position anyway *)
+			let env = Option.get hctx.ctx.eval.env in (* Use the main env, we only care about the position anyway *)
 			Some (parse_expr hctx.ctx s env.env_debug.expr.epos)
 			Some (parse_expr hctx.ctx s env.env_debug.expr.epos)
 		) None in
 		) None in
 		(line,column,condition)
 		(line,column,condition)
@@ -516,14 +515,14 @@ let handler =
 		);
 		);
 		"next",(fun hctx ->
 		"next",(fun hctx ->
 			let eval = select_thread hctx in
 			let eval = select_thread hctx in
-			let env = eval.env in
+			let env = Option.get eval.env in
 			eval.debug_state <- DbgNext(env,env.env_debug.expr.epos);
 			eval.debug_state <- DbgNext(env,env.env_debug.expr.epos);
 			ignore(Event.poll (Event.send eval.debug_channel ()));
 			ignore(Event.poll (Event.send eval.debug_channel ()));
 			JNull
 			JNull
 		);
 		);
 		"stepOut",(fun hctx ->
 		"stepOut",(fun hctx ->
 			let eval = select_thread hctx in
 			let eval = select_thread hctx in
-			let env = eval.env in
+			let env = Option.get eval.env in
 			let penv = Option.get env.env_parent in
 			let penv = Option.get env.env_parent in
 			eval.debug_state <- DbgFinish penv;
 			eval.debug_state <- DbgFinish penv;
 			ignore(Event.poll (Event.send eval.debug_channel ()));
 			ignore(Event.poll (Event.send eval.debug_channel ()));
@@ -534,7 +533,7 @@ let handler =
 		);
 		);
 		"stackTrace",(fun hctx ->
 		"stackTrace",(fun hctx ->
 			let eval = select_thread hctx in
 			let eval = select_thread hctx in
-			let env = eval.env in
+			let env = Option.get eval.env in
 			output_call_stack hctx.ctx eval env.env_debug.expr.epos
 			output_call_stack hctx.ctx eval env.env_debug.expr.epos
 		);
 		);
 		"getScopes",(fun hctx ->
 		"getScopes",(fun hctx ->
@@ -676,7 +675,7 @@ let handler =
 			JNull
 			JNull
 		);
 		);
 		"evaluate",(fun hctx ->
 		"evaluate",(fun hctx ->
-			let env = try select_frame hctx with _ -> hctx.ctx.eval.env in
+			let env = try select_frame hctx with _ -> Option.get hctx.ctx.eval.env in
 			let s = hctx.jsonrpc#get_string_param "expr" in
 			let s = hctx.jsonrpc#get_string_param "expr" in
 			begin try
 			begin try
 				let e = parse_expr hctx.ctx s env.env_debug.expr.epos in
 				let e = parse_expr hctx.ctx s env.env_debug.expr.epos in
@@ -690,7 +689,7 @@ let handler =
 			end
 			end
 		);
 		);
 		"getCompletion",(fun hctx ->
 		"getCompletion",(fun hctx ->
-			let env = hctx.ctx.eval.env in
+			let env = Option.get hctx.ctx.eval.env in
 			let text = hctx.jsonrpc#get_string_param "text" in
 			let text = hctx.jsonrpc#get_string_param "text" in
 			let column = hctx.jsonrpc#get_int_param "column" in
 			let column = hctx.jsonrpc#get_int_param "column" in
 			try
 			try

+ 8 - 1
src/macro/eval/evalEmitter.ml

@@ -217,7 +217,14 @@ let emit_try exec catches env =
 		eval.caught_exception <- vnull;
 		eval.caught_exception <- vnull;
 		restore();
 		restore();
 		build_exception_stack ctx env;
 		build_exception_stack ctx env;
-		while eval.env != env do pop_environment ctx eval.env done;
+		let rec loop () = match eval.env with
+			| Some env' when env' != env ->
+				pop_environment ctx env';
+				loop();
+			| _ ->
+				()
+		in
+		loop();
 		let exec,_,varacc =
 		let exec,_,varacc =
 			try
 			try
 				List.find (fun (_,path,i) -> path = key_Dynamic || is v path) catches
 				List.find (fun (_,path,i) -> path = key_Dynamic || is v path) catches

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

@@ -114,7 +114,10 @@ let build_exception_stack ctx env =
 			| Some env -> loop acc env
 			| Some env -> loop acc env
 			| None -> assert false
 			| None -> assert false
 	in
 	in
-	let d = loop [] eval.env in
+	let d = match eval.env with
+	| Some env -> loop [] env
+	| None -> []
+	in
 	ctx.exception_stack <- List.map (fun env ->
 	ctx.exception_stack <- List.map (fun env ->
 		{pfile = rev_hash env.env_info.pfile;pmin = env.env_leave_pmin; pmax = env.env_leave_pmax},env.env_info.kind
 		{pfile = rev_hash env.env_info.pfile;pmin = env.env_leave_pmin; pmax = env.env_leave_pmax},env.env_info.kind
 	) d
 	) d
@@ -132,7 +135,7 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 	with
 	with
 	| RunTimeException(v,stack,p') ->
 	| RunTimeException(v,stack,p') ->
 		eval.caught_exception <- vnull;
 		eval.caught_exception <- vnull;
-		build_exception_stack ctx env;
+		Option.may (build_exception_stack ctx) env;
 		eval.env <- env;
 		eval.env <- env;
 		if is v key_haxe_macro_Error then begin
 		if is v key_haxe_macro_Error then begin
 			let v1 = field v key_message in
 			let v1 = field v key_message in

+ 3 - 3
src/macro/eval/evalMain.ml

@@ -100,7 +100,7 @@ let create com api is_macro =
 	in
 	in
 	let detail_times = Common.defined com Define.EvalTimes in
 	let detail_times = Common.defined com Define.EvalTimes in
 	let eval = {
 	let eval = {
-		env = null_env;
+		env = None;
 		thread = {
 		thread = {
 			tthread = Thread.self();
 			tthread = Thread.self();
 			tstorage = IntMap.empty;
 			tstorage = IntMap.empty;
@@ -455,7 +455,7 @@ let value_string = value_string
 
 
 let exc_string = exc_string
 let exc_string = exc_string
 
 
-let eval_expr ctx e = eval_expr ctx EKToplevel e
+let eval_expr ctx e = eval_expr ctx EKEntrypoint e
 
 
 let handle_decoding_error f v t =
 let handle_decoding_error f v t =
 	let line = ref 1 in
 	let line = ref 1 in
@@ -562,7 +562,7 @@ let handle_decoding_error f v t =
 
 
 let get_api_call_pos () =
 let get_api_call_pos () =
 	let eval = get_eval (get_ctx()) in
 	let eval = get_eval (get_ctx()) in
-	let env = eval.env in
+	let env = Option.get eval.env in
 	let env = match env.env_parent with
 	let env = match env.env_parent with
 		| None -> env
 		| None -> env
 		| Some env -> env
 		| Some env -> env

+ 2 - 2
src/macro/eval/evalStdLib.ml

@@ -586,7 +586,7 @@ module StdCallStack = struct
 			| EKMethod(st,sf) ->
 			| EKMethod(st,sf) ->
 				let local_function = encode_enum_value key_haxe_StackItem 3 [|create_unknown (rev_hash st); create_unknown (rev_hash sf)|] None in
 				let local_function = encode_enum_value key_haxe_StackItem 3 [|create_unknown (rev_hash st); create_unknown (rev_hash sf)|] None in
 				DynArray.add l (file_pos local_function);
 				DynArray.add l (file_pos local_function);
-			| EKToplevel | EKEntrypoint ->
+			| EKEntrypoint ->
 				()
 				()
 		) envs;
 		) envs;
 		encode_array (DynArray.to_list l)
 		encode_array (DynArray.to_list l)
@@ -3184,7 +3184,7 @@ let init_constructors builtins =
 							()
 							()
 					in
 					in
 					let new_eval = {
 					let new_eval = {
-						env = null_env;
+						env = None;
 						thread = thread;
 						thread = thread;
 						debug_state = DbgRunning;
 						debug_state = DbgRunning;
 						debug_channel = Event.new_channel ();
 						debug_channel = Event.new_channel ();