mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2025-04-09 02:10:43 +00:00
162 lines
5.2 KiB
C++
162 lines
5.2 KiB
C++
/*
|
|
* Copyright (C) 2006-2019 Apple Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "Identifier.h"
|
|
#include <wtf/HashSet.h>
|
|
#include <wtf/Vector.h>
|
|
|
|
namespace JSC {
|
|
|
|
// FIXME: Rename to PropertyNameArray.
|
|
class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
|
|
public:
|
|
typedef Vector<Identifier, 20> PropertyNameVector;
|
|
|
|
static Ref<PropertyNameArrayData> create() { return adoptRef(*new PropertyNameArrayData); }
|
|
|
|
PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
|
|
|
|
private:
|
|
PropertyNameArrayData()
|
|
{
|
|
}
|
|
|
|
PropertyNameVector m_propertyNameVector;
|
|
};
|
|
|
|
// FIXME: Rename to PropertyNameArrayBuilder.
|
|
class PropertyNameArray {
|
|
public:
|
|
PropertyNameArray(VM& vm, PropertyNameMode propertyNameMode, PrivateSymbolMode privateSymbolMode)
|
|
: m_data(PropertyNameArrayData::create())
|
|
, m_vm(vm)
|
|
, m_propertyNameMode(propertyNameMode)
|
|
, m_privateSymbolMode(privateSymbolMode)
|
|
{
|
|
}
|
|
|
|
VM& vm() { return m_vm; }
|
|
|
|
void add(uint32_t index)
|
|
{
|
|
add(Identifier::from(m_vm, index));
|
|
}
|
|
|
|
void add(const Identifier&);
|
|
void add(UniquedStringImpl*);
|
|
void addUnchecked(UniquedStringImpl*);
|
|
|
|
Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
|
|
const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
|
|
|
|
PropertyNameArrayData* data() { return m_data.get(); }
|
|
RefPtr<PropertyNameArrayData> releaseData() { return WTFMove(m_data); }
|
|
|
|
// FIXME: Remove these functions.
|
|
bool canAddKnownUniqueForStructure() const { return m_data->propertyNameVector().isEmpty(); }
|
|
typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
|
|
size_t size() const { return m_data->propertyNameVector().size(); }
|
|
const_iterator begin() const { return m_data->propertyNameVector().begin(); }
|
|
const_iterator end() const { return m_data->propertyNameVector().end(); }
|
|
|
|
bool includeSymbolProperties() const;
|
|
bool includeStringProperties() const;
|
|
|
|
PropertyNameMode propertyNameMode() const { return m_propertyNameMode; }
|
|
PrivateSymbolMode privateSymbolMode() const { return m_privateSymbolMode; }
|
|
|
|
private:
|
|
void addUncheckedInternal(UniquedStringImpl*);
|
|
bool isUidMatchedToTypeMode(UniquedStringImpl* identifier);
|
|
|
|
RefPtr<PropertyNameArrayData> m_data;
|
|
HashSet<UniquedStringImpl*> m_set;
|
|
VM& m_vm;
|
|
PropertyNameMode m_propertyNameMode;
|
|
PrivateSymbolMode m_privateSymbolMode;
|
|
};
|
|
|
|
ALWAYS_INLINE void PropertyNameArray::add(const Identifier& identifier)
|
|
{
|
|
add(identifier.impl());
|
|
}
|
|
|
|
ALWAYS_INLINE void PropertyNameArray::addUncheckedInternal(UniquedStringImpl* identifier)
|
|
{
|
|
m_data->propertyNameVector().append(Identifier::fromUid(m_vm, identifier));
|
|
}
|
|
|
|
ALWAYS_INLINE void PropertyNameArray::addUnchecked(UniquedStringImpl* identifier)
|
|
{
|
|
if (!isUidMatchedToTypeMode(identifier))
|
|
return;
|
|
addUncheckedInternal(identifier);
|
|
}
|
|
|
|
ALWAYS_INLINE void PropertyNameArray::add(UniquedStringImpl* identifier)
|
|
{
|
|
static constexpr unsigned setThreshold = 20;
|
|
|
|
ASSERT(identifier);
|
|
|
|
if (!isUidMatchedToTypeMode(identifier))
|
|
return;
|
|
|
|
if (size() < setThreshold) {
|
|
if (m_data->propertyNameVector().contains(identifier))
|
|
return;
|
|
} else {
|
|
if (m_set.isEmpty()) {
|
|
for (Identifier& name : m_data->propertyNameVector())
|
|
m_set.add(name.impl());
|
|
}
|
|
if (!m_set.add(identifier).isNewEntry)
|
|
return;
|
|
}
|
|
|
|
addUncheckedInternal(identifier);
|
|
}
|
|
|
|
ALWAYS_INLINE bool PropertyNameArray::isUidMatchedToTypeMode(UniquedStringImpl* identifier)
|
|
{
|
|
if (identifier->isSymbol()) {
|
|
if (!includeSymbolProperties())
|
|
return false;
|
|
if (UNLIKELY(m_privateSymbolMode == PrivateSymbolMode::Include))
|
|
return true;
|
|
return !static_cast<SymbolImpl*>(identifier)->isPrivate();
|
|
}
|
|
return includeStringProperties();
|
|
}
|
|
|
|
ALWAYS_INLINE bool PropertyNameArray::includeSymbolProperties() const
|
|
{
|
|
return static_cast<std::underlying_type<PropertyNameMode>::type>(m_propertyNameMode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Symbols);
|
|
}
|
|
|
|
ALWAYS_INLINE bool PropertyNameArray::includeStringProperties() const
|
|
{
|
|
return static_cast<std::underlying_type<PropertyNameMode>::type>(m_propertyNameMode) & static_cast<std::underlying_type<PropertyNameMode>::type>(PropertyNameMode::Strings);
|
|
}
|
|
|
|
} // namespace JSC
|