Merge pull request #2531 from esdrubal/systemweb
[mono.git] / mono / mini / mini-runtime.c
index 159e3e4affb4f6dac53956c4a74c4d234028c34c..4640672dd5428c48a861892c3e4888b87b4d4fe4 100644 (file)
@@ -1846,7 +1846,7 @@ no_gsharedvt_in_wrapper (void)
 }
 
 static gpointer
-mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex)
+mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *error)
 {
        MonoDomain *target_domain, *domain = mono_domain_get ();
        MonoJitInfo *info;
@@ -1855,6 +1855,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
        MonoJitICallInfo *callinfo = NULL;
        WrapperInfo *winfo = NULL;
 
+       mono_error_init (error);
+
        /*
         * ICALL wrappers are handled specially, since there is only one copy of them
         * shared by all appdomains.
@@ -1887,9 +1889,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
                                ctx = mono_method_get_context (method);
                        method = info->d.synchronized_inner.method;
                        if (ctx) {
-                               MonoError error;
-                               method = mono_class_inflate_generic_method_checked (method, ctx, &error);
-                               g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+                               method = mono_class_inflate_generic_method_checked (method, ctx, error);
+                               g_assert (mono_error_ok (error)); /* FIXME don't swallow the error */
                        }
                }
        }
@@ -1904,9 +1905,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
                        mono_jit_stats.methods_lookups++;
                        vtable = mono_class_vtable (domain, method->klass);
                        g_assert (vtable);
-                       tmpEx = mono_runtime_class_init_full (vtable, ex == NULL);
+                       tmpEx = mono_runtime_class_init_full (vtable, FALSE);
                        if (tmpEx) {
-                               *ex = tmpEx;
+                               mono_error_set_exception_instance (error, tmpEx);
                                return NULL;
                        }
                        return mono_create_ftnptr (target_domain, info->code_start);
@@ -1937,7 +1938,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
 #endif
 
        if (!code)
-               code = mono_jit_compile_method_inner (method, target_domain, opt, ex);
+               code = mono_jit_compile_method_inner (method, target_domain, opt, error);
+       if (!mono_error_ok (error))
+               return NULL;
 
        if (!code && mono_llvm_only) {
                if (method->wrapper_type == MONO_WRAPPER_UNKNOWN) {
@@ -1988,17 +1991,11 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
 }
 
 gpointer
-mono_jit_compile_method (MonoMethod *method)
+mono_jit_compile_method (MonoMethod *method, MonoError *error)
 {
-       MonoException *ex = NULL;
        gpointer code;
 
-       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), &ex);
-       if (!code) {
-               g_assert (ex);
-               mono_raise_exception (ex);
-       }
-
+       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), error);
        return code;
 }
 
@@ -2199,7 +2196,7 @@ typedef struct {
 } RuntimeInvokeInfo;
 
 static RuntimeInvokeInfo*
-create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt)
+create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt, MonoError *error)
 {
        MonoMethod *invoke;
        RuntimeInvokeInfo *info;
@@ -2302,7 +2299,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
                                invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
                                g_free (wrapper_sig);
 
-                               info->compiled_method = mono_jit_compile_method (wrapper);
+                               info->compiled_method = mono_jit_compile_method (wrapper, error);
+                               if (!mono_error_ok (error)) {
+                                       g_free (info);
+                                       return NULL;
+                               }
                        } else {
                                /* Gsharedvt methods can be invoked the same way */
                                /* The out wrapper has the same signature as the compiled gsharedvt method */
@@ -2314,7 +2315,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
                                g_free (wrapper_sig);
                        }
                }
-               info->runtime_invoke = mono_jit_compile_method (invoke);
+               info->runtime_invoke = mono_jit_compile_method (invoke, error);
+               if (!mono_error_ok (error)) {
+                       g_free (info);
+                       return NULL;
+               }
        }
 
        return info;
@@ -2396,10 +2401,11 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
  * @method: the method to invoke
  * @obj: this pointer
  * @params: array of parameter values.
+ * @error: error
  * @exc: used to catch exceptions objects
  */
 static MonoObject*
-mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoError *error, MonoObject **exc)
 {
        MonoMethod *invoke, *callee;
        MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method);
@@ -2409,6 +2415,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
        MonoJitInfo *ji = NULL;
        gboolean callee_gsharedvt = FALSE;
 
+       mono_error_init (error);
+
        if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) {
                g_warning ("Ignoring invocation of an instance method on a NULL instance.\n");
                return NULL;
@@ -2458,18 +2466,10 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                }
 
                if (callee) {
-                       MonoException *jit_ex = NULL;
-
-                       compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), &jit_ex);
+                       compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), error);
                        if (!compiled_method) {
-                               g_assert (jit_ex);
-                               if (exc) {
-                                       *exc = (MonoObject*)jit_ex;
-                                       return NULL;
-                               } else {
-                                       mono_raise_exception (jit_ex);
-                                       /* coverity[unreachable] */
-                               }
+                               g_assert (!mono_error_ok (error));
+                               return NULL;
                        }
 
                        if (mono_llvm_only) {
@@ -2485,7 +2485,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                        compiled_method = NULL;
                }
 
-               info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt);
+               info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt, error);
+               if (!mono_error_ok (error))
+                       return NULL;
 
                mono_domain_lock (domain);
                info2 = (RuntimeInvokeInfo *)mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info);
@@ -2523,7 +2525,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
 
                if (!dyn_runtime_invoke) {
                        invoke = mono_marshal_get_runtime_invoke_dynamic ();
-                       dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke);
+                       dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke, error);
+                       if (!mono_error_ok (error))
+                               return NULL;
                }
 
                /* Convert the arguments to the format expected by start_dyn_call () */
@@ -3491,6 +3495,14 @@ mini_init (const char *filename, const char *runtime_version)
        callbacks.get_imt_trampoline = mini_get_imt_trampoline;
        callbacks.imt_entry_inited = mini_imt_entry_inited;
        callbacks.init_delegate = mini_init_delegate;
+#define JIT_INVOKE_WORKS
+#ifdef JIT_INVOKE_WORKS
+       callbacks.runtime_invoke = mono_jit_runtime_invoke;
+#endif
+#define JIT_TRAMPOLINES_WORK
+#ifdef JIT_TRAMPOLINES_WORK
+       callbacks.compile_method = mono_jit_compile_method;
+#endif
 
        mono_install_callbacks (&callbacks);
 
@@ -3560,9 +3572,7 @@ mini_init (const char *filename, const char *runtime_version)
 #endif
        mono_threads_install_cleanup (mini_thread_cleanup);
 
-#define JIT_TRAMPOLINES_WORK
 #ifdef JIT_TRAMPOLINES_WORK
-       mono_install_compile_method (mono_jit_compile_method);
        mono_install_free_method (mono_jit_free_method);
        mono_install_trampoline (mono_create_jit_trampoline);
        mono_install_jump_trampoline (mono_create_jump_trampoline);
@@ -3572,10 +3582,6 @@ mini_init (const char *filename, const char *runtime_version)
        mono_install_delegate_trampoline (mono_create_delegate_trampoline);
        mono_install_create_domain_hook (mini_create_jit_domain_info);
        mono_install_free_domain_hook (mini_free_jit_domain_info);
-#endif
-#define JIT_INVOKE_WORKS
-#ifdef JIT_INVOKE_WORKS
-       mono_install_runtime_invoke (mono_jit_runtime_invoke);
 #endif
        mono_install_get_cached_class_info (mono_aot_get_cached_class_info);
        mono_install_get_class_from_name (mono_aot_get_class_from_name);