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