Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -312,6 +312,7 @@ MONO_JIT_ICALL (mono_throw_bad_image) \
MONO_JIT_ICALL (mono_throw_not_supported) \
MONO_JIT_ICALL (mono_throw_platform_not_supported) \
MONO_JIT_ICALL (mono_throw_invalid_program) \
MONO_JIT_ICALL (mono_throw_type_load) \
MONO_JIT_ICALL (mono_trace_enter_method) \
MONO_JIT_ICALL (mono_trace_leave_method) \
MONO_JIT_ICALL (mono_trace_tail_method) \
Expand Down
8 changes: 7 additions & 1 deletion src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -9580,7 +9580,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
mono_atomic_inc_i32 (&acfg->stats.genericcount);
return;
}
if (cfg->exception_type != MONO_EXCEPTION_NONE) {
if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD) {
// Clear the exception, method-to-ir has already replaced the INITOBJ of the invalid
// type with a THROW.
cfg->exception_type = MONO_EXCEPTION_NONE;
// TODO: log this?
}
else if (cfg->exception_type != MONO_EXCEPTION_NONE) {
/* Some instances cannot be JITted due to constraints etc. */
if (!method->is_inflated)
report_loader_error (acfg, cfg->error, FALSE, "Unable to compile method '%s' due to: '%s'.\n", mono_method_get_full_name (method), mono_error_get_message (cfg->error));
Expand Down
8 changes: 8 additions & 0 deletions src/mono/mono/mini/jit-icalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,14 @@ mono_throw_invalid_program (const char *msg)
mono_error_set_pending_exception (error);
}

void
mono_throw_type_load (void)
{
ERROR_DECL (error);
mono_error_set_generic_error (error, "System", "TypeLoadException", "");
mono_error_set_pending_exception (error);
}

void
mono_dummy_jit_icall (void)
{
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/jit-icalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ ICALL_EXPORT void mono_throw_platform_not_supported (void);

ICALL_EXPORT void mono_throw_invalid_program (const char *msg);

ICALL_EXPORT void mono_throw_type_load (void);

ICALL_EXPORT void mono_dummy_jit_icall (void);

ICALL_EXPORT void mono_dummy_jit_icall_val (gpointer ptr);
Expand Down
34 changes: 29 additions & 5 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,12 @@ mono_tailcall_print (const char *format, ...)
} while (0)

#define TYPE_LOAD_ERROR(klass) do { \
cfg->exception_ptr = klass; \
LOAD_ERROR; \
if (cfg->compile_aot) { \
mono_emit_jit_icall (cfg, mono_throw_type_load, NULL); \
} else { \
cfg->exception_ptr = klass; \
LOAD_ERROR; \
} \
} while (0)

#define CHECK_CFG_ERROR do {\
Expand Down Expand Up @@ -9898,8 +9902,16 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
else {
klass = NULL;
field = mono_field_from_token_checked (image, token, &klass, generic_context, cfg->error);
if (!field)
CHECK_TYPELOAD (klass);
if (!field) {
if (cfg->compile_aot && (!klass || mono_class_has_failure (klass))) {
clear_cfg_error (cfg);
cfg->exception_type = MONO_EXCEPTION_NONE;
mono_emit_jit_icall (cfg, mono_throw_type_load, NULL);
break;
} else {
CHECK_TYPELOAD (klass);
}
}
CHECK_CFG_ERROR;
}
if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_field (method, field))
Expand Down Expand Up @@ -11855,11 +11867,23 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
case MONO_CEE_INITOBJ:
--sp;
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);

if (cfg->compile_aot) {
// In AOT we replace initobj of invalid types with a throw.
if (!klass || mono_class_has_failure (klass)) {
mono_emit_jit_icall (cfg, mono_throw_type_load, NULL);
inline_costs += 10;
break;
}
} else {
CHECK_TYPELOAD (klass);
}

if (mini_class_is_reference (klass))
MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, sp [0]->dreg, 0, 0);
else
mini_emit_initobj (cfg, *sp, NULL, klass);

inline_costs += 1;
break;
case MONO_CEE_CONSTRAINED_:
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 @@ -5139,6 +5139,7 @@ register_icalls (void)
register_icall (mono_throw_not_supported, mono_icall_sig_void, FALSE);
register_icall (mono_throw_platform_not_supported, mono_icall_sig_void, FALSE);
register_icall (mono_throw_invalid_program, mono_icall_sig_void_ptr, FALSE);
register_icall (mono_throw_type_load, mono_icall_sig_void, FALSE);
register_icall_no_wrapper (mono_dummy_jit_icall, mono_icall_sig_void);
//register_icall_no_wrapper (mono_dummy_jit_icall_val, mono_icall_sig_void_ptr);
register_icall_no_wrapper (mini_init_method_rgctx, mono_icall_sig_void_ptr_ptr);
Expand Down
6 changes: 6 additions & 0 deletions src/mono/mono/mini/mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -3491,6 +3491,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts
*/
mono_compile_create_vars (cfg);

if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
cfg->exception_type = MONO_EXCEPTION_NONE;

mono_cfg_dump_create_context (cfg);
mono_cfg_dump_begin_group (cfg);

Expand Down Expand Up @@ -3706,6 +3709,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts
}
#endif

if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
cfg->exception_type = MONO_EXCEPTION_NONE;

/* after SSA translation */
if (parts == 2) {
if (MONO_METHOD_COMPILE_END_ENABLED ())
Expand Down
9 changes: 0 additions & 9 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2405,15 +2405,6 @@
<ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/explicitlayout/objrefandnonobjrefoverlap/case9/**">
<Issue>expected failure: overlapped structs fail at AOT compile time, not runtime</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Loader/classloader/explicitlayout/NestedStructs/case03/**">
<Issue>expected failure: overlapped structs fail at AOT compile time, not runtime</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Loader/classloader/explicitlayout/NestedStructs/case04/**">
<Issue>expected failure: overlapped structs fail at AOT compile time, not runtime</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Loader/classloader/explicitlayout/NestedStructs/case05/**">
<Issue>expected failure: overlapped structs fail at AOT compile time, not runtime</Issue>
</ExcludeList>
<ExcludeList Include = "$(XunitTestBinBase)/Loader/classloader/RefFields/Validate/**">
<Issue>expected failure: unsupported type with ref field fails at AOT compile time, not runtime</Issue>
</ExcludeList>
Expand Down