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