Skip to content

Commit 8cc850b

Browse files
committed
Expose initializer zv to gc
1 parent 3007026 commit 8cc850b

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

Zend/zend_lazy_objects.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "zend_API.h"
4040
#include "zend_compile.h"
4141
#include "zend_execute.h"
42+
#include "zend_gc.h"
4243
#include "zend_hash.h"
4344
#include "zend_object_handlers.h"
4445
#include "zend_objects_API.h"
@@ -665,3 +666,39 @@ HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp)
665666
*is_temp = 0;
666667
return zend_get_properties_no_init(object);
667668
}
669+
670+
HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n)
671+
{
672+
ZEND_ASSERT(zend_object_is_lazy(zobj));
673+
674+
zend_lazy_object_info *info = zend_lazy_object_get_info(zobj);
675+
zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
676+
677+
if (zend_lazy_object_initialized(zobj)) {
678+
ZEND_ASSERT(zend_object_is_lazy_proxy(zobj));
679+
zend_get_gc_buffer_add_obj(gc_buffer, info->u.instance);
680+
zend_get_gc_buffer_use(gc_buffer, table, n);
681+
/* Initialized proxy object can not have properties */
682+
return NULL;
683+
}
684+
685+
zend_fcall_info_cache *fcc = &info->u.initializer.fcc;
686+
if (fcc->object) {
687+
zend_get_gc_buffer_add_obj(gc_buffer, fcc->object);
688+
}
689+
if (fcc->closure) {
690+
zend_get_gc_buffer_add_obj(gc_buffer, fcc->closure);
691+
}
692+
zend_get_gc_buffer_add_zval(gc_buffer, &info->u.initializer.zv);
693+
694+
/* Uninitialized lazy objects can not have dynamic properties, so we can
695+
* ignore zobj->properties. */
696+
zval *prop = zobj->properties_table;
697+
zval *end = prop + zobj->ce->default_properties_count;
698+
for ( ; prop < end; prop++) {
699+
zend_get_gc_buffer_add_zval(gc_buffer, prop);
700+
}
701+
702+
zend_get_gc_buffer_use(gc_buffer, table, n);
703+
return NULL;
704+
}

Zend/zend_lazy_objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj);
7474
void zend_lazy_object_del_info(zend_object *obj);
7575
zend_object *zend_lazy_object_clone(zend_object *old_obj);
7676
HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp);
77+
HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n);
7778
bool zend_lazy_object_decr_lazy_props(zend_object *obj);
7879
void zend_lazy_object_realize(zend_object *obj);
7980

Zend/zend_object_handlers.c

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -165,35 +165,7 @@ ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /*
165165
return zobj->handlers->get_properties(zobj);
166166
} else {
167167
if (UNEXPECTED(zend_object_is_lazy(zobj))) {
168-
zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
169-
if (zend_lazy_object_initialized(zobj)) {
170-
ZEND_ASSERT(zend_object_is_lazy_proxy(zobj));
171-
zend_object *instance = zend_lazy_object_get_instance(zobj);
172-
zend_get_gc_buffer_add_obj(gc_buffer, instance);
173-
} else {
174-
zend_fcall_info_cache* initializer = zend_lazy_object_get_initializer_fcc(zobj);
175-
if (initializer) {
176-
// TODO: also expose _get_initializer_zv() to the GC
177-
if (initializer->object) {
178-
zend_get_gc_buffer_add_obj(gc_buffer, initializer->object);
179-
}
180-
if (initializer->closure) {
181-
zend_get_gc_buffer_add_obj(gc_buffer, initializer->closure);
182-
}
183-
}
184-
}
185-
if (zobj->properties) {
186-
zend_get_gc_buffer_use(gc_buffer, table, n);
187-
return zobj->properties;
188-
} else {
189-
zval *prop = zobj->properties_table;
190-
zval *end = prop + zobj->ce->default_properties_count;
191-
for ( ; prop < end; prop++) {
192-
zend_get_gc_buffer_add_zval(gc_buffer, prop);
193-
}
194-
zend_get_gc_buffer_use(gc_buffer, table, n);
195-
return NULL;
196-
}
168+
return zend_lazy_object_get_gc(zobj, table, n);
197169
} else if (zobj->properties) {
198170
*table = NULL;
199171
*n = 0;

0 commit comments

Comments
 (0)