zval_dtor(label);
Z_TYPE_P(label) = IS_NULL;
- if (op_array->last_try_catch) {
- zend_uint i, op_num = opline - op_array->opcodes;
- 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) {
- zend_op *p, *end;
- p = opline;
- end = op_array->opcodes + opline->op1.opline_num;
- while (++p < end) {
- if (p->opcode == ZEND_LEAVE) {
- if (pass2) {
- CG(in_compilation) = 1;
- CG(active_op_array) = op_array;
- CG(zend_lineno) = opline->lineno;
- }
- zend_error(E_COMPILE_ERROR, "'goto' out of a finally block is disallowed");
- }
- }
- }
- }
- }
-
/* Check that we are not moving into loop or switch */
current = opline->extended_value;
for (distance = 0; current != dest->brk_cont; distance++) {
CG(active_op_array)->try_catch_array = erealloc(CG(active_op_array)->try_catch_array, sizeof(zend_try_catch_element)*CG(active_op_array)->last_try_catch);
CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = 0;
+ CG(active_op_array)->try_catch_array[try_catch_offset].finally_end = 0;
return try_catch_offset;
}
/* }}} */
void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */
{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) {
zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally");
}
if (finally_token->op_type != IS_UNUSED) {
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num;
- //try_token->u.op.opline_num = catch_token->u.op.opline_num;
+ CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end = get_next_op_number(CG(active_op_array));
opline->opcode = ZEND_LEAVE;
SET_UNUSED(opline->op1);
}
/* break omitted intentionally */
case ZEND_JMP:
+ if (op_array->last_try_catch) {
+ zend_uint i, op_num = opline - op_array->opcodes;
+ 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
+ && op_num < op_array->try_catch_array[i].finally_end)
+ && (opline->op1.opline_num >= op_array->try_catch_array[i].finally_end
+ || opline->op1.opline_num < op_array->try_catch_array[i].finally_op)) {
+ CG(in_compilation) = 1;
+ CG(active_op_array) = op_array;
+ CG(zend_lineno) = opline->lineno;
+ zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed");
+ }
+ }
+ }
opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
break;
case ZEND_JMPZ: