Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.496
diff -u -r1.496 zend_API.c
--- Zend/zend_API.c	14 Jan 2009 11:56:24 -0000	1.496
+++ Zend/zend_API.c	13 Mar 2009 17:44:30 -0000
@@ -349,6 +349,7 @@
 
 	switch (c) {
 		case 'l':
+		case 'L':
 			{
 				long *p = va_arg(*va, long *);
 				switch (Z_TYPE_PP(arg)) {
@@ -360,7 +361,17 @@
 							if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, -1)) == 0) {
 								return "long";
 							} else if (type == IS_DOUBLE) {
-								*p = (long) d;
+								if (c == 'L') {
+									if (d > LONG_MAX) {
+										*p = LONG_MAX;
+										break;
+									} else if (d < LONG_MIN) {
+										*p = LONG_MIN;
+										break;
+									}
+								}
+
+								*p = zend_dval_to_lval(d);
 							}
 						}
 						break;
@@ -373,14 +384,33 @@
 							if ((type = is_numeric_unicode(Z_USTRVAL_PP(arg), Z_USTRLEN_PP(arg), p, &d, -1)) == 0) {
 								return "long";
 							} else if (type == IS_DOUBLE) {
-								*p = (long) d;
+								if (c == 'L') {
+									if (d > LONG_MAX) {
+										*p = LONG_MAX;
+										break;
+									} else if (d < LONG_MIN) {
+										*p = LONG_MIN;
+										break;
+									}
+								}
+
+								*p = zend_dval_to_lval(d);
 							}
 						}
 						break;
 
+					case IS_DOUBLE:
+						if (c == 'L') {
+							if (Z_DVAL_PP(arg) > LONG_MAX) {
+								*p = LONG_MAX;
+								break;
+							} else if (Z_DVAL_PP(arg) < LONG_MIN) {
+								*p = LONG_MIN;
+								break;
+							}
+						}
 					case IS_NULL:
 					case IS_LONG:
-					case IS_DOUBLE:
 					case IS_BOOL:
 						convert_to_long_ex(arg);
 						*p = Z_LVAL_PP(arg);
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.851
diff -u -r1.851 zend_compile.c
--- Zend/zend_compile.c	10 Mar 2009 10:01:28 -0000	1.851
+++ Zend/zend_compile.c	13 Mar 2009 17:54:50 -0000
@@ -4285,7 +4285,7 @@
 				zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_LVAL(offset->u.constant), &element, sizeof(zval *), NULL);
 				break;
 			case IS_DOUBLE:
-				zend_hash_index_update(Z_ARRVAL(result->u.constant), (long)Z_DVAL(offset->u.constant), &element, sizeof(zval *), NULL);
+				zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_lval(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL);
 				break;
 			case IS_CONSTANT_ARRAY:
 				zend_error(E_ERROR, "Illegal offset type");
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.810
diff -u -r1.810 zend_execute.c
--- Zend/zend_execute.c	18 Mar 2009 14:15:59 -0000	1.810
+++ Zend/zend_execute.c	19 Mar 2009 00:25:49 -0000
@@ -927,10 +927,9 @@
 				efree(offset_key.v);
 			}
 			break;
-		case IS_DOUBLE: {
-			DVAL_TO_LVAL(Z_DVAL_P(dim), index);
+		case IS_DOUBLE:
+			index = zend_dval_to_lval(Z_DVAL_P(dim));
 			goto num_index;
-		}
 		case IS_RESOURCE:
 			zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
 			/* Fall Through */
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.475
diff -u -r1.475 zend_execute_API.c
--- Zend/zend_execute_API.c	19 Mar 2009 18:32:45 -0000	1.475
+++ Zend/zend_execute_API.c	19 Mar 2009 19:58:01 -0000
@@ -729,7 +729,7 @@
 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
 					break;
 				case IS_DOUBLE:
-					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 0, (long)Z_DVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
+					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
 					break;
 				case IS_NULL:
 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, EMPTY_ZSTR, 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
Index: Zend/zend_operators.c
===================================================================
RCS file: /repository/ZendEngine2/zend_operators.c,v
retrieving revision 1.302
diff -u -r1.302 zend_operators.c
--- Zend/zend_operators.c	18 Mar 2009 11:25:47 -0000	1.302
+++ Zend/zend_operators.c	19 Mar 2009 00:25:50 -0000
@@ -277,7 +277,7 @@
 				Z_LVAL(holder) = 0;									\
 				break;												\
 			case IS_DOUBLE:											\
-				DVAL_TO_LVAL(Z_DVAL_P(op), Z_LVAL(holder));			\
+				Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));	\
 				break;												\
 			case IS_STRING:											\
 				Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);	\
@@ -411,7 +411,7 @@
 		case IS_LONG:
 			break;
 		case IS_DOUBLE:
-			DVAL_TO_LVAL(Z_DVAL_P(op), Z_LVAL_P(op));
+			Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
 			break;
 		case IS_STRING:
 			{
@@ -1531,7 +1531,7 @@
 		ZVAL_LONG(result, ~Z_LVAL_P(op1));
 		return SUCCESS;
 	} else if (Z_TYPE_P(op1) == IS_DOUBLE) {
-		ZVAL_LONG(result, ~(long)Z_DVAL_P(op1));
+		ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
 		return SUCCESS;
 	} else if (Z_TYPE_P(op1) == IS_STRING) {
 		int i;
Index: Zend/zend_operators.h
===================================================================
RCS file: /repository/ZendEngine2/zend_operators.h,v
retrieving revision 1.136
diff -u -r1.136 zend_operators.h
--- Zend/zend_operators.h	18 Mar 2009 01:06:30 -0000	1.136
+++ Zend/zend_operators.h	19 Mar 2009 00:25:50 -0000
@@ -66,40 +66,40 @@
 ZEND_API double zend_u_strtod(const UChar *nptr, UChar **endptr);
 END_EXTERN_C()
 
-/* {{{ DVAL_TO_LVAL */
-#define MAX_UNSIGNED_INT ((double) LONG_MAX * 2) + 1
-#ifdef _WIN64
-# define DVAL_TO_LVAL(d, l) \
-       if ((d) > LONG_MAX) { \
-               (l) = (long)(unsigned long)(__int64) (d); \
-       } else { \
-               (l) = (long) (d); \
-       }
-#elif !defined(_WIN64) && __WORDSIZE == 64
-# define DVAL_TO_LVAL(d, l) \
-       if ((d) >= LONG_MAX) { \
-               (l) = LONG_MAX; \
-       } else if ((d) <=  LONG_MIN) { \
-               (l) = LONG_MIN; \
-       } else {\
-               (l) = (long) (d); \
-       }
+static zend_always_inline long zend_dval_to_lval(double d) /* {{{ */
+{
+#if __WORDSIZE == 64 && !defined(_WIN64) /* SIZEOF_LONG == 8 ??? */
+	if (d > LONG_MAX) {
+		return (long)(unsigned long) d;
+	}
+#elif defined(HAVE_ZEND_LONG64)
+	if (d > LONG_MAX || d < LONG_MIN) {
+		unsigned long ul = (unsigned long)(zend_long64) d;
+
+		if (ul > LONG_MAX) {
+			return (long) (ul + LONG_MIN) + LONG_MIN;
+		}
+		return (long) ul;
+	}
 #else
-# define DVAL_TO_LVAL(d, l) \
-       if ((d) > LONG_MAX) { \
-               if ((d) > MAX_UNSIGNED_INT) { \
-                       (l) = LONG_MAX; \
-               } else { \
-                       (l) = (unsigned long) (d); \
-               } \
-       } else { \
-               if((d) < LONG_MIN) { \
-                       (l) = LONG_MIN; \
-               } else { \
-                       (l) = (long) (d); \
-               } \
-       }
+	if (d > LONG_MAX) {
+		unsigned long ul = (unsigned long) d;
+
+		if (ul > LONG_MAX) {
+			return (long) (ul + LONG_MIN) + LONG_MIN;
+		}
+		return (long) ul;
+	} else if (d < LONG_MIN) {
+		unsigned long ul = (unsigned long) -d;
+
+		if (ul > LONG_MAX) {
+			return -(long) (ul + LONG_MIN) + LONG_MIN;
+		}
+		return -(long) ul;
+	}
 #endif
+	return (long) d;
+}
 /* }}} */
 
 static inline zend_uchar is_numeric_string(char *str, int length, long *lval, double *dval, int allow_errors)
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.260
diff -u -r1.260 zend_vm_def.h
--- Zend/zend_vm_def.h	18 Mar 2009 18:48:52 -0000	1.260
+++ Zend/zend_vm_def.h	19 Mar 2009 00:25:51 -0000
@@ -3164,11 +3164,9 @@
 		}
 	}
 	if (offset) {
-	  	long l;
 		switch (Z_TYPE_P(offset)) {
 			case IS_DOUBLE:
-			  	DVAL_TO_LVAL(Z_DVAL_P(offset), l);
-				zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
+				zend_hash_index_update(Z_ARRVAL_P(array_ptr), zend_dval_to_lval(Z_DVAL_P(offset)), &expr_ptr, sizeof(zval *), NULL);
 				break;
 			case IS_LONG:
 			case IS_BOOL:
@@ -3532,7 +3530,6 @@
 	zend_free_op free_op1, free_op2;
 	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
 	zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
-	long index;
 
 	if (OP1_TYPE != IS_VAR || container) {
 		if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -3544,14 +3541,12 @@
 
 				switch (Z_TYPE_P(offset)) {
 					case IS_DOUBLE:
-						index = (long) Z_DVAL_P(offset);
-						zend_hash_index_del(ht, index);
+						zend_hash_index_del(ht, zend_dval_to_lval(Z_DVAL_P(offset)));
 						break;
 					case IS_RESOURCE:
 					case IS_BOOL:
 					case IS_LONG:
-						index = Z_LVAL_P(offset);
-						zend_hash_index_del(ht, index);
+						zend_hash_index_del(ht, Z_LVAL_P(offset));
 						break;
 					case IS_STRING:
 					case IS_UNICODE: {
@@ -4066,7 +4061,6 @@
 	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS);
 	zval **value = NULL;
 	int result = 0;
-	long index;
 
 	if (OP1_TYPE != IS_VAR || container) {
 		zend_free_op free_op2;
@@ -4080,16 +4074,14 @@
 
 			switch (Z_TYPE_P(offset)) {
 				case IS_DOUBLE:
-					index = (long) Z_DVAL_P(offset);
-					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
+					if (zend_hash_index_find(ht, zend_dval_to_lval(Z_DVAL_P(offset)), (void **) &value) == SUCCESS) {
 						isset = 1;
 					}
 					break;
 				case IS_RESOURCE:
 				case IS_BOOL:
 				case IS_LONG:
-					index = Z_LVAL_P(offset);
-					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
+					if (zend_hash_index_find(ht, Z_LVAL_P(offset), (void **) &value) == SUCCESS) {
 						isset = 1;
 					}
 					break;
