summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorBen Morrow <ben@morrow.me.uk>2010-08-31 07:10:20 +0100
committerRafael Garcia-Suarez <rgs@consttype.org>2010-09-07 12:10:19 +0200
commit8dff4fc578385a16edd29a881d85a0aa5f09595a (patch)
tree631c8a7c8744e44cc7ed9c1acda586ddd965fafd /pp_ctl.c
parent134bbc579801d70bf58eb3e84c78e4c2c244899e (diff)
downloadperl-8dff4fc578385a16edd29a881d85a0aa5f09595a.tar.gz
API functions for accessing the runtime hinthash.
Add hinthash_fetch(sv|pv[ns]) as a replacement for refcounted_he_fetch, which is not API (and should not be). Also add caller_cx, as the correct XS equivalent to caller(). Lots of modules seem to have copies of this, so a proper API function will be more maintainable in future.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 308ccca90b..3fd46ba29c 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1670,20 +1670,32 @@ PP(pp_xor)
RETSETNO;
}
-PP(pp_caller)
+/*
+=for apidoc caller_cx
+
+The XSUB-writer's equivalent of L<caller()|perlfunc/caller>. The
+returned C<PERL_CONTEXT> structure can be interrogated to find all the
+information returned to Perl by C<caller>. Note that XSUBs don't get a
+stack frame, so C<caller_cx(0, NULL)> will return information for the
+immediately-surrounding Perl code.
+
+This function skips over the automatic calls to C<&DB::sub> made on the
+behalf of the debugger. If the stack frame requested was a sub called by
+C<DB::sub>, the return value will be the frame for the call to
+C<DB::sub>, since that has the correct line number/etc. for the call
+site. If I<dbcxp> is non-C<NULL>, it will be set to a pointer to the
+frame for the sub call itself.
+
+=cut
+*/
+
+const PERL_CONTEXT *
+Perl_caller_cx(pTHX_ I32 count, const PERL_CONTEXT **dbcxp)
{
- dVAR;
- dSP;
register I32 cxix = dopoptosub(cxstack_ix);
register const PERL_CONTEXT *cx;
register const PERL_CONTEXT *ccstack = cxstack;
const PERL_SI *top_si = PL_curstackinfo;
- I32 gimme;
- const char *stashname;
- I32 count = 0;
-
- if (MAXARG)
- count = POPi;
for (;;) {
/* we may be in a higher stacklevel, so dig down deeper */
@@ -1692,13 +1704,8 @@ PP(pp_caller)
ccstack = top_si->si_cxstack;
cxix = dopoptosub_at(ccstack, top_si->si_cxix);
}
- if (cxix < 0) {
- if (GIMME != G_ARRAY) {
- EXTEND(SP, 1);
- RETPUSHUNDEF;
- }
- RETURN;
- }
+ if (cxix < 0)
+ return NULL;
/* caller() should not report the automatic calls to &DB::sub */
if (PL_DBsub && GvCV(PL_DBsub) && cxix >= 0 &&
ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub))
@@ -1709,6 +1716,8 @@ PP(pp_caller)
}
cx = &ccstack[cxix];
+ if (dbcxp) *dbcxp = cx;
+
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
const I32 dbcxix = dopoptosub_at(ccstack, cxix - 1);
/* We expect that ccstack[dbcxix] is CXt_SUB, anyway, the
@@ -1718,6 +1727,31 @@ PP(pp_caller)
cx = &ccstack[dbcxix];
}
+ return cx;
+}
+
+PP(pp_caller)
+{
+ dVAR;
+ dSP;
+ register const PERL_CONTEXT *cx;
+ const PERL_CONTEXT *dbcx;
+ I32 gimme;
+ const char *stashname;
+ I32 count = 0;
+
+ if (MAXARG)
+ count = POPi;
+
+ cx = caller_cx(count, &dbcx);
+ if (!cx) {
+ if (GIMME != G_ARRAY) {
+ EXTEND(SP, 1);
+ RETPUSHUNDEF;
+ }
+ RETURN;
+ }
+
stashname = CopSTASHPV(cx->blk_oldcop);
if (GIMME != G_ARRAY) {
EXTEND(SP, 1);
@@ -1742,7 +1776,7 @@ PP(pp_caller)
if (!MAXARG)
RETURN;
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
- GV * const cvgv = CvGV(ccstack[cxix].blk_sub.cv);
+ GV * const cvgv = CvGV(dbcx->blk_sub.cv);
/* So is ccstack[dbcxix]. */
if (isGV(cvgv)) {
SV * const sv = newSV(0);