Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.60
diff -u -r1.296.2.27.2.34.2.60 zend_API.c
--- Zend/zend_API.c	14 Jan 2009 11:56:08 -0000	1.296.2.27.2.34.2.60
+++ Zend/zend_API.c	13 Mar 2009 17:30:00 -0000
@@ -313,6 +313,7 @@
 
 	switch (c) {
 		case 'l':
+		case 'L':
 			{
 				long *p = va_arg(*va, long *);
 				switch (Z_TYPE_PP(arg)) {
@@ -324,14 +325,33 @@
 							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;
 
+					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.647.2.27.2.41.2.103
diff -u -r1.647.2.27.2.41.2.103 zend_compile.c
--- Zend/zend_compile.c	10 Mar 2009 10:01:44 -0000	1.647.2.27.2.41.2.103
+++ Zend/zend_compile.c	13 Mar 2009 14:44:00 -0000
@@ -4041,7 +4041,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.716.2.12.2.24.2.41
diff -u -r1.716.2.12.2.24.2.41 zend_execute.c
--- Zend/zend_execute.c	18 Mar 2009 14:15:28 -0000	1.716.2.12.2.24.2.41
+++ Zend/zend_execute.c	19 Mar 2009 00:26:23 -0000
@@ -825,10 +825,9 @@
 				}
 			}
 			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.331.2.20.2.24.2.75
diff -u -r1.331.2.20.2.24.2.75 zend_execute_API.c
--- Zend/zend_execute_API.c	19 Mar 2009 18:34:16 -0000	1.331.2.20.2.24.2.75
+++ Zend/zend_execute_API.c	19 Mar 2009 19:58:38 -0000
@@ -662,7 +662,7 @@
 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 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, 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, 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, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
Index: Zend/zend_operators.c
===================================================================
RCS file: /repository/ZendEngine2/zend_operators.c,v
retrieving revision 1.208.2.4.2.23.2.22
diff -u -r1.208.2.4.2.23.2.22 zend_operators.c
--- Zend/zend_operators.c	18 Mar 2009 11:25:37 -0000	1.208.2.4.2.23.2.22
+++ Zend/zend_operators.c	19 Mar 2009 00:26:23 -0000
@@ -220,7 +220,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);	\
@@ -338,7 +338,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:
 			strval = Z_STRVAL_P(op);
@@ -1010,7 +1010,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.94.2.4.2.10.2.14
diff -u -r1.94.2.4.2.10.2.14 zend_operators.h
--- Zend/zend_operators.h	18 Mar 2009 01:08:12 -0000	1.94.2.4.2.10.2.14
+++ Zend/zend_operators.h	19 Mar 2009 00:26:23 -0000
@@ -63,39 +63,40 @@
 ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC);
 END_EXTERN_C()
 
-#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;
+}
 
 #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
 #define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a'  && (c) <= 'f'))
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.88
diff -u -r1.59.2.29.2.48.2.88 zend_vm_def.h
--- Zend/zend_vm_def.h	18 Mar 2009 18:49:27 -0000	1.59.2.29.2.48.2.88
+++ Zend/zend_vm_def.h	19 Mar 2009 00:26:24 -0000
@@ -3086,11 +3086,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:
@@ -3409,7 +3407,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)) {
@@ -3421,14 +3418,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:
 						if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
@@ -3908,7 +3903,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;
@@ -3922,16 +3916,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;
