summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.h
diff options
context:
space:
mode:
authorRasmus Lerdorf <rasmus@php.net>2014-10-26 16:58:45 -0700
committerRasmus Lerdorf <rasmus@php.net>2014-10-26 16:58:45 -0700
commit8d84b1f67adb71bdb2394b62faad04b22f6226f3 (patch)
tree0c1c1ed2aaef8eee971575eb5e336631295f4951 /Zend/zend_vm_execute.h
parentfb85d0322d39d49f37e32df6f68c9769f2cce0e4 (diff)
parent09da8952d0434b53e740ffaca66a8051cd39cf93 (diff)
downloadphp-git-8d84b1f67adb71bdb2394b62faad04b22f6226f3.tar.gz
Merge branch 'master' of git.php.net:php-src
* 'master' of git.php.net:php-src: (240 commits) Do not execute anything after quit or clean command Fix last commit, and do not output unnecessary information Stabilize execution, always run destructors and extended file breakpoints Fix nullptr dereference in clean without exec context remove dodgy param parser, bring userland breakpoint api inline with PHP7 disable output buffering by default Add question to reset execution in run/exec/clean - Updated to version 2014.9 (2014i) actually remove this disable output buffering, better breakpoint api for userland, remove hand parsing of params Fix phpdbg output when outputting via php with active output handlers Fixed Closure::call() NEWS/UPGRADING Set engine back to initial state after fatal-ed ev command Fix eventual stack overflow after clean cmd Fix listing of files with no absolute path updated libmagic.patch in master updated libmagic.patch in 5.6 updated libmagic.patch in 5.5 NEWS NEWS ...
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r--Zend/zend_vm_execute.h3299
1 files changed, 1541 insertions, 1758 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 4b58d95618..94466c581b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -538,7 +538,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *p = ZEND_CALL_ARG(call, 1);
for (i = 0; i < call->num_args; ++i) {
- zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -978,7 +978,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} 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, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
CHECK_EXCEPTION();
}
@@ -1003,7 +1003,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
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, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
@@ -1023,57 +1023,6 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval object_zval;
- zend_function *constructor;
-
- SAVE_OPLINE();
- if (UNEXPECTED((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
- if (Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_INTERFACE) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else if ((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else {
- zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- }
- }
- object_init_ex(&object_zval, Z_CE_P(EX_VAR(opline->op1.var)));
- constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
-
- if (constructor == NULL) {
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
- } else {
- zval_ptr_dtor(&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)),
- constructor,
- opline->extended_value,
- Z_CE_P(EX_VAR(opline->op1.var)),
- Z_OBJ(object_zval),
- EX(call) TSRMLS_CC);
-
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
- EX(call)->return_value = EX_VAR(opline->result.var);
- } else {
- EX(call)->return_value = NULL;
- }
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-}
-
static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -1225,7 +1174,7 @@ static int ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
trait = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv),
opline->op2.zv + 1,
- opline->extended_value TSRMLS_CC);
+ ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
if (UNEXPECTED(trait == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1474,7 +1423,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1713,7 +1662,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -1772,7 +1721,7 @@ static int ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
iface = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else {
- iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
if (UNEXPECTED(iface == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1809,7 +1758,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1995,7 +1944,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2181,7 +2130,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2220,7 +2169,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2662,10 +2611,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CONST == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CONST == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -2769,6 +2718,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&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)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3840,9 +3855,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -3931,6 +3943,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4033,7 +4046,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4324,7 +4337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -4855,9 +4868,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -5275,6 +5289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5379,7 +5394,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5898,9 +5913,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -6378,9 +6394,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -6469,6 +6482,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -6573,7 +6587,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7237,9 +7251,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -7442,9 +7457,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -7503,6 +7515,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7981,9 +7994,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -8386,6 +8400,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -8488,7 +8503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -9056,9 +9071,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -9444,10 +9460,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_TMP_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -10154,27 +10170,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10643,9 +10638,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -10734,6 +10726,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -10836,7 +10829,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -11451,6 +11444,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -11497,9 +11529,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -11917,6 +11950,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12021,7 +12055,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12513,9 +12547,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -12993,9 +13028,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -13084,6 +13116,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13188,7 +13221,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13780,6 +13813,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -13826,9 +13898,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14031,9 +14104,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -14092,6 +14162,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14422,9 +14493,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14827,6 +14899,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14929,7 +15002,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -15416,9 +15489,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -15970,10 +16044,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -16243,6 +16317,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&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)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17082,27 +17222,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17472,7 +17591,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -17495,21 +17614,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -17565,15 +17680,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -17581,9 +17700,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -17594,33 +17714,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -17646,31 +17751,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -17826,7 +17917,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17854,21 +17945,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -17920,7 +18007,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17946,19 +18033,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -18107,9 +18190,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -18179,11 +18259,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18205,6 +18282,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18246,6 +18324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18277,6 +18356,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18334,7 +18414,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18358,7 +18438,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18419,7 +18499,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18445,7 +18525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18523,29 +18603,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -18559,7 +18643,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -18902,7 +18985,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -19468,6 +19551,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -19514,9 +19636,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -19901,7 +20024,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -19924,21 +20047,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -19995,15 +20114,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -20011,9 +20134,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -20024,33 +20148,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -20076,30 +20186,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -20256,7 +20353,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20284,21 +20381,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -20351,7 +20444,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20377,19 +20470,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -20460,11 +20549,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20486,6 +20572,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20527,6 +20614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20558,6 +20646,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20616,7 +20705,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20640,7 +20729,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20702,7 +20791,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20728,7 +20817,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20773,29 +20862,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -20809,7 +20902,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -21526,9 +21618,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -21913,7 +22006,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -21936,21 +22029,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -22007,15 +22096,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -22023,9 +22116,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -22036,33 +22130,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -22088,30 +22168,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -22268,7 +22335,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22296,21 +22363,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -22363,7 +22426,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22389,19 +22452,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -22551,9 +22610,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -22623,11 +22679,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22649,6 +22702,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22690,6 +22744,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22721,6 +22776,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22779,7 +22835,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22803,7 +22859,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22865,7 +22921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22891,7 +22947,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22936,29 +22992,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -22972,7 +23032,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -23026,10 +23085,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -23046,15 +23108,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -23853,6 +23914,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -23899,9 +23999,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -24011,7 +24112,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -24034,21 +24135,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -24104,15 +24201,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -24120,9 +24221,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -24133,33 +24235,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -24185,31 +24272,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -24464,9 +24537,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -24521,11 +24591,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24547,6 +24614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -24573,6 +24641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24604,29 +24673,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -24640,7 +24713,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -25104,9 +25176,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -25476,7 +25549,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -25499,21 +25572,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -25569,15 +25638,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -25585,9 +25658,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -25598,33 +25672,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -25650,31 +25709,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -25830,7 +25875,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25858,21 +25903,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -25924,7 +25965,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25950,19 +25991,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -26032,11 +26069,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26058,6 +26092,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26099,6 +26134,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26130,6 +26166,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26187,7 +26224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26211,7 +26248,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26272,7 +26309,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26298,7 +26335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26343,29 +26380,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -26379,7 +26420,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -26432,10 +26472,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -26452,15 +26495,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -27154,9 +27196,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -27346,7 +27389,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -27369,21 +27412,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -27438,15 +27477,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -27454,9 +27497,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -27467,33 +27511,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -27519,31 +27548,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -27699,7 +27714,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27727,21 +27742,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -27793,7 +27804,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27819,19 +27830,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -27921,7 +27928,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -27945,7 +27952,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28006,7 +28013,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28032,7 +28039,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28262,7 +28269,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -28640,9 +28647,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -28736,7 +28744,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -28759,21 +28767,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -28829,15 +28833,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -28845,9 +28853,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -28858,33 +28867,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -28910,30 +28905,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -29090,7 +29072,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29118,21 +29100,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -29185,7 +29163,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29211,19 +29189,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -29315,7 +29289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29339,7 +29313,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29401,7 +29375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29427,7 +29401,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29948,9 +29922,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -30044,7 +30019,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -30067,21 +30042,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -30137,15 +30108,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -30153,9 +30128,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -30166,33 +30142,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -30218,30 +30180,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -30398,7 +30347,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30426,21 +30375,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -30493,7 +30438,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30519,19 +30464,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -30623,7 +30564,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30647,7 +30588,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30709,7 +30650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30735,7 +30676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -31256,9 +31197,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31352,7 +31294,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31375,21 +31317,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31444,15 +31382,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31460,9 +31402,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31473,33 +31416,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -31525,31 +31453,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -31775,9 +31689,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31871,7 +31786,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31894,21 +31809,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31963,15 +31874,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31979,9 +31894,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31992,33 +31908,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -32044,31 +31945,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -32224,7 +32111,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32252,21 +32139,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -32318,7 +32201,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32344,19 +32227,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -32446,7 +32325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32470,7 +32349,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32531,7 +32410,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32557,7 +32436,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -33074,9 +32953,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -33603,10 +33483,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CV == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CV == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -34456,27 +34336,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
-
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -34846,7 +34705,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -34869,21 +34728,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -34938,15 +34793,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -34954,9 +34813,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -34967,33 +34827,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -35019,31 +34864,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -35199,7 +35030,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35227,21 +35058,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -35293,7 +35120,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35319,19 +35146,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -35480,9 +35303,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -35552,11 +35372,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35578,6 +35395,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35619,6 +35437,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35650,6 +35469,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35707,7 +35527,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35731,7 +35551,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35792,7 +35612,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35818,7 +35638,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35896,29 +35716,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -35932,7 +35756,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -36618,6 +36441,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -36664,9 +36526,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -37107,7 +36970,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -37130,21 +36993,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -37200,15 +37059,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -37216,9 +37079,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -37229,33 +37093,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -37281,30 +37131,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -37461,7 +37298,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37489,21 +37326,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -37556,7 +37389,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37582,19 +37415,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -37665,11 +37494,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37691,6 +37517,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37732,6 +37559,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37763,6 +37591,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37821,7 +37650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37845,7 +37674,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37907,7 +37736,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37933,7 +37762,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37978,29 +37807,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -38014,7 +37847,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -38605,9 +38437,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -38991,7 +38824,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -39014,21 +38847,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -39084,15 +38913,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -39100,9 +38933,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -39113,33 +38947,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -39165,30 +38985,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -39345,7 +39152,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39373,21 +39180,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -39440,7 +39243,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39466,19 +39269,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -39628,9 +39427,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -39700,11 +39496,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39726,6 +39519,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39767,6 +39561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39798,6 +39593,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39856,7 +39652,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39880,7 +39676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39942,7 +39738,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39968,7 +39764,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -40013,29 +39809,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -40049,7 +39849,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -40103,10 +39902,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -40123,15 +39925,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -40802,6 +40603,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -40848,9 +40688,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -40959,7 +40800,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -40982,21 +40823,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -41051,15 +40888,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -41067,9 +40908,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -41080,33 +40922,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -41132,31 +40959,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -41411,9 +41224,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -41468,11 +41278,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41494,6 +41301,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -41520,6 +41328,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41551,29 +41360,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -41587,7 +41400,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -41908,9 +41720,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -42279,7 +42092,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -42302,21 +42115,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -42371,15 +42180,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -42387,9 +42200,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -42400,33 +42214,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -42452,31 +42251,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -42632,7 +42417,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42660,21 +42445,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -42726,7 +42507,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42752,19 +42533,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -42834,11 +42611,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42860,6 +42634,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42901,6 +42676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42932,6 +42708,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42989,7 +42766,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43013,7 +42790,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43074,7 +42851,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43100,7 +42877,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43145,29 +42922,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -43181,7 +42962,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -43234,10 +43014,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -43254,15 +43037,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -43829,9 +43611,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -45643,31 +45426,31 @@ void zend_init_opcodes_handlers(void)
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@@ -47398,26 +47181,26 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,