X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=3dd967b4534c7541de8bac8b0297ec68ca94f2a7;hb=1a6f502f565a79c453ebefea521327907fb52efa;hp=bd88fcc3c3e021cf1f0697ff49aaf0dd07706ca5;hpb=99c3107f1d47d707e6b7786422154292cdbcf938;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index bd88fcc3c3e..3dd967b4534 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -124,8 +124,6 @@ mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype static void mono_array_to_byvalarray (gpointer native_arr, MonoArray *arr, MonoClass *eltype, guint32 elnum); -static MonoObject * -mono_remoting_wrapper (MonoMethod *method, gpointer *params); static MonoAsyncResult * mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params); @@ -142,9 +140,15 @@ mono_marshal_set_domain_by_id (gint32 id, MonoBoolean push); static gboolean mono_marshal_check_domain_image (gint32 domain_id, MonoImage *image); +#ifndef DISABLE_REMOTING +static MonoObject * +mono_remoting_wrapper (MonoMethod *method, gpointer *params); + void mono_upgrade_remote_class_wrapper (MonoReflectionType *rtype, MonoTransparentProxy *tproxy); +#endif + static MonoReflectionType * type_from_handle (MonoType *handle); @@ -248,7 +252,6 @@ mono_marshal_init (void) register_icall (g_free, "g_free", "void ptr", FALSE); register_icall (mono_object_isinst, "mono_object_isinst", "object object ptr", FALSE); register_icall (mono_struct_delete_old, "mono_struct_delete_old", "void ptr ptr", FALSE); - register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE); register_icall (mono_delegate_begin_invoke, "mono_delegate_begin_invoke", "object object ptr", FALSE); register_icall (mono_delegate_end_invoke, "mono_delegate_end_invoke", "object object ptr", FALSE); register_icall (mono_marshal_xdomain_copy_value, "mono_marshal_xdomain_copy_value", "object object", FALSE); @@ -258,11 +261,14 @@ mono_marshal_init (void) register_icall (mono_compile_method, "mono_compile_method", "ptr ptr", FALSE); register_icall (mono_context_get, "mono_context_get", "object", FALSE); register_icall (mono_context_set, "mono_context_set", "void object", FALSE); - register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE); register_icall (type_from_handle, "type_from_handle", "object ptr", FALSE); register_icall (mono_gc_wbarrier_generic_nostore, "wb_generic", "void ptr", FALSE); register_icall (mono_gchandle_get_target, "mono_gchandle_get_target", "object int32", TRUE); +#ifndef DISABLE_REMOTING + register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE); + register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE); +#endif mono_cominterop_init (); } } @@ -278,9 +284,9 @@ mono_marshal_cleanup (void) marshal_mutex_initialized = FALSE; } -MonoClass *byte_array_class; +#ifndef DISABLE_REMOTING +static MonoClass *byte_array_class; static MonoMethod *method_rs_serialize, *method_rs_deserialize, *method_exc_fixexc, *method_rs_appdomain_target; -static MonoMethod *method_set_context, *method_get_context; static MonoMethod *method_set_call_context, *method_needs_context_sink, *method_rs_serialize_exc; static void @@ -302,11 +308,6 @@ mono_remoting_marshal_init (void) klass = mono_defaults.exception_class; method_exc_fixexc = mono_class_get_method_from_name (klass, "FixRemotingException", -1); - klass = mono_defaults.thread_class; - method_get_context = mono_class_get_method_from_name (klass, "get_CurrentContext", -1); - - klass = mono_defaults.appdomain_class; - method_set_context = mono_class_get_method_from_name (klass, "InternalSetContext", -1); byte_array_class = mono_array_class_get (mono_defaults.byte_class, 1); klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Messaging", "CallContext"); @@ -318,6 +319,7 @@ mono_remoting_marshal_init (void) module_initialized = TRUE; } } +#endif gpointer mono_delegate_to_ftnptr (MonoDelegate *delegate) @@ -382,40 +384,37 @@ delegate_hash_table_new (void) { static void delegate_hash_table_remove (MonoDelegate *d) { -#ifdef HAVE_MOVING_COLLECTOR - guint32 gchandle; -#endif + guint32 gchandle = 0; + mono_marshal_lock (); if (delegate_hash_table == NULL) delegate_hash_table = delegate_hash_table_new (); -#ifdef HAVE_MOVING_COLLECTOR - gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); -#endif + if (mono_gc_is_moving ()) + gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); g_hash_table_remove (delegate_hash_table, d->delegate_trampoline); mono_marshal_unlock (); -#ifdef HAVE_MOVING_COLLECTOR - mono_gchandle_free (gchandle); -#endif + if (mono_gc_is_moving ()) + mono_gchandle_free (gchandle); } static void delegate_hash_table_add (MonoDelegate *d) { -#ifdef HAVE_MOVING_COLLECTOR - guint32 gchandle = mono_gchandle_new_weakref ((MonoObject*)d, FALSE); + guint32 gchandle; guint32 old_gchandle; -#endif + mono_marshal_lock (); if (delegate_hash_table == NULL) delegate_hash_table = delegate_hash_table_new (); -#ifdef HAVE_MOVING_COLLECTOR - old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); - g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, GUINT_TO_POINTER (gchandle)); - if (old_gchandle) - mono_gchandle_free (old_gchandle); -#else - g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, d); -#endif + if (mono_gc_is_moving ()) { + gchandle = mono_gchandle_new_weakref ((MonoObject*)d, FALSE); + old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); + g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, GUINT_TO_POINTER (gchandle)); + if (old_gchandle) + mono_gchandle_free (old_gchandle); + } else { + g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, d); + } mono_marshal_unlock (); } @@ -461,9 +460,7 @@ parse_unmanaged_function_pointer_attr (MonoClass *klass, MonoMethodPInvoke *piin MonoDelegate* mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn) { -#ifdef HAVE_MOVING_COLLECTOR guint32 gchandle; -#endif MonoDelegate *d; if (ftn == NULL) @@ -473,17 +470,17 @@ mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn) if (delegate_hash_table == NULL) delegate_hash_table = delegate_hash_table_new (); -#ifdef HAVE_MOVING_COLLECTOR - gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, ftn)); - mono_marshal_unlock (); - if (gchandle) - d = (MonoDelegate*)mono_gchandle_get_target (gchandle); - else - d = NULL; -#else - d = g_hash_table_lookup (delegate_hash_table, ftn); - mono_marshal_unlock (); -#endif + if (mono_gc_is_moving ()) { + gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, ftn)); + mono_marshal_unlock (); + if (gchandle) + d = (MonoDelegate*)mono_gchandle_get_target (gchandle); + else + d = NULL; + } else { + d = g_hash_table_lookup (delegate_hash_table, ftn); + mono_marshal_unlock (); + } if (d == NULL) { /* This is a native function, so construct a delegate for it */ MonoMethodSignature *sig; @@ -731,13 +728,12 @@ mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text) items_written = mono_stringbuilder_capacity (sb); if (!error) { - if (! sb->str || sb->str == sb->cached_str) { + if (! sb->str || sb->str == sb->cached_str) MONO_OBJECT_SETREF (sb, str, mono_string_new_size (mono_domain_get (), items_written)); - sb->cached_str = NULL; - } memcpy (mono_string_chars (sb->str), ut, items_written * 2); sb->length = items_written; + sb->cached_str = NULL; } else g_error_free (error); @@ -1029,6 +1025,8 @@ mono_string_new_len_wrapper (const char *text, guint length) return mono_string_new_len (mono_domain_get (), text, length); } +#ifndef DISABLE_JIT +#ifndef DISABLE_REMOTING static int mono_mb_emit_proxy_check (MonoMethodBuilder *mb, int branch_code) { @@ -1078,6 +1076,7 @@ mono_mb_emit_contextbound_check (MonoMethodBuilder *mb, int branch_code) mono_mb_emit_icon (mb, 0); return mono_mb_emit_branch (mb, branch_code); } +#endif /* DISABLE_REMOTING */ /* * mono_mb_emit_exception_marshal_directive: @@ -1098,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) { @@ -1209,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) { @@ -1968,6 +1971,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje break; } case MONO_TYPE_OBJECT: { +#ifndef DISABLE_COM mono_init_com_types (); if (to_object) { static MonoMethod *variant_clear = NULL; @@ -1995,7 +1999,11 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje mono_mb_emit_byte(mb, CEE_LDIND_REF); mono_mb_emit_ldloc (mb, 1); mono_mb_emit_managed_call (mb, get_native_variant_for_object, NULL); - } + } +#else + char *msg = g_strdup_printf ("COM support was disabled at compilation time."); + mono_mb_emit_exception_marshal_directive (mb, msg); +#endif break; } @@ -2097,6 +2105,8 @@ mono_marshal_emit_thread_interrupt_checkpoint (MonoMethodBuilder *mb) emit_thread_interrupt_checkpoint (mb); } +#endif /* DISABLE_JIT */ + static MonoAsyncResult * mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params) { @@ -2113,10 +2123,11 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params) if (mcast_delegate->prev != NULL) mono_raise_exception (mono_get_exception_argument (NULL, "The delegate must have only one target")); +#ifndef DISABLE_REMOTING if (delegate->target && mono_object_class (delegate->target) == mono_defaults.transparent_proxy_class) { MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target; - if (!tp->remote_class->proxy_class->contextbound || tp->rp->context != (MonoObject *) mono_context_get ()) { + if (!mono_class_is_contextbound (tp->remote_class->proxy_class) || tp->rp->context != (MonoObject *) mono_context_get ()) { /* If the target is a proxy, make a direct call. Is proxy's work // to make the call asynchronous. @@ -2140,6 +2151,7 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params) return ares; } } +#endif klass = delegate->object.vtable->klass; @@ -2155,6 +2167,8 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params) return mono_thread_pool_add ((MonoObject *)delegate, msg, async_callback, state); } +#ifndef DISABLE_JIT + static int mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolean save_this) { @@ -2197,6 +2211,8 @@ mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolea return params_var; } +#endif /* DISABLE_JIT */ + static char* mono_signature_to_name (MonoMethodSignature *sig, const char *prefix) { @@ -2550,6 +2566,7 @@ mono_marshal_method_from_wrapper (MonoMethod *wrapper) case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: case MONO_WRAPPER_XDOMAIN_INVOKE: case MONO_WRAPPER_SYNCHRONIZED: + case MONO_WRAPPER_UNBOX: res = mono_marshal_get_wrapper_info (wrapper); if (res == NULL) return wrapper; @@ -2647,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) { @@ -2656,32 +2726,65 @@ 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 params_var = mono_mb_emit_save_args (mb, sig, FALSE); mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldloc (mb, params_var); mono_mb_emit_icall (mb, mono_delegate_begin_invoke); mono_mb_emit_byte (mb, CEE_RET); +#endif + + 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); + } - res = mono_mb_create_and_cache (cache, sig, mb, sig, sig->param_count + 16); mono_mb_free (mb); return res; } @@ -2729,14 +2832,17 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params) return NULL; } - if (delegate->target && mono_object_class (delegate->target) == mono_defaults.transparent_proxy_class) { +#ifndef DISABLE_REMOTING + if (delegate->target && mono_object_is_transparent_proxy (delegate->target)) { MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target; msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class); mono_message_init (domain, msg, delegate->method_info, NULL); msg->call_type = CallType_EndInvoke; MONO_OBJECT_SETREF (msg, async_result, ares); res = mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args); - } else { + } else +#endif + { res = mono_thread_pool_finish (ares, &out_args, &exc); } @@ -2756,6 +2862,8 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params) return res; } +#ifndef DISABLE_JIT + static void mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type) { @@ -2803,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 (); @@ -2811,6 +2925,8 @@ mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type) mono_mb_emit_byte (mb, CEE_RET); } +#endif /* DISABLE_JIT */ + MonoMethod * mono_marshal_get_delegate_end_invoke (MonoMethod *method) { @@ -2820,24 +2936,49 @@ 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 params_var = mono_mb_emit_save_args (mb, sig, FALSE); mono_mb_emit_ldarg (mb, 0); @@ -2849,14 +2990,23 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method) mono_mb_emit_byte (mb, CEE_RET); } else 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; } +#ifndef DISABLE_REMOTING + static MonoObject * mono_remoting_wrapper (MonoMethod *method, gpointer *params) { @@ -2873,7 +3023,7 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params) /* skip the this pointer */ params++; - if (this->remote_class->proxy_class->contextbound && this->rp->context == (MonoObject *) mono_context_get ()) + if (mono_class_is_contextbound (this->remote_class->proxy_class) && this->rp->context == (MonoObject *) mono_context_get ()) { int i; MonoMethodSignature *sig = mono_method_signature (method); @@ -2926,18 +3076,16 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) return method; /* this seems to be the best plase to put this, as all remoting invokes seem to get filtered through here */ - if (method->klass->is_com_object || method->klass == mono_defaults.com_object_class) { +#ifndef DISABLE_COM + 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) { -#ifndef DISABLE_COM + if (!mono_vtable_is_remote (vtable)) { return mono_cominterop_get_invoke (method); -#else - g_assert_not_reached (); -#endif } } +#endif sig = mono_signature_no_pinvoke (method); @@ -2949,6 +3097,8 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) return res; mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_REMOTING_INVOKE); + +#ifndef DISABLE_JIT mb->method->save_lmf = 1; params_var = mono_mb_emit_save_args (mb, sig, TRUE); @@ -2964,6 +3114,7 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) } else { mono_mb_emit_restore_result (mb, sig->ret); } +#endif res = mono_remoting_mb_create_and_cache (method, mb, sig, sig->param_count + 16); mono_mb_free (mb); @@ -2971,6 +3122,9 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) return res; } +#endif /* DISABLE_REMOTING */ + + /* mono_get_xdomain_marshal_type() * Returns the kind of marshalling that a type needs for cross domain calls. */ @@ -3109,6 +3263,9 @@ mono_marshal_xdomain_copy_out_value (MonoObject *src, MonoObject *dst) } } + +#if !(defined (DISABLE_JIT) || defined (DISABLE_REMOTING)) + static void mono_marshal_emit_xdomain_copy_value (MonoMethodBuilder *mb, MonoClass *pclass) { @@ -3121,16 +3278,19 @@ mono_marshal_emit_xdomain_copy_out_value (MonoMethodBuilder *mb, MonoClass *pcla { mono_mb_emit_icall (mb, mono_marshal_xdomain_copy_out_value); } +#endif +#ifndef DISABLE_REMOTING /* mono_marshal_supports_fast_xdomain() * Returns TRUE if the method can use the fast xdomain wrapper. */ static gboolean mono_marshal_supports_fast_xdomain (MonoMethod *method) { - return !method->klass->contextbound && + return !mono_class_is_contextbound (method->klass) && !((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && (strcmp (".ctor", method->name) == 0)); } +#endif static gint32 mono_marshal_set_domain_by_id (gint32 id, MonoBoolean push) @@ -3149,6 +3309,7 @@ mono_marshal_set_domain_by_id (gint32 id, MonoBoolean push) return current_domain->domain_id; } +#if !(defined (DISABLE_JIT) || defined (DISABLE_REMOTING)) static void mono_marshal_emit_switch_domain (MonoMethodBuilder *mb) { @@ -3168,6 +3329,7 @@ mono_marshal_emit_load_domain_method (MonoMethodBuilder *mb, MonoMethod *method) mono_mb_emit_ptr (mb, method); mono_mb_emit_icall (mb, mono_compile_method); } +#endif /* mono_marshal_check_domain_image () * Returns TRUE if the image is loaded in the specified @@ -3194,6 +3356,8 @@ mono_marshal_check_domain_image (gint32 domain_id, MonoImage *image) return tmp != NULL; } +#ifndef DISABLE_REMOTING + /* mono_marshal_get_xappdomain_dispatch () * Generates a method that dispatches a method call from another domain into * the current domain. @@ -3236,6 +3400,7 @@ mono_marshal_get_xappdomain_dispatch (MonoMethod *method, int *marshal_types, in mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_XDOMAIN_DISPATCH); mb->method->save_lmf = 1; +#ifndef DISABLE_JIT /* Locals */ loc_serialized_exc = mono_mb_add_local (mb, &byte_array_class->byval_arg); @@ -3445,6 +3610,7 @@ mono_marshal_get_xappdomain_dispatch (MonoMethod *method, int *marshal_types, in mono_mb_emit_byte (mb, CEE_RET); mono_mb_set_clauses (mb, 1, main_clause); +#endif res = mono_remoting_mb_create_and_cache (method, mb, csig, csig->param_count + 16); mono_mb_free (mb); @@ -3521,6 +3687,7 @@ mono_marshal_get_xappdomain_invoke (MonoMethod *method) /* Locals */ +#ifndef DISABLE_JIT if (complex_count > 0) loc_array = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); loc_serialized_data = mono_mb_add_local (mb, &byte_array_class->byval_arg); @@ -3770,6 +3937,7 @@ mono_marshal_get_xappdomain_invoke (MonoMethod *method) } mono_mb_emit_byte (mb, CEE_RET); +#endif /* DISABLE_JIT */ res = mono_remoting_mb_create_and_cache (method, mb, sig, sig->param_count + 16); mono_mb_free (mb); @@ -3827,6 +3995,7 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK); +#ifndef DISABLE_JIT for (i = 0; i <= sig->param_count; i++) mono_mb_emit_ldarg (mb, i); @@ -3853,6 +4022,7 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) mono_mb_patch_branch (mb, pos); mono_mb_emit_managed_call (mb, method, mono_method_signature (method)); mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_remoting_mb_create_and_cache (method, mb, sig, sig->param_count + 16); mono_mb_free (mb); @@ -3860,6 +4030,8 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) return res; } +#endif /* DISABLE_REMOTING */ + typedef struct { MonoMethodSignature *sig; @@ -3916,6 +4088,9 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) gboolean callvirt = FALSE; gboolean closed_over_null = FALSE; gboolean static_method_with_first_arg_bound = FALSE; + MonoGenericContext *ctx = NULL; + MonoGenericContainer *container = NULL; + MonoMethod *orig_method = NULL; /* * If the delegate target is null, and the target method is not static, a virtual @@ -3951,7 +4126,31 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) static_method_with_first_arg_bound = TRUE; } - if (callvirt || static_method_with_first_arg_bound) { + /* + * For generic delegates, create a generic wrapper, and returns an instance to help AOT. + */ + if (method->is_inflated && !callvirt && !static_method_with_first_arg_bound) { + orig_method = method; + ctx = &((MonoMethodInflated*)method)->context; + method = ((MonoMethodInflated*)method)->declaring; + + container = mono_method_get_generic_container (method); + if (!container) + container = method->klass->generic_container; + g_assert (container); + + invoke_sig = sig = mono_signature_no_pinvoke (method); + } + + /* + * Check cache + */ + if (ctx) { + cache = get_cache (&method->klass->image->delegate_invoke_generic_cache, mono_aligned_addr_hash, NULL); + res = check_generic_delegate_wrapper_cache (cache, orig_method, method, ctx); + if (res) + return res; + } else if (callvirt || static_method_with_first_arg_bound) { GHashTable **cache_ptr; if (static_method_with_first_arg_bound) cache_ptr = &method->klass->image->delegate_bound_static_invoke_cache; @@ -3973,7 +4172,8 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) cache = get_cache (&method->klass->image->delegate_invoke_cache, (GHashFunc)mono_signature_hash, (GCompareFunc)mono_metadata_signature_equal); - if ((res = mono_marshal_find_in_cache (cache, sig))) + res = mono_marshal_find_in_cache (cache, sig); + if (res) return res; } @@ -3983,9 +4183,13 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) invoke_sig = static_sig; name = mono_signature_to_name (sig, "invoke"); - mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_INVOKE); + if (ctx) + mb = mono_mb_new (method->klass, name, MONO_WRAPPER_DELEGATE_INVOKE); + else + mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_INVOKE); g_free (name); +#ifndef DISABLE_JIT /* allocate local 0 (object) */ local_target = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); local_prev = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); @@ -4019,7 +4223,10 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) mono_mb_emit_ldloc (mb, local_prev); for (i = 0; i < sig->param_count; i++) mono_mb_emit_ldarg (mb, i + 1); - mono_mb_emit_op (mb, CEE_CALLVIRT, method); + if (ctx) + mono_mb_emit_op (mb, CEE_CALLVIRT, mono_class_inflate_generic_method (method, &container->context)); + else + mono_mb_emit_op (mb, CEE_CALLVIRT, method); if (sig->ret->type != MONO_TYPE_VOID) mono_mb_emit_byte (mb, CEE_POP); @@ -4087,9 +4294,16 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) mono_mb_emit_byte (mb, CEE_RET); - if (static_method_with_first_arg_bound || callvirt) { + mb->skip_visibility = 1; +#endif /* DISABLE_JIT */ + + 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 if (static_method_with_first_arg_bound || callvirt) { // From mono_mb_create_and_cache - mb->skip_visibility = 1; newm = mono_mb_create_method (mb, sig, sig->param_count + 16); /*We perform double checked locking, so must fence before publishing*/ mono_memory_barrier (); @@ -4109,7 +4323,6 @@ mono_marshal_get_delegate_invoke (MonoMethod *method, MonoDelegate *del) mono_free_method (newm); } } else { - mb->skip_visibility = 1; res = mono_mb_create_and_cache (cache, sig, mb, sig, sig->param_count + 16); } mono_mb_free (mb); @@ -4274,6 +4487,8 @@ runtime_invoke_signature_equal (MonoMethodSignature *sig1, MonoMethodSignature * return mono_metadata_signature_equal (sig1, sig2); } +#ifndef DISABLE_JIT + /* * emit_invoke_call: * @@ -4303,7 +4518,12 @@ emit_invoke_call (MonoMethodBuilder *mb, MonoMethod *method, if (sig->hasthis) { if (method->string_ctor) { - mono_mb_emit_ptr (mb, string_dummy); + if (mono_gc_is_moving ()) { + mono_mb_emit_ptr (mb, &string_dummy); + mono_mb_emit_byte (mb, CEE_LDIND_REF); + } else { + mono_mb_emit_ptr (mb, string_dummy); + } } else { mono_mb_emit_ldarg (mb, 0); } @@ -4548,6 +4768,7 @@ emit_runtime_invoke_body (MonoMethodBuilder *mb, MonoClass *target_klass, MonoMe mono_mb_emit_ldloc (mb, 0); mono_mb_emit_byte (mb, CEE_RET); } +#endif /* * generates IL code for the runtime invoke function @@ -4693,6 +4914,7 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual) mb = mono_mb_new (target_klass, name, MONO_WRAPPER_RUNTIME_INVOKE); g_free (name); +#ifndef DISABLE_JIT param_names [0] = "this"; param_names [1] = "params"; param_names [2] = "exc"; @@ -4700,9 +4922,12 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual) mono_mb_set_param_names (mb, param_names); emit_runtime_invoke_body (mb, target_klass, method, sig, callsig, virtual, need_direct_wrapper); +#endif if (need_direct_wrapper) { +#ifndef DISABLE_JIT mb->skip_visibility = 1; +#endif res = mono_mb_create_and_cache (cache, method, mb, csig, sig->param_count + 16); info = mono_wrapper_info_create (res, virtual ? WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL : WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT); info->d.runtime_invoke.method = method; @@ -4725,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); } @@ -4780,6 +5008,7 @@ mono_marshal_get_runtime_invoke_dynamic (void) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_RUNTIME_INVOKE); g_free (name); +#ifndef DISABLE_JIT /* allocate local 0 (object) tmp */ mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); /* allocate local 1 (object) exc */ @@ -4849,6 +5078,7 @@ mono_marshal_get_runtime_invoke_dynamic (void) mono_mb_patch_branch (mb, pos); //mono_mb_emit_ldloc (mb, 0); mono_mb_emit_byte (mb, CEE_RET); +#endif /* DISABLE_JIT */ mono_loader_lock (); /* double-checked locking */ @@ -4864,6 +5094,7 @@ mono_marshal_get_runtime_invoke_dynamic (void) return method; } +#ifndef DISABLE_JIT static void mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass) { @@ -4872,7 +5103,9 @@ mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass) mono_mb_emit_exception_marshal_directive (mb, msg); } +#endif +#ifndef DISABLE_REMOTING /* * mono_marshal_get_ldfld_remote_wrapper: * @klass: The return type @@ -4907,6 +5140,7 @@ mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass) sig->params [2] = &mono_defaults.int_class->byval_arg; sig->ret = &mono_defaults.object_class->byval_arg; +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldarg (mb, 1); mono_mb_emit_ldarg (mb, 2); @@ -4922,7 +5156,8 @@ mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass) emit_thread_interrupt_checkpoint (mb); mono_mb_emit_byte (mb, CEE_RET); - +#endif + mono_marshal_lock (); res = cached; mono_marshal_unlock (); @@ -5005,6 +5240,7 @@ mono_marshal_get_ldfld_wrapper (MonoType *type) sig->params [3] = &mono_defaults.int_class->byval_arg; sig->ret = &klass->byval_arg; +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); pos0 = mono_mb_emit_proxy_check (mb, CEE_BNE_UN); @@ -5086,7 +5322,8 @@ mono_marshal_get_ldfld_wrapper (MonoType *type) } mono_mb_emit_byte (mb, CEE_RET); - +#endif /* DISABLE_JIT */ + res = mono_mb_create_and_cache (cache, klass, mb, sig, sig->param_count + 16); mono_mb_free (mb); @@ -5154,6 +5391,7 @@ mono_marshal_get_ldflda_wrapper (MonoType *type) sig->params [3] = &mono_defaults.int_class->byval_arg; sig->ret = &mono_defaults.int_class->byval_arg; +#ifndef DISABLE_JIT /* if typeof (this) != transparent_proxy goto pos0 */ mono_mb_emit_ldarg (mb, 0); pos0 = mono_mb_emit_proxy_check (mb, CEE_BNE_UN); @@ -5207,7 +5445,8 @@ mono_marshal_get_ldflda_wrapper (MonoType *type) mono_mb_emit_byte (mb, CEE_ADD); mono_mb_emit_byte (mb, CEE_RET); - +#endif + res = mono_mb_create_and_cache (cache, klass, mb, sig, sig->param_count + 16); mono_mb_free (mb); @@ -5250,6 +5489,7 @@ mono_marshal_get_stfld_remote_wrapper (MonoClass *klass) sig->params [3] = &mono_defaults.object_class->byval_arg; sig->ret = &mono_defaults.void_class->byval_arg; +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldarg (mb, 1); mono_mb_emit_ldarg (mb, 2); @@ -5267,7 +5507,8 @@ mono_marshal_get_stfld_remote_wrapper (MonoClass *klass) emit_thread_interrupt_checkpoint (mb); mono_mb_emit_byte (mb, CEE_RET); - +#endif + mono_marshal_lock (); res = cached; mono_marshal_unlock (); @@ -5350,6 +5591,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type) sig->params [4] = &klass->byval_arg; sig->ret = &mono_defaults.void_class->byval_arg; +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); pos = mono_mb_emit_proxy_check (mb, CEE_BNE_UN); @@ -5410,13 +5652,15 @@ mono_marshal_get_stfld_wrapper (MonoType *type) } mono_mb_emit_byte (mb, CEE_RET); - +#endif + res = mono_mb_create_and_cache (cache, klass, mb, sig, sig->param_count + 16); mono_mb_free (mb); return res; } +#endif /* DISABLE_REMOTING */ /* * generates IL code for the icall wrapper (the generated method @@ -5444,16 +5688,20 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon else csig2 = signature_dup (mono_defaults.corlib, sig); +#ifndef DISABLE_JIT if (sig->hasthis) mono_mb_emit_byte (mb, CEE_LDARG_0); 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); +#endif csig = signature_dup (mono_defaults.corlib, sig); csig->pinvoke = 0; @@ -5464,6 +5712,7 @@ 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; @@ -5475,6 +5724,11 @@ emit_marshal_custom (EmitMarshalContext *m, int argnum, MonoType *t, 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; @@ -5768,8 +6022,9 @@ handle_exception: default: g_assert_not_reached (); } - return conv_arg; +#endif + } static int @@ -5778,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) { @@ -5814,7 +6070,7 @@ emit_marshal_asany (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -5824,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; @@ -6097,7 +6354,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -6107,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); @@ -6264,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){ @@ -6423,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){ @@ -6484,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; @@ -6967,10 +7249,14 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } +#ifndef DISABLE_JIT + +#ifndef DISABLE_COM + static int emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, @@ -7086,6 +7372,9 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } +#endif /* DISABLE_COM */ +#endif /* DISABLE_JIT */ + static gboolean mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo) { @@ -7104,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; @@ -7782,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) { @@ -7800,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 @@ -7878,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 @@ -7969,7 +8298,7 @@ emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t, default: g_assert_not_reached (); } - +#endif return conv_arg; } @@ -7978,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) { @@ -8003,7 +8333,7 @@ emit_marshal_ptr (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8012,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) { @@ -8030,7 +8361,7 @@ emit_marshal_char (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8039,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) { @@ -8054,7 +8386,7 @@ emit_marshal_scalar (EmitMarshalContext *m, int argnum, MonoType *t, default: break; } - +#endif return conv_arg; } @@ -8082,10 +8414,10 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, return emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action); case MONO_TYPE_CLASS: case MONO_TYPE_OBJECT: +#ifndef DISABLE_COM if (spec && spec->native == MONO_NATIVE_STRUCT) return emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action); -#ifndef DISABLE_COM if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || spec->native == MONO_NATIVE_IDISPATCH || spec->native == MONO_NATIVE_INTERFACE)) @@ -8130,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 @@ -8353,6 +8685,8 @@ 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) { @@ -8442,11 +8776,13 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, /* create a wrapper to preserve .ctor in stack trace */ mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED); +#ifndef DISABLE_JIT mono_mb_emit_byte (mb, CEE_LDARG_0); for (i = 1; i <= csig->param_count; i++) mono_mb_emit_ldarg (mb, i); mono_mb_emit_managed_call (mb, res, NULL); mono_mb_emit_byte (mb, CEE_RET); +#endif /* use native_wrapper_cache because internal calls are looked up there */ res = mono_mb_create_and_cache (cache, method, @@ -8477,12 +8813,19 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, * 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; } @@ -8497,6 +8840,7 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, if (method->string_ctor) csig->ret = &mono_defaults.string_class->byval_arg; +#ifndef DISABLE_JIT if (sig->hasthis) { int pos; @@ -8526,6 +8870,7 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, if (check_exceptions) emit_thread_interrupt_checkpoint (mb); mono_mb_emit_byte (mb, CEE_RET); +#endif csig = signature_dup (method->klass->image, csig); csig->pinvoke = 0; @@ -8544,10 +8889,12 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, if (!aot) g_assert (piinfo->addr); +#ifndef DISABLE_JIT mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1); mono_method_get_marshal_info (method, mspecs); mono_marshal_emit_native_wrapper (mb->method->klass->image, mb, sig, piinfo, mspecs, piinfo->addr, aot, check_exceptions, FALSE); +#endif csig = signature_dup (method->klass->image, sig); csig->pinvoke = 0; @@ -8559,10 +8906,12 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, info->d.managed_to_native.method = method; mono_marshal_set_wrapper_info (res, info); +#ifndef DISABLE_JIT for (i = sig->param_count; i >= 0; i--) if (mspecs [i]) mono_metadata_free_marshal_spec (mspecs [i]); g_free (mspecs); +#endif /* code_for (res); */ @@ -8597,7 +8946,9 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE); mb->method->save_lmf = 1; +#ifndef DISABLE_JIT mono_marshal_emit_native_wrapper (image, mb, sig, piinfo, mspecs, func, FALSE, TRUE, FALSE); +#endif csig = signature_dup (image, sig); csig->pinvoke = 0; @@ -8652,7 +9003,9 @@ mono_marshal_get_native_func_wrapper_aot (MonoClass *klass) mb = mono_mb_new (invoke->klass, name, MONO_WRAPPER_MANAGED_TO_NATIVE); mb->method->save_lmf = 1; +#ifndef DISABLE_JIT mono_marshal_emit_native_wrapper (image, mb, sig, piinfo, mspecs, NULL, FALSE, TRUE, TRUE); +#endif g_assert (!sig->hasthis); csig = signature_dup_add_this (image, sig, mono_defaults.int_class); @@ -8674,7 +9027,7 @@ mono_marshal_get_native_func_wrapper_aot (MonoClass *klass) return res; } - + /* * mono_marshal_emit_managed_wrapper: * @@ -8686,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; @@ -8867,9 +9243,9 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i if (closed) g_free (sig); +#endif } - static void mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *csig) { @@ -9055,7 +9431,9 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, info->d.native_to_managed.klass = delegate_klass; mono_marshal_set_wrapper_info (res, info); } else { +#ifndef DISABLE_JIT mb->dynamic = 1; +#endif res = mono_mb_create_method (mb, csig, sig->param_count + 16); } mono_mb_free (mb); @@ -9112,7 +9490,9 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) 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); mono_mb_free (mb); @@ -9127,6 +9507,7 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) sig = mono_method_signature (method); mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED); +#ifndef DISABLE_JIT param_count = sig->param_count + sig->hasthis; for (i = 0; i < param_count; i++) mono_mb_emit_ldarg (mb, i); @@ -9138,6 +9519,8 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) mono_mb_emit_byte (mb, CEE_RET); mb->dynamic = 1; +#endif + method = mono_mb_create_method (mb, sig, param_count); mono_mb_free (mb); @@ -9181,6 +9564,7 @@ mono_marshal_get_castclass_with_cache (void) sig->ret = &mono_defaults.object_class->byval_arg; sig->pinvoke = 0; +#ifndef DISABLE_JIT /* allocate local 0 (pointer) obj_vtable */ mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); @@ -9230,6 +9614,7 @@ mono_marshal_get_castclass_with_cache (void) mono_mb_patch_branch (mb, return_null_pos); mono_mb_emit_byte (mb, CEE_LDNULL); mono_mb_emit_byte (mb, CEE_RET); +#endif /* DISABLE_JIT */ res = mono_mb_create_method (mb, sig, 8); info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_CASTCLASS_WITH_CACHE); @@ -9270,6 +9655,7 @@ mono_marshal_get_isinst_with_cache (void) sig->ret = &mono_defaults.object_class->byval_arg; sig->pinvoke = 0; +#ifndef DISABLE_JIT /* allocate local 0 (pointer) obj_vtable */ mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); /* allocate local 1 (pointer) cached_vtable */ @@ -9350,6 +9736,7 @@ mono_marshal_get_isinst_with_cache (void) mono_mb_patch_branch (mb, return_null_pos); mono_mb_emit_byte (mb, CEE_LDNULL); mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_method (mb, sig, 8); info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_ISINST_WITH_CACHE); @@ -9401,16 +9788,17 @@ mono_marshal_get_isinst (MonoClass *klass) mb->method->save_lmf = 1; +#ifndef DISABLE_JIT /* check if the object is a proxy that needs special cast */ mono_mb_emit_ldarg (mb, 0); mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); mono_mb_emit_op (mb, CEE_MONO_CISINST, klass); - /* The result of MONO_ISINST can be: + /* The result of MONO_CISINST can be: 0) the type check succeeded 1) the type check did not succeed 2) a CanCastTo call is needed */ - +#ifndef DISABLE_REMOTING mono_mb_emit_byte (mb, CEE_DUP); pos_was_ok = mono_mb_emit_branch (mb, CEE_BRFALSE); @@ -9440,6 +9828,25 @@ mono_marshal_get_isinst (MonoClass *klass) mono_mb_patch_branch (mb, pos_end); mono_mb_patch_branch (mb, pos_end2); mono_mb_emit_byte (mb, CEE_RET); +#else + pos_was_ok = mono_mb_emit_branch (mb, CEE_BRFALSE); + + /* fail */ + + mono_mb_emit_byte (mb, CEE_LDNULL); + pos_end = mono_mb_emit_branch (mb, CEE_BR); + + /* success */ + + mono_mb_patch_branch (mb, pos_was_ok); + mono_mb_emit_ldarg (mb, 0); + + /* the end */ + + mono_mb_patch_branch (mb, pos_end); + mono_mb_emit_byte (mb, CEE_RET); +#endif /* DISABLE_REMOTING */ +#endif /* DISABLE_JIT */ res = mono_mb_create_and_cache (cache, klass, mb, isint_sig, isint_sig->param_count + 16); mono_mb_free (mb); @@ -9485,17 +9892,18 @@ mono_marshal_get_castclass (MonoClass *klass) mb->method->save_lmf = 1; +#ifndef DISABLE_JIT /* check if the object is a proxy that needs special cast */ mono_mb_emit_ldarg (mb, 0); mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); mono_mb_emit_op (mb, CEE_MONO_CCASTCLASS, klass); - /* The result of MONO_ISINST can be: + /* The result of MONO_CCASTCLASS can be: 0) the cast is valid 1) cast of unknown proxy type or an exception if the cast is is invalid */ - +#ifndef DISABLE_REMOTING pos_was_ok = mono_mb_emit_branch (mb, CEE_BRFALSE); /* get the real proxy from the transparent proxy*/ @@ -9510,10 +9918,16 @@ mono_marshal_get_castclass (MonoClass *klass) /* success */ mono_mb_patch_branch (mb, pos_was_ok); mono_mb_patch_branch (mb, pos_was_ok2); +#else + /* MONO_CCASTCLASS leaves an int in the stack with the result, pop it. */ + mono_mb_emit_byte (mb, CEE_POP); +#endif /* DISABLE_REMOTING */ + mono_mb_emit_ldarg (mb, 0); /* the end */ mono_mb_emit_byte (mb, CEE_RET); +#endif /* DISABLE_JIT */ res = mono_mb_create_and_cache (cache, klass, mb, castclass_sig, castclass_sig->param_count + 16); mono_mb_free (mb); @@ -9524,6 +9938,7 @@ mono_marshal_get_castclass (MonoClass *klass) return res; } +#ifndef DISABLE_REMOTING MonoMethod * mono_marshal_get_proxy_cancast (MonoClass *klass) { @@ -9555,6 +9970,7 @@ mono_marshal_get_proxy_cancast (MonoClass *klass) mb->method->save_lmf = 1; +#ifndef DISABLE_JIT /* get the real proxy from the transparent proxy*/ mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoTransparentProxy, rp)); @@ -9595,6 +10011,7 @@ mono_marshal_get_proxy_cancast (MonoClass *klass) mono_mb_patch_branch (mb, pos_end); mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_and_cache (cache, klass, mb, isint_sig, isint_sig->param_count + 16); mono_mb_free (mb); @@ -9610,6 +10027,7 @@ mono_upgrade_remote_class_wrapper (MonoReflectionType *rtype, MonoTransparentPro klass = mono_class_from_mono_type (rtype->type); mono_upgrade_remote_class (domain, (MonoObject*)tproxy, klass); } +#endif /*DISABLE_REMOTING */ /** * mono_marshal_get_struct_to_ptr: @@ -9639,6 +10057,7 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass) mb = mono_mb_new (klass, stoptr->name, MONO_WRAPPER_UNKNOWN); +#ifndef DISABLE_JIT if (klass->blittable) { mono_mb_emit_byte (mb, CEE_LDARG_1); mono_mb_emit_byte (mb, CEE_LDARG_0); @@ -9670,6 +10089,7 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass) } mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_method (mb, mono_signature_no_pinvoke (stoptr), 0); mono_mb_free (mb); @@ -9718,6 +10138,7 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass) mb = mono_mb_new (klass, "PtrToStructure", MONO_WRAPPER_UNKNOWN); +#ifndef DISABLE_JIT if (klass->blittable) { mono_mb_emit_byte (mb, CEE_LDARG_1); mono_mb_emit_ldflda (mb, sizeof (MonoObject)); @@ -9745,6 +10166,7 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass) } mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_method (mb, ptostr, 0); mono_mb_free (mb); @@ -9772,8 +10194,10 @@ mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method) MonoMethod *res; mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNKNOWN); +#ifndef DISABLE_JIT mono_mb_emit_exception_full (mb, "System", "ExecutionEngineException", "Shouldn't be called."); mono_mb_emit_byte (mb, CEE_RET); +#endif sig = signature_dup (method->klass->image, mono_method_signature (method)); res = mono_mb_create_method (mb, sig, 0); mono_mb_free (mb); @@ -9812,12 +10236,15 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_SYNCHRONIZED); +#ifndef DISABLE_JIT /* result */ if (!MONO_TYPE_IS_VOID (sig->ret)) ret_local = mono_mb_add_local (mb, sig->ret); +#endif if (method->klass->valuetype && !(method->flags & MONO_METHOD_ATTR_STATIC)) { mono_class_set_failure (method->klass, MONO_EXCEPTION_TYPE_LOAD, NULL); +#ifndef DISABLE_JIT /* This will throw the type load exception when the wrapper is compiled */ mono_mb_emit_byte (mb, CEE_LDNULL); mono_mb_emit_op (mb, CEE_ISINST, method->klass); @@ -9826,6 +10253,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) if (!MONO_TYPE_IS_VOID (sig->ret)) mono_mb_emit_ldloc (mb, ret_local); mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16); @@ -9834,11 +10262,13 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) return res; } +#ifndef DISABLE_JIT /* this */ this_local = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); clause = mono_image_alloc0 (method->klass->image, sizeof (MonoExceptionClause)); clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY; +#endif mono_loader_lock (); @@ -9863,6 +10293,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) mono_loader_unlock (); +#ifndef DISABLE_JIT /* Push this or the type object */ if (method->flags & METHOD_ATTRIBUTE_STATIC) { /* We have special handling for this in the JIT */ @@ -9912,6 +10343,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) mono_mb_emit_byte (mb, CEE_RET); mono_mb_set_clauses (mb, 1, clause); +#endif res = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16); @@ -9941,6 +10373,7 @@ mono_marshal_get_unbox_wrapper (MonoMethod *method) g_assert (sig->hasthis); +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); mono_mb_emit_icon (mb, sizeof (MonoObject)); mono_mb_emit_byte (mb, CEE_ADD); @@ -9948,6 +10381,7 @@ mono_marshal_get_unbox_wrapper (MonoMethod *method) mono_mb_emit_ldarg (mb, i + 1); mono_mb_emit_managed_call (mb, method, NULL); mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16); @@ -9997,13 +10431,15 @@ get_virtual_stelemref_kind (MonoClass *element_class) return STELEMREF_INTERFACE; #endif /*Arrays are sealed but are covariant on their element type, We can't use any of the fast paths.*/ - if (element_class->marshalbyref || element_class->rank || mono_class_has_variant_generic_params (element_class)) + if (mono_class_is_marshalbyref (element_class) || element_class->rank || mono_class_has_variant_generic_params (element_class)) return STELEMREF_COMPLEX; if (element_class->flags & TYPE_ATTRIBUTE_SEALED) return STELEMREF_SEALED_CLASS; return STELEMREF_CLASS; } +#ifndef DISABLE_JIT + static void load_array_element_address (MonoMethodBuilder *mb) { @@ -10035,6 +10471,7 @@ load_value_class (MonoMethodBuilder *mb, int vklass) mono_mb_emit_byte (mb, CEE_LDIND_I); mono_mb_emit_stloc (mb, vklass); } +#endif #if 0 static void @@ -10055,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; @@ -10070,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]; @@ -10080,10 +10513,6 @@ mono_marshal_get_virtual_stelemref (MonoClass *array_class) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_STELEMREF); g_free (name); - param_names [0] = "index"; - param_names [1] = "value"; - mono_mb_set_param_names (mb, param_names); - if (!signature) { MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_defaults.corlib, 2); @@ -10095,6 +10524,11 @@ mono_marshal_get_virtual_stelemref (MonoClass *array_class) signature = sig; } +#ifndef DISABLE_JIT + param_names [0] = "index"; + param_names [1] = "value"; + mono_mb_set_param_names (mb, param_names); + /*For now simply call plain old stelemref*/ switch (kind) { case STELEMREF_OBJECT: @@ -10417,6 +10851,7 @@ mono_marshal_get_virtual_stelemref (MonoClass *array_class) mono_mb_emit_byte (mb, CEE_RET); g_assert (0); } +#endif /* DISABLE_JIT */ res = mono_mb_create_method (mb, signature, 4); res->flags |= METHOD_ATTRIBUTE_VIRTUAL; @@ -10438,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. */ @@ -10467,7 +10926,8 @@ mono_marshal_get_stelemref () sig->params [0] = &mono_defaults.object_class->byval_arg; sig->params [1] = &mono_defaults.int_class->byval_arg; /* this is a natural sized int */ sig->params [2] = &mono_defaults.object_class->byval_arg; - + +#ifndef DISABLE_JIT aklass = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); vklass = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); array_slot_addr = mono_mb_add_local (mb, &mono_defaults.object_class->this_arg); @@ -10578,6 +11038,8 @@ mono_marshal_get_stelemref () mono_mb_emit_exception (mb, "ArrayTypeMismatchException", NULL); mono_mb_emit_byte (mb, CEE_RET); +#endif + ret = mono_mb_create_method (mb, sig, 4); mono_mb_free (mb); @@ -10587,6 +11049,84 @@ mono_marshal_get_stelemref () return ret; } +/* + * mono_marshal_get_gsharedvt_in_wrapper: + * + * This wrapper handles calls from normal code to gsharedvt code. + * + * The wrapper info for the wrapper is a WrapperInfo structure. + */ +MonoMethod* +mono_marshal_get_gsharedvt_in_wrapper (void) +{ + static MonoMethod* ret = NULL; + MonoMethodSignature *sig; + MonoMethodBuilder *mb; + WrapperInfo *info; + + if (ret) + return ret; + + mb = mono_mb_new (mono_defaults.object_class, "gsharedvt_in", MONO_WRAPPER_UNKNOWN); + + sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0); + sig->ret = &mono_defaults.void_class->byval_arg; + +#ifndef DISABLE_JIT + /* + * The body is generated by the JIT, we use a wrapper instead of a trampoline so EH works. + */ + mono_mb_emit_byte (mb, CEE_RET); +#endif + + ret = mono_mb_create_method (mb, sig, 4); + mono_mb_free (mb); + + info = mono_wrapper_info_create (ret, WRAPPER_SUBTYPE_GSHAREDVT_IN); + mono_marshal_set_wrapper_info (ret, info); + + return ret; +} + +/* + * mono_marshal_get_gsharedvt_out_wrapper: + * + * This wrapper handles calls from gsharedvt code to normal code. + * + * The wrapper info for the wrapper is a WrapperInfo structure. + */ +MonoMethod* +mono_marshal_get_gsharedvt_out_wrapper (void) +{ + static MonoMethod* ret = NULL; + MonoMethodSignature *sig; + MonoMethodBuilder *mb; + WrapperInfo *info; + + if (ret) + return ret; + + mb = mono_mb_new (mono_defaults.object_class, "gsharedvt_out", MONO_WRAPPER_UNKNOWN); + + sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0); + sig->ret = &mono_defaults.void_class->byval_arg; + +#ifndef DISABLE_JIT + /* + * The body is generated by the JIT, we use a wrapper instead of a trampoline so EH works. + */ + mono_mb_emit_byte (mb, CEE_RET); +#endif + + ret = mono_mb_create_method (mb, sig, 4); + mono_mb_free (mb); + + info = mono_wrapper_info_create (ret, WRAPPER_SUBTYPE_GSHAREDVT_OUT); + mono_marshal_set_wrapper_info (ret, info); + + return ret; +} + typedef struct { int rank; int elem_size; @@ -10643,6 +11183,7 @@ mono_marshal_get_array_address (int rank, int elem_size) mb = mono_mb_new (mono_defaults.object_class, "ElementAddr", MONO_WRAPPER_MANAGED_TO_MANAGED); +#ifndef DISABLE_JIT bounds = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); ind = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg); realidx = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg); @@ -10722,6 +11263,8 @@ mono_marshal_get_array_address (int rank, int elem_size) mono_mb_emit_exception (mb, "IndexOutOfRangeException", NULL); g_free (branch_positions); +#endif /* DISABLE_JIT */ + ret = mono_mb_create_method (mb, sig, 4); mono_mb_free (mb); @@ -11999,6 +12542,7 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar csig = signature_dup (method->klass->image, sig); csig->generic_param_count = 0; +#ifndef DISABLE_JIT mono_mb_emit_ldarg (mb, 0); for (i = 0; i < csig->param_count; i++) mono_mb_emit_ldarg (mb, i + 1); @@ -12007,6 +12551,7 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar /* We can corlib internal methods */ mb->skip_visibility = TRUE; +#endif res = mono_mb_create_method (mb, csig, csig->param_count + 16); @@ -12133,6 +12678,7 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method) if (MONO_TYPE_ISSTRUCT (sig->ret)) csig->ret = &mono_defaults.object_class->byval_arg; +#ifndef DISABLE_JIT /* local 0 (temp for exception object) */ mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg); @@ -12215,6 +12761,7 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method) } mono_mb_emit_byte (mb, CEE_RET); +#endif res = mono_mb_create_and_cache (cache, method, mb, csig, param_count + 16); mono_mb_free (mb); @@ -12252,12 +12799,6 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) mono_marshal_unlock (); } -/* - * mono_marshal_free_inflated_wrappers: - * - * Free wrappers of the inflated method METHOD. - */ - static gboolean signature_method_pair_matches_signature (gpointer key, gpointer value, gpointer user_data) { @@ -12267,6 +12808,11 @@ signature_method_pair_matches_signature (gpointer key, gpointer value, gpointer return mono_metadata_signature_equal (pair->sig, sig); } +/* + * mono_marshal_free_inflated_wrappers: + * + * Free wrappers of the inflated method METHOD. + */ void mono_marshal_free_inflated_wrappers (MonoMethod *method) {