Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zend_generator: Fix zend_object std layout for zend_generator (draft)(cannot-pass-tests) #17636

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/zend_execute.c
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion Zend/zend_fibers.c
Original file line number Diff line number Diff line change
@@ -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,
46 changes: 24 additions & 22 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
@@ -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;
9 changes: 7 additions & 2 deletions Zend/zend_generators.h
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
@@ -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();
8 changes: 4 additions & 4 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions ext/reflection/php_reflection.c
Original file line number Diff line number Diff line change
@@ -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();
4 changes: 2 additions & 2 deletions sapi/phpdbg/phpdbg_prompt.c
Original file line number Diff line number Diff line change
@@ -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));