Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (220052 => 220053)
--- trunk/Source/_javascript_Core/ChangeLog 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-07-31 04:57:15 UTC (rev 220053)
@@ -1,3 +1,45 @@
+2017-07-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Introduce Private Symbols
+ https://bugs.webkit.org/show_bug.cgi?id=174935
+
+ Reviewed by Darin Adler.
+
+ 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):
+
2017-07-29 Keith Miller <[email protected]>
LLInt offsets extractor should be able to handle C++ constexprs
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -38,12 +38,12 @@
JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_BUILTIN_STATIC_SYMBOLS)
#undef INITIALIZE_BUILTIN_STATIC_SYMBOLS
-#define INITIALIZE_BUILTIN_PRIVATE_NAMES(name) SymbolImpl::StaticSymbolImpl name##PrivateName { "PrivateSymbol." #name };
+#define INITIALIZE_BUILTIN_PRIVATE_NAMES(name) SymbolImpl::StaticSymbolImpl name##PrivateName { "PrivateSymbol." #name, SymbolImpl::s_flagIsPrivate };
JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_PRIVATE_NAMES)
JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_BUILTIN_PRIVATE_NAMES)
#undef INITIALIZE_BUILTIN_PRIVATE_NAMES
-SymbolImpl::StaticSymbolImpl dollarVMPrivateName { "PrivateSymbol.$vm" };
+SymbolImpl::StaticSymbolImpl dollarVMPrivateName { "PrivateSymbol.$vm", SymbolImpl::s_flagIsPrivate };
} // namespace Symbols
} // namespace JSC
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (220052 => 220053)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -32,6 +32,12 @@
namespace JSC {
+#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)))
+#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"))
+#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
+#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
+ const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
+
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(macro) \
JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(macro) \
@@ -217,9 +223,6 @@
m_publicToPrivateMap.add(m_dollarVMName.impl(), &m_dollarVMPrivateName);
}
- bool isPrivateName(SymbolImpl& uid) const;
- bool isPrivateName(UniquedStringImpl& uid) const;
- bool isPrivateName(const Identifier&) const;
const Identifier* lookUpPrivateName(const Identifier&) const;
const Identifier& lookUpPublicName(const Identifier&) const;
@@ -243,25 +246,6 @@
BuiltinNamesMap m_privateToPublicMap;
};
-inline bool BuiltinNames::isPrivateName(SymbolImpl& uid) const
-{
- return m_privateToPublicMap.contains(&uid);
-}
-
-inline bool BuiltinNames::isPrivateName(UniquedStringImpl& uid) const
-{
- if (!uid.isSymbol())
- return false;
- return m_privateToPublicMap.contains(&uid);
-}
-
-inline bool BuiltinNames::isPrivateName(const Identifier& ident) const
-{
- if (ident.isNull())
- return false;
- return isPrivateName(*ident.impl());
-}
-
inline const Identifier* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
{
auto iter = m_publicToPrivateMap.find(ident.impl());
Modified: trunk/Source/_javascript_Core/builtins/BuiltinUtils.h (220052 => 220053)
--- trunk/Source/_javascript_Core/builtins/BuiltinUtils.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/builtins/BuiltinUtils.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -30,18 +30,12 @@
namespace JSC {
-#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))))
-#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)))
+#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))))
#define DECLARE_BUILTIN_NAMES(name) const JSC::Identifier m_##name; const JSC::Identifier m_##name##PrivateName;
#define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
const JSC::Identifier& name##PublicName() const { return m_##name; } \
const JSC::Identifier& name##PrivateName() const { return m_##name##PrivateName; }
-#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"))
-#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
-#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
- const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
-
class Identifier;
class SourceCode;
class UnlinkedFunctionExecutable;
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -77,7 +77,7 @@
BytecodeIntrinsicNode::EmitterType BytecodeIntrinsicRegistry::lookup(const Identifier& ident) const
{
- if (!m_vm.propertyNames->isPrivateName(ident))
+ if (!ident.isPrivateName())
return nullptr;
auto iterator = m_bytecodeIntrinsicMap.find(ident.impl());
if (iterator == m_bytecodeIntrinsicMap.end())
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -51,21 +51,6 @@
{
}
-bool CommonIdentifiers::isPrivateName(SymbolImpl& uid) const
-{
- return m_builtinNames->isPrivateName(uid);
-}
-
-bool CommonIdentifiers::isPrivateName(UniquedStringImpl& uid) const
-{
- return m_builtinNames->isPrivateName(uid);
-}
-
-bool CommonIdentifiers::isPrivateName(const Identifier& ident) const
-{
- return m_builtinNames->isPrivateName(ident);
-}
-
const Identifier* CommonIdentifiers::lookUpPrivateName(const Identifier& ident) const
{
return m_builtinNames->lookUpPrivateName(ident);
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -438,10 +438,6 @@
JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL)
#undef JSC_IDENTIFIER_DECLARE_PRIVATE_WELL_KNOWN_SYMBOL_GLOBAL
- bool isPrivateName(SymbolImpl& uid) const;
- bool isPrivateName(UniquedStringImpl& uid) const;
- bool isPrivateName(const Identifier&) const;
-
const Identifier* lookUpPrivateName(const Identifier&) const;
Identifier lookUpPublicName(const Identifier&) const;
Modified: trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/ExceptionHelpers.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -82,7 +82,7 @@
JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
{
- if (exec->propertyNames().isPrivateName(ident)) {
+ if (ident.isPrivateName()) {
String message(makeString("Can't find private variable: @", exec->propertyNames().lookUpPublicName(ident).string()));
return createReferenceError(exec, message);
}
Modified: trunk/Source/_javascript_Core/runtime/Identifier.h (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/Identifier.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/Identifier.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -139,6 +139,7 @@
bool isNull() const { return m_string.isNull(); }
bool isEmpty() const { return m_string.isEmpty(); }
bool isSymbol() const { return !isNull() && impl()->isSymbol(); }
+ bool isPrivateName() const { return isSymbol() && static_cast<const SymbolImpl*>(impl())->isPrivate(); }
friend bool operator==(const Identifier&, const Identifier&);
friend bool operator!=(const Identifier&, const Identifier&);
Modified: trunk/Source/_javascript_Core/runtime/IdentifierInlines.h (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/IdentifierInlines.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/IdentifierInlines.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -143,7 +143,7 @@
inline JSValue identifierToSafePublicJSValue(VM& vm, const Identifier& identifier)
{
- if (identifier.isSymbol() && !vm.propertyNames->isPrivateName(identifier))
+ if (identifier.isSymbol() && !identifier.isPrivateName())
return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
return jsString(&vm, identifier.impl());
}
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -356,7 +356,7 @@
if (foundSymbol) {
for (unsigned j = 0; j < numProperties; j++) {
const auto& propertyName = properties[j];
- if (propertyName.isSymbol() && !vm.propertyNames->isPrivateName(propertyName)) {
+ if (propertyName.isSymbol() && !propertyName.isPrivateName()) {
assign(propertyName);
RETURN_IF_EXCEPTION(scope, { });
}
@@ -565,7 +565,7 @@
}
for (size_t i = 0; i < numProperties; i++) {
Identifier propertyName = propertyNames[i];
- if (vm.propertyNames->isPrivateName(propertyName))
+ if (propertyName.isPrivateName())
continue;
object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, descriptors[i], true);
RETURN_IF_EXCEPTION(scope, { });
@@ -631,7 +631,7 @@
PropertyNameArray::const_iterator end = properties.end();
for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
Identifier propertyName = *iter;
- if (vm.propertyNames->isPrivateName(propertyName))
+ if (propertyName.isPrivateName())
continue;
PropertyDescriptor desc;
@@ -680,7 +680,7 @@
PropertyNameArray::const_iterator end = keys.end();
for (PropertyNameArray::const_iterator iter = keys.begin(); iter != end; ++iter) {
Identifier propertyName = *iter;
- if (vm.propertyNames->isPrivateName(propertyName))
+ if (propertyName.isPrivateName())
continue;
// a. Let currentDesc be ? O.[[GetOwnProperty]](k)
@@ -868,7 +868,7 @@
for (size_t i = 0; i < numProperties; i++) {
const auto& identifier = properties[i];
ASSERT(identifier.isSymbol());
- if (!vm.propertyNames->isPrivateName(identifier)) {
+ if (!identifier.isPrivateName()) {
if (filterPropertyIfNeeded(identifier))
keys->push(exec, Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl())));
RETURN_IF_EXCEPTION(scope, nullptr);
@@ -882,10 +882,9 @@
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++) {
const auto& identifier = properties[i];
- if (identifier.isSymbol()) {
- if (!vm.propertyNames->isPrivateName(identifier))
- propertySymbols.append(identifier);
- } else {
+ if (identifier.isSymbol() && !identifier.isPrivateName())
+ propertySymbols.append(identifier);
+ else {
if (filterPropertyIfNeeded(identifier))
keys->push(exec, jsOwnedString(exec, identifier.string()));
RETURN_IF_EXCEPTION(scope, nullptr);
Modified: trunk/Source/_javascript_Core/runtime/PrivateName.h (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/PrivateName.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/PrivateName.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -48,6 +48,12 @@
{
}
+ enum PrivateSymbolTag { PrivateSymbol };
+ explicit PrivateName(PrivateSymbolTag, const String& description)
+ : m_uid(PrivateSymbolImpl::create(*description.impl()))
+ {
+ }
+
PrivateName(const PrivateName& privateName)
: m_uid(privateName.m_uid.copyRef())
{
Modified: trunk/Source/_javascript_Core/runtime/PropertyName.h (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/PropertyName.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/PropertyName.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -57,6 +57,11 @@
return m_impl && m_impl->isSymbol();
}
+ bool isPrivateName() const
+ {
+ return isSymbol() && static_cast<const SymbolImpl*>(m_impl)->isPrivate();
+ }
+
UniquedStringImpl* uid() const
{
return m_impl;
Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (220052 => 220053)
--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -135,7 +135,7 @@
return jsUndefined();
};
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
+ if (propertyName.isPrivateName())
return performDefaultGet();
JSValue handlerValue = proxyObject->handler();
@@ -199,7 +199,7 @@
return target->methodTable(vm)->getOwnPropertySlot(target, exec, propertyName, slot);
};
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
+ if (propertyName.isPrivateName()) {
scope.release();
return performDefaultGetOwnProperty();
}
@@ -305,7 +305,7 @@
return target->methodTable(vm)->getOwnPropertySlot(target, exec, propertyName, slot);
};
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
+ if (propertyName.isPrivateName()) {
scope.release();
return performDefaultHasProperty();
}
@@ -407,7 +407,7 @@
return false;
}
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
+ if (propertyName.isPrivateName()) {
scope.release();
return performDefaultPut();
}
@@ -604,7 +604,7 @@
return false;
}
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid()))) {
+ if (propertyName.isPrivateName()) {
scope.release();
return performDefaultDelete();
}
@@ -795,7 +795,7 @@
return target->methodTable(vm)->defineOwnProperty(target, exec, propertyName, descriptor, shouldThrow);
};
- if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
+ if (propertyName.isPrivateName())
return performDefaultDefineOwnProperty();
JSValue handlerValue = this->handler();
Modified: trunk/Source/WTF/ChangeLog (220052 => 220053)
--- trunk/Source/WTF/ChangeLog 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/WTF/ChangeLog 2017-07-31 04:57:15 UTC (rev 220053)
@@ -1,3 +1,34 @@
+2017-07-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Introduce Private Symbols
+ https://bugs.webkit.org/show_bug.cgi?id=174935
+
+ Reviewed by Darin Adler.
+
+ 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):
+
2017-07-30 Brady Eidson <[email protected]>
Add URLSchemeHandler API tests that verify the lack of URLSchemeTask object leaks.
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (220052 => 220053)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -190,6 +190,7 @@
friend class JSC::LLIntOffsetsExtractor;
friend class AtomicStringImpl;
friend class SymbolImpl;
+ friend class PrivateSymbolImpl;
friend class RegisteredSymbolImpl;
private:
Modified: trunk/Source/WTF/wtf/text/SymbolImpl.cpp (220052 => 220053)
--- trunk/Source/WTF/wtf/text/SymbolImpl.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/WTF/wtf/text/SymbolImpl.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -56,6 +56,20 @@
return adoptRef(*new SymbolImpl);
}
+Ref<PrivateSymbolImpl> PrivateSymbolImpl::create(StringImpl& rep)
+{
+ auto* ownerRep = (rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep;
+ ASSERT(ownerRep->bufferOwnership() != BufferSubstring);
+ if (rep.is8Bit())
+ return adoptRef(*new PrivateSymbolImpl(rep.m_data8, rep.length(), *ownerRep));
+ return adoptRef(*new PrivateSymbolImpl(rep.m_data16, rep.length(), *ownerRep));
+}
+
+Ref<PrivateSymbolImpl> PrivateSymbolImpl::createNullSymbol()
+{
+ return adoptRef(*new PrivateSymbolImpl);
+}
+
Ref<RegisteredSymbolImpl> RegisteredSymbolImpl::create(StringImpl& rep, SymbolRegistry& symbolRegistry)
{
auto* ownerRep = (rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep;
Modified: trunk/Source/WTF/wtf/text/SymbolImpl.h (220052 => 220053)
--- trunk/Source/WTF/wtf/text/SymbolImpl.h 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Source/WTF/wtf/text/SymbolImpl.h 2017-07-31 04:57:15 UTC (rev 220053)
@@ -36,13 +36,15 @@
class SymbolImpl : public UniquedStringImpl {
public:
using Flags = unsigned;
- static constexpr const Flags s_flagDefault = 0u;
- static constexpr const Flags s_flagIsNullSymbol = 0b01u;
- static constexpr const Flags s_flagIsRegistered = 0b10u;
+ static constexpr Flags s_flagDefault = 0u;
+ static constexpr Flags s_flagIsNullSymbol = 0b001u;
+ static constexpr Flags s_flagIsRegistered = 0b010u;
+ static constexpr Flags s_flagIsPrivate = 0b100u;
unsigned hashForSymbol() const { return m_hashForSymbol; }
bool isNullSymbol() const { return m_flags & s_flagIsNullSymbol; }
bool isRegistered() const { return m_flags & s_flagIsRegistered; }
+ bool isPrivate() const { return m_flags & s_flagIsPrivate; }
SymbolRegistry* symbolRegistry() const;
@@ -55,18 +57,20 @@
WTF_MAKE_NONCOPYABLE(StaticSymbolImpl);
public:
template<unsigned characterCount>
- constexpr StaticSymbolImpl(const char (&characters)[characterCount])
+ constexpr StaticSymbolImpl(const char (&characters)[characterCount], Flags flags = s_flagDefault)
: StringImplShape(s_refCountFlagIsStaticString, characterCount - 1, characters,
s_hashFlag8BitBuffer | s_hashFlagDidReportCost | StringSymbol | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount), ConstructWithConstExpr)
, m_hashForSymbol(StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount)
+ , m_flags(flags)
{
}
template<unsigned characterCount>
- constexpr StaticSymbolImpl(const char16_t (&characters)[characterCount])
+ constexpr StaticSymbolImpl(const char16_t (&characters)[characterCount], Flags flags = s_flagDefault)
: StringImplShape(s_refCountFlagIsStaticString, characterCount - 1, characters,
s_hashFlagDidReportCost | StringSymbol | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount), ConstructWithConstExpr)
, m_hashForSymbol(StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount)
+ , m_flags(flags)
{
}
@@ -77,7 +81,7 @@
StringImpl* m_owner { nullptr }; // We do not make StaticSymbolImpl BufferSubstring. Thus we can make this nullptr.
unsigned m_hashForSymbol;
- Flags m_flags { s_flagDefault };
+ Flags m_flags;
};
protected:
@@ -103,11 +107,11 @@
ASSERT(StringImpl::tailOffset<StringImpl*>() == OBJECT_OFFSETOF(SymbolImpl, m_owner));
}
- SymbolImpl()
+ SymbolImpl(Flags flags = s_flagDefault)
: UniquedStringImpl(CreateSymbol)
, m_owner(StringImpl::empty())
, m_hashForSymbol(nextHashForSymbol())
- , m_flags(s_flagIsNullSymbol)
+ , m_flags(flags | s_flagIsNullSymbol)
{
ASSERT(StringImpl::tailOffset<StringImpl*>() == OBJECT_OFFSETOF(SymbolImpl, m_owner));
}
@@ -120,6 +124,28 @@
};
static_assert(sizeof(SymbolImpl) == sizeof(SymbolImpl::StaticSymbolImpl), "");
+class PrivateSymbolImpl : public SymbolImpl {
+public:
+ WTF_EXPORT_STRING_API static Ref<PrivateSymbolImpl> createNullSymbol();
+ WTF_EXPORT_STRING_API static Ref<PrivateSymbolImpl> create(StringImpl& rep);
+
+private:
+ PrivateSymbolImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base)
+ : SymbolImpl(characters, length, WTFMove(base), s_flagIsPrivate)
+ {
+ }
+
+ PrivateSymbolImpl(const UChar* characters, unsigned length, Ref<StringImpl>&& base)
+ : SymbolImpl(characters, length, WTFMove(base), s_flagIsPrivate)
+ {
+ }
+
+ PrivateSymbolImpl()
+ : SymbolImpl(s_flagIsPrivate)
+ {
+ }
+};
+
class RegisteredSymbolImpl : public SymbolImpl {
private:
friend class StringImpl;
@@ -193,4 +219,5 @@
} // namespace WTF
using WTF::SymbolImpl;
+using WTF::PrivateSymbolImpl;
using WTF::RegisteredSymbolImpl;
Modified: trunk/Tools/ChangeLog (220052 => 220053)
--- trunk/Tools/ChangeLog 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Tools/ChangeLog 2017-07-31 04:57:15 UTC (rev 220053)
@@ -1,3 +1,13 @@
+2017-07-30 Yusuke Suzuki <[email protected]>
+
+ [WTF] Introduce Private Symbols
+ https://bugs.webkit.org/show_bug.cgi?id=174935
+
+ Reviewed by Darin Adler.
+
+ * TestWebKitAPI/Tests/WTF/StringImpl.cpp:
+ (TestWebKitAPI::TEST):
+
2017-07-30 Darin Adler <[email protected]>
Remove code in HTMLObjectElement attribute parsing that forces style resolution and layout
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp (220052 => 220053)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp 2017-07-30 21:44:01 UTC (rev 220052)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp 2017-07-31 04:57:15 UTC (rev 220053)
@@ -530,6 +530,7 @@
{
auto reference = SymbolImpl::createNullSymbol();
ASSERT_TRUE(reference->isSymbol());
+ ASSERT_FALSE(reference->isPrivate());
ASSERT_TRUE(reference->isNullSymbol());
ASSERT_FALSE(reference->isAtomic());
ASSERT_EQ(0u, reference->length());
@@ -541,6 +542,7 @@
auto original = stringFromUTF8("original");
auto reference = SymbolImpl::create(original);
ASSERT_TRUE(reference->isSymbol());
+ ASSERT_FALSE(reference->isPrivate());
ASSERT_FALSE(reference->isNullSymbol());
ASSERT_FALSE(reference->isAtomic());
ASSERT_FALSE(original->isSymbol());
@@ -551,6 +553,7 @@
auto empty = stringFromUTF8("");
auto emptyReference = SymbolImpl::create(empty);
ASSERT_TRUE(emptyReference->isSymbol());
+ ASSERT_FALSE(emptyReference->isPrivate());
ASSERT_FALSE(emptyReference->isNullSymbol());
ASSERT_FALSE(emptyReference->isAtomic());
ASSERT_FALSE(empty->isSymbol());
@@ -559,11 +562,37 @@
ASSERT_TRUE(equal(emptyReference.ptr(), ""));
}
+TEST(WTF, StringImplCreatePrivateSymbol)
+{
+ auto original = stringFromUTF8("original");
+ auto reference = PrivateSymbolImpl::create(original);
+ ASSERT_TRUE(reference->isSymbol());
+ ASSERT_TRUE(reference->isPrivate());
+ ASSERT_FALSE(reference->isNullSymbol());
+ ASSERT_FALSE(reference->isAtomic());
+ ASSERT_FALSE(original->isSymbol());
+ ASSERT_FALSE(original->isAtomic());
+ ASSERT_EQ(original->length(), reference->length());
+ ASSERT_TRUE(equal(reference.ptr(), "original"));
+
+ auto empty = stringFromUTF8("");
+ auto emptyReference = PrivateSymbolImpl::create(empty);
+ ASSERT_TRUE(emptyReference->isSymbol());
+ ASSERT_TRUE(emptyReference->isPrivate());
+ ASSERT_FALSE(emptyReference->isNullSymbol());
+ ASSERT_FALSE(emptyReference->isAtomic());
+ ASSERT_FALSE(empty->isSymbol());
+ ASSERT_TRUE(empty->isAtomic());
+ ASSERT_EQ(empty->length(), emptyReference->length());
+ ASSERT_TRUE(equal(emptyReference.ptr(), ""));
+}
+
TEST(WTF, StringImplSymbolToAtomicString)
{
auto original = stringFromUTF8("original");
auto reference = SymbolImpl::create(original);
ASSERT_TRUE(reference->isSymbol());
+ ASSERT_FALSE(reference->isPrivate());
ASSERT_FALSE(reference->isAtomic());
auto result = AtomicStringImpl::lookUp(reference.ptr());
@@ -583,6 +612,7 @@
{
auto reference = SymbolImpl::createNullSymbol();
ASSERT_TRUE(reference->isSymbol());
+ ASSERT_FALSE(reference->isPrivate());
ASSERT_FALSE(reference->isAtomic());
// Because the substring of the reference is the empty string which is already interned.
@@ -690,4 +720,21 @@
ASSERT_EQ(str1.impl(), str2.impl());
}
+static SymbolImpl::StaticSymbolImpl staticSymbol {"Cocoa"};
+static SymbolImpl::StaticSymbolImpl staticPrivateSymbol {"Cocoa", SymbolImpl::s_flagIsPrivate };
+
+TEST(WTF, StaticSymbolImpl)
+{
+ auto& symbol = static_cast<SymbolImpl&>(staticSymbol);
+ ASSERT_TRUE(symbol.isSymbol());
+ ASSERT_FALSE(symbol.isPrivate());
+}
+
+TEST(WTF, StaticPrivateSymbolImpl)
+{
+ auto& symbol = static_cast<SymbolImpl&>(staticPrivateSymbol);
+ ASSERT_TRUE(symbol.isSymbol());
+ ASSERT_TRUE(symbol.isPrivate());
+}
+
} // namespace TestWebKitAPI