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