diff --git a/ext/random/config.m4 b/ext/random/config.m4 index 86f802247521..0bdb1ed7e3af 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -29,4 +29,4 @@ PHP_NEW_EXTENSION(random, gammasection.c \ randomizer.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) -PHP_INSTALL_HEADERS([ext/random], [php_random.h]) +PHP_INSTALL_HEADERS([ext/random], [php_random.h php_random_uint128.h]) diff --git a/ext/random/config.w32 b/ext/random/config.w32 index 65627c14f971..930ee623ca94 100644 --- a/ext/random/config.w32 +++ b/ext/random/config.w32 @@ -1,4 +1,4 @@ EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); PHP_RANDOM="yes"; ADD_SOURCES(configure_module_dirname, "csprng.c engine_combinedlcg.c engine_mt19937.c engine_pcgoneseq128xslrr64.c engine_xoshiro256starstar.c engine_secure.c engine_user.c gammasection.c randomizer.c", "random"); -PHP_INSTALL_HEADERS("ext/random", "php_random.h"); +PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_uint128.h"); diff --git a/ext/random/engine_pcgoneseq128xslrr64.c b/ext/random/engine_pcgoneseq128xslrr64.c index b19aff7e987e..f7c5f0ebbcfc 100644 --- a/ext/random/engine_pcgoneseq128xslrr64.c +++ b/ext/random/engine_pcgoneseq128xslrr64.c @@ -22,6 +22,7 @@ #include "php.h" #include "php_random.h" +#include "php_random_uint128.h" #include "Zend/zend_exceptions.h" diff --git a/ext/random/php_random.h b/ext/random/php_random.h index 9fc29951f383..b3e2400d9959 100644 --- a/ext/random/php_random.h +++ b/ext/random/php_random.h @@ -32,6 +32,7 @@ # define PHP_RANDOM_H # include "php.h" +# include "php_random_uint128.h" PHPAPI double php_combined_lcg(void); @@ -64,109 +65,6 @@ PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max); PHPAPI void php_srand(zend_long seed); PHPAPI zend_long php_rand(void); -# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128) -typedef struct _php_random_uint128_t { - uint64_t hi; - uint64_t lo; -} php_random_uint128_t; - -static inline uint64_t php_random_uint128_hi(php_random_uint128_t num) -{ - return num.hi; -} - -static inline uint64_t php_random_uint128_lo(php_random_uint128_t num) -{ - return num.lo; -} - -static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo) -{ - php_random_uint128_t r; - - r.hi = hi; - r.lo = lo; - - return r; -} - -static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2) -{ - php_random_uint128_t r; - - r.lo = (num1.lo + num2.lo); - r.hi = (num1.hi + num2.hi + (r.lo < num1.lo)); - - return r; -} - -static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2) -{ - php_random_uint128_t r; - const uint64_t - x0 = num1.lo & 0xffffffffULL, - x1 = num1.lo >> 32, - y0 = num2.lo & 0xffffffffULL, - y1 = num2.lo >> 32, - z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1; - - r.hi = num1.hi * num2.lo + num1.lo * num2.hi; - r.lo = num1.lo * num2.lo; - r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32); - - return r; -} - -static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num) -{ - const uint64_t - v = (num.hi ^ num.lo), - s = num.hi >> 58U; - - return (v >> s) | (v << ((-s) & 63)); -} -# else -typedef __uint128_t php_random_uint128_t; - -static inline uint64_t php_random_uint128_hi(php_random_uint128_t num) -{ - return (uint64_t) (num >> 64); -} - -static inline uint64_t php_random_uint128_lo(php_random_uint128_t num) -{ - return (uint64_t) num; -} - -static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo) -{ - php_random_uint128_t r; - - r = ((php_random_uint128_t) hi << 64) + lo; - - return r; -} - -static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2) -{ - return num1 + num2; -} - -static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2) -{ - return num1 * num2; -} - -static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num) -{ - const uint64_t - v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num, - s = num >> 122U; - - return (v >> s) | (v << ((-s) & 63)); -} -# endif - PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw); PHPAPI zend_result php_random_int(zend_long min, zend_long max, zend_long *result, bool should_throw); diff --git a/ext/random/php_random_uint128.h b/ext/random/php_random_uint128.h new file mode 100644 index 000000000000..8c484ce5ba9f --- /dev/null +++ b/ext/random/php_random_uint128.h @@ -0,0 +1,128 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Tim Düsterhus | + | Go Kudo | + | | + | Based on code from: Melissa O'Neill | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_RANDOM_UINT128_H +# define PHP_RANDOM_UINT128_H + +# include + +# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128) +typedef struct _php_random_uint128_t { + uint64_t hi; + uint64_t lo; +} php_random_uint128_t; + +static inline uint64_t php_random_uint128_hi(php_random_uint128_t num) +{ + return num.hi; +} + +static inline uint64_t php_random_uint128_lo(php_random_uint128_t num) +{ + return num.lo; +} + +static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo) +{ + php_random_uint128_t r; + + r.hi = hi; + r.lo = lo; + + return r; +} + +static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2) +{ + php_random_uint128_t r; + + r.lo = (num1.lo + num2.lo); + r.hi = (num1.hi + num2.hi + (r.lo < num1.lo)); + + return r; +} + +static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2) +{ + php_random_uint128_t r; + const uint64_t + x0 = num1.lo & 0xffffffffULL, + x1 = num1.lo >> 32, + y0 = num2.lo & 0xffffffffULL, + y1 = num2.lo >> 32, + z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1; + + r.hi = num1.hi * num2.lo + num1.lo * num2.hi; + r.lo = num1.lo * num2.lo; + r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32); + + return r; +} + +static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num) +{ + const uint64_t + v = (num.hi ^ num.lo), + s = num.hi >> 58U; + + return (v >> s) | (v << ((-s) & 63)); +} +# else +typedef __uint128_t php_random_uint128_t; + +static inline uint64_t php_random_uint128_hi(php_random_uint128_t num) +{ + return (uint64_t) (num >> 64); +} + +static inline uint64_t php_random_uint128_lo(php_random_uint128_t num) +{ + return (uint64_t) num; +} + +static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo) +{ + php_random_uint128_t r; + + r = ((php_random_uint128_t) hi << 64) + lo; + + return r; +} + +static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2) +{ + return num1 + num2; +} + +static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2) +{ + return num1 * num2; +} + +static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num) +{ + const uint64_t + v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num, + s = num >> 122U; + + return (v >> s) | (v << ((-s) & 63)); +} +# endif + +#endif /* PHP_RANDOM_UINT128_H */