Skip to content

Commit

Permalink
Pop LMF frames in exception handlers on wasm, since the normal pop LM…
Browse files Browse the repository at this point in the history
…F code might not get executed in case of an exception.

Fixes dotnet#46613.
  • Loading branch information
vargaz committed Jan 19, 2021
1 parent 48f4f29 commit a689569
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/mono/mono/metadata/jit-icall-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ MONO_JIT_ICALL (mini_llvmonly_resolve_iface_call_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_resolve_vcall_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_throw_nullref_exception) \
MONO_JIT_ICALL (mini_llvmonly_throw_aot_failed_exception) \
MONO_JIT_ICALL (mini_llvmonly_pop_lmf) \
MONO_JIT_ICALL (mono_amd64_resume_unwind) \
MONO_JIT_ICALL (mono_amd64_start_gsharedvt_call) \
MONO_JIT_ICALL (mono_amd64_throw_corlib_exception) \
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/aot-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "mini.h"

/* Version number of the AOT file format */
#define MONO_AOT_FILE_VERSION 179
#define MONO_AOT_FILE_VERSION 180

#define MONO_AOT_TRAMP_PAGE_SIZE 16384

Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/mini/llvmonly-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,15 @@ mini_llvmonly_throw_aot_failed_exception (const char *name)
g_free (msg);
mono_llvm_throw_exception ((MonoObject*)ex);
}

/*
* mini_llvmonly_pop_lmf:
*
* Pop LMF off the LMF stack.
*/
void
mini_llvmonly_pop_lmf (MonoLMF *lmf)
{
if (lmf->previous_lmf)
mono_set_lmf (lmf->previous_lmf);
}
2 changes: 2 additions & 0 deletions src/mono/mono/mini/llvmonly-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ G_EXTERN_C void mini_llvmonly_throw_nullref_exception (void);

G_EXTERN_C void mini_llvmonly_throw_aot_failed_exception (const char *name);

G_EXTERN_C void mini_llvmonly_pop_lmf (MonoLMF *lmf);

#endif
12 changes: 12 additions & 0 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -8052,6 +8052,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b

#ifdef TARGET_WASM
if (common_call && needs_stack_walk)
/* If an exception is thrown, the LMF is popped by a call to mini_llvmonly_pop_lmf () */
emit_pop_lmf (cfg);
#endif

Expand Down Expand Up @@ -11669,6 +11670,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
mono_get_got_var (cfg);
#endif

#ifdef TARGET_WASM
if (cfg->lmf_var) {
// mini_llvmonly_pop_lmf () might be called before emit_push_lmf () so initialize the LMF
cfg->cbb = init_localsbb;
EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
int lmf_reg = ins->dreg;

EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_IMM, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0);
}
#endif

if (cfg->method == method && cfg->got_var)
mono_emit_load_got_addr (cfg);

Expand Down
18 changes: 18 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4700,6 +4700,24 @@ emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBloc
mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
}

#ifdef TARGET_WASM
if (ctx->cfg->lmf_var) {
LLVMValueRef callee;
LLVMValueRef args [1];
LLVMTypeRef sig = LLVMFunctionType1 (LLVMVoidType (), ctx->module->ptr_type, FALSE);

/*
* There might be an LMF on the stack inserted to enable stack walking, see
* method_needs_stack_walk (). If an exception is thrown, the LMF popping code
* is not executed, so do it here.
*/
g_assert (ctx->addresses [ctx->cfg->lmf_var->dreg]);
callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_pop_lmf));
args [0] = convert (ctx, ctx->addresses [ctx->cfg->lmf_var->dreg], ctx->module->ptr_type);
emit_call (ctx, bb, &ctx->builder, callee, args, 1);
}
#endif

LLVMBuilderRef handler_builder = create_builder (ctx);
LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
LLVMPositionBuilderAtEnd (handler_builder, target_bb);
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4913,6 +4913,7 @@ register_icalls (void)
register_icall (mini_llvmonly_init_delegate_virtual, mono_icall_sig_void_object_object_ptr, TRUE);
register_icall (mini_llvmonly_throw_nullref_exception, mono_icall_sig_void, TRUE);
register_icall (mini_llvmonly_throw_aot_failed_exception, mono_icall_sig_void_ptr, TRUE);
register_icall (mini_llvmonly_pop_lmf, mono_icall_sig_void_ptr, TRUE);

register_icall (mono_get_assembly_object, mono_icall_sig_object_ptr, TRUE);
register_icall (mono_get_method_object, mono_icall_sig_object_ptr, TRUE);
Expand Down

0 comments on commit a689569

Please sign in to comment.