X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=3dd967b4534c7541de8bac8b0297ec68ca94f2a7;hb=1a6f502f565a79c453ebefea521327907fb52efa;hp=c0a81b341f499345d94144762cce30e754580af5;hpb=93e2d1dc48339be472300910e9290939ee253177;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index c0a81b341f4..3dd967b4534 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -1097,6 +1097,8 @@ mono_mb_emit_exception_marshal_directive (MonoMethodBuilder *mb, char *msg) mono_mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", s); } +#endif /* !DISABLE_JIT */ + guint mono_type_to_ldind (MonoType *type) { @@ -1208,6 +1210,8 @@ handle_enum: return -1; } +#ifndef DISABLE_JIT + static void emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec) { @@ -2660,6 +2664,59 @@ get_wrapper_target_class (MonoImage *image) return klass; } +static MonoMethod* +check_generic_delegate_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def_method, MonoGenericContext *ctx) +{ + MonoMethod *res; + MonoMethod *inst, *def; + + /* + * Look for the instance + */ + res = mono_marshal_find_in_cache (cache, orig_method->klass); + if (res) + return res; + + /* + * Look for the definition + */ + def = mono_marshal_find_in_cache (cache, def_method->klass); + if (def) { + inst = mono_class_inflate_generic_method (def, ctx); + /* Cache it */ + mono_memory_barrier (); + mono_marshal_lock (); + res = g_hash_table_lookup (cache, orig_method->klass); + if (!res) { + g_hash_table_insert (cache, orig_method->klass, inst); + res = inst; + } + mono_marshal_unlock (); + return res; + } + return NULL; +} + +static MonoMethod* +cache_generic_delegate_wrapper (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def, MonoGenericContext *ctx) +{ + MonoMethod *inst, *res; + + /* + * We use the same cache for the generic definition and the instances. + */ + inst = mono_class_inflate_generic_method (def, ctx); + mono_memory_barrier (); + mono_marshal_lock (); + res = g_hash_table_lookup (cache, orig_method->klass); + if (!res) { + g_hash_table_insert (cache, orig_method->klass, inst); + res = inst; + } + mono_marshal_unlock (); + return res; +} + MonoMethod * mono_marshal_get_delegate_begin_invoke (MonoMethod *method) { @@ -2669,22 +2726,46 @@ mono_marshal_get_delegate_begin_invoke (MonoMethod *method) GHashTable *cache; int params_var; char *name; + MonoGenericContext *ctx = NULL; + MonoMethod *orig_method = NULL; g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class && !strcmp (method->name, "BeginInvoke")); + /* + * For generic delegates, create a generic wrapper, and returns an instance to help AOT. + */ + if (method->is_inflated) { + orig_method = method; + ctx = &((MonoMethodInflated*)method)->context; + method = ((MonoMethodInflated*)method)->declaring; + } + sig = mono_signature_no_pinvoke (method); - cache = get_cache (&method->klass->image->delegate_begin_invoke_cache, - (GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - if ((res = mono_marshal_find_in_cache (cache, sig))) - return res; + /* + * Check cache + */ + if (ctx) { + cache = get_cache (&method->klass->image->delegate_begin_invoke_generic_cache, mono_aligned_addr_hash, NULL); + res = check_generic_delegate_wrapper_cache (cache, orig_method, method, ctx); + if (res) + return res; + } else { + cache = get_cache (&method->klass->image->delegate_begin_invoke_cache, + (GHashFunc)mono_signature_hash, + (GCompareFunc)mono_metadata_signature_equal); + if ((res = mono_marshal_find_in_cache (cache, sig))) + return res; + } g_assert (sig->hasthis); name = mono_signature_to_name (sig, "begin_invoke"); - mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_BEGIN_INVOKE); + if (ctx) + mb = mono_mb_new (method->klass, name, MONO_WRAPPER_DELEGATE_BEGIN_INVOKE); + else + mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_BEGIN_INVOKE); g_free (name); #ifndef DISABLE_JIT @@ -2696,7 +2777,14 @@ mono_marshal_get_delegate_begin_invoke (MonoMethod *method) mono_mb_emit_byte (mb, CEE_RET); #endif - res = mono_mb_create_and_cache (cache, sig, mb, sig, sig->param_count + 16); + if (ctx) { + MonoMethod *def; + def = mono_mb_create_and_cache (cache, method->klass, mb, sig, sig->param_count + 16); + res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); + } else { + res = mono_mb_create_and_cache (cache, sig, mb, sig, sig->param_count + 16); + } + mono_mb_free (mb); return res; } @@ -2823,6 +2911,12 @@ mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type) mono_mb_emit_op (mb, CEE_LDOBJ, klass); break; } + case MONO_TYPE_VAR: + case MONO_TYPE_MVAR: { + MonoClass *klass = mono_class_from_mono_type (return_type); + mono_mb_emit_op (mb, CEE_UNBOX_ANY, klass); + break; + } default: g_warning ("type 0x%x not handled", return_type->type); g_assert_not_reached (); @@ -2842,22 +2936,46 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method) GHashTable *cache; int params_var; char *name; + MonoGenericContext *ctx = NULL; + MonoMethod *orig_method = NULL; g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class && !strcmp (method->name, "EndInvoke")); + /* + * For generic delegates, create a generic wrapper, and returns an instance to help AOT. + */ + if (method->is_inflated) { + orig_method = method; + ctx = &((MonoMethodInflated*)method)->context; + method = ((MonoMethodInflated*)method)->declaring; + } + sig = mono_signature_no_pinvoke (method); - cache = get_cache (&method->klass->image->delegate_end_invoke_cache, - (GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - if ((res = mono_marshal_find_in_cache (cache, sig))) - return res; + /* + * Check cache + */ + if (ctx) { + cache = get_cache (&method->klass->image->delegate_end_invoke_generic_cache, mono_aligned_addr_hash, NULL); + res = check_generic_delegate_wrapper_cache (cache, orig_method, method, ctx); + if (res) + return res; + } else { + cache = get_cache (&method->klass->image->delegate_end_invoke_cache, + (GHashFunc)mono_signature_hash, + (GCompareFunc)mono_metadata_signature_equal); + if ((res = mono_marshal_find_in_cache (cache, sig))) + return res; + } g_assert (sig->hasthis); name = mono_signature_to_name (sig, "end_invoke"); - mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_END_INVOKE); + if (ctx) + mb = mono_mb_new (method->klass, name, MONO_WRAPPER_DELEGATE_END_INVOKE); + else + mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_END_INVOKE); g_free (name); #ifndef DISABLE_JIT @@ -2874,8 +2992,14 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method) mono_mb_emit_restore_result (mb, sig->ret); #endif - res = mono_mb_create_and_cache (cache, sig, - mb, sig, sig->param_count + 16); + if (ctx) { + MonoMethod *def; + def = mono_mb_create_and_cache (cache, method->klass, mb, sig, sig->param_count + 16); + res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); + } else { + res = mono_mb_create_and_cache (cache, sig, + mb, sig, sig->param_count + 16); + } mono_mb_free (mb); return res; @@ -2953,11 +3077,11 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) /* this seems to be the best plase to put this, as all remoting invokes seem to get filtered through here */ #ifndef DISABLE_COM - if (method->klass->is_com_object || method->klass == mono_defaults.com_object_class) { + if (mono_class_is_com_object (method->klass) || method->klass == mono_defaults.com_object_class) { MonoVTable *vtable = mono_class_vtable (mono_domain_get (), method->klass); g_assert (vtable); /*FIXME do proper error handling*/ - if (!vtable->remote) { + if (!mono_vtable_is_remote (vtable)) { return mono_cominterop_get_invoke (method); } } @@ -4022,33 +4146,10 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) * Check cache */ if (ctx) { - MonoMethod *def, *inst; - - /* - * Look for the instance - */ cache = get_cache (&method->klass->image->delegate_invoke_generic_cache, mono_aligned_addr_hash, NULL); - res = mono_marshal_find_in_cache (cache, orig_method->klass); + res = check_generic_delegate_wrapper_cache (cache, orig_method, method, ctx); if (res) return res; - - /* - * Look for the definition - */ - def = mono_marshal_find_in_cache (cache, method->klass); - if (def) { - inst = mono_class_inflate_generic_method (def, ctx); - /* Cache it */ - mono_memory_barrier (); - mono_marshal_lock (); - res = g_hash_table_lookup (cache, orig_method->klass); - if (!res) { - g_hash_table_insert (cache, orig_method->klass, inst); - res = inst; - } - mono_marshal_unlock (); - return res; - } } else if (callvirt || static_method_with_first_arg_bound) { GHashTable **cache_ptr; if (static_method_with_first_arg_bound) @@ -4197,22 +4298,10 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) #endif /* DISABLE_JIT */ if (ctx) { - MonoMethod *def, *inst; + MonoMethod *def; - /* - * We use the same cache for the generic definition and the instances. - */ def = mono_mb_create_and_cache (cache, method->klass, mb, sig, sig->param_count + 16); - - inst = mono_class_inflate_generic_method (def, ctx); - mono_memory_barrier (); - mono_marshal_lock (); - res = g_hash_table_lookup (cache, orig_method->klass); - if (!res) { - g_hash_table_insert (cache, orig_method->klass, inst); - res = inst; - } - mono_marshal_unlock (); + res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); } else if (static_method_with_first_arg_bound || callvirt) { // From mono_mb_create_and_cache newm = mono_mb_create_method (mb, sig, sig->param_count + 16); @@ -4861,6 +4950,9 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual) g_hash_table_insert (cache, callsig, res); /* Can't insert it into wrapper_hash since the key is a signature */ g_hash_table_insert (method->klass->image->runtime_invoke_direct_cache, method, res); + info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_RUNTIME_INVOKE_NORMAL); + info->d.runtime_invoke.sig = callsig; + mono_marshal_set_wrapper_info (res, info); } else { mono_free_method (newm); } @@ -5603,7 +5695,9 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon for (i = 0; i < sig->param_count; i++) mono_mb_emit_ldarg (mb, i + sig->hasthis); - mono_mb_emit_native_call (mb, csig2, (gpointer) func); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_op (mb, CEE_MONO_JIT_ICALL_ADDR, (gpointer)func); + mono_mb_emit_calli (mb, csig2); if (check_exceptions) emit_thread_interrupt_checkpoint (mb); mono_mb_emit_byte (mb, CEE_RET); @@ -5618,18 +5712,23 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon mono_mb_free (mb); info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_ICALL_WRAPPER); + info->d.icall.func = (gpointer)func; mono_marshal_set_wrapper_info (res, info); return res; } -#ifndef DISABLE_JIT static int emit_marshal_custom (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + if (action == MARSHAL_ACTION_CONV_IN && t->type == MONO_TYPE_VALUETYPE) + *conv_arg_type = &mono_defaults.int_class->byval_arg; + return conv_arg; +#else MonoType *mtype; MonoClass *mklass; static MonoClass *ICustomMarshaler = NULL; @@ -5923,8 +6022,9 @@ handle_exception: default: g_assert_not_reached (); } - return conv_arg; +#endif + } static int @@ -5933,6 +6033,7 @@ emit_marshal_asany (EmitMarshalContext *m, int argnum, MonoType *t, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifndef DISABLE_JIT MonoMethodBuilder *mb = m->mb; switch (action) { @@ -5969,7 +6070,7 @@ emit_marshal_asany (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -5979,6 +6080,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifndef DISABLE_JIT MonoMethodBuilder *mb = m->mb; MonoClass *klass, *date_time_class; int pos = 0, pos2; @@ -6252,7 +6354,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -6262,6 +6364,16 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + switch (action) { + case MARSHAL_ACTION_CONV_IN: + *conv_arg_type = &mono_defaults.int_class->byval_arg; + break; + case MARSHAL_ACTION_MANAGED_CONV_IN: + *conv_arg_type = &mono_defaults.int_class->byval_arg; + break; + } +#else MonoMethodBuilder *mb = m->mb; MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, spec); MonoMarshalConv conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec); @@ -6419,15 +6531,20 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } + static int emit_marshal_safehandle (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + if (action == MARSHAL_ACTION_CONV_IN) + *conv_arg_type = &mono_defaults.int_class->byval_arg; +#else MonoMethodBuilder *mb = m->mb; switch (action){ @@ -6578,15 +6695,20 @@ emit_marshal_safehandle (EmitMarshalContext *m, int argnum, MonoType *t, default: printf ("Unhandled case for MarshalAction: %d\n", action); } - +#endif return conv_arg; } + static int emit_marshal_handleref (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + if (action == MARSHAL_ACTION_CONV_IN) + *conv_arg_type = &mono_defaults.int_class->byval_arg; +#else MonoMethodBuilder *mb = m->mb; switch (action){ @@ -6639,16 +6761,21 @@ emit_marshal_handleref (EmitMarshalContext *m, int argnum, MonoType *t, default: fprintf (stderr, "Unhandled case for MarshalAction: %d\n", action); } - +#endif return conv_arg; } + static int emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + if (action == MARSHAL_ACTION_CONV_IN) + *conv_arg_type = &mono_defaults.int_class->byval_arg; +#else MonoMethodBuilder *mb = m->mb; MonoClass *klass = mono_class_from_mono_type (t); int pos, pos2, loc; @@ -7122,10 +7249,11 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } +#ifndef DISABLE_JIT #ifndef DISABLE_COM @@ -7245,6 +7373,7 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, } #endif /* DISABLE_COM */ +#endif /* DISABLE_JIT */ static gboolean mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo) @@ -7264,12 +7393,23 @@ mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo) } } + static int emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + switch (action) { + case MARSHAL_ACTION_CONV_IN: + *conv_arg_type = &mono_defaults.object_class->byval_arg; + break; + case MARSHAL_ACTION_MANAGED_CONV_IN: + *conv_arg_type = &mono_defaults.int_class->byval_arg; + break; + } +#else MonoMethodBuilder *mb = m->mb; MonoClass *klass = mono_class_from_mono_type (t); gboolean need_convert, need_free; @@ -7942,16 +8082,82 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } +static MonoType* +marshal_boolean_conv_in_get_local_type (MonoMarshalSpec *spec, guint8 *ldc_op /*out*/) +{ + if (spec == NULL) { + return &mono_defaults.int32_class->byval_arg; + } else { + switch (spec->native) { + case MONO_NATIVE_I1: + case MONO_NATIVE_U1: + return &mono_defaults.byte_class->byval_arg; + case MONO_NATIVE_VARIANTBOOL: + if (ldc_op) *ldc_op = CEE_LDC_I4_M1; + return &mono_defaults.int16_class->byval_arg; + case MONO_NATIVE_BOOLEAN: + return &mono_defaults.int32_class->byval_arg; + default: + g_warning ("marshalling bool as native type %x is currently not supported", spec->native); + return &mono_defaults.int32_class->byval_arg; + } + } +} + +static MonoClass* +marshal_boolean_managed_conv_in_get_conv_arg_class (MonoMarshalSpec *spec, guint8 *ldop/*out*/) +{ + MonoClass* conv_arg_class = mono_defaults.int32_class; + if (spec) { + switch (spec->native) { + case MONO_NATIVE_I1: + case MONO_NATIVE_U1: + conv_arg_class = mono_defaults.byte_class; + if (ldop) *ldop = CEE_LDIND_I1; + break; + case MONO_NATIVE_VARIANTBOOL: + conv_arg_class = mono_defaults.int16_class; + if (ldop) *ldop = CEE_LDIND_I2; + break; + case MONO_NATIVE_BOOLEAN: + break; + default: + g_warning ("marshalling bool as native type %x is currently not supported", spec->native); + } + } + return conv_arg_class; +} + static int emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifdef DISABLE_JIT + switch (action) { + case MARSHAL_ACTION_CONV_IN: + if (t->byref) + *conv_arg_type = &mono_defaults.int_class->byval_arg; + else + *conv_arg_type = marshal_boolean_conv_in_get_local_type (spec, NULL); + break; + + case MARSHAL_ACTION_MANAGED_CONV_IN: { + MonoClass* conv_arg_class = marshal_boolean_managed_conv_in_get_conv_arg_class (spec, NULL); + if (t->byref) + *conv_arg_type = &conv_arg_class->this_arg; + else + *conv_arg_type = &conv_arg_class->byval_arg; + break; + } + + } +#else MonoMethodBuilder *mb = m->mb; switch (action) { @@ -7960,27 +8166,7 @@ emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t, int label_false; guint8 ldc_op = CEE_LDC_I4_1; - if (spec == NULL) { - local_type = &mono_defaults.int32_class->byval_arg; - } else { - switch (spec->native) { - case MONO_NATIVE_I1: - case MONO_NATIVE_U1: - local_type = &mono_defaults.byte_class->byval_arg; - break; - case MONO_NATIVE_VARIANTBOOL: - local_type = &mono_defaults.int16_class->byval_arg; - ldc_op = CEE_LDC_I4_M1; - break; - case MONO_NATIVE_BOOLEAN: - local_type = &mono_defaults.int32_class->byval_arg; - break; - default: - g_warning ("marshalling bool as native type %x is currently not supported", spec->native); - local_type = &mono_defaults.int32_class->byval_arg; - break; - } - } + local_type = marshal_boolean_conv_in_get_local_type (spec, &ldc_op); if (t->byref) *conv_arg_type = &mono_defaults.int_class->byval_arg; else @@ -8038,26 +8224,9 @@ emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t, guint8 ldop = CEE_LDIND_I4; int label_null, label_false; + conv_arg_class = marshal_boolean_managed_conv_in_get_conv_arg_class (spec, &ldop); conv_arg = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg); - if (spec) { - switch (spec->native) { - case MONO_NATIVE_I1: - case MONO_NATIVE_U1: - conv_arg_class = mono_defaults.byte_class; - ldop = CEE_LDIND_I1; - break; - case MONO_NATIVE_VARIANTBOOL: - conv_arg_class = mono_defaults.int16_class; - ldop = CEE_LDIND_I2; - break; - case MONO_NATIVE_BOOLEAN: - break; - default: - g_warning ("marshalling bool as native type %x is currently not supported", spec->native); - } - } - if (t->byref) *conv_arg_type = &conv_arg_class->this_arg; else @@ -8129,7 +8298,7 @@ emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -8138,6 +8307,7 @@ emit_marshal_ptr (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifndef DISABLE_JIT MonoMethodBuilder *mb = m->mb; switch (action) { @@ -8163,7 +8333,7 @@ emit_marshal_ptr (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8172,6 +8342,7 @@ emit_marshal_char (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifndef DISABLE_JIT MonoMethodBuilder *mb = m->mb; switch (action) { @@ -8190,7 +8361,7 @@ emit_marshal_char (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8199,6 +8370,7 @@ emit_marshal_scalar (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action) { +#ifndef DISABLE_JIT MonoMethodBuilder *mb = m->mb; switch (action) { @@ -8214,7 +8386,7 @@ emit_marshal_scalar (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8290,10 +8462,10 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, else return emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action); } - return conv_arg; } +#ifndef DISABLE_JIT /** * mono_marshal_emit_native_wrapper: * @image: the image to use for looking up custom marshallers @@ -8513,9 +8685,9 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM mono_mb_emit_byte (mb, CEE_RET); } - #endif /* DISABLE_JIT */ + G_GNUC_UNUSED static void code_for (MonoMethod *method) { MonoMethodHeader *header = mono_method_get_header (method); @@ -8636,21 +8808,26 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, mb->method->save_lmf = 1; -#ifndef DISABLE_JIT /* * In AOT mode and embedding scenarios, it is possible that the icall is not * registered in the runtime doing the AOT compilation. */ if (!piinfo->addr && !aot) { +#ifndef DISABLE_JIT mono_mb_emit_exception (mb, exc_class, exc_arg); +#endif csig = signature_dup (method->klass->image, sig); csig->pinvoke = 0; res = mono_mb_create_and_cache (cache, method, mb, csig, csig->param_count + 16); mono_mb_free (mb); + + info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_NONE); + info->d.managed_to_native.method = method; + mono_marshal_set_wrapper_info (res, info); + return res; } -#endif /* internal calls: we simply push all arguments and call the method (no conversions) */ if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) { @@ -8851,7 +9028,6 @@ mono_marshal_get_native_func_wrapper_aot (MonoClass *klass) return res; } -#ifndef DISABLE_JIT /* * mono_marshal_emit_managed_wrapper: * @@ -8863,6 +9039,29 @@ mono_marshal_get_native_func_wrapper_aot (MonoClass *klass) void mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, uint32_t target_handle) { +#ifdef DISABLE_JIT + MonoMethodSignature *sig, *csig; + int i; + + sig = m->sig; + csig = m->csig; + + /* we first do all conversions */ + for (i = 0; i < sig->param_count; i ++) { + MonoType *t = sig->params [i]; + + switch (t->type) { + case MONO_TYPE_OBJECT: + case MONO_TYPE_CLASS: + case MONO_TYPE_VALUETYPE: + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_STRING: + case MONO_TYPE_BOOLEAN: + emit_marshal (m, i, sig->params [i], mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN); + } + } +#else MonoMethodSignature *sig, *csig; int i, *tmp_locals; gboolean closed = FALSE; @@ -9044,8 +9243,8 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i if (closed) g_free (sig); +#endif } -#endif /* DISABLE_JIT */ static void mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *csig) @@ -9219,9 +9418,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, mono_custom_attrs_free (cinfo); } -#ifndef DISABLE_JIT mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, target_handle); -#endif if (!target_handle) { WrapperInfo *info; @@ -9291,9 +9488,9 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) /* FIXME: Implement VTFIXUP_TYPE_FROM_UNMANAGED_RETAIN_APPDOMAIN. */ -#ifndef DISABLE_JIT mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, 0); +#ifndef DISABLE_JIT mb->dynamic = 1; #endif method = mono_mb_create_method (mb, csig, sig->param_count + 16); @@ -10295,14 +10492,13 @@ record_slot_vstore (MonoObject *array, size_t index, MonoObject *value) * - Maybe mve some MonoClass field into the vtable to reduce the number of loads * - Add a case for arrays of arrays. */ -MonoMethod* -mono_marshal_get_virtual_stelemref (MonoClass *array_class) +static MonoMethod* +get_virtual_stelemref_wrapper (int kind) { static MonoMethod *cached_methods [STELEMREF_KIND_COUNT] = { NULL }; /*object iface sealed regular*/ static MonoMethodSignature *signature; MonoMethodBuilder *mb; MonoMethod *res; - int kind; char *name; const char *param_names [16]; guint32 b1, b2, b3; @@ -10310,9 +10506,6 @@ mono_marshal_get_virtual_stelemref (MonoClass *array_class) int array_slot_addr; WrapperInfo *info; - g_assert (array_class->rank == 1); - kind = get_virtual_stelemref_kind (array_class->element_class); - if (cached_methods [kind]) return cached_methods [kind]; @@ -10680,6 +10873,30 @@ mono_marshal_get_virtual_stelemref (MonoClass *array_class) return cached_methods [kind]; } +MonoMethod* +mono_marshal_get_virtual_stelemref (MonoClass *array_class) +{ + int kind; + + g_assert (array_class->rank == 1); + kind = get_virtual_stelemref_kind (array_class->element_class); + + return get_virtual_stelemref_wrapper (kind); +} + +MonoMethod** +mono_marshal_get_virtual_stelemref_wrappers (int *nwrappers) +{ + MonoMethod **res; + int i; + + *nwrappers = STELEMREF_KIND_COUNT; + res = g_malloc0 (STELEMREF_KIND_COUNT * sizeof (MonoMethod*)); + for (i = 0; i < STELEMREF_KIND_COUNT; ++i) + res [i] = get_virtual_stelemref_wrapper (i); + return res; +} + /* * The wrapper info for the wrapper is a WrapperInfo structure. */