Browse Source

[eval] emit user-friendly exception on infinite recursion (#8313)

* [eval] emit user-friendly exception on infinite recursion

* make stack overflow catchable in macros

* use exc_string
Aleksandr Kuzmenko 6 years ago
parent
commit
5d8177a2c5
2 changed files with 6 additions and 2 deletions
  1. 1 1
      src/macro/eval/evalEmitter.ml
  2. 5 1
      src/macro/eval/evalExceptions.ml

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

@@ -210,7 +210,7 @@ let emit_try exec catches env =
 		List.iter (fun (_,path,_) -> Hashtbl.remove eval.caught_types path) catches
 		List.iter (fun (_,path,_) -> Hashtbl.remove eval.caught_types path) catches
 	in
 	in
 	let v = try
 	let v = try
-		let v = exec env in
+		let v = handle_stack_overflow eval (fun() -> exec env) in
 		restore();
 		restore();
 		v
 		v
 	with RunTimeException(v,_,_) as exc ->
 	with RunTimeException(v,_,_) as exc ->

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

@@ -122,13 +122,17 @@ let build_exception_stack ctx 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
 
 
+let handle_stack_overflow eval f =
+	try f()
+	with Stack_overflow -> exc_string "Stack overflow"
+
 let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 let catch_exceptions ctx ?(final=(fun() -> ())) f p =
 	let prev = !get_ctx_ref in
 	let prev = !get_ctx_ref in
 	select ctx;
 	select ctx;
 	let eval = get_eval ctx in
 	let eval = get_eval ctx in
 	let env = eval.env in
 	let env = eval.env in
 	let r = try
 	let r = try
-		let v = f() in
+		let v = handle_stack_overflow eval f in
 		get_ctx_ref := prev;
 		get_ctx_ref := prev;
 		final();
 		final();
 		Some v
 		Some v