static void
mono_icall_end (MonoThreadInfo *info, HandleStackMark *stackmark, MonoError *error);
+static MonoObjectHandle
+mono_icall_handle_new_full (gpointer rawobj, MonoBoolean interior);
+
/* 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");
return result;
}
+static MonoString*
+ves_icall_string_new_wrapper (const char *text)
+{
+ if (text) {
+ MonoError error;
+ MonoString *res = mono_string_new_checked (mono_domain_get (), text, &error);
+ mono_error_set_pending_exception (&error);
+ return res;
+ }
+
+ return NULL;
+}
+
void
mono_marshal_init (void)
{
register_icall (mono_string_from_byvalstr, "mono_string_from_byvalstr", "obj ptr int", FALSE);
register_icall (mono_string_from_byvalwstr, "mono_string_from_byvalwstr", "obj ptr int", FALSE);
register_icall (mono_string_new_wrapper, "mono_string_new_wrapper", "obj ptr", FALSE);
+ register_icall (ves_icall_string_new_wrapper, "ves_icall_string_new_wrapper", "obj ptr", FALSE);
register_icall (mono_string_new_len_wrapper, "mono_string_new_len_wrapper", "obj ptr int", FALSE);
register_icall (ves_icall_mono_string_to_utf8, "ves_icall_mono_string_to_utf8", "ptr obj", FALSE);
register_icall (mono_string_to_utf8str, "mono_string_to_utf8str", "ptr obj", FALSE);
register_icall (mono_struct_delete_old, "mono_struct_delete_old", "void 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_context_get, "mono_context_get", "object", FALSE);
- register_icall (mono_context_set, "mono_context_set", "void object", 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);
register_icall (mono_gchandle_new, "mono_gchandle_new", "uint32 object bool", TRUE);
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_full, "mono_icall_handle_new_full", "ptr ptr bool", TRUE);
mono_cominterop_init ();
mono_remoting_init ();
} else {
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
- mono_mb_emit_icall (mb, mono_string_new_wrapper);
+ mono_mb_emit_icall (mb, ves_icall_string_new_wrapper);
}
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
#ifdef TARGET_WIN32
mono_mb_emit_icall (mb, ves_icall_mono_string_from_utf16);
#else
- mono_mb_emit_icall (mb, mono_string_new_wrapper);
+ mono_mb_emit_icall (mb, ves_icall_string_new_wrapper);
#endif
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, mono_string_new_wrapper);
+ mono_mb_emit_icall (mb, ves_icall_string_new_wrapper);
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
case MONO_MARSHAL_CONV_STR_LPWSTR:
return ves_icall_mono_string_from_utf16;
case MONO_MARSHAL_CONV_LPTSTR_STR:
*ind_store_type = CEE_STIND_REF;
- return mono_string_new_wrapper;
+ return ves_icall_string_new_wrapper;
case MONO_MARSHAL_CONV_UTF8STR_STR:
case MONO_MARSHAL_CONV_LPSTR_STR:
*ind_store_type = CEE_STIND_REF;
- return mono_string_new_wrapper;
+ return ves_icall_string_new_wrapper;
case MONO_MARSHAL_CONV_STR_LPTSTR:
#ifdef TARGET_WIN32
return mono_marshal_string_to_utf16;
if (is_ok (&inner_error)) {
char *tmp;
tmp = g_strdup_printf ("%s\nException Rethrown at:\n", strace);
- g_free (strace);
- MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, mono_string_new (domain, tmp));
+ g_free (strace);
+ MonoString *tmp_str = mono_string_new_checked (domain, tmp, &inner_error);
g_free (tmp);
- } else
+ if (is_ok (&inner_error))
+ MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, tmp_str);
+ };
+ if (!is_ok (&inner_error))
mono_error_cleanup (&inner_error); /* no stack trace, but at least throw the original exception */
}
mono_set_pending_exception ((MonoException*)exc);
/* 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_full);
}
for (i = 0; i < sig->param_count; i++) {
/* load each argument. references into the managed heap get wrapped in handles */
/* argI = mono_handle_new_full (argI_raw, FALSE) */
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_full);
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);
+ mono_mb_emit_icall (mb, mono_icall_handle_new_full);
/* tmp = argI */
mono_mb_emit_byte (mb, CEE_DUP);
/* handleI = tmp */
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_full);
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);
STELEMREF_OBJECT, /*no check at all*/
STELEMREF_SEALED_CLASS, /*check vtable->klass->element_type */
STELEMREF_CLASS, /*only the klass->parents check*/
+ STELEMREF_CLASS_SMALL_IDEPTH, /* like STELEMREF_CLASS bit without the idepth check */
STELEMREF_INTERFACE, /*interfaces without variant generic arguments. */
STELEMREF_COMPLEX, /*arrays, MBR or types with variant generic args - go straight to icalls*/
STELEMREF_KIND_COUNT
};
static const char *strelemref_wrapper_name[] = {
- "object", "sealed_class", "class", "interface", "complex"
+ "object", "sealed_class", "class", "class_small_idepth", "interface", "complex"
};
static gboolean
return STELEMREF_COMPLEX;
if (mono_class_is_sealed (element_class))
return STELEMREF_SEALED_CLASS;
+ if (element_class->idepth <= MONO_DEFAULT_SUPERTABLE_SIZE)
+ return STELEMREF_CLASS_SMALL_IDEPTH;
+
return STELEMREF_CLASS;
}
mono_mb_emit_exception (mb, "ArrayTypeMismatchException", NULL);
break;
}
+
+ case STELEMREF_CLASS_SMALL_IDEPTH:
+ /*
+ the method:
+ <ldelema (bound check)>
+ if (!value)
+ goto do_store;
+
+ aklass = array->vtable->klass->element_class;
+ vklass = value->vtable->klass;
+
+ if (vklass->supertypes [aklass->idepth - 1] != aklass)
+ goto do_exception;
+
+ do_store:
+ *array_slot_addr = value;
+ return;
+
+ long:
+ throw new ArrayTypeMismatchException ();
+ */
+ 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);
+
+ /* ldelema (implicit bound check) */
+ load_array_element_address (mb);
+ mono_mb_emit_stloc (mb, array_slot_addr);
+
+ /* if (!value) goto do_store */
+ mono_mb_emit_ldarg (mb, 2);
+ b1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* aklass = array->vtable->klass->element_class */
+ load_array_class (mb, aklass);
+
+ /* vklass = value->vtable->klass */
+ load_value_class (mb, vklass);
+
+ /* if (vklass->supertypes [aklass->idepth - 1] != aklass) goto failure */
+ mono_mb_emit_ldloc (mb, vklass);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, supertypes));
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_ldloc (mb, aklass);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, idepth));
+ mono_mb_emit_byte (mb, CEE_LDIND_U2);
+ mono_mb_emit_icon (mb, 1);
+ mono_mb_emit_byte (mb, CEE_SUB);
+ mono_mb_emit_icon (mb, sizeof (void*));
+ mono_mb_emit_byte (mb, CEE_MUL);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_ldloc (mb, aklass);
+ b4 = mono_mb_emit_branch (mb, CEE_BNE_UN);
+
+ /* do_store: */
+ mono_mb_patch_branch (mb, b1);
+ mono_mb_emit_ldloc (mb, array_slot_addr);
+ mono_mb_emit_ldarg (mb, 2);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ /* do_exception: */
+ mono_mb_patch_branch (mb, b4);
+
+ mono_mb_emit_exception (mb, "ArrayTypeMismatchException", NULL);
+ break;
+
case STELEMREF_INTERFACE:
/*Mono *klass;
MonoVTable *vt;
memcpy (dest_addr, src, length * element_size);
}
-MonoString *
-ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr)
+MonoStringHandle
+ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr, MonoError *error)
{
+ error_init (error);
if (ptr == NULL)
- return NULL;
+ return MONO_HANDLE_CAST (MonoString, NULL_HANDLE);
else
- return mono_string_new (mono_domain_get (), ptr);
+ return mono_string_new_handle (mono_domain_get (), ptr, error);
}
MonoString *
if (G_UNLIKELY (!is_ok (error)))
mono_error_set_pending_exception (error);
}
+
+static MonoObjectHandle
+mono_icall_handle_new_full (gpointer rawobj, MonoBoolean interior)
+{
+#ifdef MONO_HANDLE_TRACK_OWNER
+ return mono_handle_new_full (rawobj, interior, "<marshal args>");
+#else
+ return mono_handle_new_full (rawobj, interior);
+#endif
+}