static MonoStringBuilder *
mono_string_utf8_to_builder2 (char *text);
+static MonoStringBuilder *
+mono_string_utf16_to_builder2 (gunichar2 *text);
+
static void
mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype, guint32 elnum);
static MonoObject *
mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params);
-static MonoObject *
-mono_marshal_xdomain_copy_value (MonoObject *val);
-
static void
mono_marshal_xdomain_copy_out_value (MonoObject *src, MonoObject *dst);
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_string_utf16_to_builder2, "mono_string_utf16_to_builder2", "object ptr", FALSE);
register_icall (mono_marshal_free_array, "mono_marshal_free_array", "void ptr int32", FALSE);
register_icall (mono_string_to_byvalstr, "mono_string_to_byvalstr", "void ptr ptr int32", FALSE);
register_icall (mono_string_to_byvalwstr, "mono_string_to_byvalwstr", "void ptr ptr int32", FALSE);
sb->length = len;
}
+MonoStringBuilder *
+mono_string_utf16_to_builder2 (gunichar2 *text)
+{
+ int len;
+ MonoStringBuilder *sb;
+ static MonoClass *string_builder_class;
+ static MonoMethod *sb_ctor;
+ void *args [1];
+ MonoObject *exc;
+
+ if (!text)
+ return NULL;
+
+ if (!string_builder_class) {
+ MonoMethodDesc *desc;
+
+ string_builder_class = mono_class_from_name (mono_defaults.corlib, "System.Text", "StringBuilder");
+ g_assert (string_builder_class);
+ desc = mono_method_desc_new (":.ctor(int)", FALSE);
+ sb_ctor = mono_method_desc_search_in_class (desc, string_builder_class);
+ g_assert (sb_ctor);
+ mono_method_desc_free (desc);
+ }
+
+ for (len = 0; text [len] != 0; ++len)
+ ;
+
+ sb = (MonoStringBuilder*)mono_object_new (mono_domain_get (), string_builder_class);
+ g_assert (sb);
+ args [0] = &len;
+ mono_runtime_invoke (sb_ctor, sb, args, &exc);
+ g_assert (!exc);
+
+ sb->length = len;
+ memcpy (mono_string_chars (sb->str), text, len * 2);
+
+ return sb;
+}
+
/**
* mono_string_builder_to_utf8:
* @sb: the string builder
return;
}
+ if (klass != mono_defaults.safehandle_class) {
+ if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+ 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);
+ return;
+ }
+ }
+
for (i = 0; i < info->num_fields; i++) {
MonoMarshalNative ntype;
MonoMarshalConv conv;
"reference field at the same offset as another field.",
mono_type_full_name (&klass->byval_arg));
}
-
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
- g_error ("Type %s which is passed to unmanaged code must have a StructLayout attribute",
- mono_type_full_name (&klass->byval_arg));
-
}
switch (conv) {
/* mono_marshal_xdomain_copy_value
* Makes a copy of "val" suitable for the current domain.
*/
-static MonoObject *
+MonoObject *
mono_marshal_xdomain_copy_value (MonoObject *val)
{
MonoDomain *domain;
MarshalAction action)
{
MonoMethodBuilder *mb = m->mb;
- MonoClass *klass;
+ MonoClass *klass, *date_time_class;
int pos = 0, pos2;
klass = mono_class_from_mono_type (t);
+ date_time_class = mono_class_from_name_cached (mono_defaults.corlib, "System", "DateTime");
+
switch (action) {
case MARSHAL_ACTION_CONV_IN:
if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
klass->blittable || klass->enumtype)
break;
+ if (klass == date_time_class) {
+ /* Convert it to an OLE DATE type */
+ static MonoMethod *to_oadate;
+
+ if (!to_oadate)
+ to_oadate = mono_class_get_method_from_name (date_time_class, "ToOADate", 0);
+ g_assert (to_oadate);
+
+ if (t->byref)
+ g_assert_not_reached ();
+
+ conv_arg = mono_mb_add_local (mb, &mono_defaults.double_class->byval_arg);
+
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ mono_mb_emit_managed_call (mb, to_oadate, NULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
/* store the address of the source into local variable 0 */
break;
}
+ if (klass == date_time_class) {
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+ }
+
if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
klass->blittable || klass->enumtype) {
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_stloc (mb, 3);
break;
}
+
/* load pointer to returned value type */
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
MonoMarshalConv conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
- g_assert (!t->byref);
+ if (t->byref) {
+ if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ char *msg = g_strdup_printf ("Byref marshalling of stringbuilders is not implemented.");
+ mono_mb_emit_exception_marshal_directive (mb, msg);
+ }
+ break;
+ }
+
mono_mb_emit_ldarg (mb, argnum);
if (conv != -1)
encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
- g_assert (!t->byref);
g_assert (encoding != -1);
- mono_mb_emit_ldarg (mb, argnum);
- mono_mb_emit_ldloc (mb, conv_arg);
+ if (t->byref) {
+ g_assert ((t->attrs & PARAM_ATTRIBUTE_OUT));
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ need_free = TRUE;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ switch (encoding) {
+ case MONO_NATIVE_LPWSTR:
+ mono_mb_emit_icall (mb, mono_string_utf16_to_builder2);
+ break;
+ case MONO_NATIVE_LPSTR:
+ mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ } else {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ mono_mb_emit_icall (mb, conv_to_icall (conv));
+ }
if (need_free) {
mono_mb_emit_ldloc (mb, conv_arg);