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; + } }