original_in_execution = EG(in_execution);
EG(in_execution) = 1;
- if (0) {
-zend_vm_enter:
- execute_data = i_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
- }
-
LOAD_REGS();
LOAD_OPLINE();
EG(in_execution) = original_in_execution;
return;
case 2:
- goto zend_vm_enter;
- break;
case 3:
execute_data = EG(current_execute_data);
break;
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
-ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC)
+ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC)
{
if (EG(exception) != NULL) {
return;
}
- zend_execute_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);
+ zend_execute_ex(i_create_execute_data_from_op_array(op_array, return_value, 0 TSRMLS_CC) TSRMLS_CC);
}
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
-//??? EG(return_value_ptr_ptr) = EX(original_return_value);
destroy_op_array(op_array TSRMLS_CC);
efree(op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
} 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)) {
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
- if (RETURN_VALUE_USED(opline) /*???&& EX_VAR(opline->result.var).var.ptr*/) {
+ if (RETURN_VALUE_USED(opline) /*???&& EX_VAR(opline->result.var) */) {
zval_ptr_dtor(EX_VAR(opline->result.var));
}
HANDLE_EXCEPTION_LEAVE();
//??? EX_T(opline->result.var).var.ptr = NULL;
}
} else if (fbc->type == ZEND_USER_FUNCTION) {
-//??? EX(original_return_value) = EG(return_value_ptr_ptr);
+ zval *return_value = NULL;
+
EG(active_symbol_table) = NULL;
EG(active_op_array) = &fbc->op_array;
-//??? EG(return_value_ptr_ptr) = NULL;
if (RETURN_VALUE_USED(opline)) {
- zval *ret = EX_VAR(opline->result.var);
+ return_value = EX_VAR(opline->result.var);
- ZVAL_NULL(ret);
-//??? EG(return_value_ptr_ptr) = &ret->var.ptr;
+ ZVAL_NULL(return_value);
//??? ret->var.ptr_ptr = &ret->var.ptr;
//??? ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
}
}
} else if (EXPECTED(zend_execute_ex == execute_ex)) {
if (EXPECTED(EG(exception) == NULL)) {
+ i_create_execute_data_from_op_array(EG(active_op_array), return_value, 1 TSRMLS_CC);
ZEND_VM_ENTER();
}
} else {
- zend_execute(EG(active_op_array) TSRMLS_CC);
+ zend_execute(EG(active_op_array), return_value TSRMLS_CC);
}
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)) {
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
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);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
/* Close the generator to free up resources */
-//??? zend_generator_close(generator, 1 TSRMLS_CC);
+ zend_generator_close(generator, 1 TSRMLS_CC);
/* Pass execution back to handling code */
ZEND_VM_RETURN();
z = opline->op1.zv;
if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
-//??? INIT_PZVAL(z);
+ Z_SET_REFCOUNT_P(z, 1);
}
zend_print_variable(z);
SAVE_OPLINE();
retval_ptr = opline->op1.zv;
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
} else {
if (IS_CONST == IS_CONST ||
if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&ret);
}
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), &ret);
} else {
-//??? *EG(return_value_ptr_ptr) = retval_ptr;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
if (IS_CONST == IS_CV) {
Z_ADDREF_P(retval_ptr);
}
zend_error(E_NOTICE, "Only variable references should be returned by reference");
retval_ptr = opline->op1.zv;
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
if (IS_CONST == IS_TMP_VAR) {
}
} else if (!0) { /* Not a temp var */
- zval ret;
-
- ZVAL_DUP(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_DUP(EX(return_value), retval_ptr);
} else {
- zval ret;
-
- ZVAL_COPY_VALUE(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
}
break;
}
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
-//???
-#if 0
- if (IS_CONST == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- EX_T(opline->op1.var).var.fcall_returned_reference) {
- } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(retval_ptr)) {
+//??? if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+//??? EX_T(opline->op1.var).var.fcall_returned_reference) {
+//??? } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- if (EG(return_value_ptr_ptr)) {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_DUP(ret, *retval_ptr_ptr);
- *EG(return_value_ptr_ptr) = ret;
+ if (EX(return_value)) {
+ ZVAL_DUP(EX(return_value), retval_ptr);
}
break;
- }
+//??? }
}
- if (EG(return_value_ptr_ptr)) {
- SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
- Z_ADDREF_PP(retval_ptr_ptr);
-
- *EG(return_value_ptr_ptr) = *retval_ptr_ptr;
+ if (EX(return_value)) {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
+ ZVAL_COPY(EX(return_value), retval_ptr);
}
-#endif
} while (0);
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
-//??? EX(original_return_value) = EG(return_value_ptr_ptr);
+ zval *return_value = NULL;
+
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
-//??? EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
-//??? EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr;
- } else {
-//??? EG(return_value_ptr_ptr) = NULL;
+ return_value = EX_VAR(opline->result.var);
}
EX(function_state).function = (zend_function *) new_op_array;
}
if (EXPECTED(zend_execute_ex == execute_ex)) {
+ i_create_execute_data_from_op_array(new_op_array, return_value, 1 TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array TSRMLS_CC);
+ zend_execute(new_op_array, return_value TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
-//??? EG(return_value_ptr_ptr) = EX(original_return_value);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CONST != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = opline->op1.zv;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = opline->op1.zv;
- if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CONST == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CONST != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = opline->op1.zv;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = opline->op1.zv;
- if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CONST == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CONST != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = opline->op1.zv;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = opline->op1.zv;
- if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CONST == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
}
zval_ptr_dtor_nogc(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CONST != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = opline->op1.zv;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = opline->op1.zv;
- if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CONST == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CONST != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = opline->op1.zv;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = opline->op1.zv;
- if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CONST == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CONST == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
+ Z_SET_REFCOUNT_P(z, 1);
}
zend_print_variable(z);
SAVE_OPLINE();
retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
zval_dtor(free_op1.var);
} else {
if (IS_TMP_VAR == IS_CONST ||
if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&ret);
}
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), &ret);
} else {
-//??? *EG(return_value_ptr_ptr) = retval_ptr;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(retval_ptr);
}
zend_error(E_NOTICE, "Only variable references should be returned by reference");
retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
}
} else if (!1) { /* Not a temp var */
- zval ret;
-
- ZVAL_DUP(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_DUP(EX(return_value), retval_ptr);
} else {
- zval ret;
-
- ZVAL_COPY_VALUE(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
}
break;
}
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
-//???
-#if 0
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- EX_T(opline->op1.var).var.fcall_returned_reference) {
- } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
+//??? if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+//??? EX_T(opline->op1.var).var.fcall_returned_reference) {
+//??? } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- if (EG(return_value_ptr_ptr)) {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_DUP(ret, *retval_ptr_ptr);
- *EG(return_value_ptr_ptr) = ret;
+ if (EX(return_value)) {
+ ZVAL_DUP(EX(return_value), retval_ptr);
}
break;
- }
+//??? }
}
- if (EG(return_value_ptr_ptr)) {
- SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
- Z_ADDREF_PP(retval_ptr_ptr);
-
- *EG(return_value_ptr_ptr) = *retval_ptr_ptr;
+ if (EX(return_value)) {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
+ ZVAL_COPY(EX(return_value), retval_ptr);
}
-#endif
} while (0);
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
-//??? EX(original_return_value) = EG(return_value_ptr_ptr);
+ zval *return_value = NULL;
+
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
-//??? EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
-//??? EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr;
- } else {
-//??? EG(return_value_ptr_ptr) = NULL;
+ return_value = EX_VAR(opline->result.var);
}
EX(function_state).function = (zend_function *) new_op_array;
}
if (EXPECTED(zend_execute_ex == execute_ex)) {
+ i_create_execute_data_from_op_array(new_op_array, return_value, 1 TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array TSRMLS_CC);
+ zend_execute(new_op_array, return_value TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
-//??? EG(return_value_ptr_ptr) = EX(original_return_value);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_TMP_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_TMP_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_TMP_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
}
zval_ptr_dtor_nogc(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_TMP_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_TMP_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
+ Z_SET_REFCOUNT_P(z, 1);
}
zend_print_variable(z);
SAVE_OPLINE();
retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CONST ||
if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&ret);
}
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), &ret);
zval_ptr_dtor_nogc(free_op1.var);
} else {
-//??? *EG(return_value_ptr_ptr) = retval_ptr;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
if (IS_VAR == IS_CV) {
Z_ADDREF_P(retval_ptr);
}
zend_error(E_NOTICE, "Only variable references should be returned by reference");
retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
if (IS_VAR == IS_TMP_VAR) {
zval_ptr_dtor_nogc(free_op1.var);
}
} else if (!0) { /* Not a temp var */
- zval ret;
-
- ZVAL_DUP(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_DUP(EX(return_value), retval_ptr);
} else {
- zval ret;
-
- ZVAL_COPY_VALUE(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
}
break;
}
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
-//???
-#if 0
- if (IS_VAR == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- EX_T(opline->op1.var).var.fcall_returned_reference) {
- } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
+//??? if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+//??? EX_T(opline->op1.var).var.fcall_returned_reference) {
+//??? } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- if (EG(return_value_ptr_ptr)) {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_DUP(ret, *retval_ptr_ptr);
- *EG(return_value_ptr_ptr) = ret;
+ if (EX(return_value)) {
+ ZVAL_DUP(EX(return_value), retval_ptr);
}
break;
- }
+//??? }
}
- if (EG(return_value_ptr_ptr)) {
- SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
- Z_ADDREF_PP(retval_ptr_ptr);
-
- *EG(return_value_ptr_ptr) = *retval_ptr_ptr;
+ if (EX(return_value)) {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
+ ZVAL_COPY(EX(return_value), retval_ptr);
}
-#endif
} while (0);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
-//??? EX(original_return_value) = EG(return_value_ptr_ptr);
+ zval *return_value = NULL;
+
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
-//??? EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
-//??? EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr;
- } else {
-//??? EG(return_value_ptr_ptr) = NULL;
+ return_value = EX_VAR(opline->result.var);
}
EX(function_state).function = (zend_function *) new_op_array;
}
if (EXPECTED(zend_execute_ex == execute_ex)) {
+ i_create_execute_data_from_op_array(new_op_array, return_value, 1 TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array TSRMLS_CC);
+ zend_execute(new_op_array, return_value TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
-//??? EG(return_value_ptr_ptr) = EX(original_return_value);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
}
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
}
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
}
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
}
zval_ptr_dtor_nogc(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
}
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_VAR != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_VAR == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
}
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
zval_ptr_dtor_nogc(free_op1.var);
} else {
if (IS_VAR == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_UNUSED != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = NULL;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = NULL;
- if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_UNUSED == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_UNUSED != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = NULL;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = NULL;
- if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_UNUSED == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_UNUSED != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = NULL;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = NULL;
- if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_UNUSED == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
}
zval_ptr_dtor_nogc(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_UNUSED != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = NULL;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = NULL;
- if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_UNUSED == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_UNUSED != IS_UNUSED) {
/* 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;
+ zval *value;
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
value = NULL;
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = NULL;
- if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_UNUSED == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
+ Z_SET_REFCOUNT_P(z, 1);
}
zend_print_variable(z);
SAVE_OPLINE();
retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
} else {
if (IS_CV == IS_CONST ||
if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&ret);
}
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), &ret);
} else {
-//??? *EG(return_value_ptr_ptr) = retval_ptr;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
if (IS_CV == IS_CV) {
Z_ADDREF_P(retval_ptr);
}
zend_error(E_NOTICE, "Only variable references should be returned by reference");
retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (/*???!EG(return_value_ptr_ptr)*/0) {
+ if (!EX(return_value)) {
if (IS_CV == IS_TMP_VAR) {
}
} else if (!0) { /* Not a temp var */
- zval ret;
-
- ZVAL_DUP(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_DUP(EX(return_value), retval_ptr);
} else {
- zval ret;
-
- ZVAL_COPY_VALUE(&ret, retval_ptr);
-//??? *EG(return_value_ptr_ptr) = ret;
+ ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
}
break;
}
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
-//???
-#if 0
- if (IS_CV == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- EX_T(opline->op1.var).var.fcall_returned_reference) {
- } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(retval_ptr)) {
+//??? if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+//??? EX_T(opline->op1.var).var.fcall_returned_reference) {
+//??? } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- if (EG(return_value_ptr_ptr)) {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_DUP(ret, *retval_ptr_ptr);
- *EG(return_value_ptr_ptr) = ret;
+ if (EX(return_value)) {
+ ZVAL_DUP(EX(return_value), retval_ptr);
}
break;
- }
+//??? }
}
- if (EG(return_value_ptr_ptr)) {
- SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
- Z_ADDREF_PP(retval_ptr_ptr);
-
- *EG(return_value_ptr_ptr) = *retval_ptr_ptr;
+ if (EX(return_value)) {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr);
+ ZVAL_COPY(EX(return_value), retval_ptr);
}
-#endif
} while (0);
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
-//??? EX(original_return_value) = EG(return_value_ptr_ptr);
+ zval *return_value = NULL;
+
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
-//??? EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
-//??? EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr;
- } else {
-//??? EG(return_value_ptr_ptr) = NULL;
+ return_value = EX_VAR(opline->result.var);
}
EX(function_state).function = (zend_function *) new_op_array;
}
if (EXPECTED(zend_execute_ex == execute_ex)) {
+ i_create_execute_data_from_op_array(new_op_array, return_value, 1 TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array TSRMLS_CC);
+ zend_execute(new_op_array, return_value TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
-//??? EG(return_value_ptr_ptr) = EX(original_return_value);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CV != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
- if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CV == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CV != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
- if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CV == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!1) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CV != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
- if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CV == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
}
zval_ptr_dtor_nogc(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
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)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CV != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
- if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CV == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
-//???
-return 0;
-#if 0
USE_OPLINE
/* The generator object is stored in return_value_ptr_ptr */
- zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+ zend_generator *generator = (zend_generator *) Z_OBJ_P(EX(return_value));
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);
- }
+ zval_ptr_dtor(&generator->value);
/* Destroy the previously yielded key */
- if (generator->key) {
- zval_ptr_dtor(&generator->key);
- }
+ zval_ptr_dtor(&generator->key);
/* Set the new yielded value */
if (IS_CV != IS_UNUSED) {
/* 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;
+ zval *value;
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);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
-
- generator->value = copy;
} else {
- zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
- if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
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) {
+ if (IS_CV == IS_VAR && !Z_ISREF_P(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;
}
+ ZVAL_COPY(&generator->value, value_ptr);
}
} else {
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| Z_ISREF_P(value)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, value);
+//??? INIT_PZVAL_COPY(copy, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->value);
}
- generator->value = copy;
-
} else {
if (IS_CV == IS_CV) {
Z_ADDREF_P(value);
}
- generator->value = value;
+ ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
/* If no value was specified yield null */
- Z_ADDREF(EG(uninitialized_zval));
- generator->value = &EG(uninitialized_zval);
+ ZVAL_NULL(&generator->value);
}
/* Set the new yielded key */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
|| (Z_ISREF_P(key) && Z_REFCOUNT_P(key) > 0)
) {
- zval *copy;
-
- ALLOC_ZVAL(copy);
- INIT_PZVAL_COPY(copy, key);
+//??? INIT_PZVAL_COPY(copy, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ Z_SET_REFCOUNT(generator->key, 1);
/* Temporary variables don't need ctor copying */
if (!0) {
- zval_copy_ctor(copy);
+ zval_copy_ctor(&generator->key);
}
-
- generator->key = copy;
} else {
- Z_ADDREF_P(key);
- generator->key = key;
+ ZVAL_COPY(&generator->key, key);
}
- if (Z_TYPE_P(generator->key) == IS_LONG
- && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
) {
- generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ generator->largest_used_integer_key = Z_LVAL(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);
+ 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);
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
} else {
generator->send_target = NULL;
}
SAVE_OPLINE();
ZEND_VM_RETURN();
-#endif
}
static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)