-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ext/spl: Various refactorings #14518
Conversation
ext/spl/spl_array.c
Outdated
zend_symtable_update(debug_info, zname, storage); | ||
zend_string_release_ex(zname, 0); | ||
|
||
zend_string *mangled_named = zend_mangle_property_name( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO there was nothing wrong with the old code having a specialised helper, now there's more repetition in the code. I would prefer this commit to be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case I would prefer an API that actually sets the hashtable value at the same time, rather than just get the mangled name.
I'll see what I can cook up.
@@ -783,11 +780,18 @@ static inline HashTable* spl_array_get_debug_info(zend_object *obj) /* {{{ */ | |||
storage = &intern->array; | |||
Z_TRY_ADDREF_P(storage); | |||
|
|||
base = obj->handlers == &spl_handler_ArrayIterator | |||
const zend_class_entry *base_class_ce = instanceof_function(obj->ce, spl_ce_ArrayIterator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given SPL's funkyness I'm not so sure changing this is a good idea, this call is also more expensive btw than the previous code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to remove the dedicated object handlers as they are identical to the ArrayObject ones, I'd also expect the base case to be fast as subclassing should be relatively rare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another reason is that I'd like to move the ArrayIterator into the iterator.c file in the long run
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay fair enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks much better
ZVAL_ARR(&intern->array, | ||
zend_array_dup(spl_array_get_hash_table(other))); | ||
} else { | ||
ZEND_ASSERT(orig->handlers == &spl_handler_ArrayIterator); | ||
ZEND_ASSERT(instanceof_function(class_type, spl_ce_ArrayIterator)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though asserts are gone in release builds, the call to instanceof_function
will remain because the compiler can't prove in this compile unit that this function is side-effect-free. It's a bit unfortunate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is unfortunate indeed, would adding __attribute__((const))
(GCC) attributes to instanceof_function
and instanceof_function_slow
fix this issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably.
Or surround the assertion line with #if ZEND_DEBUG
#endif
.
I rearranged the commits and folded the relevant fixups into the appropriate commits |
Mainly to use zend_mangle_property_name() directly instead of spl_gen_private_prop_name()
They are the same
memset(intern, 0, | ||
MAX(XtOffsetOf(spl_filesystem_object, u.dir.entry), | ||
XtOffsetOf(spl_filesystem_object, u.file.escape) + sizeof(int))); | ||
intern = ecalloc(1, sizeof(spl_filesystem_object) + zend_object_properties_size(class_type)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stumbled on this by accident. The memset
was intentional to avoid writing the entirety of spl_filesystem_object.u.dir.entry
. Did this cause any issues? If not, I think this should be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't ecalloc
take care of setting the whole memory to 0
tho?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but we don't need to do that. spl_filesystem_object.u.dir.entry
will later be initialized, and we don't need to initialize the entire structure anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, I personally find the memset confusing, which is why I replaced it with a calloc. I don't really care but then SPL is convoluted enough that being clear seems like a positive to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment should suffice :) I'll take care of it. Thanks!
No description provided.