Ensure consistent order of evaluation in LLInt slow paths
https://bugs.webkit.org/show_bug.cgi?id=88409
Reviewed by Geoffrey Garen.
* llint/LLIntSlowPaths.cpp:
(slow_path_mul)
(slow_path_sub)
(slow_path_div)
(slow_path_mod)
(slow_path_lshift)
(slow_path_rshift)
(slow_path_urshift)
(slow_path_bitand)
(slow_path_bitor)
(slow_path_bitxor): Avoid calling toNumber, toInt32, or toUInt32
multiple times without intervening sequence points. Fixes
fast/js/exception-sequencing-binops.html with GCC 4.7 on x86-64
Linux, which reordered evaluation of the arguments to fmod.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@119602 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 3558be9..1865c2d 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,5 +1,27 @@
2012-06-06 Andy Wingo <wingo@igalia.com>
+ Ensure consistent order of evaluation in LLInt slow paths
+ https://bugs.webkit.org/show_bug.cgi?id=88409
+
+ Reviewed by Geoffrey Garen.
+
+ * llint/LLIntSlowPaths.cpp:
+ (slow_path_mul)
+ (slow_path_sub)
+ (slow_path_div)
+ (slow_path_mod)
+ (slow_path_lshift)
+ (slow_path_rshift)
+ (slow_path_urshift)
+ (slow_path_bitand)
+ (slow_path_bitor)
+ (slow_path_bitxor): Avoid calling toNumber, toInt32, or toUInt32
+ multiple times without intervening sequence points. Fixes
+ fast/js/exception-sequencing-binops.html with GCC 4.7 on x86-64
+ Linux, which reordered evaluation of the arguments to fmod.
+
+2012-06-06 Andy Wingo <wingo@igalia.com>
+
[GTK] Enable the LLInt
https://bugs.webkit.org/show_bug.cgi?id=88315
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index ac567bd..7133b0d 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -621,64 +621,88 @@
LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
}
+// The following arithmetic and bitwise operations need to be sure to run
+// toNumber() on their operands in order. (A call to toNumber() is idempotent
+// if an exception is already set on the ExecState.)
+
LLINT_SLOW_PATH_DECL(slow_path_mul)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) * LLINT_OP_C(3).jsValue().toNumber(exec)));
+ double a = LLINT_OP_C(2).jsValue().toNumber(exec);
+ double b = LLINT_OP_C(3).jsValue().toNumber(exec);
+ LLINT_RETURN(jsNumber(a * b));
}
LLINT_SLOW_PATH_DECL(slow_path_sub)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) - LLINT_OP_C(3).jsValue().toNumber(exec)));
+ double a = LLINT_OP_C(2).jsValue().toNumber(exec);
+ double b = LLINT_OP_C(3).jsValue().toNumber(exec);
+ LLINT_RETURN(jsNumber(a - b));
}
LLINT_SLOW_PATH_DECL(slow_path_div)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) / LLINT_OP_C(3).jsValue().toNumber(exec)));
+ double a = LLINT_OP_C(2).jsValue().toNumber(exec);
+ double b = LLINT_OP_C(3).jsValue().toNumber(exec);
+ LLINT_RETURN(jsNumber(a / b));
}
LLINT_SLOW_PATH_DECL(slow_path_mod)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(fmod(LLINT_OP_C(2).jsValue().toNumber(exec), LLINT_OP_C(3).jsValue().toNumber(exec))));
+ double a = LLINT_OP_C(2).jsValue().toNumber(exec);
+ double b = LLINT_OP_C(3).jsValue().toNumber(exec);
+ LLINT_RETURN(jsNumber(fmod(a, b)));
}
LLINT_SLOW_PATH_DECL(slow_path_lshift)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) << (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
+ int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
+ uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
+ LLINT_RETURN(jsNumber(a << (b & 31)));
}
LLINT_SLOW_PATH_DECL(slow_path_rshift)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) >> (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
+ int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
+ uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
+ LLINT_RETURN(jsNumber(a >> (b & 31)));
}
LLINT_SLOW_PATH_DECL(slow_path_urshift)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toUInt32(exec) >> (LLINT_OP_C(3).jsValue().toUInt32(exec) & 31)));
+ uint32_t a = LLINT_OP_C(2).jsValue().toUInt32(exec);
+ uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
+ LLINT_RETURN(jsNumber(a >> (b & 31)));
}
LLINT_SLOW_PATH_DECL(slow_path_bitand)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) & LLINT_OP_C(3).jsValue().toInt32(exec)));
+ int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
+ int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
+ LLINT_RETURN(jsNumber(a & b));
}
LLINT_SLOW_PATH_DECL(slow_path_bitor)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) | LLINT_OP_C(3).jsValue().toInt32(exec)));
+ int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
+ int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
+ LLINT_RETURN(jsNumber(a | b));
}
LLINT_SLOW_PATH_DECL(slow_path_bitxor)
{
LLINT_BEGIN();
- LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
+ int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
+ int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
+ LLINT_RETURN(jsNumber(a ^ b));
}
LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)