summaryrefslogtreecommitdiffstats
path: root/src/opcode_list.h
diff options
context:
space:
mode:
authorNico Williams <nico@cryptonector.com>2023-07-24 06:20:21 -0500
committerGitHub <noreply@github.com>2023-07-24 13:20:21 +0200
commit1cf6515c0638f409ea266463bd29a5f87fb054e0 (patch)
tree34c36860942562abd96156e54f32501e066840d7 /src/opcode_list.h
parent98f709d0c1fd87a8b6a3e10c679442667712b264 (diff)
Fix try/catch catches more than it should #1859
Close #1885, #2140, #2011, #2220, #2485, #2073 Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap errors when raising through a TRY_END so that they will not be caught by the matching TRY_BEGIN. Now a `try exp catch handler` expression generates code like: TRY_BEGIN handler <exp> TRY_END JUMP past_handler handler: <handler> past_handler: ... On backtrack through TRY_BEGIN it just backtracks. If anything past the whole thing raises when <exp> produced a value, then the TRY_END will catch the error, wrap it in another, and backtrack. The TRY_BEGIN will see a wrapped error and then it will unwrap and re-raise the error. If <exp> raises, then TRY_BEGIN will catch the error and jump to the handler, but the TRY_BEGIN will not stack_save() in that case, so on raise/backtrack the TRY_BEGIN will not execute again (nor will the TRY_END).
Diffstat (limited to 'src/opcode_list.h')
-rw-r--r--src/opcode_list.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/opcode_list.h b/src/opcode_list.h
index 886131d7..06147f0f 100644
--- a/src/opcode_list.h
+++ b/src/opcode_list.h
@@ -11,9 +11,10 @@ OP(STORE_GLOBAL, GLOBAL, 0, 0)
OP(INDEX, NONE, 2, 1)
OP(INDEX_OPT, NONE, 2, 1)
OP(EACH, NONE, 1, 1)
-OP(EACH_OPT, NONE, 1, 1)
+OP(EACH_OPT, NONE, 1, 1)
OP(FORK, BRANCH, 0, 0)
-OP(FORK_OPT, BRANCH, 0, 0)
+OP(TRY_BEGIN, BRANCH, 0, 0)
+OP(TRY_END, NONE, 0, 0)
OP(JUMP, BRANCH, 0, 0)
OP(JUMP_F,BRANCH, 1, 0)
OP(BACKTRACK, NONE, 0, 0)