#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#define NEED_caller_cx
#define NEED_PL_parser
#define DPPP_PL_parser_NO_DUMMY
#include "ppport.h"
void
call_after (pTHX_ void *p)
{
dSP;
SV *cv = (SV*)p;
PUSHSTACKi(PERLSI_DESTROY);
PUSHMARK(SP);
call_sv(cv, G_VOID|G_DISCARD);
POPSTACK;
SvREFCNT_dec(cv);
}
void show_cx (pTHX_ const char *name, const PERL_CONTEXT *cx)
{
int is_sub = CxTYPE(cx) == CXt_SUB;
CV *cxcv = is_sub ? cx->blk_sub.cv : NULL;
int is_special = is_sub ? CvSPECIAL(cxcv) : 0;
const char *cvname = is_sub ? GvNAME(CvGV(cxcv)) : "<none>";
Perl_warn(aTHX_ "%s: sub %s, special %s, name %s\n",
name,
(is_sub ? "yes" : "no"),
(is_special ? "yes" : "no"),
cvname);
}
MODULE = B::Hooks::AtRuntime PACKAGE = B::Hooks::AtRuntime
#ifdef lex_stuff_sv
void
lex_stuff (s)
SV *s
CODE:
if (!PL_parser)
Perl_croak(aTHX_ "Not currently compiling anything");
lex_stuff_sv(s, 0);
#endif
UV
count_BEGINs ()
PREINIT:
I32 c = 0;
const PERL_CONTEXT *cx;
const PERL_CONTEXT *dbcx;
const CV *cxcv;
CODE:
RETVAL = 0;
while ((cx = caller_cx(c++, &dbcx))) {
/*
show_cx(aTHX_ "cx", cx);
show_cx(aTHX_ "dbcx", dbcx);
*/
if (CxTYPE(dbcx) == CXt_SUB &&
(cxcv = dbcx->blk_sub.cv) &&
CvSPECIAL(cxcv) &&
strEQ(GvNAME(CvGV(cxcv)), "BEGIN")
)
RETVAL++;
}
/*
Perl_warn(aTHX_ "count_BEGINS: frames %i, BEGINs %lu\n",
c, RETVAL);
*/
OUTPUT:
RETVAL
bool
compiling_string_eval ()
PREINIT:
I32 c = 0;
const PERL_CONTEXT *cx;
const PERL_CONTEXT *dbcx;
const CV *cxcv;
CODE:
RETVAL = 0;
while ((cx = caller_cx(c++, &dbcx))) {
if (CxTYPE(dbcx) == CXt_SUB &&
(cxcv = dbcx->blk_sub.cv) &&
CvSPECIAL(cxcv) &&
strEQ(GvNAME(CvGV(cxcv)), "BEGIN")
) {
cx = caller_cx(c + 1, &dbcx);
if (cx && CxREALEVAL(dbcx))
RETVAL = 1;
break;
}
}
OUTPUT:
RETVAL
SV *
remaining_text ()
PREINIT:
char *c;
CODE:
RETVAL = &PL_sv_undef;
if (PL_parser) {
for (c = PL_bufptr; c < PL_bufend; c++) {
if (isSPACE(*c)) continue;
if (*c == '#') break;
/* strictly it might be UTF8, but this is just an error so I
* don't care. */
RETVAL = newSVpvn(c, PL_bufend - c);
break;
}
}
OUTPUT:
RETVAL
void
run (...)
PREINIT:
dORIGMARK;
SV *sv;
I32 i = 0;
CODE:
/* This is the magic step... This leaves the scope that
* surrounds the call to run(), putting us back in the outer
* scope we were called from. This is what makes after_runtime
* subs run at the end of the inserted-into scope, rather than
* when run() finishes. */
LEAVE;
while (i++ < items) {
sv = *(MARK + i);
if (!SvROK(sv))
Perl_croak(aTHX_ "Not a reference");
sv = SvRV(sv);
/* We have a ref to a ref; this is after_runtime. */
if (SvROK(sv)) {
sv = SvRV(sv);
SvREFCNT_inc(sv);
SAVEDESTRUCTOR_X(call_after, sv);
}
/* This is at_runtime. */
else {
PUSHMARK(SP); PUTBACK;
call_sv(sv, G_VOID|G_DISCARD);
MSPAGAIN;
}
}
/* Re-enter the scope level we were supposed to be in, or perl
* will get confused. */
ENTER;