[MERGE #6078 @MikeHolman] remove byteLength from asm.js imports

Merge pull request #6078 from MikeHolman:boundthisbug

byteLength was only used for changeHeap, which was removed from asm.js spec.

There was bug in how it handled bound this, but since we shouldn't be having it in our list of imports at all, so fixed by removing all the handling for it.

Fixes #6052
diff --git a/lib/Runtime/Language/AsmJsUtils.cpp b/lib/Runtime/Language/AsmJsUtils.cpp
index 310a6ab..ec11589 100644
--- a/lib/Runtime/Language/AsmJsUtils.cpp
+++ b/lib/Runtime/Language/AsmJsUtils.cpp
@@ -37,7 +37,10 @@
             ParseNode* rhs = GetBinaryRight( body );
             if( rhs && rhs->nop == knopList )
             {
-                AssertMsg( lhs->nop == knopStr, "this should be use asm" );
+                if (lhs->nop != knopStr)
+                {
+                    return false;
+                }
                 *var = rhs;
                 return true;
             }
diff --git a/lib/Runtime/Language/JavascriptConversion.inl b/lib/Runtime/Language/JavascriptConversion.inl
index 0c2e002..8925806 100644
--- a/lib/Runtime/Language/JavascriptConversion.inl
+++ b/lib/Runtime/Language/JavascriptConversion.inl
@@ -303,9 +303,10 @@
            if (typeId == TypeIds_Number)
            {
                double numberValue = JavascriptNumber::GetValue(value);
+               // NaN and -NaN do not canonicalize to the same value, but they are equal, so only allow +NaN
                return JavascriptNumber::IsNan(numberValue)
                    ? JavascriptNumber::IsNegative(numberValue)
-                        ? JavascriptNumber::ToVar(JavascriptNumber::NegativeNaN)
+                        ? nullptr
                         : JavascriptNumber::ToVar(JavascriptNumber::NaN)
                    : value;
            }
diff --git a/lib/Runtime/Language/JavascriptOperators.cpp b/lib/Runtime/Language/JavascriptOperators.cpp
index 56642a3..407ecc4 100644
--- a/lib/Runtime/Language/JavascriptOperators.cpp
+++ b/lib/Runtime/Language/JavascriptOperators.cpp
@@ -6624,7 +6624,25 @@
 
             if (constructorBody->GetHasOnlyThisStmts())
             {
-                if (typeHandler->IsSharable())
+                if (!typeHandler->IsSharable())
+                {
+                    // Dynamic type created is not sharable.
+                    // So in future don't try to check for "this assignment optimization".
+                    constructorBody->SetHasOnlyThisStmts(false);
+#if DBG_DUMP
+                    TraceUpdateConstructorCache(constructorCache, constructorBody, false, _u("because final type is not shareable"));
+#endif
+                }
+                else if (typeHandler->GetPropertyCount() >= Js::PropertyIndexRanges<PropertyIndex>::MaxValue)
+                {
+                    // Dynamic type created has too many properties.
+                    // So in future don't try to check for "this assignment optimization".
+                    constructorBody->SetHasOnlyThisStmts(false);
+#if DBG_DUMP
+                    TraceUpdateConstructorCache(constructorCache, constructorBody, false, _u("because final type has too many properties"));
+#endif
+                }
+                else
                 {
 #if DBG
                     bool cachedProtoCanBeCached = false;
@@ -6643,7 +6661,6 @@
                     if ((profileInfo != nullptr && profileInfo->GetImplicitCallFlags() <= ImplicitCall_None) ||
                         CheckIfPrototypeChainHasOnlyWritableDataProperties(type->GetPrototype()))
                     {
-                        Assert(typeHandler->GetPropertyCount() < Js::PropertyIndexRanges<PropertyIndex>::MaxValue);
 
                         for (PropertyIndex pi = 0; pi < typeHandler->GetPropertyCount(); pi++)
                         {
@@ -6684,15 +6701,6 @@
 #endif
 #endif
                 }
-                else
-                {
-                    // Dynamic type created is not sharable.
-                    // So in future don't try to check for "this assignment optimization".
-                    constructorBody->SetHasOnlyThisStmts(false);
-#if DBG_DUMP
-                    TraceUpdateConstructorCache(constructorCache, constructorBody, false, _u("because final type is not shareable"));
-#endif
-                }
             }
             else
             {
diff --git a/lib/Runtime/Library/ArgumentsObjectEnumerator.h b/lib/Runtime/Library/ArgumentsObjectEnumerator.h
index 3983522..423962d 100644
--- a/lib/Runtime/Library/ArgumentsObjectEnumerator.h
+++ b/lib/Runtime/Library/ArgumentsObjectEnumerator.h
@@ -21,6 +21,7 @@
         ArgumentsObjectPrefixEnumerator(ArgumentsObject* argumentsObject, EnumeratorFlags flags, ScriptContext* requestContext);
         virtual void Reset() override;
         virtual JavascriptString * MoveAndGetNext(PropertyId& propertyId, PropertyAttributes* attributes = nullptr) override;
+        virtual uint32 GetCurrentItemIndex()  override { return formalArgIndex; }
     };
 
     class ES5ArgumentsObjectEnumerator : public ArgumentsObjectPrefixEnumerator
diff --git a/lib/Runtime/Library/JavascriptArray.cpp b/lib/Runtime/Library/JavascriptArray.cpp
index 7ac7247..fd020f0 100644
--- a/lib/Runtime/Library/JavascriptArray.cpp
+++ b/lib/Runtime/Library/JavascriptArray.cpp
@@ -5365,6 +5365,11 @@
     Var JavascriptArray::EntryPushJavascriptArray(ScriptContext * scriptContext, Var * args, uint argCount)
     {
         JavascriptArray * arr = JavascriptArray::FromAnyArray(args[0]);
+
+#if ENABLE_COPYONACCESS_ARRAY
+        JavascriptLibrary::CheckAndConvertCopyOnAccessNativeIntArray<Var>(arr);
+#endif
+
         uint n = arr->length;
         ThrowTypeErrorOnFailureHelper h(scriptContext, _u("Array.prototype.push"));
 
diff --git a/test/Array/CopyOnAccessArray_bugs.js b/test/Array/CopyOnAccessArray_bugs.js
index 2c0b4ce..4a2e594 100644
--- a/test/Array/CopyOnAccessArray_bugs.js
+++ b/test/Array/CopyOnAccessArray_bugs.js
@@ -26,6 +26,8 @@
             var a=[1,2];

             Array.prototype.push.call(a,1);

             assert.areEqual([1,2,1], a, "Incorrect result from Array.prototype.push()");

+            

+            Array.prototype.push.call([0, 0, 0, 0, 0]);

         }

     },

     {

diff --git a/test/AsmJs/rlexe.xml b/test/AsmJs/rlexe.xml
index d4d539e..4d5a75e 100644
--- a/test/AsmJs/rlexe.xml
+++ b/test/AsmJs/rlexe.xml
@@ -1004,6 +1004,13 @@
   </test>
   <test>
     <default>
+      <files>useasmbug.js</files>
+      <baseline>useasmbug.baseline</baseline>
+      <compile-flags>-testtrace:asmjs</compile-flags>
+    </default>
+  </test>
+  <test>
+    <default>
       <files>lambda.js</files>
       <baseline>lambda.baseline</baseline>
       <compile-flags>-testtrace:asmjs</compile-flags>
diff --git a/test/AsmJs/useasmbug.baseline b/test/AsmJs/useasmbug.baseline
new file mode 100644
index 0000000..fe7e84e
--- /dev/null
+++ b/test/AsmJs/useasmbug.baseline
@@ -0,0 +1 @@
+Asm.js compilation failed.

diff --git a/test/AsmJs/useasmbug.js b/test/AsmJs/useasmbug.js
new file mode 100644
index 0000000..5ee4201
--- /dev/null
+++ b/test/AsmJs/useasmbug.js
@@ -0,0 +1,10 @@
+//-------------------------------------------------------------------------------------------------------

+// Copyright (C) Microsoft. All rights reserved.

+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

+//-------------------------------------------------------------------------------------------------------

+

+function $() {

+    "use asm"

+    ( );

+    return

+}

diff --git a/test/JSON/arguments.js b/test/JSON/arguments.js
new file mode 100644
index 0000000..9ad5aed
--- /dev/null
+++ b/test/JSON/arguments.js
@@ -0,0 +1,16 @@
+//-------------------------------------------------------------------------------------------------------

+// Copyright (C) Microsoft. All rights reserved.

+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

+//-------------------------------------------------------------------------------------------------------

+

+let set = false;

+let a = JSON.parse('["first", null]', function (key, value) {                                    

+  if(!set) {

+    this[1] = arguments;

+    set = true;

+  }

+  return value;

+});

+let passed = JSON.stringify(a) === `["first",{"0":"0","1":"first"}]`;

+

+print(passed ? "Pass" : "Fail")
\ No newline at end of file
diff --git a/test/JSON/rlexe.xml b/test/JSON/rlexe.xml
index 9dc15b0..e361ed0 100644
--- a/test/JSON/rlexe.xml
+++ b/test/JSON/rlexe.xml
@@ -29,6 +29,11 @@
   </test>
   <test>
     <default>
+      <files>arguments.js</files>
+    </default>
+  </test>
+  <test>
+    <default>
       <files>replacerFunction.js</files>
       <timeout>300</timeout>
     </default>
diff --git a/test/Object/bigconstructorbug.js b/test/Object/bigconstructorbug.js
new file mode 100644
index 0000000..f56ce58
--- /dev/null
+++ b/test/Object/bigconstructorbug.js
@@ -0,0 +1,17 @@
+//-------------------------------------------------------------------------------------------------------

+// Copyright (C) Microsoft. All rights reserved.

+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

+//-------------------------------------------------------------------------------------------------------

+

+var var_0 = '';

+for (var var_1 = 0; var_1 < 100000; var_1++) {

+    var_0 += `this.a${ var_1 } = 0;\n`;

+}

+var var_2 = new Function(var_0);

+function func_0() {}

+func_0.prototype = new var_2();

+

+function func_1() {}

+func_1.prototype = new var_2();

+

+print("Pass")
\ No newline at end of file
diff --git a/test/Object/rlexe.xml b/test/Object/rlexe.xml
index f574cff..dc62151 100644
--- a/test/Object/rlexe.xml
+++ b/test/Object/rlexe.xml
@@ -44,6 +44,12 @@
   </test>
   <test>
     <default>
+      <files>bigconstructorbug.js</files>
+      <tags>Slow</tags>
+    </default>
+  </test>
+  <test>
+    <default>
       <files>Object.js</files>
       <baseline>Object.baseline</baseline>
     </default>
diff --git a/test/es6/set_functionality.js b/test/es6/set_functionality.js
index 9df8c67..d2eae23 100644
--- a/test/es6/set_functionality.js
+++ b/test/es6/set_functionality.js
@@ -742,6 +742,15 @@
             assert.isTrue(set.has(value), "1.0 should be equal to the value 1 and set has it");

         }

     },

+    {

+        name: "-NaN and +NaN in set should not assert (github #6063)",

+        body: function() {

+            let set = new Set([+NaN, -NaN, "asdf"]);

+            assert.isTrue(set.has(-NaN));

+            assert.isTrue(set.has(NaN));

+            assert.isTrue(set.has("asdf"));

+        }

+    },

 ];

 

 testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });