Skip to content

Commit 2bc9bcc

Browse files
committed
wip
1 parent abe3673 commit 2bc9bcc

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,7 @@ ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY)
31253125
if (Z_FE_ITER_P(var) != (uint32_t)-1) {
31263126
zend_hash_iterator_del(Z_FE_ITER_P(var));
31273127
}
3128-
zval_ptr_dtor_nogc(var);
3128+
zval_ptr_dtor(var);
31293129
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
31303130
}
31313131

Zend/zend_vm_execute.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14317,7 +14317,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVA
1431714317
if (Z_FE_ITER_P(var) != (uint32_t)-1) {
1431814318
zend_hash_iterator_del(Z_FE_ITER_P(var));
1431914319
}
14320-
zval_ptr_dtor_nogc(var);
14320+
zval_ptr_dtor(var);
1432114321
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1432214322
}
1432314323

ext/intl/breakiterator/breakiterator_iterators.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
231231
ii->iterator->index = 0;
232232

233233
((zoi_with_current*)ii->iterator)->destroy_it = _breakiterator_parts_destroy_it;
234+
// TODO ???
234235
ZVAL_OBJ(&((zoi_with_current*)ii->iterator)->wrapping_obj, Z_OBJ_P(object));
235236
ZVAL_UNDEF(&((zoi_with_current*)ii->iterator)->current);
236237

ext/intl/common/common_enum.cpp

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ extern "C" {
3232
zend_class_entry *IntlIterator_ce_ptr;
3333
zend_object_handlers IntlIterator_handlers;
3434

35+
static void zoi_with_current_destroy_self(zend_object_iterator *iter, zoi_with_current *zoiwc)
36+
{
37+
/* Object not here anymore (we've been called by the object free handler)
38+
* Note that the iterator wrapper objects (that also depend on this
39+
* structure) call this function earlier, in the destruction phase, which
40+
* precedes the object free phase. Therefore there's no risk on this
41+
* function being called by the iterator wrapper destructor function and
42+
* not finding the memory of this iterator allocated anymore. */
43+
iter->funcs->invalidate_current(iter);
44+
zoiwc->destroy_it(iter);
45+
}
46+
3547
void zoi_with_current_dtor(zend_object_iterator *iter)
3648
{
3749
zoi_with_current *zoiwc = (zoi_with_current*)iter;
@@ -44,15 +56,14 @@ void zoi_with_current_dtor(zend_object_iterator *iter)
4456
/* object is still here, we can rely on it to call this again and
4557
* destroy this object */
4658
zval_ptr_dtor(zwo);
59+
60+
/* We may only invalidate and destroy if this was actually the last instance.
61+
* If it was, then IntlIterator_objects_free() will have set zwo to UNDEF. */
62+
if (Z_ISUNDEF_P(zwo)) {
63+
zoi_with_current_destroy_self(iter, zoiwc);
64+
}
4765
} else {
48-
/* Object not here anymore (we've been called by the object free handler)
49-
* Note that the iterator wrapper objects (that also depend on this
50-
* structure) call this function earlier, in the destruction phase, which
51-
* precedes the object free phase. Therefore there's no risk on this
52-
* function being called by the iterator wrapper destructor function and
53-
* not finding the memory of this iterator allocated anymore. */
54-
iter->funcs->invalidate_current(iter);
55-
zoiwc->destroy_it(iter);
66+
zoi_with_current_destroy_self(iter, zoiwc);
5667
}
5768
}
5869

@@ -126,6 +137,17 @@ static void string_enum_destroy_it(zend_object_iterator *iter)
126137
delete (StringEnumeration*)Z_PTR(iter->data);
127138
}
128139

140+
static HashTable *string_enum_get_gc(zend_object_iterator *object, zval **table, int *n)
141+
{
142+
printf("get gc\n");
143+
zoi_with_current *zoiwc = (zoi_with_current *) object;
144+
145+
*table = &zoiwc->wrapping_obj;
146+
*n = 1;
147+
148+
return NULL;
149+
}
150+
129151
static const zend_object_iterator_funcs string_enum_object_iterator_funcs = {
130152
zoi_with_current_dtor,
131153
zoi_with_current_valid,
@@ -134,7 +156,7 @@ static const zend_object_iterator_funcs string_enum_object_iterator_funcs = {
134156
string_enum_current_move_forward,
135157
string_enum_rewind,
136158
zoi_with_current_invalidate_current,
137-
NULL, /* get_gc */
159+
string_enum_get_gc,
138160
};
139161

140162
U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *object)
@@ -148,7 +170,7 @@ U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *ob
148170
ii->iterator->funcs = &string_enum_object_iterator_funcs;
149171
ii->iterator->index = 0;
150172
((zoi_with_current*)ii->iterator)->destroy_it = string_enum_destroy_it;
151-
ZVAL_OBJ(&((zoi_with_current*)ii->iterator)->wrapping_obj, Z_OBJ_P(object));
173+
ZVAL_OBJ_COPY(&((zoi_with_current*)ii->iterator)->wrapping_obj, Z_OBJ_P(object));
152174
ZVAL_UNDEF(&((zoi_with_current*)ii->iterator)->current);
153175
}
154176

@@ -166,6 +188,26 @@ static void IntlIterator_objects_free(zend_object *object)
166188
zend_object_std_dtor(&ii->zo);
167189
}
168190

191+
static HashTable *IntlIterator_get_gc(zend_object *object, zval **table, int *n)
192+
{
193+
printf("iterator get gc\n");
194+
IntlIterator_object *ii = php_intl_iterator_fetch_object(object);
195+
196+
if (ii->iterator) {
197+
zend_get_gc_buffer *gc = zend_get_gc_buffer_create();
198+
zend_get_gc_buffer_add_obj(gc, &ii->iterator->std);
199+
/* current can't participate in a cycle */
200+
zend_get_gc_buffer_use(gc, table, n);
201+
202+
// TODO: can be optimized
203+
return zend_std_get_properties(object);
204+
} else {
205+
*table = NULL;
206+
*n = 0;
207+
return zend_std_get_gc(object, table, n);
208+
}
209+
}
210+
169211
static zend_object_iterator *IntlIterator_get_iterator(
170212
zend_class_entry *ce, zval *object, int by_ref)
171213
{
@@ -298,5 +340,5 @@ U_CFUNC void intl_register_IntlIterator_class(void)
298340
IntlIterator_handlers.offset = XtOffsetOf(IntlIterator_object, zo);
299341
IntlIterator_handlers.clone_obj = NULL;
300342
IntlIterator_handlers.free_obj = IntlIterator_objects_free;
301-
343+
IntlIterator_handlers.get_gc = IntlIterator_get_gc;
302344
}

0 commit comments

Comments
 (0)