]> granicus.if.org Git - php/commitdiff
Changed meaning of "op2" for ZEND_FREE, ZEND_FE_FREE, ZEND_FAST_CALL, ZEND_FAST_RET.
authorDmitry Stogov <dmitry@zend.com>
Tue, 10 Nov 2015 16:13:54 +0000 (19:13 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 10 Nov 2015 16:13:54 +0000 (19:13 +0300)
Previously it was an instruction number.
Now it's an index in op_array->try_cacth_array[].

Zend/zend_compile.c
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h
ext/opcache/Optimizer/block_pass.c
sapi/phpdbg/phpdbg_opcode.c
sapi/phpdbg/tests/exceptions_003.phpt

index 44d8d22e0233232e981a7a8418bc675fc47f156b..193370f48ec87b1067ad0d54d057164ee3662b98 100644 (file)
@@ -58,10 +58,7 @@ typedef struct _zend_loop_var {
        zend_uchar opcode;
        zend_uchar var_type;
        uint32_t   var_num;
-       union {
-               uint32_t try_catch_offset;
-               uint32_t brk_cont_offset;
-       } u;
+       uint32_t   try_catch_offset;
 } zend_loop_var;
 
 static inline void zend_alloc_cache_slot(uint32_t literal) {
@@ -584,7 +581,7 @@ static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var
                info.opcode = free_opcode;
                info.var_type = loop_var->op_type;
                info.var_num = loop_var->u.op.var;
-               info.u.brk_cont_offset = CG(context).current_brk_cont;
+               info.try_catch_offset = CG(active_op_array)->last_try_catch;
                brk_cont_element->start = get_next_op_number(CG(active_op_array));
        } else {
                info.opcode = ZEND_NOP;
@@ -3574,7 +3571,7 @@ static int zend_handle_loops_and_finally_ex(zend_long depth) /* {{{ */
                        opline->result.var = loop_var->var_num;
                        SET_UNUSED(opline->op1);
                        SET_UNUSED(opline->op2);
-                       opline->op1.num = loop_var->u.try_catch_offset;
+                       opline->op1.num = loop_var->try_catch_offset;
                } else if (loop_var->opcode == ZEND_RETURN) {
                        /* Stack separator */
                        break;
@@ -3592,7 +3589,7 @@ static int zend_handle_loops_and_finally_ex(zend_long depth) /* {{{ */
                        opline->op1_type = loop_var->var_type;
                        opline->op1.var = loop_var->var_num;
                        SET_UNUSED(opline->op2);
-                       opline->op2.num = loop_var->u.brk_cont_offset;
+                       opline->op2.num = loop_var->try_catch_offset;
                        opline->extended_value = ZEND_FREE_ON_RETURN;
                        depth--;
            }
@@ -4163,7 +4160,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
                fast_call.opcode = ZEND_FAST_CALL;
                fast_call.var_type = IS_TMP_VAR;
                fast_call.var_num = CG(context).fast_call_var;
-               fast_call.u.try_catch_offset = try_catch_offset;
+               fast_call.try_catch_offset = try_catch_offset;
                zend_stack_push(&CG(loop_var_stack), &fast_call);
        }
 
index 4cf131af53b57e6044f07fe2e8944982be385d9a..524eb5cb676d1bb22613c5a1b8eab08474374626 100644 (file)
@@ -516,48 +516,52 @@ static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num
 static void zend_resolve_fast_call(zend_op_array *op_array, uint32_t op_num)
 {
        int i;
-       uint32_t finally_op_num = 0;
+       uint32_t finally_num = (uint32_t)-1;
 
        for (i = 0; i < op_array->last_try_catch; i++) {
                if (op_num >= op_array->try_catch_array[i].finally_op
                                && op_num < op_array->try_catch_array[i].finally_end) {
-                       finally_op_num = op_array->try_catch_array[i].finally_op;
+                       finally_num = i;
                }
        }
 
-       if (finally_op_num) {
+       if (finally_num != (uint32_t)-1) {
                /* Must be ZEND_FAST_CALL */
-               ZEND_ASSERT(op_array->opcodes[finally_op_num - 2].opcode == ZEND_FAST_CALL);
+               ZEND_ASSERT(op_array->opcodes[op_array->try_catch_array[finally_num].finally_op - 2].opcode == ZEND_FAST_CALL);
                op_array->opcodes[op_num].extended_value = ZEND_FAST_CALL_FROM_FINALLY;
-               op_array->opcodes[op_num].op2.opline_num = finally_op_num - 2;
+               op_array->opcodes[op_num].op2.num = finally_num;
        }
 }
 
 static void zend_resolve_finally_ret(zend_op_array *op_array, uint32_t op_num)
 {
        int i;
-       uint32_t catch_op_num = 0, finally_op_num = 0;
+       uint32_t finally_num = (uint32_t)-1;
+       uint32_t catch_num = (uint32_t)-1;
 
        for (i = 0; i < op_array->last_try_catch; i++) {
                if (op_array->try_catch_array[i].try_op > op_num) {
                        break;
                }
                if (op_num < op_array->try_catch_array[i].finally_op) {
-                       finally_op_num = op_array->try_catch_array[i].finally_op;
+                       finally_num = i;
                }
                if (op_num < op_array->try_catch_array[i].catch_op) {
-                       catch_op_num = op_array->try_catch_array[i].catch_op;
+                       catch_num = i;
                }
        }
 
-       if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
+       if (finally_num != (uint32_t)-1 &&
+           (catch_num == (uint32_t)-1 ||
+            op_array->try_catch_array[catch_num].catch_op >=
+            op_array->try_catch_array[finally_num].finally_op)) {
                /* in case of unhandled exception return to upward finally block */
                op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_FINALLY;
-               op_array->opcodes[op_num].op2.opline_num = finally_op_num;
-       } else if (catch_op_num) {
+               op_array->opcodes[op_num].op2.num = finally_num;
+       } else if (catch_num != (uint32_t)-1) {
                /* in case of unhandled exception return to upward catch block */
                op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_CATCH;
-               op_array->opcodes[op_num].op2.opline_num = catch_op_num;
+               op_array->opcodes[op_num].op2.num = catch_num;
        }
 }
 
index 88bd9f22805046de45725d36172df66b38248e18..3c7e20213bb9941c81b1935e8ad9f13789130067 100644 (file)
@@ -2711,7 +2711,7 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
        ZEND_VM_JMP(opline);
 }
 
-ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY)
+ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, TRY_CATCH)
 {
        USE_OPLINE
 
@@ -2720,7 +2720,7 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY)
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY)
+ZEND_VM_HANDLER(127, ZEND_FE_FREE, TMPVAR, TRY_CATCH)
 {
        zval *var;
        USE_OPLINE
@@ -7239,6 +7239,7 @@ ZEND_VM_HANDLER(155, ZEND_BIND_TRAITS, ANY, ANY)
 ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 {
        uint32_t op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
+       uint32_t last_try_catch = EX(func)->op_array.last_try_catch;
        int i;
        uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
        int in_finally = 0;
@@ -7250,14 +7251,14 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                if ((exc_opline->opcode == ZEND_FREE || exc_opline->opcode == ZEND_FE_FREE)
                        && exc_opline->extended_value & ZEND_FREE_ON_RETURN) {
                        /* exceptions thrown because of loop var destruction on return/break/...
-                        * are logically thrown at the end of the foreach loop, so adjust the
-                        * op_num.
+                        * are logically thrown at the end of the foreach loop,
+                        * so don't check the inner exception regions
                         */
-                       op_num = EX(func)->op_array.brk_cont_array[exc_opline->op2.num].brk;
+                       last_try_catch = exc_opline->op2.num;
                }
        }
 
-       for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+       for (i = 0; i < last_try_catch; i++) {
                if (EX(func)->op_array.try_catch_array[i].try_op > op_num) {
                        /* further blocks will not be relevant... */
                        break;
@@ -7679,7 +7680,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, JMP_ABS, FAST_CALL)
+ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, TRY_CATCH, FAST_CALL)
 {
        USE_OPLINE
        zval *fast_call = EX_VAR(opline->result.var);
@@ -7695,7 +7696,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, JMP_ABS, FAST_CALL)
        ZEND_VM_CONTINUE();
 }
 
-ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, JMP_ABS, FAST_RET)
+ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH, FAST_RET)
 {
        USE_OPLINE
        zval *fast_call = EX_VAR(opline->op1.var);
@@ -7704,7 +7705,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, JMP_ABS, FAST_RET)
                const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
                ZEND_VM_SET_OPCODE(fast_ret + 1);
                if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
-                       fast_call->u2.lineno = fast_ret->op2.opline_num;
+                       fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2;
                }
                ZEND_VM_CONTINUE();
        } else {
@@ -7712,15 +7713,19 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, JMP_ABS, FAST_RET)
                USE_OPLINE
 
                if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
-                       cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num);
-                       ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
+                       uint32_t finally_op = EX(func)->op_array.try_catch_array[opline->op2.num].finally_op;
+
+                       cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, finally_op);
+                       ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op]);
                        ZEND_VM_CONTINUE();
                } else {
                        EG(exception) = Z_OBJ_P(fast_call);
                        Z_OBJ_P(fast_call) = NULL;
                        if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
-                               cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num);
-                               ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
+                               uint32_t catch_op = EX(func)->op_array.try_catch_array[opline->op2.num].catch_op;
+
+                               cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, catch_op);
+                               ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op]);
                                ZEND_VM_CONTINUE();
                        } else {
                                cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0);
index cc0193bfcd2eb1e0fc68bdd79232eab15f90632d..42bd60b620d8bad66e0e2d48743ff33c664ffa88 100644 (file)
@@ -1476,6 +1476,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_TRAITS_SPEC_HANDLER(ZEND_
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        uint32_t op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
+       uint32_t last_try_catch = EX(func)->op_array.last_try_catch;
        int i;
        uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
        int in_finally = 0;
@@ -1487,14 +1488,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
                if ((exc_opline->opcode == ZEND_FREE || exc_opline->opcode == ZEND_FE_FREE)
                        && exc_opline->extended_value & ZEND_FREE_ON_RETURN) {
                        /* exceptions thrown because of loop var destruction on return/break/...
-                        * are logically thrown at the end of the foreach loop, so adjust the
-                        * op_num.
+                        * are logically thrown at the end of the foreach loop,
+                        * so don't check the inner exception regions
                         */
-                       op_num = EX(func)->op_array.brk_cont_array[exc_opline->op2.num].brk;
+                       last_try_catch = exc_opline->op2.num;
                }
        }
 
-       for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+       for (i = 0; i < last_try_catch; i++) {
                if (EX(func)->op_array.try_catch_array[i].try_op > op_num) {
                        /* further blocks will not be relevant... */
                        break;
@@ -1633,7 +1634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
                const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
                ZEND_VM_SET_OPCODE(fast_ret + 1);
                if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
-                       fast_call->u2.lineno = fast_ret->op2.opline_num;
+                       fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2;
                }
                ZEND_VM_CONTINUE();
        } else {
@@ -1641,15 +1642,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
                USE_OPLINE
 
                if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
-                       cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num);
-                       ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
+                       uint32_t finally_op = EX(func)->op_array.try_catch_array[opline->op2.num].finally_op;
+
+                       cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, finally_op);
+                       ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op]);
                        ZEND_VM_CONTINUE();
                } else {
                        EG(exception) = Z_OBJ_P(fast_call);
                        Z_OBJ_P(fast_call) = NULL;
                        if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
-                               cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num);
-                               ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
+                               uint32_t catch_op = EX(func)->op_array.try_catch_array[opline->op2.num].catch_op;
+
+                               cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, catch_op);
+                               ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op]);
                                ZEND_VM_CONTINUE();
                        } else {
                                cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0);
index d55b876dba48a827993d30f971df9f5cf116be85..fb6681a0c4e2c7acfef4ed30af56c46fb2050c21 100644 (file)
@@ -60,14 +60,14 @@ $vm_op_flags = array(
        "ZEND_VM_OP1_TMPVAR"      => 1<<2,
        "ZEND_VM_OP1_NUM"         => 1<<3,
        "ZEND_VM_OP1_JMP_ADDR"    => 1<<4,
-       "ZEND_VM_OP1_JMP_ABS"     => 1<<5,
+       "ZEND_VM_OP1_TRY_CATCH"   => 1<<5,
 
        "ZEND_VM_OP2_SPEC"        => 1<<8,
        "ZEND_VM_OP2_CONST"       => 1<<9,
        "ZEND_VM_OP2_TMPVAR"      => 1<<10,
        "ZEND_VM_OP2_NUM"         => 1<<11,
        "ZEND_VM_OP2_JMP_ADDR"    => 1<<12,
-       "ZEND_VM_OP2_JMP_ABS"     => 1<<13,
+       "ZEND_VM_OP2_TRY_CATCH"   => 1<<13,
 
        "ZEND_VM_EXT_NUM"         => 1<<16,
        "ZEND_VM_EXT_VAR"         => 1<<17,
@@ -98,7 +98,7 @@ $vm_op_decode = array(
        "TMPVAR"               => ZEND_VM_OP1_SPEC | ZEND_VM_OP1_TMPVAR,
        "NUM"                  => ZEND_VM_OP1_NUM,
        "JMP_ADDR"             => ZEND_VM_OP1_JMP_ADDR,
-       "JMP_ABS"              => ZEND_VM_OP1_JMP_ABS,
+       "TRY_CATCH"            => ZEND_VM_OP1_TRY_CATCH,
 );
 
 $vm_ext_decode = array(
index 70b3e81f843d81a78f33862f0ec3bd1c531b55c5..d53ce5ecd946325c97236c21e62e266bae1acae9 100644 (file)
@@ -277,7 +277,7 @@ static uint32_t zend_vm_opcodes_flags[182] = {
        0x00000801,
        0x00011003,
        0x00010300,
-       0x00000005,
+       0x00002005,
        0x00800703,
        0x00010703,
        0x02000007,
@@ -334,7 +334,7 @@ static uint32_t zend_vm_opcodes_flags[182] = {
        0x00000103,
        0x00001003,
        0x00040001,
-       0x00000005,
+       0x00002005,
        0x00010700,
        0x00000000,
        0x00000000,
index 62dbe2205d51ebc6cb91d64c12bc9fe35fa2e115..039f6d8d4ece577c4034e2476fa8f9781b71fc26 100644 (file)
 #define ZEND_VM_OP1_TMPVAR       0x00000004
 #define ZEND_VM_OP1_NUM          0x00000008
 #define ZEND_VM_OP1_JMP_ADDR     0x00000010
-#define ZEND_VM_OP1_JMP_ABS      0x00000020
+#define ZEND_VM_OP1_TRY_CATCH    0x00000020
 #define ZEND_VM_OP2_SPEC         0x00000100
 #define ZEND_VM_OP2_CONST        0x00000200
 #define ZEND_VM_OP2_TMPVAR       0x00000400
 #define ZEND_VM_OP2_NUM          0x00000800
 #define ZEND_VM_OP2_JMP_ADDR     0x00001000
-#define ZEND_VM_OP2_JMP_ABS      0x00002000
+#define ZEND_VM_OP2_TRY_CATCH    0x00002000
 #define ZEND_VM_EXT_NUM          0x00010000
 #define ZEND_VM_EXT_VAR          0x00020000
 #define ZEND_VM_EXT_JMP_ADDR     0x00040000
index eeb263a434435bfc1115ddd5304b9b0994f79dde..4053fe7da470ba3083bf9820faaa0c8b5000daca 100644 (file)
@@ -125,18 +125,6 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
        while (opline < end) {
                switch((unsigned)opline->opcode) {
                        case ZEND_FAST_CALL:
-                               START_BLOCK_OP(ZEND_OP1(opline).opline_num);
-                               if (opline->extended_value) {
-                                       START_BLOCK_OP(ZEND_OP2(opline).opline_num);
-                               }
-                               START_BLOCK_OP(opno + 1);
-                               break;
-                       case ZEND_FAST_RET:
-                               if (opline->extended_value) {
-                                       START_BLOCK_OP(ZEND_OP2(opline).opline_num);
-                               }
-                               START_BLOCK_OP(opno + 1);
-                               break;
                        case ZEND_JMP:
                        case ZEND_DECLARE_ANON_CLASS:
                        case ZEND_DECLARE_ANON_INHERITED_CLASS:
@@ -147,6 +135,7 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
                        case ZEND_GENERATOR_RETURN:
                        case ZEND_EXIT:
                        case ZEND_THROW:
+                       case ZEND_FAST_RET:
                                /* start new block from this+1 */
                                START_BLOCK_OP(opno + 1);
                                break;
@@ -272,21 +261,12 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
                                case ZEND_GENERATOR_RETURN:
                                case ZEND_EXIT:
                                case ZEND_THROW:
-                                       break;
-                               case ZEND_FAST_CALL:
-                                       if (opline->extended_value) {
-                                               cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
-                                       }
-                                       cur_block->op1_to = &blocks[ZEND_OP1(opline).opline_num];
-                                       break;
                                case ZEND_FAST_RET:
-                                       if (opline->extended_value) {
-                                               cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
-                                       }
                                        break;
                                case ZEND_JMP:
                                        cur_block->op1_to = &blocks[ZEND_OP1(opline).opline_num];
                                        break;
+                               case ZEND_FAST_CALL:
                                case ZEND_DECLARE_ANON_CLASS:
                                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                        cur_block->op1_to = &blocks[ZEND_OP1(opline).opline_num];
index 44170c8c9ed910fa8af1b92d4243fbc5097a412f..a792090275b2d451ded0cab2a4855df7c0190eef 100644 (file)
@@ -121,7 +121,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
        case ZEND_FAST_CALL:
        case ZEND_FAST_RET:
                if (op->extended_value != 0) {
-                       spprintf(&decode[2], 0, "J%" PRIu32, op->op2.opline_num);
+                       spprintf(&decode[2], 0, "%" PRIu32, op->op2.num);
                }
                break;
 
index fffe7a9296bbb0e557b08947960fc401ccd9db74..c83eb7517a461eab67ee53b4cd0de8a6f86c8a71 100644 (file)
@@ -25,7 +25,7 @@ prompt> [L7 %s ECHO                    "ok "
  00008:        }
  00009: } catch (Error $e) {
 prompt> ok
-[L7 %s FAST_RET<TO_CATCH>      ~%d                   J7                                        %s]
+[L7 %s FAST_RET<TO_CATCH>      ~%d                   0                                        %s]
 [L9 %s CATCH                   "Error"              $e                   1                    %s]
 >00005:                x();
  00006:        } finally {