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