1/*
2 * Copyright (c) 2023 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_VTABLE_H
17#define ECMASCRIPT_VTABLE_H
18
19#include "ecmascript/weak_vector.h"
20
21namespace panda::ecmascript {
22class VTable : public TaggedArray {
23public:
24    static constexpr uint32_t DEFAULT_SUPERS_CAPACITY = 4;
25
26    enum TupleItem {
27        NAME = 0,
28        TYPE,
29        OWNER,
30        OFFSET,
31
32        ITEM_NUM,
33        ITEM_FIRST = NAME,
34        ITEM_LAST = OFFSET,
35    };
36
37    class Tuple {
38    public:
39        JSHandle<JSTaggedValue> GetItem(TupleItem item) const
40        {
41            return items_[item];
42        }
43    private:
44        // only allow VTable to create a instance of Tuple
45        explicit Tuple(const CVector<JSHandle<JSTaggedValue>> &vec) : items_(std::move(vec)) {}
46        CVector<JSHandle<JSTaggedValue>> items_;
47
48        friend class VTable;
49    };
50
51    enum TypeKind {
52        FUNCTION = 0,
53        ACCESSOR,
54        NORMAL
55    };
56
57    static constexpr uint32_t TUPLE_SIZE = 4;
58
59    CAST_CHECK(VTable, IsTaggedArray);
60
61    static Tuple CreateTuple(const JSThread *thread, JSTaggedValue phc,
62                             const JSHandle<JSTaggedValue> &owner, uint32_t propIndex);
63
64    static JSHandle<VTable> Copy(const JSThread *thread, const JSHandle<VTable> &vtable);
65
66    uint32_t GetNumberOfTuples() const
67    {
68        return GetLength() / TUPLE_SIZE;
69    }
70
71    JSTaggedValue GetTupleItem(uint32_t tupleIdx, TupleItem kind) const
72    {
73        return Get(tupleIdx * TUPLE_SIZE + kind);
74    }
75
76    bool IsAccessor(uint32_t tupleIdx) const
77    {
78        TypeKind type = static_cast<TypeKind>(GetTupleItem(tupleIdx, TupleItem::TYPE).GetInt());
79        return type == TypeKind::ACCESSOR;
80    }
81
82    Tuple GetTuple(const JSThread *thread, uint32_t tupleIdx) const;
83
84    void SetByIndex(const JSThread *thread, uint32_t idx, const VTable::Tuple &tuple);
85
86    void Trim(const JSThread *thread, uint32_t newLength);
87
88    int GetTupleIndexByName(JSTaggedValue val) const;
89
90    bool Find(JSTaggedValue val) const;
91
92    DECL_DUMP()
93};
94}  // namespace panda::ecmascript
95
96#endif  // ECMASCRIPT_VTABLE_H