Diff
Modified: trunk/LayoutTests/ChangeLog (275787 => 275788)
--- trunk/LayoutTests/ChangeLog 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/LayoutTests/ChangeLog 2021-04-10 01:00:15 UTC (rev 275788)
@@ -1,3 +1,13 @@
+2021-04-09 Alexey Shvayka <[email protected]>
+
+ Remove className() and toStringName() from the method table
+ https://bugs.webkit.org/show_bug.cgi?id=224247
+
+ Reviewed by Darin Adler.
+
+ * inspector/model/remote-object-get-properties-expected.txt:
+ * inspector/model/remote-object-get-properties.html:
+
2021-04-09 Jean-Yves Avenard <[email protected]>
Media Session action should default to the MediaElement's default when no MediaSession handler are set
Modified: trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt (275787 => 275788)
--- trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2021-04-10 01:00:15 UTC (rev 275788)
@@ -467,6 +467,7 @@
Symbol(sym)
Symbol(sym)
Symbol()
+ Symbol(Symbol.toStringTag)
__proto__
DISPLAYABLE PROPERTIES:
@@ -476,6 +477,7 @@
Symbol(sym)
Symbol(sym)
Symbol()
+ Symbol(Symbol.toStringTag)
__proto__
ALL PROPERTIES:
@@ -485,6 +487,7 @@
Symbol(sym)
Symbol(sym)
Symbol()
+ Symbol(Symbol.toStringTag)
toString
toLocaleString
valueOf
@@ -500,6 +503,65 @@
-----------------------------------------------------
-----------------------------------------------------
+_expression_: window.objectWithSymbolToStringTag
+type: object
+description: Foo
+
+OWN PROPERTIES:
+ Symbol(Symbol.toStringTag)
+ __proto__
+
+DISPLAYABLE PROPERTIES:
+ Symbol(Symbol.toStringTag)
+ __proto__
+
+ALL PROPERTIES:
+ Symbol(Symbol.toStringTag)
+ toString
+ toLocaleString
+ valueOf
+ hasOwnProperty
+ propertyIsEnumerable
+ isPrototypeOf
+ __defineGetter__
+ __defineSetter__
+ __lookupGetter__
+ __lookupSetter__
+ constructor
+ __proto__
+-----------------------------------------------------
+
+-----------------------------------------------------
+_expression_: window.objectWithShadowedSymbolToStringTag
+type: object
+description: Foo
+
+OWN PROPERTIES:
+ __proto__
+
+DISPLAYABLE PROPERTIES:
+ __proto__
+
+ALL PROPERTIES:
+ constructor
+ addEventListener
+ removeEventListener
+ dispatchEvent
+ Symbol(Symbol.toStringTag)
+ toString
+ toLocaleString
+ valueOf
+ hasOwnProperty
+ propertyIsEnumerable
+ isPrototypeOf
+ __defineGetter__
+ __defineSetter__
+ __lookupGetter__
+ __lookupSetter__
+ __proto__
+-----------------------------------------------------
+
+-----------------------------------------------------
_expression_: document.getElementById('my-select').options
type: object
subtype: array
Modified: trunk/LayoutTests/inspector/model/remote-object-get-properties.html (275787 => 275788)
--- trunk/LayoutTests/inspector/model/remote-object-get-properties.html 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/LayoutTests/inspector/model/remote-object-get-properties.html 2021-04-10 01:00:15 UTC (rev 275788)
@@ -45,7 +45,9 @@
var badGetterObject = new ClassWithBadGetter;
var unboundFunction = function() { console.log(arguments); }
var boundFunction = unboundFunction.bind(document.body, 1, 2, 3);
-var objectWithSymbolProperties = {prop:1, [Symbol()]:2, [Symbol('sym')]:3, [Symbol('sym')]:4, [Symbol()]: Symbol(), prop2: 5};
+var objectWithSymbolProperties = {prop:1, [Symbol()]:2, [Symbol('sym')]:3, [Symbol('sym')]:4, [Symbol()]: Symbol(), [Symbol.toStringTag]: new String("IgnoredTag"), prop2: 5};
+var objectWithSymbolToStringTag = {[Symbol.toStringTag]: "Foo"};
+var objectWithShadowedSymbolToStringTag = new (class Foo extends EventTarget {});
// --------
// test
@@ -64,6 +66,8 @@
{_expression_: "window.unboundFunction"},
{_expression_: "window.boundFunction"},
{_expression_: "window.objectWithSymbolProperties"},
+ {_expression_: "window.objectWithSymbolToStringTag"},
+ {_expression_: "window.objectWithShadowedSymbolToStringTag"},
{_expression_: "document.getElementById('my-select').options"},
]
Modified: trunk/Source/_javascript_Core/API/JSCallbackObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/API/JSCallbackObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/API/JSCallbackObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -199,9 +199,6 @@
void finishCreation(VM&);
static IsoSubspace* subspaceForImpl(VM&, SubspaceAccess);
- static String className(const JSObject*, VM&);
- static String toStringName(const JSObject*, JSGlobalObject*);
-
static JSValue defaultValue(const JSObject*, JSGlobalObject*, PreferredPrimitiveType);
static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
Modified: trunk/Source/_javascript_Core/API/JSCallbackObjectFunctions.h (275787 => 275788)
--- trunk/Source/_javascript_Core/API/JSCallbackObjectFunctions.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/API/JSCallbackObjectFunctions.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -131,26 +131,6 @@
}
template <class Parent>
-String JSCallbackObject<Parent>::className(const JSObject* object, VM& vm)
-{
- const JSCallbackObject* thisObject = jsCast<const JSCallbackObject*>(object);
- String thisClassName = thisObject->classRef()->className();
- if (!thisClassName.isEmpty())
- return thisClassName;
-
- return Parent::className(object, vm);
-}
-
-template <class Parent>
-String JSCallbackObject<Parent>::toStringName(const JSObject* object, JSGlobalObject* globalObject)
-{
- VM& vm = getVM(globalObject);
- const ClassInfo* info = object->classInfo(vm);
- ASSERT(info);
- return info->methodTable.className(object, vm);
-}
-
-template <class Parent>
bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
{
VM& vm = getVM(globalObject);
@@ -213,7 +193,20 @@
}
}
- RELEASE_AND_RETURN(scope, Parent::getOwnPropertySlot(thisObject, globalObject, propertyName, slot));
+ bool found = Parent::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
+ RETURN_IF_EXCEPTION(scope, false);
+ if (found)
+ return true;
+
+ if (propertyName.uid() == vm.propertyNames->toStringTagSymbol.impl()) {
+ String className = thisObject->classRef()->className();
+ if (className.isEmpty())
+ className = thisObject->className(vm);
+ slot.setValue(thisObject, static_cast<unsigned>(PropertyAttribute::DontEnum), jsString(vm, WTFMove(className)));
+ return true;
+ }
+
+ return false;
}
template <class Parent>
Modified: trunk/Source/_javascript_Core/API/tests/testapiScripts/testapi.js (275787 => 275788)
--- trunk/Source/_javascript_Core/API/tests/testapiScripts/testapi.js 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/API/tests/testapiScripts/testapi.js 2021-04-10 01:00:15 UTC (rev 275788)
@@ -198,6 +198,16 @@
shouldThrow("MyObject.nullCall()");
shouldThrow("MyObject.hasPropertyLie");
+var symbolToStringTagDescriptor = Object.getOwnPropertyDescriptor(MyObject, Symbol.toStringTag);
+shouldBe("typeof symbolToStringTagDescriptor", "object");
+shouldBe("symbolToStringTagDescriptor.value", "MyObject");
+shouldBe("symbolToStringTagDescriptor.writable", true);
+shouldBe("symbolToStringTagDescriptor.enumerable", false);
+shouldBe("symbolToStringTagDescriptor.configurable", true);
+
+MyObject[Symbol.toStringTag] = "Foo";
+shouldBe("Object.prototype.toString.call(MyObject)", "[object Foo]");
+
derived = new Derived();
shouldBe("derived instanceof Derived", true);
@@ -282,6 +292,16 @@
shouldBe("EmptyObject", "[object CallbackObject]");
+var symbolToStringTagDescriptor = Object.getOwnPropertyDescriptor(EmptyObject, Symbol.toStringTag);
+shouldBe("typeof symbolToStringTagDescriptor", "object");
+shouldBe("symbolToStringTagDescriptor.value", "CallbackObject");
+shouldBe("symbolToStringTagDescriptor.writable", true);
+shouldBe("symbolToStringTagDescriptor.enumerable", false);
+shouldBe("symbolToStringTagDescriptor.configurable", true);
+
+EmptyObject[Symbol.toStringTag] = "Foo";
+shouldBe("Object.prototype.toString.call(EmptyObject)", "[object Foo]");
+
for (var i = 0; i < 6; ++i)
PropertyCatchalls.x = i;
shouldBe("PropertyCatchalls.x", 4);
Modified: trunk/Source/_javascript_Core/ChangeLog (275787 => 275788)
--- trunk/Source/_javascript_Core/ChangeLog 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-04-10 01:00:15 UTC (rev 275788)
@@ -1,3 +1,115 @@
+2021-04-09 Alexey Shvayka <[email protected]>
+
+ Remove className() and toStringName() from the method table
+ https://bugs.webkit.org/show_bug.cgi?id=224247
+
+ Reviewed by Darin Adler.
+
+ ES6 introduced Symbol.toStringTag to customize Object.prototype.toString return value.
+ It was adopted by WebIDL spec, Chrome's DevTools, Node.js etc. There is no reason to
+ keep 2 method table methods, each with only 1 call site, instead of using the symbol.
+
+ Also, it's a bit confusing that for some objects, method table's className() returns
+ different result than JSCell::className(VM&).
+
+ This change:
+
+ 1. Removes JSProxy's className() / toStringName() methods because its target() is a
+ global object that never has these overrides and uses Symbol.toStringTag instead.
+
+ 2. Removes DebuggerScope's className() / toStringName() overrides because its objectAtScope()
+ has these methods extremely rarely (e.g. `with (new Date) {}`), and its not displayed
+ by Web Inspector.
+
+ 3. Merges JSCallbackObject's className() / toStringName() methods into Symbol.toStringTag
+ branch of getOwnPropertySlot(), with permissive property attributes. To avoid any possible
+ breakage, we make sure that it will be shadowed by a structure property.
+
+ 4. Reworks JSObject::calculatedClassName() to rely on Symbol.toStringTag, matching Chrome's
+ DevTools behavior. On its own, it's a nice change for Web Inspector. We make sure to
+ lookup Symbol.toStringTag if `constructor.name` inference fails to avoid confusion when
+ extending builtins.
+
+ 5. Removes now unused className() from the method table.
+
+ 6. Removes toStringName() override from JSFinalizationRegistry because its builtin tag [1]
+ is already "Object".
+
+ 7. Introduces BooleanObjectType for Boolean wrapper object, and Boolean.prototype as it's
+ also required to have a [[BooleanData]] internal slot [2].
+
+ 8. Reworks Object.prototype.toString to determine builtin tag [1] based on JSType rather than
+ performing method table call. It's guaranteed that a) the set of types we are checking
+ against won't be expanded, and b) objects with these types have correct `className`.
+
+ 9. Removes now unused toStringTag() from the method table.
+
+ This patch is performance-neutral and carefully preserves current behavior for API objects,
+ including isPokerBros() hack.
+
+ [1]: https://tc39.es/ecma262/#sec-object.prototype.tostring (steps 5-14)
+ [2]: https://tc39.es/ecma262/#sec-properties-of-the-boolean-prototype-object
+
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
+ (JSC::JSCallbackObject<Parent>::className): Deleted.
+ (JSC::JSCallbackObject<Parent>::toStringName): Deleted.
+ * API/tests/testapiScripts/testapi.js:
+ * debugger/DebuggerScope.cpp:
+ (JSC::DebuggerScope::className): Deleted.
+ (JSC::DebuggerScope::toStringName): Deleted.
+ * debugger/DebuggerScope.h:
+ * runtime/BooleanObject.cpp:
+ (JSC::BooleanObject::toStringName): Deleted.
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/BooleanPrototype.h:
+ * runtime/ClassInfo.h:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::toStringName): Deleted.
+ * runtime/DateInstance.h:
+ * runtime/ErrorInstance.cpp:
+ (JSC::ErrorInstance::toStringName): Deleted.
+ * runtime/ErrorInstance.h:
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::className): Deleted.
+ (JSC::JSCell::toStringName): Deleted.
+ * runtime/JSCell.h:
+ * runtime/JSFinalizationRegistry.cpp:
+ (JSC::JSFinalizationRegistry::toStringName): Deleted.
+ * runtime/JSFinalizationRegistry.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::calculatedClassName):
+ (JSC::JSObject::className): Deleted.
+ (JSC::isPokerBros): Deleted.
+ (JSC::JSObject::toStringName): Deleted.
+ * runtime/JSObject.h:
+ * runtime/JSProxy.cpp:
+ (JSC::JSProxy::className): Deleted.
+ (JSC::JSProxy::toStringName): Deleted.
+ * runtime/JSProxy.h:
+ * runtime/JSType.cpp:
+ (WTF::printInternal):
+ * runtime/JSType.h:
+ * runtime/NumberObject.cpp:
+ (JSC::NumberObject::toStringName): Deleted.
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::isPokerBros):
+ (JSC::inferBuiltinTag):
+ (JSC::objectPrototypeToString):
+ 1. Removes jsNontrivialString() because it's assertion may fail in case of iOS hack.
+ 2. Utilizes AtomStringImpl to avoid allocating StringImpl for a small fixed set of strings.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::toStringName): Deleted.
+ * runtime/RegExpObject.h:
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::toStringName): Deleted.
+ * runtime/StringObject.h:
+
2021-04-08 Khem Raj <[email protected]>
[WPE] Build fixes for musl C library on Linux
Modified: trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/debugger/DebuggerScope.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -68,28 +68,6 @@
DEFINE_VISIT_CHILDREN(DebuggerScope);
-String DebuggerScope::className(const JSObject* object, VM& vm)
-{
- const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
- // We cannot assert that scope->isValid() because the TypeProfiler may encounter an invalidated
- // DebuggerScope in its log entries. We just need to handle it appropriately as below.
- if (!scope->isValid())
- return String();
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- return thisObject->methodTable(vm)->className(thisObject, vm);
-}
-
-String DebuggerScope::toStringName(const JSObject* object, JSGlobalObject* globalObject)
-{
- const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
- // We cannot assert that scope->isValid() because the TypeProfiler may encounter an invalidated
- // DebuggerScope in its log entries. We just need to handle it appropriately as below.
- if (!scope->isValid())
- return String();
- JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
- return thisObject->methodTable(globalObject->vm())->toStringName(thisObject, globalObject);
-}
-
bool DebuggerScope::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
{
DebuggerScope* scope = jsCast<DebuggerScope*>(object);
Modified: trunk/Source/_javascript_Core/debugger/DebuggerScope.h (275787 => 275788)
--- trunk/Source/_javascript_Core/debugger/DebuggerScope.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/debugger/DebuggerScope.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -47,8 +47,6 @@
JS_EXPORT_PRIVATE static DebuggerScope* create(VM& vm, JSScope* scope);
DECLARE_VISIT_CHILDREN;
- static String className(const JSObject*, VM&);
- static String toStringName(const JSObject*, JSGlobalObject*);
static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
static bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
static bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&);
Modified: trunk/Source/_javascript_Core/runtime/BooleanObject.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/BooleanObject.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/BooleanObject.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -40,9 +40,4 @@
ASSERT(inherits(vm, info()));
}
-String BooleanObject::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "Boolean"_s;
-}
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/BooleanObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/BooleanObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/BooleanObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -49,10 +49,8 @@
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(BooleanObjectType, StructureFlags), info());
}
-
- static String toStringName(const JSObject*, JSGlobalObject*);
};
static_assert(sizeof(BooleanObject) == sizeof(JSWrapperObject));
Modified: trunk/Source/_javascript_Core/runtime/BooleanPrototype.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/BooleanPrototype.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/BooleanPrototype.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -40,7 +40,7 @@
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(BooleanObjectType, StructureFlags), info());
}
private:
Modified: trunk/Source/_javascript_Core/runtime/ClassInfo.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/ClassInfo.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/ClassInfo.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -81,12 +81,6 @@
GetOwnPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnPropertyNames);
GetOwnPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnSpecialPropertyNames);
- using ClassNameFunctionPtr = String (*)(const JSObject*, VM&);
- ClassNameFunctionPtr METHOD_TABLE_ENTRY(className);
-
- using ToStringNameFunctionPtr = String (*)(const JSObject*, JSGlobalObject*);
- ToStringNameFunctionPtr METHOD_TABLE_ENTRY(toStringName);
-
using CustomHasInstanceFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, JSValue);
CustomHasInstanceFunctionPtr METHOD_TABLE_ENTRY(customHasInstance);
@@ -169,8 +163,6 @@
&ClassName::defaultValue, \
&ClassName::getOwnPropertyNames, \
&ClassName::getOwnSpecialPropertyNames, \
- &ClassName::className, \
- &ClassName::toStringName, \
&ClassName::customHasInstance, \
&ClassName::defineOwnProperty, \
&ClassName::preventExtensions, \
Modified: trunk/Source/_javascript_Core/runtime/DateInstance.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/DateInstance.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/DateInstance.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -47,11 +47,6 @@
m_internalNumber = timeClip(time);
}
-String DateInstance::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "Date"_s;
-}
-
const GregorianDateTime* DateInstance::calculateGregorianDateTime(DateCache& cache) const
{
double milli = internalNumber();
Modified: trunk/Source/_javascript_Core/runtime/DateInstance.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/DateInstance.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/DateInstance.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -54,7 +54,6 @@
return instance;
}
- static String toStringName(const JSObject*, JSGlobalObject*);
double internalNumber() const { return m_internalNumber; }
void setInternalNumber(double value) { m_internalNumber = value; }
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -319,9 +319,4 @@
return Base::deleteProperty(thisObject, globalObject, propertyName, slot);
}
-String ErrorInstance::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "Error"_s;
-}
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -101,7 +101,6 @@
static bool defineOwnProperty(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
static bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
static bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&);
- static String toStringName(const JSObject*, JSGlobalObject*);
void computeErrorInfo(VM&);
Modified: trunk/Source/_javascript_Core/runtime/JSCell.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSCell.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSCell.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -216,18 +216,6 @@
RELEASE_ASSERT_NOT_REACHED();
}
-String JSCell::className(const JSObject*, VM&)
-{
- RELEASE_ASSERT_NOT_REACHED();
- return String();
-}
-
-String JSCell::toStringName(const JSObject*, JSGlobalObject*)
-{
- RELEASE_ASSERT_NOT_REACHED();
- return String();
-}
-
const char* JSCell::className(VM& vm) const
{
return classInfo(vm)->className;
Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSCell.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -253,8 +253,6 @@
static NO_RETURN_DUE_TO_CRASH bool setPrototype(JSObject*, JSGlobalObject*, JSValue, bool);
static NO_RETURN_DUE_TO_CRASH JSValue getPrototype(JSObject*, JSGlobalObject*);
- static String className(const JSObject*, VM&);
- static String toStringName(const JSObject*, JSGlobalObject*);
JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, JSGlobalObject*, JSValue);
static bool defineOwnProperty(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
Modified: trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -239,11 +239,6 @@
return count;
}
-String JSFinalizationRegistry::toStringName(const JSC::JSObject*, JSGlobalObject*)
-{
- return "Object"_s;
}
-}
-
Modified: trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSFinalizationRegistry.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -91,8 +91,6 @@
JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*, JSObject* callback);
- static String toStringName(const JSObject*, JSGlobalObject*);
-
struct Registration {
JSObject* target;
WriteBarrier<Unknown> holdings;
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -24,7 +24,6 @@
#include "config.h"
#include "JSObject.h"
-#include "ArrayConstructor.h"
#include "CatchScope.h"
#include "CustomGetterSetter.h"
#include "Exception.h"
@@ -45,10 +44,6 @@
#include "VMInlines.h"
#include <wtf/Assertions.h>
-#if PLATFORM(IOS)
-#include <wtf/spi/darwin/dyldSPI.h>
-#endif
-
namespace JSC {
// We keep track of the size of the last array after it was grown. We use this
@@ -485,46 +480,6 @@
DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, JSFinalObject);
-String JSObject::className(const JSObject* object, VM& vm)
-{
- const ClassInfo* info = object->classInfo(vm);
- ASSERT(info);
- return info->className;
-}
-
-#if PLATFORM(IOS)
-inline static bool isPokerBros()
-{
- auto bundleID = CFBundleGetIdentifier(CFBundleGetMainBundle());
- return bundleID
- && CFEqual(bundleID, CFSTR("com.kpgame.PokerBros"))
- && dyld_get_program_sdk_version() < DYLD_IOS_VERSION_14_0;
-}
-#endif
-
-String JSObject::toStringName(const JSObject* object, JSGlobalObject* globalObject)
-{
- VM& vm = globalObject->vm();
-#if PLATFORM(IOS)
- static bool needsOldStringName = isPokerBros();
- if (UNLIKELY(needsOldStringName)) {
- const ClassInfo* info = object->classInfo(vm);
- ASSERT(info);
- return info->className;
- }
-#endif
- auto scope = DECLARE_THROW_SCOPE(vm);
- bool objectIsArray = isArray(globalObject, object);
- RETURN_IF_EXCEPTION(scope, String());
- if (objectIsArray)
- return "Array"_s;
- if (TypeInfo::isArgumentsType(object->type()))
- return "Arguments"_s;
- if (const_cast<JSObject*>(object)->isCallable(vm))
- return "Function"_s;
- return "Object"_s;
-}
-
String JSObject::calculatedClassName(JSObject* object)
{
String constructorFunctionName;
@@ -580,10 +535,23 @@
scope.clearException();
if (constructorFunctionName.isNull() || constructorFunctionName == "Object") {
- String tableClassName = object->methodTable(vm)->className(object, vm);
- if (!tableClassName.isNull() && tableClassName != "Object")
- return tableClassName;
+ PropertySlot slot(object, PropertySlot::InternalMethodType::VMInquiry, &vm);
+ if (object->getPropertySlot(globalObject, vm.propertyNames->toStringTagSymbol, slot)) {
+ EXCEPTION_ASSERT(!scope.exception());
+ if (slot.isValue()) {
+ JSValue value = slot.getValue(globalObject, vm.propertyNames->toStringTagSymbol);
+ if (value.isString()) {
+ String tag = asString(value)->value(globalObject);
+ if (UNLIKELY(scope.exception()))
+ scope.clearException();
+ return tag;
+ }
+ }
+ }
+ if (UNLIKELY(scope.exception()))
+ scope.clearException();
+
String classInfoName = object->classInfo(vm)->className;
if (!classInfoName.isNull())
return classInfoName;
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -112,15 +112,8 @@
JS_EXPORT_PRIVATE static size_t estimatedSize(JSCell*, VM&);
JS_EXPORT_PRIVATE static void analyzeHeap(JSCell*, HeapAnalyzer&);
- JS_EXPORT_PRIVATE static String className(const JSObject*, VM&);
JS_EXPORT_PRIVATE static String calculatedClassName(JSObject*);
- // This function is what Object.prototype.toString() will use to get the name of
- // an object when using Symbol.toStringTag fails. For the most part there is no
- // difference between this and className(). The main use case is for new JS language
- // objects to set the default tag to "Object".
- JS_EXPORT_PRIVATE static String toStringName(const JSObject*, JSGlobalObject*);
-
// This is the fully virtual [[GetPrototypeOf]] internal function defined
// in the ECMAScript 6 specification. Use this when doing a [[GetPrototypeOf]]
// operation as dictated in the specification.
Modified: trunk/Source/_javascript_Core/runtime/JSProxy.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSProxy.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSProxy.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -52,18 +52,6 @@
setPrototypeDirect(vm, globalObject->getPrototypeDirect(vm));
}
-String JSProxy::className(const JSObject* object, VM& vm)
-{
- const JSProxy* thisObject = jsCast<const JSProxy*>(object);
- return thisObject->target()->methodTable(vm)->className(thisObject->target(), vm);
-}
-
-String JSProxy::toStringName(const JSObject* object, JSGlobalObject* globalObject)
-{
- const JSProxy* thisObject = jsCast<const JSProxy*>(object);
- return thisObject->target()->methodTable(globalObject->vm())->toStringName(thisObject->target(), globalObject);
-}
-
bool JSProxy::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
{
JSProxy* thisObject = jsCast<JSProxy*>(object);
Modified: trunk/Source/_javascript_Core/runtime/JSProxy.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSProxy.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSProxy.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -86,8 +86,6 @@
DECLARE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE);
- JS_EXPORT_PRIVATE static String className(const JSObject*, VM&);
- JS_EXPORT_PRIVATE static String toStringName(const JSObject*, JSGlobalObject*);
JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, JSGlobalObject*, unsigned, PropertySlot&);
JS_EXPORT_PRIVATE static bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
Modified: trunk/Source/_javascript_Core/runtime/JSType.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSType.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSType.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -65,6 +65,7 @@
CASE(JSFunctionType)
CASE(InternalFunctionType)
CASE(NullSetterFunctionType)
+ CASE(BooleanObjectType)
CASE(NumberObjectType)
CASE(ErrorInstanceType)
CASE(PureForwardingProxyType)
Modified: trunk/Source/_javascript_Core/runtime/JSType.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/JSType.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/JSType.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -62,6 +62,7 @@
JSFunctionType,
InternalFunctionType,
NullSetterFunctionType,
+ BooleanObjectType,
NumberObjectType,
ErrorInstanceType,
PureForwardingProxyType,
Modified: trunk/Source/_javascript_Core/runtime/NumberObject.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/NumberObject.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/NumberObject.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -42,11 +42,6 @@
ASSERT(type() == NumberObjectType);
}
-String NumberObject::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "Number"_s;
-}
-
NumberObject* constructNumber(JSGlobalObject* globalObject, JSValue number)
{
NumberObject* object = NumberObject::create(globalObject->vm(), globalObject->numberObjectStructure());
Modified: trunk/Source/_javascript_Core/runtime/NumberObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/NumberObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/NumberObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -51,8 +51,6 @@
{
return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
}
-
- static String toStringName(const JSObject*, JSGlobalObject*);
};
static_assert(sizeof(NumberObject) == sizeof(JSWrapperObject));
Modified: trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -21,6 +21,7 @@
#include "config.h"
#include "ObjectPrototype.h"
+#include "ArrayConstructor.h"
#include "GetterSetter.h"
#include "HasOwnPropertyCache.h"
#include "IntegrityInlines.h"
@@ -27,6 +28,10 @@
#include "JSCInlines.h"
#include "PropertySlot.h"
+#if PLATFORM(IOS)
+#include <wtf/spi/darwin/dyldSPI.h>
+#endif
+
namespace JSC {
static JSC_DECLARE_HOST_FUNCTION(objectProtoFuncValueOf);
@@ -311,6 +316,44 @@
RELEASE_AND_RETURN(scope, JSValue::encode(call(globalObject, toString, callData, thisValue, *vm.emptyList)));
}
+#if PLATFORM(IOS)
+inline static bool isPokerBros()
+{
+ auto bundleID = CFBundleGetIdentifier(CFBundleGetMainBundle());
+ return bundleID
+ && CFEqual(bundleID, CFSTR("com.kpgame.PokerBros"))
+ && dyld_get_program_sdk_version() < DYLD_IOS_VERSION_14_0;
+}
+#endif
+
+inline const char* inferBuiltinTag(JSGlobalObject* globalObject, JSObject* object)
+{
+ VM& vm = globalObject->vm();
+#if PLATFORM(IOS)
+ static bool needsOldBuiltinTag = isPokerBros();
+ if (UNLIKELY(needsOldBuiltinTag))
+ return object->className(vm);
+#endif
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ bool objectIsArray = isArray(globalObject, object);
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ if (objectIsArray)
+ return "Array";
+ if (object->isCallable(vm))
+ return "Function";
+ JSType type = object->type();
+ if (TypeInfo::isArgumentsType(type)
+ || type == ErrorInstanceType
+ || type == BooleanObjectType
+ || type == NumberObjectType
+ || type == StringObjectType
+ || type == DerivedStringObjectType
+ || type == JSDateType
+ || type == RegExpObjectType)
+ return object->className(vm);
+ return "Object";
+}
+
JSString* objectPrototypeToString(JSGlobalObject* globalObject, JSValue thisValue)
{
VM& vm = globalObject->vm();
@@ -328,7 +371,7 @@
if (result)
return asString(result);
- String tag = thisObject->methodTable(vm)->toStringName(thisObject, globalObject);
+ const char* tag = inferBuiltinTag(globalObject, thisObject);
RETURN_IF_EXCEPTION(scope, nullptr);
JSString* jsTag = nullptr;
@@ -342,10 +385,8 @@
jsTag = asString(tagValue);
}
- if (!jsTag) {
- ASSERT_WITH_MESSAGE(tag.length() > 1, "toStringName() should return strings two or more characters long.");
- jsTag = jsNontrivialString(vm, WTFMove(tag));
- }
+ if (!jsTag)
+ jsTag = jsString(vm, AtomStringImpl::add(tag).releaseNonNull());
JSString* jsResult = jsString(globalObject, vm.smallStrings.objectStringStart(), jsTag, vm.smallStrings.singleCharacterString(']'));
RETURN_IF_EXCEPTION(scope, nullptr);
Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -149,11 +149,6 @@
return Base::put(cell, globalObject, propertyName, value, slot);
}
-String RegExpObject::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "RegExp"_s;
-}
-
JSValue RegExpObject::exec(JSGlobalObject* globalObject, JSString* string)
{
return execInline(globalObject, string);
Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/RegExpObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -104,7 +104,6 @@
static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
static bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&);
- static String toStringName(const JSObject*, JSGlobalObject*);
DECLARE_EXPORT_INFO;
Modified: trunk/Source/_javascript_Core/runtime/StringObject.cpp (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/StringObject.cpp 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/StringObject.cpp 2021-04-10 01:00:15 UTC (rev 275788)
@@ -160,11 +160,6 @@
thisObject->getOwnNonIndexPropertyNames(globalObject, propertyNames, mode);
}
-String StringObject::toStringName(const JSObject*, JSGlobalObject*)
-{
- return "String"_s;
-}
-
StringObject* constructString(VM& vm, JSGlobalObject* globalObject, JSValue string)
{
StringObject* object = StringObject::create(vm, globalObject->stringObjectStructure());
Modified: trunk/Source/_javascript_Core/runtime/StringObject.h (275787 => 275788)
--- trunk/Source/_javascript_Core/runtime/StringObject.h 2021-04-10 00:45:37 UTC (rev 275787)
+++ trunk/Source/_javascript_Core/runtime/StringObject.h 2021-04-10 01:00:15 UTC (rev 275788)
@@ -61,7 +61,6 @@
JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, JSGlobalObject*, unsigned propertyName);
JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode);
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
- static String toStringName(const JSObject*, JSGlobalObject*);
DECLARE_EXPORT_INFO;