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_OBJECT_FAST_OPERATOR_H
17#define ECMASCRIPT_OBJECT_FAST_OPERATOR_H
18
19#include "ecmascript/js_handle.h"
20#include "ecmascript/js_hclass.h"
21#include "ecmascript/js_tagged_value.h"
22#include "ecmascript/property_attributes.h"
23
24namespace panda::ecmascript {
25using SCheckMode = JSShared::SCheckMode;
26
27class ObjectFastOperator final {
28public:
29    enum class Status: uint8_t {
30        None = 0x00UL,
31        UseOwn = 0x01UL,
32        GetInternal = 0x1UL << 1,
33        DefineSemantics = 0x1UL << 2,
34    };
35
36    static inline bool UseOwn(Status status)
37    {
38        return (static_cast<int32_t>(status) & static_cast<int32_t>(Status::UseOwn)) > 0;
39    }
40
41    static inline bool GetInternal(Status status)
42    {
43        return (static_cast<int32_t>(status) & static_cast<int32_t>(Status::GetInternal)) > 0;
44    }
45
46    static inline bool DefineSemantics(Status status)
47    {
48        return (static_cast<uint32_t>(status) & static_cast<int32_t>(Status::DefineSemantics)) > 0;
49    }
50
51    static inline std::pair<JSTaggedValue, bool> HasOwnProperty(JSThread *thread,
52                                                                JSTaggedValue receiver, JSTaggedValue key);
53
54    template<Status status = Status::None>
55    static inline JSTaggedValue TryFastHasProperty(JSThread *thread, JSTaggedValue receiver,
56                                                   JSMutableHandle<JSTaggedValue> keyHandle);
57
58    template<Status status = Status::None>
59    static inline JSTaggedValue TryFastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver,
60                                                          JSMutableHandle<JSTaggedValue> keyHandle);
61
62    template<Status status = Status::None>
63    static inline JSTaggedValue TryFastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index);
64
65    template<Status status = Status::None>
66    static inline JSTaggedValue TryGetPropertyByNameThroughCacheAtLocal(JSThread *thread, JSTaggedValue receiver,
67                                                                        JSTaggedValue key);
68
69    template<Status status = Status::None>
70    static inline JSTaggedValue GetPropertyByName(JSThread *thread, JSTaggedValue receiver,
71                                                  JSTaggedValue key, bool noAllocate = false,
72                                                  bool *isCallGetter = nullptr);
73
74    template <Status status = Status::None>
75    static inline JSTaggedValue TrySetPropertyByNameThroughCacheAtLocal(JSThread *thread, JSTaggedValue receiver,
76                                                                        JSTaggedValue key, JSTaggedValue value);
77
78    template <Status status = Status::None>
79    static inline JSTaggedValue SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key,
80                                                  JSTaggedValue value, SCheckMode sCheckMode = SCheckMode::CHECK);
81
82    template <Status status = Status::None>
83    static inline JSTaggedValue GetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index);
84
85    template <Status status = Status::None>
86    static inline JSTaggedValue SetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index,
87                                                   JSTaggedValue value);
88
89    template <Status status = Status::None>
90    static inline JSTaggedValue GetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key);
91
92    template <Status status = Status::None>
93    static inline JSTaggedValue SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key,
94                                                   JSTaggedValue value, SCheckMode sCheckMode = SCheckMode::CHECK);
95
96    static inline bool FastSetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key,
97                                              JSTaggedValue value, SCheckMode sCheckMode = SCheckMode::CHECK);
98
99    static inline bool FastSetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index,
100                                              JSTaggedValue value);
101
102    static inline JSTaggedValue FastGetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key);
103
104    static inline JSTaggedValue FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key,
105                                                       SCheckMode sCheckMode = SCheckMode::CHECK);
106
107    static inline JSTaggedValue FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index);
108
109    static inline JSTaggedValue FastParseDate(const EcmaString *str);
110
111    static inline PropertyAttributes AddPropertyByName(JSThread *thread, JSHandle<JSObject> objHandle,
112                                                       JSHandle<JSTaggedValue> keyHandle,
113                                                       JSHandle<JSTaggedValue> valueHandle,
114                                                       PropertyAttributes attr);
115
116    static inline JSTaggedValue CallGetter(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder,
117                                           JSTaggedValue value);
118    static inline JSTaggedValue FastGetPropertyByPorpsIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index);
119
120    static inline int64_t TryToElementsIndex(JSTaggedValue key);
121private:
122    static inline JSTaggedValue CallSetter(JSThread *thread, JSTaggedValue receiver, JSTaggedValue value,
123                                           JSTaggedValue accessorValue);
124
125    static inline bool ShouldCallSetter(JSTaggedValue receiver, JSTaggedValue holder, JSTaggedValue accessorValue,
126                                        PropertyAttributes attr);
127
128    static inline bool IsSpecialIndexedObj(JSType jsType);
129
130    static inline bool IsJSSharedArray(JSType jsType);
131
132    static inline bool IsFastTypeArray(JSType jsType);
133
134    static inline bool IsString(JSType jsType);
135
136    static inline bool IsJSPrimitiveRef(JSType jsType);
137
138    static inline bool TryStringOrSymbolToIndex(JSTaggedValue key, uint32_t *output);
139
140    static inline JSTaggedValue FastGetTypeArrayProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder,
141                                                         JSTaggedValue key, JSType jsType);
142
143    static inline JSTaggedValue FastSetTypeArrayProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder,
144                                                         JSTaggedValue key, JSTaggedValue value, JSType jsType);
145
146    // non ECMA standard jsapi container
147    static inline bool IsSpecialContainer(JSType jsType);
148
149    static inline JSTaggedValue GetContainerProperty(JSThread *thread, JSTaggedValue receiver, uint32_t index,
150                                                     JSType jsType);
151
152    static inline JSTaggedValue SetContainerProperty(JSThread *thread, JSTaggedValue receiver, uint32_t index,
153                                                     JSTaggedValue value, JSType jsType);
154
155    static inline JSTaggedValue AddPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index,
156                                                   JSTaggedValue value);
157
158    static inline bool GetNumFromString(const char *str, int len, int *index, int *num);
159
160    friend class FastRuntimeStub;
161};
162}  // namespace panda::ecmascript
163#endif  // ECMASCRIPT_OBJECT_FAST_OPERATOR_H
164