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

Reply via email to