Browse Source

[hl] fixed callstack of rethrown exceptions (closes #10109)

Aleksandr Kuzmenko 4 năm trước cách đây
mục cha
commit
36c670bdbb

+ 1 - 0
src/filters/exceptions.ml

@@ -275,6 +275,7 @@ let catch_native ctx catches t p =
 		(* Everything else falls into `if(Std.is(e, ExceptionType)`-fest *)
 		| rest ->
 			let catch_var = alloc_var VGenerated "`" ctx.wildcard_catch_type null_pos in
+			catch_var.v_meta <- (Meta.Custom "VCaught",[],null_pos) :: catch_var.v_meta;
 			let catch_local = mk (TLocal catch_var) catch_var.v_type null_pos in
 			let body =
 				let catch = new catch ctx catch_local p in

+ 5 - 0
src/generators/genhl.ml

@@ -2596,6 +2596,11 @@ and eval_expr ctx e =
 			free ctx env;
 			op ctx (OInstanceClosure (r, fid, env)));
 		r
+	(* throwing a catch var means we want to rethrow an exception *)
+	| TThrow ({ eexpr = TLocal v } as e1) when has_meta (Meta.Custom "VCaught") v.v_meta ->
+		let r = alloc_tmp ctx HVoid in
+		op ctx (ORethrow (eval_to ctx e1 HDyn));
+		r
 	| TThrow v ->
 		op ctx (OThrow (eval_to ctx v HDyn));
 		alloc_tmp ctx HDyn

+ 24 - 0
tests/unit/src/unit/issues/Issue10109.hx

@@ -0,0 +1,24 @@
+package unit.issues;
+
+class Issue10109 extends Test {
+	@:pure(false)
+	static function foo( o : String ) {
+		return o.length;
+	}
+
+	function test() {
+		try {
+			try {
+				foo(null);
+			} catch( e : Stop ) {
+			}
+			assert();
+		} catch(e) {
+			t(e.stack.length > 0);
+		}
+	}
+}
+
+private enum Stop {
+	A;
+}