[appdomain] Use coop handles for most methods in System.AppDomain (#4286)
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Wed, 25 Jan 2017 18:53:46 +0000 (13:53 -0500)
committerGitHub <noreply@github.com>
Wed, 25 Jan 2017 18:53:46 +0000 (13:53 -0500)
* [runtime] Use coop handles for ves_icall_System_AppDomain_GetData

* [runtime] Add mono_string_new_utf16_handle function that returns a MonoStringHandle

* [runtime] Use coop handles for ves_icall_System_AppDomain_InternalGetProcessGuid

* [runtime] Use coop handles for System.AppDomain icalls

  - ves_icall_System_AppDomain_InternalIsFinalizingForUnload
  - ves_icall_System_AppDomain_InternalPushDomainRef
  - ves_icall_System_AppDomain_InternalPushDomainRefByID
    (This one is slightly non-trivial because we switch from MonoException to MonoError)
  - ves_icall_System_AppDomain_InternalPopDomainRef
  - ves_icall_System_AppDomain_InternalSetDomainByID

* [runtime] Use coop handles for ves_icall_System_AppDomain_InternalSetDomain

* [runtime] Use coop handles for ves_icall_System_AppDomain_SetData

* [runtime] Coop handles for some AppDomain icalls

  - ves_icall_System_AppDomain_getCurDomain
  - ves_icall_System_AppDomain_getFriendlyName
  - ves_icall_System_AppDomain_getRootDomain
  - ves_icall_System_AppDomain_getSetup

* [coop handles] Add mono_string_handle_length function

* [marshal] Add mono_marshal_xdomain_copy_value_handle

* [coop handles] Add mono_aray_new_full_handle

* [appdomain] Use handles in mono_array_clone_in_domain

* [runtime] Use coop handles for ves_icall_System_AppDomain_createDomain

* [appdomain] Use coop handles for ves_icall_System_AppDomain_InternalUnload

mono/metadata/appdomain-icalls.h
mono/metadata/appdomain.c
mono/metadata/appdomain.h
mono/metadata/handle.c
mono/metadata/handle.h
mono/metadata/icall-def.h
mono/metadata/marshal-internals.h
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/remoting.c

index a0687a43c0c1f1931bcbfd0e4fcf53809efe6707..63e17e2dded29093b2e5fc254b5a9af500013179 100644 (file)
 #include <mono/metadata/handle.h>
 #include <mono/metadata/object-internals.h>
 
-MonoAppDomain *
-ves_icall_System_AppDomain_getCurDomain            (void);
+MonoAppDomainHandle
+ves_icall_System_AppDomain_getCurDomain            (MonoError *error);
 
-MonoAppDomain *
-ves_icall_System_AppDomain_getRootDomain           (void);
+MonoAppDomainHandle
+ves_icall_System_AppDomain_getRootDomain           (MonoError *error);
 
-MonoAppDomain *
-ves_icall_System_AppDomain_createDomain            (MonoString         *friendly_name,
-                                                   MonoAppDomainSetup *setup);
+MonoAppDomainHandle
+ves_icall_System_AppDomain_createDomain            (MonoStringHandle         friendly_name,
+                                                   MonoAppDomainSetupHandle setup,
+                                                   MonoError                *error);
 
-MonoObject *
-ves_icall_System_AppDomain_GetData                 (MonoAppDomain *ad, 
-                                                   MonoString    *name);
+MonoObjectHandle
+ves_icall_System_AppDomain_GetData                 (MonoAppDomainHandle ad, 
+                                                   MonoStringHandle    name,
+                                                   MonoError*          error);
 
 MonoReflectionAssemblyHandle
 ves_icall_System_AppDomain_LoadAssemblyRaw         (MonoAppDomainHandle ad,
@@ -34,15 +36,18 @@ ves_icall_System_AppDomain_LoadAssemblyRaw         (MonoAppDomainHandle ad,
                                                    MonoError *error);
 
 void
-ves_icall_System_AppDomain_SetData                 (MonoAppDomain *ad, 
-                                                   MonoString    *name, 
-                                                   MonoObject    *data);
+ves_icall_System_AppDomain_SetData                 (MonoAppDomainHandle ad, 
+                                                   MonoStringHandle    name, 
+                                                   MonoObjectHandle    data,
+                                                   MonoError           *error);
 
-MonoAppDomainSetup *
-ves_icall_System_AppDomain_getSetup                (MonoAppDomain *ad);
+MonoAppDomainSetupHandle
+ves_icall_System_AppDomain_getSetup                (MonoAppDomainHandle ad,
+                                                   MonoError *error);
 
-MonoString *
-ves_icall_System_AppDomain_getFriendlyName         (MonoAppDomain *ad);
+MonoStringHandle
+ves_icall_System_AppDomain_getFriendlyName         (MonoAppDomainHandle ad,
+                                                   MonoError *error);
 
 MonoArrayHandle
 ves_icall_System_AppDomain_GetAssemblies           (MonoAppDomainHandle ad,
@@ -62,10 +67,11 @@ ves_icall_System_AppDomain_LoadAssembly            (MonoAppDomainHandle ad,
                                                    MonoError *error);
 
 gboolean
-ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id);
+ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id, MonoError *error);
 
 void
-ves_icall_System_AppDomain_InternalUnload          (gint32 domain_id);
+ves_icall_System_AppDomain_InternalUnload          (gint32 domain_id,
+                                                   MonoError *error);
 
 void
 ves_icall_System_AppDomain_DoUnhandledException (MonoException *exc);
@@ -76,20 +82,20 @@ ves_icall_System_AppDomain_ExecuteAssembly         (MonoAppDomainHandle ad,
                                                    MonoArrayHandle args,
                                                    MonoError *error);
 
-MonoAppDomain * 
-ves_icall_System_AppDomain_InternalSetDomain      (MonoAppDomain *ad);
+MonoAppDomainHandle
+ves_icall_System_AppDomain_InternalSetDomain      (MonoAppDomainHandle ad, MonoError *error);
 
-MonoAppDomain * 
-ves_icall_System_AppDomain_InternalSetDomainByID   (gint32 domainid);
+MonoAppDomainHandle
+ves_icall_System_AppDomain_InternalSetDomainByID   (gint32 domainid, MonoError *error);
 
 void
-ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomain *ad);
+ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomainHandle ad, MonoError *error);
 
 void
-ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id);
+ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id, MonoError *error);
 
 void
-ves_icall_System_AppDomain_InternalPopDomainRef (void);
+ves_icall_System_AppDomain_InternalPopDomainRef (MonoError *error);
 
 MonoAppContext * 
 ves_icall_System_AppDomain_InternalGetContext      (void);
@@ -103,8 +109,8 @@ ves_icall_System_AppDomain_InternalSetContext          (MonoAppContext *mc);
 gint32 
 ves_icall_System_AppDomain_GetIDFromDomain (MonoAppDomain * ad);
 
-MonoString *
-ves_icall_System_AppDomain_InternalGetProcessGuid (MonoString* newguid);
+MonoStringHandle
+ves_icall_System_AppDomain_InternalGetProcessGuid (MonoStringHandle newguid, MonoError *error);
 
 MonoBoolean
 ves_icall_System_CLRConfig_CheckThrowUnobservedTaskExceptions (void);
index dc17ecc71c06a5786d8ee68ab4dd8cc402998ec2..d7abbb593f38e6bb8959f5b59c667f750865e7a0 100644 (file)
@@ -47,6 +47,7 @@
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/mono-gc.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/marshal-internals.h>
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-debug-debugger.h>
@@ -117,8 +118,12 @@ mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data);
 static void
 add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *hash);
 
-static MonoAppDomain *
-mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup, MonoError *error);
+static MonoAppDomainHandle
+mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetupHandle setup, MonoError *error);
+
+static MonoDomain *
+mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error);
+
 
 static char *
 get_shadow_assembly_location_base (MonoDomain *domain, MonoError *error);
@@ -130,6 +135,15 @@ static GENERATE_GET_CLASS_WITH_CACHE (assembly, System.Reflection, Assembly);
 
 static GENERATE_GET_CLASS_WITH_CACHE (appdomain, System, AppDomain);
 
+static MonoDomain *
+mono_domain_from_appdomain_handle (MonoAppDomainHandle appdomain);
+
+static void
+mono_error_set_appdomain_unloaded (MonoError *error)
+{
+       mono_error_set_generic_error (error, "System", "AppDomainUnloadedException", "");
+}
+
 void
 mono_install_runtime_load (MonoLoadFunc func)
 {
@@ -446,25 +460,49 @@ mono_runtime_quit ()
 MonoDomain *
 mono_domain_create_appdomain (char *friendly_name, char *configuration_file)
 {
+       HANDLE_FUNCTION_ENTER ();
        MonoError error;
-       MonoAppDomain *ad;
-       MonoAppDomainSetup *setup;
-       MonoClass *klass;
+       MonoDomain *domain = mono_domain_create_appdomain_checked (friendly_name, configuration_file, &error);
+       mono_error_cleanup (&error);
+       HANDLE_FUNCTION_RETURN_VAL (domain);
+}
 
-       klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
-       setup = (MonoAppDomainSetup *) mono_object_new_checked (mono_domain_get (), klass, &error);
-       if (!is_ok (&error))
-               goto fail;
-       setup->configuration_file = configuration_file != NULL ? mono_string_new (mono_domain_get (), configuration_file) : NULL;
+/**
+ * mono_domain_create_appdomain_checked:
+ * @friendly_name: The friendly name of the appdomain to create
+ * @configuration_file: The configuration file to initialize the appdomain with
+ * @error: Set on error.
+ * 
+ * Returns a MonoDomain initialized with the appdomain.  On failure sets @error and returns NULL.
+ */
+MonoDomain *
+mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       mono_error_init (error);
+       MonoDomain *result = NULL;
 
-       ad = mono_domain_create_appdomain_internal (friendly_name, setup, &error);
-       if (!is_ok (&error))
-               goto fail;
+       MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
+       MonoAppDomainSetupHandle setup = MONO_HANDLE_NEW (MonoAppDomainSetup, mono_object_new_checked (mono_domain_get (), klass, error));
+       if (!is_ok (error))
+               goto leave;
+       MonoStringHandle config_file;
+       if (configuration_file != NULL) {
+               config_file = mono_string_new_handle (mono_domain_get (), configuration_file, error);
+               if (!is_ok (error))
+                       goto leave;
+       } else {
+               config_file = MONO_HANDLE_NEW (MonoString, NULL);
+       }
+       MONO_HANDLE_SET (setup, configuration_file, config_file);
 
-       return mono_domain_from_appdomain (ad);
-fail:
-       mono_error_cleanup (&error);
-       return NULL;
+       MonoAppDomainHandle ad = mono_domain_create_appdomain_internal (friendly_name, setup, error);
+       if (!is_ok (error))
+               goto leave;
+
+       result = mono_domain_from_appdomain_handle (ad);
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (result);
 }
 
 /**
@@ -486,65 +524,77 @@ mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *co
        MONO_OBJECT_SETREF (domain->setup, configuration_file, mono_string_new (domain, config_file_name));
 }
 
-static MonoAppDomainSetup*
-copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup, MonoError *error)
+static MonoAppDomainSetupHandle
+copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetupHandle setup, MonoError *error)
 {
+       HANDLE_FUNCTION_ENTER ();
        MonoDomain *caller_domain;
        MonoClass *ads_class;
-       MonoAppDomainSetup *copy;
+       MonoAppDomainSetupHandle result = MONO_HANDLE_NEW (MonoAppDomainSetup, NULL);
 
        mono_error_init (error);
 
        caller_domain = mono_domain_get ();
        ads_class = mono_class_load_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
 
-       copy = (MonoAppDomainSetup*)mono_object_new_checked (domain, ads_class, error);
-       return_val_if_nok (error, NULL);
+       MonoAppDomainSetupHandle copy = MONO_HANDLE_NEW (MonoAppDomainSetup, mono_object_new_checked (domain, ads_class, error));
+       if (!is_ok (error))
+               goto leave;
 
        mono_domain_set_internal (domain);
 
-#define XCOPY_FIELD(dst,field,src,error)                                       \
+#define XCOPY_FIELD(dst,field,src,error)                               \
        do {                                                            \
-               MonoObject *copied_val = mono_marshal_xdomain_copy_value ((MonoObject*)(src), error); \
-               return_val_if_nok (error, NULL);                        \
-               MONO_OBJECT_SETREF ((dst),field,copied_val);            \
+               MonoObjectHandle src_val = MONO_HANDLE_NEW_GET (MonoObject, (src), field); \
+               MonoObjectHandle copied_val = mono_marshal_xdomain_copy_value_handle (src_val, error); \
+               if (!is_ok (error))                                     \
+                       goto leave;                                     \
+               MONO_HANDLE_SET ((dst),field,copied_val);               \
        } while (0)
 
-       XCOPY_FIELD (copy, application_base, setup->application_base, error);
-       XCOPY_FIELD (copy, application_name, setup->application_name, error);
-       XCOPY_FIELD (copy, cache_path, setup->cache_path, error);
-       XCOPY_FIELD (copy, configuration_file, setup->configuration_file, error);
-       XCOPY_FIELD (copy, dynamic_base, setup->dynamic_base, error);
-       XCOPY_FIELD (copy, license_file, setup->license_file, error);
-       XCOPY_FIELD (copy, private_bin_path, setup->private_bin_path, error);
-       XCOPY_FIELD (copy, private_bin_path_probe, setup->private_bin_path_probe, error);
-       XCOPY_FIELD (copy, shadow_copy_directories, setup->shadow_copy_directories, error);
-       XCOPY_FIELD (copy, shadow_copy_files, setup->shadow_copy_files, error);
-       copy->publisher_policy = setup->publisher_policy;
-       copy->path_changed = setup->path_changed;
-       copy->loader_optimization = setup->loader_optimization;
-       copy->disallow_binding_redirects = setup->disallow_binding_redirects;
-       copy->disallow_code_downloads = setup->disallow_code_downloads;
-       XCOPY_FIELD (copy, domain_initializer_args, setup->domain_initializer_args, error);
-       copy->disallow_appbase_probe = setup->disallow_appbase_probe;
-       XCOPY_FIELD (copy, application_trust, setup->application_trust, error);
-       XCOPY_FIELD (copy, configuration_bytes, setup->configuration_bytes, error);
-       XCOPY_FIELD (copy, serialized_non_primitives, setup->serialized_non_primitives, error);
-
-#undef COPY_FIELD
+#define COPY_VAL(dst,field,type,src)                                   \
+               do {                                                    \
+                       MONO_HANDLE_SETVAL ((dst), field, type, MONO_HANDLE_GETVAL ((src),field)); \
+               } while (0)
+
+       XCOPY_FIELD (copy, application_base, setup, error);
+       XCOPY_FIELD (copy, application_name, setup, error);
+       XCOPY_FIELD (copy, cache_path, setup, error);
+       XCOPY_FIELD (copy, configuration_file, setup, error);
+       XCOPY_FIELD (copy, dynamic_base, setup, error);
+       XCOPY_FIELD (copy, license_file, setup, error);
+       XCOPY_FIELD (copy, private_bin_path, setup, error);
+       XCOPY_FIELD (copy, private_bin_path_probe, setup, error);
+       XCOPY_FIELD (copy, shadow_copy_directories, setup, error);
+       XCOPY_FIELD (copy, shadow_copy_files, setup, error);
+       COPY_VAL (copy, publisher_policy, MonoBoolean, setup);
+       COPY_VAL (copy, path_changed, MonoBoolean, setup);
+       COPY_VAL (copy, loader_optimization, int, setup);
+       COPY_VAL (copy, disallow_binding_redirects, MonoBoolean, setup);
+       COPY_VAL (copy, disallow_code_downloads, MonoBoolean, setup);
+       XCOPY_FIELD (copy, domain_initializer_args, setup, error);
+       COPY_VAL (copy, disallow_appbase_probe, MonoBoolean, setup);
+       XCOPY_FIELD (copy, application_trust, setup, error);
+       XCOPY_FIELD (copy, configuration_bytes, setup, error);
+       XCOPY_FIELD (copy, serialized_non_primitives, setup, error);
+
+#undef XCOPY_FIELD
+#undef COPY_VAL
        
        mono_domain_set_internal (caller_domain);
 
-       return copy;
+       MONO_HANDLE_ASSIGN (result, copy);
+leave:
+       HANDLE_FUNCTION_RETURN_REF (MonoAppDomainSetup, result);
 }
 
-static MonoAppDomain *
-mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *setup, MonoError *error)
+static MonoAppDomainHandle
+mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetupHandle setup, MonoError *error)
 {
+       HANDLE_FUNCTION_ENTER ();
+       MonoAppDomainHandle result = MONO_HANDLE_NEW (MonoAppDomain, NULL);
        MonoClass *adclass;
-       MonoAppDomain *ad;
        MonoDomain *data;
-       char *shadow_location;
 
        mono_error_init (error);
 
@@ -553,31 +603,42 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        /* FIXME: pin all those objects */
        data = mono_domain_create();
 
-       ad = (MonoAppDomain *) mono_object_new_checked (data, adclass, error);
-       return_val_if_nok (error, NULL);
-       ad->data = data;
-       data->domain = ad;
+       MonoAppDomainHandle ad = MONO_HANDLE_NEW (MonoAppDomain,  mono_object_new_checked (data, adclass, error));
+       if (!is_ok (error))
+               goto leave;
+       MONO_HANDLE_SETVAL (ad, data, MonoDomain*, data);
+       data->domain = MONO_HANDLE_RAW (ad);
        data->friendly_name = g_strdup (friendly_name);
 
        mono_profiler_appdomain_name (data, data->friendly_name);
 
-       if (!setup->application_base) {
+       MonoStringHandle app_base = MONO_HANDLE_NEW_GET (MonoString, setup, application_base);
+       if (MONO_HANDLE_IS_NULL (app_base)) {
                /* Inherit from the root domain since MS.NET does this */
                MonoDomain *root = mono_get_root_domain ();
-               if (root->setup->application_base) {
-                       MonoString *s = mono_string_new_utf16_checked (data, mono_string_chars (root->setup->application_base), mono_string_length (root->setup->application_base), error);
-                       mono_error_assert_ok (error); /* FIXME don't swallow the error */
-                       MONO_OBJECT_SETREF (setup, application_base, s);
+               MonoAppDomainSetupHandle root_setup = MONO_HANDLE_NEW (MonoAppDomainSetup, root->setup);
+               MonoStringHandle root_app_base = MONO_HANDLE_NEW_GET (MonoString, root_setup, application_base);
+               if (!MONO_HANDLE_IS_NULL (root_app_base)) {
+                       /* N.B. new string is in the new domain */
+                       uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, root_app_base), TRUE);
+                       MonoStringHandle s = mono_string_new_utf16_handle (data, mono_string_chars (MONO_HANDLE_RAW (root_app_base)), mono_string_handle_length (root_app_base), error);
+                       mono_gchandle_free (gchandle);
+                       if (!is_ok (error)) {
+                               g_free (data->friendly_name);
+                               goto leave;
+                       }
+                       MONO_HANDLE_SET (setup, application_base, s);
                }
        }
 
        mono_context_init_checked (data, error);
-       return_val_if_nok (error, NULL);
+       if (!is_ok (error))
+               goto leave;
 
-       data->setup = copy_app_domain_setup (data, setup, error);
+       data->setup = MONO_HANDLE_RAW (copy_app_domain_setup (data, setup, error));
        if (!mono_error_ok (error)) {
                g_free (data->friendly_name);
-               return NULL;
+               goto leave;
        }
 
        mono_domain_set_options_from_config (data);
@@ -585,10 +646,10 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
 
 #ifndef DISABLE_SHADOW_COPY
        /*FIXME, guard this for when the debugger is not running */
-       shadow_location = get_shadow_assembly_location_base (data, error);
+       char *shadow_location = get_shadow_assembly_location_base (data, error);
        if (!mono_error_ok (error)) {
                g_free (data->friendly_name);
-               return NULL;
+               goto leave;
        }
 
        g_free (shadow_location);
@@ -596,7 +657,9 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
 
        create_domain_objects (data);
 
-       return ad;
+       MONO_HANDLE_ASSIGN (result, ad);
+leave:
+       HANDLE_FUNCTION_RETURN_REF (MonoAppDomain, result);
 }
 
 /**
@@ -717,106 +780,113 @@ mono_domain_set (MonoDomain *domain, gboolean force)
        return TRUE;
 }
 
-MonoObject *
-ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name)
+MonoObjectHandle
+ves_icall_System_AppDomain_GetData (MonoAppDomainHandle ad, MonoStringHandle name, MonoError *error)
 {
-       MonoError error;
-       MonoDomain *add;
-       MonoObject *o;
-       char *str;
+       mono_error_init (error);
 
-       MONO_CHECK_ARG_NULL (name, NULL);
+       if (MONO_HANDLE_IS_NULL (name)) {
+               mono_error_set_argument_null (error, "name", "");
+               return NULL_HANDLE;
+       }
 
-       g_assert (ad);
-       add = ad->data;
+       g_assert (!MONO_HANDLE_IS_NULL (ad));
+       MonoDomain *add = MONO_HANDLE_GETVAL (ad, data);
        g_assert (add);
 
-       str = mono_string_to_utf8_checked (name, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       char *str = mono_string_handle_to_utf8 (name, error);
+       return_val_if_nok (error, NULL_HANDLE);
 
        mono_domain_lock (add);
 
+       MonoAppDomainSetupHandle ad_setup = MONO_HANDLE_NEW (MonoAppDomainSetup, add->setup);
+       MonoStringHandle o;
        if (!strcmp (str, "APPBASE"))
-               o = (MonoObject *)add->setup->application_base;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, application_base);
        else if (!strcmp (str, "APP_CONFIG_FILE"))
-               o = (MonoObject *)add->setup->configuration_file;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, configuration_file);
        else if (!strcmp (str, "DYNAMIC_BASE"))
-               o = (MonoObject *)add->setup->dynamic_base;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, dynamic_base);
        else if (!strcmp (str, "APP_NAME"))
-               o = (MonoObject *)add->setup->application_name;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, application_name);
        else if (!strcmp (str, "CACHE_BASE"))
-               o = (MonoObject *)add->setup->cache_path;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, cache_path);
        else if (!strcmp (str, "PRIVATE_BINPATH"))
-               o = (MonoObject *)add->setup->private_bin_path;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, private_bin_path);
        else if (!strcmp (str, "BINPATH_PROBE_ONLY"))
-               o = (MonoObject *)add->setup->private_bin_path_probe;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, private_bin_path_probe);
        else if (!strcmp (str, "SHADOW_COPY_DIRS"))
-               o = (MonoObject *)add->setup->shadow_copy_directories;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, shadow_copy_directories);
        else if (!strcmp (str, "FORCE_CACHE_INSTALL"))
-               o = (MonoObject *)add->setup->shadow_copy_files;
+               o = MONO_HANDLE_NEW_GET (MonoString, ad_setup, shadow_copy_files);
        else 
-               o = (MonoObject *)mono_g_hash_table_lookup (add->env, name);
+               o = MONO_HANDLE_NEW (MonoString, mono_g_hash_table_lookup (add->env, MONO_HANDLE_RAW (name)));
 
        mono_domain_unlock (add);
        g_free (str);
 
-       if (!o)
-               return NULL;
-
-       return o;
+       return MONO_HANDLE_CAST (MonoObject, o);
 }
 
 void
-ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObject *data)
+ves_icall_System_AppDomain_SetData (MonoAppDomainHandle ad, MonoStringHandle name, MonoObjectHandle data, MonoError *error)
 {
-       MonoDomain *add;
+       mono_error_init (error);
 
-       MONO_CHECK_ARG_NULL (name,);
+       if (MONO_HANDLE_IS_NULL (name)) {
+               mono_error_set_argument_null (error, "name", "");
+               return;
+       }
 
-       g_assert (ad);
-       add = ad->data;
+       g_assert (!MONO_HANDLE_IS_NULL (ad));
+       MonoDomain *add = MONO_HANDLE_GETVAL (ad, data);
        g_assert (add);
 
        mono_domain_lock (add);
 
-       mono_g_hash_table_insert (add->env, name, data);
+       mono_g_hash_table_insert (add->env, MONO_HANDLE_RAW (name), MONO_HANDLE_RAW (data));
 
        mono_domain_unlock (add);
 }
 
-MonoAppDomainSetup *
-ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
+MonoAppDomainSetupHandle
+ves_icall_System_AppDomain_getSetup (MonoAppDomainHandle ad, MonoError *error)
 {
-       g_assert (ad);
-       g_assert (ad->data);
+       mono_error_init (error);
+       g_assert (!MONO_HANDLE_IS_NULL (ad));
+       MonoDomain *domain = MONO_HANDLE_GETVAL (ad, data);
+       g_assert (domain);
 
-       return ad->data->setup;
+       return MONO_HANDLE_NEW (MonoAppDomainSetup, domain->setup);
 }
 
-MonoString *
-ves_icall_System_AppDomain_getFriendlyName (MonoAppDomain *ad)
+MonoStringHandle
+ves_icall_System_AppDomain_getFriendlyName (MonoAppDomainHandle ad, MonoError *error)
 {
-       g_assert (ad);
-       g_assert (ad->data);
+       mono_error_init (error);
+       g_assert (!MONO_HANDLE_IS_NULL (ad));
+       MonoDomain *domain = MONO_HANDLE_GETVAL (ad, data);
+       g_assert (domain);
 
-       return mono_string_new (ad->data, ad->data->friendly_name);
+       return mono_string_new_handle (domain, domain->friendly_name, error);
 }
 
-MonoAppDomain *
-ves_icall_System_AppDomain_getCurDomain ()
+MonoAppDomainHandle
+ves_icall_System_AppDomain_getCurDomain (MonoError *error)
 {
+       mono_error_init (error);
        MonoDomain *add = mono_domain_get ();
 
-       return add->domain;
+       return MONO_HANDLE_NEW (MonoAppDomain, add->domain);
 }
 
-MonoAppDomain *
-ves_icall_System_AppDomain_getRootDomain ()
+MonoAppDomainHandle
+ves_icall_System_AppDomain_getRootDomain (MonoError *error)
 {
+       mono_error_init (error);
        MonoDomain *root = mono_get_root_domain ();
 
-       return root->domain;
+       return MONO_HANDLE_NEW (MonoAppDomain, root->domain);
 }
 
 MonoBoolean
@@ -966,26 +1036,22 @@ mono_domain_set_options_from_config (MonoDomain *domain)
        g_free (config_file_path);
 }
 
-MonoAppDomain *
-ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
+MonoAppDomainHandle
+ves_icall_System_AppDomain_createDomain (MonoStringHandle friendly_name, MonoAppDomainSetupHandle setup, MonoError *error)
 {
-       MonoError error;
-       MonoAppDomain *ad = NULL;
+       mono_error_init (error);
+       MonoAppDomainHandle ad = MONO_HANDLE_NEW (MonoAppDomain, NULL);
 
 #ifdef DISABLE_APPDOMAINS
-       mono_error_init (&error);
-       mono_error_set_not_supported (&error, "AppDomain creation is not supported on this runtime.");
+       mono_error_set_not_supported (error, "AppDomain creation is not supported on this runtime.");
 #else
        char *fname;
 
-       fname = mono_string_to_utf8_checked (friendly_name, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-       ad = mono_domain_create_appdomain_internal (fname, setup, &error);
-
+       fname = mono_string_handle_to_utf8 (friendly_name, error);
+       return_val_if_nok (error, ad);
+       ad = mono_domain_create_appdomain_internal (fname, setup, error);
        g_free (fname);
 #endif
-       mono_error_set_pending_exception (&error);
        return ad;
 }
 
@@ -1805,19 +1871,35 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror)
 #endif /* DISABLE_SHADOW_COPY */
 
 MonoDomain *
-mono_domain_from_appdomain (MonoAppDomain *appdomain)
+mono_domain_from_appdomain (MonoAppDomain *appdomain_raw)
 {
-       if (appdomain == NULL)
-               return NULL;
+       HANDLE_FUNCTION_ENTER ();
+       MONO_HANDLE_DCL (MonoAppDomain, appdomain);
+       MonoDomain *result = mono_domain_from_appdomain_handle (appdomain);
+       HANDLE_FUNCTION_RETURN_VAL (result);
+}
 
-       if (mono_object_is_transparent_proxy (&appdomain->mbr.obj)) {
-               MonoTransparentProxy *tp = (MonoTransparentProxy*)appdomain;
-               return mono_domain_get_by_id (tp->rp->target_domain_id);
-       }
-       
-       return appdomain->data;
+MonoDomain *
+mono_domain_from_appdomain_handle (MonoAppDomainHandle appdomain)
+{
+       HANDLE_FUNCTION_ENTER ();
+       MonoDomain *dom = NULL;
+       if (MONO_HANDLE_IS_NULL (appdomain))
+               goto leave;
+
+       if (mono_class_is_transparent_proxy (mono_handle_class (appdomain))) {
+               MonoTransparentProxyHandle tp = MONO_HANDLE_CAST (MonoTransparentProxy, appdomain);
+               MonoRealProxyHandle rp = MONO_HANDLE_NEW_GET (MonoRealProxy, tp, rp);
+               
+               dom = mono_domain_get_by_id (MONO_HANDLE_GETVAL (rp, target_domain_id));
+       } else
+               dom = MONO_HANDLE_GETVAL (appdomain, data);
+
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (dom);
 }
 
+
 static gboolean
 try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
                                        const gchar *path3, const gchar *path4,
@@ -2108,19 +2190,18 @@ fail:
 }
 
 void
-ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
+ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error)
 {
-       MonoException *exc = NULL;
+       mono_error_init (error);
        MonoDomain * domain = mono_domain_get_by_id (domain_id);
 
        if (NULL == domain) {
-               mono_get_exception_execution_engine ("Failed to unload domain, domain id not found");
-               mono_set_pending_exception (exc);
+               mono_error_set_execution_engine (error, "Failed to unload domain, domain id not found");
                return;
        }
        
        if (domain == mono_get_root_domain ()) {
-               mono_set_pending_exception (mono_get_exception_cannot_unload_appdomain ("The default appdomain can not be unloaded."));
+               mono_error_set_generic_error (error, "System", "CannotUnloadAppDomainException", "The default appdomain can not be unloaded.");
                return;
        }
 
@@ -2134,14 +2215,16 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id)
        return;
 #endif
 
+       MonoException *exc = NULL;
        mono_domain_try_unload (domain, (MonoObject**)&exc);
        if (exc)
-               mono_set_pending_exception (exc);
+               mono_error_set_exception_instance (error, exc);
 }
 
 gboolean
-ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id)
+ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id, MonoError *error)
 {
+       mono_error_init (error);
        MonoDomain *domain = mono_domain_get_by_id (domain_id);
 
        if (!domain)
@@ -2191,42 +2274,45 @@ ves_icall_System_AppDomain_GetIDFromDomain (MonoAppDomain * ad)
        return ad->data->domain_id;
 }
 
-MonoAppDomain * 
-ves_icall_System_AppDomain_InternalSetDomain (MonoAppDomain *ad)
+MonoAppDomainHandle
+ves_icall_System_AppDomain_InternalSetDomain (MonoAppDomainHandle ad, MonoError* error)
 {
-       MonoDomain *old_domain = mono_domain_get();
+       mono_error_init (error);
+       MonoDomain *old_domain = mono_domain_get ();
 
-       if (!mono_domain_set (ad->data, FALSE)) {
-               mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
-               return NULL;
+       if (!mono_domain_set (MONO_HANDLE_GETVAL (ad, data), FALSE)) {
+               mono_error_set_appdomain_unloaded (error);
+               return MONO_HANDLE_CAST (MonoAppDomain, NULL_HANDLE);
        }
 
-       return old_domain->domain;
+       return MONO_HANDLE_NEW (MonoAppDomain, old_domain->domain);
 }
 
-MonoAppDomain * 
-ves_icall_System_AppDomain_InternalSetDomainByID (gint32 domainid)
+MonoAppDomainHandle
+ves_icall_System_AppDomain_InternalSetDomainByID (gint32 domainid, MonoError *error)
 {
        MonoDomain *current_domain = mono_domain_get ();
        MonoDomain *domain = mono_domain_get_by_id (domainid);
 
        if (!domain || !mono_domain_set (domain, FALSE)) {
-               mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
-               return NULL;
+               mono_error_set_appdomain_unloaded (error);
+               return MONO_HANDLE_CAST (MonoAppDomain, NULL_HANDLE);
        }
 
-       return current_domain->domain;
+       return MONO_HANDLE_NEW (MonoAppDomain, current_domain->domain);
 }
 
 void
-ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomain *ad)
+ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomainHandle ad, MonoError *error)
 {
-       mono_thread_push_appdomain_ref (ad->data);
+       mono_error_init (error);
+       mono_thread_push_appdomain_ref (MONO_HANDLE_GETVAL (ad, data));
 }
 
 void
-ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id)
+ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id, MonoError *error)
 {
+       mono_error_init (error);
        MonoDomain *domain = mono_domain_get_by_id (domain_id);
 
        if (!domain) {
@@ -2234,7 +2320,7 @@ ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id)
                 * Raise an exception to prevent the managed code from executing a pop
                 * later.
                 */
-               mono_set_pending_exception (mono_get_exception_appdomain_unloaded ());
+               mono_error_set_appdomain_unloaded (error);
                return;
        }
 
@@ -2242,8 +2328,9 @@ ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id)
 }
 
 void
-ves_icall_System_AppDomain_InternalPopDomainRef (void)
+ves_icall_System_AppDomain_InternalPopDomainRef (MonoError *error)
 {
+       mono_error_init (error);
        mono_thread_pop_appdomain_ref ();
 }
 
@@ -2269,20 +2356,19 @@ ves_icall_System_AppDomain_InternalSetContext (MonoAppContext *mc)
        return old_context;
 }
 
-MonoString *
-ves_icall_System_AppDomain_InternalGetProcessGuid (MonoString* newguid)
+MonoStringHandle
+ves_icall_System_AppDomain_InternalGetProcessGuid (MonoStringHandle newguid, MonoError *error)
 {
+       mono_error_init (error);
        MonoDomain* mono_root_domain = mono_get_root_domain ();
        mono_domain_lock (mono_root_domain);
        if (process_guid_set) {
                mono_domain_unlock (mono_root_domain);
-               MonoError error;
-               MonoString *res = NULL;
-               res = mono_string_new_utf16_checked (mono_domain_get (), process_guid, sizeof(process_guid)/2, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
+               return mono_string_new_utf16_handle (mono_domain_get (), process_guid, sizeof(process_guid)/2, error);
        }
-       memcpy (process_guid, mono_string_chars(newguid), sizeof(process_guid));
+       uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, newguid), TRUE);
+       memcpy (process_guid, mono_string_chars(MONO_HANDLE_RAW (newguid)), sizeof(process_guid));
+       mono_gchandle_free (gchandle);
        process_guid_set = TRUE;
        mono_domain_unlock (mono_root_domain);
        return newguid;
index ebf94234bb21b83ac59f44a776c2bc2e5d2aff47..3a4286c13192f6d0e92dce005c2d33267f95dedd 100644 (file)
@@ -99,6 +99,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc);
 MONO_API mono_bool
 mono_domain_is_unloading   (MonoDomain *domain);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoDomain *
 mono_domain_from_appdomain (MonoAppDomain *appdomain);
 
index 7df0184a31f1266a3203035a5e1fd62197d6e780..d49e2456d41620b5bb914caea0ccdb2b68f1c490 100644 (file)
@@ -239,6 +239,12 @@ mono_array_new_handle (MonoDomain *domain, MonoClass *eclass, uintptr_t n, MonoE
        return MONO_HANDLE_NEW (MonoArray, mono_array_new_checked (domain, eclass, n, error));
 }
 
+MonoArrayHandle
+mono_array_new_full_handle (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds, MonoError *error)
+{
+       return MONO_HANDLE_NEW (MonoArray, mono_array_new_full_checked (domain, array_class, lengths, lower_bounds, error));
+}
+
 #ifdef ENABLE_CHECKED_BUILD
 /* Checked build helpers */
 void
index 1271fad7518aed07d0922c0cd417aee7158936ff..01ded7c4fe8df75b00893666d518f5838323841c 100644 (file)
@@ -379,6 +379,9 @@ mono_handle_assign (MonoObjectHandleOut dest, MonoObjectHandle src)
 //FIXME this should go somewhere else
 MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error);
 MonoArrayHandle mono_array_new_handle (MonoDomain *domain, MonoClass *eclass, uintptr_t n, MonoError *error);
+MonoArrayHandle
+mono_array_new_full_handle (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds, MonoError *error);
+
 
 uintptr_t mono_array_handle_length (MonoArrayHandle arr);
 
index e6ec1e4a21d9e779e68c13cabd595e669a6c796a..ebf717d1fdd11a17458660d62d1f971385f43f65 100644 (file)
@@ -117,26 +117,26 @@ ICALL_TYPE(APPDOM, "System.AppDomain", APPDOM_23)
 ICALL(APPDOM_23, "DoUnhandledException", ves_icall_System_AppDomain_DoUnhandledException)
 HANDLES(ICALL(APPDOM_1, "ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly))
 HANDLES(ICALL(APPDOM_2, "GetAssemblies", ves_icall_System_AppDomain_GetAssemblies))
-ICALL(APPDOM_3, "GetData", ves_icall_System_AppDomain_GetData)
+HANDLES(ICALL(APPDOM_3, "GetData", ves_icall_System_AppDomain_GetData))
 ICALL(APPDOM_4, "InternalGetContext", ves_icall_System_AppDomain_InternalGetContext)
 ICALL(APPDOM_5, "InternalGetDefaultContext", ves_icall_System_AppDomain_InternalGetDefaultContext)
-ICALL(APPDOM_6, "InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid)
-ICALL(APPDOM_7, "InternalIsFinalizingForUnload", ves_icall_System_AppDomain_InternalIsFinalizingForUnload)
-ICALL(APPDOM_8, "InternalPopDomainRef", ves_icall_System_AppDomain_InternalPopDomainRef)
-ICALL(APPDOM_9, "InternalPushDomainRef", ves_icall_System_AppDomain_InternalPushDomainRef)
-ICALL(APPDOM_10, "InternalPushDomainRefByID", ves_icall_System_AppDomain_InternalPushDomainRefByID)
+HANDLES(ICALL(APPDOM_6, "InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid))
+HANDLES(ICALL(APPDOM_7, "InternalIsFinalizingForUnload", ves_icall_System_AppDomain_InternalIsFinalizingForUnload))
+HANDLES(ICALL(APPDOM_8, "InternalPopDomainRef", ves_icall_System_AppDomain_InternalPopDomainRef))
+HANDLES(ICALL(APPDOM_9, "InternalPushDomainRef", ves_icall_System_AppDomain_InternalPushDomainRef))
+HANDLES(ICALL(APPDOM_10, "InternalPushDomainRefByID", ves_icall_System_AppDomain_InternalPushDomainRefByID))
 ICALL(APPDOM_11, "InternalSetContext", ves_icall_System_AppDomain_InternalSetContext)
-ICALL(APPDOM_12, "InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain)
-ICALL(APPDOM_13, "InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID)
-ICALL(APPDOM_14, "InternalUnload", ves_icall_System_AppDomain_InternalUnload)
+HANDLES(ICALL(APPDOM_12, "InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain))
+HANDLES(ICALL(APPDOM_13, "InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID))
+HANDLES(ICALL(APPDOM_14, "InternalUnload", ves_icall_System_AppDomain_InternalUnload))
 HANDLES(ICALL(APPDOM_15, "LoadAssembly", ves_icall_System_AppDomain_LoadAssembly))
 HANDLES(ICALL(APPDOM_16, "LoadAssemblyRaw", ves_icall_System_AppDomain_LoadAssemblyRaw))
-ICALL(APPDOM_17, "SetData", ves_icall_System_AppDomain_SetData)
-ICALL(APPDOM_18, "createDomain", ves_icall_System_AppDomain_createDomain)
-ICALL(APPDOM_19, "getCurDomain", ves_icall_System_AppDomain_getCurDomain)
-ICALL(APPDOM_20, "getFriendlyName", ves_icall_System_AppDomain_getFriendlyName)
-ICALL(APPDOM_21, "getRootDomain", ves_icall_System_AppDomain_getRootDomain)
-ICALL(APPDOM_22, "getSetup", ves_icall_System_AppDomain_getSetup)
+HANDLES(ICALL(APPDOM_17, "SetData", ves_icall_System_AppDomain_SetData))
+HANDLES(ICALL(APPDOM_18, "createDomain", ves_icall_System_AppDomain_createDomain))
+HANDLES(ICALL(APPDOM_19, "getCurDomain", ves_icall_System_AppDomain_getCurDomain))
+HANDLES(ICALL(APPDOM_20, "getFriendlyName", ves_icall_System_AppDomain_getFriendlyName))
+HANDLES(ICALL(APPDOM_21, "getRootDomain", ves_icall_System_AppDomain_getRootDomain))
+HANDLES(ICALL(APPDOM_22, "getSetup", ves_icall_System_AppDomain_getSetup))
 
 ICALL_TYPE(ARGI, "System.ArgIterator", ARGI_1)
 ICALL(ARGI_1, "IntGetNextArg()",                  mono_ArgIterator_IntGetNextArg)
index 1b4ff57b84bdc01134584c0681725ed591717d8c..ea210b5fb2bdcd56dd517bfc431faa2e6e25e255 100644 (file)
@@ -9,6 +9,9 @@
 #include <glib.h>
 #include <mono/metadata/object-internals.h>
 
+MonoObjectHandle
+mono_marshal_xdomain_copy_value_handle (MonoObjectHandle val, MonoError *error);
+
 // On Windows platform implementation of bellow methods are hosted in separate source file
 // masrshal-windows.c or marshal-windows-*.c. On other platforms the implementation is still keept
 // in marshal.c still declared as static and in some places even inlined.
index 2c4780ac2330963984e52efe5e8f26ba8143ecf2..e766126d255bb096b20daf60fdec2a23d3ebbf7e 100644 (file)
@@ -171,6 +171,9 @@ struct _MonoAppDomain {
 /* Safely access System.AppDomain from native code */
 TYPED_HANDLE_DECL (MonoAppDomain);
 
+/* Safely access System.AppDomainSetup from native code.  (struct is in domain-internals.h) */
+TYPED_HANDLE_DECL (MonoAppDomainSetup);
+
 typedef struct _MonoStringBuilder MonoStringBuilder;
 
 struct _MonoStringBuilder {
@@ -1480,6 +1483,9 @@ mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const
 void
 mono_release_type_locks (MonoInternalThread *thread);
 
+int
+mono_string_handle_length (MonoStringHandle s);
+
 char *
 mono_string_handle_to_utf8 (MonoStringHandle s, MonoError *error);
 
@@ -1490,8 +1496,8 @@ char *
 mono_string_to_utf8_image (MonoImage *image, MonoStringHandle s, MonoError *error);
 
 
-MonoArray*
-mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array, MonoError *error);
+MonoArrayHandle
+mono_array_clone_in_domain (MonoDomain *domain, MonoArrayHandle array, MonoError *error);
 
 MonoArray*
 mono_array_clone_checked (MonoArray *array, MonoError *error);
@@ -1784,6 +1790,9 @@ mono_string_new_checked (MonoDomain *domain, const char *text, MonoError *merror
 MonoString *
 mono_string_new_utf16_checked (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error);
 
+MonoStringHandle
+mono_string_new_utf16_handle (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error);
+
 MonoString *
 mono_string_from_utf16_checked (mono_unichar2 *data, MonoError *error);
 
index 086d22d546ad595e02d5cedfe06af3446d9e9612..382eb9fa03e825c0ba8149e4981ec6dd38ccdc60 100644 (file)
@@ -64,6 +64,9 @@ free_main_args (void);
 static char *
 mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error);
 
+static void
+array_full_copy_unchecked_size (MonoArray *src, MonoArray *dest, MonoClass *klass, uintptr_t size);
+
 static MonoMethod*
 class_get_virtual_method (MonoClass *klass, MonoMethod *method, gboolean is_proxy, MonoError *error);
 
@@ -5603,6 +5606,13 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
        size = mono_array_length (src);
        g_assert (size == mono_array_length (dest));
        size *= mono_array_element_size (klass);
+
+       array_full_copy_unchecked_size (src, dest, klass, size);
+}
+
+static void
+array_full_copy_unchecked_size (MonoArray *src, MonoArray *dest, MonoClass *klass, uintptr_t size)
+{
 #ifdef HAVE_SGEN_GC
        if (klass->element_class->valuetype) {
                if (klass->element_class->has_references)
@@ -5626,62 +5636,51 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
  * This routine returns a copy of the array that is hosted on the
  * specified MonoDomain.  On failure returns NULL and sets @error.
  */
-MonoArray*
-mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array, MonoError *error)
+MonoArrayHandle
+mono_array_clone_in_domain (MonoDomain *domain, MonoArrayHandle array_handle, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoArray *o;
-       uintptr_t size, i;
-       uintptr_t *sizes;
-       MonoClass *klass = array->obj.vtable->klass;
+       MonoArrayHandle result = MONO_HANDLE_NEW (MonoArray, NULL);
+       uintptr_t size = 0;
+       MonoClass *klass = mono_handle_class (array_handle);
 
        mono_error_init (error);
 
-       if (array->bounds == NULL) {
-               size = mono_array_length (array);
-               o = mono_array_new_full_checked (domain, klass, &size, NULL, error);
-               return_val_if_nok (error, NULL);
-
-               size *= mono_array_element_size (klass);
-#ifdef HAVE_SGEN_GC
-               if (klass->element_class->valuetype) {
-                       if (klass->element_class->has_references)
-                               mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
-                       else
-                               mono_gc_memmove_atomic (&o->vector, &array->vector, size);
-               } else {
-                       mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
-               }
-#else
-               mono_gc_memmove_atomic (&o->vector, &array->vector, size);
-#endif
-               return o;
-       }
+       /* Pin source array here - if bounds is non-NULL, it's a pointer into the object data */
+       uint32_t src_handle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, array_handle), TRUE);
        
-       sizes = (uintptr_t *)alloca (klass->rank * sizeof(intptr_t) * 2);
-       size = mono_array_element_size (klass);
-       for (i = 0; i < klass->rank; ++i) {
-               sizes [i] = array->bounds [i].length;
-               size *= array->bounds [i].length;
-               sizes [i + klass->rank] = array->bounds [i].lower_bound;
-       }
-       o = mono_array_new_full_checked (domain, klass, sizes, (intptr_t*)sizes + klass->rank, error);
-       return_val_if_nok (error, NULL);
-#ifdef HAVE_SGEN_GC
-       if (klass->element_class->valuetype) {
-               if (klass->element_class->has_references)
-                       mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
-               else
-                       mono_gc_memmove_atomic (&o->vector, &array->vector, size);
+       MonoArrayBounds *array_bounds = MONO_HANDLE_GETVAL (array_handle, bounds);
+       MonoArrayHandle o;
+       if (array_bounds == NULL) {
+               size = mono_array_handle_length (array_handle);
+               o = mono_array_new_full_handle (domain, klass, &size, NULL, error);
+               if (!is_ok (error))
+                       goto leave;
+               size *= mono_array_element_size (klass);
        } else {
-               mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
+               uintptr_t *sizes = (uintptr_t *)alloca (klass->rank * sizeof (uintptr_t));
+               intptr_t *lower_bounds = (intptr_t *)alloca (klass->rank * sizeof (intptr_t));
+               size = mono_array_element_size (klass);
+               for (int i = 0; i < klass->rank; ++i) {
+                       sizes [i] = array_bounds [i].length;
+                       size *= array_bounds [i].length;
+                       lower_bounds [i] = array_bounds [i].lower_bound;
+               }
+               o = mono_array_new_full_handle (domain, klass, sizes, lower_bounds, error);
+               if (!is_ok (error))
+                       goto leave;
        }
-#else
-       mono_gc_memmove_atomic (&o->vector, &array->vector, size);
-#endif
 
-       return o;
+       uint32_t dst_handle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, o), TRUE);
+       array_full_copy_unchecked_size (MONO_HANDLE_RAW (array_handle), MONO_HANDLE_RAW (o), klass, size);
+       mono_gchandle_free (dst_handle);
+
+       MONO_HANDLE_ASSIGN (result, o);
+
+leave:
+       mono_gchandle_free (src_handle);
+       return result;
 }
 
 /**
@@ -5710,11 +5709,15 @@ mono_array_clone (MonoArray *array)
  * failure returns NULL and sets @error.
  */
 MonoArray*
-mono_array_clone_checked (MonoArray *array, MonoError *error)
+mono_array_clone_checked (MonoArray *array_raw, MonoError *error)
 {
-
        MONO_REQ_GC_UNSAFE_MODE;
-       return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array, error);
+       HANDLE_FUNCTION_ENTER ();
+       /* FIXME: callers of mono_array_clone_checked should use handles */
+       mono_error_init (error);
+       MONO_HANDLE_DCL (MonoArray, array);
+       MonoArrayHandle result = mono_array_clone_in_domain (MONO_HANDLE_DOMAIN (array), array, error);
+       HANDLE_FUNCTION_RETURN_OBJ (result);
 }
 
 /* helper macros to check for overflow when calculating the size of arrays */
@@ -6051,6 +6054,21 @@ mono_string_new_utf16_checked (MonoDomain *domain, const guint16 *text, gint32 l
        return s;
 }
 
+/**
+ * mono_string_new_utf16_handle:
+ * @text: a pointer to an utf16 string
+ * @len: the length of the string
+ * @error: written on error.
+ *
+ * Returns: A newly created string object which contains @text.
+ * On error, returns NULL and sets @error.
+ */
+MonoStringHandle
+mono_string_new_utf16_handle (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error)
+{
+       return MONO_HANDLE_NEW (MonoString, mono_string_new_utf16_checked (domain, text, len, error));
+}
+
 /**
  * mono_string_new_utf32:
  * @text: a pointer to an utf32 string
@@ -8428,6 +8446,21 @@ mono_string_length (MonoString *s)
        return s->length;
 }
 
+/**
+ * mono_string_handle_length:
+ * @s: MonoString
+ *
+ * Returns the lenght in characters of the string
+ */
+int
+mono_string_handle_length (MonoStringHandle s)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       return MONO_HANDLE_GETVAL (s, length);
+}
+
+
 /**
  * mono_array_length:
  * @array: a MonoArray*
index 2963b62681f5a0177329b669606eb4b685fb4e16..c2e040dfc0693fc7623655ae6d44d5195a290438 100644 (file)
 
 #include "config.h"
 
+#include "mono/metadata/handle.h"
 #include "mono/metadata/remoting.h"
 #include "mono/metadata/marshal.h"
+#include "mono/metadata/marshal-internals.h"
 #include "mono/metadata/abi-details.h"
 #include "mono/metadata/cominterop.h"
 #include "mono/metadata/tabledefs.h"
@@ -1910,19 +1912,44 @@ mono_get_xdomain_marshal_type (MonoType *t)
        return MONO_MARSHAL_SERIALIZE;
 }
 
-/* mono_marshal_xdomain_copy_value
- * Makes a copy of "val" suitable for the current domain.
+/* Replace the given array element by a copy in the current domain */
+static gboolean
+xdomain_copy_array_element_inplace (MonoArrayHandle arr, int i, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       mono_error_init (error);
+       MonoObjectHandle item = MONO_HANDLE_NEW (MonoObject, NULL);
+       MONO_HANDLE_ARRAY_GETREF (item, arr, i);
+       
+       MonoObjectHandle item_copy = mono_marshal_xdomain_copy_value_handle (item, error);
+       if (!is_ok (error))
+               goto leave;
+       MONO_HANDLE_ARRAY_SETREF (arr, i, item_copy);
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
+}
+
+/**
+ * mono_marshal_xdomain_copy_value_handle:
+ * @val: The value to copy.
+ * @error: set on failure.
+ *
+ * Makes a copy of @val suitable for the current domain.
+ * On failure returns NULL and sets @error.
  */
-MonoObject *
-mono_marshal_xdomain_copy_value (MonoObject *val, MonoError *error)
+MonoObjectHandle
+mono_marshal_xdomain_copy_value_handle (MonoObjectHandle val, MonoError *error)
 {
        mono_error_init (error);
-       MonoDomain *domain;
-       if (val == NULL) return NULL;
+       MonoObjectHandle result = MONO_HANDLE_NEW (MonoObject, NULL);
+       if (MONO_HANDLE_IS_NULL (val))
+               goto leave;
 
-       domain = mono_domain_get ();
+       MonoDomain *domain = mono_domain_get ();
 
-       switch (mono_object_class (val)->byval_arg.type) {
+       MonoClass *klass = mono_handle_class (val);
+
+       switch (klass->byval_arg.type) {
        case MONO_TYPE_VOID:
                g_assert_not_reached ();
                break;
@@ -1938,40 +1965,63 @@ mono_marshal_xdomain_copy_value (MonoObject *val, MonoError *error)
        case MONO_TYPE_U8:
        case MONO_TYPE_R4:
        case MONO_TYPE_R8: {
-               MonoObject *res = mono_value_box_checked (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject), error);
-               return res;
-
+               uint32_t gchandle = mono_gchandle_from_handle (val, TRUE);
+               MonoObjectHandle res = MONO_HANDLE_NEW (MonoObject, mono_value_box_checked (domain, klass, ((char*)val) + sizeof(MonoObject), error)); /* FIXME use handles in mono_value_box_checked */
+               mono_gchandle_free (gchandle);
+               if (!is_ok (error))
+                       goto leave;
+               MONO_HANDLE_ASSIGN (result, res);
+               break;
        }
        case MONO_TYPE_STRING: {
-               MonoString *str = (MonoString *) val;
-               MonoObject *res = NULL;
-               res = (MonoObject *) mono_string_new_utf16_checked (domain, mono_string_chars (str), mono_string_length (str), error);
-               return res;
+               MonoStringHandle str = MONO_HANDLE_CAST (MonoString, val);
+               uint32_t gchandle = mono_gchandle_from_handle (val, TRUE);
+               MonoStringHandle res = mono_string_new_utf16_handle (domain, mono_string_chars (MONO_HANDLE_RAW (str)), mono_string_handle_length (str), error);
+               mono_gchandle_free (gchandle);
+               if (!is_ok (error))
+                       goto leave;
+               MONO_HANDLE_ASSIGN (result, res);
+               break;
        }
        case MONO_TYPE_ARRAY:
        case MONO_TYPE_SZARRAY: {
-               MonoArray *acopy;
-               MonoXDomainMarshalType mt = mono_get_xdomain_marshal_type (&(mono_object_class (val)->element_class->byval_arg));
-               if (mt == MONO_MARSHAL_SERIALIZE) return NULL;
-               acopy = mono_array_clone_in_domain (domain, (MonoArray *) val, error);
-               return_val_if_nok (error, NULL);
+               MonoArrayHandle arr = MONO_HANDLE_CAST (MonoArray, val);
+               MonoXDomainMarshalType mt = mono_get_xdomain_marshal_type (&klass->element_class->byval_arg);
+               if (mt == MONO_MARSHAL_SERIALIZE)
+                       goto leave;
+               MonoArrayHandle acopy = mono_array_clone_in_domain (domain, arr, error);
+               if (!is_ok (error))
+                       goto leave;
 
                if (mt == MONO_MARSHAL_COPY) {
-                       int i, len = mono_array_length (acopy);
+                       int i, len = mono_array_handle_length (acopy);
                        for (i = 0; i < len; i++) {
-                               MonoObject *item = (MonoObject *)mono_array_get (acopy, gpointer, i);
-                               MonoObject *item_copy = mono_marshal_xdomain_copy_value (item, error);
-                               return_val_if_nok (error, NULL);
-                               mono_array_setref (acopy, i, item_copy);
+                               if (!xdomain_copy_array_element_inplace (acopy, i, error))
+                                       goto leave;
                        }
                }
-               return (MonoObject *) acopy;
+               MONO_HANDLE_ASSIGN (result, acopy);
+               break;
        }
        default:
                break;
        }
 
-       return NULL;
+leave:
+       return result;
+}
+
+/* mono_marshal_xdomain_copy_value
+ * Makes a copy of "val" suitable for the current domain.
+ */
+MonoObject*
+mono_marshal_xdomain_copy_value (MonoObject* val_raw, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       /* FIXME callers of mono_marshal_xdomain_copy_value should use handles */
+       MONO_HANDLE_DCL (MonoObject, val);
+       MonoObjectHandle result = mono_marshal_xdomain_copy_value_handle (val, error);
+       HANDLE_FUNCTION_RETURN_OBJ (result);
 }
 
 /* mono_marshal_xdomain_copy_value