[interp/tramp] use MONO_STRUCT_OFFSET infrastructure and extract constants
[mono.git] / mono / mini / interp / interp.c
index 1b74cc75f5eaafedd33bf643f81cc3511d4b8547..8cf7bec464ca320de00f1ab8ef38f8ef6dd6e57b 100644 (file)
@@ -218,7 +218,8 @@ interp_ex_handler (MonoException *ex) {
        if (context == NULL)
                return;
        stack_trace = dump_frame (context->current_frame);
-       ex->stack_trace = mono_string_new (mono_domain_get(), stack_trace);
+       ex->stack_trace = mono_string_new_checked (mono_domain_get(), stack_trace, &error);
+       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        g_free (stack_trace);
        if (context->current_env == NULL || strcmp(ex->object.vtable->klass->name, "ExecutionEngineException") == 0) {
                char *strace = mono_string_to_utf8_checked (ex->stack_trace, &error);
@@ -561,9 +562,11 @@ stackval_to_data (MonoType *type, stackval *val, char *data, gboolean pinvoke)
 static void
 fill_in_trace (MonoException *exception, MonoInvocation *frame)
 {
+       MonoError error;
        char *stack_trace = dump_frame (frame);
        MonoDomain *domain = mono_domain_get();
-       (exception)->stack_trace = mono_string_new (domain, stack_trace);
+       (exception)->stack_trace = mono_string_new_checked (domain, stack_trace, &error);
+       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        (exception)->trace_ips = get_trace_ips (domain, frame);
        g_free (stack_trace);
 }
@@ -755,22 +758,10 @@ interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUn
 
 static MonoPIFunc mono_interp_enter_icall_trampoline = NULL;
 
-struct _MethodArguments {
-       size_t ilen;
-       gpointer *iargs;
-       size_t flen;
-       double *fargs;
-       gpointer *retval;
-       size_t is_float_ret;
-};
-
-typedef struct _MethodArguments MethodArguments;
-
 // TODO: this function is also arch dependent (register width).
-static MethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvocation *frame)
+static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvocation *frame)
 {
-       // TODO: don't malloc this data structure.
-       MethodArguments *margs = g_malloc0 (sizeof (MethodArguments));
+       InterpMethodArguments *margs = g_malloc0 (sizeof (InterpMethodArguments));
 
        if (sig->hasthis)
                margs->ilen++;
@@ -813,10 +804,10 @@ static MethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvoc
        if (margs->flen > 0)
                margs->fargs = g_malloc0 (sizeof (double) * margs->flen);
 
-       if (margs->ilen > 12)
+       if (margs->ilen > INTERP_ICALL_TRAMP_IARGS)
                g_error ("build_args_from_sig: TODO, allocate gregs: %d\n", margs->ilen);
 
-       if (margs->flen > 3)
+       if (margs->flen > INTERP_ICALL_TRAMP_FARGS)
                g_error ("build_args_from_sig: TODO, allocate fregs: %d\n", margs->flen);
 
 
@@ -936,7 +927,7 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
                // mono_tramp_info_register (info, NULL);
        }
 
-       MethodArguments *margs = build_args_from_sig (sig, frame);
+       InterpMethodArguments *margs = build_args_from_sig (sig, frame);
 #if DEBUG_INTERP
        g_print ("ICALL: mono_interp_enter_icall_trampoline = %p, addr = %p\n", mono_interp_enter_icall_trampoline, addr);
        g_print ("margs(out): ilen=%d, flen=%d\n", margs->ilen, margs->flen);
@@ -4288,17 +4279,50 @@ array_constructed:
                MINT_IN_CASE(MINT_LDELEM) 
                MINT_IN_CASE(MINT_STELEM) 
                MINT_IN_CASE(MINT_UNBOX_ANY) 
-
-               MINT_IN_CASE(MINT_REFANYVAL) ves_abort(); MINT_IN_BREAK;
 #endif
                MINT_IN_CASE(MINT_CKFINITE)
                        if (!isfinite(sp [-1].data.f))
                                THROW_EX (mono_get_exception_arithmetic (), ip);
                        ++ip;
                        MINT_IN_BREAK;
-#if 0
-               MINT_IN_CASE(MINT_MKREFANY) ves_abort(); MINT_IN_BREAK;
-#endif
+               MINT_IN_CASE(MINT_MKREFANY) {
+                       c = rtm->data_items [*(guint16 *)(ip + 1)];
+
+                       /* The value address is on the stack */
+                       gpointer addr = sp [-1].data.p;
+                       /* Push the typedref value on the stack */
+                       sp [-1].data.p = vt_sp;
+                       vt_sp += sizeof (MonoTypedRef);
+
+                       MonoTypedRef *tref = sp [-1].data.p;
+                       tref->klass = c;
+                       tref->type = &c->byval_arg;
+                       tref->value = addr;
+
+                       ip += 2;
+                       MINT_IN_BREAK;
+               }
+               MINT_IN_CASE(MINT_REFANYTYPE) {
+                       MonoTypedRef *tref = sp [-1].data.p;
+                       MonoType *type = tref->type;
+
+                       vt_sp -= sizeof (MonoTypedRef);
+                       sp [-1].data.p = vt_sp;
+                       vt_sp += 8;
+                       *(gpointer*)sp [-1].data.p = type;
+                       ip ++;
+                       MINT_IN_BREAK;
+               }
+               MINT_IN_CASE(MINT_REFANYVAL) {
+                       MonoTypedRef *tref = sp [-1].data.p;
+                       gpointer addr = tref->value;
+
+                       vt_sp -= sizeof (MonoTypedRef);
+
+                       sp [-1].data.p = addr;
+                       ip ++;
+                       MINT_IN_BREAK;
+               }
                MINT_IN_CASE(MINT_LDTOKEN)
                        sp->data.p = vt_sp;
                        vt_sp += 8;
@@ -5120,8 +5144,10 @@ interp_ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
        if (need_file_info) {
                if (column)
                        *column = 0;
-               if (file)
-                       *file = mono_string_new (mono_domain_get (), "unknown");
+               if (file) {
+                       *file = mono_string_new_checked (mono_domain_get (), "unknown", &error);
+                       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+               }
        }
 
        return TRUE;
@@ -5168,7 +5194,11 @@ interp_ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_fi
                        
                        filename = mono_debug_source_location_from_address (ji->method, sf->native_offset, &sf->line, domain);
 
-                       sf->filename = filename? mono_string_new (domain, filename): NULL;
+                       sf->filename = NULL;
+                       if (filename) {
+                               sf->filename = mono_string_new_checked (domain, filename, &error);
+                               mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+                       }
                        sf->column = 0;
 
                        g_free (filename);