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