Skip to content

Commit 45f8cfa

Browse files
authored
random: Split the uint128 implementation into its own header (php#13132)
The implementation of `php_random_uint128_*` exists specifically for pcgoneseq128xslrr66 and takes up a third of php_random.h. Split it into its own header to keep php_random.h focused on the functionality directly related to randomness.
1 parent 07d2fcc commit 45f8cfa

File tree

5 files changed

+132
-105
lines changed

5 files changed

+132
-105
lines changed

ext/random/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ PHP_NEW_EXTENSION(random,
2929
gammasection.c \
3030
randomizer.c,
3131
no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
32-
PHP_INSTALL_HEADERS([ext/random], [php_random.h])
32+
PHP_INSTALL_HEADERS([ext/random], [php_random.h php_random_uint128.h])

ext/random/config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
22
PHP_RANDOM="yes";
33
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");
4-
PHP_INSTALL_HEADERS("ext/random", "php_random.h");
4+
PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_uint128.h");

ext/random/engine_pcgoneseq128xslrr64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "php.h"
2424
#include "php_random.h"
25+
#include "php_random_uint128.h"
2526

2627
#include "Zend/zend_exceptions.h"
2728

ext/random/php_random.h

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
# define PHP_RANDOM_H
3333

3434
# include "php.h"
35+
# include "php_random_uint128.h"
3536

3637
PHPAPI double php_combined_lcg(void);
3738

@@ -64,109 +65,6 @@ PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max);
6465
PHPAPI void php_srand(zend_long seed);
6566
PHPAPI zend_long php_rand(void);
6667

67-
# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128)
68-
typedef struct _php_random_uint128_t {
69-
uint64_t hi;
70-
uint64_t lo;
71-
} php_random_uint128_t;
72-
73-
static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
74-
{
75-
return num.hi;
76-
}
77-
78-
static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
79-
{
80-
return num.lo;
81-
}
82-
83-
static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
84-
{
85-
php_random_uint128_t r;
86-
87-
r.hi = hi;
88-
r.lo = lo;
89-
90-
return r;
91-
}
92-
93-
static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
94-
{
95-
php_random_uint128_t r;
96-
97-
r.lo = (num1.lo + num2.lo);
98-
r.hi = (num1.hi + num2.hi + (r.lo < num1.lo));
99-
100-
return r;
101-
}
102-
103-
static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
104-
{
105-
php_random_uint128_t r;
106-
const uint64_t
107-
x0 = num1.lo & 0xffffffffULL,
108-
x1 = num1.lo >> 32,
109-
y0 = num2.lo & 0xffffffffULL,
110-
y1 = num2.lo >> 32,
111-
z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1;
112-
113-
r.hi = num1.hi * num2.lo + num1.lo * num2.hi;
114-
r.lo = num1.lo * num2.lo;
115-
r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32);
116-
117-
return r;
118-
}
119-
120-
static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
121-
{
122-
const uint64_t
123-
v = (num.hi ^ num.lo),
124-
s = num.hi >> 58U;
125-
126-
return (v >> s) | (v << ((-s) & 63));
127-
}
128-
# else
129-
typedef __uint128_t php_random_uint128_t;
130-
131-
static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
132-
{
133-
return (uint64_t) (num >> 64);
134-
}
135-
136-
static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
137-
{
138-
return (uint64_t) num;
139-
}
140-
141-
static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
142-
{
143-
php_random_uint128_t r;
144-
145-
r = ((php_random_uint128_t) hi << 64) + lo;
146-
147-
return r;
148-
}
149-
150-
static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
151-
{
152-
return num1 + num2;
153-
}
154-
155-
static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
156-
{
157-
return num1 * num2;
158-
}
159-
160-
static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
161-
{
162-
const uint64_t
163-
v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num,
164-
s = num >> 122U;
165-
166-
return (v >> s) | (v << ((-s) & 63));
167-
}
168-
# endif
169-
17068
PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw);
17169
PHPAPI zend_result php_random_int(zend_long min, zend_long max, zend_long *result, bool should_throw);
17270

ext/random/php_random_uint128.h

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| [email protected] so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Tim Düsterhus <[email protected]> |
14+
| Go Kudo <[email protected]> |
15+
| |
16+
| Based on code from: Melissa O'Neill <[email protected]> |
17+
+----------------------------------------------------------------------+
18+
*/
19+
20+
#ifndef PHP_RANDOM_UINT128_H
21+
# define PHP_RANDOM_UINT128_H
22+
23+
# include <stdint.h>
24+
25+
# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128)
26+
typedef struct _php_random_uint128_t {
27+
uint64_t hi;
28+
uint64_t lo;
29+
} php_random_uint128_t;
30+
31+
static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
32+
{
33+
return num.hi;
34+
}
35+
36+
static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
37+
{
38+
return num.lo;
39+
}
40+
41+
static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
42+
{
43+
php_random_uint128_t r;
44+
45+
r.hi = hi;
46+
r.lo = lo;
47+
48+
return r;
49+
}
50+
51+
static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
52+
{
53+
php_random_uint128_t r;
54+
55+
r.lo = (num1.lo + num2.lo);
56+
r.hi = (num1.hi + num2.hi + (r.lo < num1.lo));
57+
58+
return r;
59+
}
60+
61+
static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
62+
{
63+
php_random_uint128_t r;
64+
const uint64_t
65+
x0 = num1.lo & 0xffffffffULL,
66+
x1 = num1.lo >> 32,
67+
y0 = num2.lo & 0xffffffffULL,
68+
y1 = num2.lo >> 32,
69+
z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1;
70+
71+
r.hi = num1.hi * num2.lo + num1.lo * num2.hi;
72+
r.lo = num1.lo * num2.lo;
73+
r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32);
74+
75+
return r;
76+
}
77+
78+
static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
79+
{
80+
const uint64_t
81+
v = (num.hi ^ num.lo),
82+
s = num.hi >> 58U;
83+
84+
return (v >> s) | (v << ((-s) & 63));
85+
}
86+
# else
87+
typedef __uint128_t php_random_uint128_t;
88+
89+
static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
90+
{
91+
return (uint64_t) (num >> 64);
92+
}
93+
94+
static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
95+
{
96+
return (uint64_t) num;
97+
}
98+
99+
static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
100+
{
101+
php_random_uint128_t r;
102+
103+
r = ((php_random_uint128_t) hi << 64) + lo;
104+
105+
return r;
106+
}
107+
108+
static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
109+
{
110+
return num1 + num2;
111+
}
112+
113+
static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
114+
{
115+
return num1 * num2;
116+
}
117+
118+
static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
119+
{
120+
const uint64_t
121+
v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num,
122+
s = num >> 122U;
123+
124+
return (v >> s) | (v << ((-s) & 63));
125+
}
126+
# endif
127+
128+
#endif /* PHP_RANDOM_UINT128_H */

0 commit comments

Comments
 (0)