2 # Copyright (C) 2001-2008, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
9 use Parrot::Test tests => 31;
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" );
109 pasm_output_is( <<'CODE', <<'OUTPUT', "get_results - be sure registers are ok" );
115 set P1, "just pining"
117 print "not reached\n"
130 pir_output_is( <<'CODE', <<'OUTPUT', ".get_results() - PIR" );
135 set $P1, "just pining"
137 print "not reached\n"
159 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw - message" );
164 set P30, "something happend"
166 print "not reached\n"
181 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler" );
183 set P0, "something happend"
185 print "not reached\n"
191 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
196 print "not reached\n"
201 /No exception handler and no message/
204 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
207 print "not reached\n"
210 /No exception handler and no message/
213 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers" );
219 set P30, "something happend"
221 print "not reached\n"
226 print "caught it in 1\n"
233 print "caught it in 2\n"
243 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers, throw next" );
249 set P30, "something happend"
251 print "not reached\n"
256 print "caught it in 1\n"
263 print "caught it in 2\n"
276 pasm_output_is( <<'CODE', <<OUT, "die" );
279 print "not reached\n"
288 pasm_output_is( <<'CODE', <<OUT, "die, error, severity" );
291 print "not reached\n"
296 set I0, P5['severity']
306 pasm_error_output_like( <<'CODE', <<OUT, "die - no handler" );
308 print "not reached\n"
314 /No exception handler and no message/
317 pasm_output_is( <<'CODE', '', "exit exception" );
320 print "not reached\n"
324 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw" );
330 print "not reached\n"
342 pir_error_output_like( <<'CODE', <<'OUTPUT', 'pop_eh with no handler' );
345 print "no exceptions.\n"
348 /No handler to delete./
351 pir_output_is( <<'CODE', <<'OUTPUT', 'pop_eh out of context (2)');
353 .local pmc outer, cont
360 .get_results (exception)
371 ## pop_eh is illegal here, and signals an exception.
377 Error: No handler to delete.
381 # stringification is handled by a vtable, which runs in a second
382 # runloop. when an error in the method tries to go to a Error_Handler defined
383 # outside it, it winds up going to the inner runloop, giving strange results.
384 pir_output_is( <<'CODE', <<'OUTPUT', 'pop_eh out of context (2)', todo => 'runloop shenanigans' );
386 $P0 = get_hll_global ['Foo'], 'load'
406 .sub get_string :vtable :method
407 $P0 = new 'Exception'
414 pir_error_output_like( <<'CODE', <<'OUTPUT', "throw in main, no handler" );
417 $P0 = new 'Exception'
423 No exception handler/
426 pir_output_is( <<'CODE', <<'OUTPUT', "exit_handler via exit exception" );
435 .const 'Sub' $P0 = 'exit_handler'
440 .sub exit_handler :outer(main)
452 ## Regression test for r14697. This probably won't be needed when PDD23 is
453 ## fully implemented.
454 pir_error_output_like( <<'CODE', <<'OUTPUT', "invoke handler in calling sub" );
455 ## This tests that error handlers are out of scope when invoked (necessary for
456 ## rethrow) when the error is signalled in another sub.
460 print "not reached.\n"
463 .get_results (exception)
465 print "in handler.\n"
472 $P0 = new 'Exception'
473 $P0 = "something broke"
483 pir_error_output_like( <<'CODE', <<'OUTPUT', 'die_s' );
485 die 'We are dying str!'
490 pir_error_output_like( <<'CODE', <<'OUTPUT', 'die_p' );
494 msg = 'We are dying pmc!'
501 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - goto label" );
503 print "before calling setup_foo\n"
505 print "after calling setup_foo\n"
510 print "in setup_foo\n"
516 print "running more code\n"
524 before calling setup_foo
528 after calling setup_foo
531 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - return from cont" );
533 print "before calling setup_foo\n"
535 print "after calling setup_foo\n"
540 print "in setup_foo\n"
546 print "never reached\n"
552 before calling setup_foo
555 after calling setup_foo
559 pir_output_is( <<'CODE', <<'OUTPUT', "resuming after exception handled - return from cont" );
560 # This test is a simplified version of PGE's grammar creation code.
563 $P1 = newclass 'FirstClass'
564 $P1 = newclass 'MakerClass'
570 print "before compile\n"
572 print "after compile\n"
577 .param string classname
578 print "in compile subroutine\n"
579 $P0 = new 'FirstClass'
580 $P1 = $P0.'compile'(classname)
581 print "returned from handler\nException message: "
585 .namespace [ "FirstClass" ]
586 .sub 'compile' :method
588 print "in compile method\n"
590 $P1 = "no exception\n"
593 $P0 = new 'MakerClass'
603 .namespace [ "MakerClass" ]
606 print "in make method\n"
608 print "after newclass, never reached\n"
613 in compile subroutine
617 returned from handler
618 Exception message: Class Foo already registered!
622 pir_output_is( <<'CODE', <<'OUTPUT', "Resumable exceptions" );
626 say 'Before throwing'
636 say 'In the exception handler'
642 In the exception handler
646 pir_output_is( <<'CODE', <<'OUTPUT', "Resumable exceptions from a different context");
662 $P0 = new 'Exception'
665 $P0 = new 'Exception'
679 # cperl-indent-level: 4
682 # vim: expandtab shiftwidth=4: