How to override invoke?
Andrew Whitworth
wknight8111 at gmail.com
Mon Dec 29 22:17:03 UTC 2008
Have you tried maybe storing the Parrot Sub object in an attribute of
your subclass object?
.sub invoke :vtable
$P0 = get_attribute self, 'RealParrotSub'
.say "pre-invoke hook"
$P0()
.say "post-invoke hook"
.end
I haven't tested this myself, but it seems like the most
straight-forward way to do it.
--Andrew Whitworth
On Mon, Dec 29, 2008 at 4:32 PM, Will Coleda <will at coleda.com> wrote:
> To support tcl's [trace] mechanism, I need to be able to register pre
> and post invocation hooks (among other things)
>
> The easiest way to do this seems to be to have a subclass of Sub with
> an overridden 'invoke' vtable; then I can invoke the specified tracing
> code before and after I invoke the actual Subroutine. (This is the
> mechanism I'm using to support variable tracing: I subclass my
> existing hash-like PMC, and if someone calls get_pmc_keyed, I can fire
> off an arbitrary bit of tcl code before passing along the read to the
> original vtable entry.)
>
> Problem is, I can't seem to override invoke this way. The following code:
>
> .sub main :main
> # create a PIR sub and invoke it.
> $P1 = compreg 'PIR'
> $P2 = $P1(".sub a\nsay 'hi from PIR'\n.end\n")
> $P2 = $P2[0] # first sub from Eval
> $P2()
>
> # make a PIR subclass with the same compiled sub.
> $P0 = new 'TclProc'
> assign $P0, $P2
> $P0()
> .end
>
> .namespace [ 'TclProc' ]
>
> .sub class_init :anon :init
> $P0 = get_class 'Sub'
> $P1 = subclass $P0, 'TclProc'
> .end
>
> is basically how Tcl works on user defined procedures now; This runs
> the compiled PIR sub twice.
>
> We can trivially override the vtable, by tacking this sub on the end of the file
>
> .sub invoke :vtable
> say "IN UR VTABLE"
> .end
>
> This works, replacing the send invocation of the PIR sub by our say opcode.
>
> But there doesn't seem to be a way to actually invoke the subroutine
> once you're in the overridden vtable. I tried the proxy trick (used
> elsewhere in Tcl to get access to a parent String vtable:)
>
> .sub invoke :vtable
> say "IN UR VTABLE"
> $P0 = getattribute self, ['Sub'], 'proxy'
> .tailcall $P0()
> .end
>
> I get an error "too few arguments passed (0) - 1 params expected" on
> the getattribute call, presumably as a result of specifying 'self'.
> I've played with a few different approaches here, but it looks like
> self isn't getting passed in on the invoke override (but is, on, say,
> set_string_native).
>
> Any thoughts on getting this approach to work? Is this a bug? Just not
> going to work? Or is there a different workable approach for [trace]
> on command execution?
>
> --
> Will "Coke" Coleda
> _______________________________________________
> http://lists.parrot.org/mailman/listinfo/parrot-dev
>
More information about the parrot-dev
mailing list