php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_builtin_functions.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: Andi Gutmans <andi@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 +----------------------------------------------------------------------+
18*/
19
20#include "zend.h"
21#include "zend_API.h"
22#include "zend_attributes.h"
23#include "zend_gc.h"
25#include "zend_constants.h"
26#include "zend_ini.h"
27#include "zend_interfaces.h"
28#include "zend_exceptions.h"
29#include "zend_extensions.h"
30#include "zend_closures.h"
31#include "zend_generators.h"
33#include "zend_smart_str.h"
34
35/* }}} */
36
37ZEND_MINIT_FUNCTION(core) { /* {{{ */
39
40 zend_standard_class_def = register_class_stdClass();
41
42 return SUCCESS;
43}
44/* }}} */
45
46static zend_module_entry zend_builtin_module = { /* {{{ */
48 "Core",
49 ext_functions,
50 ZEND_MINIT(core),
51 NULL,
52 NULL,
53 NULL,
54 NULL,
57};
58/* }}} */
59
61{
62 zend_module_entry *module;
63 EG(current_module) = module = zend_register_module_ex(&zend_builtin_module, MODULE_PERSISTENT);
64 if (UNEXPECTED(module == NULL)) {
65 return FAILURE;
66 }
67 ZEND_ASSERT(module->module_number == 0);
68 return SUCCESS;
69}
70/* }}} */
71
73{
74 zend_string *str = NULL;
75 zend_long status = 0;
76
81
82 if (str) {
83 size_t len = ZSTR_LEN(str);
84 if (len != 0) {
85 /* An exception might be emitted by an output handler */
86 zend_write(ZSTR_VAL(str), len);
87 if (EG(exception)) {
89 }
90 }
91 } else {
92 EG(exit_status) = status;
93 }
94
97}
98
99/* {{{ Get the version of the Zend Engine */
106/* }}} */
107
108/* {{{ Reclaims memory used by MM caches.
109 Returns number of freed bytes */
116/* }}} */
117
118/* {{{ Forces collection of any existing garbage cycles.
119 Returns number of freed zvals */
126/* }}} */
127
128/* {{{ Returns status of the circular reference collector */
135/* }}} */
136
137/* {{{ Activates the circular reference collector */
148/* }}} */
149
150/* {{{ Deactivates the circular reference collector */
161/* }}} */
162
163/* {{{ Returns current GC statistics */
165{
167
169
171
173
174 add_assoc_bool_ex(return_value, "running", sizeof("running")-1, status.active);
175 add_assoc_bool_ex(return_value, "protected", sizeof("protected")-1, status.gc_protected);
176 add_assoc_bool_ex(return_value, "full", sizeof("full")-1, status.full);
177 add_assoc_long_ex(return_value, "runs", sizeof("runs")-1, (long)status.runs);
178 add_assoc_long_ex(return_value, "collected", sizeof("collected")-1, (long)status.collected);
179 add_assoc_long_ex(return_value, "threshold", sizeof("threshold")-1, (long)status.threshold);
180 add_assoc_long_ex(return_value, "buffer_size", sizeof("buffer_size")-1, (long)status.buf_size);
181 add_assoc_long_ex(return_value, "roots", sizeof("roots")-1, (long)status.num_roots);
182
183 /* Using double because zend_long may be too small on some platforms */
184 add_assoc_double_ex(return_value, "application_time", sizeof("application_time")-1, (double) status.application_time / ZEND_NANO_IN_SEC);
185 add_assoc_double_ex(return_value, "collector_time", sizeof("collector_time")-1, (double) status.collector_time / ZEND_NANO_IN_SEC);
186 add_assoc_double_ex(return_value, "destructor_time", sizeof("destructor_time")-1, (double) status.dtor_time / ZEND_NANO_IN_SEC);
187 add_assoc_double_ex(return_value, "free_time", sizeof("free_time")-1, (double) status.free_time / ZEND_NANO_IN_SEC);
188}
189/* }}} */
190
191/* {{{ Get the number of arguments that were passed to the function */
193{
195
197
198 if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE)) {
199 zend_throw_error(NULL, "func_num_args() must be called from a function context");
201 }
202
203 if (zend_forbid_dynamic_call() == FAILURE) {
204 RETURN_LONG(-1);
205 }
206
208}
209/* }}} */
210
211/* {{{ Get the $arg_num'th argument that was passed to the function */
213{
214 uint32_t arg_count, first_extra_arg;
215 zval *arg;
216 zend_long requested_offset;
218
219 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &requested_offset) == FAILURE) {
221 }
222
223 if (requested_offset < 0) {
224 zend_argument_value_error(1, "must be greater than or equal to 0");
226 }
227
229 if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE)) {
230 zend_throw_error(NULL, "func_get_arg() cannot be called from the global scope");
232 }
233
234 if (zend_forbid_dynamic_call() == FAILURE) {
236 }
237
238 arg_count = ZEND_CALL_NUM_ARGS(ex);
239
240 if ((zend_ulong)requested_offset >= arg_count) {
241 zend_argument_value_error(1, "must be less than the number of the arguments passed to the currently executed function");
243 }
244
245 first_extra_arg = ex->func->op_array.num_args;
246 if ((zend_ulong)requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) {
247 arg = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg);
248 } else {
249 arg = ZEND_CALL_ARG(ex, requested_offset + 1);
250 }
251 if (EXPECTED(!Z_ISUNDEF_P(arg))) {
253 }
254}
255/* }}} */
256
257/* {{{ Get an array of the arguments that were passed to the function */
259{
260 zval *p, *q;
261 uint32_t arg_count, first_extra_arg;
262 uint32_t i;
264
266
267 if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE)) {
268 zend_throw_error(NULL, "func_get_args() cannot be called from the global scope");
270 }
271
272 if (zend_forbid_dynamic_call() == FAILURE) {
274 }
275
276 arg_count = ZEND_CALL_NUM_ARGS(ex);
277
278 if (arg_count) {
279 array_init_size(return_value, arg_count);
280 first_extra_arg = ex->func->op_array.num_args;
283 i = 0;
284 p = ZEND_CALL_ARG(ex, 1);
285 if (arg_count > first_extra_arg) {
286 while (i < first_extra_arg) {
287 q = p;
288 if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
289 ZVAL_DEREF(q);
290 if (Z_OPT_REFCOUNTED_P(q)) {
291 Z_ADDREF_P(q);
292 }
294 } else {
296 }
298 p++;
299 i++;
300 }
301 p = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T);
302 }
303 while (i < arg_count) {
304 q = p;
305 if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
306 ZVAL_DEREF(q);
307 if (Z_OPT_REFCOUNTED_P(q)) {
308 Z_ADDREF_P(q);
309 }
311 } else {
313 }
315 p++;
316 i++;
317 }
319 Z_ARRVAL_P(return_value)->nNumOfElements = arg_count;
320 } else {
322 }
323}
324/* }}} */
325
326/* {{{ Get string length
327 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
338/* }}} */
339
340/* {{{ Binary safe string comparison */
352/* }}} */
353
354/* {{{ Binary safe string comparison */
356{
357 zend_string *s1, *s2;
359
361 Z_PARAM_STR(s1)
362 Z_PARAM_STR(s2)
365
366 if (len < 0) {
367 zend_argument_value_error(3, "must be greater than or equal to 0");
369 }
370
372}
373/* }}} */
374
375/* {{{ Binary safe case-insensitive string comparison */
387/* }}} */
388
389/* {{{ Binary safe string comparison */
391{
392 zend_string *s1, *s2;
394
396 Z_PARAM_STR(s1)
397 Z_PARAM_STR(s2)
400
401 if (len < 0) {
402 zend_argument_value_error(3, "must be greater than or equal to 0");
404 }
405
407}
408/* }}} */
409
410/* {{{ Return the current error_reporting level, and if an argument was passed - change to the new level */
412{
414 bool err_is_null = 1;
415 int old_error_reporting;
416
419 Z_PARAM_LONG_OR_NULL(err, err_is_null)
421
422 old_error_reporting = EG(error_reporting);
423
424 if (!err_is_null && err != old_error_reporting) {
425 zend_ini_entry *p = EG(error_reporting_ini_entry);
426
427 if (!p) {
428 zval *zv = zend_hash_find_known_hash(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING));
429 if (!zv) {
430 /* Ini setting does not exist -- can this happen? */
431 RETURN_LONG(old_error_reporting);
432 }
433
434 p = EG(error_reporting_ini_entry) = (zend_ini_entry*)Z_PTR_P(zv);
435 }
436 if (!p->modified) {
437 if (!EG(modified_ini_directives)) {
438 ALLOC_HASHTABLE(EG(modified_ini_directives));
439 zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
440 }
441 if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), p) != NULL)) {
442 p->orig_value = p->value;
443 p->orig_modifiable = p->modifiable;
444 p->modified = 1;
445 }
446 } else if (p->orig_value != p->value) {
447 zend_string_release_ex(p->value, 0);
448 }
449
450 p->value = zend_long_to_str(err);
452 }
453
454 RETURN_LONG(old_error_reporting);
455}
456/* }}} */
457
458static bool validate_constant_array_argument(HashTable *ht, int argument_number) /* {{{ */
459{
460 bool ret = 1;
461 zval *val;
462
466 if (Z_TYPE_P(val) == IS_ARRAY && Z_REFCOUNTED_P(val)) {
467 if (Z_IS_RECURSIVE_P(val)) {
468 zend_argument_value_error(argument_number, "cannot be a recursive array");
469 ret = 0;
470 break;
471 } else if (!validate_constant_array_argument(Z_ARRVAL_P(val), argument_number)) {
472 ret = 0;
473 break;
474 }
475 }
478 return ret;
479}
480/* }}} */
481
482static void copy_constant_array(zval *dst, zval *src) /* {{{ */
483{
485 zend_ulong idx;
486 zval *new_val, *val;
487
488 array_init_size(dst, zend_hash_num_elements(Z_ARRVAL_P(src)));
490 /* constant arrays can't contain references */
492 if (key) {
493 new_val = zend_hash_add_new(Z_ARRVAL_P(dst), key, val);
494 } else {
495 new_val = zend_hash_index_add_new(Z_ARRVAL_P(dst), idx, val);
496 }
497 if (Z_TYPE_P(val) == IS_ARRAY) {
498 if (Z_REFCOUNTED_P(val)) {
499 copy_constant_array(new_val, val);
500 }
501 } else {
503 }
505}
506/* }}} */
507
508/* {{{ Define a new constant */
510{
512 zval *val, val_free;
513 bool non_cs = 0;
515
520 Z_PARAM_BOOL(non_cs)
522
523 if (zend_memnstr(ZSTR_VAL(name), "::", sizeof("::") - 1, ZSTR_VAL(name) + ZSTR_LEN(name))) {
524 zend_argument_value_error(1, "cannot be a class constant");
526 }
527
528 if (non_cs) {
529 zend_error(E_WARNING, "define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported");
530 }
531
532 ZVAL_UNDEF(&val_free);
533
534 if (Z_TYPE_P(val) == IS_ARRAY) {
535 if (Z_REFCOUNTED_P(val)) {
536 if (!validate_constant_array_argument(Z_ARRVAL_P(val), 2)) {
538 } else {
539 copy_constant_array(&c.value, val);
540 goto register_constant;
541 }
542 }
543 }
544
545 ZVAL_COPY(&c.value, val);
546 zval_ptr_dtor(&val_free);
547
548register_constant:
549 /* non persistent */
551 c.name = zend_string_copy(name);
552 if (zend_register_constant(&c) == SUCCESS) {
554 } else {
556 }
557}
558/* }}} */
559
560/* {{{ Check whether a constant exists
561 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
576/* }}} */
577
578/* {{{ Retrieves the class name */
580{
581 zval *obj = NULL;
582
583 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o", &obj) == FAILURE) {
585 }
586
587 if (!obj) {
589
590 if (scope) {
591 zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
592 if (UNEXPECTED(EG(exception))) {
594 }
595 RETURN_STR_COPY(scope->name);
596 } else {
597 zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
599 }
600 }
601
603}
604/* }}} */
605
606/* {{{ Retrieves the "Late Static Binding" class name */
608{
609 zend_class_entry *called_scope;
610
612
613 called_scope = zend_get_called_scope(execute_data);
614 if (!called_scope) {
615 zend_throw_error(NULL, "get_called_class() must be called from within a class");
617 }
618
619 RETURN_STR_COPY(called_scope->name);
620}
621/* }}} */
622
623/* {{{ Retrieves the parent class name for object or class or current scope or false if not in a scope. */
625{
627
632
633 if (!ce) {
634 zend_error(E_DEPRECATED, "Calling get_parent_class() without arguments is deprecated");
635 if (UNEXPECTED(EG(exception))) {
637 }
639 }
640
641 if (ce && ce->parent) {
643 } else {
645 }
646}
647/* }}} */
648
649static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ */
650{
651 zval *obj;
652 zend_string *class_name;
653 zend_class_entry *instance_ce;
655 bool allow_string = only_subclass;
656 bool retval;
657
659 Z_PARAM_ZVAL(obj)
660 Z_PARAM_STR(class_name)
662 Z_PARAM_BOOL(allow_string)
664 /*
665 * allow_string - is_a default is no, is_subclass_of is yes.
666 * if it's allowed, then the autoloader will be called if the class does not exist.
667 * default behaviour is different, as 'is_a' used to be used to test mixed return values
668 * and there is no easy way to deprecate this.
669 */
670
671 if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
672 instance_ce = zend_lookup_class(Z_STR_P(obj));
673 if (!instance_ce) {
675 }
676 } else if (Z_TYPE_P(obj) == IS_OBJECT) {
677 instance_ce = Z_OBJCE_P(obj);
678 } else {
680 }
681
682 if (!only_subclass && EXPECTED(zend_string_equals(instance_ce->name, class_name))) {
683 retval = 1;
684 } else {
686 if (!ce) {
687 retval = 0;
688 } else {
689 if (only_subclass && instance_ce == ce) {
690 retval = 0;
691 } else {
692 retval = instanceof_function(instance_ce, ce);
693 }
694 }
695 }
696
698}
699/* }}} */
700
701/* {{{ Returns true if the object has this class as one of its parents */
706/* }}} */
707
708/* {{{ Returns true if the first argument is an object and is this class or has this class as one of its parents, */
713/* }}} */
714
715/* {{{ add_class_vars */
716static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool statics, zval *return_value)
717{
719 zval *prop, prop_copy;
721 zval *default_properties_table = CE_DEFAULT_PROPERTIES_TABLE(ce);
722
724 if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
726 ((prop_info->flags & ZEND_ACC_PRIVATE) &&
727 prop_info->ce != scope) ||
728 (prop_info->flags & ZEND_ACC_VIRTUAL)) {
729 continue;
730 }
731 prop = NULL;
732 if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
733 prop = &ce->default_static_members_table[prop_info->offset];
734 ZVAL_DEINDIRECT(prop);
735 } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
736 prop = &default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
737 }
738 if (!prop) {
739 continue;
740 }
741
742 if (Z_ISUNDEF_P(prop)) {
743 /* Return uninitialized typed properties as a null value */
744 ZVAL_NULL(&prop_copy);
745 } else {
746 /* copy: enforce read only access */
747 ZVAL_COPY_OR_DUP(&prop_copy, prop);
748 }
749 prop = &prop_copy;
750
751 /* this is necessary to make it able to work with default array
752 * properties, returned to user */
753 if (Z_OPT_TYPE_P(prop) == IS_CONSTANT_AST) {
754 if (UNEXPECTED(zval_update_constant_ex(prop, ce) != SUCCESS)) {
755 return;
756 }
757 }
758
761}
762/* }}} */
763
764/* {{{ Returns an array of default properties of the class. */
766{
768
769 if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &ce) == FAILURE) {
771 }
772
776 return;
777 }
778 }
779
781 add_class_vars(scope, ce, 0, return_value);
782 add_class_vars(scope, ce, 1, return_value);
783}
784/* }}} */
785
786/* {{{ Returns an array of object properties */
788{
789 zval *value;
790 HashTable *properties;
793 zend_ulong num_key;
794
798
799 zval obj_zv;
800 ZVAL_OBJ(&obj_zv, zobj);
802 if (properties == NULL) {
804 }
805
806 if (!zobj->ce->default_properties_count && properties == zobj->properties && !GC_IS_RECURSIVE(properties)) {
807 /* fast copy */
808 bool always_duplicate = zobj->handlers != &std_object_handlers;
809 RETVAL_ARR(zend_proptable_to_symtable(properties, always_duplicate));
810 } else {
811 array_init_size(return_value, zend_hash_num_elements(properties));
812
813 ZEND_HASH_FOREACH_KEY_VAL(properties, num_key, key, value) {
814 bool is_dynamic = 1;
815 zval tmp;
816 ZVAL_UNDEF(&tmp);
817 if (Z_TYPE_P(value) == IS_INDIRECT) {
820 continue;
821 }
822
823 is_dynamic = 0;
824 } else if (Z_TYPE_P(value) == IS_PTR) {
825 is_dynamic = 0;
826 }
827
828 if (key && zend_check_property_access(zobj, key, is_dynamic) == FAILURE) {
829 continue;
830 }
831
832 if (Z_ISREF_P(value) && Z_REFCOUNT_P(value) == 1) {
834 }
835 if (Z_TYPE_P(value) == IS_PTR) {
836 /* value is IS_PTR for properties with hooks. */
838 if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) {
839 continue;
840 }
841 const char *unmangled_name_cstr = zend_get_unmangled_property_name(prop_info->name);
842 zend_string *unmangled_name = zend_string_init(unmangled_name_cstr, strlen(unmangled_name_cstr), false);
843 value = zend_read_property_ex(prop_info->ce, zobj, unmangled_name, /* silent */ true, &tmp);
844 zend_string_release_ex(unmangled_name, false);
845 if (EG(exception)) {
846 zend_release_properties(properties);
850 }
851 }
853
854 if (UNEXPECTED(!key)) {
855 /* This case is only possible due to loopholes, e.g. ArrayObject */
857 } else if (!is_dynamic && ZSTR_VAL(key)[0] == 0) {
858 const char *prop_name, *class_name;
859 size_t prop_len;
860 zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_len);
861 /* We assume here that a mangled property name is never
862 * numeric. This is probably a safe assumption, but
863 * theoretically someone might write an extension with
864 * private, numeric properties. Well, too bad.
865 */
866 zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value);
867 } else {
868 zend_symtable_add_new(Z_ARRVAL_P(return_value), key, value);
869 }
870 zval_ptr_dtor(&tmp);
872 }
873 zend_release_properties(properties);
874}
875/* }}} */
876
877/* {{{ Returns an array of mangled object properties. Does not respect property visibility. */
879{
880 zend_object *obj;
881 HashTable *properties;
882
884 Z_PARAM_OBJ(obj)
886
887 properties = zend_get_properties_no_lazy_init(obj);
888 if (!properties) {
890 return;
891 }
892
893 properties = zend_proptable_to_symtable(properties,
895 obj->handlers != &std_object_handlers ||
896 GC_IS_RECURSIVE(properties)));
897 RETURN_ARR(properties);
898}
899/* }}} */
900
901/* {{{ Returns an array of method names for class or class instance. */
929/* }}} */
930
931/* {{{ Checks if the class method exists */
933{
934 zval *klass;
935 zend_string *method_name;
939
940 /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */
942 Z_PARAM_ZVAL(klass)
943 Z_PARAM_STR(method_name)
945
946 if (Z_TYPE_P(klass) == IS_OBJECT) {
947 ce = Z_OBJCE_P(klass);
948 } else if (Z_TYPE_P(klass) == IS_STRING) {
949 if ((ce = zend_lookup_class(Z_STR_P(klass))) == NULL) {
951 }
952 } else {
953 zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(klass));
955 }
956
957 lcname = zend_string_tolower(method_name);
958 func = zend_hash_find_ptr(&ce->function_table, lcname);
960
961 if (func) {
962 /* Exclude shadow properties when checking a method on a specific class. Include
963 * them when checking an object, as method_exists() generally ignores visibility.
964 * TODO: Should we use EG(scope) for the object case instead? */
966 || !(func->common.fn_flags & ZEND_ACC_PRIVATE) || func->common.scope == ce);
967 }
968
969 if (Z_TYPE_P(klass) == IS_OBJECT) {
970 zend_object *obj = Z_OBJ_P(klass);
971 func = Z_OBJ_HT_P(klass)->get_method(&obj, method_name, NULL);
972 if (func != NULL) {
973 if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
974 /* Returns true for the fake Closure's __invoke */
975 RETVAL_BOOL(func->common.scope == zend_ce_closure
977
978 zend_string_release_ex(func->common.function_name, 0);
980 return;
981 }
983 }
984 } else {
985 /* Returns true for fake Closure::__invoke */
986 if (ce == zend_ce_closure
989 }
990 }
992}
993/* }}} */
994
995static void _property_exists(zval *return_value, zval *object, zend_string *property)
996{
998 zend_property_info *property_info;
999
1000 if (Z_TYPE_P(object) == IS_STRING) {
1001 ce = zend_lookup_class(Z_STR_P(object));
1002 if (!ce) {
1004 }
1005 } else if (Z_TYPE_P(object) == IS_OBJECT) {
1006 ce = Z_OBJCE_P(object);
1007 } else {
1008 zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_value_name(object));
1009 RETURN_THROWS();
1010 }
1011
1012 property_info = zend_hash_find_ptr(&ce->properties_info, property);
1013 if (property_info != NULL
1014 && (!(property_info->flags & ZEND_ACC_PRIVATE)
1015 || property_info->ce == ce)) {
1017 }
1018
1019 if (Z_TYPE_P(object) == IS_OBJECT &&
1020 Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, 2, NULL)) {
1022 }
1024}
1025
1026/* {{{ Checks if the object or class has a property */
1028{
1029 zval *object;
1031
1032 /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */
1033 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zS", &object, &property) == FAILURE) {
1034 RETURN_THROWS();
1035 }
1036
1037 _property_exists(return_value, object, property);
1038}
1039/* }}} */
1040
1042{
1043 zval *object;
1044 zval property_tmp;
1046
1047 Z_FLF_PARAM_ZVAL(1, object);
1048 Z_FLF_PARAM_STR(2, property, property_tmp);
1049
1050 _property_exists(return_value, object, property);
1051
1052flf_clean:;
1053 Z_FLF_PARAM_FREE_STR(2, property_tmp)
1054}
1055
1056static inline void _class_exists_impl(zval *return_value, zend_string *name, bool autoload, int flags, int skip_flags) /* {{{ */
1057{
1059 zend_class_entry *ce;
1060
1061 if (ZSTR_HAS_CE_CACHE(name)) {
1062 ce = ZSTR_GET_CE_CACHE(name);
1063 if (ce) {
1064 RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags));
1065 }
1066 }
1067
1068 if (!autoload) {
1069 if (ZSTR_VAL(name)[0] == '\\') {
1070 /* Ignore leading "\" */
1071 lcname = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1073 } else {
1074 lcname = zend_string_tolower(name);
1075 }
1076
1077 ce = zend_hash_find_ptr(EG(class_table), lcname);
1079 } else {
1080 ce = zend_lookup_class(name);
1081 }
1082
1083 if (ce) {
1084 RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags));
1085 } else {
1087 }
1088}
1089/* {{{ */
1090
1091static inline void class_exists_impl(INTERNAL_FUNCTION_PARAMETERS, int flags, int skip_flags) /* {{{ */
1092{
1094 bool autoload = true;
1095
1099 Z_PARAM_BOOL(autoload)
1101
1102 _class_exists_impl(return_value, name, autoload, flags, skip_flags);
1103}
1104
1105/* {{{ Checks if the class exists */
1110/* }}} */
1111
1113{
1114 zval name_tmp;
1116
1117 Z_FLF_PARAM_STR(1, name, name_tmp);
1118
1119 _class_exists_impl(return_value, name, /* autoload */ true, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
1120
1121flf_clean:
1122 Z_FLF_PARAM_FREE_STR(1, name_tmp);
1123}
1124
1126{
1127 zval name_tmp;
1129 bool autoload;
1130
1131 Z_FLF_PARAM_STR(1, name, name_tmp);
1132 Z_FLF_PARAM_BOOL(2, autoload);
1133
1134 _class_exists_impl(return_value, name, autoload, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
1135
1136flf_clean:
1137 Z_FLF_PARAM_FREE_STR(1, name_tmp);
1138}
1139
1140/* {{{ Checks if the class exists */
1145/* }}} */
1146
1147/* {{{ Checks if the trait exists */
1152/* }}} */
1153
1158
1159/* {{{ Checks if the function exists */
1161{
1163 bool exists;
1165
1169
1170 if (ZSTR_VAL(name)[0] == '\\') {
1171 /* Ignore leading "\" */
1172 lcname = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1174 } else {
1175 lcname = zend_string_tolower(name);
1176 }
1177
1178 exists = zend_hash_exists(EG(function_table), lcname);
1180
1181 RETURN_BOOL(exists);
1182}
1183/* }}} */
1184
1185/* {{{ Creates an alias for user defined class */
1187{
1188 zend_string *class_name;
1189 zend_string *alias_name;
1190 zend_class_entry *ce;
1191 bool autoload = 1;
1192
1194 Z_PARAM_STR(class_name)
1195 Z_PARAM_STR(alias_name)
1197 Z_PARAM_BOOL(autoload)
1199
1200 ce = zend_lookup_class_ex(class_name, NULL, !autoload ? ZEND_FETCH_CLASS_NO_AUTOLOAD : 0);
1201
1202 if (ce) {
1203 if (zend_register_class_alias_ex(ZSTR_VAL(alias_name), ZSTR_LEN(alias_name), ce, false) == SUCCESS) {
1205 } else {
1208 }
1209 } else {
1210 zend_error(E_WARNING, "Class \"%s\" not found", ZSTR_VAL(class_name));
1212 }
1213}
1214/* }}} */
1215
1216/* {{{ Returns an array with the file names that were include_once()'d */
1218{
1219 zend_string *entry;
1220
1222
1224 ZEND_HASH_MAP_FOREACH_STR_KEY(&EG(included_files), entry) {
1225 if (entry) {
1226 add_next_index_str(return_value, zend_string_copy(entry));
1227 }
1229}
1230/* }}} */
1231
1232/* {{{ Generates a user-level error/warning/notice message */
1234{
1235 zend_long error_type = E_USER_NOTICE;
1236 zend_string *message;
1237
1238 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &message, &error_type) == FAILURE) {
1239 RETURN_THROWS();
1240 }
1241
1242 switch (error_type) {
1243 case E_USER_ERROR:
1244 zend_error(E_DEPRECATED, "Passing E_USER_ERROR to trigger_error() is deprecated since 8.4,"
1245 " throw an exception or call exit with a string message instead");
1246 if (UNEXPECTED(EG(exception))) {
1247 RETURN_THROWS();
1248 }
1249 case E_USER_WARNING:
1250 case E_USER_NOTICE:
1251 case E_USER_DEPRECATED:
1252 break;
1253 default:
1254 zend_argument_value_error(2, "must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE,"
1255 " or E_USER_DEPRECATED");
1256 RETURN_THROWS();
1257 break;
1258 }
1259
1261 // TODO Change to void
1263}
1264/* }}} */
1265
1266/* {{{ Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
1268{
1269 zend_fcall_info fci;
1271 zend_long error_type = E_ALL;
1272
1274 Z_PARAM_FUNC_OR_NULL(fci, fcc)
1276 Z_PARAM_LONG(error_type)
1278
1279 if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
1280 ZVAL_COPY(return_value, &EG(user_error_handler));
1281 }
1282
1283 zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
1284 zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
1285
1286 if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */
1287 ZVAL_UNDEF(&EG(user_error_handler));
1288 return;
1289 }
1290
1291 ZVAL_COPY(&EG(user_error_handler), &(fci.function_name));
1292 EG(user_error_handler_error_reporting) = (int)error_type;
1293}
1294/* }}} */
1295
1296/* {{{ Restores the previously defined error handler function */
1298{
1300
1301 if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
1302 zval zeh;
1303
1304 ZVAL_COPY_VALUE(&zeh, &EG(user_error_handler));
1305 ZVAL_UNDEF(&EG(user_error_handler));
1306 zval_ptr_dtor(&zeh);
1307 }
1308
1309 if (zend_stack_is_empty(&EG(user_error_handlers))) {
1310 ZVAL_UNDEF(&EG(user_error_handler));
1311 } else {
1312 zval *tmp;
1313 EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
1314 zend_stack_del_top(&EG(user_error_handlers_error_reporting));
1315 tmp = zend_stack_top(&EG(user_error_handlers));
1316 ZVAL_COPY_VALUE(&EG(user_error_handler), tmp);
1317 zend_stack_del_top(&EG(user_error_handlers));
1318 }
1319
1320 // TODO Change to void
1322}
1323/* }}} */
1324
1325/* {{{ Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
1327{
1328 zend_fcall_info fci;
1330
1332 Z_PARAM_FUNC_OR_NULL(fci, fcc)
1334
1335 if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1336 ZVAL_COPY(return_value, &EG(user_exception_handler));
1337 }
1338
1339 zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
1340
1341 if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */
1342 ZVAL_UNDEF(&EG(user_exception_handler));
1343 return;
1344 }
1345
1346 ZVAL_COPY(&EG(user_exception_handler), &(fci.function_name));
1347}
1348/* }}} */
1349
1350/* {{{ Restores the previously defined exception handler function */
1352{
1354
1355 if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1356 zval_ptr_dtor(&EG(user_exception_handler));
1357 }
1358 if (zend_stack_is_empty(&EG(user_exception_handlers))) {
1359 ZVAL_UNDEF(&EG(user_exception_handler));
1360 } else {
1361 zval *tmp = zend_stack_top(&EG(user_exception_handlers));
1362 ZVAL_COPY_VALUE(&EG(user_exception_handler), tmp);
1363 zend_stack_del_top(&EG(user_exception_handlers));
1364 }
1365
1366 // TODO Change to void
1368}
1369/* }}} */
1370
1371static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int flags) /* {{{ */
1372{
1374 zval *zv;
1375 zend_class_entry *ce;
1376
1378
1382 ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
1383 ce = Z_PTR_P(zv);
1385 && key
1386 && ZSTR_VAL(key)[0] != 0) {
1388 if (EXPECTED(Z_TYPE_P(zv) == IS_PTR)) {
1390 } else {
1393 }
1395 }
1398}
1399/* {{{ */
1400
1401/* {{{ Returns an array of all declared traits. */
1406/* }}} */
1407
1408/* {{{ Returns an array of all declared classes. */
1413/* }}} */
1414
1415/* {{{ Returns an array of all declared interfaces. */
1420/* }}} */
1421
1422/* {{{ Returns an array of all defined functions */
1424{
1425 zval internal, user;
1428 bool exclude_disabled = 1;
1429
1430 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) {
1431 RETURN_THROWS();
1432 }
1433
1434 if (exclude_disabled == 0) {
1436 "get_defined_functions(): Setting $exclude_disabled to false has no effect");
1437 }
1438
1439 array_init(&internal);
1440 array_init(&user);
1442
1443 ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(function_table), key, func) {
1444 if (key && ZSTR_VAL(key)[0] != 0) {
1445 if (func->type == ZEND_INTERNAL_FUNCTION) {
1446 add_next_index_str(&internal, zend_string_copy(key));
1447 } else if (func->type == ZEND_USER_FUNCTION) {
1448 add_next_index_str(&user, zend_string_copy(key));
1449 }
1450 }
1452
1453 zend_hash_str_add_new(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal);
1454 zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_USER), &user);
1455}
1456/* }}} */
1457
1458/* {{{ Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
1460{
1461 zend_array *symbol_table;
1462
1464
1465 if (zend_forbid_dynamic_call() == FAILURE) {
1466 return;
1467 }
1468
1469 symbol_table = zend_rebuild_symbol_table();
1470 if (UNEXPECTED(symbol_table == NULL)) {
1472 }
1473
1474 RETURN_ARR(zend_array_dup(symbol_table));
1475}
1476/* }}} */
1477
1478#if ZEND_DEBUG && defined(ZTS)
1480{
1482
1483 RETURN_LONG((zend_long)tsrm_thread_id());
1484}
1485#endif
1486
1487/* {{{ Get the resource type name for a given resource */
1489{
1490 const char *resource_type;
1491 zval *z_resource_type;
1492
1493 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_resource_type) == FAILURE) {
1494 RETURN_THROWS();
1495 }
1496
1497 resource_type = zend_rsrc_list_get_rsrc_type(Z_RES_P(z_resource_type));
1498 if (resource_type) {
1499 RETURN_STRING(resource_type);
1500 } else {
1501 RETURN_STRING("Unknown");
1502 }
1503}
1504/* }}} */
1505
1506/* {{{ Get the resource ID for a given resource */
1508{
1509 zval *resource;
1510
1512 Z_PARAM_RESOURCE(resource)
1514
1515 RETURN_LONG(Z_RES_HANDLE_P(resource));
1516}
1517/* }}} */
1518
1519/* {{{ Get an array with all active resources */
1521{
1524 zend_ulong index;
1525 zval *val;
1526
1527 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &type) == FAILURE) {
1528 RETURN_THROWS();
1529 }
1530
1531 if (!type) {
1533 ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
1534 if (!key) {
1535 Z_ADDREF_P(val);
1537 }
1539 } else if (zend_string_equals_literal(type, "Unknown")) {
1541 ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
1542 if (!key && Z_RES_TYPE_P(val) <= 0) {
1543 Z_ADDREF_P(val);
1545 }
1547 } else {
1549
1550 if (id <= 0) {
1551 zend_argument_value_error(1, "must be a valid resource type");
1552 RETURN_THROWS();
1553 }
1554
1556 ZEND_HASH_FOREACH_KEY_VAL(&EG(regular_list), index, key, val) {
1557 if (!key && Z_RES_TYPE_P(val) == id) {
1558 Z_ADDREF_P(val);
1560 }
1562 }
1563}
1564/* }}} */
1565
1566static void add_zendext_info(zend_extension *ext, void *arg) /* {{{ */
1567{
1568 zval *name_array = (zval *)arg;
1569 add_next_index_string(name_array, ext->name);
1570}
1571/* }}} */
1572
1573/* {{{ Return an array containing names of loaded extensions */
1575{
1576 bool zendext = 0;
1577
1578 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &zendext) == FAILURE) {
1579 RETURN_THROWS();
1580 }
1581
1583
1584 if (zendext) {
1586 } else {
1587 zend_module_entry *module;
1588
1590 add_next_index_string(return_value, module->name);
1592 }
1593}
1594/* }}} */
1595
1596/* {{{ Return an array containing the names and values of all defined constants */
1598{
1599 bool categorize = 0;
1600
1601 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &categorize) == FAILURE) {
1602 RETURN_THROWS();
1603 }
1604
1606
1607 if (categorize) {
1609 int module_number;
1610 zval *modules, const_val;
1611 char **module_names;
1612 zend_module_entry *module;
1613 int i = 1;
1614
1615 modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval));
1616 module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
1617
1618 module_names[0] = "internal";
1620 module_names[module->module_number] = (char *)module->name;
1621 i++;
1623 module_names[i] = "user";
1624
1625 ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), val) {
1626 if (!val->name) {
1627 /* skip special constants */
1628 continue;
1629 }
1630
1632 module_number = i;
1633 } else if (ZEND_CONSTANT_MODULE_NUMBER(val) > i) {
1634 /* should not happen */
1635 continue;
1636 } else {
1637 module_number = ZEND_CONSTANT_MODULE_NUMBER(val);
1638 }
1639
1640 if (Z_TYPE(modules[module_number]) == IS_UNDEF) {
1641 array_init(&modules[module_number]);
1642 add_assoc_zval(return_value, module_names[module_number], &modules[module_number]);
1643 }
1644
1645 ZVAL_COPY_OR_DUP(&const_val, &val->value);
1646 zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val);
1648
1649 efree(module_names);
1650 efree(modules);
1651 } else {
1653 zval const_val;
1654
1655 ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) {
1656 if (!constant->name) {
1657 /* skip special constants */
1658 continue;
1659 }
1660 ZVAL_COPY_OR_DUP(&const_val, &constant->value);
1663 }
1664}
1665/* }}} */
1666
1667static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /* {{{ */
1668{
1669 uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
1670
1671 if (num_args) {
1672 uint32_t i = 0;
1673 zval *p = ZEND_CALL_ARG(call, 1);
1674
1675 array_init_size(arg_array, num_args);
1677 ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(arg_array)) {
1678 if (call->func->type == ZEND_USER_FUNCTION) {
1679 uint32_t first_extra_arg = MIN(num_args, call->func->op_array.num_args);
1680
1682 /* In case of attached symbol_table, values on stack may be invalid
1683 * and we have to access them through symbol_table
1684 * See: https://bugs.php.net/bug.php?id=73156
1685 */
1686 while (i < first_extra_arg) {
1687 zend_string *arg_name = call->func->op_array.vars[i];
1688 zval original_arg;
1689 zval *arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1);
1691 call->func->common.attributes,
1692 "sensitiveparameter",
1693 sizeof("sensitiveparameter") - 1,
1694 i
1695 );
1696
1697 bool is_sensitive = attribute != NULL;
1698
1699 if (arg) {
1700 ZVAL_DEREF(arg);
1701 ZVAL_COPY_VALUE(&original_arg, arg);
1702 } else {
1703 ZVAL_NULL(&original_arg);
1704 }
1705
1706 if (is_sensitive) {
1707 zval redacted_arg;
1709 zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL);
1710 ZEND_HASH_FILL_SET(&redacted_arg);
1711 } else {
1712 Z_TRY_ADDREF_P(&original_arg);
1713 ZEND_HASH_FILL_SET(&original_arg);
1714 }
1715
1717 i++;
1718 }
1719 } else {
1720 while (i < first_extra_arg) {
1721 zval original_arg;
1723 call->func->common.attributes,
1724 "sensitiveparameter",
1725 sizeof("sensitiveparameter") - 1,
1726 i
1727 );
1728 bool is_sensitive = attribute != NULL;
1729
1730 if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
1731 zval *arg = p;
1732 ZVAL_DEREF(arg);
1733 ZVAL_COPY_VALUE(&original_arg, arg);
1734 } else {
1735 ZVAL_NULL(&original_arg);
1736 }
1737
1738 if (is_sensitive) {
1739 zval redacted_arg;
1741 zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL);
1742 ZEND_HASH_FILL_SET(&redacted_arg);
1743 } else {
1744 Z_TRY_ADDREF_P(&original_arg);
1745 ZEND_HASH_FILL_SET(&original_arg);
1746 }
1747
1749 p++;
1750 i++;
1751 }
1752 }
1753 p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T);
1754 }
1755
1756 while (i < num_args) {
1757 zval original_arg;
1758 bool is_sensitive = 0;
1759
1760 if (i < call->func->common.num_args || call->func->common.fn_flags & ZEND_ACC_VARIADIC) {
1762 call->func->common.attributes,
1763 "sensitiveparameter",
1764 sizeof("sensitiveparameter") - 1,
1765 MIN(i, call->func->common.num_args)
1766 );
1767 is_sensitive = attribute != NULL;
1768 }
1769
1770 if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
1771 zval *arg = p;
1772 ZVAL_DEREF(arg);
1773 ZVAL_COPY_VALUE(&original_arg, arg);
1774 } else {
1775 ZVAL_NULL(&original_arg);
1776 }
1777
1778 if (is_sensitive) {
1779 zval redacted_arg;
1781 zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL);
1782 ZEND_HASH_FILL_SET(&redacted_arg);
1783 } else {
1784 Z_TRY_ADDREF_P(&original_arg);
1785 ZEND_HASH_FILL_SET(&original_arg);
1786 }
1787
1789 p++;
1790 i++;
1791 }
1793 Z_ARRVAL_P(arg_array)->nNumOfElements = num_args;
1794 } else {
1795 ZVAL_EMPTY_ARRAY(arg_array);
1796 }
1797
1800 zval *arg;
1801 SEPARATE_ARRAY(arg_array);
1802 ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(call->extra_named_params, name, arg) {
1803 ZVAL_DEREF(arg);
1805 zend_hash_add_new(Z_ARRVAL_P(arg_array), name, arg);
1807 }
1808}
1809/* }}} */
1810
1811/* {{{ */
1813{
1814 zend_long options = 0;
1815 zend_long limit = 0;
1816 zval backtrace;
1817
1818 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &options, &limit) == FAILURE) {
1819 RETURN_THROWS();
1820 }
1821
1822 zend_fetch_debug_backtrace(&backtrace, 1, options, limit);
1823 ZEND_ASSERT(Z_TYPE(backtrace) == IS_ARRAY);
1824
1825 zend_string *str = zend_trace_to_string(Z_ARRVAL(backtrace), /* include_main */ false);
1826 ZEND_WRITE(ZSTR_VAL(str), ZSTR_LEN(str));
1827 zend_string_release(str);
1828 zval_ptr_dtor(&backtrace);
1829}
1830
1831/* }}} */
1832
1833ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit) /* {{{ */
1834{
1835 zend_execute_data *call, *last_call = NULL;
1837 bool fake_frame = 0;
1838 int lineno, frameno = 0;
1840 zend_string *filename;
1841 zend_string *include_filename = NULL;
1842 zval tmp;
1843 HashTable *stack_frame, *prev_stack_frame = NULL;
1844
1846
1847 call = EG(current_execute_data);
1848 if (!call) {
1849 return;
1850 }
1851
1852 if (EG(filename_override)) {
1853 // Add the current execution point to the frame so we don't lose it
1854 zend_string *filename_override = EG(filename_override);
1855 zend_long lineno_override = EG(lineno_override);
1856 EG(filename_override) = NULL;
1857 EG(lineno_override) = -1;
1858
1861 if (filename && (!zend_string_equals(filename, filename_override) || lineno != lineno_override)) {
1862 stack_frame = zend_new_array(8);
1863 zend_hash_real_init_mixed(stack_frame);
1864 ZVAL_STR_COPY(&tmp, filename);
1865 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1);
1866 ZVAL_LONG(&tmp, lineno);
1867 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1);
1868 ZVAL_STR_COPY(&tmp, ZSTR_KNOWN(ZEND_STR_CONST_EXPR_PLACEHOLDER));
1869 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
1870 ZVAL_ARR(&tmp, stack_frame);
1872 }
1873
1874 EG(filename_override) = filename_override;
1875 EG(lineno_override) = lineno_override;
1876 }
1877
1878 if (skip_last) {
1879 /* skip debug_backtrace() */
1880 last_call = call;
1881 call = call->prev_execute_data;
1882 }
1883
1884 while (call && (limit == 0 || frameno < limit)) {
1885 if (UNEXPECTED(!call->func)) {
1886 /* This is the fake frame inserted for nested generators. Normally,
1887 * this frame is preceded by the actual generator frame and then
1888 * replaced by zend_generator_check_placeholder_frame() below.
1889 * However, the frame is popped before cleaning the stack frame,
1890 * which is observable by destructors. */
1892 ZEND_ASSERT(call->func);
1893 }
1894
1895 zend_execute_data *prev = call->prev_execute_data;
1896
1897 if (!prev) {
1898 /* add frame for a handler call without {main} code */
1900 break;
1901 }
1902 } else if (UNEXPECTED((ZEND_CALL_INFO(call) & ZEND_CALL_GENERATOR) != 0)) {
1904 }
1905
1906 /* For frameless calls we add an additional frame for the call itself. */
1907 if (ZEND_USER_CODE(call->func->type)) {
1908 const zend_op *opline = call->opline;
1909 if (!ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) {
1910 goto not_frameless_call;
1911 }
1912 int num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
1913 /* Check if any args were already freed. Skip the frame in that case. */
1914 if (num_args >= 1) {
1915 zval *arg = zend_get_zval_ptr(opline, opline->op1_type, &opline->op1, call);
1916 if (Z_TYPE_P(arg) == IS_UNDEF) goto not_frameless_call;
1917 }
1918 if (num_args >= 2) {
1919 zval *arg = zend_get_zval_ptr(opline, opline->op2_type, &opline->op2, call);
1920 if (Z_TYPE_P(arg) == IS_UNDEF) goto not_frameless_call;
1921 }
1922 if (num_args >= 3) {
1923 const zend_op *op_data = opline + 1;
1924 zval *arg = zend_get_zval_ptr(op_data, op_data->op1_type, &op_data->op1, call);
1925 if (Z_TYPE_P(arg) == IS_UNDEF) goto not_frameless_call;
1926 }
1927 zend_function *func = ZEND_FLF_FUNC(opline);
1928 /* Assume frameless functions are not recursive with themselves.
1929 * This condition may be true when observers are enabled:
1930 * Observers will put a call frame on top of the frameless opcode. */
1931 if (last_call && last_call->func == func) {
1932 goto not_frameless_call;
1933 }
1934 stack_frame = zend_new_array(8);
1935 zend_hash_real_init_mixed(stack_frame);
1936 zend_string *name = func->common.function_name;
1938 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
1939 /* Steal file and line from the previous frame. */
1940 if (call->func && ZEND_USER_CODE(call->func->common.type)) {
1941 filename = call->func->op_array.filename;
1942 if (call->opline->opcode == ZEND_HANDLE_EXCEPTION) {
1943 if (EG(opline_before_exception)) {
1944 lineno = EG(opline_before_exception)->lineno;
1945 } else {
1946 lineno = call->func->op_array.line_end;
1947 }
1948 } else {
1949 lineno = call->opline->lineno;
1950 }
1951 ZVAL_STR_COPY(&tmp, filename);
1952 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1);
1953 ZVAL_LONG(&tmp, lineno);
1954 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1);
1955 if (prev_stack_frame) {
1956 zend_hash_del(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_FILE));
1957 zend_hash_del(prev_stack_frame, ZSTR_KNOWN(ZEND_STR_LINE));
1958 }
1959 }
1960 if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
1963 if (num_args >= 1) {
1964 zval *arg = zend_get_zval_ptr(opline, opline->op1_type, &opline->op1, call);
1967 }
1968 if (num_args >= 2) {
1969 zval *arg = zend_get_zval_ptr(opline, opline->op2_type, &opline->op2, call);
1972 }
1973 if (num_args >= 3) {
1974 const zend_op *op_data = opline + 1;
1975 zval *arg = zend_get_zval_ptr(op_data, op_data->op1_type, &op_data->op1, call);
1978 }
1979 ZVAL_ARR(&tmp, args);
1980 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_ARGS), &tmp, 1);
1981 }
1982 ZVAL_ARR(&tmp, stack_frame);
1984 }
1985not_frameless_call:
1986
1987 /* We use _zend_hash_append*() and the array must be preallocated */
1988 stack_frame = zend_new_array(8);
1989 zend_hash_real_init_mixed(stack_frame);
1990
1991 if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type)) {
1992 filename = prev->func->op_array.filename;
1993 if (prev->opline->opcode == ZEND_HANDLE_EXCEPTION) {
1994 if (EG(opline_before_exception)) {
1995 lineno = EG(opline_before_exception)->lineno;
1996 } else {
1997 lineno = prev->func->op_array.line_end;
1998 }
1999 } else {
2000 lineno = prev->opline->lineno;
2001 }
2002 ZVAL_STR_COPY(&tmp, filename);
2003 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1);
2004 ZVAL_LONG(&tmp, lineno);
2005 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1);
2006
2007 /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
2008 * and debug_backtrace() might have been called by the error_handler. in this case we don't
2009 * want to pop anything of the argument-stack */
2010 } else {
2011 zend_execute_data *prev_call = prev;
2012
2013 while (prev_call) {
2015
2016 if (prev_call &&
2017 prev_call->func &&
2018 !ZEND_USER_CODE(prev_call->func->common.type) &&
2020 break;
2021 }
2022
2023 prev = prev_call->prev_execute_data;
2024 if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type)) {
2025 ZVAL_STR_COPY(&tmp, prev->func->op_array.filename);
2026 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1);
2027 ZVAL_LONG(&tmp, prev->opline->lineno);
2028 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1);
2029 break;
2030 }
2031 prev_call = prev;
2032 }
2033 filename = NULL;
2034 }
2035
2036 func = call->func;
2037 if (!fake_frame && func->common.function_name) {
2038 ZVAL_STR_COPY(&tmp, func->common.function_name);
2039 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
2040
2041 if (Z_TYPE(call->This) == IS_OBJECT) {
2042 object = Z_OBJ(call->This);
2043 /* $this may be passed into regular internal functions */
2044 if (func->common.scope) {
2045 ZVAL_STR_COPY(&tmp, func->common.scope->name);
2046 } else if (object->handlers->get_class_name == zend_std_get_class_name) {
2047 ZVAL_STR_COPY(&tmp, object->ce->name);
2048 } else {
2049 ZVAL_STR(&tmp, object->handlers->get_class_name(object));
2050 }
2051 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_CLASS), &tmp, 1);
2053 ZVAL_OBJ_COPY(&tmp, object);
2054 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_OBJECT), &tmp, 1);
2055 }
2056
2057 ZVAL_INTERNED_STR(&tmp, ZSTR_KNOWN(ZEND_STR_OBJECT_OPERATOR));
2058 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_TYPE), &tmp, 1);
2059 } else if (func->common.scope) {
2060 ZVAL_STR_COPY(&tmp, func->common.scope->name);
2061 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_CLASS), &tmp, 1);
2062 ZVAL_INTERNED_STR(&tmp, ZSTR_KNOWN(ZEND_STR_PAAMAYIM_NEKUDOTAYIM));
2063 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_TYPE), &tmp, 1);
2064 }
2065
2066 if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 &&
2067 func->type != ZEND_EVAL_CODE) {
2068
2069 debug_backtrace_get_args(call, &tmp);
2070 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_ARGS), &tmp, 1);
2071 }
2072 } else {
2073 /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
2074 bool build_filename_arg = 1;
2075 zend_string *pseudo_function_name;
2076 uint32_t include_kind = 0;
2077 if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type) && prev->opline->opcode == ZEND_INCLUDE_OR_EVAL) {
2078 include_kind = prev->opline->extended_value;
2079 }
2080
2081 switch (include_kind) {
2082 case ZEND_EVAL:
2083 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_EVAL);
2084 build_filename_arg = 0;
2085 break;
2086 case ZEND_INCLUDE:
2087 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_INCLUDE);
2088 break;
2089 case ZEND_REQUIRE:
2090 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_REQUIRE);
2091 break;
2092 case ZEND_INCLUDE_ONCE:
2093 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_INCLUDE_ONCE);
2094 break;
2095 case ZEND_REQUIRE_ONCE:
2096 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_REQUIRE_ONCE);
2097 break;
2098 default:
2099 /* Skip dummy frame unless it is needed to preserve filename/lineno info. */
2100 if (!filename) {
2101 zend_array_destroy(stack_frame);
2102 goto skip_frame;
2103 }
2104
2105 pseudo_function_name = ZSTR_KNOWN(ZEND_STR_UNKNOWN);
2106 build_filename_arg = 0;
2107 break;
2108 }
2109
2110 if (build_filename_arg && include_filename) {
2111 zval arg_array;
2112
2113 array_init(&arg_array);
2114
2115 /* include_filename always points to the last filename of the last last called-function.
2116 if we have called include in the frame above - this is the file we have included.
2117 */
2118
2119 ZVAL_STR_COPY(&tmp, include_filename);
2120 zend_hash_next_index_insert_new(Z_ARRVAL(arg_array), &tmp);
2121 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_ARGS), &arg_array, 1);
2122 }
2123
2124 ZVAL_INTERNED_STR(&tmp, pseudo_function_name);
2125 _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
2126 }
2127
2128 ZVAL_ARR(&tmp, stack_frame);
2130 frameno++;
2131 prev_stack_frame = stack_frame;
2132
2133skip_frame:
2135 && !fake_frame
2136 && prev
2137 && prev->func
2138 && ZEND_USER_CODE(prev->func->common.type)
2139 && prev->opline->opcode == ZEND_INCLUDE_OR_EVAL) {
2140 fake_frame = 1;
2141 } else {
2142 fake_frame = 0;
2143 include_filename = filename;
2144 last_call = call;
2145 call = prev;
2146 }
2147 }
2148}
2149/* }}} */
2150
2151/* {{{ Return backtrace as array */
2163/* }}} */
2164
2165/* {{{ Returns true if the named extension is loaded */
2167{
2168 zend_string *extension_name;
2170
2171 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
2172 RETURN_THROWS();
2173 }
2174
2175 lcname = zend_string_tolower(extension_name);
2176 if (zend_hash_exists(&module_registry, lcname)) {
2178 } else {
2180 }
2182}
2183/* }}} */
2184
2185/* {{{ Returns an array with the names of functions belonging to the named extension */
2187{
2188 zend_string *extension_name;
2190 bool array;
2191 zend_module_entry *module;
2192 zend_function *zif;
2193
2194 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
2195 RETURN_THROWS();
2196 }
2197 if (strncasecmp(ZSTR_VAL(extension_name), "zend", sizeof("zend"))) {
2198 lcname = zend_string_tolower(extension_name);
2199 module = zend_hash_find_ptr(&module_registry, lcname);
2201 } else {
2202 module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core") - 1);
2203 }
2204
2205 if (!module) {
2207 }
2208
2209 if (module->functions) {
2210 /* avoid BC break, if functions list is empty, will return an empty array */
2212 array = 1;
2213 } else {
2214 array = 0;
2215 }
2216
2217 ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zif) {
2219 && zif->internal_function.module == module) {
2220 if (!array) {
2222 array = 1;
2223 }
2224 add_next_index_str(return_value, zend_string_copy(zif->common.function_name));
2225 }
2227
2228 if (!array) {
2230 }
2231}
2232/* }}} */
size_t len
Definition apprentice.c:174
file_private const char ext[]
bool exception
Definition assert.c:30
prev(array|object &$array)
constant(string $name)
char s[4]
Definition cdf.c:77
DNS_STATUS status
Definition dns_win32.c:49
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
char * err
Definition ffi.c:3029
zval * arg
Definition ffi.c:3975
zval * val
Definition ffi.c:4262
HashTable * ht
Definition ffi.c:4838
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHP_JSON_API size_t int options
Definition php_json.h:102
unsigned char key[REFLECTION_KEY_LEN]
zend_string * lcname
zend_object * ex
p
Definition session.c:1105
zval * default_static_members_table
Definition zend.h:161
HashTable properties_info
Definition zend.h:164
zend_string * name
Definition zend.h:149
uint32_t ce_flags
Definition zend.h:156
int default_properties_count
Definition zend.h:158
zend_class_entry * parent
Definition zend.h:152
HashTable function_table
Definition zend.h:163
zend_string * name
zend_execute_data * prev_execute_data
zend_function * func
struct _zend_module_entry * module
zend_class_entry * ce
Definition zend_types.h:560
const zend_object_handlers * handlers
Definition zend_types.h:561
znode_op op1
znode_op op2
uint8_t opcode
uint8_t op1_type
uint8_t op2_type
zend_class_entry * ce
zend_class_entry * scope
zend_string * function_name
struct _zend_function::@236135173067030250234125302313220025134003177336 common
uint32_t fn_flags
zend_internal_function internal_function
ZEND_API ZEND_COLD void zend_error_zstr_at(int orig_type, zend_string *error_filename, uint32_t error_lineno, zend_string *message)
Definition zend.c:1428
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API zend_class_entry * zend_standard_class_def
Definition zend.c:83
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
ZEND_API zend_write_func_t zend_write
Definition zend.c:85
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
#define DEBUG_BACKTRACE_IGNORE_ARGS
Definition zend.h:451
#define ZEND_VERSION
Definition zend.h:23
#define DEBUG_BACKTRACE_PROVIDE_OBJECT
Definition zend.h:450
#define ZEND_WRITE(str, str_len)
Definition zend.h:333
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce)
Definition zend_API.c:448
ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type)
Definition zend_API.c:1518
ZEND_API zval * zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv)
Definition zend_API.c:5187
ZEND_API const char * zend_zval_value_name(const zval *arg)
Definition zend_API.c:148
ZEND_API void add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, bool b)
Definition zend_API.c:1946
ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, bool persistent)
Definition zend_API.c:3563
ZEND_API HashTable module_registry
Definition zend_API.c:41
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
ZEND_API void add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d)
Definition zend_API.c:1964
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API void add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n)
Definition zend_API.c:1928
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:423
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
ZEND_API zend_result add_next_index_str(zval *arg, zend_string *str)
Definition zend_API.c:2177
#define ZEND_MINIT
Definition zend_API.h:1066
#define RETURN_COPY_DEREF(zv)
Definition zend_API.h:1056
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
struct _zend_fcall_info_cache zend_fcall_info_cache
#define CE_DEFAULT_PROPERTIES_TABLE(ce)
Definition zend_API.h:334
#define RETURN_STRING(s)
Definition zend_API.h:1043
#define RETURN_STRINGL(s, l)
Definition zend_API.h:1044
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define Z_PARAM_RESOURCE(dest)
Definition zend_API.h:2056
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define ZEND_MINIT_FUNCTION
Definition zend_API.h:1074
#define array_init_size(arg, size)
Definition zend_API.h:538
#define RETURN_ARR(r)
Definition zend_API.h:1050
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define ZEND_FCI_INITIALIZED(fci)
Definition zend_API.h:340
#define RETVAL_ARR(r)
Definition zend_API.h:1024
#define Z_PARAM_STR(dest)
Definition zend_API.h:2086
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETURN_BOOL(b)
Definition zend_API.h:1035
struct _zend_fcall_info zend_fcall_info
#define RETURN_THROWS()
Definition zend_API.h:1060
#define Z_PARAM_OBJ(dest)
Definition zend_API.h:1955
#define RETVAL_TRUE
Definition zend_API.h:1033
#define RETVAL_BOOL(b)
Definition zend_API.h:1009
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
Definition zend_API.h:1899
#define Z_PARAM_STR_OR_LONG(dest_str, dest_long)
Definition zend_API.h:2165
#define RETVAL_LONG(l)
Definition zend_API.h:1011
#define Z_PARAM_OBJ_OR_CLASS_NAME(dest)
Definition zend_API.h:1754
#define Z_PARAM_BOOL(dest)
Definition zend_API.h:1726
#define RETURN_EMPTY_ARRAY()
Definition zend_API.h:1051
ZEND_API zend_array * zend_rebuild_symbol_table(void)
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 Z_PARAM_ZVAL(dest)
Definition zend_API.h:2100
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define RETVAL_FALSE
Definition zend_API.h:1032
#define Z_PARAM_FUNC_OR_NULL(dest_fci, dest_fcc)
Definition zend_API.h:1830
#define RETURN_TRUE
Definition zend_API.h:1059
#define ZEND_FUNCTION(name)
Definition zend_API.h:75
#define RETURN_STR_COPY(s)
Definition zend_API.h:1042
#define array_init(arg)
Definition zend_API.h:537
ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
ZEND_API zend_mm_heap * zend_mm_get_heap(void)
#define ecalloc(nmemb, size)
Definition zend_alloc.h:158
#define efree(ptr)
Definition zend_alloc.h:155
#define ALLOC_HASHTABLE(ht)
Definition zend_alloc.h:231
#define emalloc(size)
Definition zend_alloc.h:151
ZEND_API zend_class_entry * zend_ce_sensitive_parameter_value
ZEND_API zend_attribute * zend_get_parameter_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset)
struct _zend_attribute zend_attribute
zend_result zend_startup_builtin_functions(void)
ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit)
struct _zval_struct zval
method_exists($object_or_class, string $method)
property_exists($object_or_class, string $property)
is_subclass_of(mixed $object_or_class, string $class, bool $allow_string=true)
trigger_error(string $message, int $error_level=E_USER_NOTICE)
get_defined_constants(bool $categorize=false)
function_exists(string $function)
debug_backtrace(int $options=DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit=0)
is_a(mixed $object_or_class, string $class, bool $allow_string=false)
define(string $constant_name, mixed $value, bool $case_insensitive=false)
get_extension_funcs(string $extension)
get_class_methods(object|string $object_or_class)
get_resources(?string $type=null)
error_reporting(?int $error_level=null)
set_error_handler(?callable $callback, int $error_levels=E_ALL)
debug_print_backtrace(int $options=0, int $limit=0)
get_resource_id($resource)
strlen(string $string)
strncmp(string $string1, string $string2, int $length)
class_alias(string $class, string $alias, bool $autoload=true)
get_resource_type($resource)
get_loaded_extensions(bool $zend_extensions=false)
trait_exists(string $trait, bool $autoload=true)
defined(string $constant_name)
class_exists(string $class, bool $autoload=true)
func_get_arg(int $position)
set_exception_handler(?callable $callback)
get_defined_functions(bool $exclude_disabled=true)
enum_exists(string $enum, bool $autoload=true)
get_class(object $object=UNKNOWN)
get_class_vars(string $class)
get_object_vars(object $object)
get_parent_class(object|string $object_or_class=UNKNOWN)
interface_exists(string $interface, bool $autoload=true)
exit(string|int $status=0)
get_mangled_object_vars(object $object)
extension_loaded(string $extension)
strcmp(string $string1, string $string2)
uint32_t num_args
ZEND_API zend_class_entry * zend_ce_closure
zend_string_release_ex(func->internal_function.function_name, 0)
execute_data func
zval * args
ZEND_API zend_result zend_unmangle_property_name_ex(const zend_string *name, const char **class_name, const char **prop_name, size_t *prop_len)
#define ZEND_ACC_ENUM
struct _zend_op zend_op
#define OBJ_PROP_TO_NUM(offset)
#define ZEND_USER_CODE(type)
#define ZEND_CALL_TOP_FUNCTION
#define ZEND_INTERNAL_FUNCTION
#define ZEND_EVAL
#define ZEND_ACC_LINKED
#define ZEND_EVAL_CODE
#define ZEND_FETCH_CLASS_NO_AUTOLOAD
#define EX(element)
#define ZEND_USER_FUNCTION
#define ZEND_CALL_HAS_SYMBOL_TABLE
#define ZEND_ACC_INTERFACE
#define ZEND_ACC_CALL_VIA_TRAMPOLINE
#define ZEND_CALL_GENERATOR
#define ZEND_REQUIRE
struct _zend_property_info zend_property_info
#define ZEND_CALL_HAS_EXTRA_NAMED_PARAMS
#define ZEND_ACC_TRAIT
#define ZEND_CALL_CODE
#define ZEND_ACC_PRIVATE
#define ZEND_ACC_CONSTANTS_UPDATED
#define ZEND_INCLUDE_ONCE
#define ZEND_CALL_NUM_ARGS(call)
#define ZEND_ACC_STATIC
#define ZEND_CALL_INFO(call)
#define ZEND_CALL_KIND(call)
#define ZEND_ACC_PUBLIC
#define ZEND_REQUIRE_ONCE
#define ZEND_ACC_VIRTUAL
#define ZEND_ACC_VARIADIC
#define ZEND_INCLUDE
#define ZEND_FETCH_CLASS_SILENT
#define ZEND_INVOKE_FUNC_NAME
#define ZEND_ACC_PROTECTED
#define ZEND_CALL_VAR_NUM(call, n)
#define ZEND_CALL_ARG(call, n)
#define strncasecmp(s1, s2, n)
#define strcasecmp(s1, s2)
#define ZEND_API
ZEND_API zval * zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags)
ZEND_API zend_result zend_register_constant(zend_constant *c)
#define ZEND_CONSTANT_SET_FLAGS(c, _flags, _module_number)
#define ZEND_CONSTANT_MODULE_NUMBER(c)
struct _zend_constant zend_constant
#define PHP_USER_CONSTANT
ZEND_API void zend_register_default_classes(void)
#define E_USER_NOTICE
Definition zend_errors.h:33
#define E_WARNING
Definition zend_errors.h:24
#define E_USER_WARNING
Definition zend_errors.h:32
#define E_ALL
Definition zend_errors.h:43
#define E_USER_DEPRECATED
Definition zend_errors.h:38
#define E_USER_ERROR
Definition zend_errors.h:31
#define E_DEPRECATED
Definition zend_errors.h:37
ZEND_API zend_string * zend_trace_to_string(HashTable *trace, bool include_main)
ZEND_API ZEND_COLD void zend_throw_unwind_exit(void)
ZEND_API zval * zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data)
ZEND_API zend_class_entry * zend_get_called_scope(zend_execute_data *ex)
ZEND_API zend_class_entry * zend_lookup_class(zend_string *name)
ZEND_API uint32_t zend_get_executed_lineno(void)
ZEND_API zend_class_entry * zend_get_executed_scope(void)
ZEND_API zend_string * zend_get_executed_filename_ex(void)
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *pp, zend_class_entry *scope)
ZEND_API zend_class_entry * zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags)
ZEND_API zend_llist zend_extensions
struct _zend_extension zend_extension
union _zend_function zend_function
#define Z_FLF_PARAM_ZVAL(arg_num, dest)
#define ZEND_FLF_NUM_ARGS(opcode)
#define ZEND_OP_IS_FRAMELESS_ICALL(opcode)
#define Z_FLF_PARAM_BOOL(arg_num, dest)
#define Z_FLF_PARAM_STR(arg_num, dest, tmp)
#define ZEND_FRAMELESS_FUNCTION(name, arity)
#define ZEND_FLF_FUNC(opline)
#define Z_FLF_PARAM_FREE_STR(arg_num, tmp)
ZEND_API int(* gc_collect_cycles)(void)
Definition zend_gc.c:245
ZEND_API void zend_gc_get_status(zend_gc_status *status)
Definition zend_gc.c:2114
struct _zend_gc_status zend_gc_status
ZEND_API zend_execute_data * zend_generator_check_placeholder_frame(zend_execute_data *ptr)
struct _zend_ini_entry zend_ini_entry
#define CG(v)
#define EG(v)
ZEND_API HashTable *ZEND_FASTCALL zend_proptable_to_symtable(HashTable *ht, bool always_duplicate)
Definition zend_hash.c:3387
ZEND_API void ZEND_FASTCALL zend_hash_real_init_packed(HashTable *ht)
Definition zend_hash.c:330
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
Definition zend_hash.c:1229
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
Definition zend_hash.c:1209
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
Definition zend_hash.c:1214
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:1007
ZEND_API zval *ZEND_FASTCALL zend_hash_find_known_hash(const HashTable *ht, const zend_string *key)
Definition zend_hash.c:2679
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1052
ZEND_API HashTable *ZEND_FASTCALL zend_array_dup(HashTable *source)
Definition zend_hash.c:2438
ZEND_API void ZEND_FASTCALL zend_hash_real_init_mixed(HashTable *ht)
Definition zend_hash.c:338
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
Definition zend_hash.c:1534
#define ZEND_HASH_FILL_GROW()
Definition zend_hash.h:1534
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define ZEND_HASH_FILL_PACKED(ht)
Definition zend_hash.h:1528
#define ZEND_HASH_FILL_SET(_val)
Definition zend_hash.h:1544
#define ZEND_HASH_FILL_END()
Definition zend_hash.h:1582
#define ZEND_HASH_FILL_SET_NULL()
Definition zend_hash.h:1547
#define zend_new_array(size)
Definition zend_hash.h:338
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
Definition zend_hash.h:1181
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
Definition zend_hash.h:1346
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
Definition zend_hash.h:1433
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_FILL_NEXT()
Definition zend_hash.h:1565
#define ZVAL_EMPTY_ARRAY(z)
Definition zend_hash.h:87
#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1374
#define ZEND_HASH_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1102
#define ZEND_HASH_FILL_SET_STR_COPY(_val)
Definition zend_hash.h:1559
#define ZEND_NANO_IN_SEC
Definition zend_hrtime.h:73
ZEND_API zend_result zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage)
Definition zend_ini.c:332
#define ZEND_INI_STAGE_RUNTIME
Definition zend_ini.h:231
#define ZEND_INI_USER
Definition zend_ini.h:24
ZEND_API int zend_fetch_list_dtor_id(const char *type_name)
Definition zend_list.c:285
const char * zend_rsrc_list_get_rsrc_type(zend_resource *res)
Definition zend_list.c:316
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t func, void *arg)
Definition zend_llist.c:231
void(* llist_apply_with_arg_func_t)(void *data, void *arg)
Definition zend_llist.h:34
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES
ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_string *prop_info_name, bool is_dynamic)
ZEND_API HashTable * zend_get_properties_for(zval *obj, zend_prop_purpose purpose)
ZEND_API HashTable * zend_get_properties_no_lazy_init(zend_object *zobj)
ZEND_API zend_string * zend_std_get_class_name(const zend_object *zobj)
ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_entry *scope)
ZEND_API const zend_object_handlers std_object_handlers
#define zend_release_properties(ht)
@ ZEND_PROP_PURPOSE_GET_OBJECT_VARS
#define zend_free_trampoline(func)
ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2)
ZEND_API zend_string *ZEND_FASTCALL zend_long_to_str(zend_long num)
ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length)
ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2)
ZEND_API char *ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length)
ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length)
#define MIN(a, b)
#define EXPECTED(condition)
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
struct _zend_array zend_array
@ ZEND_PROPERTY_HOOK_GET
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
Definition zend_stack.c:33
ZEND_API void * zend_stack_top(const zend_stack *stack)
Definition zend_stack.c:45
ZEND_API int zend_stack_int_top(const zend_stack *stack)
Definition zend_stack.c:61
ZEND_API bool zend_stack_is_empty(const zend_stack *stack)
Definition zend_stack.c:72
ZEND_API void zend_stack_del_top(zend_stack *stack)
Definition zend_stack.c:55
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_INIT_LITERAL(s, persistent)
#define ZSTR_KNOWN(idx)
#define zend_string_equals_literal(str, literal)
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define zend_string_equals_literal_ci(str, c)
#define Z_OBJ_HANDLER_P(zv_p, hf)
Definition zend_types.h:996
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define ZVAL_STR(z, s)
#define GC_PROTECT_RECURSION(p)
Definition zend_types.h:868
#define Z_ISREF_P(zval_p)
Definition zend_types.h:954
#define Z_TRY_ADDREF_P(pz)
#define ZVAL_UNDEF(z)
#define Z_REFVAL_P(zval_p)
#define IS_UNDEF
Definition zend_types.h:600
#define Z_ISUNDEF_P(zval_p)
Definition zend_types.h:957
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define ZVAL_NULL(z)
#define ZVAL_DEREF(z)
#define ZVAL_LONG(z, l)
#define IS_STRING
Definition zend_types.h:606
#define Z_OPT_REFCOUNTED_P(zval_p)
Definition zend_types.h:944
#define Z_REFCOUNTED_P(zval_p)
Definition zend_types.h:921
#define ZVAL_STR_COPY(z, s)
#define IS_PTR
Definition zend_types.h:624
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define IS_ARRAY
Definition zend_types.h:607
#define ZVAL_COPY_OR_DUP(z, v)
#define Z_OBJ_HT_P(zval_p)
Definition zend_types.h:993
#define Z_TYPE_INFO_P(zval_p)
Definition zend_types.h:669
#define Z_STR_P(zval_p)
Definition zend_types.h:972
#define Z_PTR_P(zval_p)
#define ZSTR_HAS_CE_CACHE(s)
Definition zend_types.h:841
#define Z_ADDREF_P(pz)
#define Z_OBJCE_P(zval_p)
#define ZVAL_OBJ(z, o)
@ FAILURE
Definition zend_types.h:61
#define IS_OBJECT
Definition zend_types.h:608
#define ZVAL_ARR(z, a)
#define ZSTR_GET_CE_CACHE(s)
Definition zend_types.h:842
#define Z_RES_HANDLE_P(zval_p)
#define ZVAL_COPY(z, v)
#define GC_UNPROTECT_RECURSION(p)
Definition zend_types.h:872
#define IS_ALIAS_PTR
Definition zend_types.h:625
#define Z_INDIRECT_P(zval_p)
#define ZVAL_OBJ_COPY(z, o)
#define Z_REFCOUNT_P(pz)
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define IS_CONSTANT_AST
Definition zend_types.h:611
#define Z_RES_P(zval_p)
#define SEPARATE_ARRAY(zv)
#define GC_IS_RECURSIVE(p)
Definition zend_types.h:865
#define Z_TYPE(zval)
Definition zend_types.h:659
#define ZVAL_INTERNED_STR(z, s)
#define IS_INDIRECT
Definition zend_types.h:623
#define Z_ARRVAL(zval)
Definition zend_types.h:986
struct _zend_execute_data zend_execute_data
Definition zend_types.h:91
#define Z_RES_TYPE_P(zval_p)
#define ZVAL_COPY_VALUE(z, v)
#define ZVAL_DEINDIRECT(z)
#define Z_IS_RECURSIVE_P(zv)
Definition zend_types.h:887
#define Z_OPT_TYPE_P(zval_p)
Definition zend_types.h:938
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval retval
zval * return_value
call prev_execute_data
zend_property_info * prop_info
zend_string * name
execute_data
object
zval * ret
value
zend_execute_data * call
property
new_op_array scope
zend_object * zobj
#define ZEND_INCLUDE_OR_EVAL
#define ZEND_HANDLE_EXCEPTION