cvsuser 03/10/23 02:28:12
Modified: include/parrot interpreter.h
. interpreter.c
Log:
Parrot_runops_fromc_args
Revision Changes Path
1.96 +3 -2 parrot/include/parrot/interpreter.h
Index: interpreter.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -w -r1.95 -r1.96
--- interpreter.h 22 Oct 2003 08:41:44 -0000 1.95
+++ interpreter.h 23 Oct 2003 09:28:07 -0000 1.96
@@ -1,7 +1,7 @@
/* interpreter.h
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: interpreter.h,v 1.95 2003/10/22 08:41:44 leo Exp $
+ * $Id: interpreter.h,v 1.96 2003/10/23 09:28:07 leo Exp $
* Overview:
* The interpreter api handles running the operations
* Data Structure and Algorithms:
@@ -259,7 +259,8 @@
void runops(struct Parrot_Interp *, size_t offset);
void runops_int(struct Parrot_Interp *, size_t offset);
-void Parrot_runops_fromc(struct Parrot_Interp *interpreter, PMC *sub);
+void Parrot_runops_fromc(Parrot_Interp, PMC *sub);
+void* Parrot_runops_fromc_args(Parrot_Interp, PMC *sub, const char *sig, ...);
typedef opcode_t *(*native_func_t)(struct Parrot_Interp * interpreter,
opcode_t * cur_opcode,
1.222 +88 -2 parrot/interpreter.c
Index: interpreter.c
===================================================================
RCS file: /cvs/public/parrot/interpreter.c,v
retrieving revision 1.221
retrieving revision 1.222
diff -u -w -r1.221 -r1.222
--- interpreter.c 22 Oct 2003 08:41:42 -0000 1.221
+++ interpreter.c 23 Oct 2003 09:28:11 -0000 1.222
@@ -1,7 +1,7 @@
/* interpreter.c
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: interpreter.c,v 1.221 2003/10/22 08:41:42 leo Exp $
+ * $Id: interpreter.c,v 1.222 2003/10/23 09:28:11 leo Exp $
* Overview:
* The interpreter api handles running the operations
* Data Structure and Algorithms:
@@ -644,7 +644,7 @@
*/
void
-Parrot_runops_fromc(struct Parrot_Interp *interpreter, PMC *sub)
+Parrot_runops_fromc(Parrot_Interp interpreter, PMC *sub)
{
static PMC *ret_c = NULL;
opcode_t offset, *dest;
@@ -665,6 +665,92 @@
offset = dest - interpreter->code->byte_code;
runops(interpreter, offset);
+}
+
+/*=for api interpreter Parrot_runops_fromc_args
+ * run parrot ops, called from c code
+ * function arguments are passed as va_args according to signature
+ * the sub argument is an invocable Sub PMC
+ *
+ * signatures are similar to NCI:
+ * v ... void return
+ * I ... INTVAL (not Interpreter)
+ * N ... NUMVAL
+ * S ... STRING*
+ * P ... PMC*
+ *
+ * return value, if any is passed as (void*)ptr or (void*)&val
+ */
+
+void *
+Parrot_runops_fromc_args(Parrot_Interp interpreter, PMC *sub,
+ const char *sig, ...)
+{
+ va_list ap;
+ /* *sig is retval like in NCI */
+ int ret;
+ int next[4];
+ int i;
+ void *retval;
+
+ for (i = 0; i < 4; i++)
+ next[i] = 5;
+
+ REG_INT(0) = 1; /* kind of a prototyped call */
+ REG_INT(1) = 0; /* nada in P3 */
+ REG_INT(2) = 0; /* params in P regs */
+ ret = *sig++;
+ REG_INT(3) = ret == 'v' ? 0 : -2; /* return expected */
+ REG_INT(4) = 0; /* no hash */
+
+ va_start(ap, sig);
+ while (*sig) {
+ switch (*sig++) {
+ case 'v': /* void func, no params */
+ break;
+ case 'I': /* REG_INT */
+ REG_INT(next[0]++) = va_arg(ap, INTVAL);
+ break;
+ case 'S': /* REG_STR */
+ REG_STR(next[1]++) = va_arg(ap, STRING*);
+ break;
+ case 'P': /* REG_PMC */
+ REG_INT(2) = 1; /* params in P regs */
+ REG_PMC(next[2]++) = va_arg(ap, PMC*);
+ break;
+ case 'N': /* REG_NUM */
+ REG_NUM(next[3]++) = va_arg(ap, FLOATVAL);
+ break;
+ default:
+ internal_exception(1,
+ "unhandle signature '%c' in Parrot_runops_fromc_args",
+ sig[-1]);
+ }
+ }
+ va_end(ap);
+
+ Parrot_runops_fromc(interpreter, sub);
+ /*
+ * TODO check, if return is prototyped, for now, assume yes
+ */
+ retval = NULL;
+ /*
+ * XXX should we trust the signature or the registers set
+ * by the subroutine or both if possible, i.e. extract
+ * e.g. an INTVAL from a returned PMC?
+ */
+ switch (ret) {
+ case 'v': break;
+ case 'I': retval = (void* )®_INT(5); break;
+ case 'S': retval = (void* ) REG_STR(5); break;
+ case 'P': retval = (void* ) REG_PMC(5); break;
+ case 'N': retval = (void* )®_NUM(5); break;
+ default:
+ internal_exception(1,
+ "unhandle signature '%c' in Parrot_runops_fromc_args",
+ ret);
+ }
+ return retval;
}
static int