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