Gregor N. Purdy <[EMAIL PROTECTED]> wrote: > #define DO_OP(PC,INTERP) \ > (PC = ((INTERP->op_func_table)[*PC])(PC,INTERP))
> The easiest way to intercept this flow with minimal cost is to > have the mechanism that wants to take over replace the interpreter's > op_func_table with a block of pointers to some Parrot_hijack() > function that conforms to the opfunc prototype. Enqueueing an > event would set the appropriate interpreter's op_func_table to > hijack_op_func_table. Thinking more about this: Switching the whole op_func_table() or ops_addr[] (for CG cores) is simpler, then e.g. replacing backward branch ops. Only the switched core doesn't play nicely here. Having neither a op_func_table nor an ops_addr[], it would need an explicit CHECK_EVENTS() in the loop. Now I have done a very similar thing some time ago: Subject: [RfC] a scheme for core.ops extending Date: Wed, 05 Feb 2003 12:28:21 +0100 On the enqueueing of an event, the op_lib is told to switch the jump_table/ops_addr via a special op_lib->init call. (If the event check func_table doesn't exist yet, its constructed on the fly, by filling the check_event opcode into the func_table. The check_event opcode now restores the func_table/ops_addr, saves the context (generates a return continuation) and branches to the event handler (if any) or handles the event internally. Then it executes the same opcode again, like its done in the prederef function, which resumes normal opcode flow. leo