From 0f16925652b49bdefaa0ae2264446a845a5bb109 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Thu, 22 Aug 2019 07:38:29 +0200 Subject: [PATCH] fixes for 7.4 --- src/definition.c | 79 ++++++++++++++++++++++++++++++++++++++---------- src/definition.h | 5 +++ src/patch.c | 12 ++++++++ tests/086.phpt | 5 +-- 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/definition.c b/src/definition.c index a569af3..ae362d2 100644 --- a/src/definition.c +++ b/src/definition.c @@ -372,15 +372,17 @@ static zend_always_inline void php_componere_relink_objects(zend_objects_store * } else if (instanceof_function(object->ce, zend_ce_closure)) { zend_closure_t *closure = (zend_closure_t*) object; + if (closure->func.type == ZEND_USER_FUNCTION) { #if PHP_VERSION_ID >= 70400 - if (RUN_TIME_CACHE(&closure->func.op_array)) { - memset(RUN_TIME_CACHE(&closure->func.op_array), 0, closure->func.op_array.cache_size); - } + if (RUN_TIME_CACHE(&closure->func.op_array)) { + memset(RUN_TIME_CACHE(&closure->func.op_array), 0, closure->func.op_array.cache_size); + } #else - if (closure->func.op_array.run_time_cache) { - memset(closure->func.op_array.run_time_cache, 0, closure->func.op_array.cache_size); - } + if (closure->func.op_array.run_time_cache) { + memset(closure->func.op_array.run_time_cache, 0, closure->func.op_array.cache_size); + } #endif + } if (closure->called_scope == parent) { closure->called_scope = def; @@ -553,9 +555,7 @@ PHP_METHOD(Definition, __construct) break; } - if (!instanceof_function(o->ce, ce)) { - zend_do_implement_interface(o->ce, ce); - } + zend_do_implement_interface(o->ce, ce); } } ZEND_HASH_FOREACH_END(); @@ -565,8 +565,52 @@ PHP_METHOD(Definition, __construct) if (!o->ce->info.user.filename) { o->ce->info.user.filename = name; } + +#if PHP_VERSION_ID >= 70400 + o->ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES; +#endif } +#if PHP_VERSION_ID >= 70400 +void php_componere_definition_properties_table_rebuild(zend_class_entry *ce) +{ + zend_property_info **table, *prop; + size_t size; + if (ce->default_properties_count == 0 || ce->properties_info_table) { + return; + } + + size = sizeof(zend_property_info *) * ce->default_properties_count; + if (ce->type == ZEND_USER_CLASS) { + ce->properties_info_table = table = zend_arena_alloc(&CG(arena), size); + } else { + ce->properties_info_table = table = pemalloc(size, 1); + } + + /* Dead slots may be left behind during inheritance. Make sure these are NULLed out. */ + memset(table, 0, size); + + if (ce->parent && ce->parent->default_properties_count != 0) { + zend_property_info **parent_table = ce->parent->properties_info_table; + memcpy( + table, parent_table, + sizeof(zend_property_info *) * ce->parent->default_properties_count + ); + + /* Child did not add any new properties, we are done */ + if (ce->default_properties_count == ce->parent->default_properties_count) { + return; + } + } + + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0) { + table[OBJ_PROP_TO_NUM(prop->offset)] = prop; + } + } ZEND_HASH_FOREACH_END(); +} +#endif + PHP_METHOD(Definition, register) { php_componere_definition_t *o = @@ -626,6 +670,10 @@ PHP_METHOD(Definition, register) o->registered = 1; zend_string_release(name); + +#if PHP_VERSION_ID >= 70400 + php_componere_definition_properties_table_rebuild(o->ce); +#endif } ZEND_BEGIN_ARG_INFO_EX(php_componere_definition_method, 0, 0, 2) @@ -750,7 +798,7 @@ PHP_METHOD(Definition, addTrait) o->ce->ce_flags |= ZEND_ACC_IMPLEMENT_TRAITS; - zend_do_link_class(o->ce); + zend_do_link_class(o->ce, NULL); o->ce->num_traits = num_traits + 1; o->ce->trait_names -= num_traits; @@ -788,6 +836,10 @@ PHP_METHOD(Definition, addInterface) zend_do_implement_interface(o->ce, interface); } +#if PHP_VERSION_ID >= 70400 + o->ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES; +#endif + RETURN_ZVAL(getThis(), 1, 0); } @@ -858,7 +910,7 @@ PHP_METHOD(Definition, addProperty) php_componere_value_addref(value); #if PHP_VERSION_ID >= 70400 - zend_do_link_class(o->ce); + zend_do_link_class(o->ce, NULL); #endif } @@ -909,16 +961,11 @@ PHP_METHOD(Definition, addConstant) return; } - zend_declare_class_constant_ex( o->ce, name, php_componere_value_default(value), php_componere_value_access(value), NULL); -#if PHP_VERSION_ID >= 70400 - zend_do_link_class(o->ce); -#endif - RETURN_ZVAL(getThis(), 1, 0); } diff --git a/src/definition.h b/src/definition.h index cfa306c..c30da51 100644 --- a/src/definition.h +++ b/src/definition.h @@ -39,4 +39,9 @@ typedef struct _php_componere_definition_t { extern void php_componere_definition_inherit(zend_class_entry *ce, zend_class_entry *parent); extern void php_componere_definition_copy(zend_class_entry *ce, zend_class_entry *parent); extern void php_componere_definition_parent(zend_class_entry *ce, zend_class_entry *parent); + +#if PHP_VERSION_ID >= 70400 +extern void php_componere_definition_properties_table_rebuild(zend_class_entry *ce); +#endif + #endif diff --git a/src/patch.c b/src/patch.c index 84772d6..79f2dce 100644 --- a/src/patch.c +++ b/src/patch.c @@ -146,6 +146,10 @@ PHP_METHOD(Patch, __construct) o->ce->ce_flags &= ~ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; } + +#if PHP_VERSION_ID >= 70400 + o->ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES; +#endif } PHP_METHOD(Patch, apply) @@ -270,6 +274,14 @@ PHP_METHOD(Patch, derive) r->saved->refcount++; ZVAL_COPY(&r->instance, instance); + +#if PHP_VERSION_ID >= 70400 + r->ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES; +#endif + +#if PHP_VERSION_ID >= 70400 + php_componere_definition_properties_table_rebuild(r->ce); +#endif } static zend_function_entry php_componere_patch_methods[] = { diff --git a/tests/086.phpt b/tests/086.phpt index 70c8786..a47e857 100644 --- a/tests/086.phpt +++ b/tests/086.phpt @@ -37,12 +37,9 @@ echo "\n"; $first->revert(); printf("first=%d second=%d ", $first->isApplied(), $second->isApplied()); -echo (string) $instance; -echo "\n"; ?> --EXPECTF-- first=1 second=0 ok first=0 second=1 ko first=1 second=0 ok -first=0 second=0 -%s fatal error: Object of class DateTime could not be converted to string in %s on line 37 +first=0 second=0