Skip to content

Instantly share code, notes, and snippets.

@Mons
Created Nov 27, 2012
Embed
What would you like to do?
Creating callback from XS
/*
* Usage:
my $x = XSTesting::makecb("my arg");
say $x->();
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
STATIC MGVTBL null_mg_vtbl = {
NULL, /* get */
NULL, /* set */
NULL, /* len */
NULL, /* clear */
NULL, /* free */
#if MGf_COPY
NULL, /* copy */
#endif /* MGf_COPY */
#if MGf_DUP
NULL, /* dup */
#endif /* MGf_DUP */
#if MGf_LOCAL
NULL, /* local */
#endif /* MGf_LOCAL */
};
XS(cb_test) {
dVAR;
dXSARGS;
dORIGMARK;
PERL_CONTEXT *cx = &cxstack[cxstack_ix];
U32 cxtype = CxTYPE (cx) & CXTYPEMASK;
char *type;
switch(cxtype)
{
case CXt_NULL: type = "null"; break;
case CXt_SUB: type = "sub"; break;
case CXt_EVAL: type = "eval"; break;
case CXt_SUBST: type = "subst"; break;
case CXt_BLOCK: type = "block"; break;
case CXt_FORMAT: type = "format"; break;
default:
warn("Unknown context type 0x%lx\n", cxtype);
type = "(unknown)";
}
// CxTYPE (cx) here is CXt_BLOCK, not CXt_SUB
// I can't yet find a way to access my CV *.
warn("my type is %d: %s", CxTYPE(cx), type);
SP = ORIGMARK;
PUSHs(&PL_sv_yes);
}
MODULE = XSTesting PACKAGE = XSTesting
void makecb(SV *var)
PPCODE:
CV *myxs = newXS(0, cb_test, __FILE__);
void *context = (void *) var;
// Currently I have an ideas:
// - Assign context ptr to magic of CV; Something like:
// sv_magicext((SV *) myxs, NULL, PERL_MAGIC_ext, &null_mg_vtbl, context, 0);
// - Create PADLIST for CV and store context there
// how?
ST(0) = newRV_noinc( (SV *) myxs );
XSRETURN(1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment