mono_mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", s);
}
+#endif /* !DISABLE_JIT */
+
guint
mono_type_to_ldind (MonoType *type)
{
return -1;
}
+#ifndef DISABLE_JIT
+
static void
emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec)
{
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)
{
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
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;
}
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 ();
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
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;
/* 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);
}
}
* 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)
#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);
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);
}
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);
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;
default:
g_assert_not_reached ();
}
-
return conv_arg;
+#endif
+
}
static int
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
+#ifndef DISABLE_JIT
MonoMethodBuilder *mb = m->mb;
switch (action) {
default:
g_assert_not_reached ();
}
-
+#endif
return conv_arg;
}
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;
default:
g_assert_not_reached ();
}
-
+#endif
return conv_arg;
}
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);
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){
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){
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;
default:
g_assert_not_reached ();
}
-
+#endif
return conv_arg;
}
+#ifndef DISABLE_JIT
#ifndef DISABLE_COM
}
#endif /* DISABLE_COM */
+#endif /* DISABLE_JIT */
static gboolean
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;
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) {
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
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
default:
g_assert_not_reached ();
}
-
+#endif
return conv_arg;
}
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
+#ifndef DISABLE_JIT
MonoMethodBuilder *mb = m->mb;
switch (action) {
default:
break;
}
-
+#endif
return conv_arg;
}
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
+#ifndef DISABLE_JIT
MonoMethodBuilder *mb = m->mb;
switch (action) {
default:
break;
}
-
+#endif
return conv_arg;
}
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
+#ifndef DISABLE_JIT
MonoMethodBuilder *mb = m->mb;
switch (action) {
default:
break;
}
-
+#endif
return conv_arg;
}
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
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);
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)) {
return res;
}
-#ifndef DISABLE_JIT
/*
* mono_marshal_emit_managed_wrapper:
*
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;
if (closed)
g_free (sig);
+#endif
}
-#endif /* DISABLE_JIT */
static void
mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *csig)
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;
/* 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);
* - 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;
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];
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.
*/