2021-09-04 08:06:49 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
#ifndef ECMASCRIPT_PROPERTY_ATTRIBUTES_H
|
|
|
|
#define ECMASCRIPT_PROPERTY_ATTRIBUTES_H
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
#include "ecmascript/js_tagged_value.h"
|
2022-07-23 10:54:34 +00:00
|
|
|
|
|
|
|
#include "libpandabase/utils/bit_field.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
namespace panda::ecmascript {
|
|
|
|
class PropertyDescriptor;
|
|
|
|
|
|
|
|
enum class Representation {
|
|
|
|
NONE,
|
|
|
|
INT,
|
|
|
|
DOUBLE,
|
2023-07-12 10:42:42 +00:00
|
|
|
TAGGED,
|
2021-09-04 08:06:49 +00:00
|
|
|
};
|
|
|
|
|
2023-07-12 10:42:42 +00:00
|
|
|
enum class TrackType : uint8_t {
|
|
|
|
NONE = 0x0ULL,
|
|
|
|
INT = 0x1ULL,
|
|
|
|
DOUBLE = 0x1ULL << 1,
|
|
|
|
NUMBER = INT | DOUBLE,
|
|
|
|
TAGGED = 0x1ULL << 2
|
2023-05-15 08:48:14 +00:00
|
|
|
};
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
enum class PropertyBoxType {
|
|
|
|
// Meaningful when a property cell does not contain the hole.
|
|
|
|
UNDEFINED, // The PREMONOMORPHIC of property cells.
|
|
|
|
CONSTANT, // Cell has been assigned only once.
|
|
|
|
CONSTANTTYPE, // Cell has been assigned only one type.
|
|
|
|
MUTABLE, // Cell will no longer be tracked as constant.
|
|
|
|
|
|
|
|
// Meaningful when a property cell contains the hole.
|
|
|
|
UNINITIALIZED = UNDEFINED, // Cell has never been initialized.
|
|
|
|
INVALIDATED = CONSTANT, // Cell has been deleted, invalidated or never existed.
|
|
|
|
};
|
|
|
|
|
|
|
|
class PropertyAttributes {
|
|
|
|
public:
|
2023-01-03 02:32:21 +00:00
|
|
|
PropertyAttributes() = default;
|
2021-09-04 08:06:49 +00:00
|
|
|
~PropertyAttributes() = default;
|
|
|
|
|
|
|
|
DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyAttributes);
|
|
|
|
DEFAULT_COPY_SEMANTIC(PropertyAttributes);
|
|
|
|
|
|
|
|
explicit PropertyAttributes(uint32_t v) : value_(v) {}
|
|
|
|
explicit PropertyAttributes(int32_t v) : value_(static_cast<uint32_t>(v)) {}
|
|
|
|
explicit PropertyAttributes(JSTaggedValue v) : value_(v.GetInt()) {}
|
|
|
|
explicit PropertyAttributes(const PropertyDescriptor &desc);
|
|
|
|
|
|
|
|
static constexpr uint32_t DICTIONARY_ORDER_NUM = 20;
|
|
|
|
static constexpr uint32_t OFFSET_BITFIELD_NUM = 10;
|
2023-07-12 10:42:42 +00:00
|
|
|
static constexpr uint32_t REPRESENTATION_NUM = 2;
|
|
|
|
static constexpr uint32_t TRACK_TYPE_NUM = 3;
|
2021-12-17 09:18:10 +00:00
|
|
|
static constexpr uint32_t MAX_CAPACITY_OF_PROPERTIES = (1U << OFFSET_BITFIELD_NUM) - 1;
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
using PropertyMetaDataField = BitField<int, 0, 4>; // 4: property metaData field occupies 4 bits
|
2023-06-12 11:51:18 +00:00
|
|
|
using AttributesField = BitField<int, 0, 4>; // 4: attributes field occupies 4 bits
|
|
|
|
using DefaultAttributesField = BitField<int, 0, 3>; // 3: default attributes field occupies 3 bits
|
|
|
|
using WritableField = BitField<bool, 0, 1>; // 1: writable field occupies 1 bits
|
2021-09-04 08:06:49 +00:00
|
|
|
using EnumerableField = WritableField::NextFlag;
|
|
|
|
using ConfigurableField = EnumerableField::NextFlag;
|
|
|
|
using IsAccessorField = ConfigurableField::NextFlag; // 4
|
|
|
|
|
2023-06-12 11:51:18 +00:00
|
|
|
using IsInlinedPropsField = PropertyMetaDataField::NextFlag; // 5
|
2023-07-12 10:42:42 +00:00
|
|
|
using RepresentationField = IsInlinedPropsField::NextField<Representation, REPRESENTATION_NUM>; // 2: 2 bits, 6-8
|
2023-07-29 04:56:54 +00:00
|
|
|
// fast mode
|
2021-09-04 08:06:49 +00:00
|
|
|
using OffsetField = RepresentationField::NextField<uint32_t, OFFSET_BITFIELD_NUM>; // 18
|
2023-07-12 10:42:42 +00:00
|
|
|
using TrackTypeField = OffsetField::NextField<TrackType, TRACK_TYPE_NUM>; // 3: 3 bits
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2023-05-16 11:24:47 +00:00
|
|
|
static constexpr uint32_t NORMAL_ATTR_BITS = 20;
|
2021-09-04 08:06:49 +00:00
|
|
|
using NormalAttrField = BitField<int, 0, NORMAL_ATTR_BITS>;
|
2023-05-16 11:24:47 +00:00
|
|
|
using SortedIndexField = TrackTypeField::NextField<uint32_t, OFFSET_BITFIELD_NUM>; // 30
|
2023-06-12 11:51:18 +00:00
|
|
|
using IsConstPropsField = SortedIndexField::NextFlag; // 31
|
|
|
|
using IsNotHoleField = IsConstPropsField::NextFlag; // 32
|
2021-09-04 08:06:49 +00:00
|
|
|
// dictionary mode, include global
|
2023-07-29 04:56:54 +00:00
|
|
|
using PropertyBoxTypeField = RepresentationField::NextField<PropertyBoxType, 2>; // 2: 2 bits, 9-10
|
|
|
|
using DictionaryOrderField = PropertyBoxTypeField::NextField<uint32_t, DICTIONARY_ORDER_NUM>; // 30
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
static constexpr uint32_t BIT_SIZE = 28;
|
2022-03-19 06:14:33 +00:00
|
|
|
static constexpr int INITIAL_PROPERTY_INDEX = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
|
|
|
|
inline int GetPropertyMetaData() const
|
|
|
|
{
|
|
|
|
return PropertyMetaDataField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PropertyAttributes Default()
|
|
|
|
{
|
|
|
|
return PropertyAttributes(GetDefaultAttributes());
|
|
|
|
}
|
|
|
|
|
|
|
|
static PropertyAttributes Default(bool w, bool e, bool c, bool isAccessor = false)
|
|
|
|
{
|
|
|
|
uint32_t value = WritableField::Encode(w) | EnumerableField::Encode(e) | ConfigurableField::Encode(c) |
|
|
|
|
IsAccessorField::Encode(isAccessor);
|
|
|
|
return PropertyAttributes(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PropertyAttributes DefaultAccessor(bool w, bool e, bool c)
|
|
|
|
{
|
|
|
|
uint32_t value = WritableField::Encode(w) | EnumerableField::Encode(e) | ConfigurableField::Encode(c) |
|
|
|
|
IsAccessorField::Encode(true);
|
|
|
|
return PropertyAttributes(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetDefaultAttributes()
|
|
|
|
{
|
|
|
|
AttributesField::Set<uint32_t>(DefaultAttributesField::Mask(), &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int GetDefaultAttributes()
|
|
|
|
{
|
|
|
|
return DefaultAttributesField::Mask();
|
|
|
|
}
|
|
|
|
|
2023-05-15 08:48:14 +00:00
|
|
|
bool UpdateTrackType(JSTaggedValue value)
|
|
|
|
{
|
|
|
|
TrackType oldType = GetTrackType();
|
|
|
|
if (oldType == TrackType::TAGGED) {
|
|
|
|
return false;
|
|
|
|
}
|
2023-07-12 10:42:42 +00:00
|
|
|
|
|
|
|
TrackType newType = TrackType::TAGGED;
|
2023-05-15 08:48:14 +00:00
|
|
|
if (value.IsInt()) {
|
2023-07-12 10:42:42 +00:00
|
|
|
newType = static_cast<TrackType>(static_cast<uint8_t>(TrackType::INT) | static_cast<uint8_t>(oldType));
|
|
|
|
} else if (value.IsDouble()) {
|
|
|
|
newType = static_cast<TrackType>(static_cast<uint8_t>(TrackType::DOUBLE) | static_cast<uint8_t>(oldType));
|
2023-05-15 08:48:14 +00:00
|
|
|
}
|
|
|
|
|
2023-07-12 10:42:42 +00:00
|
|
|
if (oldType != newType) {
|
2023-05-15 08:48:14 +00:00
|
|
|
SetTrackType(newType);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline bool IsDefaultAttributes() const
|
|
|
|
{
|
|
|
|
return AttributesField::Get(value_) == static_cast<int>(DefaultAttributesField::Mask());
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetNoneAttributes()
|
|
|
|
{
|
|
|
|
AttributesField::Set<uint32_t>(0U, &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsNoneAttributes() const
|
|
|
|
{
|
|
|
|
return AttributesField::Get(value_) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetWritable(bool flag)
|
|
|
|
{
|
|
|
|
WritableField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
|
|
|
inline bool IsWritable() const
|
|
|
|
{
|
|
|
|
return WritableField::Get(value_);
|
|
|
|
}
|
|
|
|
inline void SetEnumerable(bool flag)
|
|
|
|
{
|
|
|
|
EnumerableField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
|
|
|
inline bool IsEnumerable() const
|
|
|
|
{
|
|
|
|
return EnumerableField::Get(value_);
|
|
|
|
}
|
|
|
|
inline void SetConfigurable(bool flag)
|
|
|
|
{
|
|
|
|
ConfigurableField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
|
|
|
inline bool IsConfigurable() const
|
|
|
|
{
|
|
|
|
return ConfigurableField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetIsAccessor(bool flag)
|
|
|
|
{
|
|
|
|
IsAccessorField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
2021-09-18 09:14:04 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline bool IsAccessor() const
|
|
|
|
{
|
|
|
|
return IsAccessorField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetIsInlinedProps(bool flag)
|
|
|
|
{
|
|
|
|
IsInlinedPropsField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
2021-09-18 09:14:04 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline bool IsInlinedProps() const
|
|
|
|
{
|
|
|
|
return IsInlinedPropsField::Get(value_);
|
|
|
|
}
|
|
|
|
|
2021-09-10 08:34:37 +00:00
|
|
|
inline void SetIsConstProps(bool flag)
|
|
|
|
{
|
|
|
|
IsConstPropsField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsConstProps() const
|
|
|
|
{
|
|
|
|
return IsConstPropsField::Get(value_);
|
|
|
|
}
|
|
|
|
|
2023-05-16 11:24:47 +00:00
|
|
|
inline void SetIsNotHole(bool flag)
|
|
|
|
{
|
|
|
|
IsNotHoleField::Set<uint32_t>(flag, &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsNotHole() const
|
|
|
|
{
|
|
|
|
return IsNotHoleField::Get(value_);
|
|
|
|
}
|
|
|
|
|
2023-07-12 10:42:42 +00:00
|
|
|
inline bool IsTaggedRep() const
|
|
|
|
{
|
|
|
|
return !IsDoubleRep() && !IsIntRep();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsDoubleRep() const
|
|
|
|
{
|
|
|
|
auto rep = GetRepresentation();
|
|
|
|
return rep == Representation::DOUBLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsIntRep() const
|
|
|
|
{
|
|
|
|
auto rep = GetRepresentation();
|
|
|
|
return rep == Representation::INT;
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline void SetRepresentation(Representation representation)
|
|
|
|
{
|
|
|
|
RepresentationField::Set<uint32_t>(representation, &value_);
|
|
|
|
}
|
2023-05-15 08:48:14 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline Representation GetRepresentation() const
|
|
|
|
{
|
|
|
|
return RepresentationField::Get(value_);
|
|
|
|
}
|
|
|
|
|
2023-05-15 08:48:14 +00:00
|
|
|
inline TrackType GetTrackType() const
|
|
|
|
{
|
|
|
|
return TrackTypeField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetTrackType(TrackType type)
|
|
|
|
{
|
|
|
|
TrackTypeField::Set(type, &value_);
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
inline void SetDictionaryOrder(uint32_t order)
|
|
|
|
{
|
|
|
|
DictionaryOrderField::Set<uint32_t>(order, &value_);
|
|
|
|
}
|
|
|
|
inline uint32_t GetDictionaryOrder() const
|
|
|
|
{
|
|
|
|
return DictionaryOrderField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetOffset(uint32_t offset)
|
|
|
|
{
|
|
|
|
OffsetField::Set<uint32_t>(offset, &value_);
|
|
|
|
}
|
|
|
|
inline uint32_t GetOffset() const
|
|
|
|
{
|
|
|
|
return OffsetField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetSortedIndex(uint32_t sortedIndex)
|
|
|
|
{
|
|
|
|
SortedIndexField::Set<uint32_t>(sortedIndex, &value_);
|
|
|
|
}
|
|
|
|
inline uint32_t GetSortedIndex() const
|
|
|
|
{
|
|
|
|
return SortedIndexField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetNormalAttr(uint32_t normalAttr)
|
|
|
|
{
|
|
|
|
NormalAttrField::Set<uint32_t>(normalAttr, &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t GetNormalAttr() const
|
|
|
|
{
|
|
|
|
return NormalAttrField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline JSTaggedValue GetNormalTagged() const
|
|
|
|
{
|
|
|
|
return JSTaggedValue(static_cast<int>(GetNormalAttr()));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t GetValue() const
|
|
|
|
{
|
|
|
|
return value_;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void SetBoxType(PropertyBoxType cellType)
|
|
|
|
{
|
|
|
|
PropertyBoxTypeField::Set<uint32_t>(cellType, &value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline PropertyBoxType GetBoxType() const
|
|
|
|
{
|
|
|
|
return PropertyBoxTypeField::Get(value_);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static bool IsValidIndex(int index)
|
|
|
|
{
|
|
|
|
return DictionaryOrderField::IsValid(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline JSTaggedValue GetTaggedValue() const
|
|
|
|
{
|
|
|
|
return JSTaggedValue(static_cast<int>(value_));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
uint32_t value_{0};
|
|
|
|
};
|
|
|
|
} // namespace panda::ecmascript
|
2021-09-07 14:24:16 +00:00
|
|
|
#endif // ECMASCRIPT_PROPERTY_ATTRIBUTES_H
|