php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_interfaces.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Marcus Boerger <helly@php.net> |
16 +----------------------------------------------------------------------+
17*/
18
19#include "zend.h"
20#include "zend_API.h"
21#include "zend_interfaces.h"
22#include "zend_exceptions.h"
24#include "zend_property_hooks.h"
25
34
35static zend_object_handlers zend_internal_iterator_handlers;
36
37/* {{{ zend_call_method
38 Only returns the returned zval if retval_ptr != NULL */
39ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, uint32_t param_count, zval* arg1, zval* arg2)
40{
41 zend_function *fn;
42 zend_class_entry *called_scope;
43 zval params[2];
44
45 if (param_count > 0) {
46 ZVAL_COPY_VALUE(&params[0], arg1);
47 }
48 if (param_count > 1) {
49 ZVAL_COPY_VALUE(&params[1], arg2);
50 }
51
52 if (!obj_ce) {
53 obj_ce = object ? object->ce : NULL;
54 }
55 if (!fn_proxy || !*fn_proxy) {
56 if (EXPECTED(obj_ce)) {
58 &obj_ce->function_table, function_name, function_name_len);
59 if (UNEXPECTED(fn == NULL)) {
60 /* error at c-level */
61 zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name);
62 }
63 } else {
64 fn = zend_fetch_function_str(function_name, function_name_len);
65 if (UNEXPECTED(fn == NULL)) {
66 /* error at c-level */
67 zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
68 }
69 }
70 if (fn_proxy) {
71 *fn_proxy = fn;
72 }
73 } else {
74 fn = *fn_proxy;
75 }
76
77 if (object) {
78 called_scope = object->ce;
79 } else {
80 called_scope = obj_ce;
81 }
82
83 zend_call_known_function(fn, object, called_scope, retval_ptr, param_count, params, NULL);
84 return retval_ptr;
85}
86/* }}} */
87
88/* iterator interface, c-level functions used by engine */
89
90/* {{{ zend_user_it_new_iterator */
92{
93 zend_call_known_instance_method_with_0_params(
95}
96/* }}} */
97
98/* {{{ zend_user_it_invalidate_current */
100{
102
103 if (!Z_ISUNDEF(iter->value)) {
104 zval_ptr_dtor(&iter->value);
105 ZVAL_UNDEF(&iter->value);
106 }
107}
108/* }}} */
109
110/* {{{ zend_user_it_dtor */
111static void zend_user_it_dtor(zend_object_iterator *_iter)
112{
114 zval *object = &iter->it.data;
115
117 zval_ptr_dtor(object);
118}
119/* }}} */
120
121/* {{{ zend_user_it_valid */
123{
124 if (_iter) {
126 zval *object = &iter->it.data;
127 zval more;
128
129 zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_valid, Z_OBJ_P(object), &more);
130 bool result = i_zend_is_true(&more);
131 zval_ptr_dtor(&more);
132 return result ? SUCCESS : FAILURE;
133 }
134 return FAILURE;
135}
136/* }}} */
137
138/* {{{ zend_user_it_get_current_data */
140{
142 zval *object = &iter->it.data;
143
144 if (Z_ISUNDEF(iter->value)) {
145 zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_current, Z_OBJ_P(object), &iter->value);
146 }
147 return &iter->value;
148}
149/* }}} */
150
151/* {{{ zend_user_it_get_current_key */
153{
155 zval *object = &iter->it.data;
156 zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_key, Z_OBJ_P(object), key);
157 if (UNEXPECTED(Z_ISREF_P(key))) {
158 zend_unwrap_reference(key);
159 }
160}
161/* }}} */
162
163/* {{{ zend_user_it_move_forward */
165{
167 zval *object = &iter->it.data;
168
170 zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_next, Z_OBJ_P(object), NULL);
171}
172/* }}} */
173
174/* {{{ zend_user_it_rewind */
176{
178 zval *object = &iter->it.data;
179
181 zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_rewind, Z_OBJ_P(object), NULL);
182}
183/* }}} */
184
186{
188 if (Z_ISUNDEF(iter->value)) {
189 *table = &iter->it.data;
190 *n = 1;
191 } else {
193 zend_get_gc_buffer_add_zval(gc_buffer, &iter->it.data);
194 zend_get_gc_buffer_add_zval(gc_buffer, &iter->value);
195 zend_get_gc_buffer_use(gc_buffer, table, n);
196 }
197 return NULL;
198}
199
200static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = {
201 zend_user_it_dtor,
209};
210
211/* {{{ zend_user_it_get_iterator */
212/* by_ref is int due to Iterator API */
213static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zval *object, int by_ref)
214{
215 zend_user_iterator *iterator;
216
217 if (by_ref) {
218 zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
219 return NULL;
220 }
221
222 iterator = emalloc(sizeof(zend_user_iterator));
223
225
226 ZVAL_OBJ_COPY(&iterator->it.data, Z_OBJ_P(object));
227 iterator->it.funcs = &zend_interface_iterator_funcs_iterator;
228 iterator->ce = Z_OBJCE_P(object);
229 ZVAL_UNDEF(&iterator->value);
230 return (zend_object_iterator*)iterator;
231}
232/* }}} */
233
234/* {{{ zend_user_it_get_new_iterator */
235/* by_ref is int due to Iterator API */
237{
238 zval iterator;
239 zend_object_iterator *new_iterator;
240 zend_class_entry *ce_it;
241
242 zend_user_it_new_iterator(ce, object, &iterator);
243 ce_it = (Z_TYPE(iterator) == IS_OBJECT) ? Z_OBJCE(iterator) : NULL;
244
245 if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && Z_OBJ(iterator) == Z_OBJ_P(object))) {
246 if (!EG(exception)) {
247 zend_throw_exception_ex(NULL, 0, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ZSTR_VAL(ce->name) : ZSTR_VAL(Z_OBJCE_P(object)->name));
248 }
249 zval_ptr_dtor(&iterator);
250 return NULL;
251 }
252
253 new_iterator = ce_it->get_iterator(ce_it, &iterator, by_ref);
254 zval_ptr_dtor(&iterator);
255 return new_iterator;
256}
257/* }}} */
258
259/* {{{ zend_implement_traversable */
260static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type)
261{
262 /* Abstract class can implement Traversable only, in which case the extending class must
263 * implement Iterator or IteratorAggregate. */
264 if (class_type->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
265 return SUCCESS;
266 }
267
268 /* Check that class_type implements at least one of 'IteratorAggregate' or 'Iterator' */
269 if (class_type->num_interfaces) {
271 for (uint32_t i = 0; i < class_type->num_interfaces; i++) {
272 if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
273 return SUCCESS;
274 }
275 }
276 }
277 zend_error_noreturn(E_CORE_ERROR, "%s %s must implement interface %s as part of either %s or %s",
278 zend_get_object_type_uc(class_type),
279 ZSTR_VAL(class_type->name),
283 return FAILURE;
284}
285/* }}} */
286
287/* {{{ zend_implement_aggregate */
288static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type)
289{
292 "Class %s cannot implement both Iterator and IteratorAggregate at the same time",
293 ZSTR_VAL(class_type->name));
294 }
295
296 /* Always initialize iterator_funcs_ptr. */
297 ZEND_ASSERT(!class_type->iterator_funcs_ptr && "Iterator funcs already set?");
298 zend_class_iterator_funcs *funcs_ptr = class_type->type == ZEND_INTERNAL_CLASS
300 : zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
301 class_type->iterator_funcs_ptr = funcs_ptr;
302
303 memset(funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
304 funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(
305 &class_type->function_table, "getiterator", sizeof("getiterator") - 1);
306
307 if (class_type->get_iterator
310 /* get_iterator was explicitly assigned for an internal class. */
311 if (!class_type->parent || class_type->parent->get_iterator != class_type->get_iterator) {
312 ZEND_ASSERT(class_type->type == ZEND_INTERNAL_CLASS);
313 return SUCCESS;
314 }
315
316 /* The getIterator() method has not been overwritten, use inherited get_iterator(). */
317 if (funcs_ptr->zf_new_iterator->common.scope != class_type) {
318 return SUCCESS;
319 }
320
321 /* getIterator() has been overwritten, switch to zend_user_it_get_new_iterator. */
322 }
323
325 return SUCCESS;
326}
327/* }}} */
328
329/* {{{ zend_implement_iterator */
330static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type)
331{
334 "Class %s cannot implement both Iterator and IteratorAggregate at the same time",
335 ZSTR_VAL(class_type->name));
336 }
337
338 ZEND_ASSERT(!class_type->iterator_funcs_ptr && "Iterator funcs already set?");
339 zend_class_iterator_funcs *funcs_ptr = class_type->type == ZEND_INTERNAL_CLASS
341 : zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
342 class_type->iterator_funcs_ptr = funcs_ptr;
343
344 memset(funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
345 funcs_ptr->zf_rewind = zend_hash_str_find_ptr(
346 &class_type->function_table, "rewind", sizeof("rewind") - 1);
347 funcs_ptr->zf_valid = zend_hash_str_find_ptr(
348 &class_type->function_table, "valid", sizeof("valid") - 1);
349 funcs_ptr->zf_key = zend_hash_find_ptr(
350 &class_type->function_table, ZSTR_KNOWN(ZEND_STR_KEY));
351 funcs_ptr->zf_current = zend_hash_str_find_ptr(
352 &class_type->function_table, "current", sizeof("current") - 1);
353 funcs_ptr->zf_next = zend_hash_str_find_ptr(
354 &class_type->function_table, "next", sizeof("next") - 1);
355
356 if (class_type->get_iterator
357 && class_type->get_iterator != zend_user_it_get_iterator
359 if (!class_type->parent || class_type->parent->get_iterator != class_type->get_iterator) {
360 /* get_iterator was explicitly assigned for an internal class. */
361 ZEND_ASSERT(class_type->type == ZEND_INTERNAL_CLASS);
362 return SUCCESS;
363 }
364
365 /* None of the Iterator methods have been overwritten, use inherited get_iterator(). */
366 if (funcs_ptr->zf_rewind->common.scope != class_type &&
367 funcs_ptr->zf_valid->common.scope != class_type &&
368 funcs_ptr->zf_key->common.scope != class_type &&
369 funcs_ptr->zf_current->common.scope != class_type &&
370 funcs_ptr->zf_next->common.scope != class_type) {
371 return SUCCESS;
372 }
373
374 /* One of the Iterator methods has been overwritten,
375 * switch to zend_user_it_get_iterator. */
376 }
377
378 class_type->get_iterator = zend_user_it_get_iterator;
379 return SUCCESS;
380}
381/* }}} */
382
383/* {{{ zend_implement_arrayaccess */
384static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type)
385{
386 ZEND_ASSERT(!class_type->arrayaccess_funcs_ptr && "ArrayAccess funcs already set?");
387 zend_class_arrayaccess_funcs *funcs_ptr = class_type->type == ZEND_INTERNAL_CLASS
389 : zend_arena_alloc(&CG(arena), sizeof(zend_class_arrayaccess_funcs));
390 class_type->arrayaccess_funcs_ptr = funcs_ptr;
391
392 funcs_ptr->zf_offsetget = zend_hash_str_find_ptr(
393 &class_type->function_table, "offsetget", sizeof("offsetget") - 1);
394 funcs_ptr->zf_offsetexists = zend_hash_str_find_ptr(
395 &class_type->function_table, "offsetexists", sizeof("offsetexists") - 1);
396 funcs_ptr->zf_offsetset = zend_hash_str_find_ptr(
397 &class_type->function_table, "offsetset", sizeof("offsetset") - 1);
398 funcs_ptr->zf_offsetunset = zend_hash_str_find_ptr(
399 &class_type->function_table, "offsetunset", sizeof("offsetunset") - 1);
400
401 return SUCCESS;
402}
403/* }}} */
404
405/* {{{ zend_user_serialize */
406ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data)
407{
408 zend_class_entry * ce = Z_OBJCE_P(object);
409 zval retval;
411
412 zend_call_method_with_0_params(
413 Z_OBJ_P(object), Z_OBJCE_P(object), NULL, "serialize", &retval);
414
415 if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
416 result = FAILURE;
417 } else {
418 switch(Z_TYPE(retval)) {
419 case IS_NULL:
420 /* we could also make this '*buf_len = 0' but this allows to skip variables */
422 return FAILURE;
423 case IS_STRING:
424 *buffer = (unsigned char*)estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
425 *buf_len = Z_STRLEN(retval);
426 result = SUCCESS;
427 break;
428 default: /* failure */
429 result = FAILURE;
430 break;
431 }
433 }
434
435 if (result == FAILURE && !EG(exception)) {
436 zend_throw_exception_ex(NULL, 0, "%s::serialize() must return a string or NULL", ZSTR_VAL(ce->name));
437 }
438 return result;
439}
440/* }}} */
441
442/* {{{ zend_user_unserialize */
443ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data)
444{
445 zval zdata;
446
447 if (UNEXPECTED(object_init_ex(object, ce) != SUCCESS)) {
448 return FAILURE;
449 }
450
451 ZVAL_STRINGL(&zdata, (char*)buf, buf_len);
452 zend_call_method_with_1_params(
453 Z_OBJ_P(object), Z_OBJCE_P(object), NULL, "unserialize", NULL, &zdata);
454 zval_ptr_dtor(&zdata);
455
456 if (EG(exception)) {
457 return FAILURE;
458 } else {
459 return SUCCESS;
460 }
461}
462/* }}} */
463
464/* {{{ zend_implement_serializable */
465static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type)
466{
467 if (class_type->parent
468 && (class_type->parent->serialize || class_type->parent->unserialize)
470 return FAILURE;
471 }
472 if (!class_type->serialize) {
473 class_type->serialize = zend_user_serialize;
474 }
475 if (!class_type->unserialize) {
477 }
478 if (!(class_type->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)
479 && (!class_type->__serialize || !class_type->__unserialize)) {
480 zend_error(E_DEPRECATED, "%s implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary)", ZSTR_VAL(class_type->name));
481 if (EG(exception)) {
483 "During inheritance of %s, while implementing Serializable", ZSTR_VAL(class_type->name));
484 }
485 }
486 return SUCCESS;
487}
488/* }}}*/
489
495
496static zend_object *zend_internal_iterator_create(zend_class_entry *ce) {
498 zend_object_std_init(&intern->std, ce);
499 intern->iter = NULL;
500 intern->rewind_called = 0;
501 return &intern->std;
502}
503
505 zend_class_entry *scope = EG(current_execute_data)->func->common.scope;
507 zend_object_iterator *iter = scope->get_iterator(Z_OBJCE_P(obj), obj, /* by_ref */ 0);
508 if (!iter) {
509 return FAILURE;
510 }
511
512 zend_internal_iterator *intern =
513 (zend_internal_iterator *) zend_internal_iterator_create(zend_ce_internal_iterator);
514 intern->iter = iter;
515 intern->iter->index = 0;
516 ZVAL_OBJ(return_value, &intern->std);
517 return SUCCESS;
518}
519
520static void zend_internal_iterator_free(zend_object *obj) {
522 if (intern->iter) {
523 zend_iterator_dtor(intern->iter);
524 }
525 zend_object_std_dtor(&intern->std);
526}
527
528static zend_internal_iterator *zend_internal_iterator_fetch(zval *This) {
530 if (!intern->iter) {
531 zend_throw_error(NULL, "The InternalIterator object has not been properly initialized");
532 return NULL;
533 }
534 return intern;
535}
536
537/* Many iterators will not behave correctly if rewind() is not called, make sure it happens. */
538static zend_result zend_internal_iterator_ensure_rewound(zend_internal_iterator *intern) {
539 if (!intern->rewind_called) {
540 zend_object_iterator *iter = intern->iter;
541 intern->rewind_called = 1;
542 if (iter->funcs->rewind) {
543 iter->funcs->rewind(iter);
544 if (UNEXPECTED(EG(exception))) {
545 return FAILURE;
546 }
547 }
548 }
549 return SUCCESS;
550}
551
552
554 zend_throw_error(NULL, "Cannot manually construct InternalIterator");
555}
556
559
560 zend_internal_iterator *intern = zend_internal_iterator_fetch(ZEND_THIS);
561 if (!intern) {
563 }
564
565 if (zend_internal_iterator_ensure_rewound(intern) == FAILURE) {
567 }
568
569 zval *data = intern->iter->funcs->get_current_data(intern->iter);
570 if (data) {
572 }
573}
574
577
578 zend_internal_iterator *intern = zend_internal_iterator_fetch(ZEND_THIS);
579 if (!intern) {
581 }
582
583 if (zend_internal_iterator_ensure_rewound(intern) == FAILURE) {
585 }
586
587 if (intern->iter->funcs->get_current_key) {
588 intern->iter->funcs->get_current_key(intern->iter, return_value);
589 } else {
590 RETURN_LONG(intern->iter->index);
591 }
592}
593
596
597 zend_internal_iterator *intern = zend_internal_iterator_fetch(ZEND_THIS);
598 if (!intern) {
600 }
601
602 if (zend_internal_iterator_ensure_rewound(intern) == FAILURE) {
604 }
605
606 /* Advance index first to match foreach behavior. */
607 intern->iter->index++;
608 intern->iter->funcs->move_forward(intern->iter);
609}
610
613
614 zend_internal_iterator *intern = zend_internal_iterator_fetch(ZEND_THIS);
615 if (!intern) {
617 }
618
619 if (zend_internal_iterator_ensure_rewound(intern) == FAILURE) {
621 }
622
623 RETURN_BOOL(intern->iter->funcs->valid(intern->iter) == SUCCESS);
624}
625
628
629 zend_internal_iterator *intern = zend_internal_iterator_fetch(ZEND_THIS);
630 if (!intern) {
632 }
633
634 intern->rewind_called = 1;
635 if (!intern->iter->funcs->rewind) {
636 /* Allow calling rewind() if no iteration has happened yet,
637 * even if the iterator does not support rewinding. */
638 if (intern->iter->index != 0) {
639 zend_throw_error(NULL, "Iterator does not support rewinding");
641 }
642 intern->iter->index = 0;
643 return;
644 }
645
646 intern->iter->funcs->rewind(intern->iter);
647 intern->iter->index = 0;
648}
649
650/* {{{ zend_register_interfaces */
652{
653 zend_ce_traversable = register_class_Traversable();
654 zend_ce_traversable->interface_gets_implemented = zend_implement_traversable;
655
656 zend_ce_aggregate = register_class_IteratorAggregate(zend_ce_traversable);
657 zend_ce_aggregate->interface_gets_implemented = zend_implement_aggregate;
658
659 zend_ce_iterator = register_class_Iterator(zend_ce_traversable);
660 zend_ce_iterator->interface_gets_implemented = zend_implement_iterator;
661
662 zend_ce_serializable = register_class_Serializable();
663 zend_ce_serializable->interface_gets_implemented = zend_implement_serializable;
664
665 zend_ce_arrayaccess = register_class_ArrayAccess();
666 zend_ce_arrayaccess->interface_gets_implemented = zend_implement_arrayaccess;
667
668 zend_ce_countable = register_class_Countable();
669
670 zend_ce_stringable = register_class_Stringable();
671
672 zend_ce_internal_iterator = register_class_InternalIterator(zend_ce_iterator);
673 zend_ce_internal_iterator->create_object = zend_internal_iterator_create;
674 zend_ce_internal_iterator->default_object_handlers = &zend_internal_iterator_handlers;
675
676 memcpy(&zend_internal_iterator_handlers, zend_get_std_object_handlers(),
677 sizeof(zend_object_handlers));
678 zend_internal_iterator_handlers.clone_obj = NULL;
679 zend_internal_iterator_handlers.free_obj = zend_internal_iterator_free;
680}
681/* }}} */
bool exception
Definition assert.c:30
sizeof(Countable|array $value, int $mode=COUNT_NORMAL)
rewind($stream)
zend_long n
Definition ffi.c:4979
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
#define next(ls)
Definition minilua.c:2661
char * arena
Definition php_bcmath.h:37
unsigned char key[REFLECTION_KEY_LEN]
zend_constant * data
zval * current
Definition session.c:1024
zend_class_iterator_funcs * iterator_funcs_ptr
Definition zend.h:189
zend_object_iterator *(* get_iterator)(zend_class_entry *ce, zval *object, int by_ref)
Definition zend.h:198
zend_function * __unserialize
Definition zend.h:184
zend_string * name
Definition zend.h:149
uint32_t num_interfaces
Definition zend.h:205
zend_class_arrayaccess_funcs * arrayaccess_funcs_ptr
Definition zend.h:191
uint32_t ce_flags
Definition zend.h:156
zend_function * __serialize
Definition zend.h:183
char type
Definition zend.h:148
zend_class_entry ** interfaces
Definition zend.h:212
zend_class_entry * parent
Definition zend.h:152
int(* serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data)
Definition zend.h:202
HashTable function_table
Definition zend.h:163
int(* unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data)
Definition zend.h:203
zend_function * zf_new_iterator
void(* get_current_key)(zend_object_iterator *iter, zval *key)
void(* rewind)(zend_object_iterator *iter)
void(* move_forward)(zend_object_iterator *iter)
zend_result(* valid)(zend_object_iterator *iter)
zval *(* get_current_data)(zend_object_iterator *iter)
const zend_object_iterator_funcs * funcs
zend_object_iterator it
zend_class_entry * ce
Definition file.h:177
zend_object_iterator * iter
zend_class_entry * scope
struct _zend_function::@236135173067030250234125302313220025134003177336 common
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
Definition zend.c:1703
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
struct _zend_unserialize_data zend_unserialize_data
Definition zend.h:83
struct _zend_serialize_data zend_serialize_data
Definition zend.h:82
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
#define RETURN_COPY_DEREF(zv)
Definition zend_API.h:1056
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETURN_BOOL(b)
Definition zend_API.h:1035
#define ZEND_METHOD(classname, name)
Definition zend_API.h:76
#define RETURN_THROWS()
Definition zend_API.h:1060
#define ZEND_THIS
Definition zend_API.h:523
ZEND_API void zend_call_known_function(zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr, uint32_t param_count, zval *params, HashTable *named_params)
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define estrndup(s, length)
Definition zend_alloc.h:165
#define pemalloc(size, persistent)
Definition zend_alloc.h:189
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
#define ZEND_ACC_RESOLVED_INTERFACES
#define ZEND_INTERNAL_CLASS
#define ZEND_API
#define E_ERROR
Definition zend_errors.h:23
#define E_CORE_ERROR
Definition zend_errors.h:27
#define E_DEPRECATED
Definition zend_errors.h:37
ZEND_NORETURN void zend_exception_uncaught_error(const char *format,...)
ZEND_API ZEND_COLD zend_object * zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format,...)
ZEND_API zend_function *ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len)
union _zend_function zend_function
ZEND_API zend_get_gc_buffer * zend_get_gc_buffer_create(void)
Definition zend_gc.c:2130
#define CG(v)
#define EG(v)
ZEND_API void * zend_hash_str_find_ptr_lc(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:90
ZEND_API zend_class_entry * zend_ce_countable
ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter)
ZEND_API zend_class_entry * zend_ce_iterator
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter)
ZEND_API zend_result zend_user_it_valid(zend_object_iterator *_iter)
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data)
ZEND_API void zend_register_interfaces(void)
ZEND_API zend_class_entry * zend_ce_serializable
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter)
ZEND_API zend_class_entry * zend_ce_traversable
ZEND_API zend_class_entry * zend_ce_stringable
ZEND_API zend_class_entry * zend_ce_arrayaccess
ZEND_API HashTable * zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n)
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data)
ZEND_API zend_object_iterator * zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref)
ZEND_API zend_class_entry * zend_ce_aggregate
ZEND_API zend_result zend_create_internal_iterator_zval(zval *return_value, zval *obj)
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key)
ZEND_API zval * zend_user_it_get_current_data(zend_object_iterator *_iter)
ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *retval)
ZEND_API zval * zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, uint32_t param_count, zval *arg1, zval *arg2)
ZEND_API zend_class_entry * zend_ce_internal_iterator
struct _zend_user_iterator zend_user_iterator
ZEND_API void zend_iterator_init(zend_object_iterator *iter)
ZEND_API void zend_iterator_dtor(zend_object_iterator *iter)
struct _zend_class_arrayaccess_funcs zend_class_arrayaccess_funcs
struct _zend_class_iterator_funcs zend_class_iterator_funcs
struct _zend_object_iterator zend_object_iterator
struct _zend_object_iterator_funcs zend_object_iterator_funcs
#define zend_get_std_object_handlers()
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce)
#define EXPECTED(condition)
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
ZEND_API zend_object_iterator * zend_hooked_object_get_iterator(zend_class_entry *ce, zval *object, int by_ref)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_KNOWN(idx)
#define Z_ISREF_P(zval_p)
Definition zend_types.h:954
#define ZVAL_UNDEF(z)
#define IS_UNDEF
Definition zend_types.h:600
#define IS_STRING
Definition zend_types.h:606
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define Z_ISUNDEF(zval)
Definition zend_types.h:956
#define IS_NULL
Definition zend_types.h:601
#define Z_OBJCE_P(zval_p)
#define ZVAL_OBJ(z, o)
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_STRLEN(zval)
Definition zend_types.h:977
#define IS_OBJECT
Definition zend_types.h:608
#define ZVAL_OBJ_COPY(z, o)
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
struct _zend_object_handlers zend_object_handlers
Definition zend_types.h:88
#define Z_TYPE(zval)
Definition zend_types.h:659
#define ZVAL_COPY_VALUE(z, v)
#define Z_OBJCE(zval)
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval retval
zval * return_value
zval * arg1
zval * arg2
retval_ptr
zend_string * name
bool result
new_op_array scope