Yesterday on IIRC coke pasted[1] the following piece of code, I'll snip here some irrelevant parts:

  push_eh catch
    $P1 = find_global "Spam", "q"
  clear_eh

In combination with the resume functionality below in the "catch" handler, this will do the following:

1) global found, pop the handler (ok)
2) gobal not found, resume at C<clear_eh>), try to pop the handler:
  2a) there isn't an outer handler (ok)
  2b) there is an outer exception handler - pop em (err)

Therefore such a construct can't be used reliably.

   push_eh catch
    store_lex 3, "q", $P1
  clear_eh

The C<store_lex> does again throw an exception. But the exception constructed in this opcode isn't resumable (it has a NULL C<ret_addr> argument). Therefore it segfaults in the line C<invoke P4>.

catch:
  P4 = P5["_invoke_cc"]
  invoke P4
.end

I have recommended the following snippet to handle exceptions:

  push_eh except_N
      # code that might fail
      clear_eh
resume_N:
  ...
except_N:
  $S0 = P5["_message"]  # get and
  printerr $S0          # print
  printerr "\n"         # exception message
  gpto resume_N

This corresponds to HLL exception code with try{} / except. If no message is to be printed, the resume label should be directly after the clear_eh:

  push_eh except_N
      # code that might fail
      clear_eh
  except_N:

(the _N denotes a unique number possibly created by the compiler)

leo

[1] http://nopaste.snit.ch:8001/2808

Reply via email to