1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_MEM_SLOTS_H
17#define ECMASCRIPT_MEM_SLOTS_H
18
19#include "ecmascript/js_tagged_value.h"
20#include "ecmascript/mem/mem.h"
21
22namespace panda::ecmascript {
23enum class SlotStatus : bool {
24    KEEP_SLOT,
25    CLEAR_SLOT,
26};
27
28class ObjectSlot {
29public:
30    explicit ObjectSlot(uintptr_t slotAddr) : slotAddress_(slotAddr) {}
31    ~ObjectSlot() = default;
32
33    DEFAULT_COPY_SEMANTIC(ObjectSlot);
34    DEFAULT_MOVE_SEMANTIC(ObjectSlot);
35
36    void Update(TaggedObject *header)
37    {
38        Update(static_cast<JSTaggedType>(ToUintPtr(header)));
39    }
40
41    void Update(JSTaggedType value)
42    {
43        // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
44        *reinterpret_cast<JSTaggedType *>(slotAddress_) = value;
45    }
46
47    void UpdateWeak(uintptr_t value)
48    {
49        // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
50        *reinterpret_cast<JSTaggedType *>(slotAddress_) = value | JSTaggedValue::TAG_WEAK;
51    }
52
53    void Clear()
54    {
55        *reinterpret_cast<JSTaggedType *>(slotAddress_) = JSTaggedValue::VALUE_UNDEFINED;
56    }
57
58    TaggedObject *GetTaggedObject() const
59    {
60        return reinterpret_cast<TaggedObject *>(GetTaggedType());
61    }
62
63    JSTaggedType GetTaggedType() const
64    {
65        // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
66        return *reinterpret_cast<JSTaggedType *>(slotAddress_);
67    }
68
69    JSTaggedValue GetTaggedValue() const
70    {
71        // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
72        return *reinterpret_cast<JSTaggedValue *>(slotAddress_);
73    }
74
75    ObjectSlot &operator++()
76    {
77        slotAddress_ += sizeof(JSTaggedType);
78        return *this;
79    }
80
81    // NOLINTNEXTLINE(cert-dcl21-cpp)
82    ObjectSlot operator++(int)
83    {
84        ObjectSlot ret = *this;
85        slotAddress_ += sizeof(JSTaggedType);
86        return ret;
87    }
88
89    ObjectSlot operator+=(size_t length)
90    {
91        ObjectSlot ret = *this;
92        slotAddress_ += sizeof(JSTaggedType) * length;
93        return ret;
94    }
95
96    uintptr_t SlotAddress() const
97    {
98        return slotAddress_;
99    }
100
101    bool operator<(const ObjectSlot &other) const
102    {
103        return slotAddress_ < other.slotAddress_;
104    }
105    bool operator<=(const ObjectSlot &other) const
106    {
107        return slotAddress_ <= other.slotAddress_;
108    }
109    bool operator>(const ObjectSlot &other) const
110    {
111        return slotAddress_ > other.slotAddress_;
112    }
113    bool operator>=(const ObjectSlot &other) const
114    {
115        return slotAddress_ >= other.slotAddress_;
116    }
117    bool operator==(const ObjectSlot &other) const
118    {
119        return slotAddress_ == other.slotAddress_;
120    }
121    bool operator!=(const ObjectSlot &other) const
122    {
123        return slotAddress_ != other.slotAddress_;
124    }
125
126private:
127    uintptr_t slotAddress_;
128};
129}  // namespace panda::ecmascript
130
131#endif  // ECMASCRIPT_MEM_SLOTS_H
132