Просмотр исходного кода

Call toPrimitive on symbol objects.

Kevin Smith 7 лет назад
Родитель
Сommit
3f07affcfd

+ 6 - 1
lib/Runtime/Language/JavascriptConversion.cpp

@@ -378,8 +378,13 @@ CommonNumber:
         case TypeIds_SymbolObject:
             {
                 JavascriptSymbolObject* symbolObject = UnsafeVarTo<JavascriptSymbolObject>(aValue);
+                ScriptContext* objectScriptContext = symbolObject->GetScriptContext();
+                if (objectScriptContext->optimizationOverrides.GetSideEffects() & SideEffects_ToPrimitive)
+                {
+                    return MethodCallToPrimitive<hint>(symbolObject, requestContext);
+                }
 
-                return CrossSite::MarshalVar(requestContext, symbolObject->Unwrap(), symbolObject->GetScriptContext());
+                return CrossSite::MarshalVar(requestContext, symbolObject->Unwrap(), objectScriptContext);
             }
 
         case TypeIds_Date:

+ 0 - 1
lib/Runtime/Types/TypeHandler.cpp

@@ -562,7 +562,6 @@ using namespace Js;
                 scriptContext->optimizationOverrides.SetSideEffects((SideEffects)(SideEffects_ValueOf & possibleSideEffects));
                 scriptContext->optimizationOverrides.SetSideEffects((SideEffects)(SideEffects_ToString & possibleSideEffects));
             }
-
             else if (propertyId == PropertyIds::valueOf)
             {
                 scriptContext->optimizationOverrides.SetSideEffects((SideEffects)(SideEffects_ValueOf & possibleSideEffects));

+ 13 - 0
test/es6/toPrimitive.js

@@ -55,6 +55,19 @@ var tests = [
             assert.areEqual(s, Object(s)[Symbol.toPrimitive](), ""); // true
             assert.areEqual(s, Symbol.prototype[Symbol.toPrimitive].call(s), ""); // true
 
+            var symbolObject = Object(s);
+            Object.defineProperty(symbolObject, Symbol.toPrimitive, {
+                value: function() { return 42; },
+                configurable: true,
+            });
+            assert.areEqual(+symbolObject, 42, "User-defined @@toPrimitive is called on symbol objects");
+            Object.defineProperty(symbolObject, Symbol.toPrimitive, { value: undefined });
+            Object.defineProperty(symbolObject, 'valueOf', {
+                value: function() { return 43; },
+                configurable: true,
+            });
+            assert.areEqual(+symbolObject, 43, "OrdinaryToPrimitive is called if @@toPrimitive is undefined");
+
             assert.areEqual(Symbol.toPrimitive, Symbol.toPrimitive[Symbol.toPrimitive](), "Symbol.toPrimitive");
             assert.areEqual(Symbol.iterator, Symbol.iterator[Symbol.toPrimitive](), "Symbol.iterator");
             assert.areEqual(Symbol.hasInstance, Symbol.hasInstance[Symbol.toPrimitive](), "Symbol.hasInstance");