Just wrap PL_ppaddr[OP_REF]!

jjore on 2006-12-22T22:09:46

Jifty's land grab on the '0' package is irksome. There's only one other similar package and that's "\0" and it's impossible(?) to install methods into. The real problem is that some objects would prefer to be thought of as "not an object" and bad code out there uses ref() to decide this.

I figure it'd be better to be able to have a general mechanism where ref() can return false for any given object should that behaviour be desired.

I initially thought of installing &ref to override the builtin. This works as long as you do it before your calling code is compiled but not after. Oops.

Instead of that, the opcode pp_ref itself can be overridden by swapping in our own function into PL_ppaddr[OP_REF]. Woot! That'd work and this would mean objects of *any* class can request funky behaviour for ref( $obj ).

Cool. Package 0 isn't needed anymore (only if this wrapper gets written).


It's Not Quite That Easy

chromatic on 2006-12-22T23:43:30

One potential drawback is that you'd have to swap in a different function pointer before Perl constructs the optree of the calling code. Of course, a little B::Deparse and PadWalker magic can fix that, if you don't mind recompiling a few bad calls.

That where it seems to me much easier to rap the knuckles of every chucklehead who thinks that ref() gives useful answers in Perl. (Note to potential non-chuckleheads: it doesn't. Get over it.)

Re:It's Not Quite That Easy

jjore on 2006-12-23T04:20:29

Oh...

I thought of PL_ppaddr[...] as a global dispatch table but I guess that's wrong. I just learned that every op has the proper function pointer copied into it in the op_ppaddr. So to override ref() I'd actually need to find all the opnodes that have pointers to the real(?) function and swap in my own.

Foo.

Is there a reason for this? This means two "equivalent" opnodes can have different op_ppaddrs. That's an interesting feature and I've never heard of anyone that for anything. Possibly lexically different calls, I suppose.

Do you know the history behind this?

Re:It's Not Quite That Easy

chromatic on 2006-12-23T07:05:19

I've used it productively, but that code's not suitable for general use yet.

To my best guess, with no specific knowledge, it's there to make op dispatch in the runloop as fast as possible; it's a nice, simple scheme there.

Re:It's Not Quite That Easy

jjore on 2006-12-23T09:11:54

This strikes me as an interesting way to instrument code for debugging. The edebug in emacs does something where it wraps every instruction in a function for execution. Something similar could happen in perl 5.

Re:It's Not Quite That Easy

chromatic on 2006-12-23T21:22:15

For that I'd use an alternate runloop, as in the Runops::Trace example in Perl Hack #82.

Jifty does nothing of the sort.

jesse on 2006-12-23T07:52:10

Jifty uses Scalar::Defer. Scalar::Defer does magic with '0'

Re:Jifty does nothing of the sort.

jjore on 2006-12-23T09:05:01

Yeah, thanks. Your reply in the other blog clarified that.