Title: [90401] trunk
Revision
90401
Author
[email protected]
Date
2011-07-05 12:01:41 -0700 (Tue, 05 Jul 2011)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=63880
Evaluation order of conversions of operands to >, >= incorrect.

Reviewed by Sam Weinig.

Source/_javascript_Core: 

Add 'leftFirst' parameter to jsLess, jsLessEq matching that described in the ES5
spec. This allows these methods to be reused to perform >, >= relational compares
with correct ordering of type conversions.

* dfg/DFGOperations.cpp:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Operations.h:
(JSC::jsLess):
(JSC::jsLessEq):

LayoutTests: 

Updated layout test results. Two of these tests now pass, however for
the third we now need to check in failing results, since the test is
incorrect!

The problem if that the test author has made the mistake of thinking
that the evaluation order for the operands to '>' is RHS then LHS.
This is due to a quirk in the way the spec is written. The greater
than opeator is defined to call the abstract relational comparison
algorithm with 'leftFirst' set to false, and as such conversion is
performed on the second operand ('y') first (see 11.8.5). However
the abstract relational comparison algorith is performing a less
than comaprison, and the greater than operator calls this algorithm
with the operands to the greater than operator reversed (see 11.8.2).
As such, the second operand to the abstract comaparison is the LHS
of the greater than. This bug also affects the corresponding less
than or equals test, where we already we have failing results checked
in, and again it is the test that is wrong (for the same reason).

* fast/js/exception-sequencing-binops2-expected.txt:
* sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.2_The_Greater_than_Operator/S11.8.2_A2.3_T1-expected.txt:
* sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.4_The_Grater_than_or_equal_Operator/S11.8.4_A2.3_T1-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (90400 => 90401)


--- trunk/LayoutTests/ChangeLog	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/LayoutTests/ChangeLog	2011-07-05 19:01:41 UTC (rev 90401)
@@ -1,3 +1,32 @@
+2011-07-04  Gavin Barraclough  <[email protected]>
+
+        https://bugs.webkit.org/show_bug.cgi?id=63880
+        Evaluation order of conversions of operands to >, >= incorrect.
+
+        Reviewed by Sam Weinig.
+
+        Updated layout test results. Two of these tests now pass, however for
+        the third we now need to check in failing results, since the test is
+        incorrect!
+
+        The problem if that the test author has made the mistake of thinking
+        that the evaluation order for the operands to '>' is RHS then LHS.
+        This is due to a quirk in the way the spec is written. The greater
+        than opeator is defined to call the abstract relational comparison
+        algorithm with 'leftFirst' set to false, and as such conversion is
+        performed on the second operand ('y') first (see 11.8.5). However
+        the abstract relational comparison algorith is performing a less
+        than comaprison, and the greater than operator calls this algorithm
+        with the operands to the greater than operator reversed (see 11.8.2).
+        As such, the second operand to the abstract comaparison is the LHS
+        of the greater than. This bug also affects the corresponding less
+        than or equals test, where we already we have failing results checked
+        in, and again it is the test that is wrong (for the same reason).
+
+        * fast/js/exception-sequencing-binops2-expected.txt:
+        * sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.2_The_Greater_than_Operator/S11.8.2_A2.3_T1-expected.txt:
+        * sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.4_The_Grater_than_or_equal_Operator/S11.8.4_A2.3_T1-expected.txt:
+
 2011-07-05  Andrey Kosyakov  <[email protected]>
 
         Unreviewed. Marked css2.1/20110323/replaced-intrinsic-ratio-001.htm as flaky on mac.

Modified: trunk/LayoutTests/fast/js/exception-sequencing-binops2-expected.txt (90400 => 90401)


--- trunk/LayoutTests/fast/js/exception-sequencing-binops2-expected.txt	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/LayoutTests/fast/js/exception-sequencing-binops2-expected.txt	2011-07-05 19:01:41 UTC (rev 90401)
@@ -56,13 +56,13 @@
 PASS: Handled "'string' >= throwingProperty" correctly.
 PASS: Handled "'string' >= ({get throwingProperty(){ throw "throwing property" }}).throwingProperty" correctly.
 PASS: Handled "'string' >= getterThrower.value" correctly.
-FAIL: "valueOfThrower >= rhsNonZeroNum" threw exception, but executed right hand half of _expression_
-FAIL: "toStringThrower >= rhsNonZeroNum" threw exception, but executed right hand half of _expression_
+PASS: Handled "valueOfThrower >= rhsNonZeroNum" correctly.
+PASS: Handled "toStringThrower >= rhsNonZeroNum" correctly.
 PASS: Handled "throwingProperty >= rhsNonZeroNum" correctly.
 PASS: Handled "({get throwingProperty(){ throw "throwing property" }}).throwingProperty >= rhsNonZeroNum" correctly.
 PASS: Handled "getterThrower.value >= rhsNonZeroNum" correctly.
-FAIL: "valueOfThrower >= rhsToStringThrower" threw exception, but executed right hand half of _expression_
-FAIL: "toStringThrower >= rhsToStringThrower" threw exception, but executed right hand half of _expression_
+PASS: Handled "valueOfThrower >= rhsToStringThrower" correctly.
+PASS: Handled "toStringThrower >= rhsToStringThrower" correctly.
 PASS: Handled "throwingProperty >= rhsToStringThrower" correctly.
 PASS: Handled "({get throwingProperty(){ throw "throwing property" }}).throwingProperty >= rhsToStringThrower" correctly.
 PASS: Handled "getterThrower.value >= rhsToStringThrower" correctly.
@@ -78,13 +78,13 @@
 PASS: Handled "'string' > throwingProperty" correctly.
 PASS: Handled "'string' > ({get throwingProperty(){ throw "throwing property" }}).throwingProperty" correctly.
 PASS: Handled "'string' > getterThrower.value" correctly.
-FAIL: "valueOfThrower > rhsNonZeroNum" threw exception, but executed right hand half of _expression_
-FAIL: "toStringThrower > rhsNonZeroNum" threw exception, but executed right hand half of _expression_
+PASS: Handled "valueOfThrower > rhsNonZeroNum" correctly.
+PASS: Handled "toStringThrower > rhsNonZeroNum" correctly.
 PASS: Handled "throwingProperty > rhsNonZeroNum" correctly.
 PASS: Handled "({get throwingProperty(){ throw "throwing property" }}).throwingProperty > rhsNonZeroNum" correctly.
 PASS: Handled "getterThrower.value > rhsNonZeroNum" correctly.
-FAIL: "valueOfThrower > rhsToStringThrower" threw exception, but executed right hand half of _expression_
-FAIL: "toStringThrower > rhsToStringThrower" threw exception, but executed right hand half of _expression_
+PASS: Handled "valueOfThrower > rhsToStringThrower" correctly.
+PASS: Handled "toStringThrower > rhsToStringThrower" correctly.
 PASS: Handled "throwingProperty > rhsToStringThrower" correctly.
 PASS: Handled "({get throwingProperty(){ throw "throwing property" }}).throwingProperty > rhsToStringThrower" correctly.
 PASS: Handled "getterThrower.value > rhsToStringThrower" correctly.
@@ -170,5 +170,5 @@
 PASS: Handled "getterThrower.value >> rhsToStringThrower" correctly.
 PASS: Handled "valueOfThrower >> rhsGetterTester.value" correctly.
 PASS: Handled "toStringThrower >> rhsGetterTester.value" correctly.
-Passed 160 of 168 tests.
+Passed 168 of 168 tests.
 

Modified: trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.2_The_Greater_than_Operator/S11.8.2_A2.3_T1-expected.txt (90400 => 90401)


--- trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.2_The_Greater_than_Operator/S11.8.2_A2.3_T1-expected.txt	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.2_The_Greater_than_Operator/S11.8.2_A2.3_T1-expected.txt	2011-07-05 19:01:41 UTC (rev 90401)
@@ -1,6 +1,6 @@
 S11.8.2_A2.3_T1
 
-PASS 
+FAIL SputnikError: #1.2: ToNumber(second _expression_) is called first, and then ToNumber(first _expression_)
 
 TEST COMPLETE
 

Modified: trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.4_The_Grater_than_or_equal_Operator/S11.8.4_A2.3_T1-expected.txt (90400 => 90401)


--- trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.4_The_Grater_than_or_equal_Operator/S11.8.4_A2.3_T1-expected.txt	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/LayoutTests/sputnik/Conformance/11_Expressions/11.8_Relational_Operators/11.8.4_The_Grater_than_or_equal_Operator/S11.8.4_A2.3_T1-expected.txt	2011-07-05 19:01:41 UTC (rev 90401)
@@ -1,6 +1,6 @@
 S11.8.4_A2.3_T1
 
-FAIL SputnikError: #1.2: ToNumber(first _expression_) is called first, and then ToNumber(second _expression_)
+PASS 
 
 TEST COMPLETE
 

Modified: trunk/Source/_javascript_Core/ChangeLog (90400 => 90401)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-05 19:01:41 UTC (rev 90401)
@@ -1,7 +1,27 @@
 2011-07-04  Gavin Barraclough  <[email protected]>
 
+        https://bugs.webkit.org/show_bug.cgi?id=63880
+        Evaluation order of conversions of operands to >, >= incorrect.
+
         Reviewed by Sam Weinig.
 
+        Add 'leftFirst' parameter to jsLess, jsLessEq matching that described in the ES5
+        spec. This allows these methods to be reused to perform >, >= relational compares
+        with correct ordering of type conversions.
+
+        * dfg/DFGOperations.cpp:
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/Operations.h:
+        (JSC::jsLess):
+        (JSC::jsLessEq):
+
+2011-07-04  Gavin Barraclough  <[email protected]>
+
+        Reviewed by Sam Weinig.
+
         https://bugs.webkit.org/show_bug.cgi?id=16652
         Firefox and _javascript_Core differ in Number.toString(integer)
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (90400 => 90401)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-07-05 19:01:41 UTC (rev 90401)
@@ -369,22 +369,22 @@
 
 bool operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
 {
-    return jsLess(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
+    return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
 }
 
 bool operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
 {
-    return jsLessEq(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
+    return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
 }
 
 bool operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
 {
-    return jsLess(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); // FIXME: Bug#63880
+    return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
 }
 
 bool operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
 {
-    return jsLessEq(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1)); // FIXME: Bug#63880
+    return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
 }
 
 bool operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (90400 => 90401)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2011-07-05 19:01:41 UTC (rev 90401)
@@ -1772,7 +1772,7 @@
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        JSValue result = jsBoolean(jsLess(callFrame, src1, src2));
+        JSValue result = jsBoolean(jsLess<true>(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
         callFrame->uncheckedR(dst) = result;
 
@@ -1789,7 +1789,7 @@
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2));
+        JSValue result = jsBoolean(jsLessEq<true>(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
         callFrame->uncheckedR(dst) = result;
 
@@ -1806,7 +1806,7 @@
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        JSValue result = jsBoolean(jsLess(callFrame, src2, src1)); // FIXME: Bug#63880
+        JSValue result = jsBoolean(jsLess<false>(callFrame, src2, src1));
         CHECK_FOR_EXCEPTION();
         callFrame->uncheckedR(dst) = result;
 
@@ -1823,7 +1823,7 @@
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        JSValue result = jsBoolean(jsLessEq(callFrame, src2, src1)); // FIXME: Bug#63880
+        JSValue result = jsBoolean(jsLessEq<false>(callFrame, src2, src1));
         CHECK_FOR_EXCEPTION();
         callFrame->uncheckedR(dst) = result;
 
@@ -3688,7 +3688,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLess(callFrame, src1, src2);
+        bool result = jsLess<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3715,7 +3715,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLessEq(callFrame, src1, src2);
+        bool result = jsLessEq<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3742,7 +3742,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLess<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3769,7 +3769,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLessEq<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3793,7 +3793,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLess(callFrame, src1, src2);
+        bool result = jsLess<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3816,7 +3816,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLessEq(callFrame, src1, src2);
+        bool result = jsLessEq<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3839,7 +3839,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLess<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3862,7 +3862,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
         
-        bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLessEq<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (result) {
@@ -3885,7 +3885,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLess(callFrame, src1, src2);
+        bool result = jsLess<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (!result) {
@@ -3908,7 +3908,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLessEq(callFrame, src1, src2);
+        bool result = jsLessEq<true>(callFrame, src1, src2);
         CHECK_FOR_EXCEPTION();
         
         if (!result) {
@@ -3931,7 +3931,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLess<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (!result) {
@@ -3954,7 +3954,7 @@
         JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
         int target = vPC[3].u.operand;
 
-        bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880
+        bool result = jsLessEq<false>(callFrame, src2, src1);
         CHECK_FOR_EXCEPTION();
         
         if (!result) {

Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (90400 => 90401)


--- trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-07-05 19:01:41 UTC (rev 90401)
@@ -2541,7 +2541,7 @@
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
-    JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
+    JSValue result = jsBoolean(jsLess<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
@@ -2551,7 +2551,7 @@
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
-    JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
+    JSValue result = jsBoolean(jsLessEq<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
@@ -2561,7 +2561,7 @@
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
-    JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue())); // FIXME: Bug#63880
+    JSValue result = jsBoolean(jsLess<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
@@ -2571,7 +2571,7 @@
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
-    JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue())); // FIXME: Bug#63880
+    JSValue result = jsBoolean(jsLessEq<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
@@ -2819,7 +2819,7 @@
     JSValue src2 = stackFrame.args[1].jsValue();
     CallFrame* callFrame = stackFrame.callFrame;
 
-    bool result = jsLess(callFrame, src1, src2);
+    bool result = jsLess<true>(callFrame, src1, src2);
     CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }
@@ -2832,7 +2832,7 @@
     JSValue src2 = stackFrame.args[1].jsValue();
     CallFrame* callFrame = stackFrame.callFrame;
 
-    bool result = jsLessEq(callFrame, src1, src2);
+    bool result = jsLessEq<true>(callFrame, src1, src2);
     CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }
@@ -2845,7 +2845,7 @@
     JSValue src2 = stackFrame.args[1].jsValue();
     CallFrame* callFrame = stackFrame.callFrame;
 
-    bool result = jsLess(callFrame, src2, src1); // FIXME: Bug#63880
+    bool result = jsLess<false>(callFrame, src2, src1);
     CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }
@@ -2858,7 +2858,7 @@
     JSValue src2 = stackFrame.args[1].jsValue();
     CallFrame* callFrame = stackFrame.callFrame;
 
-    bool result = jsLessEq(callFrame, src2, src1); // FIXME: Bug#63880
+    bool result = jsLessEq<false>(callFrame, src2, src1);
     CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }

Modified: trunk/Source/_javascript_Core/runtime/Operations.h (90400 => 90401)


--- trunk/Source/_javascript_Core/runtime/Operations.h	2011-07-05 17:34:43 UTC (rev 90400)
+++ trunk/Source/_javascript_Core/runtime/Operations.h	2011-07-05 19:01:41 UTC (rev 90401)
@@ -334,6 +334,10 @@
         return strictEqualSlowCaseInline(exec, v1, v2);
     }
 
+    // See ES5 11.8.1/11.8.2/11.8.5 for definition of leftFirst, this value ensures correct
+    // evaluation ordering for argument conversions for '<' and '>'. For '<' pass the value
+    // true, for leftFirst, for '>' pass the value false (and reverse operand order).
+    template<bool leftFirst>
     ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
     {
         if (v1.isInt32() && v2.isInt32())
@@ -350,16 +354,26 @@
 
         JSValue p1;
         JSValue p2;
-        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
-        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+        bool wasNotString1;
+        bool wasNotString2;
+        if (leftFirst) {
+            wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+            wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+        } else {
+            wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+            wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+        }
 
         if (wasNotString1 | wasNotString2)
             return n1 < n2;
-
         return asString(p1)->value(callFrame) < asString(p2)->value(callFrame);
     }
 
-    inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
+    // See ES5 11.8.3/11.8.4/11.8.5 for definition of leftFirst, this value ensures correct
+    // evaluation ordering for argument conversions for '<=' and '=>'. For '<=' pass the
+    // value true, for leftFirst, for '=>' pass the value false (and reverse operand order).
+    template<bool leftFirst>
+    ALWAYS_INLINE bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
     {
         if (v1.isInt32() && v2.isInt32())
             return v1.asInt32() <= v2.asInt32();
@@ -375,12 +389,18 @@
 
         JSValue p1;
         JSValue p2;
-        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
-        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+        bool wasNotString1;
+        bool wasNotString2;
+        if (leftFirst) {
+            wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+            wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+        } else {
+            wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+            wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+        }
 
         if (wasNotString1 | wasNotString2)
             return n1 <= n2;
-
         return !(asString(p2)->value(callFrame) < asString(p1)->value(callFrame));
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to