Changeset 269801 in webkit
- Timestamp:
- Nov 13, 2020, 2:32:01 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/class-fields-harmony.js (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/parser/Parser.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/parser/ParserArena.cpp (modified) (1 diff)
-
Source/JavaScriptCore/parser/ParserArena.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/CachedTypes.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/VM.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/VM.h (modified) (2 diffs)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/text/SymbolImpl.cpp (modified) (1 diff)
-
Source/WTF/wtf/text/SymbolImpl.h (modified) (1 diff)
-
Source/WTF/wtf/text/SymbolRegistry.cpp (modified) (2 diffs)
-
Source/WTF/wtf/text/SymbolRegistry.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r269791 r269801 1 2020-11-13 Xan López <xan@igalia.com> 2 3 [JSC] Use symbols as identifiers for class fields computed names storage 4 https://bugs.webkit.org/show_bug.cgi?id=216172 5 6 Reviewed by Yusuke Suzuki. 7 8 Use private symbols for the property keys of the class fields with 9 computed names. This is cleaner than using raw numeric identifiers and 10 will be less cumbersome when we add static fields. It also prevents 11 potential collisions if other features want to store data in the class 12 scope. 13 14 * stress/class-fields-harmony.js: new test, make sure 15 setFunctionName works properly with computed fields. 16 1 17 2020-11-13 Yusuke Suzuki <ysuzuki@apple.com> 2 18 -
trunk/JSTests/stress/class-fields-harmony.js
r258071 r269801 907 907 } 908 908 909 // Additional tests by the WebKit project. 910 911 { 912 let x = 0; 913 let y = 'foo'; 914 let z = { name: 'test' }; 915 916 let C = class { 917 [x] = () => { 918 return 2; 919 }; 920 [y] = class {}; 921 [z] = class D {}; 922 } 923 924 let c = new C(); 925 assertSame(c[x](), 2); 926 assertSame(c[x].name, '0'); 927 assertSame(c[y].name, 'foo'); 928 assertSame(c[z].name, 'D'); 929 } -
trunk/Source/JavaScriptCore/ChangeLog
r269790 r269801 1 2020-11-13 Xan López <xan@igalia.com> 2 3 [JSC] Use symbols as identifiers for class fields computed names storage 4 https://bugs.webkit.org/show_bug.cgi?id=216172 5 6 Reviewed by Yusuke Suzuki. 7 8 Use private symbols for the property keys of the class fields with 9 computed names. This is cleaner than using raw numeric identifiers and 10 will be less cumbersome when we add static fields. It also prevents 11 potential collisions if other features want to store data in the class 12 scope. 13 14 * bytecompiler/NodesCodegen.cpp: 15 (JSC::PropertyListNode::emitSaveComputedFieldName): adapt a comment. 16 * parser/Parser.cpp: 17 (JSC::Parser<LexerType>::parseClass): use private identifiers for computed fields property keys. 18 (JSC::Parser<LexerType>::parseInstanceFieldInitializerSourceElements): ditto. 19 * parser/ParserArena.cpp: 20 (JSC::IdentifierArena::makePrivateIdentifier): method to create a private identifier. 21 * parser/ParserArena.h: 22 * runtime/CachedTypes.cpp: 23 (JSC::CachedUniquedStringImplBase::encode): consider registered symbols, they are used by the parser now. 24 (JSC::CachedUniquedStringImplBase::decode const): ditto. 25 * runtime/VM.cpp: 26 (JSC::VM::VM): 27 * runtime/VM.h: 28 (JSC::VM::privateSymbolRegistry): create a private symbol registry too. 29 1 30 2020-11-13 Sergey Rubanov <chi187@gmail.com> 2 31 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r268489 r269801 803 803 RefPtr<RegisterID> propertyExpr; 804 804 805 // The 'name' refers to a synthetic numeric variable name in the private namescope, 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. 806 806 const Identifier& description = *node.name(); 807 807 Variable var = generator.variable(description); … … 4818 4818 { 4819 4819 RefPtr<RegisterID> value = generator.newTemporary(); 4820 bool shouldSetFunctionName = false; 4820 4821 4821 4822 if (!m_assign) … … 4823 4824 else { 4824 4825 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) 4826 4828 generator.emitSetFunctionName(value.get(), *m_ident); 4827 4829 } … … 4851 4853 4852 4854 // For ComputedNames, the expression has already been evaluated earlier during evaluation of a ClassExprNode. 4853 // Here, `m_ident` refers to an integerID 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. 4854 4856 Variable var = generator.variable(*m_ident); 4855 4857 ASSERT_WITH_MESSAGE(!var.local(), "Computed names must be stored in captured variables"); … … 4859 4861 RefPtr<RegisterID> privateName = generator.newTemporary(); 4860 4862 generator.emitGetFromScope(privateName.get(), scope.get(), var, ThrowIfNotFound); 4863 if (shouldSetFunctionName) 4864 generator.emitSetFunctionName(value.get(), privateName.get()); 4861 4865 generator.emitProfileType(privateName.get(), var, m_position, m_position + m_ident->length()); 4862 4866 generator.emitCallDefineProperty(generator.thisRegister(), privateName.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable | BytecodeGenerator::PropertyEnumerable, m_position); -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r268688 r269801 2838 2838 } 2839 2839 2840 static constexpr ASCIILiteral instanceComputedNamePrefix { "instanceComputedName"_s }; 2841 2840 2842 template <typename LexerType> 2841 2843 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionNameRequirements requirements, ParserClassInfo<TreeBuilder>& info) … … 2997 2999 2998 3000 if (computedPropertyName) { 2999 ident = &m_parserArena.identifierArena().make NumericIdentifier(m_vm, numComputedFields++);3001 ident = &m_parserArena.identifierArena().makePrivateIdentifier(m_vm, instanceComputedNamePrefix, numComputedFields++); 3000 3002 DeclarationResultMask declarationResult = classScope->declareLexicalVariable(ident, true); 3001 3003 ASSERT_UNUSED(declarationResult, declarationResult == DeclarationResult::Valid); … … 3078 3080 JSTokenLocation fieldLocation = tokenLocation(); 3079 3081 const Identifier* ident = nullptr; 3080 TreeExpression computedPropertyName = 0;3081 3082 DefineFieldNode::Type type = DefineFieldNode::Type::Name; 3082 3083 switch (m_token.m_type) { … … 3102 3103 next(); 3103 3104 break; 3104 case OPENBRACKET: 3105 case OPENBRACKET: { 3105 3106 next(); 3106 computedPropertyName = parseAssignmentExpression(context);3107 TreeExpression computedPropertyName = parseAssignmentExpression(context); 3107 3108 failIfFalse(computedPropertyName, "Cannot parse computed property name"); 3108 3109 handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name"); 3109 ident = &m_parserArena.identifierArena().make NumericIdentifier(m_vm, numComputedFields++);3110 ident = &m_parserArena.identifierArena().makePrivateIdentifier(m_vm, instanceComputedNamePrefix, numComputedFields++); 3110 3111 type = DefineFieldNode::Type::ComputedName; 3111 3112 break; 3113 } 3112 3114 default: 3113 3115 if (m_token.m_type & KeywordTokenFlag) -
trunk/Source/JavaScriptCore/parser/ParserArena.cpp
r262342 r269801 108 108 } 109 109 110 const Identifier& IdentifierArena::makePrivateIdentifier(VM& vm, ASCIILiteral prefix, unsigned identifier) 111 { 112 String symbolName = makeString(prefix, identifier); 113 auto symbol = vm.privateSymbolRegistry().symbolForKey(symbolName); 114 m_identifiers.append(Identifier::fromUid(symbol)); 115 return m_identifiers.last(); 110 116 } 117 118 } -
trunk/Source/JavaScriptCore/parser/ParserArena.h
r261464 r269801 53 53 const Identifier& makeBigIntDecimalIdentifier(VM&, const Identifier&, uint8_t radix); 54 54 const Identifier& makeNumericIdentifier(VM&, double number); 55 const Identifier& makePrivateIdentifier(VM&, ASCIILiteral, unsigned); 55 56 56 57 public: -
trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp
r269115 r269801 703 703 m_isAtomic = string.isAtom(); 704 704 m_isSymbol = string.isSymbol(); 705 m_isRegistered = false; 705 706 m_isWellKnownSymbol = false; 707 m_isPrivate = false; 706 708 RefPtr<StringImpl> impl = const_cast<StringImpl*>(&string); 707 709 708 710 if (m_isSymbol) { 709 711 SymbolImpl* symbol = static_cast<SymbolImpl*>(impl.get()); 712 m_isRegistered = symbol->isRegistered(); 713 m_isPrivate = symbol->isPrivate(); 710 714 if (!symbol->isNullSymbol()) { 711 715 // We have special handling for well-known symbols. 712 if (! symbol->isPrivate()) {716 if (!m_isPrivate) { 713 717 m_isWellKnownSymbol = true; 714 718 impl = symbol->substring(strlen("Symbol.")); … … 743 747 744 748 SymbolImpl* symbol; 745 if (m_isWellKnownSymbol) 746 symbol = decoder.vm().propertyNames->builtinNames().lookUpWellKnownSymbol(buffer, m_length); 749 VM& vm = decoder.vm(); 750 if (m_isRegistered) { 751 String str(buffer, m_length); 752 if (m_isPrivate) 753 symbol = static_cast<SymbolImpl*>(&vm.privateSymbolRegistry().symbolForKey(str).leakRef()); 754 else 755 symbol = static_cast<SymbolImpl*>(&vm.symbolRegistry().symbolForKey(str).leakRef()); 756 } else if (m_isWellKnownSymbol) 757 symbol = vm.propertyNames->builtinNames().lookUpWellKnownSymbol(buffer, m_length); 747 758 else 748 symbol = decoder.vm().propertyNames->builtinNames().lookUpPrivateName(buffer, m_length);759 symbol = vm.propertyNames->builtinNames().lookUpPrivateName(buffer, m_length); 749 760 RELEASE_ASSERT(symbol); 750 761 String str = symbol; … … 774 785 bool m_isWellKnownSymbol : 1; 775 786 bool m_isAtomic : 1; 787 bool m_isRegistered : 1; 788 bool m_isPrivate : 1; 776 789 unsigned m_length; 777 790 }; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r269320 r269801 383 383 , deferredWorkTimer(DeferredWorkTimer::create(*this)) 384 384 , m_atomStringTable(vmType == Default ? Thread::current().atomStringTable() : new AtomStringTable) 385 , m_privateSymbolRegistry(WTF::SymbolRegistry::Type::PrivateSymbol) 385 386 , propertyNames(nullptr) 386 387 , emptyList(new ArgList) -
trunk/Source/JavaScriptCore/runtime/VM.h
r269576 r269801 715 715 AtomStringTable* m_atomStringTable; 716 716 WTF::SymbolRegistry m_symbolRegistry; 717 WTF::SymbolRegistry m_privateSymbolRegistry; 717 718 CommonIdentifiers* propertyNames; 718 719 const ArgList* emptyList; … … 726 727 AtomStringTable* atomStringTable() const { return m_atomStringTable; } 727 728 WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; } 729 WTF::SymbolRegistry& privateSymbolRegistry() { return m_privateSymbolRegistry; } 728 730 729 731 Strong<JSBigInt> heapBigIntConstantOne; -
trunk/Source/WTF/ChangeLog
r269785 r269801 1 2020-11-13 Xan López <xan@igalia.com> 2 3 [JSC] Use symbols as identifiers for class fields computed names storage 4 https://bugs.webkit.org/show_bug.cgi?id=216172 5 6 Reviewed by Yusuke Suzuki. 7 8 Use private symbols for the property keys of the class fields with 9 computed names. This is cleaner than using raw numeric identifiers and 10 will be less cumbersome when we add static fields. It also prevents 11 potential collisions if other features want to store data in the class 12 scope. 13 14 * wtf/text/SymbolImpl.cpp: 15 (WTF::RegisteredSymbolImpl::createPrivate): add a method to create a registered private symbol from a string key. 16 * wtf/text/SymbolImpl.h: 17 * wtf/text/SymbolRegistry.cpp: 18 (WTF::SymbolRegistry::symbolForKey): consider that we can hold private symbols now too. 19 * wtf/text/SymbolRegistry.h: 20 (WTF::SymbolRegistry::SymbolRegistry): new enum type for public/private symbols. 21 1 22 2020-11-12 Darin Adler <darin@apple.com> 2 23 -
trunk/Source/WTF/wtf/text/SymbolImpl.cpp
r237099 r269801 80 80 } 81 81 82 Ref<RegisteredSymbolImpl> RegisteredSymbolImpl::createPrivate(StringImpl& rep, SymbolRegistry& symbolRegistry) 83 { 84 auto* ownerRep = (rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep; 85 ASSERT(ownerRep->bufferOwnership() != BufferSubstring); 86 if (rep.is8Bit()) 87 return adoptRef(*new RegisteredSymbolImpl(rep.m_data8, rep.length(), *ownerRep, symbolRegistry, s_flagIsRegistered | s_flagIsPrivate)); 88 return adoptRef(*new RegisteredSymbolImpl(rep.m_data16, rep.length(), *ownerRep, symbolRegistry, s_flagIsRegistered | s_flagIsPrivate)); 89 } 90 82 91 } // namespace WTF -
trunk/Source/WTF/wtf/text/SymbolImpl.h
r257201 r269801 157 157 158 158 static Ref<RegisteredSymbolImpl> create(StringImpl& rep, SymbolRegistry&); 159 160 RegisteredSymbolImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base, SymbolRegistry& registry) 161 : SymbolImpl(characters, length, WTFMove(base), s_flagIsRegistered) 159 static Ref<RegisteredSymbolImpl> createPrivate(StringImpl& rep, SymbolRegistry&); 160 161 RegisteredSymbolImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base, SymbolRegistry& registry, Flags flags = s_flagIsRegistered) 162 : SymbolImpl(characters, length, WTFMove(base), flags) 162 163 , m_symbolRegistry(®istry) 163 164 { 164 165 } 165 166 166 RegisteredSymbolImpl(const UChar* characters, unsigned length, Ref<StringImpl>&& base, SymbolRegistry& registry )167 : SymbolImpl(characters, length, WTFMove(base), s_flagIsRegistered)167 RegisteredSymbolImpl(const UChar* characters, unsigned length, Ref<StringImpl>&& base, SymbolRegistry& registry, Flags flags = s_flagIsRegistered) 168 : SymbolImpl(characters, length, WTFMove(base), flags) 168 169 , m_symbolRegistry(®istry) 169 170 { -
trunk/Source/WTF/wtf/text/SymbolRegistry.cpp
r237099 r269801 29 29 namespace WTF { 30 30 31 SymbolRegistry::SymbolRegistry(Type type) 32 : m_symbolType(type) 33 { 34 } 35 31 36 SymbolRegistry::~SymbolRegistry() 32 37 { … … 45 50 } 46 51 47 auto symbol = RegisteredSymbolImpl::create(*rep.impl(), *this); 48 *addResult.iterator = SymbolRegistryKey(&symbol.get()); 49 return symbol; 52 RefPtr<RegisteredSymbolImpl> symbol; 53 if (m_symbolType == Type::PrivateSymbol) 54 symbol = RegisteredSymbolImpl::createPrivate(*rep.impl(), *this); 55 else 56 symbol = RegisteredSymbolImpl::create(*rep.impl(), *this); 57 58 *addResult.iterator = SymbolRegistryKey(symbol.get()); 59 return symbol.releaseNonNull(); 50 60 } 51 61 -
trunk/Source/WTF/wtf/text/SymbolRegistry.h
r264488 r269801 79 79 WTF_MAKE_NONCOPYABLE(SymbolRegistry); 80 80 public: 81 SymbolRegistry() = default; 81 enum class Type : uint8_t { PublicSymbol, PrivateSymbol }; 82 WTF_EXPORT_PRIVATE SymbolRegistry(Type = Type::PublicSymbol); 82 83 WTF_EXPORT_PRIVATE ~SymbolRegistry(); 83 84 … … 88 89 private: 89 90 HashSet<SymbolRegistryKey> m_table; 91 Type m_symbolType; 90 92 }; 91 93
Note:
See TracChangeset
for help on using the changeset viewer.