Changeset 220053 in webkit


Ignore:
Timestamp:
Jul 30, 2017 9:57:15 PM (7 years ago)
Author:
Yusuke Suzuki
Message:

[WTF] Introduce Private Symbols
https://bugs.webkit.org/show_bug.cgi?id=174935

Reviewed by Darin Adler.

Source/JavaScriptCore:

Use SymbolImpl::isPrivate().

  • builtins/BuiltinNames.cpp:
  • builtins/BuiltinNames.h:

(JSC::BuiltinNames::isPrivateName): Deleted.

  • builtins/BuiltinUtils.h:
  • bytecode/BytecodeIntrinsicRegistry.cpp:

(JSC::BytecodeIntrinsicRegistry::lookup):

  • runtime/CommonIdentifiers.cpp:

(JSC::CommonIdentifiers::isPrivateName): Deleted.

  • runtime/CommonIdentifiers.h:
  • runtime/ExceptionHelpers.cpp:

(JSC::createUndefinedVariableError):

  • runtime/Identifier.h:

(JSC::Identifier::isPrivateName):

  • runtime/IdentifierInlines.h:

(JSC::identifierToSafePublicJSValue):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorAssign):
(JSC::defineProperties):
(JSC::setIntegrityLevel):
(JSC::testIntegrityLevel):
(JSC::ownPropertyKeys):

  • runtime/PrivateName.h:

(JSC::PrivateName::PrivateName):

  • runtime/PropertyName.h:

(JSC::PropertyName::isPrivateName):

  • runtime/ProxyObject.cpp:

(JSC::performProxyGet):
(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::ProxyObject::performHasProperty):
(JSC::ProxyObject::performPut):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::performDefineOwnProperty):

Source/WTF:

Upcoming proposal of class fields[1] requires private fields.
The simple way to implement it is adding a property with a private symbol.
Currently, we have private symbols for internal properties. They are usual
Symbols managed by the hash table. So basically private symbols are statically
created in BuiltinNames. However this new proposal encourages users to create
such private symbols more and more.

So, this patch introduces notion of "Private" into WTF SymbolImpl. This patch
adds PrivateSymbolImpl. This is SymbolImpl with "Private" flag. We do not need
to look up the symbol from the hash table to check whether the given symbol
is a private one.

[1]: https://github.com/tc39/proposal-class-fields

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

(WTF::PrivateSymbolImpl::create):
(WTF::PrivateSymbolImpl::createNullSymbol):

  • wtf/text/SymbolImpl.h:

(WTF::SymbolImpl::isPrivate):
(WTF::SymbolImpl::StaticSymbolImpl::StaticSymbolImpl):
(WTF::SymbolImpl::SymbolImpl):
(WTF::PrivateSymbolImpl::PrivateSymbolImpl):

Tools:

  • TestWebKitAPI/Tests/WTF/StringImpl.cpp:

(TestWebKitAPI::TEST):

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r220047 r220053  
     12017-07-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WTF] Introduce Private Symbols
     4        https://bugs.webkit.org/show_bug.cgi?id=174935
     5
     6        Reviewed by Darin Adler.
     7
     8        Use SymbolImpl::isPrivate().
     9
     10        * builtins/BuiltinNames.cpp:
     11        * builtins/BuiltinNames.h:
     12        (JSC::BuiltinNames::isPrivateName): Deleted.
     13        * builtins/BuiltinUtils.h:
     14        * bytecode/BytecodeIntrinsicRegistry.cpp:
     15        (JSC::BytecodeIntrinsicRegistry::lookup):
     16        * runtime/CommonIdentifiers.cpp:
     17        (JSC::CommonIdentifiers::isPrivateName): Deleted.
     18        * runtime/CommonIdentifiers.h:
     19        * runtime/ExceptionHelpers.cpp:
     20        (JSC::createUndefinedVariableError):
     21        * runtime/Identifier.h:
     22        (JSC::Identifier::isPrivateName):
     23        * runtime/IdentifierInlines.h:
     24        (JSC::identifierToSafePublicJSValue):
     25        * runtime/ObjectConstructor.cpp:
     26        (JSC::objectConstructorAssign):
     27        (JSC::defineProperties):
     28        (JSC::setIntegrityLevel):
     29        (JSC::testIntegrityLevel):
     30        (JSC::ownPropertyKeys):
     31        * runtime/PrivateName.h:
     32        (JSC::PrivateName::PrivateName):
     33        * runtime/PropertyName.h:
     34        (JSC::PropertyName::isPrivateName):
     35        * runtime/ProxyObject.cpp:
     36        (JSC::performProxyGet):
     37        (JSC::ProxyObject::performInternalMethodGetOwnProperty):
     38        (JSC::ProxyObject::performHasProperty):
     39        (JSC::ProxyObject::performPut):
     40        (JSC::ProxyObject::performDelete):
     41        (JSC::ProxyObject::performDefineOwnProperty):
     42
    1432017-07-29  Keith Miller  <keith_miller@apple.com>
    244
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.cpp

    r219731 r220053  
    3939#undef INITIALIZE_BUILTIN_STATIC_SYMBOLS
    4040
    41 #define INITIALIZE_BUILTIN_PRIVATE_NAMES(name) SymbolImpl::StaticSymbolImpl name##PrivateName { "PrivateSymbol." #name };
     41#define INITIALIZE_BUILTIN_PRIVATE_NAMES(name) SymbolImpl::StaticSymbolImpl name##PrivateName { "PrivateSymbol." #name, SymbolImpl::s_flagIsPrivate };
    4242JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_PRIVATE_NAMES)
    4343JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_BUILTIN_PRIVATE_NAMES)
    4444#undef INITIALIZE_BUILTIN_PRIVATE_NAMES
    4545
    46 SymbolImpl::StaticSymbolImpl dollarVMPrivateName { "PrivateSymbol.$vm" };
     46SymbolImpl::StaticSymbolImpl dollarVMPrivateName { "PrivateSymbol.$vm", SymbolImpl::s_flagIsPrivate };
    4747
    4848} // namespace Symbols
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r219731 r220053  
    3232
    3333namespace JSC {
     34
     35#define INITIALIZE_BUILTIN_NAMES_IN_JSC(name) , m_##name(JSC::Identifier::fromString(vm, #name)), m_##name##PrivateName(JSC::Identifier::fromUid(vm, &static_cast<SymbolImpl&>(JSC::Symbols::name##PrivateName)))
     36#define INITIALIZE_BUILTIN_SYMBOLS(name) , m_##name##Symbol(JSC::Identifier::fromUid(vm, &static_cast<SymbolImpl&>(JSC::Symbols::name##Symbol))), m_##name##SymbolPrivateIdentifier(JSC::Identifier::fromString(vm, #name "Symbol"))
     37#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
     38#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
     39    const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
    3440
    3541#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
     
    218224    }
    219225
    220     bool isPrivateName(SymbolImpl& uid) const;
    221     bool isPrivateName(UniquedStringImpl& uid) const;
    222     bool isPrivateName(const Identifier&) const;
    223226    const Identifier* lookUpPrivateName(const Identifier&) const;
    224227    const Identifier& lookUpPublicName(const Identifier&) const;
     
    244247};
    245248
    246 inline bool BuiltinNames::isPrivateName(SymbolImpl& uid) const
    247 {
    248     return m_privateToPublicMap.contains(&uid);
    249 }
    250 
    251 inline bool BuiltinNames::isPrivateName(UniquedStringImpl& uid) const
    252 {
    253     if (!uid.isSymbol())
    254         return false;
    255     return m_privateToPublicMap.contains(&uid);
    256 }
    257 
    258 inline bool BuiltinNames::isPrivateName(const Identifier& ident) const
    259 {
    260     if (ident.isNull())
    261         return false;
    262     return isPrivateName(*ident.impl());
    263 }
    264 
    265249inline const Identifier* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
    266250{
  • trunk/Source/JavaScriptCore/builtins/BuiltinUtils.h

    r219731 r220053  
    3131namespace JSC {
    3232
    33 #define INITIALIZE_BUILTIN_NAMES(name) , m_##name(JSC::Identifier::fromString(vm, #name)), m_##name##PrivateName(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::Description, ASCIILiteral("PrivateSymbol." #name))))
    34 #define INITIALIZE_BUILTIN_NAMES_IN_JSC(name) , m_##name(JSC::Identifier::fromString(vm, #name)), m_##name##PrivateName(JSC::Identifier::fromUid(vm, &static_cast<SymbolImpl&>(JSC::Symbols::name##PrivateName)))
     33#define INITIALIZE_BUILTIN_NAMES(name) , m_##name(JSC::Identifier::fromString(vm, #name)), m_##name##PrivateName(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::PrivateSymbol, ASCIILiteral("PrivateSymbol." #name))))
    3534#define DECLARE_BUILTIN_NAMES(name) const JSC::Identifier m_##name; const JSC::Identifier m_##name##PrivateName;
    3635#define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
    3736    const JSC::Identifier& name##PublicName() const { return m_##name; } \
    3837    const JSC::Identifier& name##PrivateName() const { return m_##name##PrivateName; }
    39 
    40 #define INITIALIZE_BUILTIN_SYMBOLS(name) , m_##name##Symbol(JSC::Identifier::fromUid(vm, &static_cast<SymbolImpl&>(JSC::Symbols::name##Symbol))), m_##name##SymbolPrivateIdentifier(JSC::Identifier::fromString(vm, #name "Symbol"))
    41 #define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
    42 #define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
    43     const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
    4438
    4539class Identifier;
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp

    r218794 r220053  
    7878BytecodeIntrinsicNode::EmitterType BytecodeIntrinsicRegistry::lookup(const Identifier& ident) const
    7979{
    80     if (!m_vm.propertyNames->isPrivateName(ident))
     80    if (!ident.isPrivateName())
    8181        return nullptr;
    8282    auto iterator = m_bytecodeIntrinsicMap.find(ident.impl());
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp

    r202280 r220053  
    5252}
    5353
    54 bool CommonIdentifiers::isPrivateName(SymbolImpl& uid) const
    55 {
    56     return m_builtinNames->isPrivateName(uid);
    57 }
    58 
    59 bool CommonIdentifiers::isPrivateName(UniquedStringImpl& uid) const
    60 {
    61     return m_builtinNames->isPrivateName(uid);
    62 }
    63 
    64 bool CommonIdentifiers::isPrivateName(const Identifier& ident) const
    65 {
    66     return m_builtinNames->isPrivateName(ident);
    67 }
    68 
    6954const Identifier* CommonIdentifiers::lookUpPrivateName(const Identifier& ident) const
    7055{
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r219012 r220053  
    439439#undef JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL
    440440
    441         bool isPrivateName(SymbolImpl& uid) const;
    442         bool isPrivateName(UniquedStringImpl& uid) const;
    443         bool isPrivateName(const Identifier&) const;
    444 
    445441        const Identifier* lookUpPrivateName(const Identifier&) const;
    446442        Identifier lookUpPublicName(const Identifier&) const;
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r218794 r220053  
    8383JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
    8484{
    85     if (exec->propertyNames().isPrivateName(ident)) {
     85    if (ident.isPrivateName()) {
    8686        String message(makeString("Can't find private variable: @", exec->propertyNames().lookUpPublicName(ident).string()));
    8787        return createReferenceError(exec, message);
  • trunk/Source/JavaScriptCore/runtime/Identifier.h

    r218794 r220053  
    140140    bool isEmpty() const { return m_string.isEmpty(); }
    141141    bool isSymbol() const { return !isNull() && impl()->isSymbol(); }
     142    bool isPrivateName() const { return isSymbol() && static_cast<const SymbolImpl*>(impl())->isPrivate(); }
    142143
    143144    friend bool operator==(const Identifier&, const Identifier&);
  • trunk/Source/JavaScriptCore/runtime/IdentifierInlines.h

    r206525 r220053  
    144144inline JSValue identifierToSafePublicJSValue(VM& vm, const Identifier& identifier)
    145145{
    146     if (identifier.isSymbol() && !vm.propertyNames->isPrivateName(identifier))
     146    if (identifier.isSymbol() && !identifier.isPrivateName())
    147147        return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
    148148    return jsString(&vm, identifier.impl());
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r218790 r220053  
    357357            for (unsigned j = 0; j < numProperties; j++) {
    358358                const auto& propertyName = properties[j];
    359                 if (propertyName.isSymbol() && !vm.propertyNames->isPrivateName(propertyName)) {
     359                if (propertyName.isSymbol() && !propertyName.isPrivateName()) {
    360360                    assign(propertyName);
    361361                    RETURN_IF_EXCEPTION(scope, { });
     
    566566    for (size_t i = 0; i < numProperties; i++) {
    567567        Identifier propertyName = propertyNames[i];
    568         if (vm.propertyNames->isPrivateName(propertyName))
     568        if (propertyName.isPrivateName())
    569569            continue;
    570570        object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, descriptors[i], true);
     
    632632    for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
    633633        Identifier propertyName = *iter;
    634         if (vm.propertyNames->isPrivateName(propertyName))
     634        if (propertyName.isPrivateName())
    635635            continue;
    636636
     
    681681    for (PropertyNameArray::const_iterator iter = keys.begin(); iter != end; ++iter) {
    682682        Identifier propertyName = *iter;
    683         if (vm.propertyNames->isPrivateName(propertyName))
     683        if (propertyName.isPrivateName())
    684684            continue;
    685685
     
    869869            const auto& identifier = properties[i];
    870870            ASSERT(identifier.isSymbol());
    871             if (!vm.propertyNames->isPrivateName(identifier)) {
     871            if (!identifier.isPrivateName()) {
    872872                if (filterPropertyIfNeeded(identifier))
    873873                    keys->push(exec, Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl())));
     
    883883        for (size_t i = 0; i < numProperties; i++) {
    884884            const auto& identifier = properties[i];
    885             if (identifier.isSymbol()) {
    886                 if (!vm.propertyNames->isPrivateName(identifier))
    887                     propertySymbols.append(identifier);
    888             } else {
     885            if (identifier.isSymbol() && !identifier.isPrivateName())
     886                propertySymbols.append(identifier);
     887            else {
    889888                if (filterPropertyIfNeeded(identifier))
    890889                    keys->push(exec, jsOwnedString(exec, identifier.string()));
  • trunk/Source/JavaScriptCore/runtime/PrivateName.h

    r218794 r220053  
    4949    }
    5050
     51    enum PrivateSymbolTag { PrivateSymbol };
     52    explicit PrivateName(PrivateSymbolTag, const String& description)
     53        : m_uid(PrivateSymbolImpl::create(*description.impl()))
     54    {
     55    }
     56
    5157    PrivateName(const PrivateName& privateName)
    5258        : m_uid(privateName.m_uid.copyRef())
  • trunk/Source/JavaScriptCore/runtime/PropertyName.h

    r219981 r220053  
    5656    {
    5757        return m_impl && m_impl->isSymbol();
     58    }
     59
     60    bool isPrivateName() const
     61    {
     62        return isSymbol() && static_cast<const SymbolImpl*>(m_impl)->isPrivate();
    5863    }
    5964
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r217108 r220053  
    136136    };
    137137
    138     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
     138    if (propertyName.isPrivateName())
    139139        return performDefaultGet();
    140140
     
    200200    };
    201201
    202     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
     202    if (propertyName.isPrivateName()) {
    203203        scope.release();
    204204        return performDefaultGetOwnProperty();
     
    306306    };
    307307
    308     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
     308    if (propertyName.isPrivateName()) {
    309309        scope.release();
    310310        return performDefaultHasProperty();
     
    408408    }
    409409
    410     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
     410    if (propertyName.isPrivateName()) {
    411411        scope.release();
    412412        return performDefaultPut();
     
    605605    }
    606606
    607     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
     607    if (propertyName.isPrivateName()) {
    608608        scope.release();
    609609        return performDefaultDelete();
     
    796796    };
    797797
    798     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
     798    if (propertyName.isPrivateName())
    799799        return performDefaultDefineOwnProperty();
    800800
  • trunk/Source/WTF/ChangeLog

    r220049 r220053  
     12017-07-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WTF] Introduce Private Symbols
     4        https://bugs.webkit.org/show_bug.cgi?id=174935
     5
     6        Reviewed by Darin Adler.
     7
     8        Upcoming proposal of class fields[1] requires private fields.
     9        The simple way to implement it is adding a property with a private symbol.
     10        Currently, we have private symbols for internal properties. They are usual
     11        Symbols managed by the hash table. So basically private symbols are statically
     12        created in BuiltinNames. However this new proposal encourages users to create
     13        such private symbols more and more.
     14
     15        So, this patch introduces notion of "Private" into WTF SymbolImpl. This patch
     16        adds PrivateSymbolImpl. This is SymbolImpl with "Private" flag. We do not need
     17        to look up the symbol from the hash table to check whether the given symbol
     18        is a private one.
     19
     20        [1]: https://github.com/tc39/proposal-class-fields
     21
     22        * wtf/text/StringImpl.h:
     23        * wtf/text/SymbolImpl.cpp:
     24        (WTF::PrivateSymbolImpl::create):
     25        (WTF::PrivateSymbolImpl::createNullSymbol):
     26        * wtf/text/SymbolImpl.h:
     27        (WTF::SymbolImpl::isPrivate):
     28        (WTF::SymbolImpl::StaticSymbolImpl::StaticSymbolImpl):
     29        (WTF::SymbolImpl::SymbolImpl):
     30        (WTF::PrivateSymbolImpl::PrivateSymbolImpl):
     31
    1322017-07-30  Brady Eidson  <beidson@apple.com>
    233
  • trunk/Source/WTF/wtf/text/StringImpl.h

    r219731 r220053  
    191191    friend class AtomicStringImpl;
    192192    friend class SymbolImpl;
     193    friend class PrivateSymbolImpl;
    193194    friend class RegisteredSymbolImpl;
    194195   
  • trunk/Source/WTF/wtf/text/SymbolImpl.cpp

    r218066 r220053  
    5757}
    5858
     59Ref<PrivateSymbolImpl> PrivateSymbolImpl::create(StringImpl& rep)
     60{
     61    auto* ownerRep = (rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep;
     62    ASSERT(ownerRep->bufferOwnership() != BufferSubstring);
     63    if (rep.is8Bit())
     64        return adoptRef(*new PrivateSymbolImpl(rep.m_data8, rep.length(), *ownerRep));
     65    return adoptRef(*new PrivateSymbolImpl(rep.m_data16, rep.length(), *ownerRep));
     66}
     67
     68Ref<PrivateSymbolImpl> PrivateSymbolImpl::createNullSymbol()
     69{
     70    return adoptRef(*new PrivateSymbolImpl);
     71}
     72
    5973Ref<RegisteredSymbolImpl> RegisteredSymbolImpl::create(StringImpl& rep, SymbolRegistry& symbolRegistry)
    6074{
  • trunk/Source/WTF/wtf/text/SymbolImpl.h

    r219731 r220053  
    3737public:
    3838    using Flags = unsigned;
    39     static constexpr const Flags s_flagDefault = 0u;
    40     static constexpr const Flags s_flagIsNullSymbol = 0b01u;
    41     static constexpr const Flags s_flagIsRegistered = 0b10u;
     39    static constexpr Flags s_flagDefault = 0u;
     40    static constexpr Flags s_flagIsNullSymbol = 0b001u;
     41    static constexpr Flags s_flagIsRegistered = 0b010u;
     42    static constexpr Flags s_flagIsPrivate = 0b100u;
    4243
    4344    unsigned hashForSymbol() const { return m_hashForSymbol; }
    4445    bool isNullSymbol() const { return m_flags & s_flagIsNullSymbol; }
    4546    bool isRegistered() const { return m_flags & s_flagIsRegistered; }
     47    bool isPrivate() const { return m_flags & s_flagIsPrivate; }
    4648
    4749    SymbolRegistry* symbolRegistry() const;
     
    5658    public:
    5759        template<unsigned characterCount>
    58         constexpr StaticSymbolImpl(const char (&characters)[characterCount])
     60        constexpr StaticSymbolImpl(const char (&characters)[characterCount], Flags flags = s_flagDefault)
    5961            : StringImplShape(s_refCountFlagIsStaticString, characterCount - 1, characters,
    6062                s_hashFlag8BitBuffer | s_hashFlagDidReportCost | StringSymbol | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount), ConstructWithConstExpr)
    6163            , m_hashForSymbol(StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount)
     64            , m_flags(flags)
    6265        {
    6366        }
    6467
    6568        template<unsigned characterCount>
    66         constexpr StaticSymbolImpl(const char16_t (&characters)[characterCount])
     69        constexpr StaticSymbolImpl(const char16_t (&characters)[characterCount], Flags flags = s_flagDefault)
    6770            : StringImplShape(s_refCountFlagIsStaticString, characterCount - 1, characters,
    6871                s_hashFlagDidReportCost | StringSymbol | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount), ConstructWithConstExpr)
    6972            , m_hashForSymbol(StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount)
     73            , m_flags(flags)
    7074        {
    7175        }
     
    7882        StringImpl* m_owner { nullptr }; // We do not make StaticSymbolImpl BufferSubstring. Thus we can make this nullptr.
    7983        unsigned m_hashForSymbol;
    80         Flags m_flags { s_flagDefault };
     84        Flags m_flags;
    8185    };
    8286
     
    104108    }
    105109
    106     SymbolImpl()
     110    SymbolImpl(Flags flags = s_flagDefault)
    107111        : UniquedStringImpl(CreateSymbol)
    108112        , m_owner(StringImpl::empty())
    109113        , m_hashForSymbol(nextHashForSymbol())
    110         , m_flags(s_flagIsNullSymbol)
     114        , m_flags(flags | s_flagIsNullSymbol)
    111115    {
    112116        ASSERT(StringImpl::tailOffset<StringImpl*>() == OBJECT_OFFSETOF(SymbolImpl, m_owner));
     
    120124};
    121125static_assert(sizeof(SymbolImpl) == sizeof(SymbolImpl::StaticSymbolImpl), "");
     126
     127class PrivateSymbolImpl : public SymbolImpl {
     128public:
     129    WTF_EXPORT_STRING_API static Ref<PrivateSymbolImpl> createNullSymbol();
     130    WTF_EXPORT_STRING_API static Ref<PrivateSymbolImpl> create(StringImpl& rep);
     131
     132private:
     133    PrivateSymbolImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base)
     134        : SymbolImpl(characters, length, WTFMove(base), s_flagIsPrivate)
     135    {
     136    }
     137
     138    PrivateSymbolImpl(const UChar* characters, unsigned length, Ref<StringImpl>&& base)
     139        : SymbolImpl(characters, length, WTFMove(base), s_flagIsPrivate)
     140    {
     141    }
     142
     143    PrivateSymbolImpl()
     144        : SymbolImpl(s_flagIsPrivate)
     145    {
     146    }
     147};
    122148
    123149class RegisteredSymbolImpl : public SymbolImpl {
     
    194220
    195221using WTF::SymbolImpl;
     222using WTF::PrivateSymbolImpl;
    196223using WTF::RegisteredSymbolImpl;
  • trunk/Tools/ChangeLog

    r220052 r220053  
     12017-07-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WTF] Introduce Private Symbols
     4        https://bugs.webkit.org/show_bug.cgi?id=174935
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/Tests/WTF/StringImpl.cpp:
     9        (TestWebKitAPI::TEST):
     10
    1112017-07-30  Darin Adler  <darin@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp

    r219725 r220053  
    531531    auto reference = SymbolImpl::createNullSymbol();
    532532    ASSERT_TRUE(reference->isSymbol());
     533    ASSERT_FALSE(reference->isPrivate());
    533534    ASSERT_TRUE(reference->isNullSymbol());
    534535    ASSERT_FALSE(reference->isAtomic());
     
    542543    auto reference = SymbolImpl::create(original);
    543544    ASSERT_TRUE(reference->isSymbol());
     545    ASSERT_FALSE(reference->isPrivate());
    544546    ASSERT_FALSE(reference->isNullSymbol());
    545547    ASSERT_FALSE(reference->isAtomic());
     
    552554    auto emptyReference = SymbolImpl::create(empty);
    553555    ASSERT_TRUE(emptyReference->isSymbol());
     556    ASSERT_FALSE(emptyReference->isPrivate());
    554557    ASSERT_FALSE(emptyReference->isNullSymbol());
    555558    ASSERT_FALSE(emptyReference->isAtomic());
     
    560563}
    561564
     565TEST(WTF, StringImplCreatePrivateSymbol)
     566{
     567    auto original = stringFromUTF8("original");
     568    auto reference = PrivateSymbolImpl::create(original);
     569    ASSERT_TRUE(reference->isSymbol());
     570    ASSERT_TRUE(reference->isPrivate());
     571    ASSERT_FALSE(reference->isNullSymbol());
     572    ASSERT_FALSE(reference->isAtomic());
     573    ASSERT_FALSE(original->isSymbol());
     574    ASSERT_FALSE(original->isAtomic());
     575    ASSERT_EQ(original->length(), reference->length());
     576    ASSERT_TRUE(equal(reference.ptr(), "original"));
     577
     578    auto empty = stringFromUTF8("");
     579    auto emptyReference = PrivateSymbolImpl::create(empty);
     580    ASSERT_TRUE(emptyReference->isSymbol());
     581    ASSERT_TRUE(emptyReference->isPrivate());
     582    ASSERT_FALSE(emptyReference->isNullSymbol());
     583    ASSERT_FALSE(emptyReference->isAtomic());
     584    ASSERT_FALSE(empty->isSymbol());
     585    ASSERT_TRUE(empty->isAtomic());
     586    ASSERT_EQ(empty->length(), emptyReference->length());
     587    ASSERT_TRUE(equal(emptyReference.ptr(), ""));
     588}
     589
    562590TEST(WTF, StringImplSymbolToAtomicString)
    563591{
     
    565593    auto reference = SymbolImpl::create(original);
    566594    ASSERT_TRUE(reference->isSymbol());
     595    ASSERT_FALSE(reference->isPrivate());
    567596    ASSERT_FALSE(reference->isAtomic());
    568597
     
    584613    auto reference = SymbolImpl::createNullSymbol();
    585614    ASSERT_TRUE(reference->isSymbol());
     615    ASSERT_FALSE(reference->isPrivate());
    586616    ASSERT_FALSE(reference->isAtomic());
    587617
     
    691721}
    692722
     723static SymbolImpl::StaticSymbolImpl staticSymbol {"Cocoa"};
     724static SymbolImpl::StaticSymbolImpl staticPrivateSymbol {"Cocoa", SymbolImpl::s_flagIsPrivate };
     725
     726TEST(WTF, StaticSymbolImpl)
     727{
     728    auto& symbol = static_cast<SymbolImpl&>(staticSymbol);
     729    ASSERT_TRUE(symbol.isSymbol());
     730    ASSERT_FALSE(symbol.isPrivate());
     731}
     732
     733TEST(WTF, StaticPrivateSymbolImpl)
     734{
     735    auto& symbol = static_cast<SymbolImpl&>(staticPrivateSymbol);
     736    ASSERT_TRUE(symbol.isSymbol());
     737    ASSERT_TRUE(symbol.isPrivate());
     738}
     739
    693740} // namespace TestWebKitAPI
Note: See TracChangeset for help on using the changeset viewer.