Переглянути джерело

[1.10>master] [MERGE #5613 @sigatrev] MSFT:18327064 OpHelpers returning ints as floats leading to infinite bailouts

Merge pull request #5613 from sigatrev:stringOpt

The following operations on a number as a string all returned doubles even when the value was integral, causing bailouts on some array operations.

```
var i = "1";
+i          // Op_ConvNumber_Full
++i;        // Op_Increment_Full
-i;         // Op_Negate_Full
--i;        // Op_Decrement_Full
1 - i;      // Op_Subract_Full
1 * i;      // Op_Multiply_Ful
1 ** i      // Op_Exponentiation_Full
1 % i       // Op_Modulus_Full

var ary = [0,1];

// will bail out infinitely
ary[+i];
```
This is already checked in on the OS side
Matt Gardner 7 роки тому
батько
коміт
94947694a4

+ 1 - 1
lib/Runtime/Language/JavascriptOperators.cpp

@@ -10602,7 +10602,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
             return aRight;
         }
 
-        return JavascriptNumber::ToVarNoCheck(JavascriptConversion::ToNumber_Full(aRight, scriptContext), scriptContext);
+        return JavascriptNumber::ToVarIntCheck(JavascriptConversion::ToNumber_Full(aRight, scriptContext), scriptContext);
         JIT_HELPER_END(Op_ConvNumber_Full);
     }
 

+ 6 - 2
lib/Runtime/Library/JavascriptNumber.cpp

@@ -36,9 +36,13 @@ namespace Js
 
     Var JavascriptNumber::ToVarInPlace(int64 value, ScriptContext* scriptContext, JavascriptNumber *result)
     {
-        return InPlaceNew((double)value, scriptContext, result);
-    }
+        if (!TaggedInt::IsOverflow(value))
+        {
+            return TaggedInt::ToVarUnchecked(static_cast<int>(value));
+        }
 
+        return InPlaceNew(static_cast<double>(value), scriptContext, result);
+    }
 
     Var JavascriptNumber::ToVarMaybeInPlace(double value, ScriptContext* scriptContext, JavascriptNumber *result)
     {

+ 7 - 7
lib/Runtime/Math/JavascriptMath.cpp

@@ -14,7 +14,7 @@ using namespace Js;
             }
 
             double value = Negate_Helper(aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(value, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(value, scriptContext);
             JIT_HELPER_END(Op_Negate_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Negate_Full, Op_Negate)
@@ -77,7 +77,7 @@ using namespace Js;
             }
 
             double inc = Increment_Helper(aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(inc, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(inc, scriptContext);
             JIT_HELPER_END(Op_Increment_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Increment_Full, Op_Increment)
@@ -104,7 +104,7 @@ using namespace Js;
             }
 
             double dec = Decrement_Helper(aRight,scriptContext);
-            return JavascriptNumber::ToVarNoCheck(dec, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(dec, scriptContext);
             JIT_HELPER_END(Op_Decrement_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Decrement_Full, Op_Decrement)
@@ -792,7 +792,7 @@ StringCommon:
         {
             JIT_HELPER_REENTRANT_HEADER(Op_Subtract_Full);
             double difference = Subtract_Helper(aLeft, aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(difference, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(difference, scriptContext);
             JIT_HELPER_END(Op_Subtract_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Subtract_Full, Op_Subtract)
@@ -825,7 +825,7 @@ StringCommon:
             JIT_HELPER_REENTRANT_HEADER(Op_Exponentiation_Full);
             double x = JavascriptConversion::ToNumber(aLeft, scriptContext);
             double y = JavascriptConversion::ToNumber(aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(Math::Pow(x, y), scriptContext);
+            return JavascriptNumber::ToVarIntCheck(Math::Pow(x, y), scriptContext);
             JIT_HELPER_END(Op_Exponentiation_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Exponentiation_Full, Op_Exponentiation)
@@ -874,7 +874,7 @@ StringCommon:
                 return TaggedInt::Multiply(aLeft, aRight, scriptContext);
             }
             double product = Multiply_Helper(aLeft, aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(product, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(product, scriptContext);
             JIT_HELPER_END(Op_Multiply_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Multiply_Full, Op_Multiply)
@@ -939,7 +939,7 @@ StringCommon:
             }
 
             double remainder = Modulus_Helper(aLeft, aRight, scriptContext);
-            return JavascriptNumber::ToVarNoCheck(remainder, scriptContext);
+            return JavascriptNumber::ToVarIntCheck(remainder, scriptContext);
             JIT_HELPER_END(Op_Modulus_Full);
         }
         JIT_HELPER_TEMPLATE(Op_Modulus_Full, Op_Modulus)