diff --git a/composer.json b/composer.json index de37408..5900d49 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Library that provides direct access to native PHP structures", "type": "library", "require": { - "php": "8.2.*", + "php": "8.3.*", "ext-ffi": "*" }, "license": [ diff --git a/include/engine_x64_nts.h b/include/engine_x64_nts.h index 4d7871e..6d226cf 100644 --- a/include/engine_x64_nts.h +++ b/include/engine_x64_nts.h @@ -4,16 +4,17 @@ typedef int64_t zend_long; typedef uint64_t zend_ulong; typedef int64_t zend_off_t; +typedef uint64_t zend_hrtime_t; typedef unsigned char zend_uchar; typedef unsigned long uintptr_t; typedef struct { - /* Not using a union here, because there's no good way to initialize them - * in a way that is supported in both C and C++ (designated initializers - * are only supported since C++20). */ - void *ptr; - uint32_t type_mask; - /* TODO: We could use the extra 32-bit of padding on 64-bit systems. */ + /* Not using a union here, because there's no good way to initialize them + * in a way that is supported in both C and C++ (designated initializers + * are only supported since C++20). */ + void *ptr; + uint32_t type_mask; + /* TODO: We could use the extra 32-bit of padding on 64-bit systems. */ } zend_type; typedef enum { @@ -46,147 +47,148 @@ typedef void (*dtor_func_t)(zval *pDest); typedef void (*copy_ctor_func_t)(zval *pElement); typedef union _zend_value { - zend_long lval; /* long value */ - double dval; /* double value */ - zend_refcounted *counted; - zend_string *str; - zend_array *arr; - zend_object *obj; - zend_resource *res; - zend_reference *ref; - zend_ast_ref *ast; - zval *zv; - void *ptr; - zend_class_entry *ce; - zend_function *func; - struct { - uint32_t w1; - uint32_t w2; - } ww; + zend_long lval; /* long value */ + double dval; /* double value */ + zend_refcounted *counted; + zend_string *str; + zend_array *arr; + zend_object *obj; + zend_resource *res; + zend_reference *ref; + zend_ast_ref *ast; + zval *zv; + void *ptr; + zend_class_entry *ce; + zend_function *func; + struct { + uint32_t w1; + uint32_t w2; + } ww; } zend_value; struct _zval_struct { - zend_value value; /* value */ - union { - uint32_t type_info; - struct { - zend_uchar type; /* active type */ - zend_uchar type_flags; - union { - uint16_t extra; /* not further specified */ - } u; - } v; - } u1; - union { - uint32_t next; /* hash collision chain */ - uint32_t cache_slot; /* cache slot (for RECV_INIT) */ - uint32_t opline_num; /* opline number (for FAST_CALL) */ - uint32_t lineno; /* line number (for ast nodes) */ - uint32_t num_args; /* arguments number for EX(This) */ - uint32_t fe_pos; /* foreach position */ - uint32_t fe_iter_idx; /* foreach iterator index */ - uint32_t property_guard; /* single property guard */ - uint32_t constant_flags; /* constant flags */ - uint32_t extra; /* not further specified */ - } u2; + zend_value value; /* value */ + union { + uint32_t type_info; + struct { + zend_uchar type; /* active type */ + zend_uchar type_flags; + union { + uint16_t extra; /* not further specified */ + } u; + } v; + } u1; + union { + uint32_t next; /* hash collision chain */ + uint32_t cache_slot; /* cache slot (for RECV_INIT) */ + uint32_t opline_num; /* opline number (for FAST_CALL) */ + uint32_t lineno; /* line number (for ast nodes) */ + uint32_t num_args; /* arguments number for EX(This) */ + uint32_t fe_pos; /* foreach position */ + uint32_t fe_iter_idx; /* foreach iterator index */ + uint32_t guard; /* recursion and single property guard */ + uint32_t constant_flags; /* constant flags */ + uint32_t extra; /* not further specified */ + } u2; }; typedef struct _zend_refcounted_h { - uint32_t refcount; /* reference counter 32-bit */ - union { - uint32_t type_info; - } u; + uint32_t refcount; /* reference counter 32-bit */ + union { + uint32_t type_info; + } u; } zend_refcounted_h; struct _zend_refcounted { - zend_refcounted_h gc; + zend_refcounted_h gc; }; struct _zend_string { - zend_refcounted_h gc; - zend_ulong h; /* hash value */ - size_t len; - char val[1]; + zend_refcounted_h gc; + zend_ulong h; /* hash value */ + size_t len; + char val[1]; }; typedef struct _Bucket { - zval val; - zend_ulong h; /* hash value (or numeric index) */ - zend_string *key; /* string key or NULL for numerics */ + zval val; + zend_ulong h; /* hash value (or numeric index) */ + zend_string *key; /* string key or NULL for numerics */ } Bucket; typedef struct _zend_array HashTable; struct _zend_array { - zend_refcounted_h gc; - union { - struct { - zend_uchar flags; - zend_uchar _unused; - zend_uchar nIteratorsCount; - zend_uchar _unused2; - } v; - uint32_t flags; - } u; - uint32_t nTableMask; - union { - uint32_t *arHash; /* hash table (allocated above this pointer) */ - Bucket *arData; /* array of hash buckets */ - zval *arPacked; /* packed array of zvals */ - }; - uint32_t nNumUsed; - uint32_t nNumOfElements; - uint32_t nTableSize; - uint32_t nInternalPointer; - zend_long nNextFreeElement; - dtor_func_t pDestructor; + zend_refcounted_h gc; + union { + struct { + uint8_t flags; + uint8_t _unused; + uint8_t nIteratorsCount; + uint8_t _unused2; + } v; + uint32_t flags; + } u; + uint32_t nTableMask; + union { + uint32_t *arHash; /* hash table (allocated above this pointer) */ + Bucket *arData; /* array of hash buckets */ + zval *arPacked; /* packed array of zvals */ + }; + uint32_t nNumUsed; + uint32_t nNumOfElements; + uint32_t nTableSize; + uint32_t nInternalPointer; + zend_long nNextFreeElement; + dtor_func_t pDestructor; }; typedef uint32_t HashPosition; typedef struct _HashTableIterator { - HashTable *ht; - HashPosition pos; + HashTable *ht; + HashPosition pos; + uint32_t next_copy; // circular linked list via index into EG(ht_iterators) } HashTableIterator; struct _zend_object { - zend_refcounted_h gc; - uint32_t handle; // TODO: may be removed ??? - zend_class_entry *ce; - const zend_object_handlers *handlers; - HashTable *properties; - zval properties_table[1]; + zend_refcounted_h gc; + uint32_t handle; // TODO: may be removed ??? + zend_class_entry *ce; + const zend_object_handlers *handlers; + HashTable *properties; + zval properties_table[1]; }; struct _zend_resource { - zend_refcounted_h gc; - zend_long handle; // TODO: may be removed ??? - int type; - void *ptr; + zend_refcounted_h gc; + zend_long handle; // TODO: may be removed ??? + int type; + void *ptr; }; typedef struct _zend_property_info zend_property_info; typedef struct { - size_t num; - size_t num_allocated; - struct _zend_property_info *ptr[1]; + size_t num; + size_t num_allocated; + struct _zend_property_info *ptr[1]; } zend_property_info_list; typedef union { - struct _zend_property_info *ptr; - uintptr_t list; + struct _zend_property_info *ptr; + uintptr_t list; } zend_property_info_source_list; struct _zend_reference { - zend_refcounted_h gc; - zval val; - zend_property_info_source_list sources; + zend_refcounted_h gc; + zval val; + zend_property_info_source_list sources; }; struct _zend_ast_ref { - zend_refcounted_h gc; - /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ + zend_refcounted_h gc; + /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ }; /* zend_ast.h */ @@ -194,39 +196,38 @@ typedef uint16_t zend_ast_kind; typedef uint16_t zend_ast_attr; struct _zend_ast { - zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ - zend_ast_attr attr; /* Additional attribute, use depending on node type */ - uint32_t lineno; /* Line number */ - zend_ast *child[1]; /* Array of children (using struct hack) */ + zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ + zend_ast_attr attr; /* Additional attribute, use depending on node type */ + uint32_t lineno; /* Line number */ + zend_ast *child[1]; /* Array of children (using struct hack) */ }; /* Same as zend_ast, but with children count, which is updated dynamically */ typedef struct _zend_ast_list { - zend_ast_kind kind; - zend_ast_attr attr; - uint32_t lineno; - uint32_t children; - zend_ast *child[1]; + zend_ast_kind kind; + zend_ast_attr attr; + uint32_t lineno; + uint32_t children; + zend_ast *child[1]; } zend_ast_list; /* Lineno is stored in val.u2.lineno */ typedef struct _zend_ast_zval { - zend_ast_kind kind; - zend_ast_attr attr; - zval val; + zend_ast_kind kind; + zend_ast_attr attr; + zval val; } zend_ast_zval; /* Separate structure for function and class declaration, as they need extra information. */ typedef struct _zend_ast_decl { - zend_ast_kind kind; - zend_ast_attr attr; /* Unused - for structure compatibility */ - uint32_t start_lineno; - uint32_t end_lineno; - uint32_t flags; - unsigned char *lex_pos; - zend_string *doc_comment; - zend_string *name; - zend_ast *child[5]; + zend_ast_kind kind; + zend_ast_attr attr; /* Unused - for structure compatibility */ + uint32_t start_lineno; + uint32_t end_lineno; + uint32_t flags; + zend_string *doc_comment; + zend_string *name; + zend_ast *child[5]; } zend_ast_decl; typedef void (*zend_ast_process_t)(zend_ast *ast); @@ -239,9 +240,9 @@ typedef uintptr_t zend_uintptr_t; typedef struct _zend_arena zend_arena; struct _zend_arena { - char *ptr; - char *end; - zend_arena *prev; + char *ptr; + char *end; + zend_arena *prev; }; /* zend_compile.h */ @@ -249,271 +250,272 @@ typedef struct _zend_op_array zend_op_array; typedef struct _zend_op zend_op; typedef union _znode_op { - uint32_t constant; - uint32_t var; - uint32_t num; - uint32_t opline_num; /* Needs to be signed */ - - // We haven't support for #if..#endif constructions, so this resolved by hand - // #if ZEND_USE_ABS_JMP_ADDR - // zend_op *jmp_addr; - // #else - uint32_t jmp_offset; - // #endif - // #if ZEND_USE_ABS_CONST_ADDR - // zval *zv; - // #endif + uint32_t constant; + uint32_t var; + uint32_t num; + uint32_t opline_num; /* Needs to be signed */ + + // We haven't support for #if..#endif constructions, so this resolved by hand + // #if ZEND_USE_ABS_JMP_ADDR + // zend_op *jmp_addr; + // #else + uint32_t jmp_offset; + // #endif + // #if ZEND_USE_ABS_CONST_ADDR + // zval *zv; + // #endif } znode_op; typedef struct _znode { /* used only during compilation */ - zend_uchar op_type; - zend_uchar flag; - union { - znode_op op; - zval constant; /* replaced by literal/zv */ - } u; + uint8_t op_type; + uint8_t flag; + union { + znode_op op; + zval constant; /* replaced by literal/zv */ + } u; } znode; typedef struct _zend_ast_znode { - zend_ast_kind kind; - zend_ast_attr attr; - uint32_t lineno; - znode node; + zend_ast_kind kind; + zend_ast_attr attr; + uint32_t lineno; + znode node; } zend_ast_znode; typedef struct _zend_declarables { - zend_long ticks; + zend_long ticks; } zend_declarables; typedef struct _zend_file_context { - zend_declarables declarables; + zend_declarables declarables; - zend_string *current_namespace; - bool in_namespace; - bool has_bracketed_namespaces; + zend_string *current_namespace; + bool in_namespace; + bool has_bracketed_namespaces; - HashTable *imports; - HashTable *imports_function; - HashTable *imports_const; + HashTable *imports; + HashTable *imports_function; + HashTable *imports_const; - HashTable seen_symbols; + HashTable seen_symbols; } zend_file_context; typedef union _zend_parser_stack_elem { - zend_ast *ast; - zend_string *str; - zend_ulong num; - unsigned char *ptr; - unsigned char *ident; + zend_ast *ast; + zend_string *str; + zend_ulong num; + unsigned char *ptr; + unsigned char *ident; } zend_parser_stack_elem; typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data); struct _zend_op { - const void *handler; - znode_op op1; - znode_op op2; - znode_op result; - uint32_t extended_value; - uint32_t lineno; - zend_uchar opcode; - zend_uchar op1_type; - zend_uchar op2_type; - zend_uchar result_type; + const void *handler; + znode_op op1; + znode_op op2; + znode_op result; + uint32_t extended_value; + uint32_t lineno; + uint8_t opcode; /* Opcodes defined in Zend/zend_vm_opcodes.h */ + uint8_t op1_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */ + uint8_t op2_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */ + uint8_t result_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */ }; typedef struct _zend_brk_cont_element { - int start; - int cont; - int brk; - int parent; - bool is_switch; + int start; + int cont; + int brk; + int parent; + bool is_switch; } zend_brk_cont_element; typedef struct _zend_label { - int brk_cont; - uint32_t opline_num; + int brk_cont; + uint32_t opline_num; } zend_label; typedef struct _zend_try_catch_element { - uint32_t try_op; - uint32_t catch_op; /* ketchup! */ - uint32_t finally_op; - uint32_t finally_end; + uint32_t try_op; + uint32_t catch_op; /* ketchup! */ + uint32_t finally_op; + uint32_t finally_end; } zend_try_catch_element; typedef struct _zend_live_range { - uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */ - uint32_t start; - uint32_t end; + uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */ + uint32_t start; + uint32_t end; } zend_live_range; typedef struct _zend_oparray_context { - uint32_t opcodes_size; - int vars_size; - int literals_size; - uint32_t fast_call_var; - uint32_t try_catch_offset; - int current_brk_cont; - int last_brk_cont; - zend_brk_cont_element *brk_cont_array; - HashTable *labels; + uint32_t opcodes_size; + int vars_size; + int literals_size; + uint32_t fast_call_var; + uint32_t try_catch_offset; + int current_brk_cont; + int last_brk_cont; + zend_brk_cont_element *brk_cont_array; + HashTable *labels; } zend_oparray_context; typedef struct _zend_property_info { - uint32_t offset; /* property offset for object properties or - property index for static properties */ - uint32_t flags; - zend_string *name; - zend_string *doc_comment; - HashTable *attributes; - zend_class_entry *ce; - zend_type type; + uint32_t offset; /* property offset for object properties or + property index for static properties */ + uint32_t flags; + zend_string *name; + zend_string *doc_comment; + HashTable *attributes; + zend_class_entry *ce; + zend_type type; } zend_property_info; typedef struct _zend_class_constant { - zval value; /* flags are stored in u2 */ - zend_string *doc_comment; - HashTable *attributes; - zend_class_entry *ce; + zval value; /* flags are stored in u2 */ + zend_string *doc_comment; + HashTable *attributes; + zend_class_entry *ce; + zend_type type; } zend_class_constant; /* arg_info for internal functions */ typedef struct _zend_internal_arg_info { - const char *name; - zend_type type; - const char *default_value; + const char *name; + zend_type type; + const char *default_value; } zend_internal_arg_info; /* arg_info for user functions */ typedef struct _zend_arg_info { - zend_string *name; - zend_type type; - zend_string *default_value; + zend_string *name; + zend_type type; + zend_string *default_value; } zend_arg_info; typedef struct _zend_internal_function_info { - zend_uintptr_t required_num_args; - zend_type type; - const char *default_value; + uintptr_t required_num_args; + zend_type type; + const char *default_value; } zend_internal_function_info; struct _zend_op_array { - /* Common elements */ - zend_uchar type; - zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */ - uint32_t fn_flags; - zend_string *function_name; - zend_class_entry *scope; - zend_function *prototype; - uint32_t num_args; - uint32_t required_num_args; - zend_arg_info *arg_info; - HashTable *attributes; - uint32_t T; /* number of temporary variables */ - void ** * run_time_cache; - /* END of common elements */ - - int cache_size; /* number of run_time_cache_slots * sizeof(void*) */ - int last_var; /* number of CV variables */ - uint32_t last; /* number of opcodes */ - - zend_op *opcodes; - HashTable * * static_variables_ptr; - HashTable *static_variables; - zend_string **vars; /* names of CV variables */ - - uint32_t *refcount; - - int last_live_range; - int last_try_catch; - zend_live_range *live_range; - zend_try_catch_element *try_catch_array; - - zend_string *filename; - uint32_t line_start; - uint32_t line_end; - zend_string *doc_comment; - - int last_literal; - uint32_t num_dynamic_func_defs; - zval *literals; - - /* Functions that are declared dynamically are stored here and - * referenced by index from opcodes. */ - zend_op_array **dynamic_func_defs; - - void *reserved[6]; + /* Common elements */ + uint8_t type; + uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ + uint32_t fn_flags; + zend_string *function_name; + zend_class_entry *scope; + zend_function *prototype; + uint32_t num_args; + uint32_t required_num_args; + zend_arg_info *arg_info; + HashTable *attributes; + void ** * run_time_cache; + uint32_t T; /* number of temporary variables */ + /* END of common elements */ + + int cache_size; /* number of run_time_cache_slots * sizeof(void*) */ + int last_var; /* number of CV variables */ + uint32_t last; /* number of opcodes */ + + zend_op *opcodes; + HashTable * * static_variables_ptr; + HashTable *static_variables; + zend_string **vars; /* names of CV variables */ + + uint32_t *refcount; + + int last_live_range; + int last_try_catch; + zend_live_range *live_range; + zend_try_catch_element *try_catch_array; + + zend_string *filename; + uint32_t line_start; + uint32_t line_end; + zend_string *doc_comment; + + int last_literal; + uint32_t num_dynamic_func_defs; + zval *literals; + + /* Functions that are declared dynamically are stored here and + * referenced by index from opcodes. */ + zend_op_array **dynamic_func_defs; + + void *reserved[6]; }; /* zend_internal_function_handler */ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS); typedef struct _zend_internal_function { - /* Common elements */ - zend_uchar type; - zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */ - uint32_t fn_flags; - zend_string* function_name; - zend_class_entry *scope; - zend_function *prototype; - uint32_t num_args; - uint32_t required_num_args; - zend_internal_arg_info *arg_info; - HashTable *attributes; - uint32_t T; /* number of temporary variables */ - void ** * run_time_cache; - /* END of common elements */ - - zif_handler handler; - struct _zend_module_entry *module; - void *reserved[6]; + /* Common elements */ + uint8_t type; + uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ + uint32_t fn_flags; + zend_string* function_name; + zend_class_entry *scope; + zend_function *prototype; + uint32_t num_args; + uint32_t required_num_args; + zend_internal_arg_info *arg_info; + HashTable *attributes; + void ** * run_time_cache; + uint32_t T; /* number of temporary variables */ + /* END of common elements */ + + zif_handler handler; + struct _zend_module_entry *module; + void *reserved[6]; } zend_internal_function; union _zend_function { - zend_uchar type; /* MUST be the first element of this struct! */ - uint32_t quick_arg_flags; - - struct { - zend_uchar type; /* never used */ - zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */ - uint32_t fn_flags; - zend_string *function_name; - zend_class_entry *scope; - zend_function *prototype; - uint32_t num_args; - uint32_t required_num_args; - zend_arg_info *arg_info; /* index -1 represents the return value info, if any */ - HashTable *attributes; - uint32_t T; /* number of temporary variables */ - void ** * run_time_cache; - } common; - - zend_op_array op_array; - zend_internal_function internal_function; + uint8_t type; /* MUST be the first element of this struct! */ + uint32_t quick_arg_flags; + + struct { + uint8_t type; /* never used */ + uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ + uint32_t fn_flags; + zend_string *function_name; + zend_class_entry *scope; + zend_function *prototype; + uint32_t num_args; + uint32_t required_num_args; + zend_arg_info *arg_info; /* index -1 represents the return value info, if any */ + HashTable *attributes; + void ** * run_time_cache; + uint32_t T; /* number of temporary variables */ + } common; + + zend_op_array op_array; + zend_internal_function internal_function; }; typedef struct _zend_execute_data zend_execute_data; struct _zend_execute_data { - const zend_op *opline; /* executed opline */ - zend_execute_data *call; /* current call */ - zval *return_value; - zend_function *func; /* executed function */ - zval This; /* this + call_info + num_args */ - zend_execute_data *prev_execute_data; - zend_array *symbol_table; - void **run_time_cache; /* cache op_array->run_time_cache */ - zend_array *extra_named_params; + const zend_op *opline; /* executed opline */ + zend_execute_data *call; /* current call */ + zval *return_value; + zend_function *func; /* executed function */ + zval This; /* this + call_info + num_args */ + zend_execute_data *prev_execute_data; + zend_array *symbol_table; + void **run_time_cache; /* cache op_array->run_time_cache */ + zend_array *extra_named_params; }; /* zend_closurec.c */ typedef struct _zend_closure { - zend_object std; - zend_function func; - zval this_ptr; - zend_class_entry *called_scope; - zif_handler orig_internal_handler; + zend_object std; + zend_function func; + zval this_ptr; + zend_class_entry *called_scope; + zif_handler orig_internal_handler; } zend_closure; /* zend_object_handlers.h */ @@ -568,20 +570,20 @@ typedef HashTable *(*zend_object_get_properties_t)(zend_object *object); typedef HashTable *(*zend_object_get_debug_info_t)(zend_object *object, int *is_temp); typedef enum _zend_prop_purpose { - /* Used for debugging. Supersedes get_debug_info handler. */ - ZEND_PROP_PURPOSE_DEBUG, - /* Used for (array) casts. */ - ZEND_PROP_PURPOSE_ARRAY_CAST, - /* Used for serialization using the "O" scheme. - * Unserialization will use __wakeup(). */ - ZEND_PROP_PURPOSE_SERIALIZE, - /* Used for var_export(). - * The data will be passed to __set_state() when evaluated. */ - ZEND_PROP_PURPOSE_VAR_EXPORT, - /* Used for json_encode(). */ - ZEND_PROP_PURPOSE_JSON, - /* Dummy member to ensure that "default" is specified. */ - _ZEND_PROP_PURPOSE_NON_EXHAUSTIVE_ENUM + /* Used for debugging. Supersedes get_debug_info handler. */ + ZEND_PROP_PURPOSE_DEBUG, + /* Used for (array) casts. */ + ZEND_PROP_PURPOSE_ARRAY_CAST, + /* Used for serialization using the "O" scheme. + * Unserialization will use __wakeup(). */ + ZEND_PROP_PURPOSE_SERIALIZE, + /* Used for var_export(). + * The data will be passed to __set_state() when evaluated. */ + ZEND_PROP_PURPOSE_VAR_EXPORT, + /* Used for json_encode(). */ + ZEND_PROP_PURPOSE_JSON, + /* Dummy member to ensure that "default" is specified. */ + _ZEND_PROP_PURPOSE_NON_EXHAUSTIVE_ENUM } zend_prop_purpose; /* The return value must be released using zend_release_properties(). */ @@ -618,43 +620,43 @@ typedef zend_result (*zend_object_get_closure_t)(zend_object *obj, zend_class_en typedef HashTable *(*zend_object_get_gc_t)(zend_object *object, zval **table, int *n); -typedef zend_result (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval *op1, zval *op2); +typedef zend_result (*zend_object_do_operation_t)(uint8_t opcode, zval *result, zval *op1, zval *op2); struct _zend_object_handlers { - /* offset of real object header (usually zero) */ - int offset; - /* object handlers */ - zend_object_free_obj_t free_obj; /* required */ - zend_object_dtor_obj_t dtor_obj; /* required */ - zend_object_clone_obj_t clone_obj; /* optional */ - zend_object_read_property_t read_property; /* required */ - zend_object_write_property_t write_property; /* required */ - zend_object_read_dimension_t read_dimension; /* required */ - zend_object_write_dimension_t write_dimension; /* required */ - zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */ - zend_object_has_property_t has_property; /* required */ - zend_object_unset_property_t unset_property; /* required */ - zend_object_has_dimension_t has_dimension; /* required */ - zend_object_unset_dimension_t unset_dimension; /* required */ - zend_object_get_properties_t get_properties; /* required */ - zend_object_get_method_t get_method; /* required */ - zend_object_get_constructor_t get_constructor; /* required */ - zend_object_get_class_name_t get_class_name; /* required */ - zend_object_cast_t cast_object; /* required */ - zend_object_count_elements_t count_elements; /* optional */ - zend_object_get_debug_info_t get_debug_info; /* optional */ - zend_object_get_closure_t get_closure; /* optional */ - zend_object_get_gc_t get_gc; /* required */ - zend_object_do_operation_t do_operation; /* optional */ - zend_object_compare_t compare; /* required */ - zend_object_get_properties_for_t get_properties_for; /* optional */ + /* offset of real object header (usually zero) */ + int offset; + /* object handlers */ + zend_object_free_obj_t free_obj; /* required */ + zend_object_dtor_obj_t dtor_obj; /* required */ + zend_object_clone_obj_t clone_obj; /* optional */ + zend_object_read_property_t read_property; /* required */ + zend_object_write_property_t write_property; /* required */ + zend_object_read_dimension_t read_dimension; /* required */ + zend_object_write_dimension_t write_dimension; /* required */ + zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */ + zend_object_has_property_t has_property; /* required */ + zend_object_unset_property_t unset_property; /* required */ + zend_object_has_dimension_t has_dimension; /* required */ + zend_object_unset_dimension_t unset_dimension; /* required */ + zend_object_get_properties_t get_properties; /* required */ + zend_object_get_method_t get_method; /* required */ + zend_object_get_constructor_t get_constructor; /* required */ + zend_object_get_class_name_t get_class_name; /* required */ + zend_object_cast_t cast_object; /* required */ + zend_object_count_elements_t count_elements; /* optional */ + zend_object_get_debug_info_t get_debug_info; /* optional */ + zend_object_get_closure_t get_closure; /* optional */ + zend_object_get_gc_t get_gc; /* required */ + zend_object_do_operation_t do_operation; /* optional */ + zend_object_compare_t compare; /* required */ + zend_object_get_properties_for_t get_properties_for; /* optional */ }; /* zend_llist.h*/ typedef struct _zend_llist_element { - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ } zend_llist_element; typedef void (*llist_dtor_func_t)(void *); @@ -664,13 +666,13 @@ typedef void (*llist_apply_with_arg_func_t)(void *data, void *arg); typedef void (*llist_apply_func_t)(void *); typedef struct _zend_llist { - zend_llist_element *head; - zend_llist_element *tail; - size_t count; - size_t size; - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; + zend_llist_element *head; + zend_llist_element *tail; + size_t count; + size_t size; + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; } zend_llist; typedef zend_llist_element* zend_llist_position; @@ -680,8 +682,8 @@ typedef struct _zend_encoding zend_encoding; /* zend_stack.h */ typedef struct _zend_stack { - int size, top, max; - void *elements; + int size, top, max; + void *elements; } zend_stack; /* zend_globals.h */ @@ -689,97 +691,98 @@ typedef struct _zend_vm_stack *zend_vm_stack; typedef struct _zend_ini_entry zend_ini_entry; typedef enum { - ON_TOKEN, - ON_FEEDBACK, - ON_STOP + ON_TOKEN, + ON_FEEDBACK, + ON_STOP } zend_php_scanner_event; /* zend_execute.h */ typedef struct _zend_vm_stack *zend_vm_stack; struct _zend_vm_stack { - zval *top; - zval *end; - zend_vm_stack prev; + zval *top; + zval *end; + zend_vm_stack prev; }; /* zend_API.h */ typedef struct _zend_function_entry { - const char *fname; - zif_handler handler; - const struct _zend_internal_arg_info *arg_info; - uint32_t num_args; - uint32_t flags; + const char *fname; + zif_handler handler; + const struct _zend_internal_arg_info *arg_info; + uint32_t num_args; + uint32_t flags; } zend_function_entry; typedef struct _zend_fcall_info { - size_t size; - zval function_name; - zval *retval; - zval *params; - zend_object *object; - uint32_t param_count; - /* This hashtable can also contain positional arguments (with integer keys), - * which will be appended to the normal params[]. This makes it easier to - * integrate APIs like call_user_func_array(). The usual restriction that - * there may not be position arguments after named arguments applies. */ - HashTable *named_params; + size_t size; + zval function_name; + zval *retval; + zval *params; + zend_object *object; + uint32_t param_count; + /* This hashtable can also contain positional arguments (with integer keys), + * which will be appended to the normal params[]. This makes it easier to + * integrate APIs like call_user_func_array(). The usual restriction that + * there may not be position arguments after named arguments applies. */ + HashTable *named_params; } zend_fcall_info; typedef struct _zend_fcall_info_cache { - zend_function *function_handler; - zend_class_entry *calling_scope; - zend_class_entry *called_scope; - zend_object *object; + zend_function *function_handler; + zend_class_entry *calling_scope; + zend_class_entry *called_scope; + zend_object *object; /* Instance of object for method calls */ + zend_object *closure; /* Closure reference, only if the callable *is* the object */ } zend_fcall_info_cache; /* zend_iterators.h */ typedef struct _zend_object_iterator zend_object_iterator; typedef struct _zend_object_iterator_funcs { - /* release all resources associated with this iterator instance */ - void (*dtor)(zend_object_iterator *iter); + /* release all resources associated with this iterator instance */ + void (*dtor)(zend_object_iterator *iter); - /* check for end of iteration (FAILURE or SUCCESS if data is valid) */ - int (*valid)(zend_object_iterator *iter); + /* check for end of iteration (FAILURE or SUCCESS if data is valid) */ + int (*valid)(zend_object_iterator *iter); - /* fetch the item data for the current element */ - zval *(*get_current_data)(zend_object_iterator *iter); + /* fetch the item data for the current element */ + zval *(*get_current_data)(zend_object_iterator *iter); - /* fetch the key for the current element (optional, may be NULL). The key - * should be written into the provided zval* using the ZVAL_* macros. If - * this handler is not provided auto-incrementing integer keys will be - * used. */ - void (*get_current_key)(zend_object_iterator *iter, zval *key); + /* fetch the key for the current element (optional, may be NULL). The key + * should be written into the provided zval* using the ZVAL_* macros. If + * this handler is not provided auto-incrementing integer keys will be + * used. */ + void (*get_current_key)(zend_object_iterator *iter, zval *key); - /* step forwards to next element */ - void (*move_forward)(zend_object_iterator *iter); + /* step forwards to next element */ + void (*move_forward)(zend_object_iterator *iter); - /* rewind to start of data (optional, may be NULL) */ - void (*rewind)(zend_object_iterator *iter); + /* rewind to start of data (optional, may be NULL) */ + void (*rewind)(zend_object_iterator *iter); - /* invalidate current value/key (optional, may be NULL) */ - void (*invalidate_current)(zend_object_iterator *iter); + /* invalidate current value/key (optional, may be NULL) */ + void (*invalidate_current)(zend_object_iterator *iter); - /* Expose owned values to GC. - * This has the same semantics as the corresponding object handler. */ - HashTable *(*get_gc)(zend_object_iterator *iter, zval **table, int *n); + /* Expose owned values to GC. + * This has the same semantics as the corresponding object handler. */ + HashTable *(*get_gc)(zend_object_iterator *iter, zval **table, int *n); } zend_object_iterator_funcs; struct _zend_object_iterator { - zend_object std; - zval data; - const zend_object_iterator_funcs *funcs; - zend_ulong index; /* private to fe_reset/fe_fetch opcodes */ + zend_object std; + zval data; + const zend_object_iterator_funcs *funcs; + zend_ulong index; /* private to fe_reset/fe_fetch opcodes */ }; typedef struct _zend_class_iterator_funcs { - zend_function *zf_new_iterator; - zend_function *zf_valid; - zend_function *zf_current; - zend_function *zf_key; - zend_function *zf_next; - zend_function *zf_rewind; + zend_function *zf_new_iterator; + zend_function *zf_valid; + zend_function *zf_current; + zend_function *zf_key; + zend_function *zf_next; + zend_function *zf_rewind; } zend_class_iterator_funcs; typedef struct _zend_class_arrayaccess_funcs { @@ -797,170 +800,172 @@ typedef struct _zend_serialize_data zend_serialize_data; typedef struct _zend_unserialize_data zend_unserialize_data; typedef struct _zend_class_name { - zend_string *name; - zend_string *lc_name; + zend_string *name; + zend_string *lc_name; } zend_class_name; typedef struct _zend_trait_method_reference { - zend_string *method_name; - zend_string *class_name; + zend_string *method_name; + zend_string *class_name; } zend_trait_method_reference; typedef struct _zend_trait_precedence { - zend_trait_method_reference trait_method; - uint32_t num_excludes; - zend_string *exclude_class_names[1]; + zend_trait_method_reference trait_method; + uint32_t num_excludes; + zend_string *exclude_class_names[1]; } zend_trait_precedence; typedef struct _zend_trait_alias { - zend_trait_method_reference trait_method; + zend_trait_method_reference trait_method; - /** - * name for method to be added - */ - zend_string *alias; + /** + * name for method to be added + */ + zend_string *alias; - /** - * modifiers to be set on trait method - */ - uint32_t modifiers; + /** + * modifiers to be set on trait method + */ + uint32_t modifiers; } zend_trait_alias; typedef struct _zend_class_mutable_data { - zval *default_properties_table; - HashTable *constants_table; - uint32_t ce_flags; + zval *default_properties_table; + HashTable *constants_table; + uint32_t ce_flags; HashTable *backed_enum_table; } zend_class_mutable_data; typedef struct _zend_class_dependency { - zend_string *name; - zend_class_entry *ce; + zend_string *name; + zend_class_entry *ce; } zend_class_dependency; typedef struct _zend_error_info { - int type; - uint32_t lineno; - zend_string *filename; - zend_string *message; + int type; + uint32_t lineno; + zend_string *filename; + zend_string *message; } zend_error_info; typedef struct _zend_inheritance_cache_entry zend_inheritance_cache_entry; struct _zend_inheritance_cache_entry { - zend_inheritance_cache_entry *next; - zend_class_entry *ce; - zend_class_entry *parent; - zend_class_dependency *dependencies; - uint32_t dependencies_count; - uint32_t num_warnings; - zend_error_info **warnings; - zend_class_entry *traits_and_interfaces[1]; + zend_inheritance_cache_entry *next; + zend_class_entry *ce; + zend_class_entry *parent; + zend_class_dependency *dependencies; + uint32_t dependencies_count; + uint32_t num_warnings; + zend_error_info **warnings; + zend_class_entry *traits_and_interfaces[1]; }; struct _zend_class_entry { - char type; - zend_string *name; - /* class_entry or string depending on ZEND_ACC_LINKED */ - union { - zend_class_entry *parent; - zend_string *parent_name; - }; - int refcount; - uint32_t ce_flags; - - int default_properties_count; - int default_static_members_count; - zval *default_properties_table; - zval *default_static_members_table; - zval ** static_members_table; - HashTable function_table; - HashTable properties_info; - HashTable constants_table; - - zend_class_mutable_data ** mutable_data; - zend_inheritance_cache_entry *inheritance_cache; - - struct _zend_property_info **properties_info_table; - - zend_function *constructor; - zend_function *destructor; - zend_function *clone; - zend_function *__get; - zend_function *__set; - zend_function *__unset; - zend_function *__isset; - zend_function *__call; - zend_function *__callstatic; - zend_function *__tostring; - zend_function *__debugInfo; - zend_function *__serialize; - zend_function *__unserialize; - - /* allocated only if class implements Iterator or IteratorAggregate interface */ - zend_class_iterator_funcs *iterator_funcs_ptr; - /* allocated only if class implements ArrayAccess interface */ - zend_class_arrayaccess_funcs *arrayaccess_funcs_ptr; - - /* handlers */ - union { - zend_object* (*create_object)(zend_class_entry *class_type); - int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type); /* a class implements this interface */ - }; - zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref); - zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method); - - /* serializer callbacks */ - int (*serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data); - int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data); - - uint32_t num_interfaces; - uint32_t num_traits; - - /* class_entry or string(s) depending on ZEND_ACC_LINKED */ - union { - zend_class_entry **interfaces; - zend_class_name *interface_names; - }; - - zend_class_name *trait_names; - zend_trait_alias **trait_aliases; - zend_trait_precedence **trait_precedences; - HashTable *attributes; - - uint32_t enum_backing_type; - HashTable *backed_enum_table; - - union { - struct { - zend_string *filename; - uint32_t line_start; - uint32_t line_end; - zend_string *doc_comment; - } user; - struct { - const struct _zend_function_entry *builtin_functions; - struct _zend_module_entry *module; - } internal; - } info; + char type; + zend_string *name; + /* class_entry or string depending on ZEND_ACC_LINKED */ + union { + zend_class_entry *parent; + zend_string *parent_name; + }; + int refcount; + uint32_t ce_flags; + + int default_properties_count; + int default_static_members_count; + zval *default_properties_table; + zval *default_static_members_table; + zval ** static_members_table; + HashTable function_table; + HashTable properties_info; + HashTable constants_table; + + zend_class_mutable_data ** mutable_data; + zend_inheritance_cache_entry *inheritance_cache; + + struct _zend_property_info **properties_info_table; + + zend_function *constructor; + zend_function *destructor; + zend_function *clone; + zend_function *__get; + zend_function *__set; + zend_function *__unset; + zend_function *__isset; + zend_function *__call; + zend_function *__callstatic; + zend_function *__tostring; + zend_function *__debugInfo; + zend_function *__serialize; + zend_function *__unserialize; + + const zend_object_handlers *default_object_handlers; + + /* allocated only if class implements Iterator or IteratorAggregate interface */ + zend_class_iterator_funcs *iterator_funcs_ptr; + /* allocated only if class implements ArrayAccess interface */ + zend_class_arrayaccess_funcs *arrayaccess_funcs_ptr; + + /* handlers */ + union { + zend_object* (*create_object)(zend_class_entry *class_type); + int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type); /* a class implements this interface */ + }; + zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref); + zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method); + + /* serializer callbacks */ + int (*serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data); + int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data); + + uint32_t num_interfaces; + uint32_t num_traits; + + /* class_entry or string(s) depending on ZEND_ACC_LINKED */ + union { + zend_class_entry **interfaces; + zend_class_name *interface_names; + }; + + zend_class_name *trait_names; + zend_trait_alias **trait_aliases; + zend_trait_precedence **trait_precedences; + HashTable *attributes; + + uint32_t enum_backing_type; + HashTable *backed_enum_table; + + union { + struct { + zend_string *filename; + uint32_t line_start; + uint32_t line_end; + zend_string *doc_comment; + } user; + struct { + const struct _zend_function_entry *builtin_functions; + struct _zend_module_entry *module; + } internal; + } info; }; typedef enum { - EH_NORMAL = 0, - EH_THROW + EH_NORMAL = 0, + EH_THROW } zend_error_handling_t; typedef struct { - zend_error_handling_t handling; - zend_class_entry *exception; + zend_error_handling_t handling; + zend_class_entry *exception; } zend_error_handling; /* zend_objects_API.h */ typedef struct _zend_objects_store { - zend_object **object_buckets; - uint32_t top; - uint32_t size; - int free_list_head; + zend_object **object_buckets; + uint32_t top; + uint32_t size; + int free_list_head; } zend_objects_store; /* zend_modules.h */ @@ -969,70 +974,78 @@ typedef struct _zend_module_entry zend_module_entry; typedef struct _zend_module_dep zend_module_dep; struct _zend_module_entry { - unsigned short size; - unsigned int zend_api; - unsigned char zend_debug; - unsigned char zts; - const struct _zend_ini_entry *ini_entry; - const struct _zend_module_dep *deps; - const char *name; - const struct _zend_function_entry *functions; - zend_result (*module_startup_func)(int type, int module_number); - zend_result (*module_shutdown_func)(int type, int module_number); - zend_result (*request_startup_func)(int type, int module_number); - zend_result (*request_shutdown_func)(int type, int module_number); - void (*info_func)(zend_module_entry *zend_module); - const char *version; - size_t globals_size; + unsigned short size; + unsigned int zend_api; + unsigned char zend_debug; + unsigned char zts; + const struct _zend_ini_entry *ini_entry; + const struct _zend_module_dep *deps; + const char *name; + const struct _zend_function_entry *functions; + zend_result (*module_startup_func)(int type, int module_number); + zend_result (*module_shutdown_func)(int type, int module_number); + zend_result (*request_startup_func)(int type, int module_number); + zend_result (*request_shutdown_func)(int type, int module_number); + void (*info_func)(zend_module_entry *zend_module); + const char *version; + size_t globals_size; #ifdef ZTS - ts_rsrc_id* globals_id_ptr; + ts_rsrc_id* globals_id_ptr; #endif #ifndef ZTS - void* globals_ptr; + void* globals_ptr; #endif - void (*globals_ctor)(void *global); - void (*globals_dtor)(void *global); - zend_result (*post_deactivate_func)(void); - int module_started; - unsigned char type; - void *handle; - int module_number; - const char *build_id; + void (*globals_ctor)(void *global); + void (*globals_dtor)(void *global); + zend_result (*post_deactivate_func)(void); + int module_started; + unsigned char type; + void *handle; + int module_number; + const char *build_id; }; struct _zend_module_dep { - const char *name; /* module name */ - const char *rel; /* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */ - const char *version; /* version */ - unsigned char type; /* dependency type */ + const char *name; /* module name */ + const char *rel; /* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */ + const char *version; /* version */ + unsigned char type; /* dependency type */ }; /* zend_gc.h */ typedef struct _zend_gc_status { - uint32_t runs; - uint32_t collected; - uint32_t threshold; - uint32_t num_roots; + bool active; + bool gc_protected; + bool full; + uint32_t runs; + uint32_t collected; + uint32_t threshold; + uint32_t buf_size; + uint32_t num_roots; + zend_hrtime_t application_time; + zend_hrtime_t collector_time; + zend_hrtime_t dtor_time; + zend_hrtime_t free_time; } zend_gc_status; typedef struct { - zval *cur; - zval *end; - zval *start; + zval *cur; + zval *end; + zval *start; } zend_get_gc_buffer; typedef struct _zend_fiber_context zend_fiber_context; /* Encapsulates data needed for a context switch. */ typedef struct _zend_fiber_transfer { - /* Fiber that will be switched to / has resumed us. */ - zend_fiber_context *context; + /* Fiber that will be switched to / has resumed us. */ + zend_fiber_context *context; - /* Value to that should be send to (or was received from) a fiber. */ - zval value; + /* Value to that should be send to (or was received from) a fiber. */ + zval value; - /* Bitmask of flags defined in enum zend_fiber_transfer_flag. */ - uint8_t flags; + /* Bitmask of flags defined in enum zend_fiber_transfer_flag. */ + uint8_t flags; } zend_fiber_transfer; /* Coroutine functions must populate the given transfer with a new context @@ -1042,182 +1055,195 @@ typedef void (*zend_fiber_clean)(zend_fiber_context *context); typedef struct _zend_fiber_stack zend_fiber_stack; struct _zend_fiber_stack { - void *pointer; - size_t size; + void *pointer; + size_t size; #ifdef HAVE_VALGRIND - unsigned int valgrind_stack_id; + unsigned int valgrind_stack_id; #endif #ifdef __SANITIZE_ADDRESS__ - const void *asan_pointer; - size_t asan_size; + const void *asan_pointer; + size_t asan_size; #endif #ifdef ZEND_FIBER_UCONTEXT - /* Embedded ucontext to avoid unnecessary memory allocations. */ - ucontext_t ucontext; + /* Embedded ucontext to avoid unnecessary memory allocations. */ + ucontext_t ucontext; +#elif BOOST_CONTEXT_SHADOW_STACK + /* Shadow stack: base, size */ + void *ss_base; + size_t ss_size; #endif }; typedef enum { - ZEND_FIBER_STATUS_INIT, - ZEND_FIBER_STATUS_RUNNING, - ZEND_FIBER_STATUS_SUSPENDED, - ZEND_FIBER_STATUS_DEAD, + ZEND_FIBER_STATUS_INIT, + ZEND_FIBER_STATUS_RUNNING, + ZEND_FIBER_STATUS_SUSPENDED, + ZEND_FIBER_STATUS_DEAD, } zend_fiber_status; typedef struct _zend_fiber zend_fiber; struct _zend_fiber_context { - /* Pointer to boost.context or ucontext_t data. */ - void *handle; + /* Pointer to boost.context or ucontext_t data. */ + void *handle; - /* Pointer that identifies the fiber type. */ - void *kind; + /* Pointer that identifies the fiber type. */ + void *kind; - /* Entrypoint function of the fiber. */ - zend_fiber_coroutine function; + /* Entrypoint function of the fiber. */ + zend_fiber_coroutine function; - /* Cleanup function for fiber. */ - zend_fiber_clean cleanup; + /* Cleanup function for fiber. */ + zend_fiber_clean cleanup; - /* Assigned C stack. */ - zend_fiber_stack *stack; + /* Assigned C stack. */ + zend_fiber_stack *stack; - /* Fiber status. */ - zend_fiber_status status; + /* Fiber status. */ + zend_fiber_status status; - /* Observer state */ - zend_execute_data *top_observed_frame; + /* Observer state */ + zend_execute_data *top_observed_frame; - /* Reserved for extensions */ - void *reserved[6]; + /* Reserved for extensions */ + void *reserved[6]; }; struct _zend_fiber { - /* PHP object handle. */ - zend_object std; + /* PHP object handle. */ + zend_object std; - /* Flags are defined in enum zend_fiber_flag. */ - uint8_t flags; + /* Flags are defined in enum zend_fiber_flag. */ + uint8_t flags; - /* Native C fiber context. */ - zend_fiber_context context; + /* Native C fiber context. */ + zend_fiber_context context; - /* Fiber that resumed us. */ - zend_fiber_context *caller; + /* Fiber that resumed us. */ + zend_fiber_context *caller; - /* Fiber that suspended us. */ - zend_fiber_context *previous; + /* Fiber that suspended us. */ + zend_fiber_context *previous; - /* Callback and info / cache to be used when fiber is started. */ - zend_fcall_info fci; - zend_fcall_info_cache fci_cache; + /* Callback and info / cache to be used when fiber is started. */ + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; - /* Current Zend VM execute data being run by the fiber. */ - zend_execute_data *execute_data; + /* Current Zend VM execute data being run by the fiber. */ + zend_execute_data *execute_data; - /* Frame on the bottom of the fiber vm stack. */ - zend_execute_data *stack_bottom; + /* Frame on the bottom of the fiber vm stack. */ + zend_execute_data *stack_bottom; - /* Active fiber vm stack. */ - zend_vm_stack vm_stack; + /* Active fiber vm stack. */ + zend_vm_stack vm_stack; - /* Storage for fiber return value. */ - zval result; + /* Storage for fiber return value. */ + zval result; }; +typedef enum { + ZEND_MEMOIZE_NONE, + ZEND_MEMOIZE_COMPILE, + ZEND_MEMOIZE_FETCH, +} zend_memoize_mode; + /* zend_globals.h */ struct _zend_compiler_globals { - zend_stack loop_var_stack; + zend_stack loop_var_stack; - zend_class_entry *active_class_entry; + zend_class_entry *active_class_entry; - zend_string *compiled_filename; + zend_string *compiled_filename; - int zend_lineno; + int zend_lineno; - zend_op_array *active_op_array; + zend_op_array *active_op_array; - HashTable *function_table; /* function symbol table */ - HashTable *class_table; /* class table */ + HashTable *function_table; /* function symbol table */ + HashTable *class_table; /* class table */ - HashTable *auto_globals; + HashTable *auto_globals; - /* Refer to zend_yytnamerr() in zend_language_parser.y for meaning of values */ - zend_uchar parse_error; - bool in_compilation; - bool short_tags; + /* Refer to zend_yytnamerr() in zend_language_parser.y for meaning of values */ + uint8_t parse_error; + bool in_compilation; + bool short_tags; - bool unclean_shutdown; + bool unclean_shutdown; - bool ini_parser_unbuffered_errors; + bool ini_parser_unbuffered_errors; - zend_llist open_files; + zend_llist open_files; - struct _zend_ini_parser_param *ini_parser_param; + struct _zend_ini_parser_param *ini_parser_param; - bool skip_shebang; - bool increment_lineno; + bool skip_shebang; + bool increment_lineno; - bool variable_width_locale; /* UTF-8, Shift-JIS, Big5, ISO 2022, EUC, etc */ - bool ascii_compatible_locale; /* locale uses ASCII characters as singletons */ - /* and don't use them as lead/trail units */ + bool variable_width_locale; /* UTF-8, Shift-JIS, Big5, ISO 2022, EUC, etc */ + bool ascii_compatible_locale; /* locale uses ASCII characters as singletons */ + /* and don't use them as lead/trail units */ - zend_string *doc_comment; - uint32_t extra_fn_flags; + zend_string *doc_comment; + uint32_t extra_fn_flags; - uint32_t compiler_options; /* set of ZEND_COMPILE_* constants */ + uint32_t compiler_options; /* set of ZEND_COMPILE_* constants */ - zend_oparray_context context; - zend_file_context file_context; + zend_oparray_context context; + zend_file_context file_context; - zend_arena *arena; + zend_arena *arena; - HashTable interned_strings; + HashTable interned_strings; - const zend_encoding **script_encoding_list; - size_t script_encoding_list_size; - bool multibyte; - bool detect_unicode; - bool encoding_declared; + const zend_encoding **script_encoding_list; + size_t script_encoding_list_size; + bool multibyte; + bool detect_unicode; + bool encoding_declared; - zend_ast *ast; - zend_arena *ast_arena; + zend_ast *ast; + zend_arena *ast_arena; - zend_stack delayed_oplines_stack; - HashTable *memoized_exprs; - int memoize_mode; + zend_stack delayed_oplines_stack; + HashTable *memoized_exprs; + zend_memoize_mode memoize_mode; - void *map_ptr_real_base; - void *map_ptr_base; - size_t map_ptr_size; - size_t map_ptr_last; + void *map_ptr_real_base; + void *map_ptr_base; + size_t map_ptr_size; + size_t map_ptr_last; - HashTable *delayed_variance_obligations; - HashTable *delayed_autoloads; - HashTable *unlinked_uses; - zend_class_entry *current_linking_class; + HashTable *delayed_variance_obligations; + HashTable *delayed_autoloads; + HashTable *unlinked_uses; + zend_class_entry *current_linking_class; - uint32_t rtd_key_counter; + uint32_t rtd_key_counter; - zend_stack short_circuiting_opnums; + zend_stack short_circuiting_opnums; +#ifdef ZTS + uint32_t copied_functions_count; +#endif }; #ifdef ZEND_WIN32 typedef struct _OSVERSIONINFOEXA { - uint32_t dwOSVersionInfoSize; - uint32_t dwMajorVersion; - uint32_t dwMinorVersion; - uint32_t dwBuildNumber; - uint32_t dwPlatformId; - char szCSDVersion[128]; - uint16_t wServicePackMajor; - uint16_t wServicePackMinor; - uint16_t wSuiteMask; - char wProductType; - char wReserved; + uint32_t dwOSVersionInfoSize; + uint32_t dwMajorVersion; + uint32_t dwMinorVersion; + uint32_t dwBuildNumber; + uint32_t dwPlatformId; + char szCSDVersion[128]; + uint16_t wServicePackMajor; + uint16_t wServicePackMinor; + uint16_t wSuiteMask; + char wProductType; + char wReserved; } OSVERSIONINFOEX; #endif @@ -1226,155 +1252,172 @@ typedef struct zend_atomic_bool_s { } zend_atomic_bool; struct _zend_executor_globals { - zval uninitialized_zval; - zval error_zval; + zval uninitialized_zval; + zval error_zval; - /* symbol table cache */ - zend_array *symtable_cache[32]; - /* Pointer to one past the end of the symtable_cache */ - zend_array **symtable_cache_limit; - /* Pointer to first unused symtable_cache slot */ - zend_array **symtable_cache_ptr; + /* symbol table cache */ + zend_array *symtable_cache[32]; + /* Pointer to one past the end of the symtable_cache */ + zend_array **symtable_cache_limit; + /* Pointer to first unused symtable_cache slot */ + zend_array **symtable_cache_ptr; - zend_array symbol_table; /* main symbol table */ + zend_array symbol_table; /* main symbol table */ - HashTable included_files; /* files already included */ + HashTable included_files; /* files already included */ - void *bailout; + void *bailout; - int error_reporting; - int exit_status; + int error_reporting; + int exit_status; - HashTable *function_table; /* function symbol table */ - HashTable *class_table; /* class table */ - HashTable *zend_constants; /* constants table */ + HashTable *function_table; /* function symbol table */ + HashTable *class_table; /* class table */ + HashTable *zend_constants; /* constants table */ - zval *vm_stack_top; - zval *vm_stack_end; - zend_vm_stack vm_stack; - size_t vm_stack_page_size; + zval *vm_stack_top; + zval *vm_stack_end; + zend_vm_stack vm_stack; + size_t vm_stack_page_size; - struct _zend_execute_data *current_execute_data; - zend_class_entry *fake_scope; /* used to avoid checks accessing properties */ + struct _zend_execute_data *current_execute_data; + zend_class_entry *fake_scope; /* used to avoid checks accessing properties */ - uint32_t jit_trace_num; /* Used by tracing JIT to reference the currently running trace */ + uint32_t jit_trace_num; /* Used by tracing JIT to reference the currently running trace */ - zend_long precision; + int ticks_count; - int ticks_count; + zend_long precision; - uint32_t persistent_constants_count; - uint32_t persistent_functions_count; - uint32_t persistent_classes_count; + uint32_t persistent_constants_count; + uint32_t persistent_functions_count; + uint32_t persistent_classes_count; - HashTable *in_autoload; - bool full_tables_cleanup; + /* for extended information support */ + bool no_extensions; - /* for extended information support */ - bool no_extensions; + bool full_tables_cleanup; - zend_atomic_bool vm_interrupt; - zend_atomic_bool timed_out; - zend_long hard_timeout; + zend_atomic_bool vm_interrupt; + zend_atomic_bool timed_out; + + HashTable *in_autoload; + + zend_long hard_timeout; + void *stack_base; + void *stack_limit; #ifdef ZEND_WIN32 - OSVERSIONINFOEX windows_version_info; + OSVERSIONINFOEX windows_version_info; #endif - HashTable regular_list; - HashTable persistent_list; + HashTable regular_list; + HashTable persistent_list; - int user_error_handler_error_reporting; - zval user_error_handler; - zval user_exception_handler; - zend_stack user_error_handlers_error_reporting; - zend_stack user_error_handlers; - zend_stack user_exception_handlers; + int user_error_handler_error_reporting; + bool exception_ignore_args; + zval user_error_handler; + zval user_exception_handler; + zend_stack user_error_handlers_error_reporting; + zend_stack user_error_handlers; + zend_stack user_exception_handlers; - zend_error_handling_t error_handling; - zend_class_entry *exception_class; + zend_class_entry *exception_class; + zend_error_handling_t error_handling; - /* timeout support */ - zend_long timeout_seconds; + int capture_warnings_during_sccp; - int capture_warnings_during_sccp; + /* timeout support */ + zend_long timeout_seconds; - HashTable *ini_directives; - HashTable *modified_ini_directives; - zend_ini_entry *error_reporting_ini_entry; + HashTable *ini_directives; + HashTable *modified_ini_directives; + zend_ini_entry *error_reporting_ini_entry; - zend_objects_store objects_store; - zend_object *exception, *prev_exception; - const zend_op *opline_before_exception; - zend_op exception_op[3]; + zend_objects_store objects_store; + zend_object *exception, *prev_exception; + const zend_op *opline_before_exception; + zend_op exception_op[3]; - struct _zend_module_entry *current_module; + struct _zend_module_entry *current_module; - bool active; - zend_uchar flags; + bool active; + uint8_t flags; - zend_long assertions; + zend_long assertions; - uint32_t ht_iterators_count; /* number of allocated slots */ - uint32_t ht_iterators_used; /* number of used slots */ - HashTableIterator *ht_iterators; - HashTableIterator ht_iterators_slots[16]; + uint32_t ht_iterators_count; /* number of allocated slots */ + uint32_t ht_iterators_used; /* number of used slots */ + HashTableIterator *ht_iterators; + HashTableIterator ht_iterators_slots[16]; - void *saved_fpu_cw_ptr; + void *saved_fpu_cw_ptr; #ifdef XPFPA_HAVE_CW - XPFPA_CW_DATATYPE saved_fpu_cw; + XPFPA_CW_DATATYPE saved_fpu_cw; #endif - zend_function trampoline; - zend_op call_trampoline_op; + zend_function trampoline; + zend_op call_trampoline_op; + + HashTable weakrefs; - HashTable weakrefs; + zend_long exception_string_param_max_len; - bool exception_ignore_args; - zend_long exception_string_param_max_len; + zend_get_gc_buffer get_gc_buffer; - zend_get_gc_buffer get_gc_buffer; + zend_fiber_context *main_fiber_context; + zend_fiber_context *current_fiber_context; - zend_fiber_context *main_fiber_context; - zend_fiber_context *current_fiber_context; + /* Active instance of Fiber. */ + zend_fiber *active_fiber; - /* Active instance of Fiber. */ - zend_fiber *active_fiber; + /* Default fiber C stack size. */ + size_t fiber_stack_size; - /* Default fiber C stack size. */ - zend_long fiber_stack_size; + /* If record_errors is enabled, all emitted diagnostics will be recorded, + * in addition to being processed as usual. */ + bool record_errors; + uint32_t num_errors; + zend_error_info **errors; - /* If record_errors is enabled, all emitted diagnostics will be recorded, - * in addition to being processed as usual. */ - bool record_errors; - uint32_t num_errors; - zend_error_info **errors; + /* Override filename or line number of thrown errors and exceptions */ + zend_string *filename_override; + zend_long lineno_override; - /* Override filename or line number of thrown errors and exceptions */ - zend_string *filename_override; - zend_long lineno_override; +#ifdef ZEND_CHECK_STACK_LIMIT + zend_call_stack call_stack; + zend_long max_allowed_stack_size; + zend_ulong reserved_stack_size; +#endif + +#ifdef ZEND_MAX_EXECUTION_TIMERS + timer_t max_execution_timer_timer; + pid_t pid; + struct sigaction oldact; +#endif - void *reserved[6]; + void *reserved[6]; }; typedef struct _zend_executor_globals zend_executor_globals; +typedef struct _zend_compiler_globals zend_compiler_globals; #ifndef ZTS +ZEND_API zend_compiler_globals compiler_globals; ZEND_API zend_executor_globals executor_globals; -ZEND_API struct _zend_compiler_globals compiler_globals; #endif /* stdio.h */ typedef struct { - int level; /* fill/empty level of buffer */ - unsigned flags; /* File status flags */ - char fd; /* File descriptor */ - unsigned char hold; /* Ungetc char if no buffer */ - int bsize; /* Buffer size */ - unsigned char *buffer; /* Data transfer buffer */ - unsigned char *curp; /* Current active pointer */ - unsigned istemp; /* Temporary file indicator */ - short token; /* Used for validity checking */ + int level; /* fill/empty level of buffer */ + unsigned flags; /* File status flags */ + char fd; /* File descriptor */ + unsigned char hold; /* Ungetc char if no buffer */ + int bsize; /* Buffer size */ + unsigned char *buffer; /* Data transfer buffer */ + unsigned char *curp; /* Current active pointer */ + unsigned istemp; /* Temporary file indicator */ + short token; /* Used for validity checking */ } FILE; /* zend_stream.h */ @@ -1383,39 +1426,39 @@ typedef ssize_t (*zend_stream_reader_t)(void* handle, char *buf, size_t len); typedef void (*zend_stream_closer_t)(void* handle); typedef enum { - ZEND_HANDLE_FILENAME, - ZEND_HANDLE_FP, - ZEND_HANDLE_STREAM + ZEND_HANDLE_FILENAME, + ZEND_HANDLE_FP, + ZEND_HANDLE_STREAM } zend_stream_type; typedef struct _zend_stream { - void *handle; - int isatty; - zend_stream_reader_t reader; - zend_stream_fsizer_t fsizer; - zend_stream_closer_t closer; + void *handle; + int isatty; + zend_stream_reader_t reader; + zend_stream_fsizer_t fsizer; + zend_stream_closer_t closer; } zend_stream; typedef struct _zend_file_handle { - union { - FILE *fp; - zend_stream stream; - } handle; - zend_string *filename; - zend_string *opened_path; - zend_uchar type; /* packed zend_stream_type */ - bool primary_script; - bool in_list; /* added into CG(open_file) */ - char *buf; - size_t len; + union { + FILE *fp; + zend_stream stream; + } handle; + zend_string *filename; + zend_string *opened_path; + uint8_t type; /* packed zend_stream_type */ + bool primary_script; + bool in_list; /* added into CG(open_file) */ + char *buf; + size_t len; } zend_file_handle; /* zend_ptr_stack.h */ typedef struct _zend_ptr_stack { - int top, max; - void **elements; - void **top_element; - bool persistent; + int top, max; + void **elements; + void **top_element; + bool persistent; } zend_ptr_stack; /* zend_multibyte.h */ @@ -1423,49 +1466,49 @@ typedef size_t (*zend_encoding_filter)(unsigned char **str, size_t *str_length, /* zend_language_scanner.h */ typedef struct _zend_lex_state { - unsigned int yy_leng; - unsigned char *yy_start; - unsigned char *yy_text; - unsigned char *yy_cursor; - unsigned char *yy_marker; - unsigned char *yy_limit; - int yy_state; - zend_stack state_stack; - zend_ptr_stack heredoc_label_stack; - zend_stack nest_location_stack; /* for syntax error reporting */ - - zend_file_handle *in; - uint32_t lineno; - zend_string *filename; - - /* original (unfiltered) script */ - unsigned char *script_org; - size_t script_org_size; - - /* filtered script */ - unsigned char *script_filtered; - size_t script_filtered_size; - - /* input/output filters */ - zend_encoding_filter input_filter; - zend_encoding_filter output_filter; - const zend_encoding *script_encoding; - - /* hooks */ - void (*on_event)( - zend_php_scanner_event event, int token, int line, - const char *text, size_t length, void *context); - void *on_event_context; - - zend_ast *ast; - zend_arena *ast_arena; + unsigned int yy_leng; + unsigned char *yy_start; + unsigned char *yy_text; + unsigned char *yy_cursor; + unsigned char *yy_marker; + unsigned char *yy_limit; + int yy_state; + zend_stack state_stack; + zend_ptr_stack heredoc_label_stack; + zend_stack nest_location_stack; /* for syntax error reporting */ + + zend_file_handle *in; + uint32_t lineno; + zend_string *filename; + + /* original (unfiltered) script */ + unsigned char *script_org; + size_t script_org_size; + + /* filtered script */ + unsigned char *script_filtered; + size_t script_filtered_size; + + /* input/output filters */ + zend_encoding_filter input_filter; + zend_encoding_filter output_filter; + const zend_encoding *script_encoding; + + /* hooks */ + void (*on_event)( + zend_php_scanner_event event, int token, int line, + const char *text, size_t length, void *context); + void *on_event_context; + + zend_ast *ast; + zend_arena *ast_arena; } zend_lex_state; typedef struct _zend_heredoc_label { - char *label; - int length; - int indentation; - bool indentation_uses_spaces; + char *label; + int length; + int indentation; + bool indentation_uses_spaces; } zend_heredoc_label; /** @@ -1484,8 +1527,8 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_add_or_update(HashTable *ht, zend_string /** * Opcode API */ -ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler); -ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode); +ZEND_API zend_result zend_set_user_opcode_handler(uint8_t opcode, user_opcode_handler_t handler); +ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(uint8_t opcode); /** * Zend inheritance API @@ -1516,6 +1559,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_5(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4, zend_ast *child5); ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4