diff options
author | Jesse Luehrs <doy@tozt.net> | 2011-07-08 03:01:49 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2011-07-08 03:01:49 -0500 |
commit | 1a0c3c3a02da09abc11bbad291d09a41c1850d1d (patch) | |
tree | c19787eda8fa4dd155e028752cc38bc19dad0aca /core.xs | |
parent | 046119999e010e4a38b67f5f194baaf60e7c8707 (diff) | |
download | smartmatch-engine-core-1a0c3c3a02da09abc11bbad291d09a41c1850d1d.tar.gz smartmatch-engine-core-1a0c3c3a02da09abc11bbad291d09a41c1850d1d.zip |
split this out into its own dist, and implement the custom opcode
Diffstat (limited to 'core.xs')
-rw-r--r-- | core.xs | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -0,0 +1,44 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include "ppport.h" + +#include "stolen_chunk_of_pp_ctl.c" + +STATIC OP* +install_sm_op(pTHX_ OP *o, GV *gv, SV *ud) +{ + OP *list, *left, *right, *new; + + list = cUNOPo->op_first; + left = cLISTOPx(list)->op_first->op_sibling; /* skip over the pushmark */ + right = left->op_sibling; + + cLISTOPx(list)->op_first->op_sibling = right->op_sibling; + left->op_sibling = right->op_sibling = NULL; + op_free(o); + + new = newBINOP(OP_CUSTOM, 0, left, right); + new->op_ppaddr = INT2PTR(Perl_ppaddr_t, Perl_pp_old_smartmatch); + + return new; +} + +MODULE = smartmatch::engine::core PACKAGE = smartmatch::engine::core + +PROTOTYPES: DISABLE + +void +init(match) + SV *match; + PREINIT: + CV *cv; + CODE: + if (!SvROK(match) || SvTYPE(SvRV(match)) != SVt_PVCV) { + croak("not a coderef"); + } + + cv = (CV*)SvRV(match); + + cv_set_call_checker(cv, install_sm_op, (SV*)cv); |