diff options
author | Nicholas Clark <nick@ccl4.org> | 2010-11-03 14:57:11 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2010-11-03 15:04:34 +0000 |
commit | 25a9ffce153b0e67cfefd260754edeb097da5be7 (patch) | |
tree | 6d7e60d1842fa73c3f0fcec7cc9a2e2272baf085 /gv.c | |
parent | 7d255dc8b56bf0fe58c3f8a5aa84ba17aade145f (diff) | |
download | perl-25a9ffce153b0e67cfefd260754edeb097da5be7.tar.gz |
Add Perl_amagic_deref_call() to implement the bulk of tryAMAGICunDEREF_var().
This removes around 300 bytes of object code from each place it was previously
inlined. It also provides a better interface - quite a lot of the core
currently bodges things by creating a local variable C<SV **sp = &sv> to use
the macro.
Change the XS::APItest wrapper to amagic_deref_call().
Diffstat (limited to 'gv.c')
-rw-r--r-- | gv.c | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -2010,6 +2010,25 @@ Perl_try_amagic_bin(pTHX_ int method, int flags) { return FALSE; } +SV * +Perl_amagic_deref_call(pTHX_ SV *ref, int method) { + SV *tmpsv = NULL; + + PERL_ARGS_ASSERT_AMAGIC_DEREF_CALL; + + while (SvAMAGIC(ref) && + (tmpsv = amagic_call(ref, &PL_sv_undef, method, + AMGf_noright | AMGf_unary))) { + if (!SvROK(tmpsv)) + Perl_croak(aTHX_ "Overloaded dereference did not return a reference"); + if (tmpsv == ref || SvRV(tmpsv) == SvRV(ref)) { + /* Bail out if it returns us the same reference. */ + return tmpsv; + } + ref = tmpsv; + } + return tmpsv ? tmpsv : ref; +} SV* Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) |