Skip to content

Commit 9aeed30

Browse files
authored
[mono][wasm] Only catch the exception thrown by mono_llvm_cpp_throw_exception() in AOT-ed code. (#92040)
Part of the fix for #90692.
1 parent 62e50b6 commit 9aeed30

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

src/mono/mono/mini/llvm-intrinsics.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ INTRINS_OVR_TAG(SIMD_CEIL, ceil, Generic, Scalar | V64 | V128 | R4 | R8)
107107
INTRINS_OVR_TAG(SIMD_TRUNC, trunc, Generic, Scalar | V64 | V128 | R4 | R8)
108108
INTRINS_OVR_TAG(SIMD_ROUND, round, Generic, Scalar | V64 | V128 | R4 | R8)
109109
INTRINS_OVR_TAG(SIMD_NEAREST, nearbyint, Generic, V64 | V128 | R4 | R8)
110-
110+
INTRINS(EH_TYPEID_FOR, eh_typeid_for, Generic)
111111
#if LLVM_API_VERSION >= 1400
112112
INTRINS_OVR_TAG(ROUNDEVEN, roundeven, Generic, Scalar | V64 | V128 | R4 | R8)
113113
#endif
@@ -302,6 +302,9 @@ INTRINS_OVR(WASM_SUB_SAT_SIGNED_V8, wasm_sub_sat_signed, Wasm, sse_i2_t)
302302
INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V16, wasm_sub_sat_unsigned, Wasm, sse_i1_t)
303303
INTRINS_OVR(WASM_SUB_SAT_UNSIGNED_V8, wasm_sub_sat_unsigned, Wasm, sse_i2_t)
304304
INTRINS(WASM_SWIZZLE, wasm_swizzle, Wasm)
305+
INTRINS(WASM_GET_EXCEPTION, wasm_get_exception, Wasm)
306+
INTRINS(WASM_GET_EHSELECTOR, wasm_get_ehselector, Wasm)
307+
INTRINS(WASM_RETHROW, wasm_rethrow, Wasm)
305308
#endif
306309
#if defined(TARGET_ARM64)
307310
INTRINS_OVR(BITREVERSE_I32, bitreverse, Generic, LLVMInt32Type ())

src/mono/mono/mini/mini-llvm.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5001,8 +5001,47 @@ emit_llvmonly_landing_pad (EmitContext *ctx, int group_index, int group_size)
50015001
LLVMPositionBuilderAtEnd (builder, catch_bb);
50025002

50035003
LLVMValueRef catchpad_args [1];
5004-
catchpad_args [0] = LLVMConstNull (pointer_type (LLVMInt8Type ()));
5004+
catchpad_args [0] = ctx->module->sentinel_exception;
50055005
catchpad = LLVMBuildCatchPad (builder, lpad, catchpad_args, 1, "");
5006+
5007+
// The ifdef is needed because of INTRINS_WASM
5008+
#ifdef TARGET_WASM
5009+
// LLVM seems to require at least the following code sequence
5010+
// %7 = catchpad within %5 [ptr @typeinfo for int*]
5011+
// %8 = tail call ptr @llvm.wasm.get.exception(token %7)
5012+
// %9 = tail call i32 @llvm.wasm.get.ehselector(token %7)
5013+
5014+
LLVMValueRef args [] = { catchpad };
5015+
LLVMValueRef call = call_intrins (ctx, INTRINS_WASM_GET_EXCEPTION, args, "");
5016+
LLVMSetTailCall (call, TRUE);
5017+
LLVMValueRef sel_call = call_intrins (ctx, INTRINS_WASM_GET_EHSELECTOR, args, "");
5018+
LLVMSetTailCall (sel_call, TRUE);
5019+
5020+
//%10 = tail call i32 @llvm.eh.typeid.for(ptr nonnull @typeinfo for int*) #5, !dbg !31
5021+
//%11 = icmp eq i32 %9, %10, !dbg !31
5022+
//br i1 %11, label %12, label %14, !dbg !31
5023+
5024+
LLVMValueRef typeid_args [] = { ctx->module->sentinel_exception };
5025+
LLVMValueRef typeid = call_intrins (ctx, INTRINS_EH_TYPEID_FOR, typeid_args, "");
5026+
LLVMSetTailCall (typeid, TRUE);
5027+
5028+
LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, sel_call, typeid, "");
5029+
5030+
LLVMBasicBlockRef ex_bb = gen_bb (ctx, "CATCH_BB");
5031+
LLVMBasicBlockRef noex_bb = gen_bb (ctx, "NOCATCH_BB");
5032+
5033+
LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
5034+
5035+
/* No catch case */
5036+
//call void @llvm.wasm.rethrow() #3 [ "funclet"(token %7) ], !dbg !34
5037+
//unreachable, !dbg !34
5038+
LLVMPositionBuilderAtEnd (builder, noex_bb);
5039+
call_intrins (ctx, INTRINS_WASM_RETHROW, args, "");
5040+
LLVMBuildUnreachable (builder);
5041+
5042+
/* Catch case */
5043+
LLVMPositionBuilderAtEnd (builder, ex_bb);
5044+
#endif
50065045
} else {
50075046
MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
50085047
g_assert (handler_bb);

0 commit comments

Comments
 (0)