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_JS_TAGGED_VALUE_H 17 #define ECMASCRIPT_JS_TAGGED_VALUE_H 18 19 #include "ecmascript/base/bit_helper.h" 20 #include "ecmascript/base/config.h" 21 #include "ecmascript/mem/c_string.h" 22 #include "ecmascript/mem/mem_common.h" 23 #include "ecmascript/js_tagged_value_internals.h" 24 namespace panda::ecmascript { 25 class JSArray; 26 class JSObject; 27 class JSTaggedNumber; 28 template<typename T> 29 class JSHandle; 30 class TaggedArray; 31 class LinkedHashMap; 32 class LinkedHashSet; 33 class PropertyDescriptor; 34 class OperationResult; 35 class EcmaString; 36 class JSThread; 37 struct Reference; 38 39 namespace JSShared { 40 // check mode for js shared 41 enum SCheckMode: uint8_t { 42 SKIP = 0, 43 CHECK 44 }; 45 } // namespace JSShared 46 47 using SCheckMode = JSShared::SCheckMode; 48 49 static constexpr double SAFE_NUMBER = 9007199254740991LL; 50 51 // Don't switch the order! 52 enum PreferredPrimitiveType : uint8_t { PREFER_NUMBER = 0, PREFER_STRING, NO_PREFERENCE }; 53 54 // Result of an abstract relational comparison of x and y, implemented according 55 // to ES6 section 7.2.11 Abstract Relational Comparison. 56 enum class ComparisonResult { 57 LESS, // x < y 58 EQUAL, // x = y 59 GREAT, // x > y 60 UNDEFINED // at least one of x or y was undefined or NaN 61 }; 62 63 enum class ClassKind : uint8_t { SENDABLE = 0, NON_SENDABLE }; 64 class JSTaggedValue : public JSTaggedValueInternals { 65 public: Cast(TaggedObject * object)66 static JSTaggedValue Cast(TaggedObject *object) 67 { 68 return JSTaggedValue(object); 69 } 70 71 static const JSTaggedType NULL_POINTER = VALUE_HOLE; 72 static const JSTaggedType INVALID_VALUE_LIMIT = 0x40000ULL; 73 CastDoubleToTagged(double value)74 static inline JSTaggedType CastDoubleToTagged(double value) 75 { 76 return base::bit_cast<JSTaggedType>(value); 77 } 78 CastTaggedToDouble(JSTaggedType value)79 static inline double CastTaggedToDouble(JSTaggedType value) 80 { 81 return base::bit_cast<double>(value); 82 } 83 TaggedTypeSize()84 static inline constexpr size_t TaggedTypeSize() 85 { 86 return sizeof(JSTaggedType); 87 } 88 89 static JSHandle<JSTaggedValue> PublishSharedValue(JSThread *thread, JSHandle<JSTaggedValue> value); 90 91 static JSHandle<JSTaggedValue> PublishSharedValueSlow(JSThread *thread, JSHandle<JSTaggedValue> value); 92 93 static constexpr size_t SizeArch32 = sizeof(JSTaggedType); 94 95 static constexpr size_t SizeArch64 = sizeof(JSTaggedType); 96 97 explicit JSTaggedValue(void *) = delete; 98 JSTaggedValue()99 ARK_INLINE constexpr JSTaggedValue() : value_(JSTaggedValue::NULL_POINTER) {} 100 JSTaggedValue(JSTaggedType v)101 ARK_INLINE constexpr explicit JSTaggedValue(JSTaggedType v) : value_(v) {} 102 JSTaggedValue(int v)103 ARK_INLINE constexpr explicit JSTaggedValue(int v) : value_(static_cast<JSTaggedType>(v) | TAG_INT) {} 104 JSTaggedValue(unsigned int v)105 ARK_INLINE explicit JSTaggedValue(unsigned int v) 106 { 107 if (static_cast<int32_t>(v) < 0) { 108 value_ = JSTaggedValue(static_cast<double>(v)).GetRawData(); 109 return; 110 } 111 value_ = JSTaggedValue(static_cast<int32_t>(v)).GetRawData(); 112 } 113 JSTaggedValue(bool v)114 ARK_INLINE constexpr explicit JSTaggedValue(bool v) 115 : value_(static_cast<JSTaggedType>(v) | TAG_BOOLEAN_MASK) {} 116 JSTaggedValue(double v)117 ARK_INLINE explicit JSTaggedValue(double v) 118 { 119 ASSERT_PRINT(!IsImpureNaN(v), "pureNaN will break the encoding of tagged double: " 120 << std::hex << CastDoubleToTagged(v)); 121 value_ = CastDoubleToTagged(v) + DOUBLE_ENCODE_OFFSET; 122 } 123 JSTaggedValue(const TaggedObject * v)124 ARK_INLINE explicit JSTaggedValue(const TaggedObject *v) : value_(static_cast<JSTaggedType>(ToUintPtr(v))) {} 125 JSTaggedValue(int64_t v)126 ARK_INLINE explicit JSTaggedValue(int64_t v) 127 { 128 if (UNLIKELY(static_cast<int32_t>(v) != v)) { 129 value_ = JSTaggedValue(static_cast<double>(v)).GetRawData(); 130 return; 131 } 132 value_ = JSTaggedValue(static_cast<int32_t>(v)).GetRawData(); 133 } 134 135 ~JSTaggedValue() = default; 136 DEFAULT_COPY_SEMANTIC(JSTaggedValue); 137 DEFAULT_MOVE_SEMANTIC(JSTaggedValue); 138 CreateWeakRef()139 inline void CreateWeakRef() 140 { 141 ASSERT_PRINT(IsHeapObject() && ((value_ & TAG_WEAK) == 0U), 142 "The least significant two bits of JSTaggedValue are not zero."); 143 value_ = value_ | TAG_WEAK; 144 } 145 RemoveWeakTag()146 inline void RemoveWeakTag() 147 { 148 ASSERT_PRINT(IsHeapObject() && ((value_ & TAG_WEAK) == TAG_WEAK), "The tagged value is not a weak ref."); 149 value_ = value_ & (~TAG_WEAK); 150 } 151 CreateAndGetWeakRef()152 inline JSTaggedValue CreateAndGetWeakRef() const 153 { 154 ASSERT_PRINT(IsHeapObject() && ((value_ & TAG_WEAK) == 0U), 155 "The least significant two bits of JSTaggedValue are not zero."); 156 return JSTaggedValue(value_ | TAG_WEAK); 157 } 158 GetWeakRawValue()159 inline JSTaggedValue GetWeakRawValue() const 160 { 161 if (IsHeapObject()) { 162 return JSTaggedValue(value_ & (~TAG_WEAK)); 163 } 164 return JSTaggedValue(value_); 165 } 166 IsWeak()167 ARK_INLINE bool IsWeak() const 168 { 169 return ((value_ & TAG_WEAK_MASK) == TAG_WEAK); 170 } 171 IsDouble()172 ARK_INLINE bool IsDouble() const 173 { 174 return !IsInt() && !IsObject(); 175 } 176 IsInt()177 ARK_INLINE bool IsInt() const 178 { 179 return (value_ & TAG_MARK) == TAG_INT; 180 } 181 IsSpecial()182 ARK_INLINE bool IsSpecial() const 183 { 184 return ((value_ & TAG_SPECIAL_MASK) == TAG_SPECIAL) || IsHole(); 185 } 186 IsObject()187 ARK_INLINE bool IsObject() const 188 { 189 return ((value_ & TAG_MARK) == TAG_OBJECT); 190 } 191 GetWeakReferentUnChecked()192 ARK_INLINE TaggedObject *GetWeakReferentUnChecked() const 193 { 194 return reinterpret_cast<TaggedObject *>(value_ & (~TAG_WEAK)); 195 } 196 IsHeapObject()197 ARK_INLINE bool IsHeapObject() const 198 { 199 return ((value_ & TAG_HEAPOBJECT_MASK) == 0U); 200 } 201 IsInvalidValue()202 ARK_INLINE bool IsInvalidValue() const 203 { 204 return value_ <= INVALID_VALUE_LIMIT; 205 } 206 GetDouble()207 ARK_INLINE double GetDouble() const 208 { 209 ASSERT_PRINT(IsDouble(), "can not convert JSTaggedValue to Double : " << std::hex << value_); 210 return CastTaggedToDouble(value_ - DOUBLE_ENCODE_OFFSET); 211 } 212 GetInt()213 ARK_INLINE int GetInt() const 214 { 215 ASSERT_PRINT(IsInt(), "can not convert JSTaggedValue to Int :" << std::hex << value_); 216 return static_cast<int>(value_ & (~TAG_MARK)); 217 } 218 GetLargeUInt()219 ARK_INLINE uint64_t GetLargeUInt() const 220 { 221 ASSERT_PRINT(IsInt(), "can not convert JSTaggedValue to Int :" << std::hex << value_); 222 return (value_ & (~TAG_MARK)); 223 } 224 GetRawData()225 ARK_INLINE JSTaggedType GetRawData() const 226 { 227 return value_; 228 } 229 230 // This function returns the heap object pointer which may have the weak tag. GetRawHeapObject()231 ARK_INLINE TaggedObject *GetRawHeapObject() const 232 { 233 ASSERT_PRINT(IsHeapObject(), "can not convert JSTaggedValue to HeapObject :" << std::hex << value_); 234 return reinterpret_cast<TaggedObject *>(value_); 235 } 236 GetWeakReferent()237 ARK_INLINE TaggedObject *GetWeakReferent() const 238 { 239 ASSERT_PRINT(IsWeak(), "can not convert JSTaggedValue to WeakRef HeapObject :" << std::hex << value_); 240 return reinterpret_cast<TaggedObject *>(value_ & (~TAG_WEAK)); 241 } 242 Cast(void * ptr)243 static ARK_INLINE JSTaggedType Cast(void *ptr) 244 { 245 ASSERT_PRINT(sizeof(void *) == TaggedTypeSize(), "32bit platform is not support yet"); 246 return static_cast<JSTaggedType>(ToUintPtr(ptr)); 247 } 248 IsFalse()249 ARK_INLINE bool IsFalse() const 250 { 251 return value_ == VALUE_FALSE; 252 } 253 IsTrue()254 ARK_INLINE bool IsTrue() const 255 { 256 return value_ == VALUE_TRUE; 257 } 258 IsUndefined()259 ARK_INLINE bool IsUndefined() const 260 { 261 return value_ == VALUE_UNDEFINED; 262 } 263 IsNull()264 ARK_INLINE bool IsNull() const 265 { 266 return value_ == VALUE_NULL; 267 } 268 IsUndefinedOrNull()269 ARK_INLINE bool IsUndefinedOrNull() const 270 { 271 return ((value_ & TAG_HEAPOBJECT_MASK) == TAG_SPECIAL); 272 } 273 IsHole()274 ARK_INLINE bool IsHole() const 275 { 276 return value_ == VALUE_HOLE || value_ == 0U; 277 } 278 IsException()279 ARK_INLINE bool IsException() const 280 { 281 return value_ == VALUE_EXCEPTION; 282 } 283 IsNaN()284 ARK_INLINE bool IsNaN() const 285 { 286 if (!IsDouble()) { 287 return false; 288 } 289 double untagged = GetDouble(); 290 return std::isnan(untagged); 291 } 292 IsImpureNaN(double value)293 static ARK_INLINE bool IsImpureNaN(double value) 294 { 295 // Tests if the double value would break tagged double encoding. 296 return base::bit_cast<JSTaggedType>(value) >= (TAG_INT - DOUBLE_ENCODE_OFFSET); 297 } 298 299 ARK_INLINE bool operator==(const JSTaggedValue &other) const 300 { 301 return value_ == other.value_; 302 } 303 304 ARK_INLINE bool operator!=(const JSTaggedValue &other) const 305 { 306 return value_ != other.value_; 307 } 308 IsWeakForHeapObject()309 ARK_INLINE bool IsWeakForHeapObject() const 310 { 311 return (value_ & TAG_WEAK) == 1U; 312 } 313 False()314 static ARK_INLINE constexpr JSTaggedValue False() 315 { 316 return JSTaggedValue(VALUE_FALSE); 317 } 318 True()319 static ARK_INLINE constexpr JSTaggedValue True() 320 { 321 return JSTaggedValue(VALUE_TRUE); 322 } 323 Undefined()324 static ARK_INLINE constexpr JSTaggedValue Undefined() 325 { 326 return JSTaggedValue(VALUE_UNDEFINED); 327 } 328 Null()329 static ARK_INLINE constexpr JSTaggedValue Null() 330 { 331 return JSTaggedValue(VALUE_NULL); 332 } 333 Hole()334 static ARK_INLINE constexpr JSTaggedValue Hole() 335 { 336 return JSTaggedValue(VALUE_HOLE); 337 } 338 Exception()339 static ARK_INLINE constexpr JSTaggedValue Exception() 340 { 341 return JSTaggedValue(VALUE_EXCEPTION); 342 } 343 GetNumber()344 ARK_INLINE double GetNumber() const 345 { 346 return IsInt() ? GetInt() : GetDouble(); 347 } 348 GetTaggedObject()349 ARK_INLINE TaggedObject *GetTaggedObject() const 350 { 351 ASSERT_PRINT(IsHeapObject() && ((value_ & TAG_WEAK) == 0U), 352 "can not convert JSTaggedValue to HeapObject :" << std::hex << value_); 353 return reinterpret_cast<TaggedObject *>(value_); 354 } 355 GetHeapObject()356 ARK_INLINE TaggedObject *GetHeapObject() const 357 { 358 if (IsWeakForHeapObject()) { 359 return GetTaggedWeakRef(); 360 } 361 return GetTaggedObject(); 362 } 363 GetRawTaggedObject()364 ARK_INLINE TaggedObject *GetRawTaggedObject() const 365 { 366 return reinterpret_cast<TaggedObject *>(GetRawHeapObject()); 367 } 368 GetTaggedWeakRef()369 ARK_INLINE TaggedObject *GetTaggedWeakRef() const 370 { 371 return reinterpret_cast<TaggedObject *>(GetWeakReferent()); 372 } 373 374 static JSTaggedValue OrdinaryToPrimitive(JSThread *thread, const JSHandle<JSTaggedValue> &tagged, 375 PreferredPrimitiveType type = PREFER_NUMBER); 376 377 // ecma6 7.1 Type Conversion 378 static JSTaggedValue ToPrimitive(JSThread *thread, const JSHandle<JSTaggedValue> &tagged, 379 PreferredPrimitiveType type = NO_PREFERENCE); 380 bool ToBoolean() const; 381 static JSTaggedNumber ToNumber(JSThread *thread, JSTaggedValue tagged); 382 static JSTaggedNumber ToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 383 static JSTaggedValue ToBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 384 static JSTaggedValue ToBigInt64(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 385 static JSTaggedValue ToBigUint64(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 386 static JSTaggedNumber ToInteger(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 387 static JSHandle<JSTaggedValue> ToNumeric(JSThread *thread, JSHandle<JSTaggedValue> tagged); 388 static int32_t ToInt32(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 389 static uint32_t ToUint32(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 390 static int16_t ToInt16(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 391 static uint16_t ToUint16(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 392 static int8_t ToInt8(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 393 static uint8_t ToUint8(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 394 static uint8_t ToUint8Clamp(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 395 static JSHandle<EcmaString> PUBLIC_API ToString(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 396 static JSHandle<EcmaString> ToString(JSThread *thread, JSTaggedValue val); 397 static JSHandle<JSObject> ToObject(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 398 static JSHandle<JSTaggedValue> ToPropertyKey(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 399 static JSTaggedNumber ToLength(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 400 static JSTaggedValue CanonicalNumericIndexString(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 401 static JSTaggedNumber ToIndex(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 402 static JSTaggedNumber StringToDouble(JSTaggedValue tagged); 403 static JSTaggedNumber StringToNumber(JSTaggedValue tagged); 404 405 static bool ToArrayLength(JSThread *thread, const JSHandle<JSTaggedValue> &tagged, uint32_t *output); 406 static bool ToElementIndex(JSTaggedValue key, uint32_t *output); 407 static bool StringToElementIndex(JSTaggedValue key, uint32_t *output); 408 static bool IsPureString(JSTaggedValue key); 409 uint32_t GetArrayLength() const; 410 411 // ecma6 7.2 Testing and Comparison Operations 412 bool IsCallable() const; 413 bool IsConstructor() const; 414 bool IsExtensible(JSThread *thread) const; 415 bool IsInteger() const; 416 bool WithinInt32(bool acceptsNegativeZero = false) const; 417 bool IsZero() const; 418 bool IsExactlyZero() const; 419 static bool IsPropertyKey(const JSHandle<JSTaggedValue> &key); 420 static JSHandle<JSTaggedValue> RequireObjectCoercible(JSThread *thread, const JSHandle<JSTaggedValue> &tagged, 421 const char *message = "RequireObjectCoercible throw Error"); 422 static bool SameValue(const JSTaggedValue &x, const JSTaggedValue &y); 423 static bool SameValue(const JSHandle<JSTaggedValue> &xHandle, const JSHandle<JSTaggedValue> &yHandle); 424 static bool SameValueZero(const JSTaggedValue &x, const JSTaggedValue &y); 425 static bool Less(JSThread *thread, const JSHandle<JSTaggedValue> &x, const JSHandle<JSTaggedValue> &y); 426 static bool Equal(JSThread *thread, const JSHandle<JSTaggedValue> &x, const JSHandle<JSTaggedValue> &y); 427 static bool StrictEqual(const JSThread *thread, const JSHandle<JSTaggedValue> &x, const JSHandle<JSTaggedValue> &y); 428 static bool StrictEqual(const JSTaggedValue &x, const JSTaggedValue &y); 429 static bool SameValueNumberic(const JSTaggedValue &x, const JSTaggedValue &y); 430 431 // ES6 7.4 Operations on Iterator Objects 432 static JSObject *CreateIterResultObject(JSThread *thread, const JSHandle<JSTaggedValue> &value, bool done); 433 434 // ECMAScript 2023 allow the use of most Symbols as keys in weak collections 435 static bool CanBeHeldWeakly(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 436 437 // ecma6 7.3 438 static OperationResult GetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 439 const JSHandle<JSTaggedValue> &key, SCheckMode sCheckMode = SCheckMode::CHECK); 440 441 static OperationResult GetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, uint32_t key); 442 static OperationResult GetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 443 const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &receiver); 444 static bool SetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, uint32_t key, 445 const JSHandle<JSTaggedValue> &value, bool mayThrow = false); 446 447 static bool PUBLIC_API SetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 448 const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value, 449 bool mayThrow = false, SCheckMode checkMode = SCheckMode::CHECK); 450 451 static bool SetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, 452 const JSHandle<JSTaggedValue> &value, const JSHandle<JSTaggedValue> &receiver, 453 bool mayThrow = false); 454 static bool DeleteProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 455 const JSHandle<JSTaggedValue> &key); 456 static bool DeletePropertyOrThrow(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 457 const JSHandle<JSTaggedValue> &key); 458 static bool DefinePropertyOrThrow(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 459 const JSHandle<JSTaggedValue> &key, const PropertyDescriptor &desc); 460 static bool DefineOwnProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 461 const JSHandle<JSTaggedValue> &key, const PropertyDescriptor &desc, 462 SCheckMode sCheckMode = SCheckMode::CHECK); 463 static bool GetOwnProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, 464 PropertyDescriptor &desc); 465 static bool SetPrototype(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 466 const JSHandle<JSTaggedValue> &proto, bool isChangeProto = false); 467 static JSTaggedValue GetPrototype(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 468 static bool PreventExtensions(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 469 static JSHandle<TaggedArray> GetOwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 470 static JSHandle<TaggedArray> GetAllPropertyKeys(JSThread *thread, 471 const JSHandle<JSTaggedValue> &obj, uint32_t filter); 472 static JSHandle<TaggedArray> GetOwnEnumPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 473 static bool HasProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key); 474 static bool HasProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, uint32_t key); 475 static bool HasOwnProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 476 const JSHandle<JSTaggedValue> &key); 477 static bool GlobalHasOwnProperty(JSThread *thread, const JSHandle<JSTaggedValue> &key); 478 479 // Type 480 bool IsJSMap() const; 481 bool IsJSSharedMap() const; 482 bool IsJSSet() const; 483 bool IsJSSharedSet() const; 484 bool IsJSWeakMap() const; 485 bool IsJSWeakSet() const; 486 bool IsJSWeakRef() const; 487 bool IsJSFinalizationRegistry() const; 488 bool IsCellRecord() const; 489 bool IsJSRegExp() const; 490 bool IsNumber() const; 491 bool IsBigInt() const; 492 bool IsString() const; 493 bool IsLineString() const; 494 bool IsConstantString() const; 495 bool IsTreeString() const; 496 bool IsSlicedString() const; 497 bool IsStringOrSymbol() const; 498 bool IsLexicalEnv() const; 499 bool PUBLIC_API IsTaggedArray() const; 500 bool IsDictionary() const; 501 bool IsByteArray() const; 502 bool IsConstantPool() const; 503 bool IsAOTLiteralInfo() const; 504 bool IsExtraProfileTypeInfo() const; 505 bool IsProfileTypeInfoCell() const; 506 bool IsProfileTypeInfoCell0() const; 507 bool IsFunctionTemplate() const; 508 bool IsVTable() const; 509 bool IsLinkedNode() const; 510 bool IsRBTreeNode() const; 511 bool IsNativePointer() const; 512 bool IsJSNativePointer() const; 513 bool CheckIsJSNativePointer() const; 514 bool IsBoolean() const; 515 bool IsSymbol() const; 516 bool IsJSObject() const; 517 bool IsOnlyJSObject() const; 518 bool IsJSGlobalObject() const; 519 bool IsJSError() const; 520 bool IsArray(JSThread *thread) const; 521 bool IsSArray(JSThread *thread) const; 522 bool IsCOWArray() const; 523 bool IsMutantTaggedArray() const; 524 bool IsJSArray() const; 525 bool IsJSSharedArray() const; 526 bool PUBLIC_API IsJSCOWArray() const; 527 bool IsStableJSArray(JSThread *thread) const; 528 bool IsStableJSArguments(JSThread *thread) const; 529 bool IsTypedArray() const; 530 bool IsJSTypedArray() const; 531 bool IsJSInt8Array() const; 532 bool IsJSUint8Array() const; 533 bool IsJSUint8ClampedArray() const; 534 bool IsJSInt16Array() const; 535 bool IsJSUint16Array() const; 536 bool IsJSInt32Array() const; 537 bool IsJSUint32Array() const; 538 bool IsJSFloat32Array() const; 539 bool IsJSFloat64Array() const; 540 bool IsJSBigInt64Array() const; 541 bool IsJSBigUint64Array() const; 542 bool IsSharedTypedArray() const; 543 bool IsJSSharedTypedArray() const; 544 bool IsJSSharedInt8Array() const; 545 bool IsJSSharedUint8Array() const; 546 bool IsJSSharedUint8ClampedArray() const; 547 bool IsJSSharedInt16Array() const; 548 bool IsJSSharedUint16Array() const; 549 bool IsJSSharedInt32Array() const; 550 bool IsJSSharedUint32Array() const; 551 bool IsJSSharedFloat32Array() const; 552 bool IsJSSharedFloat64Array() const; 553 bool IsJSSharedBigInt64Array() const; 554 bool IsJSSharedBigUint64Array() const; 555 bool IsArguments() const; 556 bool IsDate() const; 557 bool IsBoundFunction() const; 558 bool IsJSIntlBoundFunction() const; 559 bool IsProxyRevocFunction() const; 560 bool IsJSAsyncFunction() const; 561 bool IsJSSharedAsyncFunction() const; 562 bool IsJSAsyncAwaitStatusFunction() const; 563 bool IsClassConstructor() const; 564 bool IsClassPrototype() const; 565 bool IsJSFunction() const; 566 bool IsJSFunctionBase() const; 567 bool CheckIsJSFunctionBase() const; 568 bool IsECMAObject() const; 569 bool IsJSPrimitiveRef() const; 570 bool IsJSPrimitive() const; 571 bool IsAccessorData() const; 572 bool IsInternalAccessor() const; 573 bool IsAccessor() const; 574 bool IsJSGlobalEnv() const; 575 bool PUBLIC_API IsJSProxy() const; 576 bool CheckIsJSProxy() const; 577 bool IsJSHClass() const; 578 bool IsForinIterator() const; 579 bool IsStringIterator() const; 580 bool IsArrayBuffer() const; 581 bool IsSharedArrayBuffer() const; 582 bool IsSendableArrayBuffer() const; 583 584 bool IsJSSetIterator() const; 585 bool IsJSSharedSetIterator() const; 586 bool IsJSRegExpIterator() const; 587 bool IsJSMapIterator() const; 588 bool IsJSSharedMapIterator() const; 589 bool IsJSArrayIterator() const; 590 bool IsJSSharedArrayIterator() const; 591 bool IsIterator() const; 592 bool IsAsyncIterator() const; 593 bool IsGeneratorFunction() const; 594 bool IsAsyncGeneratorFunction() const; 595 bool IsGeneratorObject() const; 596 bool IsGeneratorContext() const; 597 bool IsAsyncGeneratorRequest() const; 598 bool IsAsyncIteratorRecord() const; 599 bool IsAsyncFromSyncIterator() const; 600 bool IsAsyncGeneratorObject() const; 601 bool IsAsyncFuncObject() const; 602 bool IsJSPromise() const; 603 bool IsRecord() const; 604 bool IsPromiseReaction() const; 605 bool IsProgram() const; 606 bool IsJSPromiseReactionFunction() const; 607 bool IsJSPromiseExecutorFunction() const; 608 bool IsJSAsyncModuleFulfilledFunction() const; 609 bool IsJSAsyncModuleRejectedFunction() const; 610 bool IsJSAsyncFromSyncIterUnwarpFunction() const; 611 bool IsJSPromiseAllResolveElementFunction() const; 612 bool IsJSAsyncGeneratorResNextRetProRstFtn() const; 613 bool IsPromiseCapability() const; 614 bool IsPromiseIteratorRecord() const; 615 bool IsPromiseRecord() const; 616 bool IsJSPromiseAnyRejectElementFunction() const; 617 bool IsJSPromiseAllSettledElementFunction() const; 618 bool IsJSPromiseFinallyFunction() const; 619 bool IsJSPromiseValueThunkOrThrowerFunction() const; 620 bool IsResolvingFunctionsRecord() const; 621 bool IsCompletionRecord() const; 622 bool IsDataView() const; 623 bool IsTemplateMap() const; 624 bool IsMicroJobQueue() const; 625 bool IsPendingJob() const; 626 bool IsJSLocale() const; 627 bool IsJSDateTimeFormat() const; 628 bool IsJSRelativeTimeFormat() const; 629 bool IsJSIntl() const; 630 bool IsJSNumberFormat() const; 631 bool IsJSCollator() const; 632 bool IsJSPluralRules() const; 633 bool IsJSDisplayNames() const; 634 bool IsJSSegmenter() const; 635 bool IsJSSegments() const; 636 bool IsJSSegmentIterator() const; 637 bool IsJSListFormat() const; 638 bool IsMethod() const; 639 bool IsClassLiteral() const; 640 641 // non ECMA standard jsapis 642 bool IsJSAPIArrayList() const; 643 bool IsJSAPIArrayListIterator() const; 644 bool IsJSAPIHashMap() const; 645 bool IsJSAPIHashMapIterator() const; 646 bool IsJSAPIHashSet() const; 647 bool IsJSAPIHashSetIterator() const; 648 bool IsJSAPILightWeightMap() const; 649 bool IsJSAPILightWeightMapIterator() const; 650 bool IsJSAPILightWeightSet() const; 651 bool IsJSAPILightWeightSetIterator() const; 652 bool IsJSAPITreeMap() const; 653 bool IsJSAPITreeSet() const; 654 bool IsJSAPITreeMapIterator() const; 655 bool IsJSAPITreeSetIterator() const; 656 bool IsJSAPIVector() const; 657 bool IsJSAPIVectorIterator() const; 658 bool IsJSAPIBitVector() const; 659 bool IsJSAPIBitVectorIterator() const; 660 bool IsJSAPIQueue() const; 661 bool IsJSAPIQueueIterator() const; 662 bool IsJSAPIPlainArray() const; 663 bool IsJSAPIPlainArrayIterator() const; 664 bool IsJSAPIDeque() const; 665 bool IsJSAPIDequeIterator() const; 666 bool IsJSAPIStack() const; 667 bool IsJSAPIStackIterator() const; 668 bool IsJSAPIList() const; 669 bool IsJSAPILinkedList() const; 670 bool IsJSAPIListIterator() const; 671 bool IsJSAPILinkedListIterator() const; 672 bool IsSpecialContainer() const; 673 bool HasOrdinaryGet() const; 674 bool IsPrototypeHandler() const; 675 bool IsTransitionHandler() const; 676 bool IsTransWithProtoHandler() const; 677 bool IsStoreAOTHandler() const; 678 bool IsPropertyBox() const; 679 bool IsProtoChangeMarker() const; 680 bool IsProtoChangeDetails() const; 681 bool IsMarkerCell() const; 682 bool IsTrackInfoObject() const; 683 bool IsSpecialKeysObject() const; 684 bool IsSlowKeysObject() const; 685 bool IsRegularObject() const; 686 bool IsMachineCodeObject() const; 687 bool IsClassInfoExtractor() const; 688 689 bool IsCjsExports() const; 690 bool IsCjsModule() const; 691 bool IsCjsRequire() const; 692 bool IsModuleRecord() const; 693 bool IsSourceTextModule() const; 694 bool IsImportEntry() const; 695 bool IsLocalExportEntry() const; 696 bool IsIndirectExportEntry() const; 697 bool IsStarExportEntry() const; 698 bool IsModuleBinding() const; 699 bool IsResolvedBinding() const; 700 bool IsResolvedIndexBinding() const; 701 bool IsResolvedRecordIndexBinding() const; 702 bool IsResolvedRecordBinding() const; 703 bool IsModuleNamespace() const; 704 bool IsNativeModuleFailureInfo() const; 705 bool IsJSSharedObject() const; 706 bool IsJSSharedFunction() const; 707 bool IsJSShared() const; 708 bool IsSharedType() const; 709 710 bool PUBLIC_API IsInSharedHeap() const; 711 bool IsInSharedSweepableSpace() const; 712 static bool IsSameTypeOrHClass(JSTaggedValue x, JSTaggedValue y); 713 714 static ComparisonResult Compare(JSThread *thread, const JSHandle<JSTaggedValue> &x, 715 const JSHandle<JSTaggedValue> &y); 716 static int IntLexicographicCompare(JSTaggedValue x, JSTaggedValue y); 717 static int DoubleLexicographicCompare(JSTaggedValue x, JSTaggedValue y); 718 static ComparisonResult StrictNumberCompare(double x, double y); 719 static bool StrictNumberEquals(double x, double y); 720 static bool StrictIntEquals(int x, int y); 721 static bool StringCompare(EcmaString *xStr, EcmaString *yStr); 722 723 static JSHandle<JSTaggedValue> ToPrototypeOrObj(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 724 inline uint32_t GetKeyHashCode() const; 725 uint32_t GetStringKeyHashCode() const; 726 static JSTaggedValue GetSuperBase(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 727 static JSTaggedValue TryCastDoubleToInt32(double d); 728 729 void DumpTaggedValue(std::ostream &os) const DUMP_API_ATTR; 730 void DumpTaggedValueType(std::ostream &os) const DUMP_API_ATTR; 731 void Dump(std::ostream &os, bool isPrivacy = false) const DUMP_API_ATTR; 732 void D() const DUMP_API_ATTR; 733 void DumpForSnapshot(std::vector<Reference> &vec, bool isVmMode = true) const; 734 static void DesensitizedDump(const JSHandle<JSTaggedValue> &obj); 735 static void DV(JSTaggedType val) DUMP_API_ATTR; 736 friend std::ostream& operator<<(std::ostream& os, const JSTaggedValue& value) 737 { 738 value.Dump(os); 739 return os; 740 } 741 742 private: 743 JSTaggedType value_; 744 745 inline double ExtractNumber() const; 746 747 void DumpSpecialValue(std::ostream &os) const; 748 void DumpHeapObjectType(std::ostream &os) const; 749 750 // non ECMA standard jsapis 751 static bool HasContainerProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 752 const JSHandle<JSTaggedValue> &key); 753 static JSHandle<TaggedArray> GetOwnContainerPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 754 static JSHandle<TaggedArray> GetOwnContainerEnumPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 755 static bool GetContainerProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 756 const JSHandle<JSTaggedValue> &key, PropertyDescriptor &desc); 757 static OperationResult GetJSAPIProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 758 const JSHandle<JSTaggedValue> &key); 759 static bool SetJSAPIProperty(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 760 const JSHandle<JSTaggedValue> &key, 761 const JSHandle<JSTaggedValue> &value); 762 static JSHandle<EcmaString> NativePointerToString(JSThread *thread, const JSHandle<JSTaggedValue> &tagged); 763 static bool EqualNumber(JSThread *thread, const JSHandle<JSTaggedValue> &x, 764 const JSHandle<JSTaggedValue> &y); 765 static bool EqualString(JSThread *thread, const JSHandle<JSTaggedValue> &x, 766 const JSHandle<JSTaggedValue> &y); 767 static bool EqualSymbol(JSThread *thread, const JSHandle<JSTaggedValue> &x, 768 const JSHandle<JSTaggedValue> &y); 769 static bool EqualBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &x, 770 const JSHandle<JSTaggedValue> &y); 771 static bool EqualHeapObject(JSThread *thread, const JSHandle<JSTaggedValue> &x, 772 const JSHandle<JSTaggedValue> &y); 773 static bool EqualNullOrUndefined(const JSHandle<JSTaggedValue> &x, 774 const JSHandle<JSTaggedValue> &y); WrapUint64(uint64_t v)775 static ARK_INLINE JSTaggedValue WrapUint64(uint64_t v) 776 { 777 return JSTaggedValue(static_cast<JSTaggedType>(v) | TAG_INT); 778 } UnwrapToUint64(JSTaggedValue v)779 static ARK_INLINE uint64_t UnwrapToUint64(JSTaggedValue v) 780 { 781 ASSERT_PRINT(v.IsInt(), "can not convert JSTaggedValue to Int :" << std::hex << v.GetRawData()); 782 return static_cast<uint64_t>(v.GetRawData() & (~TAG_INT)); 783 } 784 static void DumpExceptionObject(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 785 786 friend class PropertyAttributes; 787 friend class ICRuntimeStub; 788 friend class LoadHandler; 789 friend class StoreHandler; 790 }; 791 STATIC_ASSERT_EQ_ARCH(sizeof(JSTaggedValue), JSTaggedValue::SizeArch32, JSTaggedValue::SizeArch64); 792 } // namespace panda::ecmascript 793 #endif // ECMASCRIPT_JS_TAGGED_VALUE_H 794