Skip to content

Commit 2cca3d0

Browse files
committed
Optimized ZEND_SIGNED_MULTIPLY_LONG() (Matt)
1 parent e29684a commit 2cca3d0

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

Diff for: NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ PHP NEWS
4343
. Added ability to handle exceptions in destructors. (Marcus)
4444

4545
- Improved PHP runtime speed and memory usage:
46+
. Optimized ZEND_SIGNED_MULTIPLY_LONG() (Matt)
4647
. Removed direct executor recursion. (Dmitry)
4748
. Use fastcall calling convention in executor on x86. (Dmitry)
4849
. Use IS_CV for direct access to $this variable. (Dmitry)

Diff for: Zend/zend_alloc.c

+13
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,19 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
23552355
return res;
23562356
}
23572357

2358+
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
2359+
2360+
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
2361+
{
2362+
zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
2363+
2364+
if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
2365+
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
2366+
return 0;
2367+
}
2368+
return (size_t) res;
2369+
}
2370+
23582371
#else
23592372

23602373
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)

Diff for: Zend/zend_multiply.h

+13
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@
3131
else (lval) = __tmpvar; \
3232
} while (0)
3333

34+
#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
35+
36+
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
37+
zend_long64 __result = (zend_long64) (a) * (zend_long64) (b); \
38+
if (__result > LONG_MAX || __result < LONG_MIN) { \
39+
(dval) = (double) __result; \
40+
(usedval) = 1; \
41+
} else { \
42+
(lval) = (long) __result; \
43+
(usedval) = 0; \
44+
} \
45+
} while (0)
46+
3447
#else
3548

3649
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \

Diff for: Zend/zend_types.h

+14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ typedef unsigned int zend_uint;
2828
typedef unsigned long zend_ulong;
2929
typedef unsigned short zend_ushort;
3030

31+
#define HAVE_ZEND_LONG64
32+
#ifdef ZEND_WIN32
33+
typedef __int64 zend_long64;
34+
typedef unsigned __int64 zend_ulong64;
35+
#elif SIZEOF_LONG_LONG_INT == 8
36+
typedef long long int zend_long64;
37+
typedef unsigned long long int zend_ulong64;
38+
#elif SIZEOF_LONG_LONG == 8
39+
typedef long long zend_long64;
40+
typedef unsigned long long zend_ulong64;
41+
#else
42+
# undef HAVE_ZEND_LONG64
43+
#endif
44+
3145
#ifdef _WIN64
3246
typedef __int64 zend_intptr_t;
3347
typedef unsigned __int64 zend_uintptr_t;

0 commit comments

Comments
 (0)