• 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 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