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