2004-11-04 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / interpreter / interp.c
index f00dc44559092e378cdbecb41080417cf027950f..893d736c90b7131fab3d48f099dece4376866a12 100644 (file)
@@ -669,13 +669,17 @@ ves_array_element_address (MonoInvocation *frame)
 }
 
 static void
-interp_walk_stack (MonoStackWalk func, gpointer user_data)
+interp_walk_stack (MonoStackWalk func, gboolean do_il_offset, gpointer user_data)
 {
        ThreadContext *context = TlsGetValue (thread_context_id);
-       MonoInvocation *frame = context->current_frame;
+       MonoInvocation *frame;
        int il_offset;
        MonoMethodHeader *hd;
 
+       if (!context) return;
+               
+       frame = context->current_frame;
+
        while (frame) {
                gboolean managed = FALSE;
                MonoMethod *method = frame->runtime_method->method;
@@ -760,6 +764,25 @@ interp_delegate_ctor (MonoDomain *domain, MonoObject *this, MonoObject *target,
        }
 }
 
+MonoDelegate*
+mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
+{
+       MonoDelegate *d;
+       MonoJitInfo *ji;
+       MonoDomain *domain = mono_domain_get ();
+
+       d = (MonoDelegate*)mono_object_new (domain, klass);
+
+       ji = mono_jit_info_table_find (domain, ftn);
+       if (ji == NULL)
+               mono_raise_exception (mono_get_exception_argument ("", "Function pointer was not created by a Delegate."));
+
+       /* FIXME: discard the wrapper and call the original method */
+       interp_delegate_ctor (domain, (MonoObject*)d, NULL, mono_interp_get_runtime_method (ji->method));
+
+       return d;
+}
+
 /*
  * From the spec:
  * runtime specifies that the implementation of the method is automatically
@@ -1196,6 +1219,84 @@ handle_enum:
        return retval;
 }
 
+static stackval * 
+do_icall (ThreadContext *context, int op, stackval *sp, gpointer ptr)
+{
+       MonoInvocation *old_frame = context->current_frame;
+       MonoInvocation *old_env_frame = context->env_frame;
+       jmp_buf *old_env = context->current_env;
+       jmp_buf env;
+
+       if (setjmp (env)) {
+               context->current_frame = old_frame;
+               context->env_frame = old_env_frame;
+               context->current_env = old_env;
+               context->managed_code = 1;
+               return sp;
+       }
+
+       context->env_frame = context->current_frame;
+       context->current_env = &env;
+       context->managed_code = 0;
+
+       switch (op) {
+       case MINT_ICALL_P_V: {
+               void (*func)(gpointer) = ptr;
+               func (sp [-1].data.p);
+               sp --;
+               break;
+       }
+       case MINT_ICALL_P_P: {
+               gpointer (*func)(gpointer) = ptr;
+               sp [-1].data.p = func (sp [-1].data.p);
+               break;
+       }
+       case MINT_ICALL_PP_V: {
+               void (*func)(gpointer,gpointer) = ptr;
+               sp -= 2;
+               func (sp [0].data.p, sp [1].data.p);
+               break;
+       }
+       case MINT_ICALL_PI_V: {
+               void (*func)(gpointer,int) = ptr;
+               sp -= 2;
+               func (sp [0].data.p, sp [1].data.i);
+               break;
+       }
+       case MINT_ICALL_PP_P: {
+               gpointer (*func)(gpointer,gpointer) = ptr;
+               --sp;
+               sp [-1].data.p = func (sp [-1].data.p, sp [0].data.p);
+               break;
+       }
+       case MINT_ICALL_PI_P: {
+               gpointer (*func)(gpointer,int) = ptr;
+               --sp;
+               sp [-1].data.p = func (sp [-1].data.p, sp [0].data.i);
+               break;
+       }
+       case MINT_ICALL_PPP_V: {
+               void (*func)(gpointer,gpointer,gpointer) = ptr;
+               sp -= 3;
+               func (sp [0].data.p, sp [1].data.p, sp [2].data.p);
+               break;
+       }
+       case MINT_ICALL_PPI_V: {
+               void (*func)(gpointer,gpointer,int) = ptr;
+               sp -= 3;
+               func (sp [0].data.p, sp [1].data.p, sp [2].data.i);
+               break;
+       }
+       default:
+               g_assert_not_reached ();
+       }
+
+       context->env_frame = old_env_frame;
+       context->current_env = old_env;
+
+       return sp;
+}
+
 static CRITICAL_SECTION create_method_pointer_mutex;
 
 static MonoGHashTable *method_pointer_hash = NULL;
@@ -3390,37 +3491,19 @@ array_constructed:
                        }
                        goto handle_finally;
                        MINT_IN_BREAK;
-               MINT_IN_CASE(MINT_MONO_PROC1) {
-                   void (*func)(gpointer) = rtm->data_items [*(guint16 *)(ip + 1)];
-                       ip += 2;
-
-                       func (sp [-1].data.p);
-                       sp --;
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_MONO_CONV1) {
-                   gpointer (*func)(gpointer) = rtm->data_items [*(guint16 *)(ip + 1)];
-                       ip += 2;
-
-                       sp [-1].data.p = func (sp [-1].data.p);
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_MONO_CONV2) {
-                   void (*func)(gpointer,gpointer) = rtm->data_items [*(guint16 *)(ip + 1)];
-                       ip += 2;
-                       sp -= 2;
-
-                       func (sp [0].data.p, sp [1].data.p);
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_MONO_CONV3) {
-                   void (*func)(gpointer,gpointer,gpointer) = rtm->data_items [*(guint16 *)(ip + 1)];
+               MINT_IN_CASE(MINT_ICALL_P_V) 
+               MINT_IN_CASE(MINT_ICALL_P_P)
+               MINT_IN_CASE(MINT_ICALL_PP_V)
+               MINT_IN_CASE(MINT_ICALL_PI_V)
+               MINT_IN_CASE(MINT_ICALL_PP_P)
+               MINT_IN_CASE(MINT_ICALL_PI_P)
+               MINT_IN_CASE(MINT_ICALL_PPP_V)
+               MINT_IN_CASE(MINT_ICALL_PPI_V)
+                       sp = do_icall (context, *ip, sp, rtm->data_items [*(guint16 *)(ip + 1)]);
+                       if (frame->ex != NULL)
+                               goto handle_exception;
                        ip += 2;
-                       sp -= 3;
-
-                       func (sp [0].data.p, sp [1].data.p, sp [2].data.p);
                        MINT_IN_BREAK;
-               }
                MINT_IN_CASE(MINT_MONO_LDPTR) 
                        sp->data.p = rtm->data_items [*(guint16 *)(ip + 1)];
                        ip += 2;
@@ -4300,7 +4383,8 @@ mono_interp_init(const char *file)
        g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
        g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
 
-       g_thread_init (NULL);
+       if (!g_thread_supported ())
+               g_thread_init (NULL);
 
        thread_context_id = TlsAlloc ();
        TlsSetValue (thread_context_id, NULL);
@@ -4319,7 +4403,7 @@ mono_interp_init(const char *file)
        mono_runtime_install_cleanup (quit_function);
        abort_requested = mono_thread_interruption_request_flag ();
 
-       domain = mono_init (file);
+       domain = mono_init_from_assembly (file, file);
 #ifdef __hpux /* generates very big stack frames */
        mono_threads_set_default_stacksize(32*1024*1024);
 #endif
@@ -4331,6 +4415,7 @@ mono_interp_init(const char *file)
 
        mono_runtime_init (domain, NULL, NULL);
 
+       mono_thread_attach (domain);
        return domain;
 }
 
@@ -4348,6 +4433,8 @@ mono_main (int argc, char *argv [])
        if (argc < 2)
                usage ();
 
+       MONO_GC_PRE_INIT ();
+       
        for (i = 1; i < argc && argv [i][0] == '-'; i++){
                if (strcmp (argv [i], "--trace") == 0)
                        global_tracing = 1;