Following conversation with Matt Diephouse on #parrot, I realized that that was pretty confusing. What I meant was that invoke() should accept parameters and return values as a normal subroutine. This would probably be done by moving the code that deals with the pc out of the invoke() method and into the invokecc opcode. This would result in invoke() being abstracted away from dealing with the pc.
On 3/10/07, Alek Storm <[EMAIL PROTECTED]> wrote:
That is definitely the most elegant solution. Now, the question is, shouldn't the invoke() vtable method behave that way in the first place, since passing a pc address to and returning another pc address from the invoke() method only makes sense for Sub, Coroutine, and Continuation? In other words, invoke() shouldn't be reliant on bytecode. On 3/8/07, Matt Diephouse via RT < [EMAIL PROTECTED]> wrote: On Wed Mar 07 17:02:47 2007, mdiep wrote: > This gets us close to what I want: > > > > void* invoke(void *next) { > STRING *meth = CONST_STRING(interp, "__invoke"); > STRING *meth_v = CONST_STRING(interp, "invoke"); > PMC *sub = Parrot_find_vtable_meth(interp, pmc, meth_v); > if (PMC_IS_NULL(sub)) > sub = find_or_die(interp, pmc, meth); > (void*) Parrot_run_meth_fromc_args(interp, sub, > pmc, meth, "??", next); > return next; > } We all missed the obvious solution: just invoking the sub, rather than entering a new runloop. This has the benefits of not creating a new runloop and of handling parameters and return values properly. It may even make invoke work with :multi (it might need a bit more work for that). Fixed in r17385. -- Matt Diephouse void* invoke(void *next) { STRING *meth = CONST_STRING(interp, "__invoke"); STRING *meth_v = CONST_STRING(interp, "invoke"); PMC *sub = Parrot_find_vtable_meth(interp, pmc, meth_v); if (PMC_IS_NULL(sub)) sub = find_or_die(interp, pmc, meth); INTERP->current_object = SELF; return VTABLE_invoke(interp, sub, next); }