static MonoFtnPtrEHCallback ftnptr_eh_callback = ftnptr_eh_callback_default;
static void
-delegate_hash_table_add (MonoDelegate *d);
+delegate_hash_table_add (MonoDelegateHandle d);
static void
delegate_hash_table_remove (MonoDelegate *d);
gpointer
mono_delegate_to_ftnptr (MonoDelegate *delegate);
+gpointer
+mono_delegate_handle_to_ftnptr (MonoDelegateHandle delegate, MonoError *error);
+
MonoDelegate*
mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn);
+MonoDelegateHandle
+mono_ftnptr_to_delegate_handle (MonoClass *klass, gpointer ftn, MonoError *error);
+
gpointer
mono_array_to_savearray (MonoArray *array);
static void
mono_icall_end (MonoThreadInfo *info, HandleStackMark *stackmark, MonoError *error);
+static MonoObjectHandle
+mono_icall_handle_new (gpointer rawobj);
+
+static MonoObjectHandle
+mono_icall_handle_new_interior (gpointer rawobj);
+
/* Lazy class loading functions */
static GENERATE_GET_CLASS_WITH_CACHE (string_builder, "System.Text", "StringBuilder");
static GENERATE_GET_CLASS_WITH_CACHE (date_time, "System", "DateTime");
static MonoObject*
mono_object_isinst_icall (MonoObject *obj, MonoClass *klass)
{
+ if (!klass)
+ return NULL;
+
+ /* This is called from stelemref so it is expected to succeed */
+ /* Fastpath */
+ if (mono_class_is_interface (klass)) {
+ MonoVTable *vt = obj->vtable;
+
+ if (!klass->inited)
+ mono_class_init (klass);
+
+ if (MONO_VTABLE_IMPLEMENTS_INTERFACE (vt, klass->interface_id))
+ return obj;
+ }
+
MonoError error;
MonoObject *result = mono_object_isinst_checked (obj, klass, &error);
mono_error_set_pending_exception (&error);
register_icall (mono_marshal_free_asany, "mono_marshal_free_asany", "void object ptr int32 int32", FALSE);
register_icall (ves_icall_marshal_alloc, "ves_icall_marshal_alloc", "ptr ptr", FALSE);
register_icall (mono_marshal_free, "mono_marshal_free", "void ptr", FALSE);
- register_icall (mono_marshal_set_last_error, "mono_marshal_set_last_error", "void", FALSE);
- register_icall (mono_marshal_set_last_error_windows, "mono_marshal_set_last_error_windows", "void int32", FALSE);
+ register_icall (mono_marshal_set_last_error, "mono_marshal_set_last_error", "void", TRUE);
+ register_icall (mono_marshal_set_last_error_windows, "mono_marshal_set_last_error_windows", "void int32", TRUE);
register_icall (mono_string_utf8_to_builder, "mono_string_utf8_to_builder", "void ptr ptr", FALSE);
register_icall (mono_string_utf8_to_builder2, "mono_string_utf8_to_builder2", "object ptr", FALSE);
register_icall (mono_string_utf16_to_builder, "mono_string_utf16_to_builder", "void ptr ptr", FALSE);
register_icall (mono_threads_detach_coop, "mono_threads_detach_coop", "void ptr ptr", TRUE);
register_icall (mono_icall_start, "mono_icall_start", "ptr ptr ptr", TRUE);
register_icall (mono_icall_end, "mono_icall_end", "void ptr ptr ptr", TRUE);
- register_icall (mono_handle_new_full, "mono_handle_new_full", "ptr ptr bool", TRUE);
+ register_icall (mono_icall_handle_new, "mono_icall_handle_new", "ptr ptr", TRUE);
+ register_icall (mono_icall_handle_new_interior, "mono_icall_handle_new_interior", "ptr ptr", TRUE);
mono_cominterop_init ();
mono_remoting_init ();
/* This is a JIT icall, it sets the pending exception and return NULL on error */
gpointer
-mono_delegate_to_ftnptr (MonoDelegate *delegate)
+mono_delegate_to_ftnptr (MonoDelegate *delegate_raw)
{
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
+ MONO_HANDLE_DCL (MonoDelegate, delegate);
+ gpointer result = mono_delegate_handle_to_ftnptr (delegate, &error);
+ mono_error_set_pending_exception (&error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
+
+gpointer
+mono_delegate_handle_to_ftnptr (MonoDelegateHandle delegate, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ gpointer result = NULL;
+ error_init (error);
MonoMethod *method, *wrapper;
MonoClass *klass;
uint32_t target_handle = 0;
- if (!delegate)
- return NULL;
+ if (MONO_HANDLE_IS_NULL (delegate))
+ goto leave;
- if (delegate->delegate_trampoline)
- return delegate->delegate_trampoline;
+ if (MONO_HANDLE_GETVAL (delegate, delegate_trampoline)) {
+ result = MONO_HANDLE_GETVAL (delegate, delegate_trampoline);
+ goto leave;
+ }
- klass = ((MonoObject *)delegate)->vtable->klass;
+ klass = mono_handle_class (delegate);
g_assert (klass->delegate);
- method = delegate->method;
- if (delegate->method_is_virtual)
- method = mono_object_get_virtual_method (delegate->target, method);
+ method = MONO_HANDLE_GETVAL (delegate, method);
+ if (MONO_HANDLE_GETVAL (delegate, method_is_virtual)) {
+ MonoObjectHandle delegate_target = MONO_HANDLE_NEW_GET (MonoObject, delegate, target);
+ method = mono_object_handle_get_virtual_method (delegate_target, method, error);
+ if (!is_ok (error))
+ goto leave;
+ }
if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
const char *exc_class, *exc_arg;
ftnptr = mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
if (!ftnptr) {
g_assert (exc_class);
- mono_set_pending_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
- return NULL;
+ mono_error_set_generic_error (error, "System", exc_class, "%s", exc_arg);
+ goto leave;
}
- return ftnptr;
+ result = ftnptr;
+ goto leave;
}
- if (delegate->target) {
+ MonoObjectHandle delegate_target = MONO_HANDLE_NEW_GET (MonoObject, delegate, target);
+ if (!MONO_HANDLE_IS_NULL (delegate_target)) {
/* Produce a location which can be embedded in JITted code */
- target_handle = mono_gchandle_new_weakref (delegate->target, FALSE);
+ target_handle = mono_gchandle_new_weakref (MONO_HANDLE_RAW (delegate_target), FALSE); /* FIXME: a version of mono_gchandle_new_weakref that takes a coop handle */
}
- wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle, &error);
- if (!is_ok (&error))
- goto fail;
+ wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle, error);
+ if (!is_ok (error))
+ goto leave;
- delegate->delegate_trampoline = mono_compile_method_checked (wrapper, &error);
- if (!is_ok (&error))
- goto fail;
+ MONO_HANDLE_SETVAL (delegate, delegate_trampoline, gpointer, mono_compile_method_checked (wrapper, error));
+ if (!is_ok (error))
+ goto leave;
// Add the delegate to the delegate hash table
delegate_hash_table_add (delegate);
/* when the object is collected, collect the dynamic method, too */
- mono_object_register_finalizer ((MonoObject*)delegate);
+ mono_object_register_finalizer ((MonoObject*) MONO_HANDLE_RAW (delegate));
- return delegate->delegate_trampoline;
+ result = MONO_HANDLE_GETVAL (delegate, delegate_trampoline);
-fail:
- if (target_handle != 0)
+leave:
+ if (!is_ok (error) && target_handle != 0)
mono_gchandle_free (target_handle);
- mono_error_set_pending_exception (&error);
- return NULL;
+ HANDLE_FUNCTION_RETURN_VAL (result);
}
/*
}
static void
-delegate_hash_table_add (MonoDelegate *d)
+delegate_hash_table_add (MonoDelegateHandle d)
{
guint32 gchandle;
guint32 old_gchandle;
mono_marshal_lock ();
if (delegate_hash_table == NULL)
delegate_hash_table = delegate_hash_table_new ();
+ gpointer delegate_trampoline = MONO_HANDLE_GETVAL (d, delegate_trampoline);
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));
+ gchandle = mono_gchandle_new_weakref ((MonoObject*) MONO_HANDLE_RAW (d), FALSE);
+ old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, delegate_trampoline));
+ g_hash_table_insert (delegate_hash_table, 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);
+ g_hash_table_insert (delegate_hash_table, delegate_trampoline, MONO_HANDLE_RAW (d));
}
mono_marshal_unlock ();
}
MonoDelegate*
mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
{
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
+ MonoDelegateHandle result = mono_ftnptr_to_delegate_handle (klass, ftn, &error);
+ mono_error_set_pending_exception (&error);
+ HANDLE_FUNCTION_RETURN_OBJ (result);
+}
+
+MonoDelegateHandle
+mono_ftnptr_to_delegate_handle (MonoClass *klass, gpointer ftn, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
guint32 gchandle;
- MonoDelegate *d;
+ MonoDelegateHandle d = MONO_HANDLE_NEW (MonoDelegate, NULL);
if (ftn == NULL)
- return NULL;
+ goto leave;
mono_marshal_lock ();
if (delegate_hash_table == NULL)
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;
+ MONO_HANDLE_ASSIGN (d, MONO_HANDLE_CAST (MonoDelegate, mono_gchandle_get_target_handle (gchandle)));
} else {
- d = (MonoDelegate *)g_hash_table_lookup (delegate_hash_table, ftn);
+ MONO_HANDLE_ASSIGN (d, MONO_HANDLE_NEW (MonoDelegate, g_hash_table_lookup (delegate_hash_table, ftn)));
mono_marshal_unlock ();
}
- if (d == NULL) {
+ if (MONO_HANDLE_IS_NULL (d)) {
/* This is a native function, so construct a delegate for it */
MonoMethodSignature *sig;
MonoMethod *wrapper;
MonoMarshalSpec **mspecs;
MonoMethod *invoke = mono_get_delegate_invoke (klass);
MonoMethodPInvoke piinfo;
- MonoObject *this_obj;
+ MonoObjectHandle this_obj;
int i;
if (use_aot_wrappers) {
wrapper = mono_marshal_get_native_func_wrapper_aot (klass);
- this_obj = mono_value_box_checked (mono_domain_get (), mono_defaults.int_class, &ftn, &error);
- if (!is_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
+ this_obj = MONO_HANDLE_NEW (MonoObject, mono_value_box_checked (mono_domain_get (), mono_defaults.int_class, &ftn, error));
+ if (!is_ok (error))
+ goto leave;
} else {
memset (&piinfo, 0, sizeof (piinfo));
parse_unmanaged_function_pointer_attr (klass, &piinfo);
sig->hasthis = 0;
wrapper = mono_marshal_get_native_func_wrapper (klass->image, sig, &piinfo, mspecs, ftn);
- this_obj = NULL;
+ this_obj = MONO_HANDLE_NEW (MonoObject, NULL);
for (i = mono_method_signature (invoke)->param_count; i >= 0; i--)
if (mspecs [i])
g_free (sig);
}
- d = (MonoDelegate*)mono_object_new_checked (mono_domain_get (), klass, &error);
- if (!mono_error_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
- gpointer compiled_ptr = mono_compile_method_checked (wrapper, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
- mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, compiled_ptr, wrapper, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
- }
+ MONO_HANDLE_ASSIGN (d, MONO_HANDLE_NEW (MonoDelegate, mono_object_new_checked (mono_domain_get (), klass, error)));
+ if (!is_ok (error))
+ goto leave;
+ gpointer compiled_ptr = mono_compile_method_checked (wrapper, error);
+ if (!is_ok (error))
+ goto leave;
- if (d->object.vtable->domain != mono_domain_get ()) {
- mono_set_pending_exception (mono_get_exception_not_supported ("Delegates cannot be marshalled from native code into a domain other than their home domain"));
- return NULL;
+ mono_delegate_ctor_with_method (MONO_HANDLE_CAST (MonoObject, d), this_obj, compiled_ptr, wrapper, error);
+ if (!is_ok (error))
+ goto leave;
}
- return d;
+ g_assert (!MONO_HANDLE_IS_NULL (d));
+ if (MONO_HANDLE_DOMAIN (d) != mono_domain_get ())
+ mono_error_set_not_supported (error, "Delegates cannot be marshalled from native code into a domain other than their home domain");
+
+leave:
+ HANDLE_FUNCTION_RETURN_REF (MonoDelegate, d);
}
void
int i = 0;
MonoClass *klass;
+ MonoError error;
#endif
if (!array)
return NULL;
#ifndef DISABLE_COM
-
+ error_init (&error);
klass = array->obj.vtable->klass;
switch (klass->element_class->byval_arg.type) {
break;
case MONO_TYPE_CLASS:
nativeArraySize = array->max_length;
- nativeArray = (void **)malloc(sizeof(gpointer) * nativeArraySize);
- for(i = 0; i < nativeArraySize; ++i)
- nativeArray[i] = ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal(((MonoObject **)array->vector)[i]);
+ nativeArray = (void **)g_malloc (sizeof(gpointer) * nativeArraySize);
+ for(i = 0; i < nativeArraySize; ++i) {
+ nativeArray[i] = mono_cominterop_get_com_interface (((MonoObject **)array->vector)[i], klass->element_class, &error);
+ if (mono_error_set_pending_exception (&error))
+ break;
+ }
return nativeArray;
case MONO_TYPE_U1:
case MONO_TYPE_BOOLEAN:
{
#ifndef DISABLE_COM
MonoClass *klass;
- int i = 0;
if (!array)
return;
return;
klass = array->obj.vtable->klass;
- if (klass->element_class->byval_arg.type == MONO_TYPE_CLASS) {
- for(i = 0; i < array->max_length; ++i)
- mono_marshal_free_ccw (mono_array_get (array, MonoObject*, i));
+ if (klass->element_class->byval_arg.type == MONO_TYPE_CLASS)
g_free (nativeArray);
- }
#endif
}
return result;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/*
* mono_mb_emit_exception_marshal_directive:
}
mono_mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", s);
}
-
-#endif /* !DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
guint
mono_type_to_ldind (MonoType *type)
return -1;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
static void
emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec)
emit_thread_force_interrupt_checkpoint (mb);
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static MonoAsyncResult *
return result;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
int
mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolean save_this)
return params_var;
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
static char*
mono_signature_to_name (MonoMethodSignature *sig, const char *prefix)
mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_BEGIN_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
params_var = mono_mb_emit_save_args (mb, sig, FALSE);
mono_mb_emit_ldarg (mb, 0);
return res;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
void
mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type)
mono_mb_emit_byte (mb, CEE_RET);
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
/**
* mono_marshal_get_delegate_end_invoke:
mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_END_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
params_var = mono_mb_emit_save_args (mb, sig, FALSE);
mono_mb_emit_ldarg (mb, 0);
mb = mono_mb_new (get_wrapper_target_class (method->klass->image), name, MONO_WRAPPER_DELEGATE_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
void_ret = sig->ret->type == MONO_TYPE_VOID && !method->string_ctor;
/* allocate local 0 (object) */
mono_mb_emit_byte (mb, CEE_RET);
mb->skip_visibility = 1;
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
info = mono_wrapper_info_create (mb, subtype);
info->d.delegate_invoke.method = method;
return mono_metadata_signature_equal (sig1, sig2);
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/*
* emit_invoke_call:
/* to make it work with our special string constructors */
if (!string_dummy) {
+ MonoError error;
MONO_GC_REGISTER_ROOT_SINGLE (string_dummy, MONO_ROOT_SOURCE_MARSHAL, "dummy marshal string");
- string_dummy = mono_string_new_wrapper ("dummy");
+ string_dummy = mono_string_new_checked (mono_get_root_domain (), "dummy", &error);
+ mono_error_assert_ok (&error);
}
if (virtual_) {
* its \p method argument.
*/
MonoMethod *
-mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual_)
+mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gboolean need_direct_wrapper)
{
MonoMethodSignature *sig, *csig, *callsig;
MonoMethodBuilder *mb;
static MonoMethodSignature *finalize_signature = NULL;
char *name;
const char *param_names [16];
- gboolean need_direct_wrapper = FALSE;
WrapperInfo *info;
g_assert (method);
finalize_signature->hasthis = 1;
}
- if (virtual_)
- need_direct_wrapper = TRUE;
-
/*
* Use a separate cache indexed by methods to speed things up and to avoid the
* boundless mempool growth caused by the signature_dup stuff below.
if (res)
return res;
- if (method->klass->rank && (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
- (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)) {
- /*
- * Array Get/Set/Address methods. The JIT implements them using inline code
- * so we need to create an invoke wrapper which calls the method directly.
- */
- need_direct_wrapper = TRUE;
- }
-
if (method->string_ctor) {
callsig = lookup_string_ctor_signature (mono_method_signature (method));
if (!callsig)
callsig = add_string_ctor_signature (method);
- /* Can't share this as we push a string as this */
- need_direct_wrapper = TRUE;
} else {
if (method_is_dynamic (method))
callsig = mono_metadata_signature_dup_full (method->klass->image, mono_method_signature (method));
csig->call_convention = MONO_CALL_C;
#endif
- name = mono_signature_to_name (callsig, virtual_ ? "runtime_invoke_virtual" : "runtime_invoke");
+ name = mono_signature_to_name (callsig, virtual_ ? "runtime_invoke_virtual" : (need_direct_wrapper ? "runtime_invoke_direct" : "runtime_invoke"));
mb = mono_mb_new (target_klass, name, MONO_WRAPPER_RUNTIME_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
param_names [0] = "this";
param_names [1] = "params";
param_names [2] = "exc";
#endif
if (need_direct_wrapper) {
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mb->skip_visibility = 1;
#endif
info = mono_wrapper_info_create (mb, virtual_ ? WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL : WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT);
return res;
}
+MonoMethod *
+mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual_)
+{
+ gboolean need_direct_wrapper = FALSE;
+
+ if (virtual_)
+ need_direct_wrapper = TRUE;
+
+ if (method->dynamic)
+ need_direct_wrapper = TRUE;
+
+ if (method->klass->rank && (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
+ (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)) {
+ /*
+ * Array Get/Set/Address methods. The JIT implements them using inline code
+ * so we need to create an invoke wrapper which calls the method directly.
+ */
+ need_direct_wrapper = TRUE;
+ }
+
+ if (method->string_ctor) {
+ /* Can't share this as we push a string as this */
+ need_direct_wrapper = TRUE;
+ }
+
+ return mono_marshal_get_runtime_invoke_full (method, virtual_, need_direct_wrapper);
+}
+
/*
* mono_marshal_get_runtime_invoke_dynamic:
*
mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_RUNTIME_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* allocate local 0 (object) tmp */
mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
/* allocate local 1 (object) exc */
mono_mb_patch_branch (mb, pos);
//mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_RET);
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_RUNTIME_INVOKE_DYNAMIC);
mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_RUNTIME_INVOKE);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
param_names [0] = "this";
param_names [1] = "params";
param_names [2] = "exc";
return res;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
static void
mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass)
{
else
csig2 = mono_metadata_signature_dup_full (mono_defaults.corlib, sig);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
if (sig->hasthis)
mono_mb_emit_byte (mb, CEE_LDARG_0);
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
if (action == MARSHAL_ACTION_CONV_IN && t->type == MONO_TYPE_VALUETYPE)
*conv_arg_type = &mono_defaults.int_class->byval_arg;
return conv_arg;
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
MonoMethodBuilder *mb = m->mb;
switch (action) {
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
MonoMethodBuilder *mb = m->mb;
MonoClass *klass, *date_time_class;
int pos = 0, pos2;
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
switch (action) {
case MARSHAL_ACTION_CONV_IN:
*conv_arg_type = &mono_defaults.int_class->byval_arg;
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
if (action == MARSHAL_ACTION_CONV_IN)
*conv_arg_type = &mono_defaults.int_class->byval_arg;
#else
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
if (action == MARSHAL_ACTION_CONV_IN)
*conv_arg_type = &mono_defaults.int_class->byval_arg;
#else
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
if (action == MARSHAL_ACTION_CONV_IN)
*conv_arg_type = &mono_defaults.int_class->byval_arg;
#else
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
mono_mb_emit_stloc (mb, 3);
- } else if (klass == mono_defaults.stringbuilder_class){
- // FIXME: implement
+ } else if (klass == mono_defaults.stringbuilder_class) {
+ // FIXME:
+ char *msg = g_strdup_printf ("Return marshalling of stringbuilders is not implemented.");
+ mono_mb_emit_exception_marshal_directive (mb, msg);
} else {
/* set src */
mono_mb_emit_stloc (mb, 0);
return conv_arg;
}
-#ifndef DISABLE_JIT
-
+#ifdef ENABLE_ILGEN
#ifndef DISABLE_COM
static int
}
#endif /* DISABLE_COM */
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
static gboolean
mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo)
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
switch (action) {
case MARSHAL_ACTION_CONV_IN:
*conv_arg_type = &mono_defaults.object_class->byval_arg;
int conv_arg, MonoType **conv_arg_type,
MarshalAction action)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
switch (action) {
case MARSHAL_ACTION_CONV_IN:
if (t->byref)
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
MonoMethodBuilder *mb = m->mb;
switch (action) {
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
MonoMethodBuilder *mb = m->mb;
switch (action) {
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action)
{
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
MonoMethodBuilder *mb = m->mb;
switch (action) {
return emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action);
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
-#if !defined(DISABLE_COM) && !defined(DISABLE_JIT)
+#if !defined(DISABLE_COM) && defined(ENABLE_ILGEN)
if (spec && spec->native == MONO_NATIVE_STRUCT)
return emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action);
#endif
/* Wrap the argument in an object handle, pass the handle to the icall,
write the value out from the handle when the icall returns */
ICALL_HANDLES_WRAP_OBJ_INOUT,
+ /* Initialized an object handle to null, pass to the icalls,
+ write the value out from the handle when the icall returns */
+ ICALL_HANDLES_WRAP_OBJ_OUT,
/* Wrap the argument (a valuetype reference) in a handle to pin its enclosing object,
but pass the raw reference to the icall */
ICALL_HANDLES_WRAP_VALUETYPE_REF,
signature_param_uses_handles (MonoMethodSignature *sig, int param)
{
if (MONO_TYPE_IS_REFERENCE (sig->params [param])) {
- return mono_signature_param_is_out (sig, param) ? ICALL_HANDLES_WRAP_OBJ_INOUT : ICALL_HANDLES_WRAP_OBJ;
+ if (mono_signature_param_is_out (sig, param))
+ return ICALL_HANDLES_WRAP_OBJ_OUT;
+ else if (mono_type_is_byref (sig->params [param]))
+ return ICALL_HANDLES_WRAP_OBJ_INOUT;
+ else
+ return ICALL_HANDLES_WRAP_OBJ;
} else if (mono_type_is_byref (sig->params [param]))
return ICALL_HANDLES_WRAP_VALUETYPE_REF;
else
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/**
* mono_marshal_emit_native_wrapper:
* \param image the image to use for looking up custom marshallers
int i, argnum, *tmp_locals;
int type, param_shift = 0;
int coop_gc_stack_dummy, coop_gc_var;
+#ifndef DISABLE_COM
+ int coop_cominterop_fnptr;
+#endif
memset (&m, 0, sizeof (m));
m.mb = mb;
mono_mb_add_local (mb, sig->ret);
}
- if (mono_threads_is_coop_enabled ()) {
+ if (mono_threads_is_blocking_transition_enabled ()) {
/* local 4, dummy local used to get a stack address for suspend funcs */
coop_gc_stack_dummy = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
/* local 5, the local to be used when calling the suspend funcs */
coop_gc_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+#ifndef DISABLE_COM
+ if (!func_param && MONO_CLASS_IS_IMPORT (mb->method->klass)) {
+ coop_cominterop_fnptr = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+ }
+#endif
}
/*
}
// In coop mode need to register blocking state during native call
- if (mono_threads_is_coop_enabled ()) {
+ if (mono_threads_is_blocking_transition_enabled ()) {
// Perform an extra, early lookup of the function address, so any exceptions
// potentially resulting from the lookup occur before entering blocking mode.
if (!func_param && !MONO_CLASS_IS_IMPORT (mb->method->klass) && aot) {
mono_mb_emit_byte (mb, CEE_POP); // Result not needed yet
}
+#ifndef DISABLE_COM
+ if (!func_param && MONO_CLASS_IS_IMPORT (mb->method->klass)) {
+ mono_mb_emit_cominterop_get_function_pointer (mb, &piinfo->method);
+ mono_mb_emit_stloc (mb, coop_cominterop_fnptr);
+ }
+#endif
+
mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
mono_mb_emit_icall (mb, mono_threads_enter_gc_safe_region_unbalanced);
mono_mb_emit_stloc (mb, coop_gc_var);
mono_mb_emit_calli (mb, csig);
} else if (MONO_CLASS_IS_IMPORT (mb->method->klass)) {
#ifndef DISABLE_COM
- mono_mb_emit_cominterop_call (mb, csig, &piinfo->method);
+ if (!mono_threads_is_blocking_transition_enabled ()) {
+ mono_mb_emit_cominterop_call (mb, csig, &piinfo->method);
+ } else {
+ mono_mb_emit_ldloc (mb, coop_cominterop_fnptr);
+ mono_mb_emit_cominterop_call_function_pointer (mb, csig);
+ }
#else
g_assert_not_reached ();
#endif
}
/* Unblock before converting the result, since that can involve calls into the runtime */
- if (mono_threads_is_coop_enabled ()) {
+ if (mono_threads_is_blocking_transition_enabled ()) {
mono_mb_emit_ldloc (mb, coop_gc_var);
mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
mono_mb_emit_byte (mb, CEE_RET);
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
/**
* mono_marshal_get_native_wrapper:
/* 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
+#ifdef ENABLE_ILGEN
mono_mb_emit_byte (mb, CEE_LDARG_0);
for (i = 1; i <= csig->param_count; i++)
mono_mb_emit_ldarg (mb, i);
* registered in the runtime doing the AOT compilation.
*/
if (!piinfo->addr && !aot) {
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_mb_emit_exception (mb, exc_class, exc_arg);
#endif
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
if (method->string_ctor)
csig->ret = &mono_defaults.string_class->byval_arg;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
// FIXME:
MonoClass *handle_stack_mark_class;
MonoClass *error_class;
gboolean uses_handles = FALSE;
gboolean save_handles_to_locals = FALSE;
IcallHandlesLocal *handles_locals = NULL;
- (void) mono_lookup_internal_call_full (method, &uses_handles);
+ (void) mono_lookup_internal_call_full (method, &uses_handles);
/* If it uses handles and MonoError, it had better check exceptions */
g_assert (!uses_handles || check_exceptions);
switch (w) {
case ICALL_HANDLES_WRAP_OBJ:
case ICALL_HANDLES_WRAP_OBJ_INOUT:
+ case ICALL_HANDLES_WRAP_OBJ_OUT:
ret->params [i] = mono_class_get_byref_type (mono_class_from_mono_type(csig->params[i]));
- if (w == ICALL_HANDLES_WRAP_OBJ_INOUT)
+ if (w == ICALL_HANDLES_WRAP_OBJ_OUT || w == ICALL_HANDLES_WRAP_OBJ_INOUT)
save_handles_to_locals = TRUE;
break;
case ICALL_HANDLES_WRAP_NONE:
handles_locals [j].handle = -1;
break;
case ICALL_HANDLES_WRAP_OBJ_INOUT:
+ case ICALL_HANDLES_WRAP_OBJ_OUT:
handles_locals [j].handle = mono_mb_add_local (mb, sig->params [i]);
break;
default:
mono_mb_emit_byte (mb, CEE_LDARG_0);
/* TODO support adding wrappers to non-static struct methods */
g_assert (!mono_class_is_valuetype(mono_method_get_class (method)));
- mono_mb_emit_byte (mb, CEE_LDC_I4_0);
- mono_mb_emit_icall (mb, mono_handle_new_full);
+ mono_mb_emit_icall (mb, mono_icall_handle_new);
}
for (i = 0; i < sig->param_count; i++) {
/* load each argument. references into the managed heap get wrapped in handles */
mono_mb_emit_ldarg (mb, j);
break;
case ICALL_HANDLES_WRAP_OBJ:
- /* argI = mono_handle_new_full (argI_raw, FALSE) */
+ /* argI = mono_handle_new (argI_raw) */
mono_mb_emit_ldarg (mb, j);
- mono_mb_emit_byte (mb, CEE_LDC_I4_0);
- mono_mb_emit_icall (mb, mono_handle_new_full);
+ mono_mb_emit_icall (mb, mono_icall_handle_new);
break;
case ICALL_HANDLES_WRAP_OBJ_INOUT:
- /* handleI = argI = mono_handle_new_full (NULL, FALSE) */
- mono_mb_emit_byte (mb, CEE_LDNULL);
- mono_mb_emit_byte (mb, CEE_LDC_I4_0);
- mono_mb_emit_icall (mb, mono_handle_new_full);
+ case ICALL_HANDLES_WRAP_OBJ_OUT:
+ /* if inout:
+ * handleI = argI = mono_handle_new (*argI_raw)
+ * otherwise:
+ * handleI = argI = mono_handle_new (NULL)
+ */
+ if (handles_locals[j].wrap == ICALL_HANDLES_WRAP_OBJ_INOUT) {
+ mono_mb_emit_ldarg (mb, j);
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ } else
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_icall (mb, mono_icall_handle_new);
/* tmp = argI */
mono_mb_emit_byte (mb, CEE_DUP);
/* handleI = tmp */
mono_mb_emit_stloc (mb, handles_locals[j].handle);
break;
case ICALL_HANDLES_WRAP_VALUETYPE_REF:
- /* (void) mono_handle_new_full (argI, TRUE); argI */
+ /* (void) mono_handle_new (argI); argI */
mono_mb_emit_ldarg (mb, j);
mono_mb_emit_byte (mb, CEE_DUP);
- mono_mb_emit_byte (mb, CEE_LDC_I4_1);
- mono_mb_emit_icall (mb, mono_handle_new_full);
+ mono_mb_emit_icall (mb, mono_icall_handle_new_interior);
mono_mb_emit_byte (mb, CEE_POP);
#if 0
fprintf (stderr, " Method %s.%s.%s has byref valuetype argument %d\n", method->klass->name_space, method->klass->name, method->name, i);
case ICALL_HANDLES_WRAP_VALUETYPE_REF:
break;
case ICALL_HANDLES_WRAP_OBJ_INOUT:
+ case ICALL_HANDLES_WRAP_OBJ_OUT:
/* *argI_raw = MONO_HANDLE_RAW (handleI) */
/* argI_raw */
if (!aot)
g_assert (piinfo->addr);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
mono_method_get_marshal_info (method, mspecs);
info, NULL);
mono_mb_free (mb);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
for (i = sig->param_count; i >= 0; i--)
if (mspecs [i])
mono_metadata_free_marshal_spec (mspecs [i]);
mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
mb->method->save_lmf = 1;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_marshal_emit_native_wrapper (image, mb, sig, piinfo, mspecs, func, FALSE, TRUE, FALSE);
#endif
mb = mono_mb_new (invoke->klass, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
mb->method->save_lmf = 1;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_marshal_emit_native_wrapper (image, mb, sig, piinfo, mspecs, NULL, FALSE, TRUE, TRUE);
#endif
void
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, uint32_t target_handle)
{
-#ifdef DISABLE_JIT
+#ifndef ENABLE_ILGEN
MonoMethodSignature *sig, *csig;
int i;
/* try { */
clause_catch->try_offset = clause_finally->try_offset = mono_mb_get_label (mb);
- if (!mono_threads_is_coop_enabled ()) {
+ if (!mono_threads_is_blocking_transition_enabled ()) {
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_JIT_ATTACH);
} else {
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_LDDOMAIN);
mono_mb_emit_ldloc_addr (mb, attach_dummy_local);
+ /*
+ * This icall is special cased in the JIT so it works in native-to-managed wrappers in unattached threads.
+ * Keep this in sync with the CEE_JIT_ICALL code in the JIT.
+ */
mono_mb_emit_icall (mb, mono_threads_attach_coop);
mono_mb_emit_stloc (mb, attach_cookie_local);
}
clause_finally->try_len = mono_mb_get_label (mb) - clause_finally->try_offset;
clause_finally->handler_offset = mono_mb_get_label (mb);
- if (!mono_threads_is_coop_enabled ()) {
+ if (!mono_threads_is_blocking_transition_enabled ()) {
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_JIT_DETACH);
} else {
mb, csig, sig->param_count + 16,
info, NULL);
} else {
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mb->dynamic = TRUE;
#endif
res = mono_mb_create (mb, csig, sig->param_count + 16, NULL);
mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, 0);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mb->dynamic = TRUE;
#endif
method = mono_mb_create (mb, csig, sig->param_count + 16, NULL);
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_MANAGED);
param_count = sig->param_count + sig->hasthis;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
for (i = 0; i < param_count; i++)
mono_mb_emit_ldarg (mb, i);
return compiled_ptr;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/*
* The code directly following this is the cache hit, value positive branch
mono_mb_emit_icall (mb, mono_marshal_isinst_with_cache);
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
/**
* mono_marshal_get_castclass_with_cache:
sig->ret = &mono_defaults.object_class->byval_arg;
sig->pinvoke = 0;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
generate_check_cache (obj_arg_position, class_arg_position, cache_arg_position,
&return_null_pos, &negative_cache_hit_pos, &positive_cache_hit_pos, mb);
invalid_cast_pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
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 */
+#endif /* ENABLE_ILGEN */
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_CASTCLASS_WITH_CACHE);
res = mono_mb_create (mb, sig, 8, info);
sig->ret = &mono_defaults.object_class->byval_arg;
sig->pinvoke = 0;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
generate_check_cache (obj_arg_position, class_arg_position, cache_arg_position,
&return_null_pos, &negative_cache_hit_pos, &positive_cache_hit_pos, mb);
// Return the object gotten via the slow path.
mb = mono_mb_new (klass, stoptr->name, MONO_WRAPPER_UNKNOWN);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
if (klass->blittable) {
mono_mb_emit_byte (mb, CEE_LDARG_1);
mono_mb_emit_byte (mb, CEE_LDARG_0);
mb = mono_mb_new (klass, "PtrToStructure", MONO_WRAPPER_UNKNOWN);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
if (klass->blittable) {
mono_mb_emit_byte (mb, CEE_LDARG_1);
mono_mb_emit_ldflda (mb, sizeof (MonoObject));
}
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNKNOWN);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_mb_emit_exception_full (mb, "System", "ExecutionEngineException", "Shouldn't be called.");
mono_mb_emit_byte (mb, CEE_RET);
#endif
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
info->d.synchronized.method = method;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mb->skip_visibility = 1;
/* result */
if (!MONO_TYPE_IS_VOID (sig->ret))
if (method->klass->valuetype && !(method->flags & MONO_METHOD_ATTR_STATIC)) {
/* FIXME Is this really the best way to signal an error here? Isn't this called much later after class setup? -AK */
mono_class_set_type_load_failure (method->klass, "");
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* 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);
return res;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* this */
this_local = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
taken_local = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
mono_marshal_unlock ();
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* Push this or the type object */
if (method->flags & METHOD_ATTRIBUTE_STATIC) {
/* We have special handling for this in the JIT */
g_assert (sig->hasthis);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, sizeof (MonoObject));
mono_mb_emit_byte (mb, CEE_ADD);
return STELEMREF_CLASS;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
static void
load_array_element_address (MonoMethodBuilder *mb)
signature = sig;
}
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
param_names [0] = "index";
param_names [1] = "value";
mono_mb_set_param_names (mb, param_names);
mono_mb_emit_byte (mb, CEE_RET);
g_assert (0);
}
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_VIRTUAL_STELEMREF);
info->d.virtual_stelemref.kind = kind;
res = mono_mb_create (mb, signature, 4, info);
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
+#ifdef ENABLE_ILGEN
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);
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
sig->ret = &mono_defaults.void_class->byval_arg;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/*
* The body is generated by the JIT, we use a wrapper instead of a trampoline so EH works.
*/
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
sig->ret = &mono_defaults.void_class->byval_arg;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/*
* The body is generated by the JIT, we use a wrapper instead of a trampoline so EH works.
*/
mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_MANAGED);
g_free (name);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
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);
mono_mb_emit_exception (mb, "IndexOutOfRangeException", NULL);
g_free (branch_positions);
-#endif /* DISABLE_JIT */
+#endif /* ENABLE_ILGEN */
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_ELEMENT_ADDR);
info->d.element_addr.rank = rank;
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNKNOWN);
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* Call the method */
if (sig->hasthis)
mono_mb_emit_ldarg (mb, 0);
void
mono_marshal_set_last_error (void)
{
+ /* This icall is called just after a P/Invoke call before the P/Invoke
+ * wrapper transitions the runtime back to running mode. */
+ MONO_REQ_GC_SAFE_MODE;
#ifdef WIN32
mono_native_tls_set_value (last_error_tls_id, GINT_TO_POINTER (GetLastError ()));
#else
mono_marshal_set_last_error_windows (int error)
{
#ifdef WIN32
+ /* This icall is called just after a P/Invoke call before the P/Invoke
+ * wrapper transitions the runtime back to running mode. */
+ MONO_REQ_GC_SAFE_MODE;
mono_native_tls_set_value (last_error_tls_id, GINT_TO_POINTER (error));
#endif
}
}
guint32
-ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rtype)
+ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionTypeHandle rtype, MonoError *error)
{
MonoClass *klass;
MonoType *type;
guint32 layout;
- MONO_CHECK_ARG_NULL (rtype, 0);
+ error_init (error);
+
+ if (MONO_HANDLE_IS_NULL (rtype)) {
+ mono_error_set_argument_null (error, "type", "");
+ return 0;
+ }
- type = rtype->type;
+ type = MONO_HANDLE_GETVAL (rtype, type);
klass = mono_class_from_mono_type (type);
if (!mono_class_init (klass)) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return 0;
}
if (type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR) {
return sizeof (gpointer);
} else if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
- gchar *msg;
- MonoException *exc;
-
- msg = g_strdup_printf ("Type %s cannot be marshaled as an unmanaged structure.", klass->name);
- exc = mono_get_exception_argument ("t", msg);
- g_free (msg);
- mono_set_pending_exception (exc);
+ mono_error_set_argument (error, "t", "Type %s cannot be marshaled as an unmanaged structure.", klass->name);
return 0;
}
}
int
-ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *type, MonoString *field_name)
+ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionTypeHandle ref_type, MonoStringHandle field_name, MonoError *error)
{
- MonoError error;
- MonoMarshalType *info;
- MonoClass *klass;
- char *fname;
- int match_index = -1;
-
- MONO_CHECK_ARG_NULL (type, 0);
- MONO_CHECK_ARG_NULL (field_name, 0);
-
- fname = mono_string_to_utf8_checked (field_name, &error);
- if (mono_error_set_pending_exception (&error))
+ error_init (error);
+ if (MONO_HANDLE_IS_NULL (ref_type)) {
+ mono_error_set_argument_null (error, "type", "");
return 0;
- klass = mono_class_from_mono_type (type->type);
+ }
+ if (MONO_HANDLE_IS_NULL (field_name)) {
+ mono_error_set_argument_null (error, "fieldName", "");
+ return 0;
+ }
+
+ char *fname = mono_string_handle_to_utf8 (field_name, error);
+ return_val_if_nok (error, 0);
+
+ MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
+ MonoClass *klass = mono_class_from_mono_type (type);
if (!mono_class_init (klass)) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return 0;
}
+ int match_index = -1;
while (klass && match_index == -1) {
MonoClassField* field;
int i = 0;
g_free (fname);
if(match_index == -1) {
- MonoException* exc;
- gchar *tmp;
-
/* Get back original class instance */
- klass = mono_class_from_mono_type (type->type);
+ klass = mono_class_from_mono_type (type);
- tmp = g_strdup_printf ("Field passed in is not a marshaled member of the type %s", klass->name);
- exc = mono_get_exception_argument ("fieldName", tmp);
- g_free (tmp);
-
- mono_set_pending_exception ((MonoException*)exc);
+ mono_error_set_argument (error, "fieldName", "Field passed in is not a marshaled member of the type %s", klass->name);
return 0;
}
- info = mono_marshal_load_type_info (klass);
+ MonoMarshalType *info = mono_marshal_load_type_info (klass);
return info->fields [match_index].offset;
}
return mono_array_addr_with_size_fast (arrayobj, mono_array_element_size (arrayobj->obj.vtable->klass), index);
}
-MonoDelegate*
-ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal (void *ftn, MonoReflectionType *type)
+MonoDelegateHandle
+ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal (void *ftn, MonoReflectionTypeHandle type, MonoError *error)
{
- MonoClass *klass = mono_type_get_class (type->type);
+ error_init (error);
+ MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (type, type));
if (!mono_class_init (klass)) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
- return mono_ftnptr_to_delegate (klass, ftn);
+ return mono_ftnptr_to_delegate_handle (klass, ftn, error);
}
gpointer
-ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateInternal (MonoDelegate *delegate)
+ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateInternal (MonoDelegateHandle delegate, MonoError *error)
{
- return mono_delegate_to_ftnptr (delegate);
+ error_init (error);
+ return mono_delegate_handle_to_ftnptr (delegate, error);
}
/**
layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
- /* The mempool is protected by the loader lock */
info = (MonoMarshalType *)mono_image_alloc0 (klass->image, MONO_SIZEOF_MARSHAL_TYPE + sizeof (MonoMarshalField) * count);
info->num_fields = count;
info->min_align = min_align;
/* Update the class's blittable info, if the layouts don't match */
- if (info->native_size != mono_class_value_size (klass, NULL))
+ if (info->native_size != mono_class_value_size (klass, NULL)) {
+ mono_loader_lock ();
klass->blittable = FALSE;
+ mono_loader_unlock ();
+ }
/* If this is an array type, ensure that we have element info */
if (klass->rank && !mono_marshal_is_loading_type_info (klass->element_class)) {
csig = mono_metadata_signature_dup_full (method->klass->image, sig);
csig->generic_param_count = 0;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
mono_mb_emit_ldarg (mb, 0);
for (i = 0; i < csig->param_count; i++)
mono_mb_emit_ldarg (mb, i + 1);
if (MONO_TYPE_ISSTRUCT (sig->ret))
csig->ret = &mono_defaults.object_class->byval_arg;
-#ifndef DISABLE_JIT
+#ifdef ENABLE_ILGEN
/* local 0 (temp for exception object) */
mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
mono_gchandle_free (gchandle);
- mono_raise_exception (exc);
+ mono_reraise_exception (exc);
}
/*
if (G_UNLIKELY (!is_ok (error)))
mono_error_set_pending_exception (error);
}
+
+static MonoObjectHandle
+mono_icall_handle_new (gpointer rawobj)
+{
+#ifdef MONO_HANDLE_TRACK_OWNER
+ return mono_handle_new (rawobj, "<marshal args>");
+#else
+ return mono_handle_new (rawobj);
+#endif
+}
+
+static MonoObjectHandle
+mono_icall_handle_new_interior (gpointer rawobj)
+{
+#ifdef MONO_HANDLE_TRACK_OWNER
+ return mono_handle_new_interior (rawobj, "<marshal args>");
+#else
+ return mono_handle_new_interior (rawobj);
+#endif
+}