2 # Copyright (C) 2001-2008, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
9 use Parrot::Test tests => 22;
13 t/pmc/exception.t - Exception Handling
17 % prove t/pmc/exception-old.t
21 Tests C<Exception> and C<ExceptionHandler> PMCs.
26 pasm_output_is( <<'CODE', <<'OUTPUT', "get_results" );
32 setattribute P1, 'message', P2
55 pir_output_is( <<'CODE', <<'OUTPUT', 'Exception initialized with String' );
61 ex = new ['Exception'], msg
74 pir_output_is( <<'CODE', <<'OUTPUT', 'Exception initialized with Hash' );
79 h['message'] = 'Message'
80 ex = new ['Exception'], h
93 pasm_output_is( <<'CODE', <<'OUTPUT', "get_results - be sure registers are ok" );
100 set P2, "just pining"
101 setattribute P1, 'message', P2
103 print "not reached\n"
116 pir_output_is( <<'CODE', <<'OUTPUT', ".get_results() - PIR" );
120 $P1 = new ['Exception']
122 set $P2, "just pining"
123 setattribute $P1, 'message', $P2
125 print "not reached\n"
147 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw - message" );
151 new P30, ['Exception']
153 set P20, "something happened"
154 setattribute P30, "message", P20
156 print "not reached\n"
171 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler" );
172 new P0, ['Exception']
174 set P20, "something happened"
175 setattribute P0, "message", P20
177 print "not reached\n"
183 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
185 new P0, ['Exception']
188 print "not reached\n"
193 /No exception handler and no message/
196 pasm_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler, no message" );
197 new P0, ['Exception']
199 print "not reached\n"
202 /No exception handler and no message/
205 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers" );
210 new P30, ['Exception']
212 set P20, "something happened"
213 setattribute P30, "message", P20
215 print "not reached\n"
219 getattribute P2, P5, "message"
220 print "caught it in 1\n"
226 getattribute P2, P0, "message"
227 print "caught it in 2\n"
237 pasm_output_is( <<'CODE', <<'OUTPUT', "2 exception handlers, throw next" );
242 new P30, ['Exception']
244 set P20, "something happened"
245 setattribute P30, "message", P20
247 print "not reached\n"
252 print "caught it in 1\n"
259 print "caught it in 2\n"
273 pasm_output_is( <<'CODE', <<OUT, "die, error, severity" );
276 print "not reached\n"
282 set I0, P5['severity']
292 pasm_error_output_like( <<'CODE', <<OUT, "die - no handler" );
294 print "not reached\n"
300 /No exception handler and no message/
303 pasm_output_is( <<'CODE', '', "exit exception" );
306 print "not reached\n"
310 pasm_output_is( <<'CODE', <<'OUTPUT', "push_eh - throw" );
314 new P30, ['Exception']
316 print "not reached\n"
328 # stringification is handled by a vtable, which runs in a second
329 # runloop. when an error in the method tries to go to a Error_Handler defined
330 # outside it, it winds up going to the inner runloop, giving strange results.
331 pir_output_is( <<'CODE', <<'OUTPUT', 'pop_eh out of context (2)' );
333 $P0 = get_hll_global ['Foo'], 'load'
355 .sub get_string :vtable :method
356 $P0 = new ['Exception']
363 pir_output_is( <<'CODE', <<'OUTPUT', "exit_handler via exit exception" );
372 .const 'Sub' $P0 = 'exit_handler'
377 .sub exit_handler :outer(main)
389 ## Regression test for r14697. This probably won't be needed when PDD23 is
390 ## fully implemented.
391 pir_error_output_like( <<'CODE', <<'OUTPUT', "invoke handler in calling sub", todo => "deprecate rethrow" );
392 ## This tests that error handlers are out of scope when invoked (necessary for
393 ## rethrow) when the error is signalled in another sub.
397 print "not reached.\n"
400 .get_results (exception)
402 print "in handler.\n"
409 $P0 = new ['Exception']
411 set $P2, "something broke"
412 setattribute $P0, "message", $P2
422 pir_output_is(<<'CODE', <<'OUTPUT', "taking a continuation promotes RetCs");
423 ## This test creates a continuation in a inner sub and re-invokes it later. The
424 ## re-invocation signals an error, which is caught by an intermediate sub.
425 ## Returning from the "test" sub the second time failed in r28794; invoking
426 ## parrot with "-D80" shows clearly that the "test" context was being recycled
427 ## prematurely. For some reason, it is necessary to signal the error in order
428 ## to expose the bug.
434 print "calling test\n"
436 print "back from test\n"
439 print "calling cont\n"
446 ## Push a handler around the foo() call.
448 print " calling foo\n"
451 print " returning from test.\n"
455 print " test: caught error\n"
459 ## Take a continuation.
461 cont = new ['Continuation']
462 set_addr cont, over_there
463 print " returning from foo\n"
466 print " got over there.\n"
468 ex = new ['Exception']
484 pir_error_output_like( <<'CODE', <<'OUTPUT', "throw - no handler" );
493 $S1 = $P0['backtrace']
502 /No such string attribute/
505 pir_output_is( <<'CODE', <<'OUTPUT', "catch ex from C-level MULTI function" );
514 #throw an exception from a C-level MULTI function
522 .local string message
523 .get_results (exception)
525 message = exception['message']
526 say_something(message)
531 .param string message
532 #Calling this sub is enough to trigger the bug. If execution reached this
533 #point, the bug is fixed.
541 pir_output_is( <<'CODE', <<'OUTPUT', "count_eh" );
544 if $I0 == 0 goto right_number1
552 if $I1 == 2 goto right_number2
560 if $I2 == 0 goto right_number3
566 print "first handler\n"
569 print "second handler\n"
582 # cperl-indent-level: 4
585 # vim: expandtab shiftwidth=4: