}
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error */
static MonoString *
mono_string_from_byvalstr (const char *data, int max_len)
{
+ MonoError error;
MonoDomain *domain = mono_domain_get ();
int len = 0;
while (len < max_len - 1 && data [len])
len++;
- return mono_string_new_len (domain, data, len);
+ MonoString *result = mono_string_new_len_checked (domain, data, len, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
/* This is a JIT icall, it sets the pending exception and return NULL on error */
*((gunichar2 *) dst + len) = 0;
}
+/* this is an icall, it sets the pending exception and returns NULL on error */
static MonoString*
mono_string_new_len_wrapper (const char *text, guint length)
{
- return mono_string_new_len (mono_domain_get (), text, length);
+ MonoError error;
+ MonoString *result = mono_string_new_len_checked (mono_domain_get (), text, length, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
#ifndef DISABLE_JIT
mono_type_to_stind (MonoType *type)
{
if (type->byref)
- return CEE_STIND_I;
+ return MONO_TYPE_IS_REFERENCE (type) ? CEE_STIND_REF : CEE_STIND_I;
+
handle_enum:
switch (type->type) {
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_icon (mb, mspec->data.array_data.num_elem);
mono_mb_emit_op (mb, CEE_NEWARR, eklass);
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
if (eklass->blittable) {
/* copy the elements */
}
static gpointer
-conv_to_icall (MonoMarshalConv conv)
+conv_to_icall (MonoMarshalConv conv, int *ind_store_type)
{
+ int dummy;
+ if (!ind_store_type)
+ ind_store_type = &dummy;
+ *ind_store_type = CEE_STIND_I;
switch (conv) {
case MONO_MARSHAL_CONV_STR_LPWSTR:
return mono_marshal_string_to_utf16;
case MONO_MARSHAL_CONV_LPWSTR_STR:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_from_utf16;
case MONO_MARSHAL_CONV_LPTSTR_STR:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_new_wrapper;
case MONO_MARSHAL_CONV_LPSTR_STR:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_new_wrapper;
case MONO_MARSHAL_CONV_STR_LPTSTR:
#ifdef TARGET_WIN32
case MONO_MARSHAL_CONV_STR_BSTR:
return mono_string_to_bstr;
case MONO_MARSHAL_CONV_BSTR_STR:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_from_bstr;
case MONO_MARSHAL_CONV_STR_TBSTR:
case MONO_MARSHAL_CONV_STR_ANSIBSTR:
case MONO_MARSHAL_CONV_DEL_FTN:
return mono_delegate_to_ftnptr;
case MONO_MARSHAL_CONV_FTN_DEL:
+ *ind_store_type = CEE_STIND_REF;
return mono_ftnptr_to_delegate;
case MONO_MARSHAL_CONV_LPSTR_SB:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_utf8_to_builder;
case MONO_MARSHAL_CONV_LPTSTR_SB:
+ *ind_store_type = CEE_STIND_REF;
#ifdef TARGET_WIN32
return mono_string_utf16_to_builder;
#else
return mono_string_utf8_to_builder;
#endif
case MONO_MARSHAL_CONV_LPWSTR_SB:
+ *ind_store_type = CEE_STIND_REF;
return mono_string_utf16_to_builder;
case MONO_MARSHAL_FREE_ARRAY:
return mono_marshal_free_array;
emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec)
{
int pos;
+ int stind_op;
switch (conv) {
case MONO_MARSHAL_CONV_BOOL_I4:
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_REF);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
break;
}
case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_REF);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
break;
case MONO_MARSHAL_CONV_STR_BYVALSTR:
case MONO_MARSHAL_CONV_STR_BYVALWSTR: {
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_REF); /* src String */
mono_mb_emit_icon (mb, mspec->data.array_data.num_elem);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
break;
}
case MONO_MARSHAL_CONV_ARRAY_BYVALARRAY: {
case MONO_MARSHAL_CONV_NONE: {
int t;
- if (ftype->byref || ftype->type == MONO_TYPE_I ||
- ftype->type == MONO_TYPE_U) {
+ //XXX a byref field!?!? that's not allowed! and worse, it might miss a WB
+ g_assert (!ftype->byref);
+ if (ftype->type == MONO_TYPE_I || ftype->type == MONO_TYPE_U) {
mono_mb_emit_ldloc (mb, 1);
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_byte (mb, CEE_LDIND_I);
mono_set_pending_exception ((MonoException*)exc);
}
- mono_method_return_message_restore (method, params, out_args);
+ mono_method_return_message_restore (method, params, out_args, &error);
+ mono_error_set_pending_exception (&error);
return res;
}
char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
mono_mb_emit_exception_marshal_directive (mb, msg);
} else {
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_stloc (mb, conv_arg);
}
mono_mb_emit_icall (mb, mono_string_new_len_wrapper);
mono_mb_emit_byte (mb, CEE_STIND_REF);
} else if (t->byref && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
+ int stind_op;
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_REF);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
need_free = TRUE;
}
}
mono_mb_emit_ldloc (mb, 0);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_stloc (mb, 3);
/* free the string */
mono_mb_emit_ldarg (mb, argnum);
if (t->byref)
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_stloc (mb, conv_arg);
break;
case MARSHAL_ACTION_MANAGED_CONV_OUT:
if (t->byref) {
if (conv_arg) {
+ int stind_op;
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
}
}
break;
case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if (conv_to_icall (conv) == mono_marshal_string_to_utf16)
+ if (conv_to_icall (conv, NULL) == mono_marshal_string_to_utf16)
/* We need to make a copy so the caller is able to free it */
mono_mb_emit_icall (mb, mono_marshal_string_to_utf16_copy);
else
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_stloc (mb, 3);
break;
mono_mb_emit_stloc (mb, conv_arg);
} else {
mono_mb_emit_ldarg (mb, argnum);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
mono_mb_emit_stloc (mb, conv_arg);
}
} else if (klass == mono_defaults.stringbuilder_class) {
if (t->byref)
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_stloc (mb, conv_arg);
} else if (klass->blittable) {
mono_mb_emit_byte (mb, CEE_LDNULL);
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
}
if (need_free) {
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
mono_mb_emit_byte (mb, CEE_STIND_REF);
}
break;
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
mono_mb_emit_ldloc (mb, 0);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
mono_mb_emit_stloc (mb, 3);
} else {
/* set src */
mono_mb_emit_ldarg (mb, argnum);
if (t->byref)
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
mono_mb_emit_stloc (mb, conv_arg);
break;
}
case MARSHAL_ACTION_MANAGED_CONV_OUT:
if (klass->delegate) {
if (t->byref) {
+ int stind_op;
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
break;
}
}
case MARSHAL_ACTION_MANAGED_CONV_RESULT:
if (klass->delegate) {
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
mono_mb_emit_stloc (mb, 3);
break;
}
mono_mb_emit_ldarg (mb, argnum);
if (t->byref)
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_ARRAY_LPARRAY));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_ARRAY_LPARRAY, NULL));
mono_mb_emit_stloc (mb, conv_arg);
} else {
MonoClass *eklass;
/* Emit marshalling code */
if (is_string) {
+ int stind_op;
mono_mb_emit_ldloc (mb, dest_ptr);
mono_mb_emit_ldloc (mb, src_var);
mono_mb_emit_ldloc (mb, index_var);
mono_mb_emit_byte (mb, CEE_LDELEM_REF);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
} else {
/* set the src_ptr */
mono_mb_emit_ldloc (mb, src_var);
mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
mono_mb_emit_op (mb, CEE_NEWARR, klass->element_class);
/* Store into argument */
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
}
}
mono_mb_emit_ldloc (mb, src_ptr);
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
if (need_free) {
/* src */
if (t->byref)
mono_mb_emit_byte (mb, CEE_LDIND_REF);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_FREE_LPARRAY));
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_FREE_LPARRAY, NULL));
}
break;
mono_mb_emit_ldloc (mb, src_ptr);
mono_mb_emit_byte (mb, CEE_LDIND_I);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
+ mono_mb_emit_icall (mb, conv_to_icall (conv, NULL));
mono_mb_emit_byte (mb, CEE_STELEM_REF);
}
else {
/* Emit marshalling code */
if (is_string) {
+ int stind_op;
g_assert (conv != MONO_MARSHAL_CONV_INVALID);
/* dest */
mono_mb_emit_byte (mb, CEE_LDELEM_REF);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
}
else {
char *msg = g_strdup ("Marshalling of non-string and non-blittable arrays to managed code is not implemented.");
/* Emit marshalling code */
if (is_string) {
+ int stind_op;
g_assert (conv != MONO_MARSHAL_CONV_INVALID);
/* dest */
mono_mb_emit_byte (mb, CEE_LDELEM_REF);
- mono_mb_emit_icall (mb, conv_to_icall (conv));
- mono_mb_emit_byte (mb, CEE_STIND_I);
+ mono_mb_emit_icall (mb, conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, stind_op);
}
else {
char *msg = g_strdup ("Marshalling of non-string arrays to managed code is not implemented.");
return emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action);
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
-#ifndef DISABLE_COM
+#if !defined(DISABLE_COM) && !defined(DISABLE_JIT)
if (spec && spec->native == MONO_NATIVE_STRUCT)
return emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+#endif
+#if !defined(DISABLE_COM)
if (spec && (spec->native == MONO_NATIVE_IUNKNOWN ||
spec->native == MONO_NATIVE_IDISPATCH ||
spec->native == MONO_NATIVE_INTERFACE))
// return obj
mono_mb_patch_branch (mb, positive_cache_hit_pos);
- mono_mb_emit_ldarg (mb, 0);
+ mono_mb_emit_ldarg (mb, obj_arg_position);
mono_mb_emit_byte (mb, CEE_RET);
#endif
MonoString *
ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len (char *ptr, gint32 len)
{
- if (ptr == NULL) {
- mono_set_pending_exception (mono_get_exception_argument_null ("ptr"));
- return NULL;
- } else {
- return mono_string_new_len (mono_domain_get (), ptr, len);
- }
+ MonoError error;
+ MonoString *result = NULL;
+ mono_error_init (&error);
+ if (ptr == NULL)
+ mono_error_set_argument_null (&error, "ptr", "");
+ else
+ result = mono_string_new_len_checked (mono_domain_get (), ptr, len, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
MonoString *