Ignore:
Timestamp:
Nov 13, 2020, 2:32:01 PM (5 years ago)
Author:
[email protected]
Message:

[JSC] Use symbols as identifiers for class fields computed names storage
https://bugs.webkit.org/show_bug.cgi?id=216172

Patch by Xan López <Xan Lopez> on 2020-11-13
Reviewed by Yusuke Suzuki.

Use private symbols for the property keys of the class fields with
computed names. This is cleaner than using raw numeric identifiers and
will be less cumbersome when we add static fields. It also prevents
potential collisions if other features want to store data in the class
scope.

JSTests:

  • stress/class-fields-harmony.js: new test, make sure

setFunctionName works properly with computed fields.

Source/JavaScriptCore:

  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitSaveComputedFieldName): adapt a comment.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseClass): use private identifiers for computed fields property keys.
(JSC::Parser<LexerType>::parseInstanceFieldInitializerSourceElements): ditto.

  • parser/ParserArena.cpp:

(JSC::IdentifierArena::makePrivateIdentifier): method to create a private identifier.

  • parser/ParserArena.h:
  • runtime/CachedTypes.cpp:

(JSC::CachedUniquedStringImplBase::encode): consider registered symbols, they are used by the parser now.
(JSC::CachedUniquedStringImplBase::decode const): ditto.

  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:

(JSC::VM::privateSymbolRegistry): create a private symbol registry too.

Source/WTF:

  • wtf/text/SymbolImpl.cpp:

(WTF::RegisteredSymbolImpl::createPrivate): add a method to create a registered private symbol from a string key.

  • wtf/text/SymbolImpl.h:
  • wtf/text/SymbolRegistry.cpp:

(WTF::SymbolRegistry::symbolForKey): consider that we can hold private symbols now too.

  • wtf/text/SymbolRegistry.h:

(WTF::SymbolRegistry::SymbolRegistry): new enum type for public/private symbols.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r268489 r269801  
    803803    RefPtr<RegisterID> propertyExpr;
    804804
    805     // The 'name' refers to a synthetic numeric variable name in the private name scope, where the property key is saved for later use.
     805    // The 'name' refers to a synthetic private name in the class scope, where the property key is saved for later use.
    806806    const Identifier& description = *node.name();
    807807    Variable var = generator.variable(description);
     
    48184818{
    48194819    RefPtr<RegisterID> value = generator.newTemporary();
     4820    bool shouldSetFunctionName = false;
    48204821
    48214822    if (!m_assign)
     
    48234824    else {
    48244825        generator.emitNode(value.get(), m_assign);
    4825         if (m_ident && generator.shouldSetFunctionName(m_assign))
     4826        shouldSetFunctionName = generator.shouldSetFunctionName(m_assign);
     4827        if (m_ident && shouldSetFunctionName && m_type != DefineFieldNode::Type::ComputedName)
    48264828            generator.emitSetFunctionName(value.get(), *m_ident);
    48274829    }
     
    48514853
    48524854        // For ComputedNames, the expression has already been evaluated earlier during evaluation of a ClassExprNode.
    4853         // Here, `m_ident` refers to an integer ID in a class lexical scope, containing the value already converted to an Expression.
     4855        // Here, `m_ident` refers to private symbol ID in a class lexical scope, containing the value already converted to an Expression.
    48544856        Variable var = generator.variable(*m_ident);
    48554857        ASSERT_WITH_MESSAGE(!var.local(), "Computed names must be stored in captured variables");
     
    48594861        RefPtr<RegisterID> privateName = generator.newTemporary();
    48604862        generator.emitGetFromScope(privateName.get(), scope.get(), var, ThrowIfNotFound);
     4863        if (shouldSetFunctionName)
     4864            generator.emitSetFunctionName(value.get(), privateName.get());
    48614865        generator.emitProfileType(privateName.get(), var, m_position, m_position + m_ident->length());
    48624866        generator.emitCallDefineProperty(generator.thisRegister(), privateName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position);
Note: See TracChangeset for help on using the changeset viewer.