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