• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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