Skip to content

Commit

Permalink
[wasm] Add some JIT helper functions to throw common corlib exception…
Browse files Browse the repository at this point in the history
…s. (#87044)
  • Loading branch information
vargaz authored Jun 27, 2023
1 parent 19d2e90 commit f777fe6
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/mono/mono/metadata/jit-icall-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ MONO_JIT_ICALL (mini_llvmonly_resolve_vcall_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_resolve_vcall_gsharedvt_fast) \
MONO_JIT_ICALL (mini_llvmonly_throw_nullref_exception) \
MONO_JIT_ICALL (mini_llvmonly_throw_aot_failed_exception) \
MONO_JIT_ICALL (mini_llvmonly_throw_index_out_of_range_exception) \
MONO_JIT_ICALL (mini_llvmonly_throw_invalid_cast_exception) \
MONO_JIT_ICALL (mini_llvmonly_interp_entry_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_throw_exception) \
MONO_JIT_ICALL (mini_llvmonly_rethrow_exception) \
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -14436,6 +14436,8 @@ static void aot_dump (MonoAotCompile *acfg)
static const MonoJitICallId preinited_jit_icalls [] = {
MONO_JIT_ICALL_mini_llvm_init_method,
MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception,
MONO_JIT_ICALL_mini_llvmonly_throw_index_out_of_range_exception,
MONO_JIT_ICALL_mini_llvmonly_throw_invalid_cast_exception,
MONO_JIT_ICALL_mini_llvmonly_throw_corlib_exception,
MONO_JIT_ICALL_mono_threads_state_poll,
MONO_JIT_ICALL_mini_llvmonly_init_vtable_slot,
Expand Down
22 changes: 22 additions & 0 deletions src/mono/mono/mini/llvmonly-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,8 @@ mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, gpointer meth
}

static GENERATE_GET_CLASS_WITH_CACHE (nullref, "System", "NullReferenceException")
static GENERATE_GET_CLASS_WITH_CACHE (index_out_of_range, "System", "IndexOutOfRangeException")
static GENERATE_GET_CLASS_WITH_CACHE (invalid_cast, "System", "InvalidCastException")

void
mini_llvmonly_throw_nullref_exception (void)
Expand All @@ -973,6 +975,26 @@ mini_llvmonly_throw_aot_failed_exception (const char *name)
mini_llvmonly_throw_exception ((MonoObject*)ex);
}

void
mini_llvmonly_throw_index_out_of_range_exception (void)
{
MonoClass *klass = mono_class_get_index_out_of_range_class ();

guint32 ex_token_index = m_class_get_type_token (klass) - MONO_TOKEN_TYPE_DEF;

mini_llvmonly_throw_corlib_exception (ex_token_index);
}

void
mini_llvmonly_throw_invalid_cast_exception (void)
{
MonoClass *klass = mono_class_get_invalid_cast_class ();

guint32 ex_token_index = m_class_get_type_token (klass) - MONO_TOKEN_TYPE_DEF;

mini_llvmonly_throw_corlib_exception (ex_token_index);
}

void
mini_llvmonly_interp_entry_gsharedvt (gpointer imethod, gpointer res, gpointer *args)
{
Expand Down
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 @@ -32,6 +32,8 @@ G_EXTERN_C void mini_llvmonly_init_delegate (MonoDelegate *del, MonoDelegateTram
G_EXTERN_C void mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, gpointer method_info, MonoVTable *vtable);

G_EXTERN_C void mini_llvmonly_throw_nullref_exception (void);
G_EXTERN_C void mini_llvmonly_throw_index_out_of_range_exception (void);
G_EXTERN_C void mini_llvmonly_throw_invalid_cast_exception (void);

G_EXTERN_C void mini_llvmonly_throw_aot_failed_exception (const char *name);

Expand Down
20 changes: 18 additions & 2 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2591,13 +2591,29 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
ctx->builder = builder = create_builder (ctx);
LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);

if (exc_id == MONO_EXC_NULL_REF) {
MonoJitICallId icall_id = (MonoJitICallId)0;
switch (exc_id) {
case MONO_EXC_NULL_REF:
icall_id = MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception;
break;
case MONO_EXC_INDEX_OUT_OF_RANGE:
icall_id = MONO_JIT_ICALL_mini_llvmonly_throw_index_out_of_range_exception;
break;
case MONO_EXC_INVALID_CAST:
icall_id = MONO_JIT_ICALL_mini_llvmonly_throw_invalid_cast_exception;
break;
default:
break;
}

if ((int)icall_id != 0) {
static LLVMTypeRef sig;

/* These calls are very common, so call a specialized version without an argument */
if (!sig)
sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
/* Can't cache this */
callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception));
callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (icall_id));
emit_call (ctx, bb, &builder, sig, callee, NULL, 0);
} else {
static LLVMTypeRef sig;
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -5076,6 +5076,8 @@ register_icalls (void)
register_icall (mini_llvmonly_init_vtable_slot, mono_icall_sig_ptr_ptr_int, FALSE);
register_icall (mini_llvmonly_init_delegate, mono_icall_sig_void_object_ptr, TRUE);
register_icall (mini_llvmonly_throw_nullref_exception, mono_icall_sig_void, TRUE);
register_icall (mini_llvmonly_throw_index_out_of_range_exception, mono_icall_sig_void, TRUE);
register_icall (mini_llvmonly_throw_invalid_cast_exception, mono_icall_sig_void, TRUE);
register_icall (mini_llvmonly_throw_aot_failed_exception, mono_icall_sig_void_ptr, TRUE);
register_icall (mini_llvmonly_interp_entry_gsharedvt, mono_icall_sig_void_ptr_ptr_ptr, TRUE);

Expand Down

0 comments on commit f777fe6

Please sign in to comment.