mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Include internal functions in the observer API
There are two main motivations to this: a) The logic for handling internal and userland observation can be unified. b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved. Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
This commit is contained in:
parent
0c225a2f57
commit
625f164963
49 changed files with 1675 additions and 1257 deletions
|
@ -51,6 +51,7 @@ PHP 8.2 INTERNALS UPGRADE NOTES
|
|||
are deprecated (see main UPGRADING notes). To suppress the notice, e.g. to
|
||||
avoid duplicates when processing the same value multiple times, pass or add
|
||||
IS_CALLABLE_SUPPRESS_DEPRECATIONS to the check_flags parameter.
|
||||
* Registered zend_observer_fcall_init handlers are now also called for internal functions.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
|
|
|
@ -1226,6 +1226,7 @@ ZEND_API void zend_activate(void) /* {{{ */
|
|||
if (CG(map_ptr_last)) {
|
||||
memset(CG(map_ptr_real_base), 0, CG(map_ptr_last) * sizeof(void*));
|
||||
}
|
||||
zend_init_internal_run_time_cache();
|
||||
zend_observer_activate();
|
||||
}
|
||||
/* }}} */
|
||||
|
|
|
@ -2694,6 +2694,11 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend
|
|||
internal_function->scope = scope;
|
||||
internal_function->prototype = NULL;
|
||||
internal_function->attributes = NULL;
|
||||
if (EG(active)) { // at run-time: this ought to only happen if registered with dl() or somehow temporarily at runtime
|
||||
ZEND_MAP_PTR_INIT(internal_function->run_time_cache, zend_arena_alloc(&CG(arena), zend_internal_run_time_cache_reserved_size()));
|
||||
} else {
|
||||
ZEND_MAP_PTR_NEW(internal_function->run_time_cache);
|
||||
}
|
||||
if (ptr->flags) {
|
||||
if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
|
||||
if (ptr->flags != ZEND_ACC_DEPRECATED && scope) {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "zend_inheritance.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_enum.h"
|
||||
#include "zend_observer.h"
|
||||
|
||||
#define SET_NODE(target, src) do { \
|
||||
target ## _type = (src)->op_type; \
|
||||
|
|
|
@ -448,6 +448,7 @@ struct _zend_op_array {
|
|||
uint32_t required_num_args;
|
||||
zend_arg_info *arg_info;
|
||||
HashTable *attributes;
|
||||
ZEND_MAP_PTR_DEF(void **, run_time_cache);
|
||||
/* END of common elements */
|
||||
|
||||
int cache_size; /* number of run_time_cache_slots * sizeof(void*) */
|
||||
|
@ -456,7 +457,6 @@ struct _zend_op_array {
|
|||
uint32_t last; /* number of opcodes */
|
||||
|
||||
zend_op *opcodes;
|
||||
ZEND_MAP_PTR_DEF(void **, run_time_cache);
|
||||
ZEND_MAP_PTR_DEF(HashTable *, static_variables_ptr);
|
||||
HashTable *static_variables;
|
||||
zend_string **vars; /* names of CV variables */
|
||||
|
@ -503,6 +503,7 @@ typedef struct _zend_internal_function {
|
|||
uint32_t required_num_args;
|
||||
zend_internal_arg_info *arg_info;
|
||||
HashTable *attributes;
|
||||
ZEND_MAP_PTR_DEF(void **, run_time_cache);
|
||||
/* END of common elements */
|
||||
|
||||
zif_handler handler;
|
||||
|
@ -527,6 +528,7 @@ union _zend_function {
|
|||
uint32_t required_num_args;
|
||||
zend_arg_info *arg_info; /* index -1 represents the return value info, if any */
|
||||
HashTable *attributes;
|
||||
ZEND_MAP_PTR_DEF(void **, run_time_cache);
|
||||
} common;
|
||||
|
||||
zend_op_array op_array;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "zend_enum_arginfo.h"
|
||||
#include "zend_interfaces.h"
|
||||
#include "zend_enum.h"
|
||||
#include "zend_extensions.h"
|
||||
|
||||
#define ZEND_ENUM_DISALLOW_MAGIC_METHOD(propertyName, methodName) \
|
||||
do { \
|
||||
|
@ -401,59 +402,48 @@ static ZEND_NAMED_FUNCTION(zend_enum_try_from_func)
|
|||
zend_enum_from_base(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
|
||||
}
|
||||
|
||||
static void zend_enum_register_func(zend_class_entry *ce, zend_known_string_id name_id, zend_internal_function *zif) {
|
||||
zend_string *name = ZSTR_KNOWN(name_id);
|
||||
zif->type = ZEND_INTERNAL_FUNCTION;
|
||||
zif->module = EG(current_module);
|
||||
zif->scope = ce;
|
||||
ZEND_MAP_PTR_NEW(zif->run_time_cache);
|
||||
ZEND_MAP_PTR_SET(zif->run_time_cache, zend_arena_alloc(&CG(arena), zend_internal_run_time_cache_reserved_size()));
|
||||
|
||||
if (!zend_hash_add_ptr(&ce->function_table, name, zif)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(name));
|
||||
}
|
||||
}
|
||||
|
||||
void zend_enum_register_funcs(zend_class_entry *ce)
|
||||
{
|
||||
const uint32_t fn_flags =
|
||||
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_ARENA_ALLOCATED;
|
||||
zend_internal_function *cases_function =
|
||||
zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
|
||||
memset(cases_function, 0, sizeof(zend_internal_function));
|
||||
cases_function->type = ZEND_INTERNAL_FUNCTION;
|
||||
cases_function->module = EG(current_module);
|
||||
zend_internal_function *cases_function = zend_arena_calloc(&CG(arena), sizeof(zend_internal_function), 1);
|
||||
cases_function->handler = zend_enum_cases_func;
|
||||
cases_function->function_name = ZSTR_KNOWN(ZEND_STR_CASES);
|
||||
cases_function->scope = ce;
|
||||
cases_function->fn_flags = fn_flags;
|
||||
cases_function->arg_info = (zend_internal_arg_info *) (arginfo_class_UnitEnum_cases + 1);
|
||||
if (!zend_hash_add_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_CASES), cases_function)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::cases()", ZSTR_VAL(ce->name));
|
||||
}
|
||||
zend_enum_register_func(ce, ZEND_STR_CASES, cases_function);
|
||||
|
||||
if (ce->enum_backing_type != IS_UNDEF) {
|
||||
zend_internal_function *from_function =
|
||||
zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
|
||||
memset(from_function, 0, sizeof(zend_internal_function));
|
||||
from_function->type = ZEND_INTERNAL_FUNCTION;
|
||||
from_function->module = EG(current_module);
|
||||
zend_internal_function *from_function = zend_arena_calloc(&CG(arena), sizeof(zend_internal_function), 1);
|
||||
from_function->handler = zend_enum_from_func;
|
||||
from_function->function_name = ZSTR_KNOWN(ZEND_STR_FROM);
|
||||
from_function->scope = ce;
|
||||
from_function->fn_flags = fn_flags;
|
||||
from_function->num_args = 1;
|
||||
from_function->required_num_args = 1;
|
||||
from_function->arg_info = (zend_internal_arg_info *) (arginfo_class_BackedEnum_from + 1);
|
||||
if (!zend_hash_add_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_FROM), from_function)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot redeclare %s::from()", ZSTR_VAL(ce->name));
|
||||
}
|
||||
zend_enum_register_func(ce, ZEND_STR_FROM, from_function);
|
||||
|
||||
zend_internal_function *try_from_function =
|
||||
zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
|
||||
memset(try_from_function, 0, sizeof(zend_internal_function));
|
||||
try_from_function->type = ZEND_INTERNAL_FUNCTION;
|
||||
try_from_function->module = EG(current_module);
|
||||
zend_internal_function *try_from_function = zend_arena_calloc(&CG(arena), sizeof(zend_internal_function), 1);
|
||||
try_from_function->handler = zend_enum_try_from_func;
|
||||
try_from_function->function_name = ZSTR_KNOWN(ZEND_STR_TRYFROM);
|
||||
try_from_function->scope = ce;
|
||||
try_from_function->fn_flags = fn_flags;
|
||||
try_from_function->num_args = 1;
|
||||
try_from_function->required_num_args = 1;
|
||||
try_from_function->arg_info = (zend_internal_arg_info *) (arginfo_class_BackedEnum_tryFrom + 1);
|
||||
if (!zend_hash_add_ptr(
|
||||
&ce->function_table, ZSTR_KNOWN(ZEND_STR_TRYFROM_LOWERCASE), try_from_function)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot redeclare %s::tryFrom()", ZSTR_VAL(ce->name));
|
||||
}
|
||||
zend_enum_register_func(ce, ZEND_STR_TRYFROM_LOWERCASE, try_from_function);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ ZEND_API const zend_internal_function zend_pass_function = {
|
|||
0, /* required_num_args */
|
||||
(zend_internal_arg_info *) zend_pass_function_arg_info + 1, /* arg_info */
|
||||
NULL, /* attributes */
|
||||
NULL, /* run_time_cache */
|
||||
ZEND_FN(pass), /* handler */
|
||||
NULL, /* module */
|
||||
{NULL,NULL,NULL,NULL} /* reserved */
|
||||
|
|
|
@ -935,6 +935,7 @@ cleanup_args:
|
|||
#if ZEND_DEBUG
|
||||
bool should_throw = zend_internal_call_should_throw(func, call);
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_BEGIN(call);
|
||||
if (EXPECTED(zend_execute_internal == NULL)) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
func->internal_function.handler(call, fci->retval);
|
||||
|
@ -953,6 +954,7 @@ cleanup_args:
|
|||
? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval));
|
||||
}
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_END(call, fci->retval);
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
|
||||
|
|
|
@ -280,6 +280,40 @@ ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int ha
|
|||
return handle;
|
||||
}
|
||||
|
||||
ZEND_API size_t zend_internal_run_time_cache_reserved_size() {
|
||||
return zend_op_array_extension_handles * sizeof(void *);
|
||||
}
|
||||
|
||||
ZEND_API void zend_init_internal_run_time_cache() {
|
||||
size_t rt_size = zend_internal_run_time_cache_reserved_size();
|
||||
if (rt_size) {
|
||||
size_t functions = zend_hash_num_elements(CG(function_table));
|
||||
zend_class_entry *ce;
|
||||
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
|
||||
functions += zend_hash_num_elements(&ce->function_table);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
char *ptr = zend_arena_calloc(&CG(arena), functions, rt_size);
|
||||
zend_internal_function *zif;
|
||||
ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zif) {
|
||||
if (!ZEND_USER_CODE(zif->type) && ZEND_MAP_PTR_GET(zif->run_time_cache) == NULL)
|
||||
{
|
||||
ZEND_MAP_PTR_SET(zif->run_time_cache, (void *)ptr);
|
||||
ptr += rt_size;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
|
||||
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zif) {
|
||||
if (!ZEND_USER_CODE(zif->type) && ZEND_MAP_PTR_GET(zif->run_time_cache) == NULL)
|
||||
{
|
||||
ZEND_MAP_PTR_SET(zif->run_time_cache, (void *)ptr);
|
||||
ptr += rt_size;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API zend_extension *zend_get_extension(const char *extension_name)
|
||||
{
|
||||
zend_llist_element *element;
|
||||
|
|
|
@ -145,6 +145,9 @@ void zend_startup_extensions_mechanism(void);
|
|||
void zend_startup_extensions(void);
|
||||
void zend_shutdown_extensions(void);
|
||||
|
||||
ZEND_API size_t zend_internal_run_time_cache_reserved_size(void);
|
||||
ZEND_API void zend_init_internal_run_time_cache(void);
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API zend_result zend_load_extension(const char *path);
|
||||
ZEND_API zend_result zend_load_extension_handle(DL_HANDLE handle, const char *path);
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
#include "zend_llist.h"
|
||||
#include "zend_vm.h"
|
||||
|
||||
#define ZEND_OBSERVER_DATA(op_array) \
|
||||
ZEND_OP_ARRAY_EXTENSION(op_array, zend_observer_fcall_op_array_extension)
|
||||
#define ZEND_OBSERVER_DATA(function) \
|
||||
ZEND_OP_ARRAY_EXTENSION((&(function)->common), zend_observer_fcall_op_array_extension)
|
||||
|
||||
#define ZEND_OBSERVER_NOT_OBSERVED ((void *) 2)
|
||||
|
||||
#define ZEND_OBSERVABLE_FN(fn_flags) \
|
||||
(!(fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
|
||||
#define ZEND_OBSERVABLE_FN(function) \
|
||||
(ZEND_MAP_PTR(function->common.run_time_cache) && !(function->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
|
||||
|
||||
zend_llist zend_observers_fcall_list;
|
||||
zend_llist zend_observer_error_callbacks;
|
||||
|
@ -100,12 +100,9 @@ static void zend_observer_fcall_install(zend_execute_data *execute_data)
|
|||
{
|
||||
zend_llist *list = &zend_observers_fcall_list;
|
||||
zend_function *function = execute_data->func;
|
||||
zend_op_array *op_array = &function->op_array;
|
||||
|
||||
ZEND_ASSERT(function->type != ZEND_INTERNAL_FUNCTION);
|
||||
|
||||
ZEND_ASSERT(RUN_TIME_CACHE(op_array));
|
||||
zend_observer_fcall_begin_handler *begin_handlers = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array);
|
||||
ZEND_ASSERT(RUN_TIME_CACHE(&function->common));
|
||||
zend_observer_fcall_begin_handler *begin_handlers = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(function);
|
||||
zend_observer_fcall_end_handler *end_handlers = (zend_observer_fcall_end_handler *)begin_handlers + list->count, *end_handlers_start = end_handlers;
|
||||
|
||||
*begin_handlers = ZEND_OBSERVER_NOT_OBSERVED;
|
||||
|
@ -152,9 +149,9 @@ static bool zend_observer_remove_handler(void **first_handler, void *old_handler
|
|||
return false;
|
||||
}
|
||||
|
||||
ZEND_API void zend_observer_add_begin_handler(zend_op_array *op_array, zend_observer_fcall_begin_handler begin) {
|
||||
ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin) {
|
||||
size_t registered_observers = zend_observers_fcall_list.count;
|
||||
zend_observer_fcall_begin_handler *first_handler = (void *)&ZEND_OBSERVER_DATA(op_array), *last_handler = first_handler + registered_observers - 1;
|
||||
zend_observer_fcall_begin_handler *first_handler = (void *)&ZEND_OBSERVER_DATA(function), *last_handler = first_handler + registered_observers - 1;
|
||||
if (*first_handler == ZEND_OBSERVER_NOT_OBSERVED) {
|
||||
*first_handler = begin;
|
||||
} else {
|
||||
|
@ -169,13 +166,13 @@ ZEND_API void zend_observer_add_begin_handler(zend_op_array *op_array, zend_obse
|
|||
}
|
||||
}
|
||||
|
||||
ZEND_API bool zend_observer_remove_begin_handler(zend_op_array *op_array, zend_observer_fcall_begin_handler begin) {
|
||||
return zend_observer_remove_handler((void **)&ZEND_OBSERVER_DATA(op_array), begin);
|
||||
ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin) {
|
||||
return zend_observer_remove_handler((void **)&ZEND_OBSERVER_DATA(function), begin);
|
||||
}
|
||||
|
||||
ZEND_API void zend_observer_add_end_handler(zend_op_array *op_array, zend_observer_fcall_end_handler end) {
|
||||
ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observer_fcall_end_handler end) {
|
||||
size_t registered_observers = zend_observers_fcall_list.count;
|
||||
zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(op_array) + registered_observers;
|
||||
zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(function) + registered_observers;
|
||||
// to allow to preserve the invariant that end handlers are in reverse order of begin handlers, push the new end handler in front
|
||||
if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) {
|
||||
// there's no space for new handlers, then it's forbidden to call this function
|
||||
|
@ -185,9 +182,9 @@ ZEND_API void zend_observer_add_end_handler(zend_op_array *op_array, zend_observ
|
|||
*end_handler = end;
|
||||
}
|
||||
|
||||
ZEND_API bool zend_observer_remove_end_handler(zend_op_array *op_array, zend_observer_fcall_end_handler end) {
|
||||
ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_observer_fcall_end_handler end) {
|
||||
size_t registered_observers = zend_observers_fcall_list.count;
|
||||
return zend_observer_remove_handler((void **)&ZEND_OBSERVER_DATA(op_array) + registered_observers, end);
|
||||
return zend_observer_remove_handler((void **)&ZEND_OBSERVER_DATA(function) + registered_observers, end);
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_data)
|
||||
|
@ -196,14 +193,13 @@ static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_d
|
|||
return;
|
||||
}
|
||||
|
||||
zend_op_array *op_array = &execute_data->func->op_array;
|
||||
uint32_t fn_flags = op_array->fn_flags;
|
||||
zend_function *function = execute_data->func;
|
||||
|
||||
if (!ZEND_OBSERVABLE_FN(fn_flags)) {
|
||||
if (!ZEND_OBSERVABLE_FN(function)) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_observer_fcall_begin_handler *handler = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(op_array);
|
||||
zend_observer_fcall_begin_handler *handler = (zend_observer_fcall_begin_handler *)&ZEND_OBSERVER_DATA(function);
|
||||
if (!*handler) {
|
||||
zend_observer_fcall_install(execute_data);
|
||||
}
|
||||
|
@ -243,11 +239,11 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute
|
|||
static inline bool zend_observer_is_skipped_frame(zend_execute_data *execute_data) {
|
||||
zend_function *func = execute_data->func;
|
||||
|
||||
if (!func || func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) {
|
||||
if (!func || !ZEND_OBSERVABLE_FN(func)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
zend_observer_fcall_end_handler end_handler = (&ZEND_OBSERVER_DATA(&func->op_array))[zend_observers_fcall_list.count];
|
||||
zend_observer_fcall_end_handler end_handler = (&ZEND_OBSERVER_DATA(func))[zend_observers_fcall_list.count];
|
||||
if (end_handler == NULL || end_handler == ZEND_OBSERVER_NOT_OBSERVED) {
|
||||
return true;
|
||||
}
|
||||
|
@ -259,11 +255,11 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end(zend_execute_data *execute_d
|
|||
{
|
||||
zend_function *func = execute_data->func;
|
||||
|
||||
if (!ZEND_OBSERVER_ENABLED || !ZEND_OBSERVABLE_FN(func->common.fn_flags)) {
|
||||
if (!ZEND_OBSERVER_ENABLED || !ZEND_OBSERVABLE_FN(func)) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(&func->op_array) + zend_observers_fcall_list.count;
|
||||
zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(func) + zend_observers_fcall_list.count;
|
||||
// TODO: Fix exceptions from generators
|
||||
// ZEND_ASSERT(fcall_data);
|
||||
if (!*handler || *handler == ZEND_OBSERVER_NOT_OBSERVED) {
|
||||
|
@ -291,7 +287,7 @@ ZEND_API void zend_observer_fcall_end_all(void)
|
|||
{
|
||||
zend_execute_data *ex = current_observed_frame;
|
||||
while (ex != NULL) {
|
||||
if (ex->func && ex->func->type != ZEND_INTERNAL_FUNCTION) {
|
||||
if (ex->func) {
|
||||
zend_observer_fcall_end(ex, NULL);
|
||||
}
|
||||
ex = ex->prev_execute_data;
|
||||
|
|
|
@ -58,10 +58,10 @@ ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init);
|
|||
|
||||
// Call during runtime, but only if you have used zend_observer_fcall_register.
|
||||
// You must not have more than one begin and one end handler active at the same time. Remove the old one first, if there is an existing one.
|
||||
ZEND_API void zend_observer_add_begin_handler(zend_op_array *op_array, zend_observer_fcall_begin_handler begin);
|
||||
ZEND_API bool zend_observer_remove_begin_handler(zend_op_array *op_array, zend_observer_fcall_begin_handler begin);
|
||||
ZEND_API void zend_observer_add_end_handler(zend_op_array *op_array, zend_observer_fcall_end_handler end);
|
||||
ZEND_API bool zend_observer_remove_end_handler(zend_op_array *op_array, zend_observer_fcall_end_handler end);
|
||||
ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin);
|
||||
ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin);
|
||||
ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observer_fcall_end_handler end);
|
||||
ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_observer_fcall_end_handler end);
|
||||
|
||||
ZEND_API void zend_observer_startup(void); // Called by engine before MINITs
|
||||
ZEND_API void zend_observer_post_startup(void); // Called by engine after MINITs
|
||||
|
|
|
@ -3908,7 +3908,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT)
|
|||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
||||
ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_execute_data *call = EX(call);
|
||||
|
@ -3929,6 +3929,7 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
|||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
ZEND_OBSERVER_FCALL_BEGIN(call);
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
|
@ -3943,6 +3944,7 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
|
@ -4048,6 +4050,7 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
|||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
ZEND_OBSERVER_FCALL_BEGIN(call);
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
|
@ -4062,6 +4065,7 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
|
@ -4153,6 +4157,7 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
|||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
ZEND_OBSERVER_FCALL_BEGIN(call);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
@ -4172,6 +4177,7 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
|
@ -8710,6 +8716,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
|
|||
}
|
||||
|
||||
ZVAL_NULL(ret);
|
||||
ZEND_OBSERVER_FCALL_BEGIN(call);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
@ -8729,6 +8736,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
|
|
391
Zend/zend_vm_execute.h
generated
391
Zend/zend_vm_execute.h
generated
|
@ -1350,6 +1350,70 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
|
|||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
#if ZEND_DEBUG
|
||||
bool should_throw = zend_internal_call_should_throw(fbc, call);
|
||||
#endif
|
||||
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
zend_observer_fcall_begin(call);
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && call->func) {
|
||||
if (should_throw) {
|
||||
zend_internal_call_arginfo_violation(call->func);
|
||||
}
|
||||
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
|
||||
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
|
||||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
uint32_t call_info = ZEND_CALL_INFO(call);
|
||||
if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
|
||||
if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
|
||||
zend_free_extra_named_params(call->extra_named_params);
|
||||
}
|
||||
zend_vm_stack_free_call_frame_ex(call_info, call);
|
||||
} else {
|
||||
EG(vm_stack_top) = (zval*)call;
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
i_zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_rethrow_exception(execute_data);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_SET_OPCODE(opline + 1);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
@ -1666,6 +1730,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
|||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
zend_observer_fcall_begin(call);
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
|
@ -1680,6 +1745,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
|
@ -1989,6 +2055,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
|||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
zend_observer_fcall_begin(call);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
@ -2008,6 +2075,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
|
@ -3342,6 +3410,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
|||
}
|
||||
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
@ -3479,6 +3548,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
|
|||
}
|
||||
|
||||
ZVAL_NULL(ret);
|
||||
zend_observer_fcall_begin(call);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
@ -3498,6 +3568,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
|
|||
zend_verify_internal_func_info(call->func, ret);
|
||||
}
|
||||
#endif
|
||||
zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
|
@ -54397,6 +54468,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
|
|||
(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_CV_LABEL,
|
||||
(void*)&&ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_LABEL,
|
||||
(void*)&&ZEND_DO_ICALL_SPEC_RETVAL_USED_LABEL,
|
||||
(void*)&&ZEND_DO_ICALL_SPEC_OBSERVER_LABEL,
|
||||
(void*)&&ZEND_DO_ICALL_SPEC_OBSERVER_LABEL,
|
||||
(void*)&&ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_LABEL,
|
||||
(void*)&&ZEND_DO_UCALL_SPEC_RETVAL_USED_LABEL,
|
||||
(void*)&&ZEND_DO_UCALL_SPEC_OBSERVER_LABEL,
|
||||
|
@ -55897,6 +55970,10 @@ zend_leave_helper_SPEC_LABEL:
|
|||
VM_TRACE(ZEND_DO_ICALL_SPEC_RETVAL_USED)
|
||||
ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
HYBRID_BREAK();
|
||||
HYBRID_CASE(ZEND_DO_ICALL_SPEC_OBSERVER):
|
||||
VM_TRACE(ZEND_DO_ICALL_SPEC_OBSERVER)
|
||||
ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
HYBRID_BREAK();
|
||||
HYBRID_CASE(ZEND_DO_UCALL_SPEC_RETVAL_UNUSED):
|
||||
VM_TRACE(ZEND_DO_UCALL_SPEC_RETVAL_UNUSED)
|
||||
ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
|
@ -62448,6 +62525,8 @@ void zend_vm_init(void)
|
|||
ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
|
||||
ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER,
|
||||
ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER,
|
||||
ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER,
|
||||
ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER,
|
||||
ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER,
|
||||
ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER,
|
||||
ZEND_DO_UCALL_SPEC_OBSERVER_HANDLER,
|
||||
|
@ -63755,7 +63834,7 @@ void zend_vm_init(void)
|
|||
1255,
|
||||
1256 | SPEC_RULE_OP1,
|
||||
1261 | SPEC_RULE_OP1,
|
||||
3448,
|
||||
3450,
|
||||
1266 | SPEC_RULE_OP1,
|
||||
1271 | SPEC_RULE_OP1,
|
||||
1276 | SPEC_RULE_OP2,
|
||||
|
@ -63839,133 +63918,133 @@ void zend_vm_init(void)
|
|||
2180,
|
||||
2181,
|
||||
2182 | SPEC_RULE_OP2,
|
||||
2187 | SPEC_RULE_RETVAL,
|
||||
2189 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2193 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2247 | SPEC_RULE_OP1,
|
||||
2252,
|
||||
2253 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2278,
|
||||
2279 | SPEC_RULE_OP1,
|
||||
2284,
|
||||
2285,
|
||||
2187 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2191 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2195 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2249 | SPEC_RULE_OP1,
|
||||
2254,
|
||||
2255 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2280,
|
||||
2281 | SPEC_RULE_OP1,
|
||||
2286,
|
||||
2287,
|
||||
2288,
|
||||
2289,
|
||||
2290,
|
||||
2291 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2316,
|
||||
2317,
|
||||
2291,
|
||||
2292,
|
||||
2293 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2318,
|
||||
2319 | SPEC_RULE_OP1,
|
||||
2324,
|
||||
2325 | SPEC_RULE_ISSET,
|
||||
2327 | SPEC_RULE_OP2,
|
||||
2332,
|
||||
2333 | SPEC_RULE_OP1,
|
||||
2338 | SPEC_RULE_OBSERVER,
|
||||
2340,
|
||||
2341 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2366 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
2376,
|
||||
2377,
|
||||
2319,
|
||||
2320,
|
||||
2321 | SPEC_RULE_OP1,
|
||||
2326,
|
||||
2327 | SPEC_RULE_ISSET,
|
||||
2329 | SPEC_RULE_OP2,
|
||||
2334,
|
||||
2335 | SPEC_RULE_OP1,
|
||||
2340 | SPEC_RULE_OBSERVER,
|
||||
2342,
|
||||
2343 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2368 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
2378,
|
||||
2379,
|
||||
2380 | SPEC_RULE_OP1,
|
||||
2385,
|
||||
2386,
|
||||
2387 | SPEC_RULE_OP1,
|
||||
2392 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2417,
|
||||
2418 | SPEC_RULE_OP1,
|
||||
2423,
|
||||
2424,
|
||||
2380,
|
||||
2381,
|
||||
2382 | SPEC_RULE_OP1,
|
||||
2387,
|
||||
2388,
|
||||
2389 | SPEC_RULE_OP1,
|
||||
2394 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2419,
|
||||
2420 | SPEC_RULE_OP1,
|
||||
2425,
|
||||
2426,
|
||||
2427,
|
||||
2428,
|
||||
2429,
|
||||
2430,
|
||||
2431 | SPEC_RULE_OP1,
|
||||
2436,
|
||||
2437,
|
||||
2431,
|
||||
2432,
|
||||
2433 | SPEC_RULE_OP1,
|
||||
2438,
|
||||
2439 | SPEC_RULE_OP2,
|
||||
2444,
|
||||
2445 | SPEC_RULE_OP1,
|
||||
2450 | SPEC_RULE_OP1,
|
||||
2455 | SPEC_RULE_OP1,
|
||||
2460 | SPEC_RULE_OP1,
|
||||
2465 | SPEC_RULE_OP1,
|
||||
2470,
|
||||
2471 | SPEC_RULE_OP1,
|
||||
2476 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2501 | SPEC_RULE_OP1,
|
||||
2506 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2531 | SPEC_RULE_OP1,
|
||||
2536 | SPEC_RULE_OP1,
|
||||
2541,
|
||||
2542,
|
||||
2439,
|
||||
2440,
|
||||
2441 | SPEC_RULE_OP2,
|
||||
2446,
|
||||
2447 | SPEC_RULE_OP1,
|
||||
2452 | SPEC_RULE_OP1,
|
||||
2457 | SPEC_RULE_OP1,
|
||||
2462 | SPEC_RULE_OP1,
|
||||
2467 | SPEC_RULE_OP1,
|
||||
2472,
|
||||
2473 | SPEC_RULE_OP1,
|
||||
2478 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2503 | SPEC_RULE_OP1,
|
||||
2508 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2533 | SPEC_RULE_OP1,
|
||||
2538 | SPEC_RULE_OP1,
|
||||
2543,
|
||||
2544,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
3448,
|
||||
2545,
|
||||
2546,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
3450,
|
||||
};
|
||||
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
|
||||
zend_opcode_handler_funcs = labels;
|
||||
|
@ -64138,7 +64217,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2547 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2549 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
|
@ -64146,7 +64225,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2572 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2574 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
|
@ -64154,7 +64233,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2597 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2599 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
|
@ -64165,17 +64244,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2622 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2624 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2647 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2649 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2672 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2674 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
}
|
||||
break;
|
||||
case ZEND_MUL:
|
||||
|
@ -64186,17 +64265,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2697 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2699 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2722 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2724 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2747 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2749 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_IDENTICAL:
|
||||
|
@ -64207,14 +64286,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2772 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2774 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2849 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
|
||||
spec = 3072 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3074 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
|
@ -64225,14 +64304,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2924 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2999 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
|
||||
spec = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3079 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_EQUAL:
|
||||
|
@ -64243,12 +64322,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2772 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2774 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2849 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_EQUAL:
|
||||
|
@ -64259,12 +64338,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2924 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2999 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_SMALLER:
|
||||
|
@ -64272,12 +64351,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3082 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3084 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3157 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3159 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
||||
|
@ -64285,74 +64364,74 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3232 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3234 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3307 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3309 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
}
|
||||
break;
|
||||
case ZEND_QM_ASSIGN:
|
||||
if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3394 | SPEC_RULE_OP1;
|
||||
spec = 3396 | SPEC_RULE_OP1;
|
||||
} else if (op1_info == MAY_BE_DOUBLE) {
|
||||
spec = 3399 | SPEC_RULE_OP1;
|
||||
spec = 3401 | SPEC_RULE_OP1;
|
||||
} else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) {
|
||||
spec = 3404 | SPEC_RULE_OP1;
|
||||
spec = 3406 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_PRE_INC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3382 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3384 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3386 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_PRE_DEC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3386 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3388 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3390 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_POST_INC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3390;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3391;
|
||||
}
|
||||
break;
|
||||
case ZEND_POST_DEC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3392;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3393;
|
||||
}
|
||||
break;
|
||||
case ZEND_POST_DEC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3394;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3395;
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP:
|
||||
if (OP_JMP_ADDR(op, op->op1) > op) {
|
||||
spec = 2546;
|
||||
spec = 2548;
|
||||
}
|
||||
break;
|
||||
case ZEND_RECV:
|
||||
if (op->op2.num == MAY_BE_ANY) {
|
||||
spec = 2545;
|
||||
spec = 2547;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAL:
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
|
||||
spec = 3444;
|
||||
spec = 3446;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAR_EX:
|
||||
if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
|
||||
spec = 3439 | SPEC_RULE_OP1;
|
||||
spec = 3441 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_FE_FETCH_R:
|
||||
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
|
||||
spec = 3446 | SPEC_RULE_RETVAL;
|
||||
spec = 3448 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_DIM_R:
|
||||
|
@ -64360,17 +64439,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
|||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3409 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 3411 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAL_EX:
|
||||
if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
|
||||
spec = 3445;
|
||||
spec = 3447;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAR:
|
||||
if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
|
||||
spec = 3434 | SPEC_RULE_OP1;
|
||||
spec = 3436 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_BW_OR:
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9527,13 +9527,19 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
|
|||
}
|
||||
}
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_64_ZTS str, RX, executor_globals, current_execute_data, REG1
|
||||
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
| mov FCARG1x, RX
|
||||
| EXT_CALL zend_observer_fcall_begin, REG0
|
||||
| ldr REG0, EX:RX->func // reload
|
||||
}
|
||||
|
||||
| // ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
| LOAD_ZVAL_ADDR FCARG2x, res_addr
|
||||
| SET_Z_TYPE_INFO FCARG2x, IS_NULL, TMP1w
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_64_ZTS str, RX, executor_globals, current_execute_data, REG1
|
||||
|
||||
zend_jit_reset_last_valid_opline();
|
||||
|
||||
| // fbc->internal_function.handler(call, ret);
|
||||
|
@ -9545,6 +9551,12 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
|
|||
| blr TMP1
|
||||
}
|
||||
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
| LOAD_ZVAL_ADDR FCARG2x, res_addr
|
||||
| mov FCARG1x, RX
|
||||
| EXT_CALL zend_observer_fcall_end, REG0
|
||||
}
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_64_ZTS str, FP, executor_globals, current_execute_data, REG0
|
||||
|
||||
|
|
|
@ -10231,13 +10231,19 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
|
|||
}
|
||||
}
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_ZTS aword, executor_globals, current_execute_data, RX, r1
|
||||
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
| mov FCARG1a, RX
|
||||
| EXT_CALL zend_observer_fcall_begin, r0
|
||||
| mov r0, EX:RX->func // reload
|
||||
}
|
||||
|
||||
| // ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
| LOAD_ZVAL_ADDR FCARG2a, res_addr
|
||||
| SET_Z_TYPE_INFO FCARG2a, IS_NULL
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_ZTS aword, executor_globals, current_execute_data, RX, r1
|
||||
|
||||
zend_jit_reset_last_valid_opline();
|
||||
|
||||
| // fbc->internal_function.handler(call, ret);
|
||||
|
@ -10248,6 +10254,12 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
|
|||
| call aword [r0 + offsetof(zend_internal_function, handler)]
|
||||
}
|
||||
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
| LOAD_ZVAL_ADDR FCARG2a, res_addr
|
||||
| mov FCARG1a, RX
|
||||
| EXT_CALL zend_observer_fcall_end, r0
|
||||
}
|
||||
|
||||
| // EG(current_execute_data) = execute_data;
|
||||
| MEM_STORE_ZTS aword, executor_globals, current_execute_data, FP, r0
|
||||
|
||||
|
|
|
@ -1245,6 +1245,7 @@ bool pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind)
|
|||
func.function_name = zend_string_init(funcs->fname, strlen(funcs->fname), dbh->is_persistent);
|
||||
func.scope = dbh_obj->std.ce;
|
||||
func.prototype = NULL;
|
||||
ZEND_MAP_PTR(func.run_time_cache) = NULL;
|
||||
if (funcs->flags) {
|
||||
func.fn_flags = funcs->flags | ZEND_ACC_NEVER_CACHE;
|
||||
} else {
|
||||
|
|
|
@ -264,8 +264,8 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList)
|
|||
if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) {
|
||||
ZEND_HASH_FOREACH_STR_KEY(*p, funcname) {
|
||||
if ((func = zend_hash_find_ptr(EG(function_table), funcname))) {
|
||||
zend_observer_remove_begin_handler(&func->op_array, observer_begin);
|
||||
zend_observer_remove_end_handler(&func->op_array, observer_end);
|
||||
zend_observer_remove_begin_handler(func, observer_begin);
|
||||
zend_observer_remove_end_handler(func, observer_end);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
|
@ -280,8 +280,8 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList)
|
|||
if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) {
|
||||
ZEND_HASH_FOREACH_STR_KEY(*p, funcname) {
|
||||
if ((func = zend_hash_find_ptr(EG(function_table), funcname))) {
|
||||
zend_observer_add_begin_handler(&func->op_array, observer_begin);
|
||||
zend_observer_add_end_handler(&func->op_array, observer_end);
|
||||
zend_observer_add_begin_handler(func, observer_begin);
|
||||
zend_observer_add_end_handler(func, observer_end);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,13 @@ var_dump(foo());
|
|||
{main} %s%eobserver_backtrace_%d.php
|
||||
-->
|
||||
<foo>
|
||||
<!-- init Generator::current() -->
|
||||
<!--
|
||||
Generator::current()
|
||||
foo()
|
||||
{main} %s%eobserver_backtrace_%d.php
|
||||
-->
|
||||
<Generator::current>
|
||||
<!-- init gen() -->
|
||||
<!--
|
||||
gen()
|
||||
|
@ -65,6 +72,16 @@ var_dump(foo());
|
|||
{main} %s%eobserver_backtrace_%d.php
|
||||
-->
|
||||
<TestClass::foo>
|
||||
<!-- init array_map() -->
|
||||
<!--
|
||||
array_map()
|
||||
TestClass::foo()
|
||||
gen()
|
||||
Generator::current()
|
||||
foo()
|
||||
{main} %s%eobserver_backtrace_%d.php
|
||||
-->
|
||||
<array_map>
|
||||
<!-- init TestClass::{closure}() -->
|
||||
<!--
|
||||
TestClass::{closure}()
|
||||
|
@ -94,13 +111,22 @@ var_dump(foo());
|
|||
<TestClass::bar>
|
||||
</TestClass::bar>
|
||||
</TestClass::{closure}>
|
||||
</array_map>
|
||||
</TestClass::foo>
|
||||
</gen>
|
||||
</Generator::current>
|
||||
</foo>
|
||||
<!-- init var_dump() -->
|
||||
<!--
|
||||
var_dump()
|
||||
{main} %s%eobserver_backtrace_%d.php
|
||||
-->
|
||||
<var_dump>
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(42)
|
||||
[1]=>
|
||||
int(1337)
|
||||
}
|
||||
</var_dump>
|
||||
</file '%s%eobserver_backtrace_%d.php'>
|
||||
|
|
|
@ -26,30 +26,44 @@ foo();
|
|||
echo 'DONE' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_basic_01.php' -->
|
||||
<file '%s%eobserver_basic_01.php'>
|
||||
<!-- init '%s%eobserver_basic_%d.php' -->
|
||||
<file '%s%eobserver_basic_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
Foo
|
||||
<!-- init bar() -->
|
||||
<bar>
|
||||
Bar
|
||||
<!-- init array_sum() -->
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<!-- init var_dump() -->
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</bar>
|
||||
</foo>
|
||||
<foo>
|
||||
Foo
|
||||
<bar>
|
||||
Bar
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</bar>
|
||||
</foo>
|
||||
<foo>
|
||||
Foo
|
||||
<bar>
|
||||
Bar
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</bar>
|
||||
</foo>
|
||||
DONE
|
||||
</file '%s%eobserver_basic_01.php'>
|
||||
</file '%s%eobserver_basic_%d.php'>
|
||||
|
|
|
@ -30,30 +30,44 @@ $test->foo();
|
|||
echo 'DONE' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_basic_02.php' -->
|
||||
<file '%s%eobserver_basic_02.php'>
|
||||
<!-- init '%s%eobserver_basic_%d.php' -->
|
||||
<file '%s%eobserver_basic_%d.php'>
|
||||
<!-- init TestClass::foo() -->
|
||||
<TestClass::foo>
|
||||
Foo
|
||||
<!-- init TestClass::bar() -->
|
||||
<TestClass::bar>
|
||||
Bar
|
||||
<!-- init array_sum() -->
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<!-- init var_dump() -->
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</TestClass::bar>
|
||||
</TestClass::foo>
|
||||
<TestClass::foo>
|
||||
Foo
|
||||
<TestClass::bar>
|
||||
Bar
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</TestClass::bar>
|
||||
</TestClass::foo>
|
||||
<TestClass::foo>
|
||||
Foo
|
||||
<TestClass::bar>
|
||||
Bar
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(6)
|
||||
</var_dump>
|
||||
</TestClass::bar>
|
||||
</TestClass::foo>
|
||||
DONE
|
||||
</file '%s%eobserver_basic_02.php'>
|
||||
</file '%s%eobserver_basic_%d.php'>
|
||||
|
|
|
@ -34,6 +34,7 @@ Foo
|
|||
</foo>
|
||||
<!-- init bar() -->
|
||||
Bar
|
||||
<!-- init ini_set() -->
|
||||
Foo
|
||||
<bar>
|
||||
Bar
|
||||
|
|
|
@ -25,7 +25,16 @@ call_user_func([$r->getAttributes(A::class)[0], 'newInstance']);
|
|||
--EXPECTF--
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init ReflectionFunction::__construct() -->
|
||||
<ReflectionFunction::__construct>
|
||||
</ReflectionFunction::__construct>
|
||||
<!-- init ReflectionFunctionAbstract::getAttributes() -->
|
||||
<ReflectionFunctionAbstract::getAttributes>
|
||||
</ReflectionFunctionAbstract::getAttributes>
|
||||
<!-- init ReflectionAttribute::newInstance() -->
|
||||
<ReflectionAttribute::newInstance>
|
||||
<!-- init A::__construct() -->
|
||||
<A::__construct>
|
||||
</A::__construct>
|
||||
</ReflectionAttribute::newInstance>
|
||||
</file '%s'>
|
|
@ -25,9 +25,24 @@ call_user_func([$r->getAttributes(A::class)[0], 'newInstance']);
|
|||
--EXPECTF--
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init ReflectionFunction::__construct() -->
|
||||
<ReflectionFunction::__construct>
|
||||
</ReflectionFunction::__construct>
|
||||
<!-- init ReflectionFunctionAbstract::getAttributes() -->
|
||||
<ReflectionFunctionAbstract::getAttributes>
|
||||
</ReflectionFunctionAbstract::getAttributes>
|
||||
<!-- init ReflectionAttribute::newInstance() -->
|
||||
<ReflectionAttribute::newInstance>
|
||||
<!-- init A::__construct() -->
|
||||
<A::__construct>
|
||||
<!-- init array_map() -->
|
||||
<array_map>
|
||||
<!-- init str_repeat() -->
|
||||
<str_repeat>
|
||||
|
||||
Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d
|
||||
</str_repeat>
|
||||
</array_map>
|
||||
</A::__construct>
|
||||
</ReflectionAttribute::newInstance>
|
||||
</file '%s'>
|
||||
|
|
|
@ -42,6 +42,8 @@ a();
|
|||
<d>
|
||||
</d>
|
||||
<!-- init bailout() -->
|
||||
<!-- init array_map() -->
|
||||
<!-- init str_repeat() -->
|
||||
|
||||
Fatal error: Allowed memory size of 20971520 bytes exhausted %s in %s on line %d
|
||||
</a>
|
||||
|
|
|
@ -26,14 +26,19 @@ namespace Test {
|
|||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_call_user_func_%d.php' -->
|
||||
<file '%s%eobserver_call_user_func_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init call_user_func() -->
|
||||
<call_user_func>
|
||||
<!-- init Test\MyClass::myMethod() -->
|
||||
<Test\MyClass::myMethod>
|
||||
MyClass::myMethod called
|
||||
</Test\MyClass::myMethod>
|
||||
</call_user_func>
|
||||
<call_user_func>
|
||||
<!-- init Test\my_function() -->
|
||||
<Test\my_function>
|
||||
my_function called
|
||||
</Test\my_function>
|
||||
</file '%s%eobserver_call_user_func_%d.php'>
|
||||
</call_user_func>
|
||||
</file '%s'>
|
||||
|
|
|
@ -26,14 +26,19 @@ namespace Test {
|
|||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_call_user_func_%d.php' -->
|
||||
<file '%s%eobserver_call_user_func_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init call_user_func_array() -->
|
||||
<call_user_func_array>
|
||||
<!-- init Test\MyClass::myMethod() -->
|
||||
<Test\MyClass::myMethod>
|
||||
MyClass::myMethod called
|
||||
</Test\MyClass::myMethod>
|
||||
</call_user_func_array>
|
||||
<call_user_func_array>
|
||||
<!-- init Test\my_function() -->
|
||||
<Test\my_function>
|
||||
my_function called
|
||||
</Test\my_function>
|
||||
</file '%s%eobserver_call_user_func_%d.php'>
|
||||
</call_user_func_array>
|
||||
</file '%s'>
|
||||
|
|
|
@ -23,27 +23,41 @@ $foo($bar);
|
|||
echo 'DONE' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_closure_%d.php' -->
|
||||
<file '%s%eobserver_closure_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<{closure}>
|
||||
Answer
|
||||
<!-- init {closure}() -->
|
||||
<{closure}>
|
||||
<!-- init array_sum() -->
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<!-- init var_dump() -->
|
||||
<var_dump>
|
||||
int(42)
|
||||
</var_dump>
|
||||
</{closure}>
|
||||
</{closure}>
|
||||
<{closure}>
|
||||
Answer
|
||||
<{closure}>
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(42)
|
||||
</var_dump>
|
||||
</{closure}>
|
||||
</{closure}>
|
||||
<{closure}>
|
||||
Answer
|
||||
<{closure}>
|
||||
<array_sum>
|
||||
</array_sum>
|
||||
<var_dump>
|
||||
int(42)
|
||||
</var_dump>
|
||||
</{closure}>
|
||||
</{closure}>
|
||||
DONE
|
||||
</file '%s%eobserver_closure_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -22,11 +22,14 @@ $closure();
|
|||
echo 'DONE' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_closure_%d.php' -->
|
||||
<file '%s%eobserver_closure_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init Closure::fromCallable() -->
|
||||
<Closure::fromCallable>
|
||||
</Closure::fromCallable>
|
||||
<!-- init Foo::bar() -->
|
||||
<Foo::bar>
|
||||
Called as fake closure.
|
||||
</Foo::bar>
|
||||
DONE
|
||||
</file '%s%eobserver_closure_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -19,11 +19,14 @@ foo();
|
|||
echo 'You should not see this.';
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_error_%d.php' -->
|
||||
<file '%s%eobserver_error_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init str_repeat() -->
|
||||
<str_repeat>
|
||||
|
||||
Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
|
||||
</str_repeat:NULL>
|
||||
</foo:NULL>
|
||||
</file '%s%eobserver_error_%d.php'>
|
||||
|
|
|
@ -18,11 +18,14 @@ foo();
|
|||
echo 'You should not see this.';
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_error_%d.php' -->
|
||||
<file '%s%eobserver_error_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init trigger_error() -->
|
||||
<trigger_error>
|
||||
|
||||
Fatal error: Foo error in %s on line %d
|
||||
</trigger_error:NULL>
|
||||
</foo:NULL>
|
||||
</file '%s%eobserver_error_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -36,10 +36,18 @@ echo 'Done.' . PHP_EOL;
|
|||
<main>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init SoapClient::__construct() -->
|
||||
<SoapClient::__construct>
|
||||
<!-- Exception: SoapFault -->
|
||||
</SoapClient::__construct:NULL>
|
||||
<!-- Exception: SoapFault -->
|
||||
</foo:NULL>
|
||||
<!-- Exception: SoapFault -->
|
||||
</main:NULL>
|
||||
<!-- init Exception::getMessage() -->
|
||||
<Exception::getMessage>
|
||||
</Exception::getMessage:'SOAP-ERROR: Parsing WSDL: Couldn\'t load from \'foo\' : failed to load external entity "foo"
|
||||
'>
|
||||
SOAP-ERROR: Parsing WSDL: Couldn't load from 'foo' : failed to load external entity "foo"
|
||||
|
||||
Done.
|
||||
|
|
|
@ -22,14 +22,20 @@ foo();
|
|||
echo 'You should not see this.';
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_error_%d.php' -->
|
||||
<file '%s%eobserver_error_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init set_error_handler() -->
|
||||
<set_error_handler>
|
||||
</set_error_handler:NULL>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init {closure}() -->
|
||||
<{closure}>
|
||||
<!-- init trigger_error() -->
|
||||
<trigger_error>
|
||||
|
||||
Fatal error: Foo error in %s on line %d
|
||||
</trigger_error:NULL>
|
||||
</{closure}:NULL>
|
||||
</foo:NULL>
|
||||
</file '%s%eobserver_error_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -23,8 +23,8 @@ foo();
|
|||
echo 'You should not see this' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_exception_%d.php' -->
|
||||
<file '%s%eobserver_exception_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
Call #0
|
||||
|
@ -34,10 +34,19 @@ Call #1
|
|||
</foo>
|
||||
<foo>
|
||||
Call #2
|
||||
<!-- init Exception::__construct() -->
|
||||
<Exception::__construct>
|
||||
</Exception::__construct>
|
||||
<!-- Exception: RuntimeException -->
|
||||
</foo>
|
||||
<!-- Exception: RuntimeException -->
|
||||
</file '%s%eobserver_exception_%d.php'>
|
||||
</file '%s'>
|
||||
<!-- init Exception::__toString() -->
|
||||
<Exception::__toString>
|
||||
<!-- init Exception::getTraceAsString() -->
|
||||
<Exception::getTraceAsString>
|
||||
</Exception::getTraceAsString>
|
||||
</Exception::__toString>
|
||||
|
||||
Fatal error: Uncaught RuntimeException: Third time is a charm in %s%eobserver_exception_%d.php:%d
|
||||
Stack trace:
|
||||
|
|
|
@ -19,13 +19,17 @@ $fiber->resume();
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_01.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- alloc: %s -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- init Fiber::resume() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<resume '%s'>
|
||||
<!-- switching from fiber %s to %s -->
|
||||
|
|
|
@ -16,10 +16,13 @@ $fiber->start();
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_02.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- switching from fiber %s to %s -->
|
||||
|
|
|
@ -39,14 +39,19 @@ $fiber->resume();
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_03.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- init Fiber::resume() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<resume '%s'>
|
||||
<!-- init var_dump() -->
|
||||
int(1)
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
|
|
|
@ -26,12 +26,16 @@ $fiber->resume();
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_04.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- init Fiber::resume() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<resume '%s'>
|
||||
<!-- switching from fiber %s to %s -->
|
||||
|
|
|
@ -25,12 +25,16 @@ $fiber->resume();
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_05.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- init Fiber::resume() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<resume '%s'>
|
||||
<!-- switching from fiber %s to %s -->
|
||||
|
|
|
@ -22,12 +22,17 @@ try {
|
|||
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%sobserver_fiber_06.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- init Fiber::__construct() -->
|
||||
<!-- init Fiber::start() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<init '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<!-- init Fiber::suspend() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<suspend '%s'>
|
||||
<!-- init Exception::__construct() -->
|
||||
<!-- init Fiber::throw() -->
|
||||
<!-- switching from fiber %s to %s -->
|
||||
<resume '%s'>
|
||||
<!-- switching from fiber %s to %s -->
|
||||
|
|
|
@ -28,8 +28,8 @@ function doSomething() {
|
|||
echo doSomething() . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_generator_%d.php' -->
|
||||
<file '%s%eobserver_generator_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init doSomething() -->
|
||||
<doSomething>
|
||||
<!-- init getResults() -->
|
||||
|
@ -44,7 +44,10 @@ echo doSomething() . PHP_EOL;
|
|||
12
|
||||
<getResults>
|
||||
</getResults:1337>
|
||||
<!-- init Generator::getReturn() -->
|
||||
<Generator::getReturn>
|
||||
</Generator::getReturn:1337>
|
||||
1337
|
||||
</doSomething:'Done'>
|
||||
Done
|
||||
</file '%s%eobserver_generator_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -33,32 +33,87 @@ function doSomething() {
|
|||
echo doSomething() . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_generator_%d.php' -->
|
||||
<file '%s%eobserver_generator_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init doSomething() -->
|
||||
<doSomething>
|
||||
<!-- init Generator::current() -->
|
||||
<Generator::current>
|
||||
<!-- init fooResults() -->
|
||||
<fooResults>
|
||||
Starting generator
|
||||
</fooResults:0>
|
||||
</Generator::current:0>
|
||||
<Generator::current>
|
||||
</Generator::current:0>
|
||||
0
|
||||
<Generator::current>
|
||||
</Generator::current:0>
|
||||
<!-- init Generator::next() -->
|
||||
<Generator::next>
|
||||
<fooResults>
|
||||
</fooResults:1>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:1>
|
||||
<Generator::current>
|
||||
</Generator::current:1>
|
||||
1
|
||||
<Generator::current>
|
||||
</Generator::current:1>
|
||||
<Generator::next>
|
||||
<fooResults>
|
||||
</fooResults:2>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:2>
|
||||
<Generator::current>
|
||||
</Generator::current:2>
|
||||
2
|
||||
<Generator::current>
|
||||
</Generator::current:2>
|
||||
<Generator::next>
|
||||
<fooResults>
|
||||
</fooResults:3>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:3>
|
||||
<Generator::current>
|
||||
</Generator::current:3>
|
||||
3
|
||||
<Generator::current>
|
||||
</Generator::current:3>
|
||||
<Generator::next>
|
||||
<fooResults>
|
||||
</fooResults:4>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:4>
|
||||
<Generator::current>
|
||||
</Generator::current:4>
|
||||
4
|
||||
<Generator::current>
|
||||
</Generator::current:4>
|
||||
<Generator::next>
|
||||
<fooResults>
|
||||
</fooResults:5>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:5>
|
||||
<Generator::current>
|
||||
</Generator::current:5>
|
||||
5
|
||||
<Generator::current>
|
||||
</Generator::current:5>
|
||||
<!-- init Generator::send() -->
|
||||
<Generator::send>
|
||||
<fooResults>
|
||||
</fooResults:NULL>
|
||||
</Generator::send:NULL>
|
||||
<Generator::next>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:NULL>
|
||||
</doSomething:'Done'>
|
||||
Done
|
||||
</file '%s%eobserver_generator_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -26,8 +26,8 @@ function doSomething() {
|
|||
echo doSomething() . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_generator_%d.php' -->
|
||||
<file '%s%eobserver_generator_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init doSomething() -->
|
||||
<doSomething>
|
||||
<!-- init fooResults() -->
|
||||
|
@ -38,12 +38,27 @@ echo doSomething() . PHP_EOL;
|
|||
</fooResults:1>
|
||||
1
|
||||
<fooResults>
|
||||
<!-- init Exception::__construct() -->
|
||||
<Exception::__construct>
|
||||
</Exception::__construct:NULL>
|
||||
<!-- Exception: RuntimeException -->
|
||||
</fooResults:NULL>
|
||||
<!-- Exception: RuntimeException -->
|
||||
</doSomething:NULL>
|
||||
<!-- Exception: RuntimeException -->
|
||||
</file '%s%eobserver_generator_%d.php'>
|
||||
</file '%s'>
|
||||
<!-- init Exception::__toString() -->
|
||||
<Exception::__toString>
|
||||
<!-- init Exception::getTraceAsString() -->
|
||||
<Exception::getTraceAsString>
|
||||
</Exception::getTraceAsString:'#0 %s(%d): fooResults()
|
||||
#1 %s(%d): doSomething()
|
||||
#2 {main}'>
|
||||
</Exception::__toString:'RuntimeException: Oops! in %s%eobserver_generator_%d.php:%d
|
||||
Stack trace:
|
||||
#0 %s%eobserver_generator_%d.php(%d): fooResults()
|
||||
#1 %s%eobserver_generator_%d.php(%d): doSomething()
|
||||
#2 {main}'>
|
||||
|
||||
Fatal error: Uncaught RuntimeException: Oops! in %s%eobserver_generator_%d.php:%d
|
||||
Stack trace:
|
||||
|
|
|
@ -20,9 +20,9 @@ echo array_sum([1,2,3]) . PHP_EOL;
|
|||
foo();
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_opline_%d.php' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<file '%s%eobserver_opline_%d.php'>
|
||||
<file '%s'>
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<!-- init foo() -->
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
|
@ -31,9 +31,9 @@ foo();
|
|||
Foo
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo>
|
||||
<!-- init '%s%eobserver.inc' -->
|
||||
<!-- init '%s' -->
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<file '%s%eobserver.inc'>
|
||||
<file '%s'>
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<!-- init foo_observer_test() -->
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
|
@ -43,7 +43,13 @@ foo_observer_test
|
|||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo_observer_test>
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</file '%s%eobserver.inc'>
|
||||
</file '%s'>
|
||||
<!-- init array_sum() -->
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
<array_sum>
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</array_sum>
|
||||
6
|
||||
<foo>
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
|
@ -51,4 +57,4 @@ Foo
|
|||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo>
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</file '%s%eobserver_opline_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -21,12 +21,20 @@ $gen->current();
|
|||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_retval_%d.php' -->
|
||||
<file '%s%eobserver_retval_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init Generator::current() -->
|
||||
<Generator::current>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
</Generator::current:'I should be observable'>
|
||||
<!-- init Generator::next() -->
|
||||
<Generator::next>
|
||||
<foo>
|
||||
</foo:'Me too!'>
|
||||
</Generator::next:NULL>
|
||||
<Generator::current>
|
||||
</Generator::current:'Me too!'>
|
||||
Done
|
||||
</file '%s%eobserver_retval_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
|
@ -24,13 +24,16 @@ function foo() {
|
|||
echo 'Done: ' . bar(40) . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_shutdown_%d.php' -->
|
||||
<file '%s%eobserver_shutdown_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init register_shutdown_function() -->
|
||||
<register_shutdown_function>
|
||||
</register_shutdown_function:NULL>
|
||||
<!-- init bar() -->
|
||||
<bar>
|
||||
</bar:40>
|
||||
Done: 40
|
||||
</file '%s%eobserver_shutdown_%d.php'>
|
||||
</file '%s'>
|
||||
<!-- init {closure}() -->
|
||||
<{closure}>
|
||||
<!-- init foo() -->
|
||||
|
|
|
@ -12,14 +12,24 @@ function foo(array $a) { return 1; }
|
|||
foo(42);
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_types_%d.php' -->
|
||||
<file '%s%eobserver_types_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- Exception: TypeError -->
|
||||
</foo:NULL>
|
||||
<!-- Exception: TypeError -->
|
||||
</file '%s%eobserver_types_%d.php'>
|
||||
</file '%s'>
|
||||
<!-- init Error::__toString() -->
|
||||
<Error::__toString>
|
||||
<!-- init Error::getTraceAsString() -->
|
||||
<Error::getTraceAsString>
|
||||
</Error::getTraceAsString:'#0 %s(%d): foo(42)
|
||||
#1 {main}'>
|
||||
</Error::__toString:'TypeError: foo(): Argument #1 ($a) must be of type array, int given, called in %s:%d
|
||||
Stack trace:
|
||||
#0 %s%eobserver_types_%d.php(%d): foo(42)
|
||||
#1 {main}'>
|
||||
|
||||
Fatal error: Uncaught TypeError: foo(): Argument #1 ($a) must be of type array, int given, called in %s:%d
|
||||
Stack trace:
|
||||
|
|
|
@ -18,8 +18,10 @@ var_dump(array_reduce($a, 'sum'));
|
|||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s%eobserver_zend_call_function_%d.php' -->
|
||||
<file '%s%eobserver_zend_call_function_%d.php'>
|
||||
<!-- init '%s' -->
|
||||
<file '%s'>
|
||||
<!-- init array_reduce() -->
|
||||
<array_reduce>
|
||||
<!-- init sum() -->
|
||||
<sum>
|
||||
</sum>
|
||||
|
@ -31,6 +33,10 @@ echo 'Done' . PHP_EOL;
|
|||
</sum>
|
||||
<sum>
|
||||
</sum>
|
||||
</array_reduce>
|
||||
<!-- init var_dump() -->
|
||||
<var_dump>
|
||||
int(15)
|
||||
</var_dump>
|
||||
Done
|
||||
</file '%s%eobserver_zend_call_function_%d.php'>
|
||||
</file '%s'>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue