* HttpSimpleProtocolImporter.cs: Implemented internal method to support
[mono.git] / mono / interpreter / transform.c
index a31ebb20a4fa29a9ce5f45a91e9340e3294e6cf5..3fd3dd7a93f0432a1228829d833f177fcb7d99ea 100644 (file)
@@ -115,6 +115,7 @@ grow_code (TransformData *td)
 {
        unsigned int old_ip_offset = td->new_ip - td->new_code;
        unsigned int old_last_ip_offset = td->last_new_ip - td->new_code;
+       g_assert (old_ip_offset <= td->max_code_size);
        td->new_code = g_realloc (td->new_code, (td->max_code_size *= 2) * sizeof (td->new_code [0]));
        td->new_code_end = td->new_code + td->max_code_size;
        td->new_ip = td->new_code + old_ip_offset;
@@ -143,15 +144,11 @@ grow_code (TransformData *td)
                                stack_size, n, (td)->ip - (td)->il_code); \
        } while (0)
 
-#if SIZEOF_VOID_P == 4
-#define ENSURE_I4(td, sp_off)
-#else
 #define ENSURE_I4(td, sp_off) \
        do { \
                if ((td)->sp [-sp_off].type == STACK_TYPE_I8) \
                        ADD_CODE(td, sp_off == 1 ? MINT_CONV_I4_I8 : MINT_CONV_I4_I8_SP); \
        } while (0)
-#endif
 
 static void 
 handle_branch(TransformData *td, int short_op, int long_op, int offset) 
@@ -481,12 +478,25 @@ store_arg(TransformData *td, int n)
        if (n == 0 && td->method->signature->hasthis)
                ADD_CODE(td, MINT_STTHIS);
        else {
+               MonoType *type;
                n -= td->method->signature->hasthis;
-               mt = mint_type (td->method->signature->params [n]);
-               /* FIX value types */
-               g_assert(mt != MINT_TYPE_VT);
-               ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1));
-               ADD_CODE(td, td->rtm->arg_offsets [n]);
+               type = td->method->signature->params [n];
+               mt = mint_type (type);
+               if (mt == MINT_TYPE_VT) {
+                       gint32 size;
+                       if (td->method->signature->pinvoke)
+                               size = mono_class_native_size (type->data.klass, NULL);
+                       else
+                               size = mono_class_value_size (type->data.klass, NULL);
+                       ADD_CODE(td, MINT_STARG_VT);
+                       ADD_CODE(td, n);
+                       WRITE32(td, &size);
+                       if (td->sp [-1].type == STACK_TYPE_VT)
+                               POP_VT(td, size);
+               } else {
+                       ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1));
+                       ADD_CODE(td, td->rtm->arg_offsets [n]);
+               }
        }
        --td->sp;
 }
@@ -897,9 +907,14 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                case CEE_DUP: {
                        int type = td.sp [-1].type;
                        MonoClass *klass = td.sp [-1].klass;
-                       if (td.sp [-1].type == STACK_TYPE_VT)
-                               g_warning ("dup of value type not implemented");
-                       SIMPLE_OP(td, MINT_DUP);
+                       if (td.sp [-1].type == STACK_TYPE_VT) {
+                               gint32 size = mono_class_value_size (klass, NULL);
+                               PUSH_VT(&td, size);
+                               ADD_CODE(&td, MINT_DUP_VT);
+                               WRITE32(&td, &size);
+                               td.ip ++;
+                       } else 
+                               SIMPLE_OP(td, MINT_DUP);
                        PUSH_TYPE(&td, type, klass);
                        break;
                }
@@ -1733,15 +1748,16 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                        CHECK_STACK (&td, 1);
                        token = read32 (td.ip + 1);
                        klass = mono_class_get_full (image, token, generic_context);
-                       *td.new_ip ++ = MINT_CASTCLASS;
+                       ADD_CODE(&td, MINT_CASTCLASS);
                        ADD_CODE(&td, get_data_item_index (&td, klass));
+                       td.sp [-1].klass = klass;
                        td.ip += 5;
                        break;
                case CEE_ISINST:
                        CHECK_STACK (&td, 1);
                        token = read32 (td.ip + 1);
                        klass = mono_class_get_full (image, token, generic_context);
-                       *td.new_ip ++ = MINT_ISINST;
+                       ADD_CODE(&td, MINT_ISINST);
                        ADD_CODE(&td, get_data_item_index (&td, klass));
                        td.ip += 5;
                        break;
@@ -1770,7 +1786,7 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                        else 
                                klass = mono_class_get_full (image, token, generic_context);
                        
-                       *td.new_ip ++ = MINT_UNBOX;
+                       ADD_CODE(&td, MINT_UNBOX);
                        ADD_CODE(&td, get_data_item_index (&td, klass));
                        SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP);
                        td.ip += 5;
@@ -2369,26 +2385,47 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                case CEE_UNUSED41:
                        ++td.ip;
                        switch (*td.ip) {
-                       case CEE_MONO_FUNC1:
-                               ADD_CODE(&td, MINT_MONO_CONV1);
-                               ADD_CODE(&td, *(td.ip + 1));
-                               td.ip += 2;
-                               SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I);
-                               break;
-                       case CEE_MONO_PROC2:
-                               CHECK_STACK (&td, 2);
-                               ADD_CODE(&td, MINT_MONO_CONV2);
-                               ADD_CODE(&td, *(td.ip + 1));
-                               td.ip += 2;
-                               td.sp -= 2;
-                               break;
-                       case CEE_MONO_PROC3:
-                               CHECK_STACK (&td, 3);
-                               ADD_CODE(&td, MINT_MONO_CONV3);
-                               ADD_CODE(&td, *(td.ip + 1));
-                               td.ip += 2;
-                               td.sp -= 3;
-                               break;
+                               case CEE_MONO_ICALL: {
+                                       guint32 token;
+                                       gpointer func;
+                                       MonoJitICallInfo *info;
+
+                                       token = read32 (td.ip + 1);
+                                       td.ip += 5;
+                                       func = mono_method_get_wrapper_data (method, token);
+                                       info = mono_find_jit_icall_by_addr (func);
+                                       g_assert (info);
+
+                                       CHECK_STACK (&td, info->sig->param_count);
+                                       switch (info->sig->param_count) {
+                                       case 1:
+                                               if (MONO_TYPE_IS_VOID (info->sig->ret))
+                                                       ADD_CODE (&td,MINT_ICALL_P_V);
+                                               else
+                                                       ADD_CODE (&td,MINT_ICALL_P_P);
+                                               break;
+                                       case 2:
+                                               if (MONO_TYPE_IS_VOID (info->sig->ret))
+                                                       ADD_CODE (&td,MINT_ICALL_PP_V);
+                                               else
+                                                       ADD_CODE (&td,MINT_ICALL_PP_P);
+                                               break;
+                                       case 3:
+                                               g_assert (MONO_TYPE_IS_VOID (info->sig->ret));
+                                               ADD_CODE (&td,MINT_ICALL_PPP_V);
+                                               break;
+                                       default:
+                                               g_assert_not_reached ();
+                                       }
+                                       ADD_CODE(&td, get_data_item_index (&td, func));
+                                       td.sp -= info->sig->param_count;
+
+                                       if (!MONO_TYPE_IS_VOID (info->sig->ret)) {
+                                               td.sp ++;
+                                               SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I);
+                                       }
+                                       break;
+                               }
                        case CEE_MONO_VTADDR: {
                                int size;
                                CHECK_STACK (&td, 1);
@@ -2413,12 +2450,6 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                                td.sp [0].type = STACK_TYPE_I;
                                ++td.sp;
                                break;
-                       case CEE_MONO_FREE:
-                               CHECK_STACK (&td, 1);
-                               ADD_CODE(&td, MINT_MONO_FREE);
-                               ++td.ip;
-                               --td.sp;
-                               break;
                        case CEE_MONO_OBJADDR:
                                CHECK_STACK (&td, 1);
                                ++td.ip;
@@ -2454,6 +2485,10 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                                g_assert(klass->valuetype);
                                SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP);
                                break;
+                       case CEE_MONO_SAVE_LMF:
+                       case CEE_MONO_RESTORE_LMF:
+                               ++td.ip;
+                               break;
                        default:
                                g_error ("transform.c: Unimplemented opcode: 0xF0 %02x at 0x%x\n", *td.ip, td.ip-header->code);
                        }
@@ -2698,7 +2733,7 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
        if (mono_interp_traceopt) {
                const guint16 *p = td.new_code;
                printf("Runtime method: %p, VT stack size: %d\n", rtm, td.max_vt_sp);
-               printf("Caculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack);
+               printf("Calculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack);
                while (p < td.new_ip) {
                        p = mono_interp_dis_mintop(td.new_code, p);
                        printf("\n");
@@ -2822,6 +2857,8 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
                        }
                }
                if (nm == NULL) {
+                       runtime_method->stack_size = sizeof (stackval); /* for tracing */
+                       runtime_method->alloca_size = runtime_method->stack_size;
                        runtime_method->transformed = TRUE;
                        LeaveCriticalSection(&calc_section);
                        mono_profiler_method_end_jit (method, MONO_PROFILE_OK);
@@ -2847,7 +2884,7 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
                }
                else if (in == 0xf0) {
                        ip++;
-                       in = *ip + MONO_CEE_MONO_FUNC1;
+                       in = *ip + MONO_CEE_MONO_ICALL;
                }
                opcode = &mono_opcodes [in];
                switch (opcode->argument) {