Thanks for the ticket, it's a very good catch and analysis. I have some small comments on it:
Bruce Gray (via RT) wrote: > # New Ticket Created by Bruce Gray > # Please include the string: [perl #69160] > # in the subject line of all future correspondence about this issue. > # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=69160 > > > > Consider these two classes, both faulty in the same way: > class B0rk { say $.a }; > class Chef { say $.b }; > > Each class makes reference to a attribute that has not been declared, > and so should fail to compile: > $ ./perl6 -e 'class B0rk { say $.a }; say "Done";' > Lexical 'self' not found > > $ ./perl6 -e 'class Chef { say $.b }; say "Done";' > Lexical 'self' not found > While the error message might not be helpful, its shortcomings are not > important to this issue. > The important thing is that *some* error is produced, and that > compilation is aborted. > All is working as expected, when the classes are directly compiled. > > Either class, when evaled solo, behaves as expected. Execution > proceeds, and the error message is placed in $!. > $ ./perl6 -e 'eval q[ class B0rk { say $.a; }; ]; say "Done";' > Done > > $ ./perl6 -e 'eval q[ class Chef { say $.b; }; ]; say "Done";' > Done > > $ ./perl6 -e 'eval q[ class B0rk { say $.a; }; ]; say $!;' > Lexical 'self' not found > > $ ./perl6 -e 'eval q[ class Chef { say $.b; }; ]; say $!;' > Lexical 'self' not found > > All is working as expected, when the classes are evaled in isolation > from each other. > > Evaling the classes together produces two different unexpected > behaviours, depending on how the code is combined. > First, we put both classes into the same string to be evaled once. > $ ./perl6 -e 'eval q[ class B0rk { say $.a; }; class Chef { say > $.b; }; ]; say "Done";' > Done > Lexical 'self' not found > current instr.: 'perl6;Chef;_block43' pc -1 ((unknown file):-1) > called from Sub 'perl6;Perl6;Compiler;main' pc -1 ((unknown > file):-1) > We did not tell $! to print; the error is produced on STDERR, even > though the `eval` should have trapped it. And it's quite curious that the "Done" is printed before the error message. > Next, we eval both classes in the same program, but in separate eval > statements: > $ ./perl6 -e 'eval q[ class B0rk { say $.a; }; ]; eval q[ class > Chef { say $.b; }; ]; say "Done";' > Done > src/call/pcc.c:609: failed assertion 'PObj_is_PMC_TEST(sig_pmc)' > Backtrace - Obtained 24 stack frames (max trace depth is 32). > 0 libparrot.dylib 0x0052836d > Parrot_do_check_events + 173 > 1 libparrot.dylib 0x005284d7 Parrot_confess > + 151 > 2 libparrot.dylib 0x0054171b > Parrot_init_arg_op + 315 > 3 libparrot.dylib 0x005447c2 > parrot_pass_args + 978 > 4 libparrot.dylib 0x00544936 > parrot_pass_args + 1350 > 5 libparrot.dylib 0x0054a74c > Parrot_runops_fromc_args + 220 > 6 libparrot.dylib 0x005924d5 > Parrot_ComposeRole + 3461 > 7 libparrot.dylib 0x0059278a > Parrot_ComposeRole + 4154 > 8 libparrot.dylib 0x00592a96 do_sub_pragmas > + 406 > 9 libparrot.dylib 0x0059a467 > PackFile_fixup_subs + 119 > 10 libparrot.dylib 0x00758d25 do_yylex_init > + 1317 > 11 libparrot.dylib 0x00759165 do_yylex_init > + 2405 > 12 libparrot.dylib 0x005595c0 > Parrot_mmd_cache_destroy + 2096 > 13 libparrot.dylib 0x00678601 > Parrot_Eval_get_isa + 2097 > 14 libparrot.dylib 0x004a8fa2 > Parrot_str_from_int + 3650 > 15 libparrot.dylib 0x005a3977 > enable_event_checking + 2679 > 16 libparrot.dylib 0x005a256a > Parrot_runcore_switch + 4058 > 17 libparrot.dylib 0x00549705 > new_runloop_jump_point + 389 > 18 libparrot.dylib 0x00549a26 > new_runloop_jump_point + 1190 > 19 libparrot.dylib 0x0054a72a > Parrot_runops_fromc_args + 186 > 20 libparrot.dylib 0x005251e1 Parrot_runcode > + 337 > 21 perl6 0x00001ba9 start + 505 > 22 perl6 0x000019e6 start + 54 > 23 ??? 0x00000003 0x0 + 3 > Abort trap > > Notice that in both of the last cases, "Done" *did* print, so neither > compilation nor execution were halted; the diagnostic output seems to > have been produced during program exit. The back trace at exit is a known parrot problem, the so-called "inferior run-loop" problem. If you are interested in the morbid details (I hope I get them correctly): eval() starts another run loop in parrot. Some parts (I think it's IMCC, ie parrots PIR compiler) doesn't clean up very well after itself if there's a failure in compilation, leaving some mess behind. During global destruction parrot sees this junk and chokes. It's the same problem that makes rakudo fail on exit on the test file t/spec/S12-attributes/class.t, known to the parrot folks and not easily solved (but being worked on). Cheers, Moritz