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