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