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