Merge pull request #5560 from kumpera/wasm-work-p3
[mono.git] / mono / metadata / icall.c
index 81800743bdf3605b626ea086f451ba16b6462db5..f55ed1f1847600caf96c9aced596651945e01320 100644 (file)
@@ -119,7 +119,7 @@ static GENERATE_GET_CLASS_WITH_CACHE (event_info, "System.Reflection", "EventInf
 static GENERATE_GET_CLASS_WITH_CACHE (module, "System.Reflection", "Module")
 
 static void
-array_set_value_impl (MonoArray *arr, MonoObject *value, guint32 pos, MonoError *error);
+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);
@@ -223,16 +223,14 @@ 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)
 {
-       MonoError error;
-       error_init (&error);
-       array_set_value_impl (arr, value, pos, &error);
-       mono_error_set_pending_exception (&error);
+       error_init (error);
+       array_set_value_impl (arr, value, pos, error);
 }
 
 static void
-array_set_value_impl (MonoArray *arr, MonoObject *value, guint32 pos, MonoError *error)
+array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error)
 {
        MonoClass *ac, *vc, *ec;
        gint32 esize, vsize;
@@ -243,26 +241,28 @@ array_set_value_impl (MonoArray *arr, MonoObject *value, guint32 pos, MonoError
        gint64 i64 = 0;
        gdouble r64 = 0;
 
+       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);
+               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);
                goto leave;
        }
@@ -319,29 +319,34 @@ array_set_value_impl (MonoArray *arr, MonoObject *value, guint32 pos, MonoError
                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 (!is_ok (error))
-                       goto leave;
                if (!castOk)
                        INVALID_CAST;
-               mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
+               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);
+                       mono_gc_memmove_atomic (ea, va, esize);
+               mono_gchandle_free (value_gchandle);
+               value_gchandle = 0;
                goto leave;
        }
-       if (!is_ok (error))
-               goto leave;
 
        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;
@@ -517,57 +522,70 @@ array_set_value_impl (MonoArray *arr, MonoObject *value, guint32 pos, MonoError
 #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)
 {
-       MonoError error;
+       MonoArrayBounds dim;
        MonoClass *ac, *ic;
-       gint32 i, pos, *ind;
+       gint32 idx;
+       gint32 i, pos;
 
-       MONO_CHECK_ARG_NULL (idxs,);
+       error_init (error);
 
-       error_init (&error);
+       if (MONO_HANDLE_IS_NULL (idxs)) {
+               mono_error_set_argument_null (error, "idxs", "");
+               return;
+       }
 
-       ic = idxs->obj.vtable->klass;
-       ac = arr->obj.vtable->klass;
+       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;
                }
 
-               array_set_value_impl (arr, value, *ind, &error);
-               mono_error_set_pending_exception (&error);
+               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;
 
-       array_set_value_impl (arr, value, pos, &error);
-       mono_error_set_pending_exception (&error);
+       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 *
@@ -996,7 +1014,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStac
 {
 #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;
@@ -1238,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
@@ -5447,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 ();
@@ -7848,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;