summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r--Zend/zend_vm_execute.h9364
1 files changed, 6884 insertions, 2480 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index fba5f9cc6f..4d2b6f266c 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -20,6 +20,13 @@
#ifdef ZEND_WIN32
# pragma warning(once : 4101)
+# pragma warning(once : 6235)
+# pragma warning(once : 6237)
+# pragma warning(once : 6239)
+# pragma warning(once : 6240)
+# pragma warning(once : 6285)
+# pragma warning(once : 6286)
+# pragma warning(once : 6326)
#endif
static user_opcode_handler_t zend_user_opcode_handlers[256] = {
(user_opcode_handler_t)NULL,
@@ -326,79 +333,25 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
-#undef EX
-#define EX(element) execute_data->element
-#undef EX_CV
-#define EX_CV(var) EX(CVs)[var]
-#undef EX_CVs
-#define EX_CVs() EX(CVs)
-#undef EX_T
-#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
-#undef EX_Ts
-#define EX_Ts() EX(Ts)
-
-
-ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
{
DCL_OPLINE
- zend_execute_data *execute_data;
- zend_bool nested = 0;
- zend_bool original_in_execution = EG(in_execution);
+ zend_bool original_in_execution;
- if (EG(exception)) {
- return;
- }
+ original_in_execution = EG(in_execution);
EG(in_execution) = 1;
+ if (0) {
zend_vm_enter:
- /* Initialize execute_data */
- execute_data = (zend_execute_data *)zend_vm_stack_alloc(
- ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
-
- EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
- EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
- EX(fbc) = NULL;
- EX(called_scope) = NULL;
- EX(object) = NULL;
- EX(old_error_reporting) = NULL;
- EX(op_array) = op_array;
- EX(symbol_table) = EG(active_symbol_table);
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = execute_data;
- EX(nested) = nested;
- nested = 1;
-
- LOAD_REGS();
-
- if (!op_array->run_time_cache && op_array->last_cache_slot) {
- op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ execute_data = i_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
}
- if (op_array->this_var != -1 && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (!EG(active_symbol_table)) {
- EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
- *EX_CV(op_array->this_var) = EG(This);
- } else {
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
- }
-
- EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
- EG(opline_ptr) = &EX(opline);
+ LOAD_REGS();
LOAD_OPLINE();
- EX(function_state).function = (zend_function *) op_array;
- EX(function_state).arguments = NULL;
-
while (1) {
int ret;
#ifdef ZEND_WIN32
@@ -413,10 +366,11 @@ zend_vm_enter:
EG(in_execution) = original_in_execution;
return;
case 2:
- op_array = EG(active_op_array);
goto zend_vm_enter;
+ break;
case 3:
execute_data = EG(current_execute_data);
+ break;
default:
break;
}
@@ -426,59 +380,31 @@ zend_vm_enter:
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
-static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC)
{
- USE_OPLINE
-
-#if DEBUG_ZEND>=2
- printf("Jumping to %d\n", opline->op1.opline_num);
-#endif
- ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
- ZEND_VM_CONTINUE(); /* CHECK_ME */
-}
-
-static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval *tmp = &EX_T(opline->result.var).tmp_var;
-
- SAVE_OPLINE();
- tmp->value.str.val = emalloc(1);
- tmp->value.str.val[0] = 0;
- tmp->value.str.len = 0;
- Z_SET_REFCOUNT_P(tmp, 1);
- tmp->type = IS_STRING;
- Z_UNSET_ISREF_P(tmp);
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
+ if (EG(exception)) {
+ return;
+ }
+ zend_execute_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);
}
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
- zend_bool nested;
+ zend_bool nested = EX(nested);
zend_op_array *op_array = EX(op_array);
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
- zval ***cv = EX_CVs();
- zval ***end = cv + op_array->last_var;
- while (cv != end) {
- if (*cv) {
- zval_ptr_dtor(*cv);
- }
- cv++;
- }
+ i_free_compiled_variables(execute_data);
}
+ zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC);
+
if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
zval_ptr_dtor((zval**)&op_array->prototype);
}
- nested = EX(nested);
-
- zend_vm_stack_free(execute_data TSRMLS_CC);
-
if (nested) {
execute_data = EG(current_execute_data);
}
@@ -491,7 +417,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EX(function_state).function = (zend_function *) EX(op_array);
EX(function_state).arguments = NULL;
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -501,34 +426,16 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
} else {
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
@@ -536,8 +443,8 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EX(function_state).arguments = NULL;
if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
Z_DELREF_P(EG(This));
}
if (Z_REFCOUNT_P(EG(This)) == 1) {
@@ -550,10 +457,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EG(scope) = EX(current_scope);
EG(called_scope) = EX(current_called_scope);
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
+ EX(call)--;
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -577,6 +483,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
zend_function *fbc = EX(function_state).function;
SAVE_OPLINE();
+ EX(object) = EX(call)->object;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
@@ -611,16 +518,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EX(current_called_scope) = EG(called_scope);
EG(This) = EX(object);
EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
- EG(called_scope) = EX(called_scope);
+ EG(called_scope) = EX(call)->called_scope;
}
- zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
- EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
+ EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
+ zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC);
LOAD_OPLINE();
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
- temp_variable *ret = &EX_T(opline->result.var);
-
if (fbc->common.arg_info) {
zend_uint i=0;
zval **p = (zval**)EX(function_state).arguments;
@@ -633,6 +538,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
if (EXPECTED(EG(exception) == NULL)) {
+ temp_variable *ret = &EX_T(opline->result.var);
+
MAKE_STD_ZVAL(ret->var.ptr);
ZVAL_NULL(ret->var.ptr);
ret->var.ptr_ptr = &ret->var.ptr;
@@ -642,7 +549,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
/* saves one function call if zend_execute_internal is not used */
fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
- zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
+ zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC);
}
if (!RETURN_VALUE_USED(opline)) {
@@ -665,7 +572,11 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
}
- if (EXPECTED(zend_execute == execute)) {
+ if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (RETURN_VALUE_USED(opline)) {
+ EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+ }
+ } else if (EXPECTED(zend_execute_ex == execute_ex)) {
if (EXPECTED(EG(exception) == NULL)) {
ZEND_VM_ENTER();
}
@@ -677,22 +588,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
ZVAL_NULL(EX_T(opline->result.var).var.ptr);
- /* Not sure what should be done here if it's a static method */
+ /* Not sure what should be done here if it's a static method */
if (EXPECTED(EX(object) != NULL)) {
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
@@ -719,8 +622,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
if (should_change_scope) {
if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
Z_DELREF_P(EG(This));
}
if (Z_REFCOUNT_P(EG(This)) == 1) {
@@ -734,10 +637,9 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EG(called_scope) = EX(current_called_scope);
}
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
+ EX(call)--;
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -750,12 +652,51 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+#if DEBUG_ZEND>=2
+ printf("Jumping to %d\n", opline->op1.opline_num);
+#endif
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *tmp = &EX_T(opline->result.var).tmp_var;
+
+ SAVE_OPLINE();
+ tmp->value.str.val = emalloc(1);
+ tmp->value.str.val[0] = 0;
+ tmp->value.str.len = 0;
+ Z_SET_REFCOUNT_P(tmp, 1);
+ tmp->type = IS_STRING;
+ Z_UNSET_ISREF_P(tmp);
+ /*CHECK_EXCEPTION();*/
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- EX(function_state).function = EX(fbc);
+ EX(function_state).function = EX(call)->fbc;
return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ /* Close the generator to free up resources */
+ zend_generator_close(generator, 1 TSRMLS_CC);
+
+ /* Pass execution back to handling code */
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -787,7 +728,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
Z_DELREF_PP(var_ptr);
*var_ptr = *param;
Z_ADDREF_PP(var_ptr);
@@ -827,17 +768,20 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num);
} else {
+ call_slot *call = EX(call_slots) + opline->extended_value;
+
if (RETURN_VALUE_USED(opline)) {
PZVAL_LOCK(object_zval);
AI_SET_PTR(&EX_T(opline->result.var), object_zval);
}
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
-
/* We are not handling overloaded classes right now */
- EX(object) = object_zval;
- EX(fbc) = constructor;
- EX(called_scope) = EX_T(opline->op1.var).class_entry;
+ call->fbc = constructor;
+ call->object = object_zval;
+ call->called_scope = EX_T(opline->op1.var).class_entry;
+ call->is_ctor_call = 1;
+ call->is_ctor_result_used = RETURN_VALUE_USED(opline);
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1037,13 +981,15 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
{
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
int i;
- zend_uint catch_op_num = 0;
- int catched = 0;
- zval restored_error_reporting;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+ void **stack_frame;
- void **stack_frame = (void**)(((char*)EX_Ts()) +
- (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
+ /* Figure out where the next stack frame (which maybe contains pushed
+ * arguments that have to be dtor'ed) starts */
+ stack_frame = zend_vm_stack_frame_base(execute_data);
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
zval_ptr_dtor(&stack_zval_p);
@@ -1053,27 +999,32 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
/* further blocks will not be relevant... */
break;
- } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
- catched = 1;
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
}
}
- while (EX(fbc)) {
- EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
- if (EX(object)) {
- if (IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
- Z_DELREF_P(EX(object));
- }
- if (Z_REFCOUNT_P(EX(object)) == 1) {
- zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
+ if (EX(call) >= EX(call_slots)) {
+ call_slot *call = EX(call);
+ do {
+ if (call->object) {
+ if (call->is_ctor_call) {
+ if (call->is_ctor_result_used) {
+ Z_DELREF_P(call->object);
+ }
+ if (Z_REFCOUNT_P(call->object) == 1) {
+ zend_object_store_ctor_failed(call->object TSRMLS_CC);
+ }
}
+ zval_ptr_dtor(&call->object);
}
- zval_ptr_dtor(&EX(object));
- }
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
- zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
+ call--;
+ } while (call >= EX(call_slots));
+ EX(call) = NULL;
}
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
@@ -1083,7 +1034,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
/* further blocks will not be relevant... */
break;
} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
- if (!catched ||
+ if (!catch_op_num ||
catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
@@ -1105,6 +1056,8 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
/* restore previous error_reporting value */
if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
+ zval restored_error_reporting;
+
Z_TYPE(restored_error_reporting) = IS_LONG;
Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
convert_to_string(&restored_error_reporting);
@@ -1113,12 +1066,21 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
}
EX(old_error_reporting) = NULL;
- if (!catched) {
- return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
+ if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
+ zend_exception_save(TSRMLS_C);
+ EX(fast_ret) = NULL;
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ ZEND_VM_CONTINUE();
+ } else if (catch_op_num) {
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
+ ZEND_VM_CONTINUE();
+ } else {
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
}
static int ZEND_FASTCALL ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1144,7 +1106,11 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
- return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
case ZEND_USER_OPCODE_ENTER:
ZEND_VM_ENTER();
case ZEND_USER_OPCODE_LEAVE:
@@ -1156,12 +1122,69 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
}
}
+static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ if (EG(prev_exception) != NULL) {
+ /* discard the previously thrown exception */
+ zval_ptr_dtor(&EG(prev_exception));
+ EG(prev_exception) = NULL;
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
+ UNEXPECTED(EG(prev_exception) != NULL)) {
+ /* in case of unhandled exception jump to catch block instead of finally */
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ }
+ EX(fast_ret) = opline;
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ if (EX(fast_ret)) {
+ ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
+ if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
+ EX(fast_ret) = &EX(op_array)->opcodes[EX(fast_ret)->op2.opline_num];
+ }
+ ZEND_VM_CONTINUE();
+ } else {
+ /* special case for unhandled exceptions */
+ USE_OPLINE
+
+ if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
+ zend_exception_restore(TSRMLS_C);
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ zend_exception_restore(TSRMLS_C);
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ zend_exception_restore(TSRMLS_C);
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
+}
+
static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_CONST == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
@@ -1182,6 +1205,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1194,19 +1220,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CONST == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1226,28 +1255,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_CONST == IS_VAR && 0 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST &&
@@ -1274,52 +1308,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1329,25 +1367,27 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC
{
USE_OPLINE
zend_literal *func_name;
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
func_name = opline->op2.literal + 1;
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE) {
func_name++;
- if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
+ if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
ZEND_VM_NEXT_OPCODE();
}
@@ -1377,7 +1417,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
}
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
zval_ptr_dtor(var_ptr);
*var_ptr = assignment_value;
@@ -1392,7 +1432,7 @@ static int ZEND_FASTCALL ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}
@@ -1403,7 +1443,7 @@ static int ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
@@ -1415,7 +1455,7 @@ static int ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
brk_opline = EX(op_array)->opcodes + el->brk;
@@ -1466,14 +1506,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_TMP_VAR == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_op2;
- zval *class_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1487,6 +1529,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1500,19 +1545,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_TMP_VAR == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1521,7 +1569,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
zend_free_op free_op2;
SAVE_OPLINE();
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1532,28 +1580,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
zval_dtor(free_op2.var);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_TMP_VAR == IS_VAR && 1 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
zval_dtor(free_op2.var);
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST &&
@@ -1580,52 +1633,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1636,14 +1693,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_VAR == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_op2;
- zval *class_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1657,6 +1716,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1670,19 +1732,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_VAR == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1691,7 +1756,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
zend_free_op free_op2;
SAVE_OPLINE();
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1702,28 +1767,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_VAR == IS_VAR && (free_op2.var != NULL) &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST &&
@@ -1750,52 +1820,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1806,7 +1880,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_UNUSED == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
@@ -1827,6 +1903,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1840,14 +1919,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_CV == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
- zval *class_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1861,6 +1942,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1873,19 +1957,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CV == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1894,7 +1981,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1905,28 +1992,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_CV == IS_VAR && 0 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST &&
@@ -1953,52 +2045,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -2217,8 +2313,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
USE_OPLINE
zval *fname = opline->op1.zv;
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->op2.num;
if (CACHED_PTR(opline->op1.literal->cache_slot)) {
EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
@@ -2228,7 +2323,11 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
} else {
CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function);
}
- EX(object) = NULL;
+ call->fbc = EX(function_state).function;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -2246,14 +2345,17 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_CONST == IS_TMP_VAR) {
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_CONST == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_CONST == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_CONST != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -2265,12 +2367,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -2357,8 +2453,12 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
value = opline->op1.zv;
if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -2379,7 +2479,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
}
{
@@ -2429,6 +2529,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_CONST == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -2543,7 +2646,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
zend_op_array *new_op_array=NULL;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
@@ -2635,8 +2738,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -2644,14 +2745,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -2661,15 +2761,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -2802,7 +2893,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -3378,7 +3469,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -3391,6 +3482,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN
return zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3420,9 +3530,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -3438,24 +3548,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_CONST == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -3469,6 +3579,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
function_name = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -3478,20 +3591,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -3505,29 +3618,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -3635,6 +3750,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -3947,6 +4065,163 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3955,7 +4230,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -3970,7 +4245,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -3985,7 +4260,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4000,7 +4275,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4015,7 +4290,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4030,7 +4305,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4045,7 +4320,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4060,7 +4335,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4075,7 +4350,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4091,7 +4366,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op2.var);
@@ -4108,7 +4383,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4124,7 +4399,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4140,7 +4415,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4156,7 +4431,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4171,7 +4446,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4186,7 +4461,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4201,7 +4476,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4216,21 +4491,40 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ zval_dtor(free_op2.var);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -4246,24 +4540,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -4274,9 +4568,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -4286,20 +4583,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -4313,29 +4610,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -4352,7 +4651,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4397,7 +4696,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -4459,6 +4758,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -4467,7 +4923,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4482,7 +4938,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4497,7 +4953,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4512,7 +4968,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4527,7 +4983,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4542,7 +4998,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4557,7 +5013,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4572,7 +5028,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4587,7 +5043,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4603,7 +5059,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -4620,7 +5076,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4636,7 +5092,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4652,7 +5108,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4668,7 +5124,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4683,7 +5139,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4698,7 +5154,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4713,7 +5169,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4728,7 +5184,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4886,7 +5342,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -4899,14 +5355,33 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
return zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -4922,24 +5397,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -4950,9 +5425,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -4962,20 +5440,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -4989,29 +5467,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5028,7 +5508,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -5073,7 +5553,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -5298,6 +5778,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -5449,7 +6087,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPC
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -5467,9 +6105,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -5485,24 +6123,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -5516,6 +6154,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
function_name = NULL;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -5525,20 +6166,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -5552,29 +6193,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5868,6 +6511,163 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -5876,7 +6676,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5891,7 +6691,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5906,7 +6706,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5921,7 +6721,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5936,7 +6736,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5951,7 +6751,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5966,7 +6766,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5981,7 +6781,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5996,7 +6796,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6012,7 +6812,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -6029,7 +6829,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6045,7 +6845,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6061,7 +6861,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6077,7 +6877,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OP
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6092,7 +6892,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6107,7 +6907,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6122,7 +6922,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6137,7 +6937,26 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
+
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6149,9 +6968,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -6167,24 +6986,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_CV == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -6195,9 +7014,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -6207,20 +7029,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -6234,29 +7056,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6306,7 +7130,7 @@ static int ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (EX_CV(opline->op2.var)) {
zval_ptr_dtor(EX_CV(opline->op2.var));
}
- EX_CV(opline->op2.var) = (zval**)EX_CVs() + (EX(op_array)->last_var + opline->op2.var);
+ EX_CV(opline->op2.var) = (zval**)EX_CV_NUM(execute_data, EX(op_array)->last_var + opline->op2.var);
*EX_CV(opline->op2.var) = EG(exception);
} else {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.var);
@@ -6333,7 +7157,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6377,7 +7201,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -6439,6 +7263,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -6446,7 +7427,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6459,7 +7440,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6472,7 +7453,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ z = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -6500,7 +7481,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -6530,7 +7511,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -6560,7 +7541,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6594,7 +7575,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6625,7 +7606,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6669,20 +7650,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
}
- } else if (!1) { /* Not a temp var */
+ } else {
if (IS_TMP_VAR == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_TMP_VAR == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_TMP_VAR != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -6694,12 +7678,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -6719,7 +7697,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
@@ -6783,11 +7761,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -6808,7 +7790,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
}
{
@@ -6816,7 +7798,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *value;
zend_free_op free_op1;
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ALLOC_ZVAL(valptr);
INIT_PZVAL_COPY(valptr, value);
@@ -6838,7 +7820,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -6855,10 +7837,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ obj = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -6916,7 +7901,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -6973,11 +7958,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
zend_op_array *new_op_array=NULL;
zend_free_op free_op1;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ inc_filename = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -7065,8 +8050,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -7074,14 +8057,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -7091,15 +8073,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -7154,7 +8127,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* IS_TMP_VAR */
zval *tmp;
@@ -7232,7 +8205,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -7263,7 +8236,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- zval *ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -7313,7 +8286,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -7339,7 +8312,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
@@ -7374,7 +8347,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!1) {
@@ -7392,7 +8365,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
@@ -7420,7 +8393,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -7440,7 +8413,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7455,7 +8428,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7470,7 +8443,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7485,7 +8458,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7500,7 +8473,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7515,7 +8488,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7530,7 +8503,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7545,7 +8518,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7560,7 +8533,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7576,7 +8549,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
@@ -7593,7 +8566,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7609,7 +8582,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7625,7 +8598,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7641,7 +8614,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7656,7 +8629,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7671,7 +8644,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7686,7 +8659,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7701,7 +8674,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7720,7 +8693,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -7860,7 +8833,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -7873,6 +8846,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
return zend_fetch_var_address_helper_SPEC_TMP_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -7880,7 +8872,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
PZVAL_LOCK(&EG(uninitialized_zval));
@@ -7950,63 +8942,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -8023,7 +9024,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -8047,7 +9048,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -8154,7 +9155,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -8232,7 +9233,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -8293,6 +9294,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8300,8 +9458,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8315,8 +9473,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8330,8 +9488,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8345,8 +9503,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8360,8 +9518,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8375,8 +9533,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8390,8 +9548,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8405,8 +9563,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8420,8 +9578,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8436,8 +9594,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
@@ -8453,8 +9611,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8469,8 +9627,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8485,8 +9643,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8501,8 +9659,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8516,8 +9674,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8531,8 +9689,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8546,8 +9704,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8561,14 +9719,33 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ zval_dtor(free_op2.var);
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8579,7 +9756,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -8621,63 +9798,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -8695,8 +9881,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8720,7 +9906,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -8741,7 +9927,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -8803,6 +9989,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8810,8 +10153,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8825,8 +10168,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8840,8 +10183,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8855,8 +10198,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8870,8 +10213,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8885,8 +10228,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8900,8 +10243,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8915,8 +10258,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8930,8 +10273,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8946,8 +10289,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -8963,8 +10306,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8979,8 +10322,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8995,8 +10338,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9011,8 +10354,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9026,8 +10369,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9041,8 +10384,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9056,8 +10399,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9071,8 +10414,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9090,7 +10433,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -9230,7 +10573,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9243,6 +10586,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
return zend_fetch_var_address_helper_SPEC_TMP_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -9253,7 +10615,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -9295,63 +10657,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -9369,8 +10740,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9394,7 +10765,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -9415,7 +10786,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -9501,7 +10872,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -9579,7 +10950,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -9640,6 +11011,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -9651,7 +11180,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -9791,7 +11320,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9821,7 +11350,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -9928,7 +11457,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -10006,7 +11535,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -10067,6 +11596,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10074,8 +11760,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10089,8 +11775,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10104,8 +11790,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10119,8 +11805,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10134,8 +11820,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10149,8 +11835,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10164,8 +11850,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10179,8 +11865,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10194,8 +11880,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10210,8 +11896,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
@@ -10227,8 +11913,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10243,8 +11929,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10259,8 +11945,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10275,8 +11961,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10290,8 +11976,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10305,8 +11991,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10320,8 +12006,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10335,14 +12021,33 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10353,7 +12058,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_A
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -10394,63 +12099,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -10467,8 +12181,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10491,7 +12205,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -10512,7 +12226,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -10574,6 +12288,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10581,7 +12452,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10594,7 +12465,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10607,7 +12478,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10654,7 +12525,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10701,7 +12572,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10744,7 +12615,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10787,7 +12658,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ z = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -10815,7 +12686,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -10845,7 +12716,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -10875,7 +12746,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10909,7 +12780,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10940,7 +12811,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10984,20 +12855,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_VAR == IS_TMP_VAR) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_VAR == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_VAR == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_VAR != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -11009,12 +12883,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -11034,7 +12902,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_VAR == IS_TMP_VAR) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11056,7 +12924,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
break;
}
- retval_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
@@ -11099,11 +12967,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -11123,7 +12995,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR
USE_OPLINE
zval *varptr;
zend_free_op free_op1;
- varptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (varptr == &EG(uninitialized_zval)) {
ALLOC_ZVAL(varptr);
@@ -11157,7 +13029,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -11168,7 +13040,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
varptr = EX_T(opline->op1.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
- varptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.var).var.fcall_returned_reference) &&
@@ -11183,7 +13055,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
- !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
ALLOC_ZVAL(valptr);
@@ -11206,7 +13078,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *varptr;
SAVE_OPLINE();
- varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
@@ -11221,7 +13093,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
- !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -11240,7 +13112,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
USE_OPLINE
if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
SAVE_OPLINE();
@@ -11255,7 +13127,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -11282,10 +13154,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ obj = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -11343,7 +13218,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -11400,11 +13275,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
zend_op_array *new_op_array=NULL;
zend_free_op free_op1;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ inc_filename = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -11492,8 +13367,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -11501,14 +13374,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -11518,15 +13390,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -11554,7 +13417,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
(opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
- array_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
MAKE_STD_ZVAL(array_ptr);
ZVAL_NULL(array_ptr);
@@ -11581,7 +13444,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* IS_TMP_VAR */
zval *tmp;
@@ -11659,7 +13522,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -11689,13 +13552,13 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *array = EX_T(opline->op1.var).fe.ptr;
zval **value;
- char *str_key;
- uint str_key_len;
- ulong int_key;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
- int key_type = 0;
- zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
+
+ zval *key = NULL;
+ if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
+ key = &EX_T((opline+1)->result.var).tmp_var;
+ }
SAVE_OPLINE();
@@ -11706,8 +13569,11 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
case ZEND_ITER_PLAIN_OBJECT: {
- const char *class_name, *prop_name;
zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
+ int key_type;
+ char *str_key;
+ zend_uint str_key_len;
+ zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -11719,16 +13585,23 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
- } while (key_type == HASH_KEY_NON_EXISTANT ||
- (key_type != HASH_KEY_IS_LONG &&
- zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
- zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
- if (use_key && key_type != HASH_KEY_IS_LONG) {
- zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
- str_key_len = strlen(prop_name);
- str_key = estrndup(prop_name, str_key_len);
- str_key_len++;
+ } while (key_type != HASH_KEY_IS_LONG &&
+ zend_check_property_access(zobj, str_key, str_key_len - 1 TSRMLS_CC) != SUCCESS);
+
+ if (key) {
+ if (key_type == HASH_KEY_IS_LONG) {
+ ZVAL_LONG(key, int_key);
+ } else {
+ const char *class_name, *prop_name;
+ int prop_name_len;
+ zend_unmangle_property_name_ex(
+ str_key, str_key_len - 1, &class_name, &prop_name, &prop_name_len
+ );
+ ZVAL_STRINGL(key, prop_name, prop_name_len, 1);
+ }
}
+
+ zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
break;
}
@@ -11739,8 +13612,8 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
- key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
+ if (key) {
+ zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -11775,16 +13648,15 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* failure in get_current_data */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
+ if (key) {
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
+ iter->funcs->get_current_key(iter, key TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(&array);
HANDLE_EXCEPTION();
}
} else {
- key_type = HASH_KEY_IS_LONG;
- int_key = iter->index;
+ ZVAL_LONG(key, iter->index);
}
}
break;
@@ -11800,26 +13672,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
AI_SET_PTR(&EX_T(opline->result.var), *value);
}
- if (use_key) {
- zval *key = &EX_T((opline+1)->result.var).tmp_var;
-
- switch (key_type) {
- case HASH_KEY_IS_STRING:
- Z_STRVAL_P(key) = (char*)str_key;
- Z_STRLEN_P(key) = str_key_len-1;
- Z_TYPE_P(key) = IS_STRING;
- break;
- case HASH_KEY_IS_LONG:
- Z_LVAL_P(key) = int_key;
- Z_TYPE_P(key) = IS_LONG;
- break;
- default:
- case HASH_KEY_NON_EXISTANT:
- ZVAL_NULL(key);
- break;
- }
- }
-
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
@@ -11833,7 +13685,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- zval *ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -11854,7 +13706,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -11880,7 +13732,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
@@ -11915,7 +13767,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!0) {
@@ -11933,7 +13785,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
Z_ADDREF_P(value);
@@ -11962,7 +13814,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -11982,7 +13834,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11997,7 +13849,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12012,7 +13864,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12027,7 +13879,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12042,7 +13894,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12057,7 +13909,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12072,7 +13924,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12087,7 +13939,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12102,7 +13954,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12118,7 +13970,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12135,7 +13987,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12151,7 +14003,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12167,7 +14019,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12183,7 +14035,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12198,7 +14050,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12213,7 +14065,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12228,7 +14080,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12243,7 +14095,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12255,10 +14107,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
{
USE_OPLINE
zend_free_op free_op1, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -12287,7 +14139,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
/* here property is a string */
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, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12376,7 +14228,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **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");
@@ -12389,14 +14241,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
value = opline->op2.zv;
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -12518,7 +14370,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).var.ptr;
@@ -12548,7 +14400,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12622,7 +14474,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).tmp_var;
@@ -12649,7 +14501,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12724,7 +14576,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -12864,7 +14716,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -12888,7 +14740,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12903,7 +14755,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
@@ -12937,7 +14789,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
@@ -12959,7 +14811,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12974,8 +14826,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **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");
@@ -12992,7 +14844,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_CONST == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13008,7 +14860,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -13026,6 +14878,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -13050,7 +14903,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST(
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -13099,15 +14952,10 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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 object");
}
@@ -13147,7 +14995,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -13178,7 +15026,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -13215,7 +15063,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -13223,7 +15071,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -13256,7 +15104,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
if (IS_VAR == IS_CV) {
@@ -13299,7 +15147,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property_name = opline->op2.zv;
if (0) {
@@ -13308,7 +15156,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -13328,7 +15176,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -13340,7 +15188,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -13354,8 +15202,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -13410,7 +15258,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
value = opline->op2.zv;
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
@@ -13463,63 +15311,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13532,9 +15389,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -13550,24 +15407,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_CONST == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -13581,6 +15438,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
function_name = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -13590,20 +15450,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -13617,29 +15477,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -13655,7 +15517,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -13747,6 +15609,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -13764,7 +15629,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -13773,7 +15638,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -13880,7 +15745,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -13943,7 +15808,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -14042,7 +15907,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (IS_VAR != IS_VAR || container) {
@@ -14099,7 +15964,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -14164,22 +16029,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
{
USE_OPLINE
zend_free_op free_op1;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -14198,9 +16063,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -14235,20 +16098,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -14259,7 +16122,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -14277,11 +16140,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -14314,6 +16177,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -14321,8 +16343,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14336,8 +16358,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14351,8 +16373,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14366,8 +16388,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14381,8 +16403,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14396,8 +16418,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14411,8 +16433,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14426,8 +16448,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14441,8 +16463,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14457,8 +16479,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
@@ -14474,8 +16496,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14490,8 +16512,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14506,8 +16528,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14522,8 +16544,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14537,8 +16559,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14552,8 +16574,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14567,8 +16589,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14582,8 +16604,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14594,10 +16616,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14626,7 +16648,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
/* here property is a string */
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, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -14715,7 +16737,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **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");
@@ -14725,17 +16747,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -14858,8 +16880,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14888,7 +16910,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -14962,8 +16984,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14989,7 +17011,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -15064,8 +17086,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -15079,12 +17101,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15113,12 +17135,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15135,8 +17157,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -15150,13 +17172,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -15168,8 +17190,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -15184,7 +17206,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -15194,7 +17216,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15202,6 +17224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -15226,8 +17249,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -15273,17 +17296,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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 object");
}
@@ -15322,8 +17340,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -15354,8 +17372,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -15391,15 +17409,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -15432,8 +17450,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -15475,8 +17493,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -15484,7 +17502,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -15504,19 +17522,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -15525,14 +17543,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -15586,8 +17604,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
@@ -15640,63 +17658,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -15710,9 +17737,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -15728,24 +17755,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -15756,9 +17783,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -15768,20 +17798,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -15795,29 +17825,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -15833,8 +17865,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -15849,7 +17881,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -15858,7 +17890,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -15879,7 +17911,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -15950,11 +17982,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -16049,8 +18081,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -16086,22 +18118,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -16120,9 +18152,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -16157,20 +18187,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -16181,7 +18211,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -16199,11 +18229,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -16236,6 +18266,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -16243,8 +18432,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16258,8 +18447,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16273,8 +18462,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16288,8 +18477,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16303,8 +18492,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16318,8 +18507,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16333,8 +18522,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16348,8 +18537,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16363,8 +18552,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16379,8 +18568,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -16396,8 +18585,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16412,8 +18601,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16428,8 +18617,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16444,8 +18633,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16459,8 +18648,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16474,8 +18663,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16489,8 +18678,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16504,8 +18693,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16516,10 +18705,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16548,7 +18737,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
/* here property is a string */
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, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16637,7 +18826,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **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");
@@ -16647,17 +18836,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -16780,8 +18969,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16810,7 +18999,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16884,8 +19073,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16911,7 +19100,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16986,7 +19175,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -17126,7 +19315,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -17150,8 +19339,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -17165,12 +19354,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17199,12 +19388,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17221,8 +19410,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -17236,13 +19425,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -17254,8 +19443,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -17270,7 +19459,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -17280,7 +19469,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17288,6 +19477,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -17312,8 +19502,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -17359,17 +19549,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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 object");
}
@@ -17408,8 +19593,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -17440,8 +19625,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -17477,15 +19662,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -17518,8 +19703,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -17561,8 +19746,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -17570,7 +19755,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -17590,19 +19775,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -17611,14 +19796,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -17672,8 +19857,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
@@ -17728,7 +19913,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_VAR &&
value_ptr_ptr &&
@@ -17751,7 +19936,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -17781,63 +19966,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -17851,9 +20045,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -17869,24 +20063,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -17897,9 +20091,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -17909,20 +20106,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -17936,29 +20133,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -17974,8 +20173,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -17990,7 +20189,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -17999,7 +20198,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -18020,7 +20219,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -18106,7 +20305,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -18169,11 +20368,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -18268,8 +20467,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -18325,7 +20524,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -18390,22 +20589,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -18424,9 +20623,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -18461,20 +20658,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -18485,7 +20682,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -18503,11 +20700,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -18540,14 +20737,174 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_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_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -18576,7 +20933,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
/* here property is a string */
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, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -18665,7 +21022,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **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");
@@ -18678,14 +21035,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
value = NULL;
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -18807,7 +21164,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -18947,7 +21304,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -18967,7 +21324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
@@ -19001,7 +21358,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
@@ -19023,8 +21380,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **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");
@@ -19041,7 +21398,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
if (IS_UNUSED == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -19057,7 +21414,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -19069,7 +21426,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -19083,8 +21440,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -19135,9 +21492,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -19153,24 +21510,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -19184,6 +21541,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
function_name = NULL;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -19193,20 +21553,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -19220,29 +21580,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -19256,7 +21618,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -19265,7 +21627,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -19372,7 +21734,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -19450,7 +21812,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -19519,8 +21881,8 @@ static int ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
var_ptr = EX_T(opline->op1.var).var.ptr;
if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
- !PZVAL_IS_REF(var_ptr) &&
- Z_REFCOUNT_P(var_ptr) > 1) {
+ !PZVAL_IS_REF(var_ptr) &&
+ Z_REFCOUNT_P(var_ptr) > 1) {
Z_DELREF_P(var_ptr);
ALLOC_ZVAL(new_zv);
@@ -19532,6 +21894,165 @@ static int ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -19539,8 +22060,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19554,8 +22075,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19569,8 +22090,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19584,8 +22105,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19599,8 +22120,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19614,8 +22135,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19629,8 +22150,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19644,8 +22165,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19659,8 +22180,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19675,8 +22196,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -19692,8 +22213,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19708,8 +22229,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19724,8 +22245,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19740,8 +22261,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19755,8 +22276,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19770,8 +22291,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19785,8 +22306,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19800,8 +22321,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19812,10 +22333,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
{
USE_OPLINE
zend_free_op free_op1, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -19844,7 +22365,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
/* here property is a string */
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, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -19933,7 +22454,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **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");
@@ -19943,17 +22464,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -20075,8 +22596,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -20105,7 +22626,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -20179,8 +22700,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -20206,7 +22727,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -20281,8 +22802,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -20296,12 +22817,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20330,12 +22851,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20352,8 +22873,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -20367,13 +22888,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -20385,8 +22906,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_CV == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -20401,7 +22922,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -20411,7 +22932,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20419,6 +22940,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -20443,8 +22965,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -20490,17 +23012,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ 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 object");
}
@@ -20539,8 +23056,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -20571,8 +23088,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -20608,15 +23125,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -20649,8 +23166,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -20692,8 +23209,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -20701,7 +23218,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -20721,19 +23238,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
- zval *property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -20742,13 +23259,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -20802,8 +23319,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CV TSRMLS_CC)) {
@@ -20857,7 +23374,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_VAR &&
value_ptr_ptr &&
@@ -20880,7 +23397,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -20909,63 +23426,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -20978,9 +23504,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -20996,24 +23522,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_CV == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -21024,9 +23550,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -21036,20 +23565,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -21063,29 +23592,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -21101,8 +23632,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -21116,7 +23647,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -21125,7 +23656,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -21146,7 +23677,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -21217,11 +23748,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -21316,8 +23847,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -21353,22 +23884,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
{
USE_OPLINE
zend_free_op free_op1;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -21387,9 +23918,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -21424,20 +23953,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -21448,7 +23977,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -21466,11 +23995,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -21503,6 +24032,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -21517,6 +24205,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_UNUSED == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -21595,7 +24286,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -21624,7 +24315,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
/* here property is a string */
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, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -21725,8 +24416,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
@@ -21884,7 +24575,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -21985,7 +24676,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -22106,11 +24797,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
@@ -22220,7 +24906,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -22312,7 +24998,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -22378,63 +25064,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -22526,6 +25221,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -22692,22 +25390,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -22726,9 +25424,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -22763,20 +25459,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -22787,7 +25483,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -22805,11 +25501,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -22840,14 +25536,171 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_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_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -22876,7 +25729,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
/* here property is a string */
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, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -22974,16 +25827,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -23108,7 +25961,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -23137,7 +25990,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -23212,7 +26065,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -23238,7 +26091,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -23312,7 +26165,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -23357,12 +26210,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -23405,7 +26253,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (1) {
@@ -23438,7 +26286,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -23473,14 +26321,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (1) {
@@ -23515,7 +26363,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -23557,7 +26405,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -23565,7 +26413,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -23588,7 +26436,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDL
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -23630,63 +26478,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -23721,7 +26578,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -23816,7 +26673,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -23851,22 +26708,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -23885,9 +26742,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -23922,20 +26777,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -23946,7 +26801,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -23964,11 +26819,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -23999,14 +26854,171 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_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_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24035,7 +27047,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
/* here property is a string */
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, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24133,16 +27145,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -24267,7 +27279,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24296,7 +27308,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24371,7 +27383,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24397,7 +27409,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24471,7 +27483,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -24516,12 +27528,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -24564,7 +27571,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -24597,7 +27604,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -24632,14 +27639,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -24674,7 +27681,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -24716,7 +27723,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -24724,7 +27731,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -24747,7 +27754,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -24789,63 +27796,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -24880,7 +27896,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -24975,7 +27991,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -25010,22 +28026,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -25044,9 +28060,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -25081,20 +28095,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -25105,7 +28119,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -25123,11 +28137,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -25158,6 +28172,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -25165,7 +28337,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25194,7 +28366,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
/* here property is a string */
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, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25295,8 +28467,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
@@ -25427,14 +28599,171 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_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_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25463,7 +28792,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
/* here property is a string */
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, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25561,16 +28890,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -25694,7 +29023,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25723,7 +29052,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25798,7 +29127,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25824,7 +29153,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25898,7 +29227,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -25943,12 +29272,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -25991,7 +29315,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -26024,7 +29348,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -26059,14 +29383,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -26101,7 +29425,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -26143,7 +29467,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -26151,7 +29475,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -26174,7 +29498,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLE
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -26215,63 +29539,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -26305,7 +29638,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -26400,7 +29733,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -26435,22 +29768,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -26469,9 +29802,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -26506,20 +29837,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -26530,7 +29861,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -26548,11 +29879,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -26583,6 +29914,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -26590,7 +30078,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -26603,7 +30091,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -26616,7 +30104,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26662,7 +30150,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26708,7 +30196,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26750,7 +30238,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26792,7 +30280,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ z = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -26819,7 +30307,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -26849,7 +30337,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -26879,7 +30367,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26913,7 +30401,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26944,7 +30432,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26974,20 +30462,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_CV == IS_TMP_VAR) {
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_CV == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_CV == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_CV != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -26999,12 +30490,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -27024,7 +30509,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_CV == IS_TMP_VAR) {
@@ -27046,7 +30531,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
break;
}
- retval_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
@@ -27088,11 +30573,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -27112,7 +30601,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG
USE_OPLINE
zval *varptr;
- varptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (varptr == &EG(uninitialized_zval)) {
ALLOC_ZVAL(varptr);
@@ -27146,7 +30635,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -27157,7 +30646,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
varptr = EX_T(opline->op1.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
- varptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.var).var.fcall_returned_reference) &&
@@ -27172,7 +30661,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
- !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
ALLOC_ZVAL(valptr);
@@ -27195,7 +30684,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *varptr;
SAVE_OPLINE();
- varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
@@ -27210,7 +30699,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
- !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -27228,7 +30717,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
USE_OPLINE
if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
SAVE_OPLINE();
@@ -27243,7 +30732,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC)));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -27259,10 +30748,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ obj = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -27320,7 +30812,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -27377,11 +30869,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
zend_op_array *new_op_array=NULL;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ inc_filename = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -27469,8 +30961,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -27478,14 +30968,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -27495,15 +30984,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -27531,7 +31011,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
(opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
- array_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ array_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
MAKE_STD_ZVAL(array_ptr);
ZVAL_NULL(array_ptr);
@@ -27558,7 +31038,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ array_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* IS_TMP_VAR */
zval *tmp;
@@ -27636,7 +31116,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -27667,7 +31147,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_CV != IS_UNUSED) {
- zval *ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -27688,7 +31168,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -27713,7 +31193,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
@@ -27747,7 +31227,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!0) {
@@ -27765,7 +31245,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
Z_ADDREF_P(value);
@@ -27793,7 +31273,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -27813,7 +31293,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27828,7 +31308,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27843,7 +31323,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27858,7 +31338,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27873,7 +31353,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27888,7 +31368,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27903,7 +31383,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27918,7 +31398,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27933,7 +31413,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27949,7 +31429,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -27966,7 +31446,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -27982,7 +31462,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -27998,7 +31478,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -28014,7 +31494,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -28029,7 +31509,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28044,7 +31524,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28059,7 +31539,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28074,7 +31554,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28086,10 +31566,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
{
USE_OPLINE
zend_free_op free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -28118,7 +31598,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
/* here property is a string */
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, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28206,7 +31686,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_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");
@@ -28219,14 +31699,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
value = opline->op2.zv;
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -28348,7 +31828,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).var.ptr;
@@ -28378,7 +31858,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28452,7 +31932,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).tmp_var;
@@ -28479,7 +31959,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28554,7 +32034,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -28694,7 +32174,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -28718,7 +32198,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
@@ -28733,7 +32213,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
@@ -28766,7 +32246,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_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");
@@ -28788,7 +32268,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
@@ -28803,8 +32283,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
@@ -28821,7 +32301,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CONST == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
@@ -28837,7 +32317,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -28855,6 +32335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -28879,7 +32360,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(Z
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -28927,15 +32408,10 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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 object");
}
@@ -28974,7 +32450,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -29005,7 +32481,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -29041,7 +32517,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -29049,7 +32525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -29082,7 +32558,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
if (IS_CV == IS_CV) {
@@ -29124,7 +32600,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
property_name = opline->op2.zv;
if (0) {
@@ -29133,7 +32609,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -29153,7 +32629,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -29165,7 +32641,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -29179,8 +32655,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -29235,7 +32711,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
value = opline->op2.zv;
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
@@ -29286,63 +32762,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -29359,7 +32844,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -29374,7 +32859,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -29383,7 +32868,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -29490,7 +32975,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -29553,7 +33038,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -29651,7 +33136,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (IS_CV != IS_VAR || container) {
@@ -29707,7 +33192,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -29772,22 +33257,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -29806,9 +33291,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -29843,20 +33326,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -29867,7 +33350,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -29885,11 +33368,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -29920,6 +33403,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -29927,8 +33567,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29942,8 +33582,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29957,8 +33597,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29972,8 +33612,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29987,8 +33627,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30002,8 +33642,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30017,8 +33657,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30032,8 +33672,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30047,8 +33687,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30063,8 +33703,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op2.var);
@@ -30080,8 +33720,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30096,8 +33736,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30112,8 +33752,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30128,8 +33768,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30143,8 +33783,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30158,8 +33798,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30173,8 +33813,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30188,8 +33828,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30200,10 +33840,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30232,7 +33872,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
/* here property is a string */
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, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30320,7 +33960,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_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");
@@ -30330,17 +33970,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -30463,8 +34103,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30493,7 +34133,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30567,8 +34207,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30594,7 +34234,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30669,8 +34309,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30684,12 +34324,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30717,12 +34357,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30739,8 +34379,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30754,13 +34394,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -30772,8 +34412,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
}
@@ -30788,7 +34428,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -30798,7 +34438,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30806,6 +34446,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -30830,8 +34471,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -30876,17 +34517,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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 object");
}
@@ -30924,8 +34560,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -30956,8 +34592,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -30992,15 +34628,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -31033,8 +34669,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -31075,8 +34711,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -31084,7 +34720,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -31104,19 +34740,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -31125,14 +34761,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -31186,8 +34822,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
@@ -31238,63 +34874,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -31312,8 +34957,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -31328,7 +34973,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -31337,7 +34982,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -31358,7 +35003,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -31429,11 +35074,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -31527,8 +35172,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -31563,22 +35208,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -31597,9 +35242,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -31634,20 +35277,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -31658,7 +35301,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -31676,11 +35319,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -31711,6 +35354,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -31718,8 +35518,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31733,8 +35533,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31748,8 +35548,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31763,8 +35563,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31778,8 +35578,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31793,8 +35593,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31808,8 +35608,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31823,8 +35623,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31838,8 +35638,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31854,8 +35654,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -31871,8 +35671,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31887,8 +35687,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31903,8 +35703,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31919,8 +35719,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31934,8 +35734,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31949,8 +35749,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31964,8 +35764,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31979,8 +35779,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31991,10 +35791,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32023,7 +35823,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
/* here property is a string */
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, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32111,7 +35911,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_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");
@@ -32121,17 +35921,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -32254,8 +36054,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32284,7 +36084,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32358,8 +36158,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32385,7 +36185,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32460,7 +36260,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -32600,7 +36400,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HA
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -32624,8 +36424,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -32639,12 +36439,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32672,12 +36472,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32694,8 +36494,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -32709,13 +36509,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -32727,8 +36527,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
@@ -32743,7 +36543,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -32753,7 +36553,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32761,6 +36561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -32785,8 +36586,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -32831,17 +36632,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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 object");
}
@@ -32879,8 +36675,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -32911,8 +36707,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -32947,15 +36743,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -32988,8 +36784,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -33030,8 +36826,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -33039,7 +36835,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -33059,19 +36855,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -33080,14 +36876,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -33141,8 +36937,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
@@ -33195,7 +36991,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_VAR &&
value_ptr_ptr &&
@@ -33218,7 +37014,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -33247,63 +37043,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -33321,8 +37126,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -33337,7 +37142,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -33346,7 +37151,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -33367,7 +37172,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -33453,7 +37258,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -33516,11 +37321,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -33614,8 +37419,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -33670,7 +37475,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -33735,22 +37540,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -33769,9 +37574,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -33806,20 +37609,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -33830,7 +37633,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -33848,11 +37651,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -33883,14 +37686,172 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_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_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -33919,7 +37880,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
/* here property is a string */
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, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -34007,7 +37968,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_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");
@@ -34020,14 +37981,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
value = NULL;
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -34149,7 +38110,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -34289,7 +38250,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -34309,7 +38270,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
@@ -34342,7 +38303,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_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");
@@ -34364,8 +38325,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
@@ -34382,7 +38343,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
if (IS_UNUSED == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
@@ -34398,7 +38359,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34410,7 +38371,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -34424,8 +38385,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -34479,7 +38440,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -34488,7 +38449,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -34595,7 +38556,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -34673,7 +38634,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -34734,6 +38695,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -34741,8 +38859,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34756,8 +38874,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34771,8 +38889,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34786,8 +38904,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34801,8 +38919,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34816,8 +38934,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34831,8 +38949,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34846,8 +38964,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34861,8 +38979,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34877,8 +38995,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -34894,8 +39012,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34910,8 +39028,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34926,8 +39044,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34942,8 +39060,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34957,8 +39075,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34972,8 +39090,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34987,8 +39105,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35002,8 +39120,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35014,10 +39132,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
{
USE_OPLINE
zend_free_op free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35046,7 +39164,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
/* here property is a string */
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, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35134,7 +39252,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_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");
@@ -35144,17 +39262,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
}
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((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);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -35276,8 +39394,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35306,7 +39424,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35380,8 +39498,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35407,7 +39525,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35482,8 +39600,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35497,12 +39615,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35530,12 +39648,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35552,8 +39670,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35567,13 +39685,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -35585,8 +39703,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
}
@@ -35601,7 +39719,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -35611,7 +39729,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");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35619,6 +39737,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -35643,8 +39762,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(ZEND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -35689,17 +39808,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(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 object");
}
@@ -35737,8 +39851,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -35769,8 +39883,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -35805,15 +39919,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -35846,8 +39960,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -35888,8 +40002,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -35897,7 +40011,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_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");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -35917,19 +40031,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
- zval *property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -35938,13 +40052,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
} else {
zend_free_op free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -35998,8 +40112,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CV TSRMLS_CC)) {
@@ -36051,7 +40165,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_VAR &&
value_ptr_ptr &&
@@ -36074,7 +40188,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -36102,63 +40216,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -36175,8 +40298,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -36190,7 +40313,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -36199,7 +40322,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -36220,7 +40343,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -36291,11 +40414,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -36389,8 +40512,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -36425,22 +40548,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -36459,9 +40582,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -36496,20 +40617,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -36520,7 +40641,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -36538,11 +40659,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -36573,9 +40694,167 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OP
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* 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_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
@@ -38607,16 +42886,16 @@ void zend_init_opcodes_handlers(void)
ZEND_FETCH_R_SPEC_CV_VAR_HANDLER,
ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_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_FETCH_DIM_R_SPEC_TMP_CV_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER,
@@ -40557,6 +44836,131 @@ void zend_init_opcodes_handlers(void)
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_YIELD_SPEC_CONST_CONST_HANDLER,
+ ZEND_YIELD_SPEC_CONST_TMP_HANDLER,
+ ZEND_YIELD_SPEC_CONST_VAR_HANDLER,
+ ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_CONST_CV_HANDLER,
+ ZEND_YIELD_SPEC_TMP_CONST_HANDLER,
+ ZEND_YIELD_SPEC_TMP_TMP_HANDLER,
+ ZEND_YIELD_SPEC_TMP_VAR_HANDLER,
+ ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_TMP_CV_HANDLER,
+ ZEND_YIELD_SPEC_VAR_CONST_HANDLER,
+ ZEND_YIELD_SPEC_VAR_TMP_HANDLER,
+ ZEND_YIELD_SPEC_VAR_VAR_HANDLER,
+ ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_VAR_CV_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_CV_HANDLER,
+ ZEND_YIELD_SPEC_CV_CONST_HANDLER,
+ ZEND_YIELD_SPEC_CV_TMP_HANDLER,
+ ZEND_YIELD_SPEC_CV_VAR_HANDLER,
+ ZEND_YIELD_SPEC_CV_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_CV_CV_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;