• 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 #define VALUE_TYPE_LIST(V)  \
22     V(BOOL)                 \
23     V(INT32)                \
24     V(UINT32)               \
25     V(FLOAT64)              \
26     V(TAGGED_BOOLEAN)       \
27     V(TAGGED_INT)           \
28     V(TAGGED_DOUBLE)        \
29     V(TAGGED_NUMBER)        \
30     V(CHAR)                 \
31     V(ECMA_STRING)          \
32     V(UNDEFINED)            \
33     V(HOLE_INT)             \
34     V(HOLE_DOUBLE)          \
35     V(TAGGED_NULL)
36 
37 enum class ValueType : uint8_t {
38 #define DECLARE_VALUE_TYPE(TYPE) TYPE,
39     VALUE_TYPE_LIST(DECLARE_VALUE_TYPE)
40 #undef DECLARE_VALUE_TYPE
41 };
42 
43 namespace panda::ecmascript::kungfu {
44 #define PRIMITIVE_TYPE_LIST(V)         \
45     V(ANY, AnyType)                    \
46     V(NUMBER, NumberType)              \
47     V(BOOLEAN, BooleanType)            \
48     V(VOID_TYPE, VoidType)             \
49     V(STRING, StringType)              \
50     V(INTERN_STRING, InternStringType) \
51     V(SYMBOL, SymbolType)              \
52     V(NULL_TYPE, NullType)             \
53     V(UNDEFINED, UndefinedType)        \
54     V(INT, IntType)                    \
55     V(BIG_INT, BigIntType)             \
56     V(DOUBLE, DoubleType)              \
57 
58 // ParamType: Prediction type from PGO, bound to MetaData in GATE
59 #define PARAM_TYPE_LIST(V)             \
60     V(INT_OVERFLOW, IntOverflowType)   \
61 
62 class ParamType {
63 public:
type_(type)64     explicit ParamType(uint32_t type = 0) : type_(type) {}
65 
ParamType(uint32_t jsType,bool isBuiltinType)66     ParamType(uint32_t jsType, [[maybe_unused]] bool isBuiltinType)
67     {
68         // only builtins type uses two-param constructor
69         ASSERT(isBuiltinType);
70         type_ = BUILTIN_TYPE | jsType;
71     }
72 
73 #define DEFINE_TYPE_CONSTRUCTOR(type, name) \
74     static ParamType name() { return ParamType(static_cast<uint32_t>(type)); }
75 
76     PRIMITIVE_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
PARAM_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)77     PARAM_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
78 #undef DEFINE_TYPE_CONSTRUCTOR
79 
80 #define DEFINE_JUDGE_METHOD(type, name) \
81     bool Is##name() const { return type_ == static_cast<uint32_t>(type); }
82 
83     PRIMITIVE_TYPE_LIST(DEFINE_JUDGE_METHOD)
84     PARAM_TYPE_LIST(DEFINE_JUDGE_METHOD)
85 #undef DEFINE_JUDGE_METHOD
86 
87     uint32_t Value() const
88     {
89         return type_;
90     }
91 
HasNumberType()92     bool HasNumberType() const
93     {
94         return IsNumberType() || IsIntType() || IsIntOverflowType() || IsDoubleType();
95     }
96 
IsBuiltinType()97     bool IsBuiltinType() const
98     {
99         return type_ & BUILTIN_TYPE;
100     }
101 
GetBuiltinType()102     uint32_t GetBuiltinType() const
103     {
104         return type_ & ~BUILTIN_TYPE;
105     }
106 
107     bool operator ==(const ParamType &other) const
108     {
109         return type_ == other.type_;
110     }
111 
112     bool operator !=(const ParamType &other) const
113     {
114         return !(*this == other);
115     }
116 
117 private:
118     enum : uint8_t {
119 #define DECLARE_TYPE(type, name) type,
120         PRIMITIVE_TYPE_LIST(DECLARE_TYPE)
121         PARAM_TYPE_LIST(DECLARE_TYPE)
122 #undef DECLARE_TYPE
123     };
124 
125     static constexpr uint32_t BUILTIN_TYPE = (1 << 31); // 31 : the 31-th bit is set implies builtin type
126 
127     uint32_t type_ {0};
128 };
129 #undef PARAM_TYPE_LIST
130 
131 // GateType: Trusted type, directly bound to Gate
132 class GateType {
133 public:
134     constexpr explicit GateType(uint32_t type = 0)
135     {
136         type_ |= type;
137     }
138 
GateType(GlobalTSTypeRef gt)139     explicit GateType([[maybe_unused]]GlobalTSTypeRef gt)
140     {
141         // linxiang shoult remove in part3
142         type_ = EMPTY;
143     }
144 
145     ~GateType() = default;
146 
Value()147     uint32_t Value() const
148     {
149         return type_;
150     }
151 
NJSValue()152     static GateType NJSValue()
153     {
154         return GateType(NJS_VALUE);
155     }
156 
TaggedValue()157     static GateType TaggedValue()
158     {
159         return GateType(TAGGED_VALUE);
160     }
161 
TaggedPointer()162     static GateType TaggedPointer()
163     {
164         return GateType(TAGGED_POINTER);
165     }
166 
TaggedNPointer()167     static GateType TaggedNPointer()
168     {
169         return GateType(TAGGED_NPOINTER);
170     }
171 
Empty()172     static GateType Empty()
173     {
174         return GateType(EMPTY);
175     }
176 
AnyType()177     static GateType AnyType()
178     {
179         return GateType(static_cast<uint32_t>(TSPrimitiveType::ANY));
180     }
181 
NumberType()182     static GateType NumberType()
183     {
184         return GateType(static_cast<uint32_t>(TSPrimitiveType::NUMBER));
185     }
186 
DoubleType()187     static GateType DoubleType()
188     {
189         return GateType(static_cast<uint32_t>(TSPrimitiveType::DOUBLE));
190     }
191 
BooleanType()192     static GateType BooleanType()
193     {
194         return GateType(static_cast<uint32_t>(TSPrimitiveType::BOOLEAN));
195     }
196 
VoidType()197     static GateType VoidType()
198     {
199         return GateType(static_cast<uint32_t>(TSPrimitiveType::VOID_TYPE));
200     }
201 
StringType()202     static GateType StringType()
203     {
204         return GateType(static_cast<uint32_t>(TSPrimitiveType::STRING));
205     }
206 
SymbolType()207     static GateType SymbolType()
208     {
209         return GateType(static_cast<uint32_t>(TSPrimitiveType::SYMBOL));
210     }
211 
NullType()212     static GateType NullType()
213     {
214         return GateType(static_cast<uint32_t>(TSPrimitiveType::NULL_TYPE));
215     }
216 
UndefinedType()217     static GateType UndefinedType()
218     {
219         return GateType(static_cast<uint32_t>(TSPrimitiveType::UNDEFINED));
220     }
221 
IntType()222     static GateType IntType()
223     {
224         return GateType(static_cast<uint32_t>(TSPrimitiveType::INT));
225     }
226 
BigIntType()227     static GateType BigIntType()
228     {
229         return GateType(static_cast<uint32_t>(TSPrimitiveType::BIG_INT));
230     }
231 
IsAnyType()232     bool IsAnyType() const
233     {
234         uint32_t type = GetType();
235         return type == static_cast<uint32_t>(TSPrimitiveType::ANY);
236     }
237 
IsNumberType()238     bool IsNumberType() const
239     {
240         uint32_t type = GetType();
241         return ((type == static_cast<uint32_t>(TSPrimitiveType::NUMBER)) ||
242                (type == static_cast<uint32_t>(TSPrimitiveType::INT))    ||
243                (type == static_cast<uint32_t>(TSPrimitiveType::DOUBLE)));
244     }
245 
IsIntType()246     bool IsIntType() const
247     {
248         uint32_t type = GetType();
249         return type == static_cast<uint32_t>(TSPrimitiveType::INT);
250     }
251 
IsDoubleType()252     bool IsDoubleType() const
253     {
254         uint32_t type = GetType();
255         return type == static_cast<uint32_t>(TSPrimitiveType::DOUBLE);
256     }
257 
IsStringType()258     bool IsStringType() const
259     {
260         uint32_t type = GetType();
261         return type == static_cast<uint32_t>(TSPrimitiveType::STRING);
262     }
263 
IsNullType()264     bool IsNullType() const
265     {
266         uint32_t type = GetType();
267         return type == static_cast<uint32_t>(TSPrimitiveType::NULL_TYPE);
268     }
269 
IsUndefinedType()270     bool IsUndefinedType() const
271     {
272         uint32_t type = GetType();
273         return type == static_cast<uint32_t>(TSPrimitiveType::UNDEFINED);
274     }
275 
IsBooleanType()276     bool IsBooleanType() const
277     {
278         uint32_t type = GetType();
279         return type == static_cast<uint32_t>(TSPrimitiveType::BOOLEAN);
280     }
281 
IsBigIntType()282     bool IsBigIntType() const
283     {
284         uint32_t type = GetType();
285         return type == static_cast<uint32_t>(TSPrimitiveType::BIG_INT);
286     }
287 
IsNJSValueType()288     bool IsNJSValueType() const
289     {
290         return type_ == NJS_VALUE;
291     }
292 
IsDigitablePrimitiveType()293     bool IsDigitablePrimitiveType() const
294     {
295         return IsNumberType() || IsNullType() || IsUndefinedType() || IsBooleanType() || IsBigIntType();
296     }
297 
IsSymbolType()298     bool IsSymbolType() const
299     {
300         uint32_t type = GetType();
301         return type == static_cast<uint32_t>(TSPrimitiveType::SYMBOL);
302     }
303 
304     // In addition to normal number types, null, undefined, boolean types will be converted to numeric types when doing
305     // some numerical computation.
IsPrimitiveNumberType()306     bool IsPrimitiveNumberType() const
307     {
308         return IsNumberType() || IsNullType() || IsUndefinedType() || IsBooleanType();
309     }
310 
IsPrimitiveIntType()311     bool IsPrimitiveIntType() const
312     {
313         return IsIntType() || IsNullType() || IsBooleanType();
314     }
315 
IsGCRelated()316     bool IsGCRelated() const
317     {
318         return (type_ & (~GateType::GC_MASK)) == 0;
319     }
320 
321     bool operator ==(const GateType &other) const
322     {
323         return type_ == other.type_;
324     }
325 
326     bool operator !=(const GateType &other) const
327     {
328         return type_ != other.type_;
329     }
330 
331     bool operator <(const GateType &other) const
332     {
333         return type_ < other.type_;
334     }
335 
336     bool operator <=(const GateType &other) const
337     {
338         return type_ <= other.type_;
339     }
340 
341     bool operator >(const GateType &other) const
342     {
343         return type_ > other.type_;
344     }
345 
346     bool operator >=(const GateType &other) const
347     {
348         return type_ >= other.type_;
349     }
350 
GetType()351     uint32_t GetType() const
352     {
353         return type_ & (~MIR_TYPE_MASK);
354     }
355 
GetGTRef()356     GlobalTSTypeRef GetGTRef() const
357     {
358         // linxiang shoult remove in part3
359         GlobalTSTypeRef empty;
360         return empty;
361     }
362 
363 private:
364     static constexpr uint32_t GC_MASK = ~(1 << 30); // 30 : the 30-th bit is unset implies GC-related type
365     static constexpr uint32_t NO_GC_MASK = ~(1 << 29); // 29 : the 29-th bit is unset implies NO-GC-related type
366     // 31 : the 31-st bit is set implies MIR type
367     static constexpr uint32_t MIR_BASE_BITS = (1 << 31) | (1 << 30) | (1 << 29);
368     static constexpr uint32_t EMPTY_TYPE = 1 << 28; // 1 : means offset of empty type
369     static constexpr uint32_t MIR_TYPE_MASK = MIR_BASE_BITS | EMPTY_TYPE;
370 
371     static constexpr uint32_t NJS_VALUE = MIR_BASE_BITS;                           // (1110)
372     static constexpr uint32_t TAGGED_VALUE = MIR_BASE_BITS & GC_MASK & NO_GC_MASK; // (1000)
373     static constexpr uint32_t TAGGED_POINTER = MIR_BASE_BITS & GC_MASK;            // (1010)
374     static constexpr uint32_t TAGGED_NPOINTER = MIR_BASE_BITS & NO_GC_MASK;        // (1100)
375     static constexpr uint32_t EMPTY = NJS_VALUE + EMPTY_TYPE;                      // (1111)
376     static constexpr uint32_t SIZE_BITS = 4;
377 
378     static constexpr uint32_t VALID_BITS = sizeof(uint32_t) * 8;
379     static_assert((SIZE_BITS + GlobalTSTypeRef::GetSizeBits()) <= VALID_BITS);
380 
381     uint32_t type_ {0};
382 };
383 
384 enum class ConvertSupport : uint8_t {
385     ENABLE,
386     // Not support conversion from srcType to dstType. It is necessary to use 'deopt' to ensure semantic correctness.
387     DISABLE
388 };
389 
390 class Type {
391 public:
392     explicit Type(GateType payload);
393     [[nodiscard]] bool IsBitset() const;
394     ~Type();
395 
396 private:
397     GateType payload;
398 };
399 }  // namespace panda::ecmascript::kungfu
400 
401 #endif  // ECMASCRIPT_COMPILER_TYPE_H
402