Ignore:
Timestamp:
Apr 9, 2021, 6:00:15 PM (4 years ago)
Author:
Alexey Shvayka
Message:

Remove className() and toStringName() from the method table
https://bugs.webkit.org/show_bug.cgi?id=224247

Reviewed by Darin Adler.

Source/JavaScriptCore:

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.
  1. 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.
  1. 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.
  1. 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.
  1. Removes now unused className() from the method table.
  1. Removes toStringName() override from JSFinalizationRegistry because its builtin tag [1] is already "Object".
  1. Introduces BooleanObjectType for Boolean wrapper object, and Boolean.prototype as it's also required to have a BooleanData internal slot [2].
  1. 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.
  1. 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:

LayoutTests:

  • inspector/model/remote-object-get-properties-expected.txt:
  • inspector/model/remote-object-get-properties.html:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/debugger/DebuggerScope.cpp

    r273138 r275788  
    6969DEFINE_VISIT_CHILDREN(DebuggerScope);
    7070
    71 String DebuggerScope::className(const JSObject* object, VM& vm)
    72 {
    73     const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
    74     // We cannot assert that scope->isValid() because the TypeProfiler may encounter an invalidated
    75     // DebuggerScope in its log entries. We just need to handle it appropriately as below.
    76     if (!scope->isValid())
    77         return String();
    78     JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
    79     return thisObject->methodTable(vm)->className(thisObject, vm);
    80 }
    81 
    82 String DebuggerScope::toStringName(const JSObject* object, JSGlobalObject* globalObject)
    83 {
    84     const DebuggerScope* scope = jsCast<const DebuggerScope*>(object);
    85     // We cannot assert that scope->isValid() because the TypeProfiler may encounter an invalidated
    86     // DebuggerScope in its log entries. We just need to handle it appropriately as below.
    87     if (!scope->isValid())
    88         return String();
    89     JSObject* thisObject = JSScope::objectAtScope(scope->jsScope());
    90     return thisObject->methodTable(globalObject->vm())->toStringName(thisObject, globalObject);
    91 }
    92 
    9371bool DebuggerScope::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
    9472{
Note: See TracChangeset for help on using the changeset viewer.