Brent 'Dax' Royal-Gordon wrote:
Jens Rieks <[EMAIL PROTECTED]> wrote:
It now prints an error message:
with nothing
with int 5
Parrot VM: PANIC: vt is an unknown signature type.
CAN_BUILD_CALL_FRAMES is disabled, add the signature to src/call_list.txt!
C file src/nci.c, line 4485
Parrot file (unknown file), line 0
I'm not sure this is a panic-worthy error--panics are really meant for cases where something has gone horribly, unfixably wrong in the interpreter's guts, like a critical pointer in the ParrotInterp got nulled out, or some important flags in the GC system got trashed. It should be virtually impossible to cause a panic from Parrotspace.
It' certainly better than a segfault ;) but anyway....
The whole reason I'm fooling around with nci in the first place is to register callbacks as described in pdd16, and it was the function signature of 'vCYZ' that was failing. I looked in call_list.txt as suggested by the error message, and sure enough it wasn't there (is this intentional? It seems odd that it wasn't there.). I added it, but the pcf_v_CYZ() wrapper function failed to compile. It looked like this
static void
pcf_v_CYZ(Interp *interpreter, PMC *self)
{
typedef void (*func_t)(, , ); //<- seems like something's missing :)
func_t pointer;
pointer = (func_t)D2FPTR(PMC_struct_val(self));
(void)(*pointer)(,,);
set_return_val(interpreter, 0, 0, 0, 0, 0);
return;
}
build_nativecall.pl has no reference to 'C','Y', or 'Z' parameter types. hmm... It seems that one or both of us doesn't understand what 'CYZ' means.
Anyway, gleefullly ignoring the exclamated warnings at the top of the file not to edit it by hand, I changed it to look like
static void
pcf_v_CYZ(Interp *interpreter, PMC *self)
{
typedef void (*func_t)(void(void *, void*), void * );
func_t pointer;
pointer = (func_t)D2FPTR(PMC_struct_val(self)); //ptr to my c function
PMC *parrot_sub, *user_data, *callback;
parrot_sub = REG_PMC(5); // argument 1?
user_data = REG_PMC(6); // argument 2?
STRING * sig = string_make(interpreter, "tU", 2, "iso-8859-1", 0);
callback = Parrot_make_cb(interpreter, parrot_sub, user_data, sig);
(void)(*pointer)(D2FPTR(PMC_data(callback)), user_data);
set_return_val(interpreter, 0, 0, 0, 0, 0);
return;
}
Which successfully invokes the callback, but I can't help thinking that I'm misunderstanding something like the signature. Should 'vCYZ' generate a pcf_v_CYZ() something like what I've written?
cheers, Charles
Here's the code I'm running to test it.
cb.c: void make_callback(void (callback)(void*, void*), void* parrot_cookie) { printf("calling callback\n"); callback("foo", parrot_cookie); }
cb.imc: .sub _main
.local pmc cblib .local pmc make_callback .local pmc callback .local pmc my_data
loadlib cblib, 'dynext/libcb.so'
dlfunc make_callback, cblib, 'make_callback', 'vCYZ' callback = find_global '_callback'
my_data = new .PerlString make_callback(callback, my_data) end .end
.sub _callback .param pmc my_data .param pmc their_data print "this is the callback\n" .end
output looks like: calling callback this is the callback