static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
	int i;
	zend_uint catch_op_num;
	int catched = 0;
	zval restored_error_reporting;

	void **stack_frame = (void**)(((char*)EX(Ts)) +
		(ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));

	while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
		zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
		zval_ptr_dtor(&stack_zval_p);
	}

	for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
		if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
			/* further blocks will not be relevant... */
			break;
		}
		if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
			&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
			catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
			catched = 1;
		}
	}

	while (EX(fbc)) {
		EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
		if (EX(object)) {
			if (IS_CTOR_CALL(EX(called_scope))) {
				if (IS_CTOR_USED(EX(called_scope))) {
					Z_DELREF_P(EX(object));
				}
				if (Z_REFCOUNT_P(EX(object)) == 1) {
					zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
				}
			}
			zval_ptr_dtor(&EX(object));
		}
		EX(called_scope) = DECODE_CTOR(EX(called_scope));
		zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
	}

	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
		if (EX(op_array)->brk_cont_array[i].start < 0) {
			continue;
		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
			/* further blocks will not be relevant... */
			break;
		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
			if (!catched ||
			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];

				switch (brk_opline->opcode) {
					case ZEND_SWITCH_FREE:
						if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
							zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);
						}
						break;
					case ZEND_FREE:
						if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
							zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
						}
						break;
				}
			}
		}
	}

	/* restore previous error_reporting value */
	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
		zendi_zval_dtor(restored_error_reporting);
	}
	EX(old_error_reporting) = NULL;

	if (!catched) {
		return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 	} else {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
 		ZEND_VM_CONTINUE();
 	}
}
static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
	int i;
	zend_uint catch_op_num;
	int catched = 0;
	zval restored_error_reporting;

	void **stack_frame = (void**)(((char*)EX(Ts)) +
		(ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));

	while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
		zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
		zval_ptr_dtor(&stack_zval_p);
	}

	for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
		if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
			 
			break;
		}
		if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
			&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
			catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
			catched = 1;
		}
	}

	while (EX(fbc)) {
		EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
		if (EX(object)) {
			if (IS_CTOR_CALL(EX(called_scope))) {
				if (IS_CTOR_USED(EX(called_scope))) {
					Z_DELREF_P(EX(object));
				}
				if (Z_REFCOUNT_P(EX(object)) == 1) {
					zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
				}
			}
			zval_ptr_dtor(&EX(object));
		}
		EX(called_scope) = DECODE_CTOR(EX(called_scope));
		zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
	}

	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
		if (EX(op_array)->brk_cont_array[i].start < 0) {
			continue;
		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
			 
			break;
		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
			if (!catched ||
			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];

				switch (brk_opline->opcode) {
					case ZEND_SWITCH_FREE:
						if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
							zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);
						}
						break;
					case ZEND_FREE:
						if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
							zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
						}
						break;
				}
			}
		}
	}

	 
	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
		zendi_zval_dtor(restored_error_reporting);
	}
	EX(old_error_reporting) = NULL;

	if (!catched) {
		return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 	} else {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
 		ZEND_VM_CONTINUE();
 	}
}