[interp] Implement runtime invokes by executing the runtime-invoke wrappers using...
[mono.git] / mono / mini / interp / transform.c
index a51f1891ec6409e8feb53db2c785d1eac2aba17e..113a086d3b4a0041f0a5e280d185c9b967abbd08 100644 (file)
@@ -751,6 +751,14 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                csignature = mono_method_signature (target_method);
        }
 
+       if (target_method && target_method->string_ctor) {
+               /* Create the real signature */
+               MonoMethodSignature *ctor_sig = mono_metadata_signature_dup_mempool (td->mempool, csignature);
+               ctor_sig->ret = &mono_defaults.string_class->byval_arg;
+
+               csignature = ctor_sig;
+       }
+
        /* Intrinsics */
        if (target_method) {
                if (target_method->klass == mono_defaults.string_class) {
@@ -1327,7 +1335,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        MonoMethodHeader *header = mono_method_get_header (method);
        MonoMethodSignature *signature = mono_method_signature (method);
        MonoImage *image = method->klass->image;
-       MonoDomain *domain = mono_domain_get ();
+       MonoDomain *domain = rtm->domain;
        MonoClass *constrained_class = NULL;
        MonoError error;
        int offset, mt, i, i32;
@@ -1461,11 +1469,9 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                        td.stack_state [c->data.filter_offset][0].klass = NULL; /*FIX*/
                }
 
-               if ((c->flags & MONO_EXCEPTION_CLAUSE_FINALLY) || (c->flags & MONO_EXCEPTION_CLAUSE_FAULT)) {
-                       for (int j = c->handler_offset; j < c->handler_offset + c->handler_len; ++j) {
-                               if (td.clause_indexes [j] == -1)
-                                       td.clause_indexes [j] = i;
-                       }
+               for (int j = c->handler_offset; j < c->handler_offset + c->handler_len; ++j) {
+                       if (td.clause_indexes [j] == -1)
+                               td.clause_indexes [j] = i;
                }
        }
 
@@ -3743,10 +3749,14 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                ip += 2;
                                break;
 #endif
-                       case CEE_RETHROW:
+                       case CEE_RETHROW: {
+                               int clause_index = td.clause_indexes [in_offset];
+                               g_assert (clause_index != -1);
                                SIMPLE_OP (td, MINT_RETHROW);
+                               ADD_CODE (&td, rtm->exvar_offsets [clause_index]);
                                generating_code = 0;
                                break;
+                       }
                        case CEE_SIZEOF: {
                                gint32 size;
                                token = read32 (td.ip + 1);
@@ -3877,7 +3887,10 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                ei->try_start = (guint8*)(rtm->code + c->try_offset);
                ei->try_end = (guint8*)(rtm->code + c->try_offset + c->try_len);
                ei->handler_start = (guint8*)(rtm->code + c->handler_offset);
-               if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
+               ei->exvar_offset = rtm->exvar_offsets [i];
+               if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
+                       ei->data.filter = (guint8*)(rtm->code + c->data.filter_offset);
+               } else if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
                } else {
                        ei->data.catch_class = c->data.catch_class;
                }
@@ -3921,12 +3934,12 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
        const MonoOpcode *opcode;
        MonoMethod *m;
        MonoClass *class;
-       MonoDomain *domain = mono_domain_get ();
        unsigned char *is_bb_start;
        int in;
        MonoVTable *method_class_vt;
        int backwards;
        MonoGenericContext *generic_context = NULL;
+       MonoDomain *domain = runtime_method->domain;
 
        // g_printerr ("TRANSFORM(0x%016lx): begin %s::%s\n", mono_thread_current (), method->klass->name, method->name);
        method_class_vt = mono_class_vtable (domain, runtime_method->method->klass);
@@ -4160,6 +4173,14 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
                offset += size;
        }
        offset = (offset + 7) & ~7;
+
+       runtime_method->exvar_offsets = g_malloc (header->num_clauses * sizeof (guint32));
+       for (i = 0; i < header->num_clauses; i++) {
+               offset += sizeof (MonoObject*);
+               runtime_method->exvar_offsets [i] = offset;
+       }
+       offset = (offset + 7) & ~7;
+
        runtime_method->locals_size = offset;
        g_assert (runtime_method->locals_size < 65536);
        offset = 0;