From 1e0c564df919c6f16746d5499805e044c5dda2af Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 12 Jan 2024 18:32:02 +0100 Subject: [PATCH] Build fixes --- Zend/zend_execute.c | 37 ++++++++++++++++++++++++++++---- ext/dom/php_dom.c | 16 +++++++------- ext/dom/php_dom.h | 2 +- ext/libxml/libxml.c | 6 ++---- ext/standard/var_unserializer.re | 1 + ext/tokenizer/tokenizer.c | 2 +- 6 files changed, 46 insertions(+), 18 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index e87b7af0ecd5f..e9a1795641ea2 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -18,6 +18,7 @@ +----------------------------------------------------------------------+ */ +#include "zend_portability.h" #include "zend_types.h" #define ZEND_INTENSIVE_DEBUGGING 0 @@ -1098,7 +1099,7 @@ static zend_never_inline bool check_property_type_generic( } #endif -static zend_type zend_resolve_generic_type(zend_class_reference *scope, uint32_t param_id) { +static zend_always_inline zend_type zend_resolve_generic_type(zend_class_reference *scope, uint32_t param_id) { if (param_id >= scope->ce->num_bound_generic_args) { ZEND_ASSERT(param_id - scope->ce->num_bound_generic_args < scope->args.num_types); return scope->args.types[param_id - scope->ce->num_bound_generic_args]; @@ -1222,6 +1223,10 @@ static zend_always_inline bool zend_validate_generic_args( # define HAVE_CACHE_SLOT 1 #endif +// TODO: cache_slot may not be worth it since ZSTR_CE_CACHE +#undef HAVE_CACHE_SLOT +#define HAVE_CACHE_SLOT 0 + #define PROGRESS_CACHE_SLOT() if (HAVE_CACHE_SLOT) {cache_slot++;} static zend_always_inline zend_class_entry *zend_fetch_ce_from_cache_slot( @@ -1305,6 +1310,11 @@ static bool zend_check_intersection_type_from_cache_slot(zend_type_list *interse return status; } +// TODO +static bool zend_check_type_slow_recursive( + zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, + zend_class_entry *scope, bool is_return_type, bool is_internal); + static zend_always_inline bool zend_check_type_slow( zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, zend_class_entry *scope, bool is_return_type, bool is_internal) @@ -1342,8 +1352,14 @@ static zend_always_inline bool zend_check_type_slow( if (ZEND_TYPE_CONTAINS_CODE(real_type, Z_TYPE_P(arg))) { return true; } - if (zend_check_type_slow( - &real_type, arg, ref, /* cache_slot */ NULL, scope, is_return_type, is_internal)) { + if (ZEND_TYPE_HAS_PNR(real_type) && Z_TYPE_P(arg) == IS_OBJECT) { + ce = zend_fetch_ce_from_cache_slot(cache_slot, &real_type); + if (ce && instanceof_function(Z_OBJCE_P(arg), ce)) { + return true; + } + } + if (zend_check_type_slow_recursive( + &real_type, arg, ref, cache_slot, scope, is_return_type, is_internal)) { return true; } } @@ -1368,7 +1384,13 @@ static zend_always_inline bool zend_check_type_slow( if (ZEND_TYPE_CONTAINS_CODE(real_type, Z_TYPE_P(arg))) { return true; } - if (zend_check_type_slow( + if (ZEND_TYPE_HAS_PNR(real_type) && Z_TYPE_P(arg) == IS_OBJECT) { + ce = zend_fetch_ce_from_cache_slot(cache_slot, &real_type); + if (ce && instanceof_function(Z_OBJCE_P(arg), ce)) { + return true; + } + } + if (zend_check_type_slow_recursive( &real_type, arg, ref, /* cache_slot */ NULL, scope, is_return_type, is_internal)) { return true; } @@ -1402,6 +1424,13 @@ static zend_always_inline bool zend_check_type_slow( * because this case is already checked at compile-time. */ } +static bool zend_check_type_slow_recursive( + zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, + zend_class_entry *scope, bool is_return_type, bool is_internal) +{ + return zend_check_type_slow(type, arg, ref, cache_slot, scope, is_return_type, is_internal); +} + static zend_always_inline bool zend_check_type( zend_type *type, zval *arg, void **cache_slot, zend_class_entry *scope, bool is_return_type, bool is_internal) diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 632da61c59cd2..6f93c24b853d5 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -342,15 +342,15 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo if (hnd) { if (!hnd->write_func) { - zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name)); + zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(OBJ_NAME(object)), ZSTR_VAL(name)); return &EG(error_zval); } - zend_property_info *prop = zend_get_property_info(object->ce, name, /* silent */ true); + zend_property_info *prop = zend_get_property_info(OBJ_CE(object), name, /* silent */ true); if (prop && ZEND_TYPE_IS_SET(prop->type)) { zval tmp; ZVAL_COPY(&tmp, value); - if (!zend_verify_property_type(prop, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) { + if (!zend_verify_property_type(object, prop, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) { zval_ptr_dtor(&tmp); return &EG(error_zval); } @@ -510,11 +510,11 @@ static void dom_update_refcount_after_clone(dom_object *original, xmlNodePtr ori static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */ { dom_object *intern = php_dom_obj_from_obj(zobject); - dom_object *clone = dom_objects_set_class(intern->std.ce); + dom_object *clone = dom_objects_set_class(OBJ_CE(&intern->std)); clone->std.handlers = dom_get_obj_handlers(); - if (instanceof_function(intern->std.ce, dom_node_class_entry)) { + if (instanceof_function(OBJ_CE(&intern->std), dom_node_class_entry)) { xmlNodePtr node = (xmlNodePtr)dom_object_get_node(intern); if (node != NULL) { xmlNodePtr cloned_node = xmlDocCopyNode(node, node->doc, 1); @@ -534,7 +534,7 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */ static zend_object *dom_object_namespace_node_clone_obj(zend_object *zobject) { dom_object_namespace_node *intern = php_dom_namespace_node_obj_from_obj(zobject); - zend_object *clone = dom_objects_namespace_node_new(intern->dom.std.ce); + zend_object *clone = dom_objects_namespace_node_new(OBJ_CE(&intern->dom.std)); dom_object_namespace_node *clone_intern = php_dom_namespace_node_obj_from_obj(clone); xmlNodePtr original_node = dom_object_get_node(&intern->dom); @@ -1087,8 +1087,8 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml static void dom_objects_set_class_ex(zend_class_entry *class_type, dom_object *intern) { zend_class_entry *base_class = class_type; - while ((base_class->type != ZEND_INTERNAL_CLASS || base_class->info.internal.module->module_number != dom_module_entry.module_number) && base_class->parent != NULL) { - base_class = base_class->parent; + while ((base_class->type != ZEND_INTERNAL_CLASS || base_class->info.internal.module->module_number != dom_module_entry.module_number) && base_class->num_parents != 0) { + base_class = base_class->parents[0]->ce; } intern->prop_handler = zend_hash_find_ptr(&classes, base_class->name); diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index bb778e7ab9d41..c85d59f58a383 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -194,7 +194,7 @@ void dom_mark_namespaces_for_copy_based_on_copy(xmlNodePtr copy, const xmlNode * #define DOM_GET_INTERN(__id, __intern) { \ __intern = Z_DOMOBJ_P(__id); \ if (UNEXPECTED(__intern->ptr == NULL)) { \ - zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(__intern->std.ce->name));\ + zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(OBJ_NAME(&__intern->std)));\ RETURN_THROWS();\ } \ } diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 6d7f567b95994..bd6093fd963ba 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -15,6 +15,7 @@ +----------------------------------------------------------------------+ */ +#include "zend_API.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -1258,10 +1259,7 @@ PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object) php_libxml_func_handler *export_hnd; if (Z_TYPE_P(object) == IS_OBJECT) { - ce = Z_OBJCE_P(object); - while (ce->parent != NULL) { - ce = ce->parent; - } + ce = zend_class_entry_get_root(Z_OBJCE_P(object)); if ((export_hnd = zend_hash_find_ptr(&php_libxml_exports, ce->name))) { node = export_hnd->export_func(object); } diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 583a3ffc54a5d..19f876fee969d 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -1184,6 +1184,7 @@ object ":" uiv ":" ["] { do { zend_string *lc_name; + ce = NULL; if (!(*var_hash)->allowed_classes && ZSTR_HAS_CE_CACHE(class_name)) { zend_class_reference *class_ref = ZSTR_GET_CE_CACHE(class_name); diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 75cc99d7b84c6..d8d575e39a65f 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -100,7 +100,7 @@ PHP_METHOD(PhpToken, tokenize) Z_PARAM_LONG(flags) ZEND_PARSE_PARAMETERS_END(); - token_class = zend_get_called_scope(execute_data); + token_class = zend_get_called_scope(execute_data)->ce; /* Check construction preconditions in advance, so these are not repeated for each token. */ if (token_class->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {