summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_def.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_def.h')
-rw-r--r--Zend/zend_vm_def.h341
1 files changed, 171 insertions, 170 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index b6d2b82cde..b64eb6b3cb 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -385,7 +385,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
if (Z_REFCOUNT_P(z) == 0) {
- zval_dtor(z);
+ zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC);
}
ZVAL_COPY_VALUE(z, value);
}
@@ -711,7 +711,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
if (Z_REFCOUNT_P(z) == 0) {
- zval_dtor(z);
+ zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC);
}
ZVAL_COPY_VALUE(z, value);
}
@@ -798,7 +798,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
if (Z_REFCOUNT_P(z) == 0) {
- zval_dtor(z);
+ zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC);
}
ZVAL_COPY_VALUE(z, value);
}
@@ -1199,7 +1199,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1222,7 +1222,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1263,7 +1263,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNU
}
ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP2();
@@ -1296,7 +1296,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1326,7 +1326,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
/* here we are sure we are dealing with an object */
do {
if (OP2_TYPE == IS_CONST &&
- EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+ EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
zend_object *zobj = Z_OBJ_P(container);
@@ -1376,7 +1376,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1400,7 +1400,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1415,8 +1415,6 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
zval *container;
zend_free_op free_op2;
zval *offset;
- zval *retval;
- zend_property_info *prop_info;
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
@@ -1431,7 +1429,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
/* here we are sure we are dealing with an object */
do {
if (OP2_TYPE == IS_CONST &&
- EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+ EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
zend_object *zobj = Z_OBJ_P(container);
@@ -1486,7 +1484,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1512,7 +1510,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
+ if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
}
FREE_OP1_VAR_PTR();
@@ -1738,9 +1736,9 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
{
- vm_frame_kind frame_kind = VM_FRAME_KIND(EX(frame_info));
+ zend_call_kind call_kind = EX_CALL_KIND();
- if (frame_kind == VM_FRAME_NESTED_FUNCTION) {
+ if (call_kind == ZEND_CALL_NESTED_FUNCTION) {
zend_object *object;
i_free_compiled_variables(execute_data TSRMLS_CC);
@@ -1768,7 +1766,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
}
OBJ_RELEASE(object);
}
- EG(scope) = EX(scope);
+ EG(scope) = EX(func)->op_array.scope;
if (UNEXPECTED(EG(exception) != NULL)) {
const zend_op *opline = EX(opline);
@@ -1782,7 +1780,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
LOAD_OPLINE();
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
- } else if (frame_kind == VM_FRAME_NESTED_CODE) {
+ } else if (call_kind == ZEND_CALL_NESTED_CODE) {
zend_detach_symbol_table(execute_data);
destroy_op_array(&EX(func)->op_array TSRMLS_CC);
efree_size(EX(func), sizeof(zend_op_array));
@@ -1800,7 +1798,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
} else {
- if (frame_kind == VM_FRAME_TOP_FUNCTION) {
+ if (call_kind == ZEND_CALL_TOP_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
@@ -1810,7 +1808,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
}
- } else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
+ } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
zend_array *symbol_table = EX(symbol_table);
zend_execute_data *old_execute_data;
@@ -2070,7 +2068,9 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
}
if (Z_TYPE_P(var) != IS_STRING) {
- ZVAL_DEREF(var);
+ if (OP2_TYPE != IS_TMP_VAR) {
+ ZVAL_DEREF(var);
+ }
if (Z_TYPE_P(var) != IS_STRING) {
use_copy = zend_make_printable_zval(var, &var_copy TSRMLS_CC);
@@ -2082,7 +2082,7 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
add_string_to_string(str, str, var);
if (use_copy) {
- zval_dtor(var);
+ zend_string_release(Z_STR_P(var));
}
/* original comment, possibly problematic:
* FREE_OP is missing intentionally here - we're always working on the same temporary variable
@@ -2235,7 +2235,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
GC_REFCOUNT(obj)++; /* For $this pointer */
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC);
FREE_OP2();
@@ -2358,7 +2358,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
}
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, ce, object, EX(call) TSRMLS_CC);
if (OP2_TYPE == IS_UNUSED) {
@@ -2387,7 +2387,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
@@ -2397,12 +2397,10 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
zend_free_op free_op2;
zend_class_entry *called_scope;
zend_object *object;
- zval *function_name_ptr;
SAVE_OPLINE();
- function_name_ptr = function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ function_name = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
- ZVAL_DEREF(function_name);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
if (Z_STRVAL_P(function_name)[0] == '\\') {
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
@@ -2427,10 +2425,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
if (object) {
GC_REFCOUNT(object)++;
}
- if (OP2_TYPE == IS_VAR && OP2_FREE && Z_REFCOUNT_P(function_name) == 1 &&
- fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
/* Delay closure destruction until its invocation */
- fbc->common.prototype = (zend_function*)Z_OBJ_P(function_name_ptr);
+ fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
} else if (OP2_TYPE == IS_CV) {
FREE_OP2();
}
@@ -2507,7 +2504,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
zend_error_noreturn(E_ERROR, "Function name must be a string");
ZEND_VM_CONTINUE(); /* Never reached */
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -2561,7 +2558,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMP|VAR|CV)
object = NULL;
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
func, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC);
FREE_OP2();
@@ -2593,7 +2590,7 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
ZEND_VM_NEXT_OPCODE();
@@ -2617,7 +2614,7 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
}
- EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION,
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
FREE_OP2();
@@ -2676,8 +2673,8 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
uint32_t i;
zval *p = ZEND_CALL_ARG(call, 1);
- for (i = 0; i < call->num_args; ++i) {
- zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
+ for (i = 0; i < ZEND_CALL_NUM_ARGS(call); ++i) {
+ zend_verify_arg_type(fbc, i + 1, p, NULL TSRMLS_CC);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -2719,7 +2716,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
ZEND_VM_C_GOTO(fcall_end);
}
} else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
- call->scope = EG(scope) = fbc->common.scope;
+ EG(scope) = fbc->common.scope;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
if (RETURN_VALUE_USED(opline)) {
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
@@ -2745,9 +2742,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
- call->frame_info = VM_FRAME_INFO(
- VM_FRAME_TOP_FUNCTION,
- VM_FRAME_FLAGS(call->frame_info));
+ ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
zend_execute_ex(call TSRMLS_CC);
}
}
@@ -2796,7 +2791,7 @@ ZEND_VM_C_LABEL(fcall_end_change_scope):
}
OBJ_RELEASE(object);
}
- EG(scope) = EX(scope);
+ EG(scope) = EX(func)->op_array.scope;
ZEND_VM_C_LABEL(fcall_end):
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -2982,9 +2977,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
}
exception = EG(exception);
- if (Z_REFCOUNTED_P(EX_VAR(opline->op2.var))) {
- zval_ptr_dtor(EX_VAR(opline->op2.var));
- }
+ zval_ptr_dtor(EX_VAR(opline->op2.var));
ZVAL_OBJ(EX_VAR(opline->op2.var), EG(exception));
if (UNEXPECTED(EG(exception) != exception)) {
GC_REFCOUNT(EG(exception))++;
@@ -3004,7 +2997,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
ZVAL_COPY_VALUE(arg, value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
@@ -3026,7 +3019,7 @@ ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY)
}
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
ZVAL_COPY_VALUE(arg, value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
@@ -3044,7 +3037,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
@@ -3064,11 +3057,8 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
zval *varptr, *arg;
SAVE_OPLINE();
- if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
- if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
- ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
- }
- } else {
+
+ if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) {
if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR);
}
@@ -3083,20 +3073,18 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
if (OP1_TYPE == IS_CV) {
Z_ADDREF_P(varptr);
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY_VALUE(arg, varptr);
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
- arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
- ZVAL_COPY(arg, varptr);
- FREE_OP1_IF_VAR();
}
+
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -3115,7 +3103,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
}
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
ZEND_VM_NEXT_OPCODE();
@@ -3126,12 +3114,11 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
ZVAL_COPY_VALUE(arg, varptr);
} else if (OP1_TYPE == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
- ZVAL_COPY_VALUE(arg, varptr);
- ZVAL_MAKE_REF(arg);
+ ZVAL_NEW_REF(arg, varptr);
} else {
- ZVAL_MAKE_REF(varptr);
- Z_ADDREF_P(varptr);
- ZVAL_REF(arg, Z_REF_P(varptr));
+ ZVAL_NEW_REF(arg, varptr);
+ Z_ADDREF_P(arg);
+ ZVAL_REF(varptr, Z_REF_P(arg));
}
FREE_OP1_VAR_PTR();
@@ -3149,7 +3136,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)
}
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
@@ -3171,7 +3158,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
SAVE_OPLINE();
args = GET_OP1_ZVAL_PTR(BP_VAR_R);
- arg_num = EX(call)->num_args + 1;
+ arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
ZEND_VM_C_LABEL(send_again):
switch (Z_TYPE_P(args)) {
@@ -3222,7 +3209,7 @@ ZEND_VM_C_LABEL(send_again):
ZVAL_COPY(top, arg);
}
- EX(call)->num_args++;
+ ZEND_CALL_NUM_ARGS(EX(call))++;
arg_num++;
} ZEND_HASH_FOREACH_END();
@@ -3277,7 +3264,7 @@ ZEND_VM_C_LABEL(send_again):
if (Z_TYPE(key) == IS_STRING) {
zend_error(E_RECOVERABLE_ERROR,
"Cannot unpack Traversable with string keys");
- zval_dtor(&key);
+ zend_string_release(Z_STR(key));
ZEND_VM_C_GOTO(unpack_iter_dtor);
}
@@ -3303,7 +3290,7 @@ ZEND_VM_C_LABEL(send_again):
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1 TSRMLS_CC);
top = ZEND_CALL_ARG(EX(call), arg_num);
ZVAL_COPY_VALUE(top, arg);
- EX(call)->num_args++;
+ ZEND_CALL_NUM_ARGS(EX(call))++;
iter->funcs->move_forward(iter TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -3435,7 +3422,7 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY)
} else {
ZVAL_COPY(param, arg);
}
- EX(call)->num_args++;
+ ZEND_CALL_NUM_ARGS(EX(call))++;
arg_num++;
param++;
} ZEND_HASH_FOREACH_END();
@@ -3517,7 +3504,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY)
ZVAL_COPY(param, arg);
}
- EX(call)->num_args = opline->op2.num;
+ ZEND_CALL_NUM_ARGS(EX(call)) = opline->op2.num;
FREE_OP1();
CHECK_EXCEPTION();
@@ -3530,13 +3517,13 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
uint32_t arg_num = opline->op1.num;
SAVE_OPLINE();
- if (UNEXPECTED(arg_num > EX(num_args))) {
+ if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
CHECK_EXCEPTION();
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
CHECK_EXCEPTION();
}
@@ -3551,7 +3538,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
SAVE_OPLINE();
param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- if (arg_num > EX(num_args)) {
+ if (arg_num > EX_NUM_ARGS()) {
ZVAL_COPY_VALUE(param, opline->op2.zv);
if (Z_OPT_CONSTANT_P(param)) {
zval_update_constant(param, 0 TSRMLS_CC);
@@ -3564,7 +3551,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param, opline->op2.zv TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -3575,7 +3562,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
{
USE_OPLINE
uint32_t arg_num = opline->op1.num;
- uint32_t arg_count = EX(num_args);
+ uint32_t arg_count = EX_NUM_ARGS();
zval *params;
SAVE_OPLINE();
@@ -3589,7 +3576,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
@@ -3720,16 +3707,14 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY)
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
} else {
- zval_ptr_dtor(&object_zval);
+ OBJ_RELEASE(Z_OBJ(object_zval));
}
ZEND_VM_JMP(opline->op2.jmp_addr);
} else {
/* We are not handling overloaded classes right now */
EX(call) = zend_vm_stack_push_call_frame(
- VM_FRAME_INFO(
- VM_FRAME_NESTED_FUNCTION,
- RETURN_VALUE_USED(opline) ?
- ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
+ ZEND_CALL_FUNCTION | ZEND_CALL_CTOR |
+ (RETURN_VALUE_USED(opline) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED),
constructor,
opline->extended_value,
ce,
@@ -3783,14 +3768,14 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- if (UNEXPECTED(ce != EX(scope))) {
- zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
+ if (UNEXPECTED(ce != EG(scope))) {
+ zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
}
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EX(scope)))) {
- zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EX(scope) ? EX(scope)->name->val : "");
+ if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
+ zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name->val, EG(scope) ? EG(scope)->name->val : "");
}
}
}
@@ -3798,7 +3783,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC));
if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
}
FREE_OP1_IF_VAR();
@@ -3884,7 +3869,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
if (Z_CONSTANT_P(value)) {
EG(scope) = ce;
zval_update_constant(value, 1 TSRMLS_CC);
- EG(scope) = EX(scope);
+ EG(scope) = EX(func)->op_array.scope;
}
if (OP1_TYPE == IS_CONST) {
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), value);
@@ -4205,7 +4190,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
}
}
if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) {
- zval_ptr_dtor(&tmp_inc_filename);
+ zend_string_release(Z_STR(tmp_inc_filename));
}
FREE_OP1();
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -4218,7 +4203,9 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
return_value = EX_VAR(opline->result.var);
}
- call = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_CODE,
+ new_op_array->scope = EG(scope); /* ??? */
+
+ call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE,
(zend_function*)new_op_array, 0, EX(called_scope), Z_OBJ(EX(This)), NULL TSRMLS_CC);
if (EX(symbol_table)) {
@@ -4232,7 +4219,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
- call->frame_info = VM_FRAME_TOP_CODE;
+ ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
zend_execute_ex(call TSRMLS_CC);
}
@@ -4296,8 +4283,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
} else {
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
- if (OP1_TYPE != IS_CONST) {
- zval_dtor(&tmp);
+ if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
+ zend_string_release(Z_STR(tmp));
}
FREE_OP1();
HANDLE_EXCEPTION();
@@ -4316,8 +4303,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
- if (OP1_TYPE != IS_CONST) {
- zval_dtor(&tmp);
+ if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
+ zend_string_release(Z_STR(tmp));
}
FREE_OP1();
CHECK_EXCEPTION();
@@ -4339,8 +4326,8 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
}
if (OP1_TYPE != IS_UNUSED) {
ZVAL_DEREF(container);
- SEPARATE_ZVAL_NOREF(container);
}
+ SEPARATE_ZVAL_NOREF(container);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -4423,7 +4410,9 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
}
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- ZVAL_DEREF(container);
+ if (OP1_TYPE != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
if (Z_OBJ_HT_P(container)->unset_property) {
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
@@ -4900,6 +4889,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
zend_free_op free_op1;
zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
+ ZVAL_UNDEF(&tmp);
if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_STR(&tmp, zval_get_string(varname));
varname = &tmp;
@@ -4928,8 +4918,8 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
}
- if (OP1_TYPE != IS_CONST && varname == &tmp) {
- zval_dtor(&tmp);
+ if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
+ zend_string_release(Z_STR(tmp));
}
FREE_OP1();
@@ -5028,7 +5018,7 @@ ZEND_VM_C_LABEL(num_index_prop):
result = 0;
if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
- if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
+ if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
@@ -5122,10 +5112,6 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
SAVE_OPLINE();
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
- if (EX(silence_op_num) == -1) {
- EX(silence_op_num) = opline->op2.num;
- EX(old_error_reporting) = EG(error_reporting);
- }
if (EG(error_reporting)) {
do {
@@ -5163,9 +5149,6 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
}
- if (EX(silence_op_num) == opline->op2.num) {
- EX(silence_op_num) = -1;
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -5485,6 +5468,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
}
if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
+ finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
}
if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
@@ -5500,8 +5484,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
zend_vm_stack_free_args(EX(call) TSRMLS_CC);
if (Z_OBJ(call->This)) {
- if (call->frame_info & ZEND_CALL_CTOR) {
- if (!(call->frame_info & ZEND_CALL_CTOR_RESULT_UNUSED)) {
+ if (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR) {
+ if (!(ZEND_CALL_INFO(call) & ZEND_CALL_CTOR_RESULT_UNUSED)) {
GC_REFCOUNT(Z_OBJ(call->This))--;
}
if (GC_REFCOUNT(Z_OBJ(call->This)) == 1) {
@@ -5531,40 +5515,47 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
+ } else if (brk_opline->opcode == ZEND_END_SILENCE) {
+ /* restore previous error_reporting value */
+ if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
+ EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var));
+ }
}
}
}
}
- /* restore previous error_reporting value */
- if (!EG(error_reporting) && EX(silence_op_num) != -1 && EX(old_error_reporting) != 0) {
- EG(error_reporting) = EX(old_error_reporting);
- }
- EX(silence_op_num) = -1;
-
if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
- if (EX(delayed_exception)) {
- zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
+ zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+ if (Z_OBJ_P(fast_call)) {
+ zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
}
- EX(delayed_exception) = EG(exception);
+ Z_OBJ_P(fast_call) = EG(exception);
EG(exception) = NULL;
- EX(fast_ret) = NULL;
+ fast_call->u2.lineno = (uint32_t)-1;
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else if (catch_op_num) {
if (finally_op_end && catch_op_num > finally_op_end) {
/* we are going out of current finally scope */
- if (EX(delayed_exception)) {
- zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
- EX(delayed_exception) = NULL;
+ zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+ if (Z_OBJ_P(fast_call)) {
+ zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+ Z_OBJ_P(fast_call) = NULL;
}
}
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
ZEND_VM_CONTINUE();
} else {
- if (EX(delayed_exception)) {
- zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
- EX(delayed_exception) = NULL;
+ if (finally_op_end) {
+ zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+ if (Z_OBJ_P(fast_call)) {
+ zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+ Z_OBJ_P(fast_call) = NULL;
+ }
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
@@ -5665,7 +5656,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
if (closure_is_static || closure_is_being_defined_inside_static_context) {
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL TSRMLS_CC);
} else {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -5824,10 +5815,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
{
- if (EX(delayed_exception) != NULL) {
+ USE_OPLINE
+ zval *fast_call = EX_VAR(opline->op1.var);
+
+ /* check for delayed exception */
+ if (Z_OBJ_P(fast_call) != NULL) {
/* discard the previously thrown exception */
- OBJ_RELEASE(EX(delayed_exception));
- EX(delayed_exception) = NULL;
+ OBJ_RELEASE(Z_OBJ_P(fast_call));
+ Z_OBJ_P(fast_call) = NULL;
}
ZEND_VM_NEXT_OPCODE();
@@ -5836,6 +5831,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
{
USE_OPLINE
+ zval *fast_call = EX_VAR(opline->result.var);
if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
UNEXPECTED(EG(prev_exception) != NULL)) {
@@ -5843,18 +5839,24 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
}
- EX(fast_ret) = opline;
- EX(delayed_exception) = NULL;
+ /* set no delayed exception */
+ Z_OBJ_P(fast_call) = NULL;
+ /* set return address */
+ fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
ZEND_VM_CONTINUE();
}
ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
{
- if (EX(fast_ret)) {
- ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
- if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
- EX(fast_ret) = &EX(func)->op_array.opcodes[EX(fast_ret)->op2.opline_num];
+ USE_OPLINE
+ zval *fast_call = EX_VAR(opline->op1.var);
+
+ if (fast_call->u2.lineno != (uint32_t)-1) {
+ 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;
}
ZEND_VM_CONTINUE();
} else {
@@ -5865,8 +5867,8 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
} else {
- EG(exception) = EX(delayed_exception);
- EX(delayed_exception) = NULL;
+ EG(exception) = Z_OBJ_P(fast_call);
+ Z_OBJ_P(fast_call) = NULL;
if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
@@ -5906,23 +5908,39 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
zval *varname;
zval *value;
zval *variable_ptr;
- Bucket *p;
uint32_t idx;
SAVE_OPLINE();
varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
- idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname));
- /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */
- p = EG(symbol_table).ht.arData + idx;
- if (EXPECTED(idx > 0) &&
- EXPECTED(idx < EG(symbol_table).ht.nNumUsed) &&
- EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
- (EXPECTED(p->key == Z_STR_P(varname)) ||
- (EXPECTED(p->h == Z_STR_P(varname)->h) &&
- EXPECTED(p->key != NULL) &&
- EXPECTED(p->key->len == Z_STRLEN_P(varname)) &&
- EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
- value = &EG(symbol_table).ht.arData[idx].val;
+
+ /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+ idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1;
+ if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) {
+ Bucket *p = EG(symbol_table).ht.arData + idx;
+
+ if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+ (EXPECTED(p->key == Z_STR_P(varname)) ||
+ (EXPECTED(p->h == Z_STR_P(varname)->h) &&
+ EXPECTED(p->key != NULL) &&
+ EXPECTED(p->key->len == Z_STRLEN_P(varname)) &&
+ EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
+
+ value = &EG(symbol_table).ht.arData[idx].val;
+ ZEND_VM_C_GOTO(check_indirect);
+ }
+ }
+
+ value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname));
+ if (UNEXPECTED(value == NULL)) {
+ value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval));
+ idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+ /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+ CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
+ } else {
+ idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+ /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+ CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
+ZEND_VM_C_LABEL(check_indirect):
/* GLOBAL variable may be an INDIRECT pointer to CV */
if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
@@ -5930,23 +5948,6 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
ZVAL_NULL(value);
}
}
- } else {
- value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname));
- if (UNEXPECTED(value == NULL)) {
- value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval));
- idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
- CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx);
- } else {
- idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
- CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx);
- /* GLOBAL variable may be an INDIRECT pointer to CV */
- if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
- value = Z_INDIRECT_P(value);
- if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
- ZVAL_NULL(value);
- }
- }
- }
}
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);