Procházet zdrojové kódy

@@toPrimitive should be ignored if its value is null

Nicolò Ribaudo před 10 roky
rodič
revize
70faee3978

+ 11 - 13
lib/Runtime/Language/JavascriptConversion.cpp

@@ -472,29 +472,27 @@ CommonNumber:
         RecyclableObject *const recyclableObject = RecyclableObject::FromVar(aValue);
         ScriptContext *const scriptContext = recyclableObject->GetScriptContext();
 
-        /*7.3.7 GetMethod (O, P)
-        The abstract operation GetMethod is used to get the value of a specific property of an object when the value of the property is expected to be a function.
-        The operation is called with arguments O and P where O is the object, P is the property key. This abstract operation performs the following steps:
-
-        Assert: Type(O) is Object.
-        Assert: IsPropertyKey(P) is true.
-        Let func be the result of calling the [[Get]] internal method of O passing P and O as the arguments.
-        ReturnIfAbrupt(func).
-        If func is undefined, then return undefined.
-        If IsCallable(func) is false, then throw a TypeError exception.
-        Return func.*/
+        //7.3.9 GetMethod(V, P)
+        //  The abstract operation GetMethod is used to get the value of a specific property of an ECMAScript language value when the value of the
+        //  property is expected to be a function. The operation is called with arguments V and P where V is the ECMAScript language value, P is the
+        //  property key. This abstract operation performs the following steps:
+        //  1. Assert: IsPropertyKey(P) is true.
+        //  2. Let func be ? GetV(V, P).
+        //  3. If func is either undefined or null, return undefined.
+        //  4. If IsCallable(func) is false, throw a TypeError exception.
+        //  5. Return func.
         Var varMethod;
 
         if (!(requestContext->GetConfig()->IsES6ToPrimitiveEnabled()
             && JavascriptOperators::GetPropertyReference(recyclableObject, PropertyIds::_symbolToPrimitive, &varMethod, requestContext)
-            && !JavascriptOperators::IsUndefinedObject(varMethod)))
+            && !JavascriptOperators::IsUndefinedOrNull(varMethod)))
         {
             return OrdinaryToPrimitive(aValue, hint, requestContext);
         }
         if (!JavascriptFunction::Is(varMethod))
         {
             // Don't error if we disabled implicit calls
-            JavascriptError::TryThrowTypeError(scriptContext, requestContext, JSERR_NeedFunction, requestContext->GetPropertyName(PropertyIds::_symbolToPrimitive)->GetBuffer());
+            JavascriptError::TryThrowTypeError(scriptContext, requestContext, JSERR_Property_NeedFunction, requestContext->GetPropertyName(PropertyIds::_symbolToPrimitive)->GetBuffer());
             return requestContext->GetLibrary()->GetNull();
         }
 

+ 1 - 1
test/SIMD.wrappers/testBool16x8.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Bool16x8.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Bool16x8.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Bool16x8.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testBool32x4.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Bool32x4.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Bool32x4.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Bool32x4.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testBool8x16.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Bool8x16.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Bool8x16.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Bool8x16.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testFloat32x4.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Float32x4.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Float32x4.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Float32x4.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testInt16x8.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Int16x8.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Int16x8.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Int16x8.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testInt32x4.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Int32x4.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Int32x4.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Int32x4.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testInt8x16.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Int8x16.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Int8x16.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Int8x16.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testUint16x8.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Uint16x8.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Uint16x8.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Uint16x8.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testUint32x4.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Uint32x4.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Uint32x4.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Uint32x4.prototype.toLocaleString = functionBackup

+ 1 - 1
test/SIMD.wrappers/testUint8x16.js

@@ -118,7 +118,7 @@ function testToPrimitive()
     SIMD.Uint8x16.prototype[Symbol.toPrimitive] = 5;
     try{var x =  G + G;}
     catch(e)
-    {equal("TypeError: 'Symbol.toPrimitive' is not a function", e);}
+    {equal("TypeError: The value of the property 'Symbol.toPrimitive' is not a Function object", e);}
 
     SIMD.Uint8x16.prototype[Symbol.toPrimitive] = memberBackup;
     SIMD.Uint8x16.prototype.toLocaleString = functionBackup

+ 4 - 2
test/es6/toPrimitive.js

@@ -107,14 +107,16 @@ var tests = [
        }
     },
     {
-       name: "Object toPrimitive must be Function else Throws typeError",
+       name: "Object toPrimitive must be Function or null else Throws typeError",
        body: function ()
        {
             var o = { toString : function () {return "o"}, valueOf : function() { return 0;}};
 
             o[Symbol.toPrimitive]  = {}; // can only be a  function else type error
-            assert.throws(function() {var a = o+1;}, TypeError, "o[Symbol.toPrimitive] must be a function");
+            assert.throws(function() {var a = o+1;}, TypeError, "o[Symbol.toPrimitive] must be a function", "The value of the property 'Symbol.toPrimitive' is not a Function object");
 
+            o[Symbol.toPrimitive] = null;
+            assert.doesNotThrow(function() {var a = o+1;}, "If o[Symbol.toPrimitive] is null it is ignored");
         }
     },
 // In ScriptLanguageVersion6 the ActiveXObject constructor is removed and is unable to be used for this test. Disabling until different object type can be found