On Fri, 2002-07-19 at 16:36, Melvin Smith wrote:
> Send me a complete patch and I'll put it in. I might rename the
> op to 'call'.
The attached patch makes the following changes:
- adds invoke op to core.ops (patch does not remove call and callco)
- adds vtable method 'invoke' to vtable.tbl
- adds simple description (stolen from Dan's email) of the method to
docs/pdd/pdd02_vtables.pod
- adds default invoke to classes/default.pmc
- adds an invoke method to classes/sub.pmc
- adds an invoke method to classes/coroutine.pmc
If either the op or the vtable method (or both) should be be named
'call' instead of 'invoke' then let me know and I will rework my stuff
and resubmit the patch.
I had a small patch ready for docs/core_ops.pod, but I see that the file
has been removed, so now I am not sure where to put the description of
the invoke op.
Next on my list is (next 24 hours or so):
1) remove old call and callco ops (invoke takes care of both) from
core.ops
2) change examples/assembly/sub.pasm and coroutine.pasm to use invoke
instead of call and callco
3) add some tests
After that I will look into adding a Continuation PMC.
--
Jonathan Sillito
Index: core.ops
===================================================================
RCS file: /cvs/public/parrot/core.ops,v
retrieving revision 1.185
diff -u -r1.185 core.ops
--- core.ops 18 Jul 2002 04:29:39 -0000 1.185
+++ core.ops 22 Jul 2002 16:52:05 -0000
@@ -4179,6 +4179,34 @@
goto NEXT();
}
+inline op invoke() {
+ opcode_t *dest;
+ PMC * p = interpreter->ctx.pmc_reg.registers[0];
+
+ /*
+ * FIXME: the stack manipulation code (this push and the pop below) should
+ * be moved to the vtable method. (I think ?)
+ */
+ stack_push(interpreter, &interpreter->ctx.control_stack, expr NEXT(), STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL);
+
+ dest = (opcode_t *)p->vtable->invoke(interpreter, p);
+ if(dest == 0) {
+ /*
+ * invoke returned 0 (means nothing more needs to be done), so just
+ * move on to the next instruction
+ */
+ stack_pop(interpreter, &interpreter->ctx.control_stack, NULL, STACK_ENTRY_DESTINATION);
+ goto NEXT();
+ }
+ else {
+ /*
+ * invoke returned non 0, so it should have returned a and address
+ * so that's our next
+ */
+ goto ADDRESS(dest);
+ }
+}
+
inline op call() {
/* This op will be a vtable entry */
struct Parrot_Sub * sub = (struct Parrot_Sub*)interpreter->ctx.pmc_reg..registers[0]->data;
Index: vtable.tbl
===================================================================
RCS file: /cvs/public/parrot/vtable.tbl,v
retrieving revision 1.25
diff -u -r1.25 vtable.tbl
--- vtable.tbl 21 Jun 2002 17:22:01 -0000 1.25
+++ vtable.tbl 22 Jul 2002 16:52:05 -0000
@@ -325,3 +325,5 @@
STRING* substr_str(INTVAL offset, INTVAL length)
STRING* substr_str_keyed(KEY* key, INTVAL offset, INTVAL length)
STRING* substr_str_keyed_int(INTVAL* key, INTVAL offset, INTVAL length)
+
+INTVAL invoke()
Index: docs/pdds/pdd02_vtables.pod
===================================================================
RCS file: /cvs/public/parrot/docs/pdds/pdd02_vtables.pod,v
retrieving revision 1.19
diff -u -r1.19 pdd02_vtables.pod
--- docs/pdds/pdd02_vtables.pod 21 Jun 2002 17:23:37 -0000 1.19
+++ docs/pdds/pdd02_vtables.pod 22 Jul 2002 16:52:05 -0000
@@ -1194,6 +1194,18 @@
The key is guaranteed to be not NULL.
+=item INTVAL invoke(INTERP, PMC* self)
+
+For invoking Invoke the given PMC.
+
+It should set up the environment for the sub and return the absolute
+address that the interpreter should jump to. If it returns 0, then
+the interpreter should just take up with the next instruction. (If the
+sub just goes and does its thing and returns, which most C subs will
+do at the moment)
+
+See pdd03_calling_conventions.pod for more details.
+
=back
=cut
Index: classes/default.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/default.pmc,v
retrieving revision 1.24
diff -u -r1.24 default.pmc
--- classes/default.pmc 18 Jul 2002 02:19:16 -0000 1.24
+++ classes/default.pmc 22 Jul 2002 16:52:06 -0000
@@ -2478,4 +2478,15 @@
INT_TO_KEY(&r_key, *key);
return SELF->vtable->substr_str_keyed(INTERP, SELF, &r_key, offset, length);
}
+
+ INTVAL invoke() {
+ /*
+ * FIXME: should be an exception instead:
+ * "Invoking something that can not be invoked" ??
+ */
+
+ /* returning 0 should mean the interpretor will move on to the next op */
+ return 0;
+
+ }
}
Index: classes/sub.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/sub.pmc,v
retrieving revision 1.2
diff -u -r1.2 sub.pmc
--- classes/sub.pmc 18 Jul 2002 03:48:33 -0000 1.2
+++ classes/sub.pmc 22 Jul 2002 16:52:06 -0000
@@ -325,4 +325,9 @@
void repeat_same (PMC * value, PMC* dest) {
}
*/
+
+ INTVAL invoke () {
+ /* return address that the interpreter should jump to */
+ return ((struct Parrot_Sub*)SELF->data)->init;
+ }
}
Index: classes/coroutine.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/coroutine.pmc,v
retrieving revision 1.3
diff -u -r1.3 coroutine.pmc
--- classes/coroutine.pmc 19 Jul 2002 02:40:32 -0000 1.3
+++ classes/coroutine.pmc 22 Jul 2002 16:52:06 -0000
@@ -324,4 +324,15 @@
void repeat_same (PMC * value, PMC* dest) {
}
*/
+
+ INTVAL invoke () {
+ struct Parrot_Coroutine* co = (struct Parrot_Sub*)SELF->data;
+
+ /* Resuming co-routine or fresh call? */
+ if(!co->resume) {
+ return co->init;
+ }
+
+ return co->resume;
+ }
}