t/op/calling_61.pir crashes because Parrot's trying to treat the number -1 as a PMC. Why?
Parrot_convert_arg (interp=0x804f040, st=0xbf8b70c0) at src/inter_call.c:905 905 if (key->vtable->base_type != enum_class_Key) (gdb) bt #0 Parrot_convert_arg (interp=0x804f040, st=0xbf8b70c0) at src/inter_call.c:905 #1 0xb7d39d51 in set_nci_P (interp=0x804f040, st=0xbf8b70c0, val=0xffffffff) at src/nci.c:150 #2 0xb7d3ce40 in pcf_P_JPP (interp=0x804f040, self=0x80da230) at src/nci.c:1771 #3 0xb7e3532e in Parrot_NCI_invoke (interp=0x804f040, pmc=0x80da230, next=0x0) at ./src/pmc/nci.pmc:309 #4 0xb7d1c534 in Parrot_pcc_invoke_sub_from_sig_object (interp=0x804f040, sub_obj=0x80da230, sig_obj=0x80f38f8) at src/inter_call.c:2471 #5 0xb7d27b80 in Parrot_mmd_multi_dispatch_from_c_args (interp=0x804f040, name=0xb7f2bc3e "cmp", sig=0xb7f03acf "PP->I") at src/multidispatch.c:629 #6 0xb7e00166 in Parrot_default_cmp (interp=0x804f040, pmc=0x80f3930, value=0x80f3914) at ./src/pmc/default.pmc:2447 #7 0xb7ccacfa in Parrot_lt_p_i_ic (cur_opcode=0x8127c88, interp=0x804f040) at src/ops/cmp.ops:315 The desired MMD sub should take two PMCs and returns an INTVAL (frame #5, signature "PP->I"), but the invoked MMD sub takes two PMCs and returns a PMC. The crash comes in convert_arg, where the C function has returned INTVAL -1, but the argument passing code expects that it has returned and Integer PMC. Because 0xffffffff isn't a valid PMC pointer, there's a crash. If you look at src/pmc/integer.pmc, the cmp MULTIs there return INTVALs (signature IJPP), but the MULTI registration code declares them as signature PJPP. I modified Parrot::Pmc2c::MULTI to improve the return-value-of-cmp regexp and the test passes. -- c
Index: lib/Parrot/Pmc2c/MULTI.pm =================================================================== --- lib/Parrot/Pmc2c/MULTI.pm (revision 30934) +++ lib/Parrot/Pmc2c/MULTI.pm (working copy) @@ -93,7 +93,7 @@ # prepend the short signature return type if ($self->name =~ /^i_/) { $short_sig = "v" . $short_sig; - } elsif ($self->name =~ /^is_/ or $self->name =~ /^cmp_/) { + } elsif ($self->name =~ /^is_/ or $self->name =~ /\bcmp\b/) { $short_sig = "I" . $short_sig; } else { $short_sig = "P" . $short_sig;