diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 44021b785ba95..f94340ae79d17 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4435,7 +4435,7 @@ zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, uint32 static zend_always_inline zend_generator *zend_get_running_generator(EXECUTE_DATA_D) /* {{{ */ { /* The generator object is stored in EX(return_value) */ - zend_generator *generator = (zend_generator *) EX(return_value); + zend_generator *generator = zend_generator_from_obj((zend_object *)EX(return_value)); /* However control may currently be delegated to another generator. * That's the one we're interested in. */ return generator; diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 97b7cdcc911b7..4e7e5523637c9 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -829,7 +829,7 @@ static HashTable *zend_fiber_object_gc(zend_object *object, zval **table, int *n HashTable *symTable; if (ZEND_CALL_INFO(ex) & ZEND_CALL_GENERATOR) { /* The generator object is stored in ex->return_value */ - zend_generator *generator = (zend_generator*)ex->return_value; + zend_generator *generator = zend_generator_from_obj((zend_object *)ex->return_value); /* There are two cases to consider: * - If the generator is currently running, the Generator's GC * handler will ignore it because it is not collectable. However, diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index a6ea91a7425b9..f345cf73c9268 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -240,7 +240,7 @@ static inline bool check_node_running_in_fiber(zend_generator *generator) { static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ { - zend_generator *generator = (zend_generator*) object; + zend_generator *generator = zend_generator_from_obj(object); zend_generator *current_generator = zend_generator_get_current(generator); zend_execute_data *ex = generator->execute_data; uint32_t op_num, try_catch_offset; @@ -357,7 +357,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ static void zend_generator_free_storage(zend_object *object) /* {{{ */ { - zend_generator *generator = (zend_generator*) object; + zend_generator *generator = zend_generator_from_obj(object); zend_generator_close(generator, 0); @@ -412,7 +412,7 @@ HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int *n) /* {{{ */ { - zend_generator *generator = (zend_generator*)object; + zend_generator *generator = zend_generator_from_obj(object); zend_execute_data *execute_data = generator->execute_data; if (!execute_data) { @@ -452,8 +452,9 @@ static HashTable *zend_generator_get_gc(zend_object *object, zval **table, int * static zend_object *zend_generator_create(zend_class_entry *class_type) /* {{{ */ { - zend_generator *generator = emalloc(sizeof(zend_generator)); - memset(generator, 0, sizeof(zend_generator)); + size_t block_len = sizeof(zend_generator) + zend_object_properties_size(class_type); + zend_generator *generator = emalloc(block_len); + memset(generator, 0, block_len); /* The key will be incremented on first use, so it'll start at 0 */ generator->largest_used_integer_key = -1; @@ -467,7 +468,7 @@ static zend_object *zend_generator_create(zend_class_entry *class_type) /* {{{ * generator->node.ptr.root = NULL; zend_object_std_init(&generator->std, class_type); - return (zend_object*)generator; + return &generator->std; } /* }}} */ @@ -483,7 +484,7 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_ { if (!ptr->func && Z_TYPE(ptr->This) == IS_OBJECT) { if (Z_OBJCE(ptr->This) == zend_ce_generator) { - zend_generator *generator = (zend_generator *) Z_OBJ(ptr->This); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(ptr->This)); zend_execute_data *prev = ptr->prev_execute_data; ZEND_ASSERT(generator->node.parent && "Placeholder only used with delegation"); while (generator->node.parent->node.parent) { @@ -898,7 +899,7 @@ ZEND_METHOD(Generator, rewind) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_rewind(generator); } @@ -911,7 +912,7 @@ ZEND_METHOD(Generator, valid) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -928,7 +929,7 @@ ZEND_METHOD(Generator, current) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -946,7 +947,7 @@ ZEND_METHOD(Generator, key) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -964,7 +965,7 @@ ZEND_METHOD(Generator, next) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -982,7 +983,7 @@ ZEND_METHOD(Generator, send) Z_PARAM_ZVAL(value) ZEND_PARSE_PARAMETERS_END(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -1018,7 +1019,7 @@ ZEND_METHOD(Generator, throw) Z_TRY_ADDREF_P(exception); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); @@ -1048,7 +1049,7 @@ ZEND_METHOD(Generator, getReturn) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); zend_generator_ensure_initialized(generator); if (UNEXPECTED(EG(exception))) { @@ -1072,7 +1073,7 @@ ZEND_METHOD(Generator, __debugInfo) ZEND_PARSE_PARAMETERS_NONE(); - generator = (zend_generator *) Z_OBJ_P(ZEND_THIS); + generator = zend_generator_from_obj(Z_OBJ_P(ZEND_THIS)); array_init(return_value); @@ -1105,7 +1106,7 @@ static void zend_generator_iterator_dtor(zend_object_iterator *iterator) /* {{{ static zend_result zend_generator_iterator_valid(zend_object_iterator *iterator) /* {{{ */ { - zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(iterator->data)); zend_generator_ensure_initialized(generator); @@ -1117,7 +1118,7 @@ static zend_result zend_generator_iterator_valid(zend_object_iterator *iterator) static zval *zend_generator_iterator_get_data(zend_object_iterator *iterator) /* {{{ */ { - zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data), *root; + zend_generator *generator = zend_generator_from_obj(Z_OBJ(iterator->data)), *root; zend_generator_ensure_initialized(generator); @@ -1129,7 +1130,7 @@ static zval *zend_generator_iterator_get_data(zend_object_iterator *iterator) /* static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval *key) /* {{{ */ { - zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data), *root; + zend_generator *generator = zend_generator_from_obj(Z_OBJ(iterator->data)), *root; zend_generator_ensure_initialized(generator); @@ -1147,7 +1148,7 @@ static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval static void zend_generator_iterator_move_forward(zend_object_iterator *iterator) /* {{{ */ { - zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(iterator->data)); zend_generator_ensure_initialized(generator); @@ -1157,7 +1158,7 @@ static void zend_generator_iterator_move_forward(zend_object_iterator *iterator) static void zend_generator_iterator_rewind(zend_object_iterator *iterator) /* {{{ */ { - zend_generator *generator = (zend_generator*)Z_OBJ(iterator->data); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(iterator->data)); zend_generator_rewind(generator); } @@ -1186,7 +1187,7 @@ static const zend_object_iterator_funcs zend_generator_iterator_functions = { static zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref) /* {{{ */ { zend_object_iterator *iterator; - zend_generator *generator = (zend_generator*)Z_OBJ_P(object); + zend_generator *generator = zend_generator_from_obj(Z_OBJ_P(object)); if (!generator->execute_data) { zend_throw_exception(NULL, "Cannot traverse an already closed generator", 0); @@ -1217,6 +1218,7 @@ void zend_register_generator_ce(void) /* {{{ */ zend_ce_generator->default_object_handlers = &zend_generator_handlers; memcpy(&zend_generator_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + zend_generator_handlers.offset = XtOffsetOf(zend_generator, std); zend_generator_handlers.free_obj = zend_generator_free_storage; zend_generator_handlers.dtor_obj = zend_generator_dtor_storage; zend_generator_handlers.get_gc = zend_generator_get_gc; diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index e7b01fb20ad7f..5625f621b5f87 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -56,8 +56,6 @@ struct _zend_generator_node { }; struct _zend_generator { - zend_object std; - /* The suspended execution context. */ zend_execute_data *execute_data; @@ -94,6 +92,8 @@ struct _zend_generator { /* ZEND_GENERATOR_* flags */ uint8_t flags; + + zend_object std; }; static const uint8_t ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1; @@ -136,6 +136,11 @@ static zend_always_inline zend_generator *zend_generator_get_current(zend_genera HashTable *zend_generator_frame_gc(zend_get_gc_buffer *gc_buffer, zend_generator *generator); +static zend_always_inline zend_generator *zend_generator_from_obj(zend_object *obj) +{ + return (zend_generator *) ((char *) obj - XtOffsetOf(zend_generator, std)); +} + END_EXTERN_C() #endif diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7e471b5acd8b6..17dd25e0ceae5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4620,7 +4620,7 @@ ZEND_VM_HANDLER(139, ZEND_GENERATOR_CREATE, ANY, ANY) memcpy(gen_execute_data, execute_data, used_stack); /* Save execution context in generator object. */ - generator = (zend_generator *) Z_OBJ_P(EX(return_value)); + generator = zend_generator_from_obj(Z_OBJ_P(EX(return_value))); generator->func = gen_execute_data->func; generator->execute_data = gen_execute_data; generator->frozen_call_stack = NULL; @@ -8452,7 +8452,7 @@ ZEND_VM_C_LABEL(yield_from_try_again): } else if (OP1_TYPE != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + zend_generator *new_gen = zend_generator_from_obj(Z_OBJ_P(val)); Z_ADDREF_P(val); FREE_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9209399a5cdbf..efab10ee365ca 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2237,7 +2237,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER( memcpy(gen_execute_data, execute_data, used_stack); /* Save execution context in generator object. */ - generator = (zend_generator *) Z_OBJ_P(EX(return_value)); + generator = zend_generator_from_obj(Z_OBJ_P(EX(return_value))); generator->func = gen_execute_data->func; generator->execute_data = gen_execute_data; generator->frozen_call_stack = NULL; @@ -5807,7 +5807,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER( } else if (IS_CONST != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + zend_generator *new_gen = zend_generator_from_obj(Z_OBJ_P(val)); Z_ADDREF_P(val); @@ -15411,7 +15411,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + zend_generator *new_gen = zend_generator_from_obj(Z_OBJ_P(val)); Z_ADDREF_P(val); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -41508,7 +41508,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN } else if (IS_CV != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { zend_class_entry *ce = Z_OBJCE_P(val); if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + zend_generator *new_gen = zend_generator_from_obj(Z_OBJ_P(val)); Z_ADDREF_P(val); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index f5e463699b1b5..cf92ddd0a42c6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2255,7 +2255,7 @@ ZEND_METHOD(ReflectionGenerator, __construct) ZEND_METHOD(ReflectionGenerator, getTrace) { zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_generator *root_generator; zend_execute_data *ex_backup = EG(current_execute_data); zend_execute_data *ex = generator->execute_data; @@ -2290,7 +2290,7 @@ ZEND_METHOD(ReflectionGenerator, getTrace) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getExecutingLine) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2304,7 +2304,7 @@ ZEND_METHOD(ReflectionGenerator, getExecutingLine) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getExecutingFile) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2318,7 +2318,7 @@ ZEND_METHOD(ReflectionGenerator, getExecutingFile) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getFunction) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_function *func = generator->func; ZEND_PARSE_PARAMETERS_NONE(); @@ -2338,7 +2338,7 @@ ZEND_METHOD(ReflectionGenerator, getFunction) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getThis) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); @@ -2356,7 +2356,7 @@ ZEND_METHOD(ReflectionGenerator, getThis) /* {{{ */ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_execute_data *ex = generator->execute_data; zend_generator *current; @@ -2371,7 +2371,7 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator) ZEND_METHOD(ReflectionGenerator, isClosed) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); + zend_generator *generator = zend_generator_from_obj(Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj)); zend_execute_data *ex = generator->execute_data; ZEND_PARSE_PARAMETERS_NONE(); diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 1fa15ecdb0cc5..7c34a29509846 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1007,7 +1007,7 @@ PHPDBG_COMMAND(generator) /* {{{ */ i = param->num; zend_object **obj = EG(objects_store).object_buckets + i; if (i < EG(objects_store).top && *obj && IS_OBJ_VALID(*obj) && (*obj)->ce == zend_ce_generator) { - zend_generator *gen = (zend_generator *) *obj; + zend_generator *gen = zend_generator_from_obj(*obj); if (gen->execute_data) { if (zend_generator_get_current(gen)->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { phpdbg_error("Generator currently running"); @@ -1024,7 +1024,7 @@ PHPDBG_COMMAND(generator) /* {{{ */ for (i = 0; i < EG(objects_store).top; i++) { zend_object *obj = EG(objects_store).object_buckets[i]; if (obj && IS_OBJ_VALID(obj) && obj->ce == zend_ce_generator) { - zend_generator *gen = (zend_generator *) obj, *current = zend_generator_get_current(gen); + zend_generator *gen = zend_generator_from_obj(obj), *current = zend_generator_get_current(gen); if (gen->execute_data) { zend_string *s = phpdbg_compile_stackframe(gen->execute_data); phpdbg_out("#%d: %.*s", i, (int) ZSTR_LEN(s), ZSTR_VAL(s));