With some help from DietCoke, we got most of the problem solved. However, several tests are failing now, especially those dealing with overriding the invoke vtable method.
One error specifically caught my eye, from t/pmc/namespace.t:1672: .sub 'main' :main $P0 = newclass 'Override' $P1 = new 'Override' $P2 = find_method $P1, 'foo' .end .namespace [ 'Override' ] .sub 'find_method' :vtable say "Finding method" .end With the patch, this test returns an error that we are passing one parameter, but expecting 0. This is, I assume, desired behavior: We are passing one parameter (the method name string 'foo'), but 'find_method' isn't expecting any parameters. Changing the method to this fixes the problem: .sub 'find_method' :vtable .param string name say "Finding method" .end I suspect this is desired behavior, because the 'find_method' vtable method should take the name of the method to find as a parameter (otherwise, how do you know what to find?) Some of the other tests deal with object invoking, such as "$P0()". With the patch, many of these tests are failing because we aren't passing enough parameters. For instance, the following test is failing because we are passing 0 parameters, when it expects 1: .namespace ['Foo'] .sub invoke :vtable say "you invoked me!" .return() .end .sub main :main $P0 = newclass "Foo" $P1 = new "Foo" $P1() say "got here" .end Changing the invocation to say "$P1($P1)" solves the error, but I doubt this is desired. The parser is, I assume, trying to suck the object into the self parameter, but it isn't being passed in the first place. On invokes, we should be passing the object itself as a "self" parameter, although I don't know how to make that happen. On an odd note, generating PASM output of the above example with "$P1()" and "$P1($P1)" using parrot -o both produce identical PASM files. Neither generated PASM file executes, they both fail with segmentation faults. I don't know yet if this is an artifact of the patch, a problem with the PASM generator, or something else. --Andrew Whitworth
Index: compilers/imcc/pcc.c =================================================================== --- compilers/imcc/pcc.c (revision 28866) +++ compilers/imcc/pcc.c (working copy) @@ -313,7 +313,8 @@ SymReg *regs[2]; /* if this sub is a method, unshift 'self' as first param */ - if (sub->pcc_sub->pragma & P_METHOD) { + if ((sub->pcc_sub->pragma & P_METHOD) || + (IMCC_INFO(interp)->cur_unit->is_vtable_method)) { SymReg *self = get_sym(interp, "self"); if (!self) { self = mk_symreg(interp, "self", 'P'); Index: compilers/imcc/imcc.l =================================================================== --- compilers/imcc/imcc.l (revision 28866) +++ compilers/imcc/imcc.l (working copy) @@ -557,7 +557,8 @@ (r = IMCC_INFO(interp)->cur_unit->instructions->symregs[0]) && r->pcc_sub) { - if ((r->pcc_sub->pragma & P_METHOD) && + if (((r->pcc_sub->pragma & P_METHOD) || + (IMCC_INFO(interp)->cur_unit->is_vtable_method)) && !strcmp(yytext, "self")) { valp->sr = mk_ident(interp, "self", 'P'); IMCC_INFO(interp)->cur_unit->type |= IMC_HAS_SELF; Index: t/pmc/namespace.t =================================================================== --- t/pmc/namespace.t (revision 28866) +++ t/pmc/namespace.t (working copy) @@ -1679,7 +1679,10 @@ .namespace [ 'Override' ] .sub 'find_method' :vtable - say "Finding method" + .param string name + $S0 = "Finding method" + $S1 = $S0 . name + say $S1 .end CODE /Finding method/