Object.prototype.toString is not spec-perfect
https://bugs.webkit.org/show_bug.cgi?id=199138
Reviewed by Darin Adler and Keith Miller.
JSTests:
- ChakraCore.yaml: Skip a test as
global
now has @@toStringTag.
- ChakraCore/test/LetConst/delete.baseline: Removed.
- stress/internal-promise-constructor-not-confusing.js: Use @isPromise.
- stress/object-get-own-property-symbols.js: Adjust test as
global
now has @@toStringTag.
- test262/expectations.yaml: Mark 6 test cases as passing.
LayoutTests/imported/w3c:
- web-platform-tests/WebIDL/ecmascript-binding/class-string-interface.any-expected.txt:
- web-platform-tests/WebIDL/ecmascript-binding/class-string-interface.any.worker-expected.txt:
- web-platform-tests/WebIDL/ecmascript-binding/class-string-iterator-prototype-object.any-expected.txt:
- web-platform-tests/WebIDL/ecmascript-binding/class-string-iterator-prototype-object.any.worker-expected.txt:
Source/JavaScriptCore:
Before ES6, Object.prototype.toString relied only on internal Class slot. Starting with ES6,
Object.prototype.toString checks for a handful of internal slots, mimicing Class, to ensure
backwards compatibility for pre-ES6 instances. Newly-added built-ins provide @@toStringTag for
the method to use.
Before this change, Object.prototype.toString in JSC relied on className() a.k.a Class for
all instances. For (almost all) new built-ins, it was overriden by toStringName() returning
"Object", while @@toStringTag was set to correct value. This is quite an error-prone approach
and observable spec discrepancy if @@toStringTag is deleted or set to a non-string.
This change eliminates the above-mentioned discrepancy and fixes Object.prototype.toString
to return "[object Function]" for callable Proxy objects, aligning JSC with the spec [1], V8,
and SpiderMonkey.
For Object.prototype.toString to work through DebuggerScope and JSProxy, we perform all checks
in JSObject::toStringName(). Given that isArray() may throw a TypeError [2], we invoke
toStringName() before @@toStringTag lookup to accomodate revoked Proxy case.
Also, this patch defines @@toStringTag for WebAssembly namespace object (to match Chrome),
JSC shell, and ConsoleObject.
[1]: https://tc39.es/ecma262/#sec-object.prototype.tostring
[2]: https://tc39.es/ecma262/#sec-isarray (step 3.a)
- jsc.cpp:
- runtime/BigIntObject.cpp:
(JSC::BigIntObject::toStringName): Deleted.
- runtime/BigIntObject.h:
- runtime/BooleanObject.cpp:
(JSC::BooleanObject::toStringName):
- runtime/BooleanObject.h:
- runtime/ConsoleObject.cpp:
(JSC::ConsoleObject::finishCreation):
- runtime/DateInstance.cpp:
(JSC::DateInstance::toStringName):
- runtime/DateInstance.h:
- runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::toStringName):
- runtime/ErrorInstance.h:
- runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::toStringName): Deleted.
- runtime/JSArrayBufferView.h:
- runtime/JSMap.cpp:
(JSC::JSMap::toStringName): Deleted.
- runtime/JSMap.h:
- runtime/JSObject.cpp:
(JSC::JSObject::toStringName):
(JSC::JSSet::toStringName): Deleted.
- runtime/JSSet.h:
- runtime/JSWeakMap.cpp:
(JSC::JSWeakMap::toStringName): Deleted.
- runtime/JSWeakMap.h:
- runtime/JSWeakObjectRef.cpp:
(JSC::JSWeakObjectRef::toStringName): Deleted.
- runtime/JSWeakObjectRef.h:
- runtime/JSWeakSet.cpp:
(JSC::JSWeakSet::toStringName): Deleted.
- runtime/JSWeakSet.h:
- runtime/NumberObject.cpp:
(JSC::NumberObject::toStringName):
- runtime/NumberObject.h:
- runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString):
(JSC::ProxyObject::toStringName): Deleted.
- runtime/ProxyObject.h:
- runtime/RegExpObject.cpp:
(JSC::RegExpObject::toStringName):
- runtime/RegExpObject.h:
- runtime/StringObject.cpp:
(JSC::StringObject::toStringName):
- runtime/StringObject.h:
- runtime/SymbolObject.cpp:
(JSC::SymbolObject::toStringName): Deleted.
- runtime/SymbolObject.h:
- wasm/js/JSWebAssembly.cpp:
(JSC::JSWebAssembly::finishCreation):
Source/WebCore:
This patch defines @@toStringTag symbols for all WebIDL prototypes, including
interfaces that are not exposed, as required by the spec [1].
With updated JSObject::toStringName() and @@toStringTag symbols added in r260992,
className() and toStringName() methods of JSDOMConstructorBase can be safely removed.
[1]: https://heycam.github.io/webidl/#dfn-class-string
Tests: imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/class-string-interface.any.js
imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/class-string-iterator-prototype-object.any.js
- bindings/js/JSDOMConstructorBase.cpp:
(WebCore::JSDOMConstructorBase::className): Deleted.
(WebCore::JSDOMConstructorBase::toStringName): Deleted.
- bindings/js/JSDOMConstructorBase.h:
- bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
(GeneratePrototypeDeclaration):
- bindings/scripts/test/JS/JSTestGlobalObject.cpp:
(WebCore::JSTestGlobalObjectPrototype::finishCreation):
Tools:
- TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp: