fix B::PADOP->sv and ->gv
authorDavid Mitchell <davem@iabyn.com>
Fri, 19 Sep 2014 15:07:08 +0000 (16:07 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 19 Sep 2014 15:33:08 +0000 (16:33 +0100)
commit3a23d767cf63fb2e8de3d79eadee49bbc33eec53
tree10ae7ccb7acf9c4cd2d3e0c16bb610a3555c2446
parent1da7b04307a09e4931d85cc5a89e85f653429783
fix B::PADOP->sv and ->gv

PADOP structs, which are only used on threaded builds, have an op_padix
field rather than an op_sv or op_gv.

The B::PADOP sv and gv methods would do PL_curpad[o->op_padix] to
look up the value, That is completely wrong. PL_curpad is the pad of the
caller of B::PADOP::sv/gv, not the pad of the sub containing the PADOP op.

This fault appears to to go back to 1999, when PADOP was first added.
It's probably never been spotted because:

a) PADOP only ever used for creating GV ops on threaded builds (so
->sv is probably never called),

b) it has a check where if the thing it retrieved from the pad isn't a GV,
it returns NULL instead.

Fix this by always returning NULL. This is comparable with B::SVOP_>sv,
which always returns op_sv, which on threaded builds always happens to be
NULL. Note that B::SVOP->sv expects the caller to retrieve op_targ and do
the pad lookup.

NB just to avoid confusion (I was certainly confused), these ops are
implemented with the types shown:

    unthreaded:

        const: B::SVOP
        gvsv:  B::SVOP

    threaded:

        const: B::SVOP
        gvsv:  B::PADOP
ext/B/B.xs
ext/B/t/b.t