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