-
Notifications
You must be signed in to change notification settings - Fork 71
feat: add support for empty immutable shared arrays #355
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
base: master
Are you sure you want to change the base?
feat: add support for empty immutable shared arrays #355
Conversation
8316c30
to
f4bfbce
Compare
@mszabo-wikia Thank you for the contribution! I have not that much time, but will try to have a look soon. From a quick look PHP 8.2 also seems to fail. Edit: might be because the docs bindings. |
f4bfbce
to
86f81ca
Compare
Thanks, I've regenerated the bindings using a PHP 8.2 debug build. It seems as though the bindings might not have been updated in a while, as there were some other unrelated changes. Or do they need to be generated using 8.0? |
@mszabo-wikia pretty sure its php 8.3, but no one seems to know #334 (comment) |
86f81ca
to
f57b916
Compare
@Xenira ah thanks, this is valuable context. I've regenerated the bindings using PHP 8.3. |
I think we should not do this, as returning a immutable hashtable is not the expected behaviour here |
f57b916
to
81aac48
Compare
Yeah, I had doubts about that myself. I've removed this logic. |
@mszabo-wikia fixed the issue in nightly tests (#357). Could you rebase onto master. You also need to update your commit message, as the new pipeline enforces conventional commits. |
Why: - Since PHP 7.3, it's possible for extensions to create zvals backed by an immutable shared hashtable via the ZVAL_EMPTY_ARRAY macro. - This helps avoid redundant hashtable allocations when returning empty arrays back to userland PHP code, and could likewise be beneficial for Rust extensions too. What: - Add ZendHashTable::new_empty_immutable() to obtain a ZendHashTable that is actually an empty immutable shared hashtable. - Add ZendHashTable::is_immutable(). Use it to avoid attempting to free the immutable shared hashtable on drop, and to set appropriate type flags when initializing a zval with a ZendHashTable.
81aac48
to
49244e1
Compare
Perfect, thanks—I was wondering about that since I didn't experience the same error locally, but I have stable Rust installed which explains it. |
pub fn new_empty_immutable() -> ZBox<Self> { | ||
unsafe { | ||
// SAFETY: zend_empty_array is a static global. | ||
let ptr = (&zend_empty_array as *const ZendHashTable) as *mut ZendHashTable; | ||
|
||
// SAFETY: `as_mut()` panics if the pointer is null. | ||
ZBox::from_raw(ptr.as_mut().expect("zend_empty_array inconsistent")) | ||
} | ||
} |
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.
This should probably not return a mutable vallue, as that allows mutable access to the immutable hashtable.
let mut ht = ZendHashTable::new_empty_immutable();
ht.insert("key", 1).unwrap();
would be valid but results in signal: 11 (SIGSEGV) (core dumped)
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.
Sorry for the delayed update—yeah, this definitely isn't ideal.
std::ptr
only supports mutable pointers, so making the backing ptr immutable wouldn't play well with ZBox.
Maybe the right way to go here is to have a separate helper similar to the RETURN_EMPTY_ARRAY
C macro in the Zend API, since really the only major use case for this in extensions is to return an empty array to userland without overhead. Then particularly performance-sensitive extensions can opt into using this as needed.
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.
Maybe just have a struct ZendEmptyArray;
that implements IntoZval
?
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.
That seems like a good solution, thanks.
Regarding the Really need to find a way to just automate that. |
Why:
ZVAL_EMPTY_ARRAY
macro.What:
ZendHashTable::new_empty_immutable()
to obtain aZendHashTable
that is actually an empty immutable shared hashtable.ZendHashTable::is_immutable()
. Use it to avoid attempting to free the immutable shared hashtable on drop, and to set appropriate type flags when initializing a zval with aZendHashTable
.MakeZendHashTable
'sTryFrom
implementations fromVec
andHashMap
return an empty immutable shared hashtable if the input collection was empty. Although this would allow every user to automatically benefit from this optimization, I'm not convinced about this part because this is technically a breaking change for consumers that constructZendHashTable
s via these converters in their Rust code. Maybe it'd be better to not change the converters and let projects explicitly use::new_empty_immutable
if they deem the optimization would be useful.