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
}