Mon Feb 11 12:32:35 CET 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / arch / x86 / tramp.c
index afa3a79ecee9889b0a2e19bd816f12455dee008e..e9fef810eebba32324c507a0962144a6df96a4a0 100644 (file)
@@ -27,7 +27,7 @@
 #define ARG_SIZE       sizeof (stackval)
 
 MonoPIFunc
-mono_create_trampoline (MonoMethod *method)
+mono_create_trampoline (MonoMethod *method, int runtime)
 {
        MonoMethodSignature *sig;
        unsigned char *p, *code_buffer;
@@ -176,7 +176,7 @@ enum_marshal:
                         * If it is an internalcall we assume it's the object we want.
                         * Yet another reason why MONO_TYPE_STRING should not be used to indicate char*.
                         */
-                       if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+                       if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || runtime) {
                                x86_push_membase (p, X86_EDX, arg_pos);
                                break;
                        }
@@ -258,12 +258,15 @@ enum_retvalue:
                        x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4);
                        break;
                case MONO_TYPE_STRING: 
-                       if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+                       if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || runtime) {
                                x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4);
                                x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4);
                                break;
                        }
 
+                       /* If the argument is non-null, then convert the value back */
+                       x86_alu_reg_reg (p, X86_OR, X86_EAX, X86_EAX);
+                       x86_branch8 (p, X86_CC_EQ, 11, FALSE);
                        x86_push_reg (p, X86_EAX);
                        x86_mov_reg_imm (p, X86_EDX, mono_string_new);
                        x86_call_reg (p, X86_EDX);
@@ -301,9 +304,8 @@ enum_retvalue:
         * free the allocated strings.
         */
        if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
-               if (local_size)
-                       x86_mov_reg_imm (p, X86_EDX, g_free);
                for (i = 1; i <= local_size; ++i) {
+                       x86_mov_reg_imm (p, X86_EDX, g_free);
                        x86_push_membase (p, X86_EBP, LOC_POS * i);
                        x86_call_reg (p, X86_EDX);
                }
@@ -481,4 +483,16 @@ mono_create_method_pointer (MonoMethod *method)
        return g_memdup (code_buffer, p - code_buffer);
 }
 
-
+/*
+ * mono_create_method_pointer () will insert a pointer to the MonoMethod
+ * so that the interp can easily get at the data: this function will retrieve 
+ * the method from the code stream.
+ */
+MonoMethod*
+mono_method_pointer_get (void *code)
+{
+       unsigned char *c = code;
+       if (c [2] != 'M' || c [3] != 'o')
+               return NULL;
+       return *(MonoMethod**)(code + sizeof (gpointer));
+}