Author: nickg
Date: Wed Jan 11 09:31:05 2006
New Revision: 11091

Modified:
   branches/nci/NCI_NOTES.txt
   branches/nci/config/gen/makefiles/root.in
   branches/nci/include/parrot/nci.h
   branches/nci/src/classes/nci.pmc
   branches/nci/src/nci_ffcall.c
   branches/nci/tools/build/nci_builtin_c.pl
Log:
NCI #6. An intermediate step.
Hacked nci_ffcall.c so that it can sit behind the vtables.
Makefile hardcoded to compile nci_ffcall.c for now.
nci.pmc currently uses ffcall implementation.
Passes all tests except for the one that clones. (Callbacks still using builtin
implementation)

Next to factor common code out of nci_builtin and nci_ffcall.


Modified: branches/nci/NCI_NOTES.txt
==============================================================================
--- branches/nci/NCI_NOTES.txt  (original)
+++ branches/nci/NCI_NOTES.txt  Wed Jan 11 09:31:05 2006
@@ -38,7 +38,8 @@ signatures.
 When the invoke method is called, the main nci ffcall invoke routine
 is called mostly makes ffcall calls based on the two signatures.
 
-
+PMC must store: address of library function, and two signatures
+Will probably also get it to store the ffcall NCI layer function
 
 
 Suggested unification:

Modified: branches/nci/config/gen/makefiles/root.in
==============================================================================
--- branches/nci/config/gen/makefiles/root.in   (original)
+++ branches/nci/config/gen/makefiles/root.in   Wed Jan 11 09:31:05 2006
@@ -419,6 +419,7 @@ INTERP_O_FILES = \
        $(SRC_DIR)/datatypes$(O) \
        $(SRC_DIR)/fingerprint$(O) \
        $(SRC_DIR)/nci_builtin$(O) \
+       $(SRC_DIR)/nci_ffcall$(O) \
        $(SRC_DIR)/cpu_dep$(O) \
        $(SRC_DIR)/tsq$(O) \
        $(SRC_DIR)/longopt$(O) \
@@ -558,6 +559,7 @@ STR_FILES = \
        $(SRC_DIR)/builtin.str \
        $(SRC_DIR)/inter_call.str \
        $(SRC_DIR)/inter_cb.str \
+       $(SRC_DIR)/nci_ffcall.str \
        $(SRC_DIR)/inter_misc.str \
        $(SRC_DIR)/global.str \
        $(SRC_DIR)/global_setup.str \
@@ -1069,6 +1071,9 @@ $(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES)
 
 $(SRC_DIR)/nci_builtin$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci_builtin.c
 
+$(SRC_DIR)/nci_ffcall$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci_ffcall.c \
+       $(SRC_DIR)/nci_ffcall.str
+
 $(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c
 
 $(SRC_DIR)/cpu_dep$(O) : $(GENERAL_H_FILES)

Modified: branches/nci/include/parrot/nci.h
==============================================================================
--- branches/nci/include/parrot/nci.h   (original)
+++ branches/nci/include/parrot/nci.h   Wed Jan 11 09:31:05 2006
@@ -16,13 +16,11 @@
 #include "parrot/parrot.h"
 #include "parrot/method_util.h"
 
-typedef void* (*nci_new_method_t)(Interp* interpreter, 
-                                  PMC* pmc, STRING* signature);
-typedef void* (*nci_clone_method_t)(void *context);
-typedef void  (*nci_invoke_method_t)(Interp* interpreter,
-                                     Parrot_csub_t func,
-                                     PMC* pmc);
-typedef void  (*nci_free_method_t)(void * context);
+typedef void (*nci_new_method_t)(Interp* interpreter, PMC* pmc,
+                                 STRING* signature, Parrot_csub_t func);
+typedef void (*nci_clone_method_t)(Interp* interpreter,  PMC* pmc1, PMC* pmc2);
+typedef void (*nci_invoke_method_t)(Interp* interpreter, PMC* pmc);
+typedef void (*nci_free_method_t)(Interp* interpreter, PMC *pmc);
 
 
 struct nci_vtable {

Modified: branches/nci/src/classes/nci.pmc
==============================================================================
--- branches/nci/src/classes/nci.pmc    (original)
+++ branches/nci/src/classes/nci.pmc    Wed Jan 11 09:31:05 2006
@@ -26,8 +26,8 @@ The caller has to preserve registers if 
 #include "parrot/method_util.h"
 
 
-extern struct nci_vtable nci_builtin_vtable;
-struct nci_vtable *nci_vtable_ptr = &nci_builtin_vtable;
+extern struct nci_vtable nci_builtin_vtable, nci_ffcall_vtable;
+struct nci_vtable *nci_vtable_ptr = &nci_ffcall_vtable;
 
 pmclass NCI need_ext {
 
@@ -58,11 +58,10 @@ Sets the specified function pointer and 
 
     void set_pointer_keyed_str(STRING *key, void *func) {
         /* key = signature */
-        PMC_struct_val(SELF) = func;
 
-       nci_vtable_ptr->nci_free (PMC_data(SELF));
+       nci_vtable_ptr->nci_free (INTERP, SELF);
 
-        PMC_data(SELF) = nci_vtable_ptr->nci_new (INTERP, SELF, key);
+        nci_vtable_ptr->nci_new (INTERP, SELF, key, func);
     }
 
 /*
@@ -76,7 +75,7 @@ Destroys the NCI, freeing any allocated 
 */
 
     void destroy() {
-      nci_vtable_ptr->nci_free (PMC_data(SELF));
+      nci_vtable_ptr->nci_free (INTERP, SELF);
     }
 
 /*
@@ -91,14 +90,9 @@ Creates and returns a clone of the NCI.
 
     PMC* clone () {
         PMC* ret = pmc_new_noinit(INTERP, SELF->vtable->base_type);
-        PMC_struct_val(ret) = PMC_struct_val(SELF);
-        PMC_pmc_val(ret) = NULL;
-        /* FIXME if data is malloced (JIT/i386!) then we need
-         * the length of data here, to memcpy it
-         * ManagedStruct or Buffer?
-         */
-        PMC_data(ret) = nci_vtable_ptr->nci_clone (PMC_data(SELF));
+        nci_vtable_ptr->nci_clone (INTERP, ret, SELF);        
         PObj_get_FLAGS(ret) |= (PObj_get_FLAGS(SELF) & 0x3);
+
         return ret;
     }
 
@@ -113,7 +107,7 @@ Returns whether the NCI is defined.
 */
 
     INTVAL defined () {
-        return PMC_data(SELF) != NULL;
+        return PMC_struct_val(SELF) != NULL;
     }
 
 /*
@@ -129,13 +123,9 @@ shifted down.
 */
 
     void* invoke (void * next) {
-        Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(SELF));
 
         INTERP->current_cont = NULL;
 
-        if (!func)
-            real_exception(INTERP, NULL, INVALID_OPERATION,
-                "attempt to call NULL function");
         /*
          * If the invocant is a class or there is no invocant
          * shift down arguments.
@@ -148,7 +138,7 @@ shifted down.
          *
          */
 
-        nci_vtable_ptr->nci_invoke (INTERP, func, SELF);
+        nci_vtable_ptr->nci_invoke (INTERP, SELF);
 
         return next;
     }

Modified: branches/nci/src/nci_ffcall.c
==============================================================================
--- branches/nci/src/nci_ffcall.c       (original)
+++ branches/nci/src/nci_ffcall.c       Wed Jan 11 09:31:05 2006
@@ -25,6 +25,9 @@ src/nci_ffcall.c - NCI Implementation us
 #include "parrot/method_util.h"
 #include "parrot/oplib/ops.h"
 
+#include "parrot/nci.h"
+#include "nci_ffcall.str"
+
 #if defined(HAS_JIT) && defined(I386)
 #  include "parrot/exec.h"
 #  include "parrot/jit.h"
@@ -61,6 +64,8 @@ typedef union UnionArg
 
 typedef struct NCIArgs
 {
+    Parrot_csub_t func;
+
     char *signature;
     char *signature_parrot;
 
@@ -213,55 +218,53 @@ static char *convert_signature (const ch
 /* =========== Main NCI call code =========== */
 
 
-extern void nci_invoke (Interp * interpreter, PMC *function);
-
+extern void nci_ffcall_invoke (Interp * interpreter, PMC *function);
 
-void *
-build_call_func(Interp *interpreter, PMC *pmc_nci,
-               STRING *signature)
+static void
+nci_ffcall_new (Interp *interpreter, PMC *pmc,
+                 STRING *signature, Parrot_csub_t func)
 {
-    NCIArgs* nci_args = (NCIArgs *) malloc (sizeof (NCIArgs));
+    NCIArgs* nci_args = (NCIArgs *) mem_sys_allocate (sizeof (NCIArgs));
 
+    nci_args->func = func;
     nci_args->signature = string_to_cstring (interpreter, signature);
-
     nci_args->signature_parrot = convert_signature (nci_args->signature);
 
-    PMC_pmc_val (pmc_nci) = nci_args;
+    PMC_data(pmc) = nci_args;
 
-    return nci_invoke;
+    PMC_struct_val(pmc) = nci_ffcall_invoke;
 }
 
-void *
-clone_call_func(Interp *interpreter, PMC *pmc_nci, void *args)
+static void nci_ffcall_clone (Interp * interpreter, PMC* pmc1, PMC* pmc2)
 {
-    NCIArgs* nci_args = args;
+     NCIArgs* nci_args = PMC_data(pmc2);
 
-    if (!nci_args) return NULL;
-
-    // XXX Can't clone yet
-    return NULL;
-
-    return build_call_func (interpreter, pmc_nci, nci_args->signature);
+     /* XXX: Fix signature passed */
+     nci_ffcall_new (interpreter, pmc1,
+                    0,
+                    nci_args->func);
 }
 
 
-void release_call_func(void *args)
+static void nci_ffcall_free (Interp *interpreter, PMC *pmc)
 {
+#if 0
   NCIArgs* nci_args = args;
   
   if (nci_args)
     {
-      free (nci_args->signature);
-      free (nci_args->signature_parrot);
+      mem_sys_free (nci_args->signature);
+      mem_sys_free (nci_args->signature_parrot);
 
-      free (nci_args);
+      mem_sys_free (nci_args);
     }
+#endif
 }
 
 
-void nci_invoke (Interp * interpreter, PMC *function)
+static void nci_ffcall_invoke (Interp *interpreter, PMC * pmc)
 {
-    PMC *pmc;
+    PMC *temp;
     unsigned int i, length;
     struct call_state st;
     char *signature;
@@ -269,17 +272,17 @@ void nci_invoke (Interp * interpreter, P
 
     av_alist alist;
 
-    NCIArgs* nci_args = (NCIArgs *) PMC_pmc_val(function);
+    NCIArgs* nci_args = (NCIArgs *) PMC_data(pmc);
 
     signature = nci_args->signature;
-    pointer = PMC_struct_val(function);
+    pointer = nci_args->func;
 
     /* Set up return type for function */
     switch (signature[0])
         {
 
         case 'p':
-       case 'P':
+        case 'P':
             av_start_ptr (alist, pointer, void *, &nci_args->result._pointer);
             break;
 
@@ -332,22 +335,22 @@ void nci_invoke (Interp * interpreter, P
             switch (signature[i+1])
                 {
                 case 'J':
-                    pmc = GET_NCI_P (i);
+                    temp = GET_NCI_P (i);
                     av_ptr (alist, void *, interpreter);
                     break;
 
                 case 'p':
-                    pmc = GET_NCI_P (i);
-                    nci_args->args[i]._pointer = PMC_data (pmc);
+                    temp = GET_NCI_P (i);
+                    nci_args->args[i]._pointer = PMC_data (temp);
                     av_ptr (alist, void *, nci_args->args[i]._pointer);
                     break;
 
                 case 'P':
-                    pmc = GET_NCI_P (i);                    
+                    temp = GET_NCI_P (i);                    
                     nci_args->args[i]._pointer =
-                        pmc == PMCNULL
+                        temp == PMCNULL
                         ? NULL
-                        : pmc;
+                        : temp;
                     av_ptr (alist, void *, nci_args->args[i]._pointer);
                     break;
 
@@ -398,23 +401,23 @@ void nci_invoke (Interp * interpreter, P
                     break;
 
                 case '2':
-                    pmc = GET_NCI_P (i);
-                    nci_args->args[i]._short_p = malloc (sizeof (short));
-                    *nci_args->args[i]._long_p = PMC_int_val (pmc);
+                    temp = GET_NCI_P (i);
+                    nci_args->args[i]._short_p = mem_sys_allocate (sizeof 
(short));
+                    *nci_args->args[i]._long_p = PMC_int_val (temp);
                     av_ptr (alist, short *, nci_args->args[i]._short_p);
                     break;
 
                 case '4':
-                    pmc = GET_NCI_P (i);
-                    nci_args->args[i]._long_p = malloc (sizeof (long));
-                    *nci_args->args[i]._long_p = PMC_int_val (pmc);
+                    temp = GET_NCI_P (i);
+                    nci_args->args[i]._long_p = mem_sys_allocate (sizeof 
(long));
+                    *nci_args->args[i]._long_p = PMC_int_val (temp);
                     av_ptr (alist, long *, nci_args->args[i]._long_p);
                     break;
 
                 case '3':
-                    pmc = GET_NCI_P (i);
-                    nci_args->args[i]._int_p = malloc (sizeof (int));
-                    *nci_args->args[i]._long_p = PMC_int_val (pmc);
+                    temp = GET_NCI_P (i);
+                    nci_args->args[i]._int_p = mem_sys_allocate (sizeof (int));
+                    *nci_args->args[i]._long_p = PMC_int_val (temp);
                     av_ptr (alist, int *, nci_args->args[i]._int_p);
                     break;
 
@@ -423,7 +426,7 @@ void nci_invoke (Interp * interpreter, P
                     break;
 
                 default:
-                    pmc = GET_NCI_P (i);
+                    temp = GET_NCI_P (i);
                     PIO_eprintf(interpreter, "Bad nci argument type '%c'\n",
                                 signature[i+1]);
                     break;
@@ -444,31 +447,31 @@ void nci_invoke (Interp * interpreter, P
             switch (signature[i+1])
                 {
                 case '2':
-                    pmc = GET_NCI_P (i);
-                    PMC_int_val (pmc) = *nci_args->args[i]._short_p;
-                    free (nci_args->args[i]._short_p);
+                    temp = GET_NCI_P (i);
+                    PMC_int_val (temp) = *nci_args->args[i]._short_p;
+                    mem_sys_free (nci_args->args[i]._short_p);
                     break;
 
 
                 case '3':
-                    pmc = GET_NCI_P (i);
-                    PMC_int_val (pmc) = *nci_args->args[i]._int_p;
-                    free (nci_args->args[i]._int_p);
+                    temp = GET_NCI_P (i);
+                    PMC_int_val (temp) = *nci_args->args[i]._int_p;
+                    mem_sys_free (nci_args->args[i]._int_p);
                     break;
 
                 case '4':
-                    pmc = GET_NCI_P (i);
-                    PMC_int_val (pmc) = *nci_args->args[i]._long_p;
-                    free (nci_args->args[i]._long_p);
+                    temp = GET_NCI_P (i);
+                    PMC_int_val (temp) = *nci_args->args[i]._long_p;
+                    mem_sys_free (nci_args->args[i]._long_p);
                     break;
 
                 case 't':
-                    free (nci_args->args[i]._string);
+                    mem_sys_free (nci_args->args[i]._string);
                     break;
 
                 default:
                     // This is required to synchronise the arguments
-                    pmc = GET_NCI_P (i);
+                    temp = GET_NCI_P (i);
                     break;
                 }
         }
@@ -480,9 +483,9 @@ void nci_invoke (Interp * interpreter, P
         {
         case 'p':
         case 'P':
-            pmc = pmc_new(interpreter, enum_class_UnManagedStruct);
-            PMC_data (pmc) = nci_args->result._pointer;
-            set_nci_P (interpreter, &st, pmc);
+            temp = pmc_new(interpreter, enum_class_UnManagedStruct);
+            PMC_data (temp) = nci_args->result._pointer;
+            set_nci_P (interpreter, &st, temp);
             break;
 
         case 'c':
@@ -704,62 +707,62 @@ static void Parrot_callback_trampoline (
 
     for (i = 0 ; i < length ; i++)
         {
-         signature_parrot[i] = (p[i] == 'v') ? 'v' : 'P';
+          signature_parrot[i] = (p[i] == 'v') ? 'v' : 'P';
         }
     
     /* Make actual call to parrot callback */
     pmc = Parrot_runops_fromc_args (interpreter, sub,
-                                   signature_parrot, 
-                                   pmc_args[0],
-                                   pmc_args[1],
-                                   pmc_args[2],
-                                   pmc_args[3],
-                                   pmc_args[4],
-                                   pmc_args[5],
-                                   pmc_args[6],
-                                   pmc_args[7],
-                                   pmc_args[8],
-                                   pmc_args[9]);
+                                    signature_parrot, 
+                                    pmc_args[0],
+                                    pmc_args[1],
+                                    pmc_args[2],
+                                    pmc_args[3],
+                                    pmc_args[4],
+                                    pmc_args[5],
+                                    pmc_args[6],
+                                    pmc_args[7],
+                                    pmc_args[8],
+                                    pmc_args[9]);
 
     /* Retrieve returned value */
 
     switch (p[0])
         {
         case 'p':
-           va_return_ptr (alist, void *, PMC_data (pmc));
-           break;
+            va_return_ptr (alist, void *, PMC_data (pmc));
+            break;
 
         case 'c':
-           va_return_char (alist, VTABLE_get_integer (interpreter, pmc));
+            va_return_char (alist, VTABLE_get_integer (interpreter, pmc));
             break;
 
         case 's':
-           va_return_short (alist, VTABLE_get_integer (interpreter, pmc));
+            va_return_short (alist, VTABLE_get_integer (interpreter, pmc));
             break;
 
         case 'i':
-           va_return_int (alist, VTABLE_get_integer (interpreter, pmc));
+            va_return_int (alist, VTABLE_get_integer (interpreter, pmc));
             break;
 
         case 'l':
-           va_return_long (alist, VTABLE_get_integer (interpreter, pmc));
+            va_return_long (alist, VTABLE_get_integer (interpreter, pmc));
             break;
 
         case 'f':
-           va_return_float (alist, VTABLE_get_number (interpreter, pmc));
+            va_return_float (alist, VTABLE_get_number (interpreter, pmc));
             break;
 
         case 'd':
-           va_return_double (alist, VTABLE_get_number (interpreter, pmc));
+            va_return_double (alist, VTABLE_get_number (interpreter, pmc));
             break;
 
         case 't':
-           /* This will leak memory */
-           va_return_ptr (alist,
-                          char *,
-                          string_to_cstring(interpreter,
-                                            VTABLE_get_string (interpreter,
-                                                               pmc)));
+            /* This will leak memory */
+            va_return_ptr (alist,
+                           char *,
+                           string_to_cstring(interpreter,
+                                             VTABLE_get_string (interpreter,
+                                                                pmc)));
             break;
 
         case 'v':
@@ -770,10 +773,10 @@ static void Parrot_callback_trampoline (
 }
 
 
-
+#if 0
 PMC*
-Parrot_make_cb (Parrot_Interp interpreter, PMC* sub, PMC* user_data,
-               STRING *cb_signature)
+Parrot_make_cb (Parrot_Interp interpreter, PMC* sub,
+                PMC* user_data, STRING *cb_signature)
 {
 
     PMC* interp_pmc, *cb, *cb_sig;
@@ -802,7 +805,7 @@ Parrot_make_cb (Parrot_Interp interprete
     dod_register_pmc(interpreter, cb);
 
     callback = alloc_callback (Parrot_callback_trampoline,
-                              user_data);
+                               user_data);
 
     PMC_data(cb) = callback;
 
@@ -814,10 +817,20 @@ Parrot_make_cb (Parrot_Interp interprete
 
 void
 Parrot_run_callback(Parrot_Interp interpreter,
-                   PMC* user_data, void* external_data)
+                    PMC* user_data, void* external_data)
 {
     internal_exception(1, "Parrot_run_callback needs implementing for ffcall");
 }
+#endif
+
+
+struct nci_vtable nci_ffcall_vtable =
+{
+    nci_ffcall_new,
+    nci_ffcall_clone,
+    nci_ffcall_invoke,
+    nci_ffcall_free
+};
 
 
 /*

Modified: branches/nci/tools/build/nci_builtin_c.pl
==============================================================================
--- branches/nci/tools/build/nci_builtin_c.pl   (original)
+++ branches/nci/tools/build/nci_builtin_c.pl   Wed Jan 11 09:31:05 2006
@@ -581,9 +581,9 @@ sub print_tail {
 /* This function serves a single purpose. It takes the function
    signature for a C function we want to call and returns a pointer
    to a function that can call it. */
-static void *
-nci_builtin_new (Interp *interpreter, PMC *pmc_nci,
-                STRING *signature)
+static void
+nci_builtin_new (Interp *interpreter, PMC *pmc,
+                STRING *signature, Parrot_csub_t func)
 {
     char       *c;
     STRING     *ns, *message;
@@ -595,22 +595,31 @@ nci_builtin_new (Interp *interpreter, PM
     Hash       *known_frames  = NULL;
     PMC        *HashPointer   = NULL;
 
+    PMC_struct_val(pmc) = func;
+
 #if defined(CAN_BUILD_CALL_FRAMES)
 
     /* Try if JIT code can build that signature,
      * if yes, we are done
      */
 
-     result = Parrot_jit_build_call_func(interpreter, pmc_nci, signature);
+     result = Parrot_jit_build_call_func(interpreter, pmc, signature);
 
 #endif
     if (result)
-        return result;
+    {
+       PMC_data(pmc) = result;
+        return;
+    }
 
     /* And in here is the platform-independent way. Which is to say
        "here there be hacks" */
-    UNUSED(pmc_nci);
-    if (0 == string_length(interpreter, signature)) return F2DPTR(pcf_v_v);
+    UNUSED(pmc);
+    if (0 == string_length(interpreter, signature))
+    {
+       PMC_data(pmc) = F2DPTR(pcf_v_v);
+       return;
+    }
 
     iglobals = interpreter->iglobals;
 
@@ -631,7 +640,10 @@ $put_pointer
     b = VTABLE_get_pmc_keyed_str(interpreter, HashPointer, signature);
 
     if (b && b->vtable->base_type == enum_class_UnManagedStruct)
-        return F2DPTR(PMC_data(b));
+    {
+        PMC_data(pmc) = F2DPTR(PMC_data(b));
+       return;
+    }
 
     /*
       These three lines have been added to aid debugging. I want to be able to
@@ -654,31 +666,39 @@ $put_pointer
      */
     c = string_to_cstring(interpreter, message);
     PANIC(c);
-    return NULL;
+    PMC_data(pmc) = NULL;
+    return;
 }
 
 
-static void* nci_builtin_clone (void* context)
+static void nci_builtin_clone (Interp* interpreter, PMC* pmc1, PMC* pmc2)
 {
-    return context;
+    PMC_struct_val(pmc1) = PMC_struct_val(pmc2);
+    PMC_pmc_val(pmc1) = NULL;
+    /* FIXME if data is malloced (JIT/i386!) then we need
+     * the length of data here, to memcpy it
+     * ManagedStruct or Buffer?
+     */
+    PMC_data(pmc1) = PMC_data(pmc2);
 }
 
 
 static void nci_builtin_invoke (Interp *interpreter,
-                               Parrot_csub_t func,
                                PMC * pmc)
 {
+    Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(pmc));
+
+    if (!func)
+       real_exception(interpreter, NULL, INVALID_OPERATION,
+                      "attempt to call NULL function");
+
     func (interpreter, pmc);
 }
 
 
-static void nci_builtin_free (void * context)
+static void nci_builtin_free (Interp *interpreter, PMC *pmc)
 {
-#if 0
     /* Doesn't actually look like this memory needs to be freed */
-    if (context)
-       mem_free_executable(context);
-#endif
 }
 
 

Reply via email to