MonoMethod *inflated_method;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ WrapperInfo *winfo = NULL;
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
mono_class_init (inflated_class);
- g_assert (!method->wrapper_type);
+ if (method->wrapper_type) {
+ winfo = mono_marshal_get_wrapper_info (method);
+
+ g_assert (winfo);
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ method = winfo->d.synchronized_inner.method;
+ }
if (inflated_class->byval_arg.type == MONO_TYPE_ARRAY ||
inflated_class->byval_arg.type == MONO_TYPE_SZARRAY) {
}
mono_class_init (inflated_method->klass);
g_assert (inflated_method->klass == inflated_class);
+
+ if (winfo) {
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ inflated_method = mono_marshal_get_synchronized_inner_wrapper (inflated_method);
+ }
+
res->method = inflated_method;
return res;
case MONO_RGCTX_INFO_STATIC_DATA: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
return mono_vtable_get_static_field_data (vtable);
case MONO_RGCTX_INFO_VTABLE: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
return vtable;
int i;
if (!MONO_TYPE_ISSTRUCT (t))
- return &mono_defaults.int_class->byval_arg;
+ return get_wrapper_shared_type (&mono_defaults.object_class->byval_arg);
klass = mono_class_from_mono_type (t);
orig_ctx = &klass->generic_class->context;
vtable = mono_class_vtable (domain, method->method.method.klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (method->method.method.klass));
+ mono_error_set_for_class_failure (error, method->method.method.klass);
return NULL;
}
g_assert (method->is_inflated);
+ if (mono_llvm_only && (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
+ method = mono_marshal_get_synchronized_wrapper (method);
+
if (!virtual_) {
addr = mono_compile_method_checked (method, error);
return_val_if_nok (error, NULL);
MonoGenericContext *context = mono_method_get_context (method);
MonoGenericInst *inst;
+ /*
+ * Instead of creating a shared version of the wrapper, create a shared version of the original
+ * method and construct a wrapper for it. Otherwise, we could end up with two copies of the
+ * same wrapper, breaking AOT which assumes wrappers are unique.
+ * FIXME: Add other cases.
+ */
+ if (method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
+ MonoMethod *wrapper = mono_marshal_method_from_wrapper (method);
+
+ return mono_marshal_get_synchronized_wrapper (mini_get_shared_method_full (wrapper, all_vt, is_gsharedvt));
+ }
+ if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+
+ if (info->subtype == WRAPPER_SUBTYPE_NONE) {
+ MonoMethod *m = mono_marshal_get_delegate_invoke (mini_get_shared_method_full (info->d.delegate_invoke.method, all_vt, is_gsharedvt), NULL);
+ return m;
+ }
+ }
+
if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) {
declaring_method = method;
} else {