Merge pull request #3335 from lambdageek/dev/system-reflection-assembly
[mono.git] / mono / metadata / object.c
index 7e4c9dc4e062b84777f32afaf1ab51e5ddd3ea04..7bb2b43beaf795a85ecf1bcd9c94fb7804a30c98 100644 (file)
@@ -4289,11 +4289,7 @@ mono_runtime_run_main (MonoMethod *method, int argc, char* argv[],
        MonoArray *args = prepare_run_main (method, argc, argv);
        int res;
        if (exc) {
-               res = mono_runtime_try_exec_main (method, args, exc, &error);
-               if (*exc == NULL && !is_ok (&error))
-                       *exc = (MonoObject*) mono_error_convert_to_exception (&error);
-               else
-                       mono_error_cleanup (&error);
+               res = mono_runtime_try_exec_main (method, args, exc);
        } else {
                res = mono_runtime_exec_main_checked (method, args, &error);
                mono_error_raise_exception (&error); /* OK to throw, external only without a better alternative */
@@ -4340,12 +4336,11 @@ mono_runtime_run_main_checked (MonoMethod *method, int argc, char* argv[],
  */
 int
 mono_runtime_try_run_main (MonoMethod *method, int argc, char* argv[],
-                          MonoObject **exc, MonoError *error)
+                          MonoObject **exc)
 {
        g_assert (exc);
-       mono_error_init (error);
        MonoArray *args = prepare_run_main (method, argc, argv);
-       return mono_runtime_try_exec_main (method, args, exc, error);
+       return mono_runtime_try_exec_main (method, args, exc);
 }
 
 
@@ -4780,27 +4775,20 @@ do_exec_main_checked (MonoMethod *method, MonoArray *args, MonoError *error)
                if (is_ok (error))
                        rval = 0;
                else {
-                       /* If the return type of Main is void, only
-                        * set the exitcode if an exception was thrown
-                        * (we don't want to blow away an
-                        * explicitly-set exit code)
-                        */
                        rval = -1;
-                       mono_environment_exitcode_set (rval);
                }
        }
        return rval;
 }
 
 static int
-do_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc, MonoError *error)
+do_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
        gpointer pa [1];
        int rval;
 
-       mono_error_init (error);
        g_assert (args);
        g_assert (exc);
 
@@ -4808,12 +4796,13 @@ do_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc, MonoErr
 
        /* FIXME: check signature of method */
        if (mono_method_signature (method)->ret->type == MONO_TYPE_I4) {
+               MonoError inner_error;
                MonoObject *res;
-               res = mono_runtime_try_invoke (method, NULL, pa, exc, error);
-               if (*exc == NULL && !mono_error_ok (error))
-                       *exc = (MonoObject*) mono_error_convert_to_exception (error);
+               res = mono_runtime_try_invoke (method, NULL, pa, exc, &inner_error);
+               if (*exc == NULL && !mono_error_ok (&inner_error))
+                       *exc = (MonoObject*) mono_error_convert_to_exception (&inner_error);
                else
-                       mono_error_cleanup (error);
+                       mono_error_cleanup (&inner_error);
 
                if (*exc == NULL)
                        rval = *(guint32 *)((char *)res + sizeof (MonoObject));
@@ -4822,11 +4811,12 @@ do_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc, MonoErr
 
                mono_environment_exitcode_set (rval);
        } else {
-               mono_runtime_try_invoke (method, NULL, pa, exc, error);
-               if (*exc == NULL && !mono_error_ok (error))
-                       *exc = (MonoObject*) mono_error_convert_to_exception (error);
+               MonoError inner_error;
+               mono_runtime_try_invoke (method, NULL, pa, exc, &inner_error);
+               if (*exc == NULL && !mono_error_ok (&inner_error))
+                       *exc = (MonoObject*) mono_error_convert_to_exception (&inner_error);
                else
-                       mono_error_cleanup (error);
+                       mono_error_cleanup (&inner_error);
 
                if (*exc == NULL)
                        rval = 0;
@@ -4854,11 +4844,7 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
        MonoError error;
        prepare_thread_to_exec_main (mono_object_domain (args), method);
        if (exc) {
-               int rval = do_try_exec_main (method, args, exc, &error);
-               if (*exc == NULL && !is_ok (&error))
-                       *exc = (MonoObject*) mono_error_convert_to_exception (&error);
-               else
-                       mono_error_cleanup (&error);
+               int rval = do_try_exec_main (method, args, exc);
                return rval;
        } else {
                int rval = do_exec_main_checked (method, args, &error);
@@ -4888,11 +4874,10 @@ mono_runtime_exec_main_checked (MonoMethod *method, MonoArray *args, MonoError *
  * On failure sets @error if Main couldn't be executed, or @exc if it threw an exception.
  */
 int
-mono_runtime_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc, MonoError *error)
+mono_runtime_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
 {
-       mono_error_init (error);
        prepare_thread_to_exec_main (mono_object_domain (args), method);
-       return do_try_exec_main (method, args, exc, error);
+       return do_try_exec_main (method, args, exc);
 }
 
 
@@ -7580,88 +7565,24 @@ mono_message_init (MonoDomain *domain,
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoClass *object_array_klass;
-       static MonoClass *byte_array_klass;
-       static MonoClass *string_array_klass;
-       mono_error_init (error);
-       MonoMethodSignature *sig = mono_method_signature (method->method);
-       MonoString *name;
-       MonoArray *arr;
-       int i, j;
-       char **names;
-       guint8 arg_type;
-
-       if (!object_array_klass) {
-               MonoClass *klass;
-
-               klass = mono_array_class_get (mono_defaults.byte_class, 1);
-               g_assert (klass);
-               byte_array_klass = klass;
-
-               klass = mono_array_class_get (mono_defaults.string_class, 1);
-               g_assert (klass);
-               string_array_klass = klass;
-
-               klass = mono_array_class_get (mono_defaults.object_class, 1);
-               g_assert (klass);
+       static MonoMethod *init_message_method = NULL;
 
-               mono_atomic_store_release (&object_array_klass, klass);
+       if (!init_message_method) {
+               init_message_method = mono_class_get_method_from_name (mono_defaults.mono_method_message_class, "InitMessage", 2);
+               g_assert (init_message_method != NULL);
        }
 
-       MONO_OBJECT_SETREF (this_obj, method, method);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, object_array_klass), sig->param_count, error);
-       return_val_if_nok (error, FALSE);
-
-       MONO_OBJECT_SETREF (this_obj, args, arr);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, byte_array_klass), sig->param_count, error);
-       return_val_if_nok (error, FALSE);
-
-       MONO_OBJECT_SETREF (this_obj, arg_types, arr);
-
-       this_obj->async_result = NULL;
-       this_obj->call_type = CallType_Sync;
-
-       names = g_new (char *, sig->param_count);
-       mono_method_get_param_names (method->method, (const char **) names);
-
-       arr = mono_array_new_specific_checked (mono_class_vtable (domain, string_array_klass), sig->param_count, error);
-       if (!is_ok (error))
-               goto fail;
-
-       MONO_OBJECT_SETREF (this_obj, names, arr);
+       mono_error_init (error);
+       /* FIXME set domain instead? */
+       g_assert (domain == mono_domain_get ());
        
-       for (i = 0; i < sig->param_count; i++) {
-               name = mono_string_new_checked (domain, names [i], error);
-               if (!is_ok (error))
-                       goto fail;
-               mono_array_setref (this_obj->names, i, name);   
-       }
+       gpointer args[2];
 
-       g_free (names);
-       for (i = 0, j = 0; i < sig->param_count; i++) {
-               if (sig->params [i]->byref) {
-                       if (out_args) {
-                               MonoObject* arg = (MonoObject *)mono_array_get (out_args, gpointer, j);
-                               mono_array_setref (this_obj->args, i, arg);
-                               j++;
-                       }
-                       arg_type = 2;
-                       if (!(sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT))
-                               arg_type |= 1;
-               } else {
-                       arg_type = 1;
-                       if (sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT)
-                               arg_type |= 4;
-               }
-               mono_array_set (this_obj->arg_types, guint8, i, arg_type);
-       }
+       args[0] = method;
+       args[1] = out_args;
 
-       return TRUE;
-fail:
-       g_free (names);
-       return FALSE;
+       mono_runtime_invoke_checked (init_message_method, this_obj, args, error);
+       return is_ok (error);
 }
 
 #ifndef DISABLE_REMOTING
@@ -8287,28 +8208,6 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
        return result;
 }
 
-/**
- * mono_load_remote_field_new_icall:
- * @this: pointer to an object
- * @klass: klass of the object containing @field
- * @field: the field to load
- *
- * This method is called by the runtime on attempts to load fields of
- * transparent proxy objects. @this points to such TP, @klass is the class of
- * the object containing @field.
- * 
- * Returns: a freshly allocated object containing the value of the
- * field.  On failure returns NULL and throws an exception.
- */
-MonoObject *
-mono_load_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
-{
-       MonoError error;
-       MonoObject *result = mono_load_remote_field_new_checked (this_obj, klass, field, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
 /**
  * mono_load_remote_field_new_checked:
  * @this: pointer to an object
@@ -8329,69 +8228,25 @@ mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mono
 
        mono_error_init (error);
 
-       static MonoMethod *getter = NULL;
-       MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
-       MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc, *res;
-       char* full_name;
+       static MonoMethod *tp_load = NULL;
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
-       field_class = mono_class_from_mono_type (field->type);
-
-       if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
-               gpointer val;
-               if (field_class->valuetype) {
-                       res = mono_object_new_checked (domain, field_class, error);
-                       return_val_if_nok (error, NULL);
-                       val = ((gchar *) res) + sizeof (MonoObject);
-               } else {
-                       val = &res;
-               }
-               mono_field_get_value (tp->rp->unwrapped_server, field, val);
-               return res;
-       }
-
-       if (!getter) {
-               getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
-               if (!getter) {
+       if (!tp_load) {
+               tp_load = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "LoadRemoteFieldNew", -1);
+               if (!tp_load) {
                        mono_error_set_not_supported (error, "Linked away.");
                        return NULL;
                }
        }
        
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
-       return_val_if_nok (error, NULL);
-       out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, error);
-       return_val_if_nok (error, NULL);
-
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, error);
-       return_val_if_nok (error, NULL);
-       mono_message_init (domain, msg, rm, out_args, error);
-       return_val_if_nok (error, NULL);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, NULL);
-
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return NULL;
-       }
+       /* MonoType *type = mono_class_get_type (klass); */
 
-       if (mono_array_length (out_args) == 0)
-               res = NULL;
-       else
-               res = mono_array_get (out_args, MonoObject *, 0);
+       gpointer args[2];
+       args [0] = &klass;
+       args [1] = &field;
 
-       return res;
+       return mono_runtime_invoke_checked (tp_load, this_obj, args, error);
 }
 
 /**
@@ -8433,65 +8288,24 @@ mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoCla
        
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
+       mono_error_init (error);
 
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
        MonoObject *arg;
-       char* full_name;
-
-       mono_error_init (error);
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
 
-       if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
-               if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, val);
-               else mono_field_set_value (tp->rp->unwrapped_server, field, *((MonoObject **)val));
-               return TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter) {
-                       mono_error_set_not_supported (error, "Linked away.");
-                       return FALSE;
-               }
-       }
-
        if (field_class->valuetype) {
                arg = mono_value_box_checked (domain, field_class, val, error);
                return_val_if_nok (error, FALSE);
-       } else 
-               arg = *((MonoObject **)val);
-               
-
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
-       return_val_if_nok (error, FALSE);
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
-       return_val_if_nok (error, FALSE);
-       mono_message_init (domain, msg, rm, NULL, error);
-       return_val_if_nok (error, FALSE);
-
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
-
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
+       } else {
+               arg = *((MonoObject**)val);
        }
-       return TRUE;
+
+       return mono_store_remote_field_new_checked (this_obj, klass, field, arg, error);
 }
 
 /**
@@ -8511,23 +8325,6 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        mono_error_cleanup (&error);
 }
 
-/**
- * mono_store_remote_field_new_icall:
- * @this_obj:
- * @klass:
- * @field:
- * @arg:
- *
- * Missing documentation
- */
-void
-mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
-{
-       MonoError error;
-       (void) mono_store_remote_field_new_checked (this_obj, klass, field, arg, &error);
-       mono_error_set_pending_exception (&error);
-}
-
 /**
  * mono_store_remote_field_new_checked:
  * @this_obj:
@@ -8543,56 +8340,27 @@ mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mon
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoMethod *setter = NULL;
-       MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
-       MonoClass *field_class;
-       MonoMethodMessage *msg;
-       MonoArray *out_args;
-       MonoObject *exc;
-       char* full_name;
+       static MonoMethod *tp_store = NULL;
 
        mono_error_init (error);
 
        g_assert (mono_object_is_transparent_proxy (this_obj));
 
-       field_class = mono_class_from_mono_type (field->type);
-
-       if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
-               if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, ((gchar *) arg) + sizeof (MonoObject));
-               else mono_field_set_value (tp->rp->unwrapped_server, field, arg);
-               return TRUE;
-       }
-
-       if (!setter) {
-               setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
-               if (!setter) {
+       if (!tp_store) {
+               tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1);
+               if (!tp_store) {
                        mono_error_set_not_supported (error, "Linked away.");
                        return FALSE;
                }
        }
 
-       msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error);
-       return_val_if_nok (error, FALSE);
-       MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error);
-       return_val_if_nok (error, FALSE);
-       mono_message_init (domain, msg, rm, NULL, error);
-       return_val_if_nok (error, FALSE);
+       gpointer args[3];
+       args [0] = &klass;
+       args [1] = &field;
+       args [2] = arg;
 
-       full_name = mono_type_get_full_name (klass);
-       mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
-       mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
-       mono_array_setref (msg->args, 2, arg);
-       g_free (full_name);
-
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error);
-       return_val_if_nok (error, FALSE);
-
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException *)exc);
-               return FALSE;
-       }
-       return TRUE;
+       mono_runtime_invoke_checked (tp_store, this_obj, args, error);
+       return is_ok (error);
 }
 #endif