summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2008-07-24 13:46:48 +0000
committerDmitry Stogov <dmitry@php.net>2008-07-24 13:46:48 +0000
commit0c77613d776a9236da401b3553f48b6d5a4c72b3 (patch)
tree8a6499e08bb139ae36d95f7d5ef9756c554fbf59
parent33be49a588c305a7e3db66e2f1fe30d6543731b6 (diff)
downloadphp-git-0c77613d776a9236da401b3553f48b6d5a4c72b3.tar.gz
Optimized ZEND_SIGNED_MULTIPLY_LONG() (Matt)
-rw-r--r--Zend/zend_alloc.c13
-rw-r--r--Zend/zend_multiply.h13
-rw-r--r--Zend/zend_types.h14
3 files changed, 40 insertions, 0 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index d758b8bbf4..27e392ccc2 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -2402,6 +2402,19 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
return res;
}
+#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
+
+static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+{
+ zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
+
+ if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return (size_t) res;
+}
+
#else
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) /* {{{ */
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index 0fe9eeba20..8f5f03d70e 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -31,6 +31,19 @@
else (lval) = __tmpvar; \
} while (0)
+#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ zend_long64 __result = (zend_long64) (a) * (zend_long64) (b); \
+ if (__result > LONG_MAX || __result < LONG_MIN) { \
+ (dval) = (double) __result; \
+ (usedval) = 1; \
+ } else { \
+ (lval) = (long) __result; \
+ (usedval) = 0; \
+ } \
+} while (0)
+
#else
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 66b328547b..9ea1c44f21 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -28,6 +28,20 @@ typedef unsigned int zend_uint;
typedef unsigned long zend_ulong;
typedef unsigned short zend_ushort;
+#define HAVE_ZEND_LONG64
+#ifdef ZEND_WIN32
+typedef __int64 zend_long64;
+typedef unsigned __int64 zend_ulong64;
+#elif SIZEOF_LONG_LONG_INT == 8
+typedef long long int zend_long64;
+typedef unsigned long long int zend_ulong64;
+#elif SIZEOF_LONG_LONG == 8
+typedef long long zend_long64;
+typedef unsigned long long zend_ulong64;
+#else
+# undef HAVE_ZEND_LONG64
+#endif
+
#ifdef _WIN64
typedef __int64 zend_intptr_t;
typedef unsigned __int64 zend_uintptr_t;