I still think too much junk is in jit_emit.h

The patch attached shows how I would re-factor it.

Kevin

NotFound wrote:
On Fri, Aug 22, 2008 at 9:51 PM, Kevin Tew <[EMAIL PROTECTED]> wrote:

0015a810 t Parrot_store_arg
little t means its not exported.

set_nci_* functions should probably be moved elsewhere.
as well as the Parrot_jit_build_call_func
I found Parrot_jit_build_call_func   in   src/jit/i386/jit_emit.h, so I made
my changes in place.

Parrot_store_arg lacked the PARROT_API attribute. Fixed in r30457


diff --git a/config/auto/jit.pm b/config/auto/jit.pm
index 8897dc3..702bdbd 100644
--- a/config/auto/jit.pm
+++ b/config/auto/jit.pm
@@ -108,7 +108,7 @@ sub runstep {
         jitcapable  => 1,
         cc_hasjit   => " -DHAS_JIT -D\U$jitcpuarch",
         TEMP_jit_o =>
-'$(SRC_DIR)/jit$(O) $(SRC_DIR)/jit_cpu$(O) $(SRC_DIR)/jit_debug$(O) $(SRC_DIR)/jit_debug_xcoff$(O)'
+'$(SRC_DIR)/jit$(O) $(SRC_DIR)/jit_cpu$(O) $(SRC_DIR)/jit_build_call$(O) $(SRC_DIR)/jit_debug$(O) $(SRC_DIR)/jit_debug_xcoff$(O)'
     );
 
     my $execcapable = $self->_first_probe_for_exec(
diff --git a/config/gen/makefiles/root.in b/config/gen/makefiles/root.in
index bc2bc15..aeed059 100644
--- a/config/gen/makefiles/root.in
+++ b/config/gen/makefiles/root.in
@@ -223,6 +223,7 @@ GEN_SOURCES = \
     $(SRC_DIR)/nci.c \
     $(SRC_DIR)/core_ops_switch.c \
     $(SRC_DIR)/jit_cpu.c \
+    $(SRC_DIR)/jit_build_call.c \
     $(SRC_DIR)/parrot_config.c \
     $(SRC_DIR)/null_config.c \
     $(SRC_DIR)/install_config.c \
@@ -1053,6 +1054,8 @@ $(SRC_DIR)/jit_debug_xcoff$(O) : $(GENERAL_H_FILES)
 
 $(SRC_DIR)/jit_cpu$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h
 
+$(SRC_DIR)/jit_build_call$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h
+
 $(SRC_DIR)/exec$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
 
 $(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
@@ -1243,6 +1246,8 @@ $(SRC_DIR)/jit_emit.h : $(SRC_DIR)/jit/@jitcpuarch@/jit_emit.h
 	$(CP) $(SRC_DIR)/jit/@jitcpuarch@/jit_emit.h $(SRC_DIR)/jit_emit.h
 $(SRC_DIR)/exec_dep.h : $(SRC_DIR)/jit/@jitcpuarch@/exec_dep.h
 	$(CP) $(SRC_DIR)/jit/@jitcpuarch@/exec_dep.h $(SRC_DIR)/exec_dep.h
+$(SRC_DIR)/jit_build_call.c : $(SRC_DIR)/jit/@jitcpuarch@/jit_build_call.c
+	$(CP) $(SRC_DIR)/jit/@jitcpuarch@/jit_build_call.c $(SRC_DIR)/jit_build_call.c
 $(SRC_DIR)/jit_cpu.c : lib/Parrot/OpLib/core.pm $(SRC_DIR)/jit_emit.h \
     $(SRC_DIR)/jit/@jitcpuarch@/core.jit $(JIT_BUILD_TOOL)
 	$(PERL) $(JIT_BUILD_TOOL) @jitcpuarch@ $(SRC_DIR)/jit_cpu.c
@@ -1669,6 +1674,7 @@ archclean: dynoplibs-clean dynpmc-clean dynext-clean
     $(SRC_DIR)/asmfun.s \
     $(SRC_DIR)/jit_emit.h \
     $(SRC_DIR)/jit_cpu.c \
+    $(SRC_DIR)/jit_build_call.c \
     $(SRC_DIR)/exec_cpu.c \
     $(SRC_DIR)/exec_start$(O) \
     install_config.fpmc \
diff --git a/include/parrot/nci.h b/include/parrot/nci.h
index 1b85a73..10a133a 100644
--- a/include/parrot/nci.h
+++ b/include/parrot/nci.h
@@ -17,6 +17,27 @@
 
 void *build_call_func(PARROT_INTERP, SHIM(PMC *pmc_nci), NOTNULL(STRING *signature), NOTNULL(int *jitted));
 
+/*
+ * helper funcs - get argument n
+ */
+INTVAL get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n);
+FLOATVAL get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+STRING* get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+PMC* get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n);
+
+/*
+ * set return value
+ */
+void set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val);
+void set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val);
+void set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val);
+void set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val);
 #endif /* PARROT_NCI_H_GUARD */
 
 /*
diff --git a/src/jit/i386/jit_build_call.c b/src/jit/i386/jit_build_call.c
new file mode 100644
index 0000000..94e2e57
--- /dev/null
+++ b/src/jit/i386/jit_build_call.c
@@ -0,0 +1,367 @@
+#include "parrot/parrot.h"
+#include "parrot/hash.h"
+#include "parrot/oplib/ops.h"
+#include "jit.h"
+#define JIT_EMIT 1
+#include "jit_emit.h"
+
+static size_t
+calc_signature_needs(const char *sig, int *strings)
+{
+    size_t stack_size = 0;
+    while (*sig) {
+        switch (*sig) {
+            case 't':
+                (*strings)++;
+                stack_size +=4;
+                break;
+            case 'd':
+                stack_size +=8;
+                break;
+            default:
+                stack_size +=4;
+                break;
+        }
+        sig++;
+    }
+    return stack_size;
+
+}
+/*
+ * The function generated here is called as func(interp, nci_info)
+ * interp   ...  8(%ebp)
+ * nci_info ... 12(%ebp)
+ *
+ * The generate function for a specific signature looks quite similar to
+ * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
+ * just compare the disassembly.
+ */
+void *
+Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
+{
+    Parrot_jit_info_t jit_info;
+    int i = 0;
+    char *pc;
+    int arg_count = 0;
+    int strings   = 0;
+    const int ST_SIZE_OF = 124;
+    const int JIT_ALLOC_SIZE = 1024;
+
+    char *sig = (char *)signature->strstart + 1; /* skip over the result */
+    size_t stack_space_needed = calc_signature_needs(sig, &strings);
+
+    int st_offset = 16 + stack_space_needed;
+    int args_offset = 16;
+    int strings_offset = st_offset + ST_SIZE_OF;
+    int total_stack_needed = strings_offset + 4 * strings;
+
+    /* this ought to be enough - the caller of this function
+     * should free the function pointer returned here
+     */
+    pc = jit_info.native_ptr = jit_info.arena.start = (char *)mem_alloc_executable(JIT_ALLOC_SIZE);
+
+
+    /* this generated jit function will be called as (INTERP (EBP 8), func_ptr (ESP 12), args signature (ESP 16)) */
+    /* make stack frame, preserve %ebx */
+    jit_emit_stack_frame_enter(pc);
+
+    emitm_subl_i_r(pc, total_stack_needed, emit_ESP);
+
+    /* Parrot_init_arg_nci(interp, &st, "S"); */
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+
+    /*&st*/
+    emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+
+    /*interpreter*/
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
+
+    if (sig && *sig)
+      emitm_call_cfunc(pc, Parrot_init_arg_nci);
+
+    while (*sig) {
+        emitm_movl_i_m(pc, arg_count, emit_ESP, 0, 1, 8);
+
+        switch (*sig) {
+            case '0':    /* null ptr or such - doesn't consume a reg */
+                jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'f':
+                emitm_call_cfunc(pc, get_nci_N);
+                emitm_fstps(interp, pc, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'N':
+            case 'd':
+                emitm_call_cfunc(pc, get_nci_N);
+                emitm_fstpl(interp, pc, emit_ESP, 0, 1, args_offset);
+                args_offset += 4;
+                break;
+            case 'I':   /* INTVAL */
+            case 'l':   /* long */
+            case 'i':   /* int */
+                emitm_call_cfunc(pc, get_nci_I);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 't':   /* string, pass a cstring */
+                emitm_call_cfunc(pc, get_nci_S);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+                emitm_call_cfunc(pc, string_to_cstring);
+
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                /* save off temporary allocation address */
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, strings_offset);
+                strings_offset += 4;
+
+                /* reset ESP(4) */
+                emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+                break;
+            case 's':   /* short: movswl intreg_o(base), %eax */
+                emitm_call_cfunc(pc, get_nci_I);
+                emitm_movswl_r_r(pc, emit_EAX, emit_EAX)
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'c':   /* char: movsbl intreg_o(base), %eax */
+                emitm_call_cfunc(pc, get_nci_I);
+                emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'J':   /* interpreter */
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                arg_count--;
+                break;
+            case 'p':   /* push pmc->data */
+                emitm_call_cfunc(pc, get_nci_P);
+#  if ! PMC_DATA_IN_EXT
+                /* mov pmc, %edx
+                 * mov 8(%edx), %eax
+                 * push %eax
+                 */
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
+#  else
+                /* push pmc->pmc_ext->data
+                 * mov pmc, %edx
+                 * mov pmc_ext(%edx), %eax
+                 * mov data(%eax), %eax
+                 * push %eax
+                 */
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, pmc_ext));
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC_EXT, data));
+#  endif
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'O':   /* push PMC * object in P2 */
+            case 'P':   /* push PMC * */
+            case '@':
+                emitm_call_cfunc(pc, get_nci_P);
+#  if PARROT_CATCH_NULL
+                /* PMCNULL is a global */
+                jit_emit_cmp_rm_i(pc, emit_EAX, &PMCNULL);
+                emitm_jxs(pc, emitm_jne, 2); /* skip the xor */
+                jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
+#  endif
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'v':
+                break;
+            case 'V':
+                emitm_call_cfunc(pc, get_nci_P);
+                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
+                /* emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0); */
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'b':   /* buffer (void*) pass PObj_bufstart(SReg) */
+                emitm_call_cfunc(pc, get_nci_S);
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PObj_bufstart((STRING *) 0));
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'B':   /* buffer (void**) pass &PObj_bufstart(SReg) */
+                emitm_call_cfunc(pc, get_nci_S);
+                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PObj_bufstart((STRING *) 0));
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            case 'S':
+                emitm_call_cfunc(pc, get_nci_S);
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+
+
+            /* I have no idea how to handle these */
+            case '2':
+            case '3':
+            case '4':
+                mem_free_executable(jit_info.native_ptr);
+                return NULL;
+                break;
+                /* This might be right. Or not... */
+                /* we need the offset of PMC_int_val */
+                emitm_call_cfunc(pc, get_nci_P);
+                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PMC_int_val((PMC *) 0));
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
+                break;
+            default:
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+                    "Unknown arg Signature %c\n", *sig);
+                /*
+                 * oops unknown signature:
+                 * cleanup and try nci.c
+                 */
+                mem_free_executable(jit_info.native_ptr);
+                return NULL;
+        }
+        args_offset +=4;
+        arg_count++;
+        sig++;
+    }
+
+    emitm_addl_i_r(pc, 16, emit_ESP);
+    /* get the pmc from stack - movl 12(%ebp), %eax */
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
+    emitm_callm(pc, emit_EAX, emit_None, emit_None, 0);
+    emitm_subl_i_r(pc, 16, emit_ESP);
+
+    /* SAVE OFF EAX */
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+
+    /*&st*/
+    emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+
+    /*interpreter*/
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
+
+    /* RESTORE BACK EAX */
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+
+    /* now place return value in registers */
+    /* first in signature is the return value */
+    sig = (char *)signature->strstart; /* the result */
+    switch (*sig) {
+        /* I have no idea how to handle these */
+        case '2':
+        case '3':
+        case '4':
+            /* get integer from pointer - untested */
+            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);
+            if (*sig == 2)      /* short */
+                emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
+            emitm_call_cfunc(pc, set_nci_I);
+            break;
+        case 'f':
+        case 'd':
+            jit_emit_fstore_mb_n(interp, pc, emit_ESP, 8);
+            emitm_call_cfunc(pc, set_nci_N);
+            /* pop num from st(0) and mov to reg */
+            break;
+        case 's':
+            /* movswl %ax, %eax */
+            emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+            emitm_call_cfunc(pc, set_nci_I);
+            break;
+        case 'c':
+            /* movsbl %al, %eax */
+            emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+            emitm_call_cfunc(pc, set_nci_I);
+            break;
+        case 'I':   /* INTVAL */
+        case 'l':
+        case 'i':
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+            emitm_call_cfunc(pc, set_nci_I);
+            break;
+        case 'v': /* void - do nothing */
+            break;
+        case 'P':
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+            emitm_call_cfunc(pc, set_nci_P);
+            break;
+        case 'p':   /* make a new unmanaged struct */
+            /* save return value on stack */
+
+            /* save pointer p */
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 12);
+
+            /* make new pmc */
+            emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_ESP, 0, 1, 4);
+            emitm_call_cfunc(pc, pmc_new);
+
+            /* restore pointer p to EDX */
+            emitm_movl_m_r(interp, pc, emit_EDX, emit_ESP, 0, 1, 12);
+
+            /* copy UnManagedStruct to stack for set_nci_P call */
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+
+            /* eax = PMC, get return value into edx */
+            /* stuff return value into pmc->data */
+
+#  if ! PMC_DATA_IN_EXT
+            /* mov %edx, (data) %eax */
+            emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1, offsetof(struct PMC, data));
+#  else
+            /* mov pmc_ext(%eax), %eax
+               mov %edx, data(%eax) */
+            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, pmc_ext));
+            emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1, offsetof(struct PMC_EXT, data));
+#  endif
+
+            /* reset ESP(4) */
+            emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+
+            emitm_call_cfunc(pc, set_nci_P);
+            break;
+        case 'S':
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+            emitm_call_cfunc(pc, set_nci_S);
+            break;
+        case 't':   /* string */
+            /* EAX is char* */
+            emitm_movl_i_m(pc, 0, emit_ESP, 0, 1, 8); /* len */
+
+            /* overrights addres of st in ESP(4) */
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+
+            emitm_call_cfunc(pc, string_from_cstring);
+
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
+
+            /* reset ESP(4) */
+            emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
+            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
+
+            emitm_call_cfunc(pc, set_nci_S);
+            break;
+        default:
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
+                "Unknown return Signature %c\n", *sig);
+            /*
+             * oops unknown signature:
+             * cleanup and try nci.c
+             */
+            mem_free_executable(jit_info.native_ptr);
+            return NULL;
+    }
+
+    /* free temporary strings */
+    strings_offset = st_offset + ST_SIZE_OF;
+    for (i=0; i<strings; i++) {
+        emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, strings_offset);
+        emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
+        emitm_call_cfunc(pc, string_cstring_free);
+    }
+
+    jit_emit_stack_frame_leave(pc);
+    emitm_ret(pc);
+    PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
+    /* could shrink arena.start here to used size */
+    PObj_active_destroy_SET(pmc_nci);
+    return (void *)D2FPTR(jit_info.arena.start);
+}
diff --git a/src/jit/i386/jit_emit.h b/src/jit/i386/jit_emit.h
index e67061e..3471605 100644
--- a/src/jit/i386/jit_emit.h
+++ b/src/jit/i386/jit_emit.h
@@ -24,113 +24,6 @@
 #include "parrot/hash.h"
 #include "parrot/oplib/ops.h"
 
-/*
- * helper funcs - get argument n
- */
-static INTVAL
-get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
-    if (n >= st->src.n)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "too few arguments passed to NCI function");
-
-    Parrot_fetch_arg_nci(interp, st);
-
-    return UVal_int(st->val);
-}
-
-static FLOATVAL
-get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
-    if (n >= st->src.n)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "too few arguments passed to NCI function");
-
-    Parrot_fetch_arg_nci(interp, st);
-
-    return UVal_num(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING*
-get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
-    /* TODO or act like below? */
-    if (n >= st->src.n)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "too few arguments passed to NCI function");
-
-    Parrot_fetch_arg_nci(interp, st);
-
-    return UVal_str(st->val);
-}
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC*
-get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
-{
-    /*
-     * exessive args are passed as NULL
-     * used by e.g. MMD infix like __add
-     */
-    if (n < st->src.n)
-        Parrot_fetch_arg_nci(interp, st);
-    else
-        UVal_pmc(st->val) = PMCNULL;
-
-    return UVal_pmc(st->val);
-}
-
-/*
- * set return value
- */
-static void
-set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
-{
-    Parrot_init_ret_nci(interp, st, "I");
-    if (st->dest.i < st->dest.n) {
-        UVal_int(st->val) = val;
-        Parrot_convert_arg(interp, st);
-        Parrot_store_arg(interp, st);
-    }
-}
-
-static void
-set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
-{
-    Parrot_init_ret_nci(interp, st, "N");
-    if (st->dest.i < st->dest.n) {
-        UVal_num(st->val) = val;
-        Parrot_convert_arg(interp, st);
-        Parrot_store_arg(interp, st);
-    }
-}
-
-static void
-set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
-{
-    Parrot_init_ret_nci(interp, st, "S");
-    if (st->dest.i < st->dest.n) {
-        UVal_str(st->val) = val;
-        Parrot_convert_arg(interp, st);
-        Parrot_store_arg(interp, st);
-    }
-}
-
-static void
-set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
-{
-    Parrot_init_ret_nci(interp, st, "P");
-    if (st->dest.i < st->dest.n) {
-        UVal_pmc(st->val) = val;
-        Parrot_convert_arg(interp, st);
-        Parrot_store_arg(interp, st);
-    }
-}
-
-
 #if defined HAVE_COMPUTED_GOTO && defined __GNUC__ && PARROT_I386_JIT_CGP
 #  define JIT_CGP
 #endif
@@ -3822,367 +3715,6 @@ count_regs(PARROT_INTERP, char *sig, char *sig_start)
     return first_reg;
 }
 
-static size_t
-calc_signature_needs(const char *sig, int *strings)
-{
-    size_t stack_size = 0;
-    while (*sig) {
-        switch (*sig) {
-            case 't':
-                (*strings)++;
-                stack_size +=4;
-                break;
-            case 'd':
-                stack_size +=8;
-                break;
-            default:
-                stack_size +=4;
-                break;
-        }
-        sig++;
-    }
-    return stack_size;
-
-}
-/*
- * The function generated here is called as func(interp, nci_info)
- * interp   ...  8(%ebp)
- * nci_info ... 12(%ebp)
- *
- * The generate function for a specific signature looks quite similar to
- * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
- * just compare the disassembly.
- */
-void *
-Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
-{
-    Parrot_jit_info_t jit_info;
-    int i = 0;
-    char *pc;
-    int arg_count = 0;
-    int strings   = 0;
-    const int ST_SIZE_OF = 124;
-    const int JIT_ALLOC_SIZE = 1024;
-
-    char *sig = (char *)signature->strstart + 1; /* skip over the result */
-    size_t stack_space_needed = calc_signature_needs(sig, &strings);
-
-    int st_offset = 16 + stack_space_needed;
-    int args_offset = 16;
-    int strings_offset = st_offset + ST_SIZE_OF;
-    int total_stack_needed = strings_offset + 4 * strings;
-
-    /* this ought to be enough - the caller of this function
-     * should free the function pointer returned here
-     */
-    pc = jit_info.native_ptr = jit_info.arena.start = (char *)mem_alloc_executable(JIT_ALLOC_SIZE);
-
-
-    /* this generated jit function will be called as (INTERP (EBP 8), func_ptr (ESP 12), args signature (ESP 16)) */
-    /* make stack frame, preserve %ebx */
-    jit_emit_stack_frame_enter(pc);
-
-    emitm_subl_i_r(pc, total_stack_needed, emit_ESP);
-
-    /* Parrot_init_arg_nci(interp, &st, "S"); */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 16);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-
-    /*&st*/
-    emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-
-    /*interpreter*/
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
-
-    if (sig && *sig)
-      emitm_call_cfunc(pc, Parrot_init_arg_nci);
-
-    while (*sig) {
-        emitm_movl_i_m(pc, arg_count, emit_ESP, 0, 1, 8);
-
-        switch (*sig) {
-            case '0':    /* null ptr or such - doesn't consume a reg */
-                jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'f':
-                emitm_call_cfunc(pc, get_nci_N);
-                emitm_fstps(interp, pc, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'N':
-            case 'd':
-                emitm_call_cfunc(pc, get_nci_N);
-                emitm_fstpl(interp, pc, emit_ESP, 0, 1, args_offset);
-                args_offset += 4;
-                break;
-            case 'I':   /* INTVAL */
-            case 'l':   /* long */
-            case 'i':   /* int */
-                emitm_call_cfunc(pc, get_nci_I);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 't':   /* string, pass a cstring */
-                emitm_call_cfunc(pc, get_nci_S);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-                emitm_call_cfunc(pc, string_to_cstring);
-
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                /* save off temporary allocation address */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, strings_offset);
-                strings_offset += 4;
-
-                /* reset ESP(4) */
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-                break;
-            case 's':   /* short: movswl intreg_o(base), %eax */
-                emitm_call_cfunc(pc, get_nci_I);
-                emitm_movswl_r_r(pc, emit_EAX, emit_EAX)
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'c':   /* char: movsbl intreg_o(base), %eax */
-                emitm_call_cfunc(pc, get_nci_I);
-                emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'J':   /* interpreter */
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                arg_count--;
-                break;
-            case 'p':   /* push pmc->data */
-                emitm_call_cfunc(pc, get_nci_P);
-#  if ! PMC_DATA_IN_EXT
-                /* mov pmc, %edx
-                 * mov 8(%edx), %eax
-                 * push %eax
-                 */
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
-#  else
-                /* push pmc->pmc_ext->data
-                 * mov pmc, %edx
-                 * mov pmc_ext(%edx), %eax
-                 * mov data(%eax), %eax
-                 * push %eax
-                 */
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, pmc_ext));
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC_EXT, data));
-#  endif
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'O':   /* push PMC * object in P2 */
-            case 'P':   /* push PMC * */
-            case '@':
-                emitm_call_cfunc(pc, get_nci_P);
-#  if PARROT_CATCH_NULL
-                /* PMCNULL is a global */
-                jit_emit_cmp_rm_i(pc, emit_EAX, &PMCNULL);
-                emitm_jxs(pc, emitm_jne, 2); /* skip the xor */
-                jit_emit_bxor_rr_i(interp, pc, emit_EAX, emit_EAX);
-#  endif
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'v':
-                break;
-            case 'V':
-                emitm_call_cfunc(pc, get_nci_P);
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
-                /* emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0); */
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'b':   /* buffer (void*) pass PObj_bufstart(SReg) */
-                emitm_call_cfunc(pc, get_nci_S);
-                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PObj_bufstart((STRING *) 0));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'B':   /* buffer (void**) pass &PObj_bufstart(SReg) */
-                emitm_call_cfunc(pc, get_nci_S);
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PObj_bufstart((STRING *) 0));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            case 'S':
-                emitm_call_cfunc(pc, get_nci_S);
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-
-
-            /* I have no idea how to handle these */
-            case '2':
-            case '3':
-            case '4':
-                mem_free_executable(jit_info.native_ptr);
-                return NULL;
-                break;
-                /* This might be right. Or not... */
-                /* we need the offset of PMC_int_val */
-                emitm_call_cfunc(pc, get_nci_P);
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, (size_t) &PMC_int_val((PMC *) 0));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, args_offset);
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                    "Unknown arg Signature %c\n", *sig);
-                /*
-                 * oops unknown signature:
-                 * cleanup and try nci.c
-                 */
-                mem_free_executable(jit_info.native_ptr);
-                return NULL;
-        }
-        args_offset +=4;
-        arg_count++;
-        sig++;
-    }
-
-    emitm_addl_i_r(pc, 16, emit_ESP);
-    /* get the pmc from stack - movl 12(%ebp), %eax */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
-    emitm_callm(pc, emit_EAX, emit_None, emit_None, 0);
-    emitm_subl_i_r(pc, 16, emit_ESP);
-
-    /* SAVE OFF EAX */
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-
-    /*&st*/
-    emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-
-    /*interpreter*/
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
-    emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
-
-    /* RESTORE BACK EAX */
-    emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-
-    /* now place return value in registers */
-    /* first in signature is the return value */
-    sig = (char *)signature->strstart; /* the result */
-    switch (*sig) {
-        /* I have no idea how to handle these */
-        case '2':
-        case '3':
-        case '4':
-            /* get integer from pointer - untested */
-            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0);
-            if (*sig == 2)      /* short */
-                emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
-            emitm_call_cfunc(pc, set_nci_I);
-            break;
-        case 'f':
-        case 'd':
-            jit_emit_fstore_mb_n(interp, pc, emit_ESP, 8);
-            emitm_call_cfunc(pc, set_nci_N);
-            /* pop num from st(0) and mov to reg */
-            break;
-        case 's':
-            /* movswl %ax, %eax */
-            emitm_movswl_r_r(pc, emit_EAX, emit_EAX);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-            emitm_call_cfunc(pc, set_nci_I);
-            break;
-        case 'c':
-            /* movsbl %al, %eax */
-            emitm_movsbl_r_r(pc, emit_EAX, emit_EAX);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-            emitm_call_cfunc(pc, set_nci_I);
-            break;
-        case 'I':   /* INTVAL */
-        case 'l':
-        case 'i':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-            emitm_call_cfunc(pc, set_nci_I);
-            break;
-        case 'v': /* void - do nothing */
-            break;
-        case 'P':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-            emitm_call_cfunc(pc, set_nci_P);
-            break;
-        case 'p':   /* make a new unmanaged struct */
-            /* save return value on stack */
-
-            /* save pointer p */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 12);
-
-            /* make new pmc */
-            emitm_movl_i_m(pc, enum_class_UnManagedStruct, emit_ESP, 0, 1, 4);
-            emitm_call_cfunc(pc, pmc_new);
-
-            /* restore pointer p to EDX */
-            emitm_movl_m_r(interp, pc, emit_EDX, emit_ESP, 0, 1, 12);
-
-            /* copy UnManagedStruct to stack for set_nci_P call */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-
-            /* eax = PMC, get return value into edx */
-            /* stuff return value into pmc->data */
-
-#  if ! PMC_DATA_IN_EXT
-            /* mov %edx, (data) %eax */
-            emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1, offsetof(struct PMC, data));
-#  else
-            /* mov pmc_ext(%eax), %eax
-               mov %edx, data(%eax) */
-            emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, pmc_ext));
-            emitm_movl_r_m(interp, pc, emit_EDX, emit_EAX, 0, 1, offsetof(struct PMC_EXT, data));
-#  endif
-
-            /* reset ESP(4) */
-            emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-
-            emitm_call_cfunc(pc, set_nci_P);
-            break;
-        case 'S':
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-            emitm_call_cfunc(pc, set_nci_S);
-            break;
-        case 't':   /* string */
-            /* EAX is char* */
-            emitm_movl_i_m(pc, 0, emit_ESP, 0, 1, 8); /* len */
-
-            /* overrights addres of st in ESP(4) */
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-
-            emitm_call_cfunc(pc, string_from_cstring);
-
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 8);
-
-            /* reset ESP(4) */
-            emitm_lea_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, st_offset);
-            emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 4);
-
-            emitm_call_cfunc(pc, set_nci_S);
-            break;
-        default:
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
-                "Unknown return Signature %c\n", *sig);
-            /*
-             * oops unknown signature:
-             * cleanup and try nci.c
-             */
-            mem_free_executable(jit_info.native_ptr);
-            return NULL;
-    }
-
-    /* free temporary strings */
-    strings_offset = st_offset + ST_SIZE_OF;
-    for (i=0; i<strings; i++) {
-        emitm_movl_m_r(interp, pc, emit_EAX, emit_ESP, 0, 1, strings_offset);
-        emitm_movl_r_m(interp, pc, emit_EAX, emit_ESP, 0, 1, 0);
-        emitm_call_cfunc(pc, string_cstring_free);
-    }
-
-    jit_emit_stack_frame_leave(pc);
-    emitm_ret(pc);
-    PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
-    /* could shrink arena.start here to used size */
-    PObj_active_destroy_SET(pmc_nci);
-    return (void *)D2FPTR(jit_info.arena.start);
-}
-
 #endif
 
 #if JIT_EMIT == 0
diff --git a/tools/build/nativecall.pl b/tools/build/nativecall.pl
index 4532792..974f0d6 100644
--- a/tools/build/nativecall.pl
+++ b/tools/build/nativecall.pl
@@ -311,7 +311,7 @@ sub print_head {
 /*
  * helper funcs - get argument n
  */
-static INTVAL
+INTVAL
 get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
 {
     if (n >= st->src.n)
@@ -323,7 +323,7 @@ get_nci_I(PARROT_INTERP, ARGMOD(call_state *st), int n)
     return UVal_int(st->val);
 }
 
-static FLOATVAL
+FLOATVAL
 get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
 {
     if (n >= st->src.n)
@@ -337,7 +337,7 @@ get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static STRING*
+STRING*
 get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
 {
     /* TODO or act like below? */
@@ -352,7 +352,7 @@ get_nci_S(PARROT_INTERP, ARGMOD(call_state *st), int n)
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static PMC*
+PMC*
 get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
 {
     /*
@@ -375,7 +375,7 @@ get_nci_P(PARROT_INTERP, ARGMOD(call_state *st), int n)
 /*
  * set return value
  */
-static void
+void
 set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
 {
     Parrot_init_ret_nci(interp, st, "I");
@@ -386,7 +386,7 @@ set_nci_I(PARROT_INTERP, ARGOUT(call_state *st), INTVAL val)
     }
 }
 
-static void
+void
 set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
 {
     Parrot_init_ret_nci(interp, st, "N");
@@ -397,7 +397,7 @@ set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
     }
 }
 
-static void
+void
 set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
 {
     Parrot_init_ret_nci(interp, st, "S");
@@ -408,7 +408,7 @@ set_nci_S(PARROT_INTERP, ARGOUT(call_state *st), STRING *val)
     }
 }
 
-static void
+void
 set_nci_P(PARROT_INTERP, ARGOUT(call_state *st), PMC* val)
 {
     Parrot_init_ret_nci(interp, st, "P");

Reply via email to