WebKit Bugzilla
Attachment 372719 Details for
Bug 199138
: Object.prototype.toString is not spec-perfect
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-199138-20190624023732.patch (text/plain), 36.85 KB, created by
Alexey Shvayka
on 2019-06-23 16:37:33 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Alexey Shvayka
Created:
2019-06-23 16:37:33 PDT
Size:
36.85 KB
patch
obsolete
>Index: JSTests/ChangeLog >=================================================================== >--- JSTests/ChangeLog (revision 246724) >+++ JSTests/ChangeLog (working copy) >@@ -1,3 +1,13 @@ >+2019-06-23 Alexey Shvayka <shvaikalesh@gmail.com> >+ >+ Object.prototype.toString is not spec-perfect >+ https://bugs.webkit.org/show_bug.cgi?id=199138 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * test262/expectations.yaml: Mark 2 test cases as passing. >+ * wasm/js-api/test_basic_api.js: Add @@toStringTag tests. >+ > 2019-06-22 Robin Morisset <rmorisset@apple.com> and Yusuke Suzuki <ysuzuki@apple.com> > > All prototypes should call didBecomePrototype() >Index: JSTests/test262/expectations.yaml >=================================================================== >--- JSTests/test262/expectations.yaml (revision 246723) >+++ JSTests/test262/expectations.yaml (working copy) >@@ -1089,9 +1089,6 @@ test/built-ins/Object/keys/property-trap > test/built-ins/Object/proto-from-ctor.js: > default: 'Test262Error: Expected SameValue(ë[object Object]û, ë[object Object]û) to be true' > strict mode: 'Test262Error: Expected SameValue(ë[object Object]û, ë[object Object]û) to be true' >-test/built-ins/Object/prototype/toString/proxy-function.js: >- default: 'Test262Error: function proxy Expected SameValue(ë[object Object]û, ë[object Function]û) to be true' >- strict mode: 'Test262Error: function proxy Expected SameValue(ë[object Object]û, ë[object Function]û) to be true' > test/built-ins/Object/subclass-object-arg.js: > default: 'Test262Error: Expected SameValue(ëundefinedû, ë1û) to be true' > strict mode: 'Test262Error: Expected SameValue(ëundefinedû, ë1û) to be true' >Index: JSTests/wasm/js-api/test_basic_api.js >=================================================================== >--- JSTests/wasm/js-api/test_basic_api.js (revision 246723) >+++ JSTests/wasm/js-api/test_basic_api.js (working copy) >@@ -40,6 +40,7 @@ const constructorProperties = { > assert.isNotUndef(WebAssembly); > checkOwnPropertyDescriptor(utilities.global, "WebAssembly", { typeofvalue: "object", writable: true, configurable: true, enumerable: false }); > assert.eq(String(WebAssembly), "[object WebAssembly]"); >+assert.eq(WebAssembly[Symbol.toStringTag], "WebAssembly"); > assert.isUndef(WebAssembly.length); > assert.eq(WebAssembly instanceof Object, true); > assert.throws(() => WebAssembly(), TypeError, `WebAssembly is not a function. (In 'WebAssembly()', 'WebAssembly' is an instance of WebAssembly)`); >@@ -59,8 +60,11 @@ for (const c in constructorProperties) { > checkOwnPropertyDescriptor(WebAssembly[c], "prototype", { typeofvalue: "object", writable: false, configurable: false, enumerable: false }); > if (["CompileError", "LinkError", "RuntimeError"].indexOf(c) >= 0) > WebAssembly[c](); // Per spec, the WebAssembly.*Error types match ye olden JavaScript NativeError behavior: they can be constructed without `new`. >- else >+ else { > assert.throws(() => WebAssembly[c](), TypeError, `calling WebAssembly.${c} constructor without new is invalid`); >+ checkOwnPropertyDescriptor(WebAssembly[c].prototype, Symbol.toStringTag, { typeofvalue: "string", writable: false, configurable: true, enumerable: false }); >+ assert.eq(WebAssembly[c].prototype[Symbol.toStringTag], `WebAssembly.${c}`); >+ } > switch (c) { > case "Module": > for (const invalid of invalidConstructorInputs) >Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 246723) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,89 @@ >+2019-06-23 Alexey Shvayka <shvaikalesh@gmail.com> >+ >+ Object.prototype.toString is not spec-perfect >+ https://bugs.webkit.org/show_bug.cgi?id=199138 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Before @@toStringTag was introduced, Object#toString relied solely on internal [[Class]] slot. >+ Starting with ES6, newly introduced built-ins provide @@toStringTag for Object#toString to use. >+ With @@toStringTag removed, Object#toString should not special-case those built-ins and return "[object Object]". >+ Currently, Object#toString examines only a handful of internal slots for backwards compatibility. >+ >+ JSC always uses JSObject::className a.k.a. [[Class]] in Object#toString that is overriden with "Object" for new built-ins. >+ This is quite error-prone and is observable spec discrepancy if @@toStringTag is deleted or set to non-string. >+ >+ This change aligns both algorithm and results of Object#toString with the specification. >+ (https://tc39.es/ecma262/#sec-object.prototype.tostring) >+ >+ 1. Changes JSObject::toStringName to return either "Function" or "Object" instead of `className`. >+ 2. Adds `toStringName` overrides to pre-ES6 classes: Boolean, Arguments, Date, Arguments, Error, Number, RegExp, and String. >+ 3. Adds `isArray` check to `objectProtoFuncToString` for Proxy detection. >+ 4. Adds @@toStringTag to WebAssembly constructors. >+ 5. Adds @@toStringTag to DOM constructors, prototypes, and iterators. >+ 6. Removes now useless "Object" overrides for BigInt, ArrayBuffer, Map, Set, WeakMap, WeakRef, and WeakSet. >+ 7. Removes now useless ProxyObject::toStringName. >+ >+ * jsc.cpp: >+ (GlobalObject::toStringName): >+ * runtime/BigIntObject.cpp: >+ (JSC::BigIntObject::toStringName): Deleted. >+ * runtime/BigIntObject.h: >+ * runtime/BooleanObject.h: >+ (JSC::BooleanObject::toStringName): >+ * runtime/ClonedArguments.h: >+ * runtime/ConsoleObject.h: >+ * runtime/DateInstance.h: >+ * runtime/DirectArguments.h: >+ * runtime/ErrorInstance.h: >+ (JSC::ErrorInstance::toStringName): >+ * runtime/JSArray.cpp: >+ (JSC::JSArray::toStringName): >+ * runtime/JSArray.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): >+ * runtime/JSSet.cpp: >+ (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.h: >+ (JSC::NumberObject::toStringName): >+ * runtime/ObjectPrototype.cpp: >+ (JSC::objectProtoFuncToString): >+ * runtime/ProxyObject.cpp: >+ (JSC::ProxyObject::toStringName): Deleted. >+ * runtime/ProxyObject.h: >+ * runtime/RegExpObject.h: >+ * runtime/StringObject.h: >+ (JSC::StringObject::toStringName): >+ * runtime/SymbolObject.cpp: >+ (JSC::SymbolObject::toStringName): Deleted. >+ * runtime/SymbolObject.h: >+ * wasm/js/JSWebAssembly.cpp: >+ (JSC::JSWebAssembly::finishCreation): >+ * wasm/js/WebAssemblyInstancePrototype.cpp: >+ (JSC::WebAssemblyInstancePrototype::finishCreation): >+ * wasm/js/WebAssemblyMemoryPrototype.cpp: >+ (JSC::WebAssemblyMemoryPrototype::finishCreation): >+ * wasm/js/WebAssemblyModulePrototype.cpp: >+ (JSC::WebAssemblyModulePrototype::finishCreation): >+ * wasm/js/WebAssemblyTablePrototype.cpp: >+ (JSC::WebAssemblyTablePrototype::finishCreation): >+ > 2019-06-22 Robin Morisset <rmorisset@apple.com> and Yusuke Suzuki <ysuzuki@apple.com> > > All prototypes should call didBecomePrototype() >Index: Source/JavaScriptCore/jsc.cpp >=================================================================== >--- Source/JavaScriptCore/jsc.cpp (revision 246723) >+++ Source/JavaScriptCore/jsc.cpp (working copy) >@@ -493,6 +493,7 @@ public: > return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); > } > >+ static String toStringName(const JSObject*, ExecState*) { return "global"_s; } > static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags::createAllEnabled(); } > > protected: >Index: Source/JavaScriptCore/runtime/BigIntObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/BigIntObject.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/BigIntObject.cpp (working copy) >@@ -56,11 +56,6 @@ void BigIntObject::finishCreation(VM& vm > setInternalValue(vm, bigInt); > } > >-String BigIntObject::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > JSValue BigIntObject::defaultValue(const JSObject* object, ExecState*, PreferredPrimitiveType) > { > const BigIntObject* bigIntObject = jsCast<const BigIntObject*>(object); >Index: Source/JavaScriptCore/runtime/BigIntObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/BigIntObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/BigIntObject.h (working copy) >@@ -48,8 +48,6 @@ public: > > static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); > >- static String toStringName(const JSObject*, ExecState*); >- > protected: > JS_EXPORT_PRIVATE void finishCreation(VM&, JSBigInt*); > JS_EXPORT_PRIVATE BigIntObject(VM&, Structure*); >Index: Source/JavaScriptCore/runtime/BooleanObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/BooleanObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/BooleanObject.h (working copy) >@@ -45,6 +45,8 @@ public: > { > return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); > } >+ >+ static String toStringName(const JSObject*, ExecState*) { return "Boolean"_s; } > }; > > } // namespace JSC >Index: Source/JavaScriptCore/runtime/ClonedArguments.h >=================================================================== >--- Source/JavaScriptCore/runtime/ClonedArguments.h (revision 246723) >+++ Source/JavaScriptCore/runtime/ClonedArguments.h (working copy) >@@ -56,6 +56,7 @@ public: > static Structure* createSlowPutStructure(VM&, JSGlobalObject*, JSValue prototype); > > static void visitChildren(JSCell*, SlotVisitor&); >+ static String toStringName(const JSObject*, ExecState*) { return "Arguments"_s; } > > DECLARE_INFO; > >Index: Source/JavaScriptCore/runtime/ConsoleObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/ConsoleObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/ConsoleObject.h (working copy) >@@ -50,6 +50,8 @@ public: > return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); > } > >+ static String toStringName(const JSObject*, ExecState*) { return "Console"_s; } >+ > protected: > void finishCreation(VM&, JSGlobalObject*); > }; >Index: Source/JavaScriptCore/runtime/DateInstance.h >=================================================================== >--- Source/JavaScriptCore/runtime/DateInstance.h (revision 246723) >+++ Source/JavaScriptCore/runtime/DateInstance.h (working copy) >@@ -73,6 +73,8 @@ public: > return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); > } > >+ static String toStringName(const JSObject*, ExecState*) { return "Date"_s; } >+ > private: > JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(ExecState*) const; > JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const; >Index: Source/JavaScriptCore/runtime/DirectArguments.h >=================================================================== >--- Source/JavaScriptCore/runtime/DirectArguments.h (revision 246723) >+++ Source/JavaScriptCore/runtime/DirectArguments.h (working copy) >@@ -170,6 +170,8 @@ public: > { > return offsetOfSlot(capacity); > } >+ >+ static String toStringName(const JSObject*, ExecState*) { return "Arguments"_s; } > > private: > WriteBarrier<Unknown>* storage() >Index: Source/JavaScriptCore/runtime/ErrorInstance.h >=================================================================== >--- Source/JavaScriptCore/runtime/ErrorInstance.h (revision 246723) >+++ Source/JavaScriptCore/runtime/ErrorInstance.h (working copy) >@@ -51,6 +51,7 @@ public: > } > > static ErrorInstance* create(ExecState*, Structure*, JSValue message, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true); >+ static String toStringName(const JSObject*, ExecState*) { return "Error"_s; } > > bool hasSourceAppender() const { return !!m_sourceAppender; } > SourceAppender sourceAppender() const { return m_sourceAppender; } >Index: Source/JavaScriptCore/runtime/JSArray.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSArray.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSArray.cpp (working copy) >@@ -43,6 +43,7 @@ STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE( > > const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArray)}; > >+String JSArray::toStringName(const JSObject*, ExecState*) { return "Array"_s; } > JSArray* JSArray::tryCreateUninitializedRestricted(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength) > { > VM& vm = scope.vm(); >Index: Source/JavaScriptCore/runtime/JSArray.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSArray.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSArray.h (working copy) >@@ -171,6 +171,8 @@ public: > { > return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), indexingType); > } >+ >+ JS_EXPORT_PRIVATE static String toStringName(const JSObject*, ExecState*); > > protected: > void finishCreation(VM& vm) >Index: Source/JavaScriptCore/runtime/JSArrayBufferView.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSArrayBufferView.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSArrayBufferView.cpp (working copy) >@@ -42,11 +42,6 @@ const ClassInfo JSArrayBufferView::s_inf > "ArrayBufferView", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSArrayBufferView) > }; > >-String JSArrayBufferView::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > JSArrayBufferView::ConstructionContext::ConstructionContext( > Structure* structure, uint32_t length, void* vector) > : m_structure(structure) >Index: Source/JavaScriptCore/runtime/JSArrayBufferView.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSArrayBufferView.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSArrayBufferView.h (working copy) >@@ -193,8 +193,6 @@ protected: > > ArrayBuffer* existingBufferInButterfly(); > >- static String toStringName(const JSObject*, ExecState*); >- > VectorPtr m_vector; > uint32_t m_length; > TypedArrayMode m_mode; >Index: Source/JavaScriptCore/runtime/JSMap.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSMap.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSMap.cpp (working copy) >@@ -33,11 +33,6 @@ namespace JSC { > > const ClassInfo JSMap::s_info = { "Map", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMap) }; > >-String JSMap::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > JSMap* JSMap::clone(ExecState* exec, VM& vm, Structure* structure) > { > JSMap* instance = new (NotNull, allocateCell<JSMap>(vm.heap)) JSMap(vm, structure); >Index: Source/JavaScriptCore/runtime/JSMap.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSMap.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSMap.h (working copy) >@@ -62,8 +62,6 @@ private: > : Base(vm, structure) > { > } >- >- static String toStringName(const JSObject*, ExecState*); > }; > > static_assert(std::is_final<JSMap>::value, "Required for JSType based casting"); >Index: Source/JavaScriptCore/runtime/JSObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSObject.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSObject.cpp (working copy) >@@ -518,10 +518,7 @@ String JSObject::className(const JSObjec > > String JSObject::toStringName(const JSObject* object, ExecState* exec) > { >- VM& vm = exec->vm(); >- const ClassInfo* info = object->classInfo(vm); >- ASSERT(info); >- return info->className; >+ return const_cast<JSObject*>(object)->isFunction(exec->vm()) ? "Function"_s : "Object"_s; > } > > String JSObject::calculatedClassName(JSObject* object) >Index: Source/JavaScriptCore/runtime/JSSet.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSSet.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSSet.cpp (working copy) >@@ -33,11 +33,6 @@ namespace JSC { > > const ClassInfo JSSet::s_info = { "Set", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSet) }; > >-String JSSet::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > JSSet* JSSet::clone(ExecState* exec, VM& vm, Structure* structure) > { > JSSet* instance = new (NotNull, allocateCell<JSSet>(vm.heap)) JSSet(vm, structure); >Index: Source/JavaScriptCore/runtime/JSSet.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSSet.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSSet.h (working copy) >@@ -67,8 +67,6 @@ private: > : Base(vm, structure, sizeHint) > { > } >- >- static String toStringName(const JSObject*, ExecState*); > }; > > static_assert(std::is_final<JSSet>::value, "Required for JSType based casting"); >Index: Source/JavaScriptCore/runtime/JSWeakMap.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakMap.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakMap.cpp (working copy) >@@ -32,9 +32,4 @@ namespace JSC { > > const ClassInfo JSWeakMap::s_info = { "WeakMap", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWeakMap) }; > >-String JSWeakMap::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > } >Index: Source/JavaScriptCore/runtime/JSWeakMap.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakMap.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakMap.h (working copy) >@@ -58,8 +58,6 @@ private: > : Base(vm, structure) > { > } >- >- static String toStringName(const JSObject*, ExecState*); > }; > > static_assert(std::is_final<JSWeakMap>::value, "Required for JSType based casting"); >Index: Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakObjectRef.cpp (working copy) >@@ -57,10 +57,5 @@ void JSWeakObjectRef::finalizeUnconditio > m_value.clear(); > } > >-String JSWeakObjectRef::toStringName(const JSC::JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > } > >Index: Source/JavaScriptCore/runtime/JSWeakObjectRef.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakObjectRef.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakObjectRef.h (working copy) >@@ -75,8 +75,6 @@ private: > > JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* value); > >- static String toStringName(const JSObject*, ExecState*); >- > uintptr_t m_lastAccessVersion; > WriteBarrier<JSObject> m_value; > }; >Index: Source/JavaScriptCore/runtime/JSWeakSet.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakSet.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakSet.cpp (working copy) >@@ -32,9 +32,4 @@ namespace JSC { > > const ClassInfo JSWeakSet::s_info = { "WeakSet", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWeakSet) }; > >-String JSWeakSet::toStringName(const JSC::JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > } >Index: Source/JavaScriptCore/runtime/JSWeakSet.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSWeakSet.h (revision 246723) >+++ Source/JavaScriptCore/runtime/JSWeakSet.h (working copy) >@@ -53,8 +53,6 @@ private: > : Base(vm, structure) > { > } >- >- static String toStringName(const JSObject*, ExecState*); > }; > > static_assert(std::is_final<JSWeakSet>::value, "Required for JSType based casting"); >Index: Source/JavaScriptCore/runtime/NumberObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/NumberObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/NumberObject.h (working copy) >@@ -45,6 +45,8 @@ public: > { > return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info()); > } >+ >+ static String toStringName(const JSObject*, ExecState*) { return "Number"_s; } > }; > > JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue); >Index: Source/JavaScriptCore/runtime/ObjectPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ObjectPrototype.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/ObjectPrototype.cpp (working copy) >@@ -21,6 +21,7 @@ > #include "config.h" > #include "ObjectPrototype.h" > >+#include "ArrayConstructor.h" > #include "Error.h" > #include "GetterSetter.h" > #include "HasOwnPropertyCache.h" >@@ -339,7 +340,9 @@ EncodedJSValue JSC_HOST_CALL objectProto > } > } > >- String tag = thisObject->methodTable(vm)->toStringName(thisObject, exec); >+ bool thisIsArray = isArray(exec, thisObject); >+ RETURN_IF_EXCEPTION(scope, { }); >+ String tag = thisIsArray ? "Array"_s : thisObject->methodTable(vm)->toStringName(thisObject, exec); > RETURN_IF_EXCEPTION(scope, { }); > String newString = tryMakeString("[object ", WTFMove(tag), "]"); > if (!newString) >Index: Source/JavaScriptCore/runtime/ProxyObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyObject.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/ProxyObject.cpp (working copy) >@@ -26,7 +26,6 @@ > #include "config.h" > #include "ProxyObject.h" > >-#include "ArrayConstructor.h" > #include "Error.h" > #include "IdentifierInlines.h" > #include "JSCInlines.h" >@@ -51,24 +50,6 @@ ProxyObject::ProxyObject(VM& vm, Structu > { > } > >-String ProxyObject::toStringName(const JSObject* object, ExecState* exec) >-{ >- VM& vm = exec->vm(); >- auto scope = DECLARE_THROW_SCOPE(vm); >- const ProxyObject* proxy = jsCast<const ProxyObject*>(object); >- while (proxy) { >- const JSObject* target = proxy->target(); >- bool targetIsArray = isArray(exec, target); >- if (UNLIKELY(scope.exception())) >- break; >- if (targetIsArray) >- RELEASE_AND_RETURN(scope, target->classInfo(vm)->methodTable.toStringName(target, exec)); >- >- proxy = jsDynamicCast<const ProxyObject*>(vm, target); >- } >- return "Object"_s; >-} >- > Structure* ProxyObject::structureForTarget(JSGlobalObject* globalObject, JSValue target) > { > if (!target.isObject()) >Index: Source/JavaScriptCore/runtime/ProxyObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/ProxyObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/ProxyObject.h (working copy) >@@ -74,7 +74,6 @@ private: > JS_EXPORT_PRIVATE void finishCreation(VM&, ExecState*, JSValue target, JSValue handler); > JS_EXPORT_PRIVATE static Structure* structureForTarget(JSGlobalObject*, JSValue target); > >- static String toStringName(const JSObject*, ExecState*); > static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); > static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); > static CallType getCallData(JSCell*, CallData&); >Index: Source/JavaScriptCore/runtime/RegExpObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/RegExpObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/RegExpObject.h (working copy) >@@ -48,6 +48,8 @@ public: > return object; > } > >+ static String toStringName(const JSObject*, ExecState*) { return "RegExp"_s; } >+ > void setRegExp(VM& vm, RegExp* regExp) > { > uintptr_t result = (m_regExpAndLastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag) | bitwise_cast<uintptr_t>(regExp); >Index: Source/JavaScriptCore/runtime/StringObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/StringObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/StringObject.h (working copy) >@@ -66,6 +66,8 @@ public: > return Structure::create(vm, globalObject, prototype, TypeInfo(StringObjectType, StructureFlags), info()); > } > >+ static String toStringName(const JSObject*, ExecState*) { return "String"_s; } >+ > protected: > JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*); > JS_EXPORT_PRIVATE StringObject(VM&, Structure*); >Index: Source/JavaScriptCore/runtime/SymbolObject.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/SymbolObject.cpp (revision 246723) >+++ Source/JavaScriptCore/runtime/SymbolObject.cpp (working copy) >@@ -47,11 +47,6 @@ void SymbolObject::finishCreation(VM& vm > setInternalValue(vm, symbol); > } > >-String SymbolObject::toStringName(const JSObject*, ExecState*) >-{ >- return "Object"_s; >-} >- > JSValue SymbolObject::defaultValue(const JSObject* object, ExecState*, PreferredPrimitiveType) > { > const SymbolObject* symbolObject = jsCast<const SymbolObject*>(object); >Index: Source/JavaScriptCore/runtime/SymbolObject.h >=================================================================== >--- Source/JavaScriptCore/runtime/SymbolObject.h (revision 246723) >+++ Source/JavaScriptCore/runtime/SymbolObject.h (working copy) >@@ -56,8 +56,6 @@ public: > > static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); > >- static String toStringName(const JSObject*, ExecState*); >- > protected: > JS_EXPORT_PRIVATE void finishCreation(VM&, Symbol*); > JS_EXPORT_PRIVATE SymbolObject(VM&, Structure*); >Index: Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp (revision 246723) >+++ Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp (working copy) >@@ -82,6 +82,7 @@ void JSWebAssembly::finishCreation(VM& v > { > Base::finishCreation(vm); > ASSERT(inherits(vm, info())); >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WebAssembly"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > JSWebAssembly::JSWebAssembly(VM& vm, Structure* structure) >Index: Source/JavaScriptCore/wasm/js/WebAssemblyInstancePrototype.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyInstancePrototype.cpp (revision 246723) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyInstancePrototype.cpp (working copy) >@@ -87,6 +87,7 @@ void WebAssemblyInstancePrototype::finis > { > Base::finishCreation(vm); > didBecomePrototype(); >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WebAssembly.Instance"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > WebAssemblyInstancePrototype::WebAssemblyInstancePrototype(VM& vm, Structure* structure) >Index: Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp (revision 246723) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp (working copy) >@@ -110,6 +110,7 @@ void WebAssemblyMemoryPrototype::finishC > Base::finishCreation(vm); > ASSERT(inherits(vm, info())); > didBecomePrototype(); >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WebAssembly.Memory"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > WebAssemblyMemoryPrototype::WebAssemblyMemoryPrototype(VM& vm, Structure* structure) >Index: Source/JavaScriptCore/wasm/js/WebAssemblyModulePrototype.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyModulePrototype.cpp (revision 246723) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyModulePrototype.cpp (working copy) >@@ -57,6 +57,7 @@ void WebAssemblyModulePrototype::finishC > { > Base::finishCreation(vm); > didBecomePrototype(); >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WebAssembly.Modules"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > WebAssemblyModulePrototype::WebAssemblyModulePrototype(VM& vm, Structure* structure) >Index: Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp >=================================================================== >--- Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp (revision 246723) >+++ Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp (working copy) >@@ -167,6 +167,7 @@ void WebAssemblyTablePrototype::finishCr > Base::finishCreation(vm); > ASSERT(inherits(vm, info())); > didBecomePrototype(); >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WebAssembly.Table"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > WebAssemblyTablePrototype::WebAssemblyTablePrototype(VM& vm, Structure* structure) >Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 246723) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,18 @@ >+2019-06-23 Alexey Shvayka <shvaikalesh@gmail.com> >+ >+ Object.prototype.toString is not spec-perfect >+ https://bugs.webkit.org/show_bug.cgi?id=199138 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Adds @@toStringTag to DOM constructors, prototypes, and iterators. >+ >+ * bindings/js/JSDOMIterator.h: >+ (WebCore::JSDOMIteratorPrototype::create): >+ * bindings/scripts/CodeGeneratorJS.pm: >+ (GenerateImplementation): >+ (GeneratePrototypeDeclaration): >+ > 2019-06-23 Simon Fraser <simon.fraser@apple.com> > > Add OverflowScrollProxyNodes to the scrolling tree >Index: Source/WebCore/bindings/js/JSDOMIterator.h >=================================================================== >--- Source/WebCore/bindings/js/JSDOMIterator.h (revision 246723) >+++ Source/WebCore/bindings/js/JSDOMIterator.h (working copy) >@@ -54,6 +54,8 @@ public: > { > JSDOMIteratorPrototype* prototype = new (NotNull, JSC::allocateCell<JSDOMIteratorPrototype>(vm.heap)) JSDOMIteratorPrototype(vm, structure); > prototype->finishCreation(vm, globalObject); >+ auto className = jsString(&vm, prototype->methodTable(vm)->className(prototype, vm)); >+ prototype->putDirect(vm, vm.propertyNames->toStringTagSymbol, className, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); > return prototype; > } > >Index: Source/WebCore/bindings/scripts/CodeGeneratorJS.pm >=================================================================== >--- Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (revision 246723) >+++ Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (working copy) >@@ -4359,6 +4359,8 @@ sub GenerateImplementation > push(@implContent, " putDirect(vm, vm.propertyNames->toPrimitiveSymbol, jsUndefined(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n"); > } > >+ push(@implContent, " putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, \"${visibleInterfaceName}\"), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n"); >+ > if ($interface->mapLike) { > push(@implContent, " synchronizeBackingMap(*globalObject()->globalExec(), *globalObject(), *this);\n"); > } >@@ -7063,6 +7065,8 @@ sub GeneratePrototypeDeclaration > { > my ($outputArray, $className, $interface) = @_; > >+ my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface); >+ my $prototypeVisibleName = "${visibleInterfaceName}Prototype"; > my $prototypeClassName = "${className}Prototype"; > > my %structureFlags = (); >@@ -7074,6 +7078,7 @@ sub GeneratePrototypeDeclaration > push(@$outputArray, " {\n"); > push(@$outputArray, " ${className}Prototype* ptr = new (NotNull, JSC::allocateCell<${className}Prototype>(vm.heap)) ${className}Prototype(vm, globalObject, structure);\n"); > push(@$outputArray, " ptr->finishCreation(vm);\n"); >+ push(@$outputArray, " ptr->putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, \"${prototypeVisibleName}\"), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly);\n"); > push(@$outputArray, " return ptr;\n"); > push(@$outputArray, " }\n\n"); > >Index: LayoutTests/imported/w3c/ChangeLog >=================================================================== >--- LayoutTests/imported/w3c/ChangeLog (revision 246723) >+++ LayoutTests/imported/w3c/ChangeLog (working copy) >@@ -1,3 +1,16 @@ >+2019-06-23 Alexey Shvayka <shvaikalesh@gmail.com> >+ >+ Object.prototype.toString is not spec-perfect >+ https://bugs.webkit.org/show_bug.cgi?id=199138 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Mark 3 test cases as passing. >+ >+ * web-platform-tests/WebIDL/ecmascript-binding/default-iterator-object-expected.txt: >+ * web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-object-expected.txt: >+ * web-platform-tests/WebIDL/ecmascript-binding/iterator-prototype-object-expected.txt: >+ > 2019-06-23 Antoine Quint <graouts@apple.com> > > [Pointer Events WPT] Unflake imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_pointercapture_in_frame.html >Index: LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/default-iterator-object-expected.txt >=================================================================== >--- LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/default-iterator-object-expected.txt (revision 246723) >+++ LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/default-iterator-object-expected.txt (working copy) >@@ -1,5 +1,5 @@ > > PASS Default iterator objects for an interface have the same prototype > PASS Object.prototype.toString returns correct value >-FAIL @@toStringTag has correct value from prototype assert_equals: expected (string) "URLSearchParams Iterator" but got (undefined) undefined >+PASS @@toStringTag has correct value from prototype > >Index: LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-object-expected.txt >=================================================================== >--- LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-object-expected.txt (revision 246723) >+++ LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-object-expected.txt (working copy) >@@ -1,3 +1,3 @@ > >-FAIL The class string of an interface prototype object is the concatenation of the interface's identifier and the string 'Prototype'. assert_true: An interface prototype object should have toStringTag property. expected true got false >+PASS The class string of an interface prototype object is the concatenation of the interface's identifier and the string 'Prototype'. > >Index: LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/iterator-prototype-object-expected.txt >=================================================================== >--- LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/iterator-prototype-object-expected.txt (revision 246723) >+++ LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/iterator-prototype-object-expected.txt (working copy) >@@ -3,6 +3,6 @@ PASS Has %IteratorPrototype% as prototyp > PASS next() exists and is writable, enumerable, and configurable > PASS next() throws TypeError when called on ineligible receiver > PASS Object.prototype.toString returns correct value >-FAIL @@toStringTag has correct value undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(iteratorProto, Symbol.toStringTag).value') >+PASS @@toStringTag has correct value > PASS Is specific to an interface >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199138
:
372719
|
372722
|
372723
|
372725
|
372726
|
372748
|
372771
|
374400
|
374407
|
398257
|
398293
|
398436