From: Zoltan Varga Date: Mon, 19 Jun 2017 15:12:33 +0000 (-0400) Subject: [interp] Implement runtime invokes by executing the runtime-invoke wrappers using... X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=df203f3532c11d3d54d32b37aba49fd7a7abd5e4 [interp] Implement runtime invokes by executing the runtime-invoke wrappers using the interpreter. This saves some code and allows better interop with JIT exceptions. (#5057) --- diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index 556595081a5..c720d786dc1 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -1366,8 +1366,6 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb MonoObject *retval = NULL; MonoMethodSignature *sig = mono_method_signature (method); MonoClass *klass = mono_class_from_mono_type (sig->ret); - int i, type, isobject = 0; - void *ret = NULL; stackval result; stackval *args; ThreadContext context_struct; @@ -1404,118 +1402,23 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb MonoDomain *domain = mono_domain_get (); - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_STRING: - case MONO_TYPE_OBJECT: - case MONO_TYPE_CLASS: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - isobject = 1; - break; - case MONO_TYPE_VALUETYPE: - retval = mono_object_new_checked (domain, klass, error); - ret = mono_object_unbox (retval); - if (!sig->ret->data.klass->enumtype) - result.data.vt = ret; - else - result.data.vt = alloca (mono_class_instance_size (klass)); - break; - case MONO_TYPE_GENERICINST: - if (!MONO_TYPE_IS_REFERENCE (sig->ret)) { - retval = mono_object_new_checked (domain, klass, error); - ret = mono_object_unbox (retval); - if (!sig->ret->data.klass->enumtype) - result.data.vt = ret; - else - result.data.vt = alloca (mono_class_instance_size (klass)); - } else { - isobject = 1; - } - break; + MonoMethod *invoke_wrapper = mono_marshal_get_runtime_invoke_full (method, FALSE, TRUE); - case MONO_TYPE_PTR: - retval = mono_object_new_checked (domain, mono_defaults.int_class, error); - ret = mono_object_unbox (retval); - break; - default: - retval = mono_object_new_checked (domain, klass, error); - ret = mono_object_unbox (retval); - break; - } + //* MonoObject *runtime_invoke (MonoObject *this_obj, void **params, MonoObject **exc, void* method) + + result.data.vt = alloca (mono_class_instance_size (klass)); + args = alloca (sizeof (stackval) * 4); - args = alloca (sizeof (stackval) * (sig->param_count + !!sig->hasthis)); if (sig->hasthis) args [0].data.p = obj; + else + args [0].data.p = NULL; + args [1].data.p = params; + args [2].data.p = exc; + args [3].data.p = method; - for (i = 0; i < sig->param_count; ++i) { - int a_index = i + !!sig->hasthis; - if (sig->params [i]->byref) { - args [a_index].data.p = params [i]; - continue; - } - type = sig->params [i]->type; -handle_enum: - switch (type) { - case MONO_TYPE_U1: - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - args [a_index].data.i = *(MonoBoolean*)params [i]; - break; - case MONO_TYPE_U2: - case MONO_TYPE_I2: - case MONO_TYPE_CHAR: - args [a_index].data.i = *(gint16*)params [i]; - break; -#if SIZEOF_VOID_P == 4 - case MONO_TYPE_U: /* use VAL_POINTER? */ - case MONO_TYPE_I: -#endif - case MONO_TYPE_U4: - case MONO_TYPE_I4: - args [a_index].data.i = *(gint32*)params [i]; - break; -#if SIZEOF_VOID_P == 8 - case MONO_TYPE_U: - case MONO_TYPE_I: -#endif - case MONO_TYPE_U8: - case MONO_TYPE_I8: - args [a_index].data.l = *(gint64*)params [i]; - break; - case MONO_TYPE_R4: - args [a_index].data.f = *(gfloat *) params [i]; - break; - case MONO_TYPE_R8: - args [a_index].data.f = *(gdouble *) params [i]; - break; - case MONO_TYPE_VALUETYPE: - if (sig->params [i]->data.klass->enumtype) { - type = mono_class_enum_basetype (sig->params [i]->data.klass)->type; - goto handle_enum; - } else { - args [a_index].data.p = params [i]; - } - break; - case MONO_TYPE_STRING: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_OBJECT: - case MONO_TYPE_GENERICINST: - args [a_index].data.p = params [i]; - break; - default: - g_error ("type 0x%x not handled in runtime invoke", sig->params [i]->type); - } - } - - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - method = mono_marshal_get_native_wrapper (method, FALSE, FALSE); + INIT_FRAME (&frame, context->current_frame, args, &result, domain, invoke_wrapper, error); - INIT_FRAME (&frame,context->current_frame,args,&result,domain,method,error); if (exc) frame.invoke_trap = 1; context->managed_code = 1; @@ -1537,12 +1440,7 @@ handle_enum: else printf("dropped exception...\n"); } - if (sig->ret->type == MONO_TYPE_VOID && !method->string_ctor) - return NULL; - if (isobject || method->string_ctor) - return result.data.p; - stackval_to_data (sig->ret, &result, ret, sig->pinvoke); - return retval; + return result.data.p; } typedef struct { diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index 21bbecf8e50..113a086d3b4 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -751,6 +751,14 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target csignature = mono_method_signature (target_method); } + if (target_method && target_method->string_ctor) { + /* Create the real signature */ + MonoMethodSignature *ctor_sig = mono_metadata_signature_dup_mempool (td->mempool, csignature); + ctor_sig->ret = &mono_defaults.string_class->byval_arg; + + csignature = ctor_sig; + } + /* Intrinsics */ if (target_method) { if (target_method->klass == mono_defaults.string_class) {