static GENERATE_GET_CLASS_WITH_CACHE (event_info, "System.Reflection", "EventInfo")
static GENERATE_GET_CLASS_WITH_CACHE (module, "System.Reflection", "Module")
+static void
+array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error);
+
static MonoArrayHandle
type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
}
ICALL_EXPORT void
-ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
+ves_icall_System_Array_SetValueImpl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error)
+{
+ error_init (error);
+ array_set_value_impl (arr, value, pos, error);
+}
+
+static void
+array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error)
{
- MonoError error;
MonoClass *ac, *vc, *ec;
gint32 esize, vsize;
gpointer *ea, *va;
gint64 i64 = 0;
gdouble r64 = 0;
- error_init (&error);
+ uint32_t arr_gchandle = 0;
+ uint32_t value_gchandle = 0;
+
+ error_init (error);
- if (value)
- vc = value->vtable->klass;
+ if (!MONO_HANDLE_IS_NULL (value))
+ vc = mono_handle_class (value);
else
vc = NULL;
- ac = arr->obj.vtable->klass;
+ ac = mono_handle_class (arr);
ec = ac->element_class;
esize = mono_array_element_size (ac);
- ea = (gpointer*)((char*)arr->vector + (pos * esize));
- va = (gpointer*)((char*)value + sizeof (MonoObject));
+ ea = mono_array_handle_pin_with_size (arr, esize, pos, &arr_gchandle);
if (mono_class_is_nullable (ec)) {
- mono_nullable_init ((guint8*)ea, value, ec);
- return;
+ mono_nullable_init_from_handle ((guint8*)ea, value, ec);
+ goto leave;
}
- if (!value) {
+ if (MONO_HANDLE_IS_NULL (value)) {
mono_gc_bzero_atomic (ea, esize);
- return;
+ goto leave;
}
-#define NO_WIDENING_CONVERSION G_STMT_START{\
- mono_set_pending_exception (mono_get_exception_argument ( \
- "value", "not a widening conversion")); \
- return; \
-}G_STMT_END
+#define NO_WIDENING_CONVERSION G_STMT_START{ \
+ mono_error_set_argument (error, "value", "not a widening conversion"); \
+ goto leave; \
+ }G_STMT_END
-#define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
- if (esize < vsize + (extra)) { \
- mono_set_pending_exception (mono_get_exception_argument ( \
- "value", "not a widening conversion")); \
- return; \
- } \
-}G_STMT_END
+#define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{ \
+ if (esize < vsize + (extra)) { \
+ mono_error_set_argument (error, "value", "not a widening conversion"); \
+ goto leave; \
+ } \
+ }G_STMT_END
-#define INVALID_CAST G_STMT_START{ \
+#define INVALID_CAST G_STMT_START{ \
mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
- mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
- return; \
-}G_STMT_END
+ mono_error_set_invalid_cast (error); \
+ goto leave; \
+ }G_STMT_END
/* Check element (destination) type. */
switch (ec->byval_arg.type) {
break;
}
+ MonoObjectHandle inst = mono_object_handle_isinst (value, ec, error);
+ if (!is_ok (error))
+ goto leave;
+ gboolean castOk = !MONO_HANDLE_IS_NULL (inst);
+
if (!ec->valuetype) {
- gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
- if (mono_error_set_pending_exception (&error))
- return;
if (!castOk)
INVALID_CAST;
- mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
- return;
+ MONO_HANDLE_ARRAY_SETREF (arr, pos, value);
+ goto leave;
}
- if (mono_object_isinst_checked (value, ec, &error)) {
+ if (castOk) {
+ va = mono_object_handle_pin_unbox (value, &value_gchandle);
if (ec->has_references)
- mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
+ mono_value_copy (ea, va, ec);
else
- mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
- return;
+ mono_gc_memmove_atomic (ea, va, esize);
+ mono_gchandle_free (value_gchandle);
+ value_gchandle = 0;
+ goto leave;
}
- if (mono_error_set_pending_exception (&error))
- return;
if (!vc->valuetype)
INVALID_CAST;
+ va = mono_object_handle_pin_unbox (value, &value_gchandle);
+
vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
et = ec->byval_arg.type;
case MONO_TYPE_CHAR: \
CHECK_WIDENING_CONVERSION(0); \
*(etype *) ea = (etype) u64; \
- return; \
+ goto leave; \
/* You can't assign a signed value to an unsigned array. */ \
case MONO_TYPE_I1: \
case MONO_TYPE_I2: \
case MONO_TYPE_I8: \
CHECK_WIDENING_CONVERSION(0); \
*(etype *) ea = (etype) i64; \
- return; \
+ goto leave; \
/* You can assign an unsigned value to a signed array if the array's */ \
/* element size is larger than the value size. */ \
case MONO_TYPE_U1: \
case MONO_TYPE_CHAR: \
CHECK_WIDENING_CONVERSION(1); \
*(etype *) ea = (etype) u64; \
- return; \
+ goto leave; \
/* You can't assign a floating point number to an integer array. */ \
case MONO_TYPE_R4: \
case MONO_TYPE_R8: \
case MONO_TYPE_R8: \
CHECK_WIDENING_CONVERSION(0); \
*(etype *) ea = (etype) r64; \
- return; \
+ goto leave; \
/* All integer values fit into a floating point array, so we don't */ \
/* need to CHECK_WIDENING_CONVERSION here. */ \
case MONO_TYPE_I1: \
case MONO_TYPE_I4: \
case MONO_TYPE_I8: \
*(etype *) ea = (etype) i64; \
- return; \
+ goto leave; \
case MONO_TYPE_U1: \
case MONO_TYPE_U2: \
case MONO_TYPE_U4: \
case MONO_TYPE_U8: \
case MONO_TYPE_CHAR: \
*(etype *) ea = (etype) u64; \
- return; \
+ goto leave; \
} \
}G_STMT_END
}
INVALID_CAST;
- /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
- return;
+ /* Not reached, INVALID_CAST does fall thru. */
+ g_assert_not_reached ();
#undef INVALID_CAST
#undef NO_WIDENING_CONVERSION
#undef ASSIGN_UNSIGNED
#undef ASSIGN_SIGNED
#undef ASSIGN_REAL
+leave:
+ if (arr_gchandle)
+ mono_gchandle_free (arr_gchandle);
+ if (value_gchandle)
+ mono_gchandle_free (value_gchandle);
+ return;
}
ICALL_EXPORT void
-ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
- MonoArray *idxs)
+ves_icall_System_Array_SetValue (MonoArrayHandle arr, MonoObjectHandle value,
+ MonoArrayHandle idxs, MonoError *error)
{
+ MonoArrayBounds dim;
MonoClass *ac, *ic;
- gint32 i, pos, *ind;
+ gint32 idx;
+ gint32 i, pos;
- MONO_CHECK_ARG_NULL (idxs,);
+ error_init (error);
- ic = idxs->obj.vtable->klass;
- ac = arr->obj.vtable->klass;
+ if (MONO_HANDLE_IS_NULL (idxs)) {
+ mono_error_set_argument_null (error, "idxs", "");
+ return;
+ }
+
+ ic = mono_handle_class (idxs);
+ ac = mono_handle_class (arr);
g_assert (ic->rank == 1);
- if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
- mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
+ if (mono_handle_array_has_bounds (idxs) || MONO_HANDLE_GETVAL (idxs, max_length) != ac->rank) {
+ mono_error_set_argument (error, "idxs", "");
return;
}
- ind = (gint32 *)idxs->vector;
-
- if (arr->bounds == NULL) {
- if (*ind < 0 || *ind >= arr->max_length) {
- mono_set_pending_exception (mono_get_exception_index_out_of_range ());
+ if (!mono_handle_array_has_bounds (arr)) {
+ MONO_HANDLE_ARRAY_GETVAL (idx, idxs, gint32, 0);
+ if (idx < 0 || idx >= MONO_HANDLE_GETVAL (arr, max_length)) {
+ mono_error_set_exception_instance (error, mono_get_exception_index_out_of_range ());
return;
}
- ves_icall_System_Array_SetValueImpl (arr, value, *ind);
+ array_set_value_impl (arr, value, idx, error);
return;
}
- for (i = 0; i < ac->rank; i++)
- if ((ind [i] < arr->bounds [i].lower_bound) ||
- (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
- mono_set_pending_exception (mono_get_exception_index_out_of_range ());
+ for (i = 0; i < ac->rank; i++) {
+ mono_handle_array_get_bounds_dim (arr, i, &dim);
+ MONO_HANDLE_ARRAY_GETVAL (idx, idxs, gint32, i);
+ if ((idx < dim.lower_bound) ||
+ (idx >= (mono_array_lower_bound_t)dim.length + dim.lower_bound)) {
+ mono_error_set_exception_instance (error, mono_get_exception_index_out_of_range ());
return;
}
+ }
- pos = ind [0] - arr->bounds [0].lower_bound;
- for (i = 1; i < ac->rank; i++)
- pos = pos * arr->bounds [i].length + ind [i] -
- arr->bounds [i].lower_bound;
- ves_icall_System_Array_SetValueImpl (arr, value, pos);
+ MONO_HANDLE_ARRAY_GETVAL (idx, idxs, gint32, 0);
+ mono_handle_array_get_bounds_dim (arr, 0, &dim);
+ pos = idx - dim.lower_bound;
+ for (i = 1; i < ac->rank; i++) {
+ mono_handle_array_get_bounds_dim (arr, i, &dim);
+ MONO_HANDLE_ARRAY_GETVAL (idx, idxs, gint32, i);
+ pos = pos * dim.length + idx - dim.lower_bound;
+ }
+
+ array_set_value_impl (arr, value, pos, error);
}
ICALL_EXPORT MonoArray *
{
#if defined(TARGET_WIN32) || defined(HOST_WIN32)
// It does not work on win32
-#elif defined(TARGET_ANDROID)
+#elif defined(TARGET_ANDROID) || defined(__linux__)
// No need for now
#else
guint8 *stack_addr;
if (mono_class_is_transparent_proxy (klass)) {
MonoTransparentProxyHandle proxy_obj = MONO_HANDLE_CAST (MonoTransparentProxy, obj);
MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (proxy_obj, remote_class);
- MonoType *proxy_type = &remote_class->proxy_class->byval_arg;
+ /* If it's a transparent proxy for an interface, return the
+ * interface type, not the unhelpful proxy_class class (which
+ * is just MarshalByRefObject). */
+ MonoType *proxy_type =
+ mono_remote_class_is_interface_proxy (remote_class) ?
+ &remote_class->interfaces[0]->byval_arg :
+ &remote_class->proxy_class->byval_arg;
return mono_type_get_object_handle (domain, proxy_type, error);
} else
#endif
MONO_HANDLE_ARRAY_SETREF (res, count, rt);
} else {
- MonoException *ex = mono_error_convert_to_exception (error);
+ MonoException *ex = mono_error_convert_to_exception (&klass_error);
MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
}
HANDLE_FUNCTION_RETURN ();
}
ICALL_EXPORT MonoObject*
-ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
+ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo(void)
{
mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
return NULL;