-
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
[RFC] Add Random Extension #7079
Conversation
85f6c30
to
01fc380
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Please keep design discussions to the thread on the PHP internals mailing list (https://externals.io/message/114561). Otherwise relevant parties may not be aware of it. |
Sorry it's my first time commenting here, I didn't know that details and will comply. Sorry about that. |
@nikic @drupol @kamil-tekiela I would be happy to have future design discussions in the following threads. |
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.
EXTENSION("random"
should create module symbols with random
, not php_random
(excluding static methods or C functions exposed to other modules in the header)
(both by convention and to avoid build issues - I forget exactly where it's important)
ext/random/php_random_module.h
Outdated
@@ -0,0 +1,67 @@ | |||
/* |
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.
The file name is wrong and will cause build issues, I think. This should be named php_random.h
instead. See build/print_include.awk
../php-src/ext/tokenizer/php_tokenizer.h
21:#define phpext_tokenizer_ptr &tokenizer_module_entry
../php-src/ext/xsl/php_xsl.h
21:#define phpext_xsl_ptr &xsl_module_entry
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.
If changed to php_random.h, the include guard conflicts with php_random.h in ext/standard.
Use PHP_RANDOM_H_MODULE for the include guard only.
ext/random/php_random_module.h
Outdated
#ifndef PHP_RANDOM_MODULE_H | ||
#define PHP_RANDOM_MODULE_H | ||
|
||
extern zend_module_entry php_random_module_entry; |
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.
nit: I don't remember if this affects the build (it might or might not), but the conventional name would be random_module_entry
here and below.
(E.g. if php looks for a symbol with that name when loading a shared library - it very likely might)
ext/random/php_random_module.h
Outdated
extern zend_module_entry php_random_module_entry; | ||
#define phpext_random_ptr &php_random_module_entry | ||
|
||
extern PHPAPI zend_class_entry *php_random_ce_Random_NumberGenerator_RandomNumberGenerator; |
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.
nit: I think random_ce_
would be shorter and follow conventions, e.g. spl starts with spl.
The other names in this header are fine.
extern PHPAPI zend_class_entry *spl_ce_SplFixedArray;
ext/random/random.c
Outdated
/* }}} */ | ||
|
||
/* {{{ php_random_module_entry */ | ||
zend_module_entry php_random_module_entry = { |
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.
same here for random_module_entry, both in PHP_MINIT(random) and PHP_MINIT_FUNCTION(random)
ext/random/random.c
Outdated
} | ||
|
||
static inline zend_object *php_random_rng_common_init(zend_class_entry *ce, const php_random_rng_algo *algo, const zend_object_handlers *handlers) { | ||
php_random_rng *rng = zend_object_alloc(sizeof(php_random_rng), ce); |
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 seems to be correct - zend_object_alloc is zeroing out state (i.e. setting it to NULL)
/* Allocates object type and zeros it, but not the standard zend_object and properties.
* Standard object MUST be initialized using zend_object_std_init().
* Properties MUST be initialized using object_properties_init(). */
static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_entry *ce) {
void *obj = emalloc(obj_size + zend_object_properties_size(ce));
memset(obj, 0, obj_size - sizeof(zend_object));
return obj;
}
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 I'm still getting unintended Valgrind warnings.
Also, the ZTS build on Windows seems to be SEGV on during testing. I do not have a Windows environment, but will continue to try to resolve this.
ext/random/random.c
Outdated
php_random_rng *rng = php_random_rng_from_obj(object); | ||
|
||
if (rng->state) { | ||
efree(rng->state); |
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.
Could set rng->state to NULL just in case - I think the object can be referenced even after __destruct
is called.
I don't think that's the issue, though
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.
The object can't be referenced after free_obj, only dtor_obj.
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.
OK, I'll leave this as is.
ext/random/random.c
Outdated
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
if (!rng) { | ||
rng = php_random_rng_xorshfit128plus_new(php_random_ce_Random_NumberGenerator_XorShift128Plus); |
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.
rng = php_random_rng_xorshfit128plus_new(php_random_ce_Random_NumberGenerator_XorShift128Plus); | |
rng = php_random_rng_xorshift128plus_new(php_random_ce_Random_NumberGenerator_XorShift128Plus); |
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.
Fixed.
ext/random/random.c
Outdated
return php_random_rng_next(random->rng, truncate); | ||
} | ||
|
||
rng = Z_OBJ_P(zend_read_property(random->std.ce, &random->std, "rng", sizeof("rng") - 1, 0, NULL)); |
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.
Should add a check that the zval from zend_read_property is IS_OBJECT.
I'm not sure if using a property is efficient, though - e.g. adding a zend_object *obj
to php_random
instead would make that a simple pointer lookup.
Also, with Closure->bindTo, it's possible for userland code to call unset($this->std), I think?
For the alternative, it's possible to override get_properties, get_gc, etc. handlers. Look at SplDoublyLinkedList as an example in ext/spl/spl_dll.c
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.
Thank you. I'll take a look.
ext/random/random.c
Outdated
return ret; | ||
} | ||
|
||
uint64_t php_random_next(php_random *random, bool truncate) |
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.
uint64_t php_random_next(php_random *random, bool truncate) | |
PHPAPI uint64_t php_random_next(php_random *random, bool truncate) |
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.
Fixed
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.
(just scrolling through)
ext/random/random.c
Outdated
zend_string *rng_fname; | ||
zend_function *rng_func; | ||
|
||
if (random->rng) { |
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 think that userland should also be handled via php_random_rng_algo. It should be created on construction, and the state can cache the zend_function for generate for example. This will make it more efficient, and also make your implementation uniform, because you don't need to distinguish between the userland/internal cases. This is a benefit of the Random class vs the previous free functions, as you can do work during construction now.
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.
Now that Random is a final class, this is a very reasonable opinion.
Thanks. I will implement.
ext/random/random.c
Outdated
php_random_rng *rng = php_random_rng_from_obj(object); | ||
|
||
if (rng->state) { | ||
efree(rng->state); |
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.
The object can't be referenced after free_obj, only dtor_obj.
Create an updated RFC and a new Pull-Request. Thanks. |
Added
Random
extension and many classes.RFC is now available.
https://wiki.php.net/rfc/rng_extension
Available Algorithm's
Random\NumberGenerator\XorShift128Plus
)Random\NumberGenerator\MT19937
)php_random_byte()
internally) (Random\NumberGenerator\Secure
)