• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_COMPILER_TYPE_H
17 #define ECMASCRIPT_COMPILER_TYPE_H
18 
19 #include "ecmascript/ts_types/global_ts_type_ref.h"
20 
21 namespace panda::ecmascript::kungfu {
22 class GateType {
23 public:
type_(type)24     constexpr explicit GateType(uint32_t type = 0) : type_(type)
25     {
26     }
27 
GateType(GlobalTSTypeRef gt)28     explicit GateType(GlobalTSTypeRef gt) : type_(0)
29     {
30         type_ |= gt.GetType();
31     }
32 
33     ~GateType() = default;
34 
Value()35     uint32_t Value() const
36     {
37         return type_;
38     }
39 
NJSValue()40     static GateType NJSValue()
41     {
42         return GateType(NJS_VALUE);
43     }
44 
TaggedValue()45     static GateType TaggedValue()
46     {
47         return GateType(TAGGED_VALUE);
48     }
49 
TaggedPointer()50     static GateType TaggedPointer()
51     {
52         return GateType(TAGGED_POINTER);
53     }
54 
TaggedNPointer()55     static GateType TaggedNPointer()
56     {
57         return GateType(TAGGED_NPOINTER);
58     }
59 
Empty()60     static GateType Empty()
61     {
62         return GateType(EMPTY);
63     }
64 
AnyType()65     static GateType AnyType()
66     {
67         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::ANY));
68         return GateType(r);
69     }
70 
NumberType()71     static GateType NumberType()
72     {
73         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::NUMBER));
74         return GateType(r);
75     }
76 
DoubleType()77     static GateType DoubleType()
78     {
79         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::DOUBLE));
80         return GateType(r);
81     }
82 
BooleanType()83     static GateType BooleanType()
84     {
85         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::BOOLEAN));
86         return GateType(r);
87     }
88 
VoidType()89     static GateType VoidType()
90     {
91         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::VOID_TYPE));
92         return GateType(r);
93     }
94 
StringType()95     static GateType StringType()
96     {
97         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::STRING));
98         return GateType(r);
99     }
100 
SymbolType()101     static GateType SymbolType()
102     {
103         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::SYMBOL));
104         return GateType(r);
105     }
106 
NullType()107     static GateType NullType()
108     {
109         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::NULL_TYPE));
110         return GateType(r);
111     }
112 
UndefinedType()113     static GateType UndefinedType()
114     {
115         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::UNDEFINED));
116         return GateType(r);
117     }
118 
IntType()119     static GateType IntType()
120     {
121         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::INT));
122         return GateType(r);
123     }
124 
BigIntType()125     static GateType BigIntType()
126     {
127         GlobalTSTypeRef r(0, static_cast<int>(TSPrimitiveType::BIG_INT));
128         return GateType(r);
129     }
130 
IsAnyType()131     bool IsAnyType() const
132     {
133         GlobalTSTypeRef r = GetGTRef();
134         uint32_t m = r.GetModuleId();
135         uint32_t l = r.GetLocalId();
136         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::ANY));
137     }
138 
IsNumberType()139     bool IsNumberType() const
140     {
141         GlobalTSTypeRef r = GetGTRef();
142         uint32_t m = r.GetModuleId();
143         uint32_t l = r.GetLocalId();
144         return (m == 0) && ((l == static_cast<uint32_t>(TSPrimitiveType::NUMBER)) ||
145                             (l == static_cast<uint32_t>(TSPrimitiveType::INT))    ||
146                             (l == static_cast<uint32_t>(TSPrimitiveType::DOUBLE)));
147     }
148 
IsIntType()149     bool IsIntType() const
150     {
151         GlobalTSTypeRef r = GetGTRef();
152         uint32_t m = r.GetModuleId();
153         uint32_t l = r.GetLocalId();
154         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::INT));
155     }
156 
IsDoubleType()157     bool IsDoubleType() const
158     {
159         GlobalTSTypeRef r = GetGTRef();
160         uint32_t m = r.GetModuleId();
161         uint32_t l = r.GetLocalId();
162         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::DOUBLE));
163     }
164 
IsStringType()165     bool IsStringType() const
166     {
167         GlobalTSTypeRef r = GetGTRef();
168         uint32_t m = r.GetModuleId();
169         uint32_t l = r.GetLocalId();
170         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::STRING));
171     }
172 
IsNullType()173     bool IsNullType() const
174     {
175         GlobalTSTypeRef r = GetGTRef();
176         uint32_t m = r.GetModuleId();
177         uint32_t l = r.GetLocalId();
178         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::NULL_TYPE));
179     }
180 
IsUndefinedType()181     bool IsUndefinedType() const
182     {
183         GlobalTSTypeRef r = GetGTRef();
184         uint32_t m = r.GetModuleId();
185         uint32_t l = r.GetLocalId();
186         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::UNDEFINED));
187     }
188 
IsBooleanType()189     bool IsBooleanType() const
190     {
191         GlobalTSTypeRef r = GetGTRef();
192         uint32_t m = r.GetModuleId();
193         uint32_t l = r.GetLocalId();
194         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::BOOLEAN));
195     }
196 
IsBigIntType()197     bool IsBigIntType() const
198     {
199         GlobalTSTypeRef r = GetGTRef();
200         uint32_t m = r.GetModuleId();
201         uint32_t l = r.GetLocalId();
202         return (m == 0) && (l == static_cast<uint32_t>(TSPrimitiveType::BIG_INT));
203     }
204 
IsNJSValueType()205     bool IsNJSValueType() const
206     {
207         return type_ == NJS_VALUE;
208     }
209 
IsDigitablePrimitiveType()210     bool IsDigitablePrimitiveType() const
211     {
212         return IsNumberType() || IsNullType() || IsUndefinedType() || IsBooleanType() || IsBigIntType();
213     }
214 
IsGCRelated()215     bool IsGCRelated() const
216     {
217         return (type_ & (~GateType::GC_MASK)) == 0;
218     }
219 
220     bool operator ==(const GateType &other) const
221     {
222         return type_ == other.type_;
223     }
224 
225     bool operator !=(const GateType &other) const
226     {
227         return type_ != other.type_;
228     }
229 
230     bool operator <(const GateType &other) const
231     {
232         return type_ < other.type_;
233     }
234 
235     bool operator <=(const GateType &other) const
236     {
237         return type_ <= other.type_;
238     }
239 
240     bool operator >(const GateType &other) const
241     {
242         return type_ > other.type_;
243     }
244 
245     bool operator >=(const GateType &other) const
246     {
247         return type_ >= other.type_;
248     }
249 
GetGTRef()250     GlobalTSTypeRef GetGTRef() const
251     {
252         uint32_t r = type_ & (~MIR_TYPE_MASK);
253         return GlobalTSTypeRef(r);
254     }
255 
256 private:
257     static constexpr uint32_t GC_MASK = ~(1 << 30); // 30 : the 30-th bit is unset implies GC-related type
258     static constexpr uint32_t NO_GC_MASK = ~(1 << 29); // 29 : the 29-th bit is unset implies NO-GC-related type
259     // 31 : the 31-st bit is set implies MIR type
260     static constexpr uint32_t MIR_BASE_BITS = (1 << 31) | (1 << 30) | (1 << 29);
261     static constexpr uint32_t EMPTY_TYPE = 1 << 28; // 1 : means offset of empty type
262     static constexpr uint32_t MIR_TYPE_MASK = MIR_BASE_BITS | EMPTY_TYPE;
263 
264     static constexpr uint32_t NJS_VALUE = MIR_BASE_BITS;                           // (1110)
265     static constexpr uint32_t TAGGED_VALUE = MIR_BASE_BITS & GC_MASK & NO_GC_MASK; // (1000)
266     static constexpr uint32_t TAGGED_POINTER = MIR_BASE_BITS & GC_MASK;            // (1010)
267     static constexpr uint32_t TAGGED_NPOINTER = MIR_BASE_BITS & NO_GC_MASK;        // (1100)
268     static constexpr uint32_t EMPTY = NJS_VALUE + EMPTY_TYPE;                      // (1111)
269     static constexpr uint32_t SIZE_BITS = 4;
270 
271     static constexpr uint32_t VALID_BITS = sizeof(uint32_t) * 8;
272     static_assert((SIZE_BITS + GlobalTSTypeRef::GetSizeBits()) <= VALID_BITS);
273 
274     uint32_t type_ {0};
275 };
276 
277 enum class ValueType : uint8_t {
278     BOOL,
279     INT32,
280     UINT32,
281     FLOAT64,
282     TAGGED_BOOLEAN,
283     TAGGED_INT,
284     TAGGED_DOUBLE,
285     TAGGED_NUMBER,
286 };
287 
288 enum class ConvertSupport : uint8_t {
289     ENABLE,
290     // Not support conversion from srcType to dstType. It is necessary to use 'deopt' to ensure semantic correctness.
291     DISABLE
292 };
293 
294 class Type {
295 public:
296     explicit Type(GateType payload);
297     [[nodiscard]] bool IsBitset() const;
298     ~Type();
299 
300 private:
301     GateType payload;
302 };
303 }  // namespace panda::ecmascript::kungfu
304 
305 #endif  // ECMASCRIPT_COMPILER_TYPE_H
306