2 # Copyright (C) 2001-2008, The Perl Foundation.
7 use lib qw( . lib ../lib ../../lib );
9 use Parrot::Test tests => 30;
13 t/op/exceptions.t - Exception Handling
17 % prove t/op/exceptions.t
21 Tests C<Exception> and C<ExceptionHandler> PMCs.
25 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh label - pop_eh" );
38 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh eh - pop_eh" );
39 new P29, 'ExceptionHandler'
50 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw" );
65 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh eh - throw" );
67 new P29, 'ExceptionHandler'
68 set_addr P29, _handler
82 pasm_output_is( <<'CODE', <<'OUTPUT', "get_results" );
91 get_results "0,0", P0, S0
108 pasm_output_is( <<'CODE', <<'OUTPUT', "get_results - be sure registers are ok" );
114 set P1, "just pining"
116 print "not reached\n"
119 get_results "0,0", P1, S0
129 pir_output_is( <<'CODE', <<'OUTPUT', ".get_results() - PIR" );
134 set P1, "just pining"
136 print "not reached\n"
157 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw - message" );
162 set P30, "something happend"
164 print "not reached\n"
167 get_results "0,0", P5, S0
178 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler" );
180 set P0, "something happend"
182 print "not reached\n"
188 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
193 print "not reached\n"
198 /No exception handler and no message/
201 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
204 print "not reached\n"
207 /No exception handler and no message/
210 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers" );
216 set P30, "something happend"
218 print "not reached\n"
221 get_results "0,0", P5, S0
222 print "caught it in 1\n"
227 get_results "0,0", P0, S0
228 print "caught it in 2\n"
238 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers, throw next" );
244 set P30, "something happend"
246 print "not reached\n"
249 get_results "0,0", P5, S0
250 print "caught it in 1\n"
255 get_results "0,0", P5, S0
256 print "caught it in 2\n"
269 pasm_output_is( <<'CODE', <<OUT, "die" );
272 print "not reached\n"
281 pasm_output_is( <<'CODE', <<OUT, "die, error, severity" );
284 print "not reached\n"
287 get_results "0,0", P5, S0
289 set I0, P5['severity']
299 pasm_error_output_like( <<'CODE', <<OUT, "die - no handler" );
301 print "not reached\n"
307 /No exception handler and no message/
310 pasm_output_is( <<'CODE', '', "exit exception" );
313 print "not reached\n"
317 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw" );
323 print "not reached\n"
335 pir_error_output_like( <<'CODE', <<'OUTPUT', 'pop_eh with no handler' );
338 print "no exceptions.\n"
341 /No handler to delete./
344 pir_output_is( <<'CODE', <<'OUTPUT', 'pop_eh out of context (2)');
346 .local pmc outer, cont
353 .get_results (exception, $S0)
363 ## pop_eh is illegal here, and signals an exception.
369 Error: No handler to delete.
373 # stringification is handled by a vtable method, which runs in a second
374 # runloop. when an error in the method tries to go to a Error_Handler defined
375 # outside it, it winds up going to the inner runloop, giving strange results.
376 pir_output_is( <<'CODE', <<'OUTPUT', 'pop_eh out of context (2)', todo => 'runloop shenanigans' );
378 $P0 = get_hll_global ['Foo'], 'load'
398 .sub get_string :vtable :method
399 $P0 = new 'Exception'
406 pir_error_output_like( <<'CODE', <<'OUTPUT', "throw in main, no handler" );
409 $P0 = new 'Exception'
415 No exception handler/
418 pir_output_is( <<'CODE', <<'OUTPUT', "exit_handler via exit exception" );
427 .return exit_handler()
430 .sub exit_handler :outer(main)
442 ## Regression test for r14697. This probably won't be needed when PDD23 is
443 ## fully implemented.
444 pir_error_output_like( <<'CODE', <<'OUTPUT', "invoke handler in calling sub" );
445 ## This tests that error handlers are out of scope when invoked (necessary for
446 ## rethrow) when the error is signalled in another sub.
450 print "not reached.\n"
453 .get_results (exception, $S0)
454 print "in handler.\n"
461 $P0 = new 'Exception'
462 $P0 = "something broke"
472 pir_error_output_like( <<'CODE', <<'OUTPUT', 'die_s' );
474 die 'We are dying str!'
479 pir_error_output_like( <<'CODE', <<'OUTPUT', 'die_p' );
483 msg = 'We are dying pmc!'
490 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - goto label" );
492 print "before calling setup_foo\n"
494 print "after calling setup_foo\n"
499 print "in setup_foo\n"
505 print "running more code\n"
513 before calling setup_foo
517 after calling setup_foo
520 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - return from cont" );
522 print "before calling setup_foo\n"
524 print "after calling setup_foo\n"
529 print "in setup_foo\n"
535 print "never reached\n"
541 before calling setup_foo
544 after calling setup_foo
548 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - return from cont" );
549 # This test is a simplified version of PGE's grammar creation code.
552 $P1 = newclass 'FirstClass'
553 $P1 = newclass 'MakerClass'
559 print "before compile\n"
561 print "after compile\n"
566 .param string classname
567 print "in compile subroutine\n"
568 $P0 = new 'FirstClass'
569 $P1 = $P0.'compile'(classname)
570 print "returned from handler\nException message: "
574 .namespace [ "FirstClass" ]
575 .sub 'compile' :method
577 print "in compile method\n"
579 $P1 = "no exception\n"
582 $P0 = new 'MakerClass'
587 get_results "0,0", $P2, $S2
592 .namespace [ "MakerClass" ]
595 print "in make method\n"
597 print "after newclass, never reached\n"
602 in compile subroutine
606 returned from handler
607 Exception message: Class Foo already registered!
611 pir_output_is( <<'CODE', <<'OUTPUT', "Resumable exceptions" );
615 say 'Before throwing'
624 say 'In the exception handler'
630 In the exception handler
636 # cperl-indent-level: 4
639 # vim: expandtab shiftwidth=4: