X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ficall.c;h=f55ed1f1847600caf96c9aced596651945e01320;hb=HEAD;hp=ed071dd099555683c2851f00500137b4fdad6973;hpb=427e0f335cfe3a0df8a650ce1ac72b74035ef159;p=mono.git diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index ed071dd0995..f55ed1f1847 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -118,6 +118,9 @@ static GENERATE_GET_CLASS_WITH_CACHE (property_info, "System.Reflection", "Prope 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); @@ -220,9 +223,15 @@ ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs) } 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; @@ -232,49 +241,49 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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) { @@ -310,29 +319,34 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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; @@ -352,7 +366,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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: \ @@ -373,7 +387,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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: \ @@ -383,7 +397,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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: \ @@ -397,7 +411,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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: \ @@ -405,14 +419,14 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 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 @@ -498,8 +512,8 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 } 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 @@ -507,51 +521,71 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 #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 * @@ -980,6 +1014,8 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStac { #if defined(TARGET_WIN32) || defined(HOST_WIN32) // It does not work on win32 +#elif defined(TARGET_ANDROID) || defined(__linux__) + // No need for now #else guint8 *stack_addr; guint8 *current; @@ -1220,7 +1256,13 @@ ves_icall_System_Object_GetType (MonoObjectHandle obj, MonoError *error) 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 @@ -1913,32 +1955,27 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob } ICALL_EXPORT void -ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value) +ves_icall_MonoField_SetValueInternal (MonoReflectionFieldHandle field, MonoObjectHandle obj, MonoObjectHandle value, MonoError *error) { - MonoError error; - MonoClassField *cf = field->field; - MonoType *type; - gchar *v; + MonoClassField *cf = MONO_HANDLE_GETVAL (field, field); - if (field->klass->image->assembly->ref_only) { - mono_set_pending_exception (mono_get_exception_invalid_operation ( - "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods.")); + MonoClass *field_klass = MONO_HANDLE_GETVAL (field, klass); + if (field_klass->image->assembly->ref_only) { + mono_error_set_invalid_operation (error, "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."); return; } if (mono_security_core_clr_enabled () && - !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) { - mono_error_set_pending_exception (&error); + !mono_security_core_clr_ensure_reflection_access_field (cf, error)) { return; } - type = mono_field_get_type_checked (cf, &error); - if (!mono_error_ok (&error)) { - mono_error_set_pending_exception (&error); - return; - } + MonoType *type = mono_field_get_type_checked (cf, error); + return_if_nok (error); - v = (gchar *) value; + gboolean isref = FALSE; + uint32_t value_gchandle = 0; + gchar *v = NULL; if (!type->byref) { switch (type->type) { case MONO_TYPE_U1: @@ -1957,8 +1994,9 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob case MONO_TYPE_R8: case MONO_TYPE_VALUETYPE: case MONO_TYPE_PTR: - if (v != NULL) - v += sizeof (MonoObject); + isref = FALSE; + if (!MONO_HANDLE_IS_NULL (value)) + v = mono_object_handle_pin_unbox (value, &value_gchandle); break; case MONO_TYPE_STRING: case MONO_TYPE_OBJECT: @@ -1966,6 +2004,7 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: /* Do nothing */ + isref = TRUE; break; case MONO_TYPE_GENERICINST: { MonoGenericClass *gclass = type->data.generic_class; @@ -1973,26 +2012,29 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob if (mono_class_is_nullable (mono_class_from_mono_type (type))) { MonoClass *nklass = mono_class_from_mono_type (type); - MonoObject *nullable; /* * Convert the boxed vtype into a Nullable structure. * This is complicated by the fact that Nullables have * a variable structure. */ - nullable = mono_object_new_checked (mono_domain_get (), nklass, &error); - if (!mono_error_ok (&error)) { - mono_error_set_pending_exception (&error); - return; - } + MonoObjectHandle nullable = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (mono_domain_get (), nklass, error)); + return_if_nok (error); - mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass); + uint32_t nullable_gchandle = 0; + guint8 *nval = mono_object_handle_pin_unbox (nullable, &nullable_gchandle); + mono_nullable_init_from_handle (nval, value, nklass); - v = (gchar *)mono_object_unbox (nullable); + isref = FALSE; + value_gchandle = nullable_gchandle; + v = (gchar*)nval; + } + else { + isref = !gclass->container_class->valuetype; + if (!isref && !MONO_HANDLE_IS_NULL (value)) { + v = mono_object_handle_pin_unbox (value, &value_gchandle); + }; } - else - if (gclass->container_class->valuetype && (v != NULL)) - v += sizeof (MonoObject); break; } default: @@ -2002,22 +2044,35 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob } } + /* either value is a reference type, or it's a value type and we pinned + * it and v points to the payload. */ + g_assert ((isref && v == NULL && value_gchandle == 0) || + (!isref && v != NULL && value_gchandle != 0) || + (!isref && v == NULL && value_gchandle == 0)); + if (type->attrs & FIELD_ATTRIBUTE_STATIC) { - MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error); - if (!is_ok (&error)) { - mono_error_set_pending_exception (&error); - return; - } + MonoVTable *vtable = mono_class_vtable_full (MONO_HANDLE_DOMAIN (field), cf->parent, error); + if (!is_ok (error)) + goto leave; + if (!vtable->initialized) { - if (!mono_runtime_class_init_full (vtable, &error)) { - mono_error_set_pending_exception (&error); - return; - } + if (!mono_runtime_class_init_full (vtable, error)) + goto leave; } - mono_field_static_set_value (vtable, cf, v); + if (isref) + mono_field_static_set_value (vtable, cf, MONO_HANDLE_RAW (value)); /* FIXME make mono_field_static_set_value work with handles for value */ + else + mono_field_static_set_value (vtable, cf, v); } else { - mono_field_set_value (obj, cf, v); + + if (isref) + MONO_HANDLE_SET_FIELD_REF (obj, cf, value); + else + mono_field_set_value (MONO_HANDLE_RAW (obj), cf, v); /* FIXME: make mono_field_set_value take a handle for obj */ } +leave: + if (value_gchandle) + mono_gchandle_free (value_gchandle); } ICALL_EXPORT void @@ -3293,110 +3348,123 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo } #ifndef DISABLE_REMOTING -ICALL_EXPORT MonoObject * -ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs) +static void +internal_execute_field_getter (MonoDomain *domain, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs, MonoError *error) { - MonoError error; - MonoDomain *domain = mono_object_domain (method); - MonoMethod *m = method->method; - MonoMethodSignature *sig = mono_method_signature (m); + error_init (error); MonoArray *out_args; - MonoObject *result; - int i, j, outarg_count = 0; - - if (m->klass == mono_defaults.object_class) { - if (!strcmp (m->name, "FieldGetter")) { - MonoClass *k = mono_object_class (this_arg); - MonoString *name; - char *str; + MonoClass *k = mono_object_class (this_arg); + MonoString *name; + char *str; - /* If this is a proxy, then it must be a CBO */ - if (mono_class_is_transparent_proxy (k)) { - MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg; - this_arg = tp->rp->unwrapped_server; - g_assert (this_arg); - k = mono_object_class (this_arg); - } + /* If this is a proxy, then it must be a CBO */ + if (mono_class_is_transparent_proxy (k)) { + MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg; + this_arg = tp->rp->unwrapped_server; + g_assert (this_arg); + k = mono_object_class (this_arg); + } - name = mono_array_get (params, MonoString *, 1); - str = mono_string_to_utf8_checked (name, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + name = mono_array_get (params, MonoString *, 1); + str = mono_string_to_utf8_checked (name, error); + return_if_nok (error); - do { - MonoClassField* field = mono_class_get_field_from_name (k, str); - if (field) { - g_free (str); - MonoClass *field_klass = mono_class_from_mono_type (field->type); - if (field_klass->valuetype) { - result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; - } else - result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset)); - - out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; - mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args); - mono_array_setref (out_args, 0, result); - return NULL; - } - k = k->parent; - } while (k); - + do { + MonoClassField* field = mono_class_get_field_from_name (k, str); + if (field) { g_free (str); - g_assert_not_reached (); + MonoClass *field_klass = mono_class_from_mono_type (field->type); + MonoObject *result; + if (field_klass->valuetype) { + result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, error); + return_if_nok (error); + } else + result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset)); + + out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, error); + return_if_nok (error); + mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args); + mono_array_setref (out_args, 0, result); + return; + } + k = k->parent; + } while (k); - } else if (!strcmp (m->name, "FieldSetter")) { - MonoClass *k = mono_object_class (this_arg); - MonoString *name; - guint32 size; - gint32 align; - char *str; + g_free (str); + g_assert_not_reached (); +} + +static void +internal_execute_field_setter (MonoDomain *domain, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs, MonoError *error) +{ + error_init (error); + MonoArray *out_args; + MonoClass *k = mono_object_class (this_arg); + MonoString *name; + guint32 size; + gint32 align; + char *str; - /* If this is a proxy, then it must be a CBO */ - if (mono_class_is_transparent_proxy (k)) { - MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg; - this_arg = tp->rp->unwrapped_server; - g_assert (this_arg); - k = mono_object_class (this_arg); - } + /* If this is a proxy, then it must be a CBO */ + if (mono_class_is_transparent_proxy (k)) { + MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg; + this_arg = tp->rp->unwrapped_server; + g_assert (this_arg); + k = mono_object_class (this_arg); + } - name = mono_array_get (params, MonoString *, 1); - str = mono_string_to_utf8_checked (name, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + name = mono_array_get (params, MonoString *, 1); + str = mono_string_to_utf8_checked (name, error); + return_if_nok (error); - do { - MonoClassField* field = mono_class_get_field_from_name (k, str); - if (field) { - g_free (str); - MonoClass *field_klass = mono_class_from_mono_type (field->type); - MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2); - - if (field_klass->valuetype) { - size = mono_type_size (field->type, &align); - g_assert (size == mono_class_value_size (field_klass, NULL)); - mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass); - } else { - mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val); - } - - out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; - mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args); + do { + MonoClassField* field = mono_class_get_field_from_name (k, str); + if (field) { + g_free (str); + MonoClass *field_klass = mono_class_from_mono_type (field->type); + MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2); - return NULL; - } + if (field_klass->valuetype) { + size = mono_type_size (field->type, &align); + g_assert (size == mono_class_value_size (field_klass, NULL)); + mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass); + } else { + mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val); + } + + out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, error); + return_if_nok (error); + mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args); + return; + } - k = k->parent; - } while (k); + k = k->parent; + } while (k); - g_free (str); - g_assert_not_reached (); + g_free (str); + g_assert_not_reached (); +} + +ICALL_EXPORT MonoObject * +ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs) +{ + MonoError error; + MonoDomain *domain = mono_object_domain (method); + MonoMethod *m = method->method; + MonoMethodSignature *sig = mono_method_signature (m); + MonoArray *out_args; + MonoObject *result; + int i, j, outarg_count = 0; + if (m->klass == mono_defaults.object_class) { + if (!strcmp (m->name, "FieldGetter")) { + internal_execute_field_getter (domain, this_arg, params, outArgs, &error); + mono_error_set_pending_exception (&error); + return NULL; + } else if (!strcmp (m->name, "FieldSetter")) { + internal_execute_field_setter (domain, this_arg, params, outArgs, &error); + mono_error_set_pending_exception (&error); + return NULL; } } @@ -5403,7 +5471,7 @@ image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int t 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 (); @@ -6168,99 +6236,92 @@ ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type, MonoEr return mono_type_get_object_handle (domain, &pklass->byval_arg, error); } -ICALL_EXPORT MonoObject * -ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target, - MonoReflectionMethod *info, MonoBoolean throwOnBindFailure) +ICALL_EXPORT MonoObjectHandle +ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionTypeHandle ref_type, MonoObjectHandle target, + MonoReflectionMethodHandle info, MonoBoolean throwOnBindFailure, MonoError *error) { - MonoError error; - MonoClass *delegate_class = mono_class_from_mono_type (type->type); - MonoObject *delegate; + MonoType *type = MONO_HANDLE_GETVAL (ref_type, type); + MonoClass *delegate_class = mono_class_from_mono_type (type); gpointer func; - MonoMethod *method = info->method; + MonoMethod *method = MONO_HANDLE_GETVAL (info, method); MonoMethodSignature *sig = mono_method_signature(method); - mono_class_init_checked (delegate_class, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + mono_class_init_checked (delegate_class, error); + return_val_if_nok (error, NULL_HANDLE); if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) { /* FIXME improve this exception message */ - mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__, + mono_error_set_execution_engine (error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__, __func__, "delegate_class->parent == mono_defaults.multicastdelegate_class"); - mono_error_set_pending_exception (&error); - return NULL; + return NULL_HANDLE; } if (mono_security_core_clr_enabled ()) { - if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) { + MonoError security_error; + if (!mono_security_core_clr_ensure_delegate_creation (method, &security_error)) { if (throwOnBindFailure) - mono_error_set_pending_exception (&error); + mono_error_move (error, &security_error); else - mono_error_cleanup (&error); - return NULL; + mono_error_cleanup (&security_error); + return NULL_HANDLE; } } if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) { if (!method->is_inflated) { - mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type")); - return NULL; + mono_error_set_argument (error, "method", " Cannot bind to the target method because its signature differs from that of the delegate type"); + return NULL_HANDLE; } } - delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + MonoObjectHandle delegate = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (MONO_HANDLE_DOMAIN (ref_type), delegate_class, error)); + return_val_if_nok (error, NULL_HANDLE); if (method_is_dynamic (method)) { /* Creating a trampoline would leak memory */ - func = mono_compile_method_checked (method, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + func = mono_compile_method_checked (method, error); + return_val_if_nok (error, NULL_HANDLE); } else { - if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target)) - method = mono_object_get_virtual_method (target, method); - gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + if (!MONO_HANDLE_IS_NULL (target) && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_handle_class (target)) { + method = mono_object_handle_get_virtual_method (target, method, error); + return_val_if_nok (error, NULL_HANDLE); + } + gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, error); + return_val_if_nok (error, NULL_HANDLE); func = mono_create_ftnptr (mono_domain_get (), trampoline); } - mono_delegate_ctor_with_method (delegate, target, func, method, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + mono_delegate_ctor_with_method (delegate, target, func, method, error); + return_val_if_nok (error, NULL_HANDLE); return delegate; } -ICALL_EXPORT MonoMulticastDelegate * -ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate) +ICALL_EXPORT MonoMulticastDelegateHandle +ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegateHandle delegate, MonoError *error) { - MonoError error; - MonoMulticastDelegate *ret; + error_init (error); - g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class)); + MonoClass *klass = mono_handle_class (delegate); + g_assert (mono_class_has_parent (klass, mono_defaults.multicastdelegate_class)); - ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + MonoMulticastDelegateHandle ret = MONO_HANDLE_NEW (MonoMulticastDelegate, mono_object_new_checked (MONO_HANDLE_DOMAIN (delegate), klass, error)); + return_val_if_nok (error, MONO_HANDLE_CAST (MonoMulticastDelegate, NULL_HANDLE)); - ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate)); + MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoDelegate, ret), invoke_impl, gpointer, mono_runtime_create_delegate_trampoline (klass)); return ret; } -ICALL_EXPORT MonoReflectionMethod* -ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate) +ICALL_EXPORT MonoReflectionMethodHandle +ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegateHandle delegate, MonoError *error) { - MonoReflectionMethod *ret = NULL; - MonoError error; - MonoMethod *m; + error_init (error); - m = mono_object_get_virtual_method (delegate->target, delegate->method); - ret = mono_method_get_object_checked (mono_domain_get (), m, m->klass, &error); - mono_error_set_pending_exception (&error); - return ret; + MonoObjectHandle delegate_target = MONO_HANDLE_NEW_GET (MonoObject, delegate, target); + MonoMethod *m = mono_object_handle_get_virtual_method (delegate_target, MONO_HANDLE_GETVAL (delegate, method), error); + return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE)); + return mono_method_get_object_handle (mono_domain_get (), m, m->klass, error); } /* System.Buffer */ @@ -6668,11 +6729,6 @@ ves_icall_System_Environment_Exit (int result) { mono_environment_exitcode_set (result); -/* FIXME: There are some cleanup hangs that should be worked out, but - * if the program is going to exit, everything will be cleaned up when - * NaCl exits anyway. - */ -#ifndef __native_client__ if (!mono_runtime_try_shutdown ()) mono_thread_exit (); @@ -6680,7 +6736,6 @@ ves_icall_System_Environment_Exit (int result) mono_thread_suspend_all_other_threads (); mono_runtime_quit (); -#endif /* we may need to do some cleanup here... */ exit (result); @@ -6916,54 +6971,56 @@ ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void) #ifndef DISABLE_REMOTING ICALL_EXPORT MonoBoolean -ves_icall_IsTransparentProxy (MonoObject *proxy) +ves_icall_IsTransparentProxy (MonoObjectHandle proxy, MonoError *error) { - if (!proxy) + error_init (error); + if (MONO_HANDLE_IS_NULL (proxy)) return 0; - if (mono_object_is_transparent_proxy (proxy)) + if (mono_class_is_transparent_proxy (mono_handle_class (proxy))) return 1; return 0; } -ICALL_EXPORT MonoReflectionMethod * +ICALL_EXPORT MonoReflectionMethodHandle ves_icall_Remoting_RemotingServices_GetVirtualMethod ( - MonoReflectionType *rtype, MonoReflectionMethod *rmethod) + MonoReflectionTypeHandle rtype, MonoReflectionMethodHandle rmethod, MonoError *error) { - MonoReflectionMethod *ret = NULL; - MonoError error; - - MonoClass *klass; - MonoMethod *method; - MonoMethod **vtable; - MonoMethod *res = NULL; + MonoReflectionMethodHandle ret = MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE); - MONO_CHECK_ARG_NULL (rtype, NULL); - MONO_CHECK_ARG_NULL (rmethod, NULL); + error_init (error); + if (MONO_HANDLE_IS_NULL (rtype)) { + mono_error_set_argument_null (error, "type", ""); + return ret; + } + if (MONO_HANDLE_IS_NULL (rmethod)) { + mono_error_set_argument_null (error, "method", ""); + return ret; + } - method = rmethod->method; - klass = mono_class_from_mono_type (rtype->type); - mono_class_init_checked (klass, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + MonoMethod *method = MONO_HANDLE_GETVAL (rmethod, method); + MonoType *type = MONO_HANDLE_GETVAL (rtype, type); + MonoClass *klass = mono_class_from_mono_type (type); + mono_class_init_checked (klass, error); + return_val_if_nok (error, ret); if (MONO_CLASS_IS_INTERFACE (klass)) - return NULL; + return ret; if (method->flags & METHOD_ATTRIBUTE_STATIC) - return NULL; + return ret; if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) { if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)) - return rmethod; - else - return NULL; + ret = rmethod; + return ret; } mono_class_setup_vtable (klass); - vtable = klass->vtable; + MonoMethod **vtable = klass->vtable; + MonoMethod *res = NULL; if (mono_class_is_interface (method->klass)) { gboolean variance_used = FALSE; /*MS fails with variant interfaces but it's the right thing to do anyway.*/ @@ -6972,33 +7029,27 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod ( res = vtable [offs + method->slot]; } else { if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))) - return NULL; + return ret; if (method->slot != -1) res = vtable [method->slot]; } if (!res) - return NULL; + return ret; - ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error); - mono_error_set_pending_exception (&error); + ret = mono_method_get_object_handle (mono_domain_get (), res, NULL, error); return ret; } ICALL_EXPORT void -ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable) +ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionTypeHandle type, MonoBoolean enable, MonoError *error) { - MonoError error; - MonoClass *klass; - MonoVTable* vtable; + error_init (error); - klass = mono_class_from_mono_type (type->type); - vtable = mono_class_vtable_full (mono_domain_get (), klass, &error); - if (!is_ok (&error)) { - mono_error_set_pending_exception (&error); - return; - } + MonoClass *klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (type, type)); + MonoVTable *vtable = mono_class_vtable_full (mono_domain_get (), klass, error); + return_if_nok (error); mono_vtable_set_is_remote (vtable, enable); } @@ -7006,48 +7057,38 @@ ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (Mo #else /* DISABLE_REMOTING */ ICALL_EXPORT void -ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable) +ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionTypeHandle type, MonoBoolean enable, MonoError *error) { + error_init (error); g_assert_not_reached (); } #endif -ICALL_EXPORT MonoObject * -ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type) +ICALL_EXPORT MonoObjectHandle +ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionTypeHandle type, MonoError *error) { - MonoError error; - MonoClass *klass; - MonoDomain *domain; - MonoObject *ret; + error_init (error); - domain = mono_object_domain (type); - klass = mono_class_from_mono_type (type->type); - mono_class_init_checked (klass, &error); - if (mono_error_set_pending_exception (&error)) - return NULL; + MonoDomain *domain = MONO_HANDLE_DOMAIN (type); + MonoClass *klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (type, type)); + mono_class_init_checked (klass, error); + return_val_if_nok (error, NULL_HANDLE); if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) { - mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated")); - return NULL; + mono_error_set_argument (error, "type", "Type cannot be instantiated"); + return NULL_HANDLE; } if (klass->rank >= 1) { g_assert (klass->rank == 1); - ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error); - mono_error_set_pending_exception (&error); - return ret; + return MONO_HANDLE_CAST (MonoObject, mono_array_new_handle (domain, klass->element_class, 0, error)); } else { - MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error); - if (!is_ok (&error)) { - mono_error_set_pending_exception (&error); - return NULL; - } - /* Bypass remoting object creation check */ - ret = mono_object_new_alloc_specific_checked (vtable, &error); - mono_error_set_pending_exception (&error); + MonoVTable *vtable = mono_class_vtable_full (domain, klass, error); + return_val_if_nok (error, NULL_HANDLE); - return ret; + /* Bypass remoting object creation check */ + return MONO_HANDLE_NEW (MonoObject, mono_object_new_alloc_specific_checked (vtable, error)); } } @@ -7371,12 +7412,6 @@ mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter) iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1)); #endif res.value = iter->args; -#if defined(__native_client__) && SIZEOF_REGISTER == 8 - /* Values are stored as 8 byte register sized objects, but 'value' - * is dereferenced as a pointer in other routines. - */ - res.value = (char*)res.value + 4; -#endif #if G_BYTE_ORDER != G_LITTLE_ENDIAN if (arg_size <= sizeof (gpointer)) { int dummy; @@ -7506,38 +7541,34 @@ prelink_method (MonoMethod *method, MonoError *error) return; mono_lookup_pinvoke_call (method, &exc_class, &exc_arg); if (exc_class) { - mono_error_set_exception_instance (error, - mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg)); + mono_error_set_generic_error (error, "System", exc_class, "%s", exc_arg); return; } /* create the wrapper, too? */ } ICALL_EXPORT void -ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method) +ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethodHandle method, MonoError *error) { - MonoError error; + error_init (error); - prelink_method (method->method, &error); - mono_error_set_pending_exception (&error); + prelink_method (MONO_HANDLE_GETVAL (method, method), error); } ICALL_EXPORT void -ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type) +ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionTypeHandle type, MonoError *error) { - MonoError error; - MonoClass *klass = mono_class_from_mono_type (type->type); + error_init (error); + MonoClass *klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (type, type)); MonoMethod* m; gpointer iter = NULL; - mono_class_init_checked (klass, &error); - if (mono_error_set_pending_exception (&error)) - return; + mono_class_init_checked (klass, error); + return_if_nok (error); while ((m = mono_class_get_methods (klass, &iter))) { - prelink_method (m, &error); - if (mono_error_set_pending_exception (&error)) - return; + prelink_method (m, error); + return_if_nok (error); } } @@ -7841,7 +7872,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAdd } 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;