static gboolean use_aot_wrappers;
+static int class_marshal_info_count;
+
static void ftnptr_eh_callback_default (guint32 gchandle);
static MonoFtnPtrEHCallback ftnptr_eh_callback = ftnptr_eh_callback_default;
#ifndef HOST_WIN32
static gpointer
-mono_string_to_lpstr (MonoString *string_obj);
+mono_string_to_utf8str (MonoString *string_obj);
#endif
static MonoStringBuilder *
register_icall (mono_string_new_wrapper, "mono_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_lpstr, "mono_string_to_lpstr", "ptr obj", FALSE);
+ register_icall (mono_string_to_utf8str, "mono_string_to_utf8str", "ptr obj", FALSE);
register_icall (mono_string_to_ansibstr, "mono_string_to_ansibstr", "ptr object", FALSE);
register_icall (mono_string_builder_to_utf8, "mono_string_builder_to_utf8", "ptr object", FALSE);
register_icall (mono_string_builder_to_utf16, "mono_string_builder_to_utf16", "ptr object", FALSE);
mono_cominterop_init ();
mono_remoting_init ();
+
+ mono_counters_register ("MonoClass::class_marshal_info_count count",
+ MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_marshal_info_count);
+
}
}
if (!sb || !text)
return;
- int len = strlen (text);
- if (len > mono_string_builder_capacity (sb))
- len = mono_string_builder_capacity (sb);
-
GError *error = NULL;
glong copied;
- gunichar2* ut = g_utf8_to_utf16 (text, len, NULL, &copied, &error);
+ gunichar2* ut = g_utf8_to_utf16 (text, strlen (text), NULL, &copied, &error);
+ int capacity = mono_string_builder_capacity (sb);
+
+ if (copied > capacity)
+ copied = capacity;
if (!error) {
MONO_OBJECT_SETREF (sb, chunkPrevious, NULL);
return sb;
}
-
void
mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text)
{
{
MonoError error;
GError *gerror = NULL;
-
+ glong byte_count;
if (!sb)
return NULL;
guint str_len = mono_string_builder_string_length (sb);
- gchar *tmp = g_utf16_to_utf8 (str_utf16, str_len, NULL, NULL, &gerror);
+ gchar *tmp = g_utf16_to_utf8 (str_utf16, str_len, NULL, &byte_count, &gerror);
if (gerror) {
g_error_free (gerror);
return NULL;
} else {
guint len = mono_string_builder_capacity (sb) + 1;
- gchar *res = (gchar *)mono_marshal_alloc (len * sizeof (gchar), &error);
+ gchar *res = (gchar *)mono_marshal_alloc (MAX (byte_count+1, len * sizeof (gchar)), &error);
if (!mono_error_ok (&error)) {
mono_marshal_free (str_utf16);
g_free (tmp);
return NULL;
}
- g_assert (str_len < len);
- memcpy (res, tmp, str_len * sizeof (gchar));
- res[str_len] = '\0';
+ memcpy (res, tmp, byte_count);
+ res[byte_count] = '\0';
mono_marshal_free (str_utf16);
g_free (tmp);
return str;
}
-/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
#ifndef HOST_WIN32
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static gpointer
-mono_string_to_lpstr (MonoString *s)
+mono_string_to_utf8str (MonoString *s)
{
MonoError error;
char *result = mono_string_to_utf8_checked (s, &error);
mono_error_set_pending_exception (&error);
return result;
}
-#endif /* HOST_WIN32 */
+#endif
gpointer
mono_string_to_ansibstr (MonoString *string_obj)
#endif
mono_mb_emit_byte (mb, CEE_STIND_REF);
break;
+
+ // In Mono historically LPSTR was treated as a UTF8STR
case MONO_MARSHAL_CONV_STR_LPSTR:
+ case MONO_MARSHAL_CONV_STR_UTF8STR:
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_I);
case MONO_MARSHAL_CONV_LPTSTR_STR:
*ind_store_type = CEE_STIND_REF;
return mono_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;
#ifdef TARGET_WIN32
return mono_marshal_string_to_utf16;
#else
- return mono_string_to_lpstr;
+ return mono_string_to_utf8str;
#endif
+ // In Mono historically LPSTR was treated as a UTF8STR
+ case MONO_MARSHAL_CONV_STR_UTF8STR:
case MONO_MARSHAL_CONV_STR_LPSTR:
- return mono_string_to_lpstr;
+ return mono_string_to_utf8str;
case MONO_MARSHAL_CONV_STR_BSTR:
return mono_string_to_bstr;
case MONO_MARSHAL_CONV_BSTR_STR:
case MONO_MARSHAL_CONV_STR_TBSTR:
case MONO_MARSHAL_CONV_STR_ANSIBSTR:
return mono_string_to_ansibstr;
+ case MONO_MARSHAL_CONV_SB_UTF8STR:
case MONO_MARSHAL_CONV_SB_LPSTR:
return mono_string_builder_to_utf8;
case MONO_MARSHAL_CONV_SB_LPTSTR:
case MONO_MARSHAL_CONV_FTN_DEL:
*ind_store_type = CEE_STIND_REF;
return mono_ftnptr_to_delegate;
+ case MONO_MARSHAL_CONV_UTF8STR_SB:
case MONO_MARSHAL_CONV_LPSTR_SB:
*ind_store_type = CEE_STIND_REF;
return mono_string_utf8_to_builder;
mono_mb_emit_byte (mb, CEE_NEG);
mono_mb_emit_byte (mb, CEE_STIND_I2);
break;
+ // In Mono historically LPSTR was treated as a UTF8STR
+ case MONO_MARSHAL_CONV_STR_UTF8STR:
case MONO_MARSHAL_CONV_STR_LPWSTR:
case MONO_MARSHAL_CONV_STR_LPSTR:
case MONO_MARSHAL_CONV_STR_LPTSTR:
}
}
-static int offset_of_first_nonstatic_field(MonoClass *klass)
+static int
+offset_of_first_nonstatic_field (MonoClass *klass)
{
int i;
- for (i = 0; i < klass->field.count; i++) {
+ int fcount = mono_class_get_field_count (klass);
+ for (i = 0; i < fcount; i++) {
if (!(klass->fields[i].type->attrs & FIELD_ATTRIBUTE_STATIC) && !mono_field_is_deleted (&klass->fields[i]))
return klass->fields[i].offset - sizeof (MonoObject);
}
}
if (klass != mono_class_try_get_safehandle_class ()) {
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+ if (mono_class_is_auto_layout (klass)) {
char *msg = g_strdup_printf ("Type %s which is passed to unmanaged code must have a StructLayout attribute.",
mono_type_full_name (&klass->byval_arg));
mono_mb_emit_exception_marshal_directive (mb, msg);
* the layout to the managed structure as well.
*/
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) && (usize == 0)) {
+ if (mono_class_is_explicit_layout (klass) && (usize == 0)) {
if (MONO_TYPE_IS_REFERENCE (info->fields [i].field->type) ||
((!last_field && MONO_TYPE_IS_REFERENCE (info->fields [i + 1].field->type))))
g_error ("Type %s which has an [ExplicitLayout] attribute cannot have a "
return MONO_MARSHAL_CONV_STR_LPTSTR;
case MONO_NATIVE_BSTR:
return MONO_MARSHAL_CONV_STR_BSTR;
+ case MONO_NATIVE_UTF8STR:
+ return MONO_MARSHAL_CONV_STR_UTF8STR;
default:
return MONO_MARSHAL_CONV_INVALID;
}
switch (encoding) {
case MONO_NATIVE_LPWSTR:
return MONO_MARSHAL_CONV_SB_LPWSTR;
- break;
case MONO_NATIVE_LPSTR:
return MONO_MARSHAL_CONV_SB_LPSTR;
- break;
+ case MONO_NATIVE_UTF8STR:
+ return MONO_MARSHAL_CONV_SB_UTF8STR;
case MONO_NATIVE_LPTSTR:
return MONO_MARSHAL_CONV_SB_LPTSTR;
- break;
default:
return MONO_MARSHAL_CONV_INVALID;
}
case MONO_NATIVE_LPWSTR:
*need_free = FALSE;
return MONO_MARSHAL_CONV_LPWSTR_STR;
+ case MONO_NATIVE_UTF8STR:
+ return MONO_MARSHAL_CONV_UTF8STR_STR;
case MONO_NATIVE_LPSTR:
case MONO_NATIVE_VBBYREFSTR:
return MONO_MARSHAL_CONV_LPSTR_STR;
*/
*need_free = FALSE;
return MONO_MARSHAL_CONV_LPWSTR_SB;
+ case MONO_NATIVE_UTF8STR:
+ return MONO_MARSHAL_CONV_UTF8STR_SB;
case MONO_NATIVE_LPSTR:
return MONO_MARSHAL_CONV_LPSTR_SB;
break;
{
MonoError error;
MonoMethod *inst, *res;
+ WrapperInfo *ginfo, *info;
/*
* We use the same cache for the generic definition and the instances.
inst = mono_class_inflate_generic_method_checked (def, ctx, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ ginfo = mono_marshal_get_wrapper_info (def);
+ if (ginfo) {
+ info = (WrapperInfo *)mono_image_alloc0 (def->klass->image, sizeof (WrapperInfo));
+ info->subtype = ginfo->subtype;
+ if (info->subtype == WRAPPER_SUBTYPE_NONE) {
+ info->d.delegate_invoke.method = mono_class_inflate_generic_method_checked (ginfo->d.delegate_invoke.method, ctx, &error);
+ mono_error_assert_ok (&error);
+ }
+ }
+
mono_memory_barrier ();
mono_marshal_lock ();
res = (MonoMethod *)g_hash_table_lookup (cache, orig_method->klass);
MonoMethod *res;
GHashTable *cache;
gpointer cache_key = NULL;
- SignaturePointerPair key;
+ SignaturePointerPair key = { NULL, NULL };
SignaturePointerPair *new_key;
int local_i, local_len, local_delegates, local_d, local_target, local_res;
int pos0, pos1, pos2;
container = mono_method_get_generic_container (method);
if (!container)
- container = method->klass->generic_container;
+ container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
g_assert (container);
invoke_sig = sig = mono_signature_no_pinvoke (method);
#endif /* DISABLE_JIT */
info = mono_wrapper_info_create (mb, subtype);
- info->d.delegate_invoke.method = orig_method;
+ info->d.delegate_invoke.method = method;
if (ctx) {
MonoMethod *def;
break;
}
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype)
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
break;
conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
/* Have to change the signature since the vtype is passed byref */
m->csig->params [argnum - m->csig->hasthis] = &mono_defaults.int_class->byval_arg;
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype)
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
mono_mb_emit_ldarg_addr (mb, argnum);
else
mono_mb_emit_ldloc (mb, conv_arg);
break;
}
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype) {
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
mono_mb_emit_ldarg (mb, argnum);
break;
}
break;
}
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype)
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
break;
if (t->byref) {
break;
case MARSHAL_ACTION_CONV_RESULT:
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable) {
+ if (mono_class_is_explicit_layout (klass) || klass->blittable) {
mono_mb_emit_stloc (mb, 3);
break;
}
break;
case MARSHAL_ACTION_MANAGED_CONV_IN:
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype) {
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
conv_arg = 0;
break;
}
break;
case MARSHAL_ACTION_MANAGED_CONV_OUT:
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype) {
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
break;
- }
-
if (t->byref && (t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))
break;
break;
case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype) {
+ if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
mono_mb_emit_stloc (mb, 3);
m->retobj_var = 0;
break;
MonoMethod *ctor = NULL;
int intptr_handle_slot;
- if (t->data.klass->flags & TYPE_ATTRIBUTE_ABSTRACT){
+ if (mono_class_is_abstract (t->data.klass)) {
mono_mb_emit_byte (mb, CEE_POP);
mono_mb_emit_exception_marshal_directive (mb, g_strdup ("Returned SafeHandles should not be abstract"));
break;
case MONO_NATIVE_LPSTR:
mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
break;
+ case MONO_NATIVE_UTF8STR:
+ mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+ break;
default:
g_assert_not_reached ();
}
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 {
/* set src */
mono_mb_emit_stloc (mb, 0);
encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
// FIXME:
- g_assert (encoding == MONO_NATIVE_LPSTR);
+ g_assert (encoding == MONO_NATIVE_LPSTR || encoding == MONO_NATIVE_UTF8STR);
g_assert (!t->byref);
g_assert (encoding != -1);
}
/* The class can not have an automatic layout */
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+ if (mono_class_is_auto_layout (klass)) {
mono_mb_emit_auto_layout_exception (mb, klass);
break;
}
}
/* The class can not have an automatic layout */
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+ if (mono_class_is_auto_layout (klass)) {
mono_mb_emit_auto_layout_exception (mb, klass);
break;
}
mono_mb_emit_icon (mb, esize);
mono_mb_emit_byte (mb, CEE_MUL);
mono_mb_emit_byte (mb, CEE_PREFIX1);
- mono_mb_emit_byte (mb, CEE_CPBLK);
+ mono_mb_emit_byte (mb, CEE_CPBLK);
+ mono_mb_patch_branch (mb, label1);
break;
}
if (MONO_TYPE_ISSTRUCT (sig->ret)) {
MonoClass *klass = mono_class_from_mono_type (sig->ret);
mono_class_init (klass);
- if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+ if (!(mono_class_is_explicit_layout (klass) || klass->blittable)) {
/* This is used by emit_marshal_vtype (), but it needs to go right before the call */
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
if (MONO_TYPE_ISSTRUCT (sig->ret)) {
MonoClass *klass = mono_class_from_mono_type (sig->ret);
mono_class_init (klass);
- if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+ if (!(mono_class_is_explicit_layout (klass) || klass->blittable)) {
/* This is used by emit_marshal_vtype (), but it needs to go right before the call */
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
mono_marshal_load_type_info (klass);
- if (klass->marshal_info->str_to_ptr)
- return klass->marshal_info->str_to_ptr;
+ MonoMarshalType *marshal_info = mono_class_get_marshal_info (klass);
+ if (marshal_info->str_to_ptr)
+ return marshal_info->str_to_ptr;
if (!stoptr)
stoptr = mono_class_get_method_from_name (mono_defaults.marshal_class, "StructureToPtr", 3);
mono_mb_free (mb);
mono_marshal_lock ();
- if (!klass->marshal_info->str_to_ptr)
- klass->marshal_info->str_to_ptr = res;
+ if (!marshal_info->str_to_ptr)
+ marshal_info->str_to_ptr = res;
else
- res = klass->marshal_info->str_to_ptr;
+ res = marshal_info->str_to_ptr;
mono_marshal_unlock ();
return res;
}
mono_marshal_load_type_info (klass);
- if (klass->marshal_info->ptr_to_str)
- return klass->marshal_info->ptr_to_str;
+ MonoMarshalType *marshal_info = mono_class_get_marshal_info (klass);
+ if (marshal_info->ptr_to_str)
+ return marshal_info->ptr_to_str;
if (!ptostr) {
MonoMethodSignature *sig;
mono_mb_free (mb);
mono_marshal_lock ();
- if (!klass->marshal_info->ptr_to_str)
- klass->marshal_info->ptr_to_str = res;
+ if (!marshal_info->ptr_to_str)
+ marshal_info->ptr_to_str = res;
else
- res = klass->marshal_info->ptr_to_str;
+ res = marshal_info->ptr_to_str;
mono_marshal_unlock ();
return res;
}
method = ((MonoMethodInflated*)method)->declaring;
container = mono_method_get_generic_container (method);
if (!container)
- container = method->klass->generic_container;
+ container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
g_assert (container);
}
method = ((MonoMethodInflated*)method)->declaring;
container = mono_method_get_generic_container (method);
if (!container)
- container = method->klass->generic_container;
+ container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
g_assert (container);
}
return FALSE;
element_class = klass->element_class;
- return (element_class->flags & TYPE_ATTRIBUTE_SEALED) || element_class->valuetype;
+ return mono_class_is_sealed (element_class) || element_class->valuetype;
}
static int
/*Arrays are sealed but are covariant on their element type, We can't use any of the fast paths.*/
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)
+ if (mono_class_is_sealed (element_class))
return STELEMREF_SEALED_CLASS;
return STELEMREF_CLASS;
}
/* uiid = klass->interface_id; */
mono_mb_emit_ldloc (mb, aklass);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, interface_id));
- mono_mb_emit_byte (mb, CEE_LDIND_U2);
+ mono_mb_emit_byte (mb, CEE_LDIND_U4);
mono_mb_emit_stloc (mb, uiid);
/*if (uiid > vt->max_interface_id)*/
mono_mb_emit_ldloc (mb, uiid);
mono_mb_emit_ldloc (mb, vtable);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
- mono_mb_emit_byte (mb, CEE_LDIND_U2);
+ mono_mb_emit_byte (mb, CEE_LDIND_U4);
b2 = mono_mb_emit_branch (mb, CEE_BGT_UN);
/* if (!(vt->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7)))) */
return 0;
}
- layout = (klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK);
+ layout = (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK);
if (type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR) {
return sizeof (gpointer);
case MONO_MARSHAL_CONV_STR_BSTR:
case MONO_MARSHAL_CONV_STR_ANSIBSTR:
case MONO_MARSHAL_CONV_STR_TBSTR:
+ case MONO_MARSHAL_CONV_STR_UTF8STR:
mono_marshal_free (*(gpointer *)cpos);
break;
return res;
}
+void*
+ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMemSize (gulong size)
+{
+ void *res = mono_marshal_alloc_co_task_mem (size);
+
+ if (!res) {
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ return NULL;
+ }
+ return res;
+}
+
void
ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem (void *ptr)
{
/**
* mono_marshal_load_type_info:
*
- * Initialize klass->marshal_info using information from metadata. This function can
+ * Initialize klass::marshal_info using information from metadata. This function can
* recursively call itself, and the caller is responsible to avoid that by calling
* mono_marshal_is_loading_type_info () beforehand.
*
g_assert (klass != NULL);
- if (klass->marshal_info)
- return klass->marshal_info;
+ info = mono_class_get_marshal_info (klass);
+ if (info)
+ return info;
if (!klass->inited)
mono_class_init (klass);
- if (klass->marshal_info)
- return klass->marshal_info;
+ info = mono_class_get_marshal_info (klass);
+ if (info)
+ return info;
/*
* This function can recursively call itself, so we keep the list of classes which are
count++;
}
- layout = klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+ 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);
mono_native_tls_set_value (load_type_info_tls_id, loads_list);
mono_marshal_lock ();
- if (!klass->marshal_info) {
+ MonoMarshalType *info2 = mono_class_get_marshal_info (klass);
+ if (!info2) {
/*We do double-checking locking on marshal_info */
mono_memory_barrier ();
- klass->marshal_info = info;
+ mono_class_set_marshal_info (klass, info);
+ ++class_marshal_info_count;
+ info2 = info;
}
mono_marshal_unlock ();
- return klass->marshal_info;
+ return info2;
}
/**
*/
gint32
mono_class_native_size (MonoClass *klass, guint32 *align)
-{
- if (!klass->marshal_info) {
+{
+ MonoMarshalType *info = mono_class_get_marshal_info (klass);
+ if (!info) {
if (mono_marshal_is_loading_type_info (klass)) {
if (align)
*align = 0;
} else {
mono_marshal_load_type_info (klass);
}
+ info = mono_class_get_marshal_info (klass);
}
if (align)
- *align = klass->marshal_info->min_align;
+ *align = info->min_align;
- return klass->marshal_info->native_size;
+ return info->native_size;
}
/*
case MONO_NATIVE_BSTR:
case MONO_NATIVE_ANSIBSTR:
case MONO_NATIVE_TBSTR:
+ case MONO_NATIVE_UTF8STR:
case MONO_NATIVE_LPARRAY:
case MONO_NATIVE_SAFEARRAY:
case MONO_NATIVE_IUNKNOWN:
switch (string_encoding) {
case MONO_NATIVE_LPWSTR:
return mono_marshal_string_to_utf16_copy ((MonoString*)o);
- break;
case MONO_NATIVE_LPSTR:
- return mono_string_to_lpstr ((MonoString*)o);
- break;
+ case MONO_NATIVE_UTF8STR:
+ // Same code path, because in Mono, we treated strings as Utf8
+ return mono_string_to_utf8str ((MonoString*)o);
default:
g_warning ("marshaling conversion %d not implemented", string_encoding);
g_assert_not_reached ();
klass = t->data.klass;
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ if (mono_class_is_auto_layout (klass))
break;
- if (klass->valuetype && (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype))
+ if (klass->valuetype && (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype))
return mono_object_unbox (o);
res = mono_marshal_alloc (mono_class_native_size (klass, NULL), &error);
switch (string_encoding) {
case MONO_NATIVE_LPWSTR:
case MONO_NATIVE_LPSTR:
+ case MONO_NATIVE_UTF8STR:
mono_marshal_free (ptr);
break;
default:
case MONO_TYPE_VALUETYPE: {
klass = t->data.klass;
- if (klass->valuetype && (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
- klass->blittable || klass->enumtype))
+ if (klass->valuetype && (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype))
break;
if (param_attrs & PARAM_ATTRIBUTE_OUT) {