Created
September 27, 2014 08:58
-
-
Save niner/493268db5ba449caef49 to your computer and use it in GitHub Desktop.
SEGFAULTs in S_mg_findext_flags because obj_deref in line 110 is a broken SV.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <EXTERN.h> | |
#include <XSUB.h> | |
#include <perl.h> | |
static void xs_init (pTHX); | |
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); | |
EXTERN_C void boot_Socket (pTHX_ CV* cv); | |
XS(p5_call_p6_method); | |
EXTERN_C void xs_init(pTHX) { | |
char *file = __FILE__; | |
newXS("Perl6::Object::call_method", p5_call_p6_method, file); | |
} | |
PerlInterpreter *my_perl; | |
PerlInterpreter *p5_init_perl() { | |
char *embedding[] = { "", "-e", "0" }; | |
PERL_SYS_INIT3(0, NULL, NULL); | |
my_perl = perl_alloc(); | |
PERL_SET_CONTEXT(my_perl); | |
PL_perl_destruct_level = 1; | |
perl_construct( my_perl ); | |
perl_parse(my_perl, xs_init, 3, embedding, NULL); | |
PL_exit_flags |= PERL_EXIT_DESTRUCT_END; | |
perl_run(my_perl); | |
return my_perl; | |
} | |
AV *p5_call_function(PerlInterpreter *my_perl, char *name, int len, SV *args[]) { | |
dSP; | |
int i; | |
int count; | |
AV * const retval = newAV(); | |
int flags = G_ARRAY | G_EVAL; | |
PERL_SET_CONTEXT(my_perl); | |
ENTER; | |
SAVETMPS; | |
PUSHMARK(SP); | |
for (i = 0; i < len; i++) { | |
XPUSHs(sv_2mortal(args[i])); | |
} | |
PUTBACK; | |
count = call_pv(name, flags); | |
return retval; | |
} | |
typedef struct { | |
I32 key; /* to make sure it came from Inline */ | |
IV index; | |
SV *(*call_p6_method)(int, char *, SV *, SV **); | |
} _perl6_magic; | |
#define PERL6_MAGIC_KEY 0x0DD515FE | |
SV *p5_wrap_p6_object(PerlInterpreter *my_perl, IV i, SV *p5obj, SV *(*call_p6_method)(int, char * , SV *, SV **)) { | |
SV * inst; | |
SV * inst_ptr; | |
if (p5obj == NULL) { | |
inst_ptr = newSViv(0); | |
inst = newSVrv(inst_ptr, "Perl6::Object"); | |
} | |
else { | |
inst_ptr = p5obj; | |
inst = SvRV(inst_ptr); | |
SvREFCNT_inc(inst_ptr); | |
} | |
_perl6_magic priv; | |
/* set up magic */ | |
priv.key = PERL6_MAGIC_KEY; | |
priv.index = i; | |
priv.call_p6_method = call_p6_method; | |
sv_magic(inst, inst, PERL_MAGIC_ext, (char *) &priv, sizeof(priv)); | |
MAGIC * const mg = mg_find(inst, PERL_MAGIC_ext); | |
return inst_ptr; | |
} | |
SV *call_p6_method(int obj, char *name, SV *i, SV **args) { | |
} | |
XS(p5_call_p6_method) { | |
dXSARGS; | |
SV * name = ST(0); | |
SV * obj = ST(1); | |
AV * args = newAV(); | |
av_extend(args, items - 2); | |
int i; | |
for (i = 0; i < items - 2; i++) { | |
SV * const next = SvREFCNT_inc(ST(i + 2)); | |
if (av_store(args, i, next) == NULL) | |
SvREFCNT_dec(next); /* see perlguts Working with AVs */ | |
} | |
STRLEN len; | |
char * const name_pv = SvPV(name, len); | |
char * const name_str = savepvn(name_pv, len); | |
SV * const obj_deref = SvRV(obj); | |
MAGIC * const mg = mg_find(obj_deref, '~'); | |
_perl6_magic* const p6mg = (_perl6_magic*)(mg->mg_ptr); | |
SV *err = NULL; | |
return newRV_inc((SV*)p5_call_function(my_perl, "zero", 0, NULL)); | |
} | |
int main(int argc, char **argv) { | |
PerlInterpreter *my_perl = p5_init_perl(); | |
eval_pv("\ | |
package Perl6::Object;\ | |
\ | |
our $AUTOLOAD;\ | |
sub AUTOLOAD {\ | |
my ($self) = @_;\ | |
warn qq{AUTOLOAD $AUTOLOAD};\ | |
my $name = $AUTOLOAD =~ s/.*:://r;\ | |
Perl6::Object::call_method($name, @_);\ | |
}\ | |
\ | |
", 1); | |
eval_pv("\ | |
sub zero {\ | |
warn 'zero';\ | |
return 1;\ | |
}\ | |
sub one {\ | |
my ($obj) = @_;\ | |
warn 'callback one';\ | |
return $obj->foo;\ | |
}\ | |
", 1); | |
SV *callme = p5_wrap_p6_object(my_perl, 0, NULL, &call_p6_method); | |
p5_call_function(my_perl, "one", 1, &callme); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment