php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
observer.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: |
14 +----------------------------------------------------------------------+
15*/
16
17#include "php.h"
18#include "php_test.h"
19#include "observer.h"
20#include "zend_observer.h"
21#include "zend_smart_str.h"
23#include "zend_generators.h"
24
26
28{
30 php_printf("%*s<!-- opcode: '%s' in user handler -->\n", 2 * ZT_G(observer_nesting_depth), "", zend_get_opcode_name(EX(opline)->opcode));
31 }
32
34}
35
36static void observer_set_user_opcode_handler(const char *opcode_names, user_opcode_handler_t handler)
37{
38 const char *s = NULL, *e = opcode_names;
39
40 while (1) {
41 if (*e == ' ' || *e == ',' || *e == '\0') {
42 if (s) {
43 uint8_t opcode = zend_get_opcode_id(s, e - s);
44 if (opcode <= ZEND_VM_LAST_OPCODE) {
46 } else {
47 zend_error(E_WARNING, "Invalid opcode name %.*s", (int) (e - s), e);
48 }
49 s = NULL;
50 }
51 } else {
52 if (!s) {
53 s = e;
54 }
55 }
56 if (*e == '\0') {
57 break;
58 }
59 e++;
60 }
61}
62
64{
66 return;
67 }
68 php_printf("%*s<!-- opcode: '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", zend_get_opcode_name(EX(opline)->opcode));
69}
70
71static inline void assert_observer_opline(zend_execute_data *execute_data) {
73 (EX(opline) >= EX(func)->op_array.opcodes && EX(opline) < EX(func)->op_array.opcodes + EX(func)->op_array.last) ||
74 (EX(opline) >= EG(exception_op) && EX(opline) < EG(exception_op) + 3));
75}
76
77static void observer_begin(zend_execute_data *execute_data)
78{
79 assert_observer_opline(execute_data);
80
82 return;
83 }
84
85 if (execute_data->func && execute_data->func->common.function_name) {
86 if (execute_data->func->common.scope) {
87 php_printf("%*s<%s::%s>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->common.scope->name), ZSTR_VAL(execute_data->func->common.function_name));
88 } else {
89 php_printf("%*s<%s>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->common.function_name));
90 }
91 } else {
92 php_printf("%*s<file '%s'>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->op_array.filename));
93 }
96}
97
98static void get_retval_info(zval *retval, smart_str *buf)
99{
101 return;
102 }
103
104 smart_str_appendc(buf, ':');
105 if (retval == NULL) {
106 smart_str_appendl(buf, "NULL", 4);
107 } else if (ZT_G(observer_show_return_value)) {
108 if (Z_TYPE_P(retval) == IS_OBJECT) {
109 smart_str_appendl(buf, "object(", 7);
110 smart_str_append(buf, Z_OBJCE_P(retval)->name);
111 smart_str_appendl(buf, ")#", 2);
112 smart_str_append_long(buf, Z_OBJ_HANDLE_P(retval));
113 } else {
115 }
116 } else if (ZT_G(observer_show_return_type)) {
117 smart_str_appends(buf, zend_zval_type_name(retval));
118 }
119 smart_str_0(buf);
120}
121
122static void observer_end(zend_execute_data *execute_data, zval *retval)
123{
124 assert_observer_opline(execute_data);
125
127 return;
128 }
129
130 if (EG(exception)) {
131 php_printf("%*s<!-- Exception: %s -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(EG(exception)->ce->name));
132 }
135 if (execute_data->func && execute_data->func->common.function_name) {
136 smart_str retval_info = {0};
137 get_retval_info(retval, &retval_info);
138 if (execute_data->func->common.scope) {
139 php_printf("%*s</%s::%s%s>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->common.scope->name), ZSTR_VAL(execute_data->func->common.function_name), retval_info.s ? ZSTR_VAL(retval_info.s) : "");
140 } else {
141 php_printf("%*s</%s%s>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->common.function_name), retval_info.s ? ZSTR_VAL(retval_info.s) : "");
142 }
143 smart_str_free(&retval_info);
144 } else {
145 php_printf("%*s</file '%s'>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->op_array.filename));
146 }
147}
148
149static void observer_show_init(zend_function *fbc)
150{
151 if (fbc->common.function_name) {
152 if (fbc->common.scope) {
153 php_printf("%*s<!-- init %s::%s() -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
154 } else {
155 php_printf("%*s<!-- init %s() -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->common.function_name));
156 }
157 } else {
158 php_printf("%*s<!-- init '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->op_array.filename));
159 }
160}
161
163{
165 php_printf("%*s<!--\n", 2 * ZT_G(observer_nesting_depth), "");
166 do {
167 if (UNEXPECTED(!ex->func)) {
169 ZEND_ASSERT(ex->func);
170 }
171
172 zend_function *fbc = ex->func;
173 int indent = 2 * ZT_G(observer_nesting_depth) + 4;
174 if (fbc->common.function_name) {
175 if (fbc->common.scope) {
176 php_printf("%*s%s::%s()\n", indent, "", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
177 } else {
178 php_printf("%*s%s()\n", indent, "", ZSTR_VAL(fbc->common.function_name));
179 }
180 } else {
181 php_printf("%*s{main} %s\n", indent, "", ZSTR_VAL(fbc->op_array.filename));
182 }
183 } while ((ex = ex->prev_execute_data) != NULL);
184 php_printf("%*s-->\n", 2 * ZT_G(observer_nesting_depth), "");
185}
186
188{
191 observer_show_init(fbc);
194 }
196 }
197
199 return (zend_observer_fcall_handlers){observer_begin, observer_end};
200 } else if (fbc->common.function_name) {
202 return (zend_observer_fcall_handlers){observer_begin, observer_end};
203 } else if (zend_hash_exists(ZT_G(observer_observe_function_names), fbc->common.function_name)) {
204 return (zend_observer_fcall_handlers){observer_begin, observer_end};
205 }
206 } else {
208 return (zend_observer_fcall_handlers){observer_begin, observer_end};
209 }
210 }
212}
213
214static void fiber_init_observer(zend_fiber_context *initializing) {
216 php_printf("<!-- alloc: %p -->\n", initializing);
217 }
218}
219
220static void fiber_destroy_observer(zend_fiber_context *destroying) {
222 php_printf("<!-- destroy: %p -->\n", destroying);
223 }
224}
225
226static void fiber_address_observer(zend_fiber_context *from, zend_fiber_context *to)
227{
229 php_printf("<!-- switching from fiber %p to %p -->\n", from, to);
230 }
231}
232
233static void fiber_enter_observer(zend_fiber_context *from, zend_fiber_context *to)
234{
236 if (to->status == ZEND_FIBER_STATUS_INIT) {
237 php_printf("<init '%p'>\n", to);
238 } else if (to->kind == zend_ce_fiber) {
239 zend_fiber *fiber = zend_fiber_from_context(to);
240 if (fiber->caller != from) {
241 return;
242 }
243
244 if (fiber->flags & ZEND_FIBER_FLAG_DESTROYED) {
245 php_printf("<destroying '%p'>\n", to);
246 } else if (to->status != ZEND_FIBER_STATUS_DEAD) {
247 php_printf("<resume '%p'>\n", to);
248 }
249 }
250 }
251}
252
253static void fiber_suspend_observer(zend_fiber_context *from, zend_fiber_context *to)
254{
256 if (from->status == ZEND_FIBER_STATUS_DEAD) {
257 zend_fiber *fiber = (from->kind == zend_ce_fiber) ? zend_fiber_from_context(from) : NULL;
258
259 if (fiber && fiber->flags & ZEND_FIBER_FLAG_THREW) {
260 php_printf("<threw '%p'>\n", from);
261 } else if (fiber && fiber->flags & ZEND_FIBER_FLAG_DESTROYED) {
262 php_printf("<destroyed '%p'>\n", from);
263 } else {
264 php_printf("<returned '%p'>\n", from);
265 }
266 } else if (from->kind == zend_ce_fiber) {
267 zend_fiber *fiber = zend_fiber_from_context(from);
268 if (fiber->caller == NULL) {
269 php_printf("<suspend '%p'>\n", from);
270 }
271 }
272 }
273}
274
277 php_printf("%*s<!-- declared function '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(name));
278 }
279}
280
283 php_printf("%*s<!-- declared class '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(name));
284 }
285}
286
287static void (*zend_test_prev_execute_internal)(zend_execute_data *execute_data, zval *return_value);
288static void zend_test_execute_internal(zend_execute_data *execute_data, zval *return_value) {
290
291 if (fbc->common.function_name) {
292 if (fbc->common.scope) {
293 php_printf("%*s<!-- internal enter %s::%s() -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
294 } else {
295 php_printf("%*s<!-- internal enter %s() -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->common.function_name));
296 }
297 } else if (ZEND_USER_CODE(fbc->type)) {
298 php_printf("%*s<!-- internal enter '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(fbc->op_array.filename));
299 }
300
301 if (zend_test_prev_execute_internal) {
302 zend_test_prev_execute_internal(execute_data, return_value);
303 } else {
304 fbc->internal_function.handler(execute_data, return_value);
305 }
306}
307
308static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList)
309{
311 zend_string *funcname;
313 if (!ZT_G(observer_enabled)) {
314 return FAILURE;
315 }
316 if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) {
317 ZEND_HASH_FOREACH_STR_KEY(*p, funcname) {
318 if ((func = zend_hash_find_ptr(EG(function_table), funcname))) {
319 void *old_handler;
322 }
324 }
326 if (new_value && ZSTR_LEN(new_value)) {
327 const char *start = ZSTR_VAL(new_value), *ptr;
328 while ((ptr = strchr(start, ','))) {
329 zend_string *str = zend_string_init(start, ptr - start, 1);
332 zend_string_release(str);
333 start = ptr + 1;
334 }
335 zend_string *str = zend_string_init(start, ZSTR_VAL(new_value) + ZSTR_LEN(new_value) - start, 1);
338 zend_string_release(str);
339 if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) {
340 ZEND_HASH_FOREACH_STR_KEY(*p, funcname) {
341 if ((func = zend_hash_find_ptr(EG(function_table), funcname))) {
342 zend_observer_add_begin_handler(func, observer_begin);
343 zend_observer_add_end_handler(func, observer_end);
344 }
346 }
347 }
348 return SUCCESS;
349}
350
352 STD_PHP_INI_BOOLEAN("zend_test.observer.enabled", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_enabled, zend_zend_test_globals, zend_test_globals)
353 STD_PHP_INI_BOOLEAN("zend_test.observer.show_output", "1", PHP_INI_SYSTEM, OnUpdateBool, observer_show_output, zend_zend_test_globals, zend_test_globals)
354 STD_PHP_INI_BOOLEAN("zend_test.observer.observe_all", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_all, zend_zend_test_globals, zend_test_globals)
355 STD_PHP_INI_BOOLEAN("zend_test.observer.observe_includes", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_includes, zend_zend_test_globals, zend_test_globals)
356 STD_PHP_INI_BOOLEAN("zend_test.observer.observe_functions", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_functions, zend_zend_test_globals, zend_test_globals)
357 STD_PHP_INI_BOOLEAN("zend_test.observer.observe_declaring", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_declaring, zend_zend_test_globals, zend_test_globals)
358 STD_PHP_INI_ENTRY("zend_test.observer.observe_function_names", "", PHP_INI_ALL, zend_test_observer_OnUpdateCommaList, observer_observe_function_names, zend_zend_test_globals, zend_test_globals)
359 STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_type", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_type, zend_zend_test_globals, zend_test_globals)
360 STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_value", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_value, zend_zend_test_globals, zend_test_globals)
361 STD_PHP_INI_BOOLEAN("zend_test.observer.show_init_backtrace", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_init_backtrace, zend_zend_test_globals, zend_test_globals)
362 STD_PHP_INI_BOOLEAN("zend_test.observer.show_opcode", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_opcode, zend_zend_test_globals, zend_test_globals)
363 STD_PHP_INI_ENTRY("zend_test.observer.show_opcode_in_user_handler", "", PHP_INI_SYSTEM, OnUpdateString, observer_show_opcode_in_user_handler, zend_zend_test_globals, zend_test_globals)
364 STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_init", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_init, zend_zend_test_globals, zend_test_globals)
365 STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals)
366 STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_destroy", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_destroy, zend_zend_test_globals, zend_test_globals)
367 STD_PHP_INI_BOOLEAN("zend_test.observer.execute_internal", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_execute_internal, zend_zend_test_globals, zend_test_globals)
369
371{
372 // Loading via dl() not supported with the observer API
373 if (type != MODULE_TEMPORARY) {
375 if (ZT_G(observer_enabled)) {
376 zend_observer_fcall_register(observer_fcall_init);
377 }
378 } else {
379 (void)ini_entries;
380 }
381
384 }
385
386 if (ZT_G(observer_enabled)) {
387 zend_observer_fiber_init_register(fiber_init_observer);
388 zend_observer_fiber_switch_register(fiber_address_observer);
389 zend_observer_fiber_switch_register(fiber_enter_observer);
390 zend_observer_fiber_switch_register(fiber_suspend_observer);
391 zend_observer_fiber_destroy_register(fiber_destroy_observer);
392
395 }
396
398 zend_test_prev_execute_internal = zend_execute_internal;
399 zend_execute_internal = zend_test_execute_internal;
400 }
401}
402
409
410void zend_test_observer_ginit(zend_zend_test_globals *zend_test_globals) {
411 zend_test_globals->observer_observe_function_names = malloc(sizeof(HashTable));
412 _zend_hash_init(zend_test_globals->observer_observe_function_names, 8, ZVAL_PTR_DTOR, 1);
413 GC_MAKE_PERSISTENT_LOCAL(zend_test_globals->observer_observe_function_names);
414}
415
416void zend_test_observer_gshutdown(zend_zend_test_globals *zend_test_globals) {
417 zend_hash_release(zend_test_globals->observer_observe_function_names);
418}
bool exception
Definition assert.c:30
strchr(string $haystack, string $needle, bool $before_needle=false)
char s[4]
Definition cdf.c:77
zend_ffi_type * type
Definition ffi.c:3812
void * ptr
Definition ffi.c:3814
buf start
Definition ffi.c:4687
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI size_t php_printf(const char *format,...)
Definition main.c:938
void zend_test_observer_ginit(zend_zend_test_globals *zend_test_globals)
Definition observer.c:410
void zend_test_observer_init(INIT_FUNC_ARGS)
Definition observer.c:370
void zend_test_observer_gshutdown(zend_zend_test_globals *zend_test_globals)
Definition observer.c:416
void declared_function_observer(zend_op_array *op_array, zend_string *name)
Definition observer.c:275
void zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS)
Definition observer.c:403
void declared_class_observer(zend_class_entry *ce, zend_string *name)
Definition observer.c:281
#define PHP_INI_STAGE_ACTIVATE
Definition php_ini.h:73
#define PHP_INI_ALL
Definition php_ini.h:45
#define PHP_INI_STAGE_DEACTIVATE
Definition php_ini.h:74
#define PHP_INI_BEGIN
Definition php_ini.h:52
#define STD_PHP_INI_ENTRY
Definition php_ini.h:64
#define STD_PHP_INI_BOOLEAN
Definition php_ini.h:66
#define PHP_INI_SYSTEM
Definition php_ini.h:43
#define PHP_INI_STAGE_SHUTDOWN
Definition php_ini.h:72
#define PHP_INI_END
Definition php_ini.h:53
#define PHP_INI_STAGE_STARTUP
Definition php_ini.h:71
#define ZT_G(v)
int observer_observe_functions
Definition php_test.h:40
int observer_fiber_destroy
Definition php_test.h:51
int observer_show_return_type
Definition php_test.h:43
int observer_observe_all
Definition php_test.h:38
int observer_observe_declaring
Definition php_test.h:41
int observer_observe_includes
Definition php_test.h:39
int observer_nesting_depth
Definition php_test.h:48
int observer_enabled
Definition php_test.h:36
int observer_execute_internal
Definition php_test.h:52
int observer_fiber_switch
Definition php_test.h:50
int observer_show_return_value
Definition php_test.h:44
int observer_show_opcode
Definition php_test.h:46
int observer_show_output
Definition php_test.h:37
int observer_show_init_backtrace
Definition php_test.h:45
char * observer_show_opcode_in_user_handler
Definition php_test.h:47
int observer_fiber_init
Definition php_test.h:49
zend_array * observer_observe_function_names
Definition php_test.h:42
PHPAPI zend_result php_var_export_ex(zval *struc, int level, smart_str *buf)
Definition var.c:510
zend_object * ex
p
Definition session.c:1105
zend_fiber_status status
Definition zend_fibers.h:93
zend_fiber_context * caller
uint8_t flags
zend_string * s
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
ZEND_API const char * zend_zval_type_name(const zval *arg)
Definition zend_API.c:167
struct _zval_struct zval
execute_data func
#define ZEND_USER_CODE(type)
#define EX(element)
int(* user_opcode_handler_t)(zend_execute_data *execute_data)
struct _zend_op_array zend_op_array
#define E_WARNING
Definition zend_errors.h:24
ZEND_API zend_result zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API void(* zend_execute_internal)(zend_execute_data *execute_data, zval *return_value)
#define ZEND_USER_OPCODE_DISPATCH
ZEND_API zend_class_entry * zend_ce_fiber
@ ZEND_FIBER_FLAG_THREW
Definition zend_fibers.h:41
@ ZEND_FIBER_FLAG_DESTROYED
Definition zend_fibers.h:43
@ ZEND_FIBER_STATUS_INIT
Definition zend_fibers.h:34
@ ZEND_FIBER_STATUS_DEAD
Definition zend_fibers.h:37
union _zend_function zend_function
ZEND_API zend_execute_data * zend_generator_check_placeholder_frame(zend_execute_data *ptr)
struct _zend_fiber_context zend_fiber_context
struct _zend_fiber zend_fiber
#define EG(v)
ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, bool persistent)
Definition zend_hash.c:277
ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
Definition zend_hash.c:1869
ZEND_API zval *ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
Definition zend_hash.c:1067
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_FOREACH_STR_KEY(ht, _key)
Definition zend_hash.h:1138
#define UNREGISTER_INI_ENTRIES()
Definition zend_ini.h:204
#define REGISTER_INI_ENTRIES()
Definition zend_ini.h:203
#define ZEND_INI_MH(name)
Definition zend_ini.h:30
#define ZEND_INI_GET_ADDR()
Definition zend_ini.h:259
struct _zend_string zend_string
#define INIT_FUNC_ARGS
#define SHUTDOWN_FUNC_ARGS
#define MODULE_TEMPORARY
ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_observer_fcall_end_handler end, zend_observer_fcall_end_handler *next)
ZEND_API void zend_observer_fiber_init_register(zend_observer_fiber_init_handler handler)
ZEND_API void zend_observer_class_linked_register(zend_observer_class_linked_cb cb)
ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init)
ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin, zend_observer_fcall_begin_handler *next)
ZEND_API void zend_observer_fiber_switch_register(zend_observer_fiber_switch_handler handler)
ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observer_fcall_end_handler end)
ZEND_API void zend_observer_function_declared_register(zend_observer_function_declared_cb cb)
ZEND_API void zend_observer_fiber_destroy_register(zend_observer_fiber_destroy_handler handler)
ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin)
void(* zend_observer_fcall_end_handler)(zend_execute_data *execute_data, zval *retval)
void(* zend_observer_fcall_begin_handler)(zend_execute_data *execute_data)
struct _zend_observer_fcall_handlers zend_observer_fcall_handlers
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
struct _zend_array zend_array
struct _zend_class_entry zend_class_entry
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
struct _zend_array HashTable
Definition zend_types.h:386
#define GC_MAKE_PERSISTENT_LOCAL(p)
#define Z_OBJ_HANDLE_P(zval_p)
Definition zend_types.h:999
#define Z_OBJCE_P(zval_p)
@ FAILURE
Definition zend_types.h:61
#define IS_OBJECT
Definition zend_types.h:608
struct _zend_execute_data zend_execute_data
Definition zend_types.h:91
#define ZVAL_PTR_DTOR
zval retval
zval * return_value
zend_string * name
fbc internal_function handler(call, ret)
zend_function * fbc
execute_data
ZEND_API const char *ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode)
ZEND_API uint8_t zend_get_opcode_id(const char *name, size_t length)
#define ZEND_VM_LAST_OPCODE