• 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_TAGGED_VALUE_INL_H
17 #define ECMASCRIPT_TAGGED_VALUE_INL_H
18 
19 #include "ecmascript/js_tagged_value.h"
20 
21 #include "ecmascript/accessor_data.h"
22 #include "ecmascript/base/error_helper.h"
23 #include "ecmascript/base/number_helper.h"
24 #include "ecmascript/base/string_helper.h"
25 #include "ecmascript/ecma_macros.h"
26 #include "ecmascript/ecma_runtime_call_info.h"
27 #include "ecmascript/js_bigint.h"
28 #include "ecmascript/js_object.h"
29 #include "ecmascript/js_proxy.h"
30 #include "ecmascript/js_symbol.h"
31 #include "ecmascript/js_tagged_number.h"
32 #include "ecmascript/js_thread.h"
33 #include "ecmascript/mem/c_containers.h"
34 #include "ecmascript/mem/tagged_object-inl.h"
35 #include "ecmascript/module/js_module_namespace.h"
36 #include "ecmascript/object_factory.h"
37 
38 namespace panda::ecmascript {
39 // ecma6 7.1 Type Conversion
40 static constexpr uint32_t MAX_ELEMENT_INDEX_LEN = 10;
41 
ToBoolean()42 inline bool JSTaggedValue::ToBoolean() const
43 {
44     if (IsInt()) {
45         return GetInt() != 0;
46     }
47     if (IsDouble()) {
48         double d = GetDouble();
49         return !std::isnan(d) && d != 0;
50     }
51     switch (GetRawData()) {
52         case JSTaggedValue::VALUE_UNDEFINED:
53             [[fallthrough]];
54         case JSTaggedValue::VALUE_HOLE:
55             [[fallthrough]];
56         case JSTaggedValue::VALUE_NULL:
57             [[fallthrough]];
58         case JSTaggedValue::VALUE_FALSE: {
59             return false;
60         }
61         case JSTaggedValue::VALUE_TRUE: {
62             return true;
63         }
64         default: {
65             break;
66         }
67     }
68 
69     if (IsBigInt()) {
70         BigInt *bigint = BigInt::Cast(GetTaggedObject());
71         return !bigint->IsZero();
72     }
73     if (IsHeapObject()) {
74         TaggedObject *obj = GetTaggedObject();
75         if (IsString()) {
76             auto str = static_cast<EcmaString *>(obj);
77             return EcmaStringAccessor(str).GetLength() != 0;
78         }
79         return true;
80     }
81     LOG_ECMA(FATAL) << "this branch is unreachable";
82     UNREACHABLE();
83 }
84 
ToNumber(JSThread * thread,JSTaggedValue tagged)85 inline JSTaggedNumber JSTaggedValue::ToNumber(JSThread *thread, JSTaggedValue tagged)
86 {
87     DISALLOW_GARBAGE_COLLECTION;
88     if (tagged.IsInt() || tagged.IsDouble()) {
89         return JSTaggedNumber(tagged);
90     }
91 
92     switch (tagged.GetRawData()) {
93         case JSTaggedValue::VALUE_UNDEFINED:
94         case JSTaggedValue::VALUE_HOLE: {
95             return JSTaggedNumber(base::NAN_VALUE);
96         }
97         case JSTaggedValue::VALUE_TRUE: {
98             return JSTaggedNumber(1);
99         }
100         case JSTaggedValue::VALUE_FALSE:
101         case JSTaggedValue::VALUE_NULL: {
102             return JSTaggedNumber(0);
103         }
104         default: {
105             break;
106         }
107     }
108 
109     if (tagged.IsString()) {
110         return StringToNumber(tagged);
111     }
112     if (tagged.IsECMAObject()) {
113         JSHandle<JSTaggedValue>taggedHandle(thread, tagged);
114         JSTaggedValue primValue = ToPrimitive(thread, taggedHandle, PREFER_NUMBER);
115         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedNumber::Exception());
116         return ToNumber(thread, primValue);
117     }
118     if (tagged.IsSymbol()) {
119         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a Symbol value to a number", JSTaggedNumber::Exception());
120     }
121     if (tagged.IsBigInt()) {
122         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a BigInt value to a number", JSTaggedNumber::Exception());
123     }
124     THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a Unknown value to a number", JSTaggedNumber::Exception());
125 }
126 
ToNumber(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)127 inline JSTaggedNumber JSTaggedValue::ToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
128 {
129     return ToNumber(thread, tagged.GetTaggedValue());
130 }
131 
ToBigInt(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)132 inline JSTaggedValue JSTaggedValue::ToBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
133 {
134     JSHandle<JSTaggedValue> primValue(thread, ToPrimitive(thread, tagged));
135     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
136     switch (primValue->GetRawData()) {
137         case JSTaggedValue::VALUE_UNDEFINED:
138         case JSTaggedValue::VALUE_NULL: {
139             THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a undefine or null value to a BigInt",
140                                         JSTaggedValue::Exception());
141         }
142         case JSTaggedValue::VALUE_TRUE: {
143             return BigInt::Int32ToBigInt(thread, 1).GetTaggedValue();
144         }
145         case JSTaggedValue::VALUE_FALSE: {
146             return BigInt::Int32ToBigInt(thread, 0).GetTaggedValue();
147         }
148         default: {
149             break;
150         }
151     }
152 
153     if (primValue->IsNumber()) {
154         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a Number value to a BigInt", JSTaggedNumber::Exception());
155     }
156     if (primValue->IsString()) {
157         JSHandle<JSTaggedValue> value(thread, base::NumberHelper::StringToBigInt(thread, primValue));
158         if (value->IsBigInt()) {
159             return value.GetTaggedValue();
160         }
161         THROW_SYNTAX_ERROR_AND_RETURN(thread, "Cannot convert string to a BigInt,"
162                                       "because not allow Infinity, decimal points, or exponents",
163                                       JSTaggedValue::Exception());
164     }
165     if (primValue->IsSymbol()) {
166         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a Symbol value to a BigInt", JSTaggedNumber::Exception());
167     }
168     if (primValue->IsBigInt()) {
169         return primValue.GetTaggedValue();
170     }
171     THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot convert a Unknown value to a BigInt", JSTaggedNumber::Exception());
172 }
173 
ToBigInt64(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)174 inline JSTaggedValue JSTaggedValue::ToBigInt64(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
175 {
176     JSHandle<BigInt> value(thread, ToBigInt(thread, tagged));
177     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
178     JSHandle<BigInt> tVal = BigInt::GetUint64MaxBigint(thread);
179     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
180     JSHandle<BigInt> int64bitVal = BigInt::FloorMod(thread, value, tVal);
181     JSHandle<BigInt> resValue = BigInt::GetInt64MaxBigint(thread);
182     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
183     if (!BigInt::LessThan(int64bitVal.GetTaggedValue(), resValue.GetTaggedValue())) {
184         return BigInt::Subtract(thread, int64bitVal, tVal).GetTaggedValue();
185     } else {
186         return int64bitVal.GetTaggedValue();
187     }
188 }
189 
ToBigUint64(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)190 inline JSTaggedValue JSTaggedValue::ToBigUint64(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
191 {
192     JSHandle<BigInt> value(thread, ToBigInt(thread, tagged));
193     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
194     bool signFlag = value->GetSign();
195     uint32_t len = value->GetLength();
196     if (!signFlag && len <= 2) { // 2:2 int equal int64
197         return value.GetTaggedValue();
198     }
199     JSHandle<BigInt> tVal = BigInt::GetUint64MaxBigint(thread);
200     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
201     return BigInt::FloorMod(thread, value, tVal).GetTaggedValue();
202 }
203 
ToInteger(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)204 inline JSTaggedNumber JSTaggedValue::ToInteger(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
205 {
206     JSTaggedNumber number = ToNumber(thread, tagged);
207     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedNumber::Exception());
208 
209     return JSTaggedNumber(base::NumberHelper::TruncateDouble(number.GetNumber()));
210 }
211 
ToInt32(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)212 inline int32_t JSTaggedValue::ToInt32(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
213 {
214     JSTaggedNumber number = ToNumber(thread, tagged);
215     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0);
216     return base::NumberHelper::DoubleToInt(number.GetNumber(), base::INT32_BITS);
217 }
218 
ToUint32(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)219 inline uint32_t JSTaggedValue::ToUint32(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
220 {
221     return ToInt32(thread, tagged);
222 }
223 
ToInt16(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)224 inline int16_t JSTaggedValue::ToInt16(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
225 {
226     JSTaggedNumber number = ToNumber(thread, tagged);
227     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0);
228 
229     return base::NumberHelper::DoubleToInt(number.GetNumber(), base::INT16_BITS);
230 }
231 
ToUint16(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)232 inline uint16_t JSTaggedValue::ToUint16(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
233 {
234     return ToInt16(thread, tagged);
235 }
236 
ToInt8(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)237 inline int8_t JSTaggedValue::ToInt8(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
238 {
239     JSTaggedNumber number = ToNumber(thread, tagged);
240     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0);
241 
242     return base::NumberHelper::DoubleToInt(number.GetNumber(), base::INT8_BITS);
243 }
244 
ToUint8(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)245 inline uint8_t JSTaggedValue::ToUint8(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
246 {
247     return ToInt8(thread, tagged);
248 }
249 
ToUint8Clamp(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)250 inline uint8_t JSTaggedValue::ToUint8Clamp(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
251 {
252     JSTaggedNumber number = ToNumber(thread, tagged);
253     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0);
254 
255     double d = number.GetNumber();
256     if (std::isnan(d) || d <= 0) {
257         return 0;
258     }
259     if (d >= UINT8_MAX) {
260         return UINT8_MAX;
261     }
262 
263     return lrint(d);
264 }
265 
ToLength(JSThread * thread,const JSHandle<JSTaggedValue> & tagged)266 inline JSTaggedNumber JSTaggedValue::ToLength(JSThread *thread, const JSHandle<JSTaggedValue> &tagged)
267 {
268     JSTaggedNumber len = ToInteger(thread, tagged);
269     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedNumber::Exception());
270     if (len.GetNumber() < 0.0) {
271         return JSTaggedNumber(static_cast<double>(0));
272     }
273     if (len.GetNumber() > SAFE_NUMBER) {
274         return JSTaggedNumber(static_cast<double>(SAFE_NUMBER));
275     }
276     return len;
277 }
278 
279 // ecma6 7.2 Testing and Comparison Operations
RequireObjectCoercible(JSThread * thread,const JSHandle<JSTaggedValue> & tagged,const char * message)280 inline JSHandle<JSTaggedValue> JSTaggedValue::RequireObjectCoercible(JSThread *thread,
281                                                                      const JSHandle<JSTaggedValue> &tagged,
282                                                                      const char *message)
283 {
284     if (tagged->IsUndefinedOrNull()) {
285         THROW_TYPE_ERROR_AND_RETURN(thread, message, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Exception()));
286     }
287     return tagged;
288 }
289 
IsCallable()290 inline bool JSTaggedValue::IsCallable() const
291 {
292     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCallable();
293 }
294 
IsConstructor()295 inline bool JSTaggedValue::IsConstructor() const
296 {
297     return IsHeapObject() && GetTaggedObject()->GetClass()->IsConstructor();
298 }
299 
IsExtensible(JSThread * thread)300 inline bool JSTaggedValue::IsExtensible(JSThread *thread) const
301 {
302     if (UNLIKELY(IsJSProxy())) {
303         return JSProxy::IsExtensible(thread, JSHandle<JSProxy>(thread, *this));
304     }
305     if (UNLIKELY(IsModuleNamespace())) {
306         ModuleNamespace* ns = ModuleNamespace::Cast(this->GetTaggedObject());
307         return ns->IsExtensible();
308     }
309 
310     return IsHeapObject() && GetTaggedObject()->GetClass()->IsExtensible();
311 }
312 
IsExactlyZero()313 inline bool JSTaggedValue::IsExactlyZero() const
314 {
315     return value_ == VALUE_ZERO || value_ == VALUE_POSITIVE_ZERO || value_ == VALUE_NEGATIVE_ZERO;
316 }
317 
IsClassConstructor()318 inline bool JSTaggedValue::IsClassConstructor() const
319 {
320     return IsHeapObject() && GetTaggedObject()->GetClass()->IsClassConstructor();
321 }
322 
IsClassPrototype()323 inline bool JSTaggedValue::IsClassPrototype() const
324 {
325     return IsHeapObject() && GetTaggedObject()->GetClass()->IsClassPrototype();
326 }
327 
IsPropertyKey(const JSHandle<JSTaggedValue> & key)328 inline bool JSTaggedValue::IsPropertyKey(const JSHandle<JSTaggedValue> &key)
329 {
330     return key->IsStringOrSymbol() || key->IsNumber();
331 }
332 
SameValue(const JSTaggedValue & x,const JSTaggedValue & y)333 inline bool JSTaggedValue::SameValue(const JSTaggedValue &x, const JSTaggedValue &y)
334 {
335     // same object or special type must be same value
336     if (x == y) {
337         return true;
338     }
339     if (x.IsInt() && y.IsInt()) {
340         // same value should be returned above
341         return false;
342     }
343     if (x.IsNumber() && y.IsNumber()) {
344         return SameValueNumberic(x, y);
345     }
346     if (x.IsString() && y.IsString()) {
347         return StringCompare(EcmaString::Cast(x.GetTaggedObject()), EcmaString::Cast(y.GetTaggedObject()));
348     }
349     if (x.IsBigInt() && y.IsBigInt()) {
350         return BigInt::SameValue(x, y);
351     }
352     return false;
353 }
354 
SameValue(const JSHandle<JSTaggedValue> & xHandle,const JSHandle<JSTaggedValue> & yHandle)355 inline bool JSTaggedValue::SameValue(const JSHandle<JSTaggedValue> &xHandle, const JSHandle<JSTaggedValue> &yHandle)
356 {
357     return SameValue(xHandle.GetTaggedValue(), yHandle.GetTaggedValue());
358 }
359 
SameValueZero(const JSTaggedValue & x,const JSTaggedValue & y)360 inline bool JSTaggedValue::SameValueZero(const JSTaggedValue &x, const JSTaggedValue &y)
361 {
362     if (x == y) {
363         return true;
364     }
365 
366     if (x.IsNumber() && y.IsNumber()) {
367         double xValue = x.ExtractNumber();
368         double yValue = y.ExtractNumber();
369         // Compare xValue with yValue to deal with -0.0
370         return (xValue == yValue) || (std::isnan(xValue) && std::isnan(yValue));
371     }
372 
373     if (x.IsString() && y.IsString()) {
374         auto xStr = static_cast<EcmaString *>(x.GetTaggedObject());
375         auto yStr = static_cast<EcmaString *>(y.GetTaggedObject());
376         return EcmaStringAccessor::StringsAreEqual(xStr, yStr);
377     }
378     if (x.IsBigInt() && y.IsBigInt()) {
379         return BigInt::SameValueZero(x, y);
380     }
381     return false;
382 }
383 
SameValueNumberic(const JSTaggedValue & x,const JSTaggedValue & y)384 inline bool JSTaggedValue::SameValueNumberic(const JSTaggedValue &x, const JSTaggedValue &y)
385 {
386     double xValue = x.ExtractNumber();
387     double yValue = y.ExtractNumber();
388     // SameNumberValue(NaN, NaN) is true.
389     if (xValue != yValue) {
390         return std::isnan(xValue) && std::isnan(yValue);
391     }
392     // SameNumberValue(0.0, -0.0) is false.
393     return (std::signbit(xValue) == std::signbit(yValue));
394 }
395 
Less(JSThread * thread,const JSHandle<JSTaggedValue> & x,const JSHandle<JSTaggedValue> & y)396 inline bool JSTaggedValue::Less(JSThread *thread, const JSHandle<JSTaggedValue> &x, const JSHandle<JSTaggedValue> &y)
397 {
398     ComparisonResult result = Compare(thread, x, y);
399     return result == ComparisonResult::LESS;
400 }
401 
StrictNumberEquals(double x,double y)402 inline bool JSTaggedValue::StrictNumberEquals(double x, double y)
403 {
404     // Must check explicitly for NaN's on Windows, but -0 works fine.
405     if (std::isnan(x) || std::isnan(y)) {
406         return false;
407     }
408     return x == y;
409 }
410 
StrictIntEquals(int x,int y)411 inline bool JSTaggedValue::StrictIntEquals(int x, int y)
412 {
413     return x == y;
414 }
415 
StrictEqual(const JSThread * thread,const JSHandle<JSTaggedValue> & x,const JSHandle<JSTaggedValue> & y)416 inline bool JSTaggedValue::StrictEqual([[maybe_unused]] const JSThread *thread, const JSHandle<JSTaggedValue> &x,
417                                        const JSHandle<JSTaggedValue> &y)
418 {
419     return StrictEqual(x.GetTaggedValue(), y.GetTaggedValue());
420 }
421 
StrictEqual(const JSTaggedValue & x,const JSTaggedValue & y)422 inline bool JSTaggedValue::StrictEqual(const JSTaggedValue &x, const JSTaggedValue &y)
423 {
424     if (x.IsInt() && y.IsInt()) {
425         return StrictIntEquals(x.GetInt(), y.GetInt());
426     }
427     if (x.IsNumber() && y.IsNumber()) {
428         return StrictNumberEquals(x.GetNumber(), y.GetNumber());
429     }
430     // Note: x == y must be put after number comparison
431     // in case of NaN (whose comparison result is always false even with another NaN)
432     if (x == y) {
433         return true;
434     }
435     if (x.IsString() && y.IsString()) {
436         return StringCompare(EcmaString::Cast(x.GetTaggedObject()), EcmaString::Cast(y.GetTaggedObject()));
437     }
438     if (x.IsBigInt() && y.IsBigInt()) {
439         return BigInt::Equal(x, y);
440     }
441     return false;
442 }
443 
StrictNumberCompare(double x,double y)444 inline ComparisonResult JSTaggedValue::StrictNumberCompare(double x, double y)
445 {
446     if (std::isnan(x) || std::isnan(y)) {
447         return ComparisonResult::UNDEFINED;
448     }
449     if (x < y) {
450         return ComparisonResult::LESS;
451     }
452     if (x > y) {
453         return ComparisonResult::GREAT;
454     }
455     return ComparisonResult::EQUAL;
456 }
457 
IsNumber()458 inline bool JSTaggedValue::IsNumber() const
459 {
460     return IsInt() || IsDouble();
461 }
462 
IsString()463 inline bool JSTaggedValue::IsString() const
464 {
465     return IsHeapObject() && GetTaggedObject()->GetClass()->IsString();
466 }
467 
IsLineString()468 inline bool JSTaggedValue::IsLineString() const
469 {
470     return IsHeapObject() && GetTaggedObject()->GetClass()->IsLineString();
471 }
472 
IsConstantString()473 inline bool JSTaggedValue::IsConstantString() const
474 {
475     return IsHeapObject() && GetTaggedObject()->GetClass()->IsConstantString();
476 }
477 
IsTreeString()478 inline bool JSTaggedValue::IsTreeString() const
479 {
480     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTreeString();
481 }
482 
IsSlicedString()483 inline bool JSTaggedValue::IsSlicedString() const
484 {
485     return IsHeapObject() && GetTaggedObject()->GetClass()->IsSlicedString();
486 }
487 
IsBigInt()488 inline bool JSTaggedValue::IsBigInt() const
489 {
490     return IsHeapObject() && GetTaggedObject()->GetClass()->IsBigInt();
491 }
492 
IsStringOrSymbol()493 inline bool JSTaggedValue::IsStringOrSymbol() const
494 {
495     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStringOrSymbol();
496 }
497 
IsLexicalEnv()498 inline bool JSTaggedValue::IsLexicalEnv() const
499 {
500     return IsHeapObject() && GetTaggedObject()->GetClass()->IsLexicalEnv();
501 }
502 
IsTaggedArray()503 inline bool JSTaggedValue::IsTaggedArray() const
504 {
505     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTaggedArray();
506 }
507 
IsDictionary()508 inline bool JSTaggedValue::IsDictionary() const
509 {
510     return IsHeapObject() && GetTaggedObject()->GetClass()->IsDictionary();
511 }
512 
IsByteArray()513 inline bool JSTaggedValue::IsByteArray() const
514 {
515     return IsHeapObject() && GetTaggedObject()->GetClass()->IsByteArray();
516 }
517 
IsConstantPool()518 inline bool JSTaggedValue::IsConstantPool() const
519 {
520     return IsHeapObject() && GetTaggedObject()->GetClass()->IsConstantPool();
521 }
522 
IsAOTLiteralInfo()523 inline bool JSTaggedValue::IsAOTLiteralInfo() const
524 {
525     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAOTLiteralInfo();
526 }
527 
IsVTable()528 inline bool JSTaggedValue::IsVTable() const
529 {
530     return IsHeapObject() && GetTaggedObject()->GetClass()->IsVTable();
531 }
532 
IsLinkedNode()533 inline bool JSTaggedValue::IsLinkedNode() const
534 {
535     return IsHeapObject() && GetTaggedObject()->GetClass()->IsLinkedNode();
536 }
537 
IsRBTreeNode()538 inline bool JSTaggedValue::IsRBTreeNode() const
539 {
540     return IsHeapObject() && GetTaggedObject()->GetClass()->IsRBTreeNode();
541 }
542 
IsNativePointer()543 inline bool JSTaggedValue::IsNativePointer() const
544 {
545     return IsJSNativePointer();
546 }
547 
IsJSNativePointer()548 inline bool JSTaggedValue::IsJSNativePointer() const
549 {
550     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSNativePointer();
551 }
552 
CheckIsJSNativePointer()553 inline bool JSTaggedValue::CheckIsJSNativePointer() const
554 {
555     if (IsHeapObject() && !IsInvalidValue()) {
556         auto hclass = GetTaggedObject()->GetClass();
557         if (hclass != nullptr) {
558             return hclass->IsJSNativePointer();
559         }
560     }
561     return false;
562 }
563 
IsSymbol()564 inline bool JSTaggedValue::IsSymbol() const
565 {
566     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSSymbol();
567 }
568 
IsJSProxy()569 inline bool JSTaggedValue::IsJSProxy() const
570 {
571     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSProxy();
572 }
573 
CheckIsJSProxy()574 inline bool JSTaggedValue::CheckIsJSProxy() const
575 {
576     if (IsHeapObject() && !IsInvalidValue()) {
577         auto hclass = GetTaggedObject()->GetClass();
578         if (hclass != nullptr) {
579             return hclass->IsJSProxy();
580         }
581     }
582     return false;
583 }
584 
IsBoolean()585 inline bool JSTaggedValue::IsBoolean() const
586 {
587     return ((value_ & TAG_HEAPOBJECT_MASK) == TAG_BOOLEAN_MASK);
588 }
589 
IsJSObject()590 inline bool JSTaggedValue::IsJSObject() const
591 {
592     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSObject();
593 }
594 
IsOnlyJSObject()595 inline bool JSTaggedValue::IsOnlyJSObject() const
596 {
597     // Distinguish the JSObject and the subclasses of JSObject.
598     return IsHeapObject() && GetTaggedObject()->GetClass()->IsOnlyJSObject();
599 }
600 
IsECMAObject()601 inline bool JSTaggedValue::IsECMAObject() const
602 {
603     return IsHeapObject() && GetTaggedObject()->GetClass()->IsECMAObject();
604 }
605 
IsJSPromise()606 inline bool JSTaggedValue::IsJSPromise() const
607 {
608     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromise();
609 }
610 
IsRecord()611 inline bool JSTaggedValue::IsRecord() const
612 {
613     return IsHeapObject() && GetTaggedObject()->GetClass()->IsRecord();
614 }
615 
IsPromiseReaction()616 inline bool JSTaggedValue::IsPromiseReaction() const
617 {
618     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseReaction();
619 }
620 
IsJSPromiseReactionFunction()621 inline bool JSTaggedValue::IsJSPromiseReactionFunction() const
622 {
623     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseReactionFunction();
624 }
625 
IsProgram()626 inline bool JSTaggedValue::IsProgram() const
627 {
628     return IsHeapObject() && GetTaggedObject()->GetClass()->IsProgram();
629 }
630 
IsJSPromiseExecutorFunction()631 inline bool JSTaggedValue::IsJSPromiseExecutorFunction() const
632 {
633     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseExecutorFunction();
634 }
635 
IsJSAsyncModuleFulfilledFunction()636 inline bool JSTaggedValue::IsJSAsyncModuleFulfilledFunction() const
637 {
638     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncModuleFulfilledFunction();
639 }
640 
IsJSAsyncModuleRejectedFunction()641 inline bool JSTaggedValue::IsJSAsyncModuleRejectedFunction() const
642 {
643     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncModuleRejectedFunction();
644 }
645 
IsJSAsyncFromSyncIterUnwarpFunction()646 inline bool JSTaggedValue::IsJSAsyncFromSyncIterUnwarpFunction() const
647 {
648     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncFromSyncIterUnwarpFunction();
649 }
650 
IsJSPromiseAllResolveElementFunction()651 inline bool JSTaggedValue::IsJSPromiseAllResolveElementFunction() const
652 {
653     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseAllResolveElementFunction();
654 }
655 
IsJSAsyncGeneratorResNextRetProRstFtn()656 inline bool JSTaggedValue::IsJSAsyncGeneratorResNextRetProRstFtn() const
657 {
658     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncGeneratorResNextRetProRstFtn();
659 }
660 
IsCompletionRecord()661 inline bool JSTaggedValue::IsCompletionRecord() const
662 {
663     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCompletionRecord();
664 }
665 
IsResolvingFunctionsRecord()666 inline bool JSTaggedValue::IsResolvingFunctionsRecord() const
667 {
668     return IsHeapObject() && GetTaggedObject()->GetClass()->IsResolvingFunctionsRecord();
669 }
670 
IsPromiseRecord()671 inline bool JSTaggedValue::IsPromiseRecord() const
672 {
673     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseRecord();
674 }
675 
IsJSLocale()676 inline bool JSTaggedValue::IsJSLocale() const
677 {
678     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSLocale();
679 }
680 
IsJSIntl()681 inline bool JSTaggedValue::IsJSIntl() const
682 {
683     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSIntl();
684 }
685 
IsJSDateTimeFormat()686 inline bool JSTaggedValue::IsJSDateTimeFormat() const
687 {
688     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSDateTimeFormat();
689 }
690 
IsJSRelativeTimeFormat()691 inline bool JSTaggedValue::IsJSRelativeTimeFormat() const
692 {
693     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSRelativeTimeFormat();
694 }
695 
IsJSNumberFormat()696 inline bool JSTaggedValue::IsJSNumberFormat() const
697 {
698     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSNumberFormat();
699 }
700 
IsJSCollator()701 inline bool JSTaggedValue::IsJSCollator() const
702 {
703     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSCollator();
704 }
705 
IsJSPluralRules()706 inline bool JSTaggedValue::IsJSPluralRules() const
707 {
708     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPluralRules();
709 }
710 
IsJSDisplayNames()711 inline bool JSTaggedValue::IsJSDisplayNames() const
712 {
713     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSDisplayNames();
714 }
715 
IsJSListFormat()716 inline bool JSTaggedValue::IsJSListFormat() const
717 {
718     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSListFormat();
719 }
720 
IsMethod()721 inline bool JSTaggedValue::IsMethod() const
722 {
723     return IsHeapObject() && GetTaggedObject()->GetClass()->IsMethod();
724 }
725 
IsClassLiteral()726 inline bool JSTaggedValue::IsClassLiteral() const
727 {
728     return IsHeapObject() && GetTaggedObject()->GetClass()->IsClassLiteral();
729 }
730 
IsJSAPIArrayList()731 inline bool JSTaggedValue::IsJSAPIArrayList() const
732 {
733     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIArrayList();
734 }
735 
IsJSAPIHashMap()736 inline bool JSTaggedValue::IsJSAPIHashMap() const
737 {
738     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIHashMap();
739 }
740 
IsJSAPIHashSet()741 inline bool JSTaggedValue::IsJSAPIHashSet() const
742 {
743     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIHashSet();
744 }
745 
IsJSAPITreeMap()746 inline bool JSTaggedValue::IsJSAPITreeMap() const
747 {
748     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPITreeMap();
749 }
750 
IsJSAPITreeSet()751 inline bool JSTaggedValue::IsJSAPITreeSet() const
752 {
753     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPITreeSet();
754 }
755 
IsJSAPIPlainArray()756 inline bool JSTaggedValue::IsJSAPIPlainArray() const
757 {
758     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIPlainArray();
759 }
760 
IsJSAPIPlainArrayIterator()761 inline bool JSTaggedValue::IsJSAPIPlainArrayIterator() const
762 {
763     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIPlainArrayIterator();
764 }
765 
IsJSAPIQueue()766 inline bool JSTaggedValue::IsJSAPIQueue() const
767 {
768     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIQueue();
769 }
770 
IsJSAPIDeque()771 inline bool JSTaggedValue::IsJSAPIDeque() const
772 {
773     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIDeque();
774 }
775 
IsJSAPILightWeightMap()776 inline bool JSTaggedValue::IsJSAPILightWeightMap() const
777 {
778     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILightWeightMap();
779 }
780 
IsJSAPILightWeightSet()781 inline bool JSTaggedValue::IsJSAPILightWeightSet() const
782 {
783     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILightWeightSet();
784 }
785 
IsJSAPIStack()786 inline bool JSTaggedValue::IsJSAPIStack() const
787 {
788     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIStack();
789 }
790 
IsJSAPIVector()791 inline bool JSTaggedValue::IsJSAPIVector() const
792 {
793     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIVector();
794 }
795 
IsJSAPIList()796 inline bool JSTaggedValue::IsJSAPIList() const
797 {
798     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIList();
799 }
800 
IsJSAPILinkedList()801 inline bool JSTaggedValue::IsJSAPILinkedList() const
802 {
803     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILinkedList();
804 }
805 
IsJSAPILinkedListIterator()806 inline bool JSTaggedValue::IsJSAPILinkedListIterator() const
807 {
808     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILinkedListIterator();
809 }
810 
IsJSAPIListIterator()811 inline bool JSTaggedValue::IsJSAPIListIterator() const
812 {
813     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIListIterator();
814 }
815 
IsSpecialContainer()816 inline bool JSTaggedValue::IsSpecialContainer() const
817 {
818     return IsHeapObject() && GetTaggedObject()->GetClass()->IsSpecialContainer();
819 }
820 
HasOrdinaryGet()821 inline bool JSTaggedValue::HasOrdinaryGet() const
822 {
823     return IsHeapObject() && GetTaggedObject()->GetClass()->HasOrdinaryGet();
824 }
825 
IsPromiseIteratorRecord()826 inline bool JSTaggedValue::IsPromiseIteratorRecord() const
827 {
828     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseIteratorRecord();
829 }
830 
IsPromiseCapability()831 inline bool JSTaggedValue::IsPromiseCapability() const
832 {
833     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseCapability();
834 }
835 
IsJSPromiseAnyRejectElementFunction()836 inline bool JSTaggedValue::IsJSPromiseAnyRejectElementFunction() const
837 {
838     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseAnyRejectElementFunction();
839 }
840 
IsJSPromiseAllSettledElementFunction()841 inline bool JSTaggedValue::IsJSPromiseAllSettledElementFunction() const
842 {
843     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseAllSettledElementFunction();
844 }
845 
IsJSPromiseFinallyFunction()846 inline bool JSTaggedValue::IsJSPromiseFinallyFunction() const
847 {
848     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseFinallyFunction();
849 }
850 
IsJSPromiseValueThunkOrThrowerFunction()851 inline bool JSTaggedValue::IsJSPromiseValueThunkOrThrowerFunction() const
852 {
853     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPromiseValueThunkOrThrowerFunction();
854 }
855 
IsJSError()856 inline bool JSTaggedValue::IsJSError() const
857 {
858     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSError();
859 }
860 
IsMicroJobQueue()861 inline bool JSTaggedValue::IsMicroJobQueue() const
862 {
863     return IsHeapObject() && GetTaggedObject()->GetClass()->IsMicroJobQueue();
864 }
865 
IsPendingJob()866 inline bool JSTaggedValue::IsPendingJob() const
867 {
868     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPendingJob();
869 }
870 
IsArguments()871 inline bool JSTaggedValue::IsArguments() const
872 {
873     return IsHeapObject() && GetTaggedObject()->GetClass()->IsArguments();
874 }
875 
IsDate()876 inline bool JSTaggedValue::IsDate() const
877 {
878     return IsHeapObject() && GetTaggedObject()->GetClass()->IsDate();
879 }
880 
IsArray(JSThread * thread)881 inline bool JSTaggedValue::IsArray(JSThread *thread) const
882 {
883     if (!IsHeapObject()) {
884         return false;
885     }
886     JSHClass *jsHclass = GetTaggedObject()->GetClass();
887     if (jsHclass->IsJSArray()) {
888         return true;
889     }
890 
891     if (jsHclass->IsJSProxy()) {
892         return JSProxy::Cast(GetTaggedObject())->IsArray(thread);
893     }
894     return false;
895 }
896 
IsCOWArray()897 inline bool JSTaggedValue::IsCOWArray() const
898 {
899     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCOWArray();
900 }
901 
IsMutantTaggedArray()902 inline bool JSTaggedValue::IsMutantTaggedArray() const
903 {
904     return IsHeapObject() && GetTaggedObject()->GetClass()->IsMutantTaggedArray();
905 }
906 
IsJSArray()907 inline bool JSTaggedValue::IsJSArray() const
908 {
909     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSArray();
910 }
911 
IsStableJSArray(JSThread * thread)912 inline bool JSTaggedValue::IsStableJSArray(JSThread *thread) const
913 {
914     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableJSArray() &&
915            !thread->IsStableArrayElementsGuardiansInvalid();
916 }
917 
IsStableJSArguments(JSThread * thread)918 inline bool JSTaggedValue::IsStableJSArguments(JSThread *thread) const
919 {
920     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableJSArguments() &&
921            !thread->IsStableArrayElementsGuardiansInvalid();
922 }
923 
HasStableElements(JSThread * thread)924 inline bool JSTaggedValue::HasStableElements(JSThread *thread) const
925 {
926     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableElements() &&
927            !thread->IsStableArrayElementsGuardiansInvalid();
928 }
929 
IsTypedArray()930 inline bool JSTaggedValue::IsTypedArray() const
931 {
932     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTypedArray();
933 }
934 
IsJSTypedArray()935 inline bool JSTaggedValue::IsJSTypedArray() const
936 {
937     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSTypedArray();
938 }
939 
IsJSInt8Array()940 inline bool JSTaggedValue::IsJSInt8Array() const
941 {
942     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSInt8Array();
943 }
944 
IsJSUint8Array()945 inline bool JSTaggedValue::IsJSUint8Array() const
946 {
947     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSUint8Array();
948 }
949 
IsJSUint8ClampedArray()950 inline bool JSTaggedValue::IsJSUint8ClampedArray() const
951 {
952     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSUint8ClampedArray();
953 }
954 
IsJSInt16Array()955 inline bool JSTaggedValue::IsJSInt16Array() const
956 {
957     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSInt16Array();
958 }
959 
IsJSUint16Array()960 inline bool JSTaggedValue::IsJSUint16Array() const
961 {
962     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSUint16Array();
963 }
964 
IsJSInt32Array()965 inline bool JSTaggedValue::IsJSInt32Array() const
966 {
967     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSInt32Array();
968 }
969 
IsJSUint32Array()970 inline bool JSTaggedValue::IsJSUint32Array() const
971 {
972     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSUint32Array();
973 }
974 
IsJSFloat32Array()975 inline bool JSTaggedValue::IsJSFloat32Array() const
976 {
977     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFloat32Array();
978 }
979 
IsJSFloat64Array()980 inline bool JSTaggedValue::IsJSFloat64Array() const
981 {
982     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFloat64Array();
983 }
984 
IsJSBigInt64Array()985 inline bool JSTaggedValue::IsJSBigInt64Array() const
986 {
987     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSBigInt64Array();
988 }
989 
IsJSBigUint64Array()990 inline bool JSTaggedValue::IsJSBigUint64Array() const
991 {
992     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSBigUint64Array();
993 }
994 
IsJSMap()995 inline bool JSTaggedValue::IsJSMap() const
996 {
997     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSMap();
998 }
999 
IsJSWeakMap()1000 inline bool JSTaggedValue::IsJSWeakMap() const
1001 {
1002     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSWeakMap();
1003 }
1004 
IsJSWeakSet()1005 inline bool JSTaggedValue::IsJSWeakSet() const
1006 {
1007     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSWeakSet();
1008 }
1009 
IsJSSet()1010 inline bool JSTaggedValue::IsJSSet() const
1011 {
1012     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSSet();
1013 }
1014 
IsJSWeakRef()1015 inline bool JSTaggedValue::IsJSWeakRef() const
1016 {
1017     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSWeakRef();
1018 }
1019 
IsJSFinalizationRegistry()1020 inline bool JSTaggedValue::IsJSFinalizationRegistry() const
1021 {
1022     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFinalizationRegistry();
1023 }
1024 
IsCellRecord()1025 inline bool JSTaggedValue::IsCellRecord() const
1026 {
1027     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCellRecord();
1028 }
1029 
IsJSRegExp()1030 inline bool JSTaggedValue::IsJSRegExp() const
1031 {
1032     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSRegExp();
1033 }
1034 
IsJSFunction()1035 inline bool JSTaggedValue::IsJSFunction() const
1036 {
1037     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFunction();
1038 }
1039 
IsJSFunctionBase()1040 inline bool JSTaggedValue::IsJSFunctionBase() const
1041 {
1042     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFunctionBase();
1043 }
1044 
CheckIsJSFunctionBase()1045 inline bool JSTaggedValue::CheckIsJSFunctionBase() const
1046 {
1047     if (IsHeapObject() && !IsInvalidValue()) {
1048         auto hclass = GetTaggedObject()->GetClass();
1049         if (hclass != nullptr) {
1050             return hclass->IsJSFunctionBase();
1051         }
1052     }
1053     return false;
1054 }
1055 
IsBoundFunction()1056 inline bool JSTaggedValue::IsBoundFunction() const
1057 {
1058     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJsBoundFunction();
1059 }
1060 
IsJSIntlBoundFunction()1061 inline bool JSTaggedValue::IsJSIntlBoundFunction() const
1062 {
1063     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSIntlBoundFunction();
1064 }
1065 
IsProxyRevocFunction()1066 inline bool JSTaggedValue::IsProxyRevocFunction() const
1067 {
1068     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSProxyRevocFunction();
1069 }
1070 
IsJSAsyncFunction()1071 inline bool JSTaggedValue::IsJSAsyncFunction() const
1072 {
1073     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncFunction();
1074 }
1075 
IsJSAsyncAwaitStatusFunction()1076 inline bool JSTaggedValue::IsJSAsyncAwaitStatusFunction() const
1077 {
1078     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAsyncAwaitStatusFunction();
1079 }
1080 
IsJSPrimitiveRef()1081 inline bool JSTaggedValue::IsJSPrimitiveRef() const
1082 {
1083     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJsPrimitiveRef();
1084 }
1085 
IsJSPrimitive()1086 inline bool JSTaggedValue::IsJSPrimitive() const
1087 {
1088     return IsNumber() || IsStringOrSymbol() || IsBoolean();
1089 }
1090 
IsAccessorData()1091 inline bool JSTaggedValue::IsAccessorData() const
1092 {
1093     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAccessorData();
1094 }
1095 
IsInternalAccessor()1096 inline bool JSTaggedValue::IsInternalAccessor() const
1097 {
1098     return IsHeapObject() && GetTaggedObject()->GetClass()->IsInternalAccessor();
1099 }
1100 
IsAccessor()1101 inline bool JSTaggedValue::IsAccessor() const
1102 {
1103     if (IsHeapObject()) {
1104         auto *jshclass = GetTaggedObject()->GetClass();
1105         return jshclass->IsAccessorData() || jshclass->IsInternalAccessor();
1106     }
1107 
1108     return false;
1109 }
1110 
IsPrototypeHandler()1111 inline bool JSTaggedValue::IsPrototypeHandler() const
1112 {
1113     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPrototypeHandler();
1114 }
1115 
IsTransitionHandler()1116 inline bool JSTaggedValue::IsTransitionHandler() const
1117 {
1118     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTransitionHandler();
1119 }
1120 
IsTransWithProtoHandler()1121 inline bool JSTaggedValue::IsTransWithProtoHandler() const
1122 {
1123     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTransWithProtoHandler();
1124 }
1125 
IsStoreTSHandler()1126 inline bool JSTaggedValue::IsStoreTSHandler() const
1127 {
1128     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStoreTSHandler();
1129 }
1130 
IsPropertyBox()1131 inline bool JSTaggedValue::IsPropertyBox() const
1132 {
1133     return IsHeapObject() && GetTaggedObject()->GetClass()->IsPropertyBox();
1134 }
1135 
IsProtoChangeDetails()1136 inline bool JSTaggedValue::IsProtoChangeDetails() const
1137 {
1138     return IsHeapObject() && GetTaggedObject()->GetClass()->IsProtoChangeDetails();
1139 }
IsProtoChangeMarker()1140 inline bool JSTaggedValue::IsProtoChangeMarker() const
1141 {
1142     return IsHeapObject() && GetTaggedObject()->GetClass()->IsProtoChangeMarker();
1143 }
1144 
IsMarkerCell()1145 inline bool JSTaggedValue::IsMarkerCell() const
1146 {
1147     return IsHeapObject() && GetTaggedObject()->GetClass()->IsMarkerCell();
1148 }
1149 
IsTrackInfoObject()1150 inline bool JSTaggedValue::IsTrackInfoObject() const
1151 {
1152     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTrackInfoObject();
1153 }
1154 
IsJSGlobalEnv()1155 inline bool JSTaggedValue::IsJSGlobalEnv() const
1156 {
1157     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJsGlobalEnv();
1158 }
1159 
IsForinIterator()1160 inline bool JSTaggedValue::IsForinIterator() const
1161 {
1162     return IsHeapObject() && GetTaggedObject()->GetClass()->IsForinIterator();
1163 }
1164 
IsJSSetIterator()1165 inline bool JSTaggedValue::IsJSSetIterator() const
1166 {
1167     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSSetIterator();
1168 }
1169 
IsJSRegExpIterator()1170 inline bool JSTaggedValue::IsJSRegExpIterator() const
1171 {
1172     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSRegExpIterator();
1173 }
1174 
IsJSMapIterator()1175 inline bool JSTaggedValue::IsJSMapIterator() const
1176 {
1177     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSMapIterator();
1178 }
1179 
IsJSAPIHashMapIterator()1180 inline bool JSTaggedValue::IsJSAPIHashMapIterator() const
1181 {
1182     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIHashMapIterator();
1183 }
1184 
IsJSAPIHashSetIterator()1185 inline bool JSTaggedValue::IsJSAPIHashSetIterator() const
1186 {
1187     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIHashSetIterator();
1188 }
1189 
IsJSAPITreeMapIterator()1190 inline bool JSTaggedValue::IsJSAPITreeMapIterator() const
1191 {
1192     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPITreeMapIterator();
1193 }
1194 
IsJSAPITreeSetIterator()1195 inline bool JSTaggedValue::IsJSAPITreeSetIterator() const
1196 {
1197     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPITreeSetIterator();
1198 }
1199 
IsJSArrayIterator()1200 inline bool JSTaggedValue::IsJSArrayIterator() const
1201 {
1202     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSArrayIterator();
1203 }
1204 
IsJSAPIArrayListIterator()1205 inline bool JSTaggedValue::IsJSAPIArrayListIterator() const
1206 {
1207     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIArrayListIterator();
1208 }
1209 
IsJSAPIQueueIterator()1210 inline bool JSTaggedValue::IsJSAPIQueueIterator() const
1211 {
1212     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIQueueIterator();
1213 }
1214 
IsJSAPIDequeIterator()1215 inline bool JSTaggedValue::IsJSAPIDequeIterator() const
1216 {
1217     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIDequeIterator();
1218 }
1219 
IsJSAPILightWeightMapIterator()1220 inline bool JSTaggedValue::IsJSAPILightWeightMapIterator() const
1221 {
1222     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILightWeightMapIterator();
1223 }
1224 
IsJSAPILightWeightSetIterator()1225 inline bool JSTaggedValue::IsJSAPILightWeightSetIterator() const
1226 {
1227     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPILightWeightSetIterator();
1228 }
1229 
IsJSAPIStackIterator()1230 inline bool JSTaggedValue::IsJSAPIStackIterator() const
1231 {
1232     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIStackIterator();
1233 }
1234 
IsJSAPIVectorIterator()1235 inline bool JSTaggedValue::IsJSAPIVectorIterator() const
1236 {
1237     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSAPIVectorIterator();
1238 }
1239 
IsIterator()1240 inline bool JSTaggedValue::IsIterator() const
1241 {
1242     return IsHeapObject() && GetTaggedObject()->GetClass()->IsIterator();
1243 }
1244 
IsAsyncIterator()1245 inline bool JSTaggedValue::IsAsyncIterator() const
1246 {
1247     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncIterator();
1248 }
1249 
IsAsyncFromSyncIterator()1250 inline bool JSTaggedValue::IsAsyncFromSyncIterator() const
1251 {
1252     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncFromSyncIterator();
1253 }
1254 
IsGeneratorFunction()1255 inline bool JSTaggedValue::IsGeneratorFunction() const
1256 {
1257     return IsHeapObject() && GetTaggedObject()->GetClass()->IsGeneratorFunction();
1258 }
1259 
IsAsyncGeneratorFunction()1260 inline bool JSTaggedValue::IsAsyncGeneratorFunction() const
1261 {
1262     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncGeneratorFunction();
1263 }
1264 
IsGeneratorObject()1265 inline bool JSTaggedValue::IsGeneratorObject() const
1266 {
1267     return IsHeapObject() && GetTaggedObject()->GetClass()->IsGeneratorObject();
1268 }
1269 
IsGeneratorContext()1270 inline bool JSTaggedValue::IsGeneratorContext() const
1271 {
1272     return IsHeapObject() && GetTaggedObject()->GetClass()->IsGeneratorContext();
1273 }
1274 
IsAsyncGeneratorRequest()1275 inline bool JSTaggedValue::IsAsyncGeneratorRequest() const
1276 {
1277     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncGeneratorRequest();
1278 }
1279 
IsAsyncIteratorRecord()1280 inline bool JSTaggedValue::IsAsyncIteratorRecord() const
1281 {
1282     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncIteratorRecord();
1283 }
1284 
IsAsyncGeneratorObject()1285 inline bool JSTaggedValue::IsAsyncGeneratorObject() const
1286 {
1287     return IsHeapObject() &&  GetTaggedObject()->GetClass()->IsAsyncGeneratorObject();
1288 }
1289 
IsAsyncFuncObject()1290 inline bool JSTaggedValue::IsAsyncFuncObject() const
1291 {
1292     return IsHeapObject() && GetTaggedObject()->GetClass()->IsAsyncFuncObject();
1293 }
1294 
IsJSHClass()1295 inline bool JSTaggedValue::IsJSHClass() const
1296 {
1297     return IsHeapObject() && GetTaggedObject()->GetClass()->IsHClass();
1298 }
1299 
IsStringIterator()1300 inline bool JSTaggedValue::IsStringIterator() const
1301 {
1302     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStringIterator();
1303 }
1304 
IsArrayBuffer()1305 inline bool JSTaggedValue::IsArrayBuffer() const
1306 {
1307     return IsHeapObject() && GetTaggedObject()->GetClass()->IsArrayBuffer();
1308 }
1309 
IsSharedArrayBuffer()1310 inline bool JSTaggedValue::IsSharedArrayBuffer() const
1311 {
1312     return IsHeapObject() && GetTaggedObject()->GetClass()->IsSharedArrayBuffer();
1313 }
1314 
IsDataView()1315 inline bool JSTaggedValue::IsDataView() const
1316 {
1317     return IsHeapObject() && GetTaggedObject()->GetClass()->IsDataView();
1318 }
1319 
IsTemplateMap()1320 inline bool JSTaggedValue::IsTemplateMap() const
1321 {
1322     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTemplateMap();
1323 }
1324 
IsJSGlobalObject()1325 inline bool JSTaggedValue::IsJSGlobalObject() const
1326 {
1327     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSGlobalObject();
1328 }
1329 
IsSpecialKeysObject()1330 inline bool JSTaggedValue::IsSpecialKeysObject() const
1331 {
1332     return IsTypedArray() || IsModuleNamespace() || IsSpecialContainer();
1333 }
1334 
IsSlowKeysObject()1335 inline bool JSTaggedValue::IsSlowKeysObject() const
1336 {
1337     return IsJSGlobalObject() || IsJSProxy() || IsSpecialKeysObject();
1338 }
1339 
IsRegularObject()1340 inline bool JSTaggedValue::IsRegularObject() const
1341 {
1342     return IsHeapObject() && GetTaggedObject()->GetClass()->IsRegularObject();
1343 }
1344 
IsMachineCodeObject()1345 inline bool JSTaggedValue::IsMachineCodeObject() const
1346 {
1347     return IsHeapObject() && GetTaggedObject()->GetClass()->IsMachineCodeObject();
1348 }
1349 
IsClassInfoExtractor()1350 inline bool JSTaggedValue::IsClassInfoExtractor() const
1351 {
1352     return IsHeapObject() && GetTaggedObject()->GetClass()->IsClassInfoExtractor();
1353 }
1354 
IsTSType()1355 inline bool JSTaggedValue::IsTSType() const
1356 {
1357     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSType();
1358 }
1359 
IsTSObjectType()1360 inline bool JSTaggedValue::IsTSObjectType() const
1361 {
1362     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSObjectType();
1363 }
1364 
IsTSClassType()1365 inline bool JSTaggedValue::IsTSClassType() const
1366 {
1367     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSClassType();
1368 }
1369 
IsTSInterfaceType()1370 inline bool JSTaggedValue::IsTSInterfaceType() const
1371 {
1372     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSInterfaceType();
1373 }
1374 
IsTSUnionType()1375 inline bool JSTaggedValue::IsTSUnionType() const
1376 {
1377     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSUnionType();
1378 }
1379 
IsTSClassInstanceType()1380 inline bool JSTaggedValue::IsTSClassInstanceType() const
1381 {
1382     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSClassInstanceType();
1383 }
1384 
IsCjsExports()1385 inline bool JSTaggedValue::IsCjsExports() const
1386 {
1387     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCjsExports();
1388 }
1389 
IsCjsModule()1390 inline bool JSTaggedValue::IsCjsModule() const
1391 {
1392     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCjsModule();
1393 }
1394 
IsCjsRequire()1395 inline bool JSTaggedValue::IsCjsRequire() const
1396 {
1397     return IsHeapObject() && GetTaggedObject()->GetClass()->IsCjsRequire();
1398 }
1399 
IsTSFunctionType()1400 inline bool JSTaggedValue::IsTSFunctionType() const
1401 {
1402     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSFunctionType();
1403 }
1404 
IsTSArrayType()1405 inline bool JSTaggedValue::IsTSArrayType() const
1406 {
1407     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSArrayType();
1408 }
1409 
IsTSIteratorInstanceType()1410 inline bool JSTaggedValue::IsTSIteratorInstanceType() const
1411 {
1412     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSIteratorInstanceType();
1413 }
1414 
IsTSNamespaceType()1415 inline bool JSTaggedValue::IsTSNamespaceType() const
1416 {
1417     return IsHeapObject() && GetTaggedObject()->GetClass()->IsTSNamespaceType();
1418 }
1419 
IsModuleRecord()1420 inline bool JSTaggedValue::IsModuleRecord() const
1421 {
1422     return IsHeapObject() && GetTaggedObject()->GetClass()->IsModuleRecord();
1423 }
1424 
IsSourceTextModule()1425 inline bool JSTaggedValue::IsSourceTextModule() const
1426 {
1427     return IsHeapObject() && GetTaggedObject()->GetClass()->IsSourceTextModule();
1428 }
1429 
IsImportEntry()1430 inline bool JSTaggedValue::IsImportEntry() const
1431 {
1432     return IsHeapObject() && GetTaggedObject()->GetClass()->IsImportEntry();
1433 }
1434 
IsLocalExportEntry()1435 inline bool JSTaggedValue::IsLocalExportEntry() const
1436 {
1437     return IsHeapObject() && GetTaggedObject()->GetClass()->IsLocalExportEntry();
1438 }
1439 
IsIndirectExportEntry()1440 inline bool JSTaggedValue::IsIndirectExportEntry() const
1441 {
1442     return IsHeapObject() && GetTaggedObject()->GetClass()->IsIndirectExportEntry();
1443 }
1444 
IsStarExportEntry()1445 inline bool JSTaggedValue::IsStarExportEntry() const
1446 {
1447     return IsHeapObject() && GetTaggedObject()->GetClass()->IsStarExportEntry();
1448 }
1449 
IsResolvedBinding()1450 inline bool JSTaggedValue::IsResolvedBinding() const
1451 {
1452     return IsHeapObject() && GetTaggedObject()->GetClass()->IsResolvedBinding();
1453 }
1454 
IsResolvedIndexBinding()1455 inline bool JSTaggedValue::IsResolvedIndexBinding() const
1456 {
1457     return IsHeapObject() && GetTaggedObject()->GetClass()->IsResolvedIndexBinding();
1458 }
1459 
IsModuleNamespace()1460 inline bool JSTaggedValue::IsModuleNamespace() const
1461 {
1462     return IsHeapObject() && GetTaggedObject()->GetClass()->IsModuleNamespace();
1463 }
1464 
IsJSSharedObject()1465 inline bool JSTaggedValue::IsJSSharedObject() const
1466 {
1467     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSSharedObject();
1468 }
1469 
IsJSSharedFunction()1470 inline bool JSTaggedValue::IsJSSharedFunction() const
1471 {
1472     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSSharedFunction();
1473 }
1474 
IsJSShared()1475 inline bool JSTaggedValue::IsJSShared() const
1476 {
1477     return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSShared();
1478 }
1479 
ExtractNumber()1480 inline double JSTaggedValue::ExtractNumber() const
1481 {
1482     ASSERT(IsNumber());
1483     return GetNumber();
1484 }
1485 
1486 // 9.4.2.4 ArraySetLength 3 to 7
ToArrayLength(JSThread * thread,const JSHandle<JSTaggedValue> & tagged,uint32_t * output)1487 inline bool JSTaggedValue::ToArrayLength(JSThread *thread, const JSHandle<JSTaggedValue> &tagged, uint32_t *output)
1488 {
1489     // 3. Let newLen be ToUint32(Desc.[[Value]]).
1490     uint32_t newLen = ToUint32(thread, tagged);
1491     // 4. ReturnIfAbrupt(newLen).
1492     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
1493 
1494     // 5. Let numberLen be ToNumber(Desc.[[Value]]).
1495     JSTaggedNumber numberLen = ToNumber(thread, tagged);
1496     // 6. ReturnIfAbrupt(newLen).
1497     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
1498 
1499     // 7. If newLen != numberLen, throw a RangeError exception.
1500     if (JSTaggedNumber(newLen) != numberLen) {
1501         THROW_RANGE_ERROR_AND_RETURN(thread, "Not a valid array length", false);
1502     }
1503 
1504     *output = newLen;
1505     return true;
1506 }
1507 
GetArrayLength()1508 inline uint32_t JSTaggedValue::GetArrayLength() const
1509 {
1510     ASSERT(IsNumber());
1511     if (IsInt()) {
1512         return static_cast<uint32_t>(GetInt());
1513     }
1514     if (IsDouble()) {
1515         ASSERT(GetDouble() <= TaggedArray::MAX_ARRAY_INDEX);
1516         return static_cast<uint32_t>(GetDouble());
1517     }
1518     LOG_ECMA(FATAL) << "this branch is unreachable";
1519     UNREACHABLE();
1520 }
1521 
ToElementIndex(JSTaggedValue key,uint32_t * output)1522 inline bool JSTaggedValue::ToElementIndex(JSTaggedValue key, uint32_t *output)
1523 {
1524     if (key.IsInt()) {
1525         int index = key.GetInt();
1526         if (index >= 0) {
1527             *output = index;
1528             return true;
1529         }
1530     } else if (key.IsDouble()) {
1531         double d = key.GetDouble();
1532         uint32_t index = static_cast<uint32_t>(base::NumberHelper::DoubleToInt(d, base::INT32_BITS));
1533         if (d - static_cast<double>(index) == 0.0) {
1534             *output = index;
1535             return true;
1536         }
1537     } else if (key.IsString()) {
1538         return StringToElementIndex(key, output);
1539     }
1540     return false;
1541 }
1542 
StringToElementIndex(JSTaggedValue key,uint32_t * output)1543 inline bool JSTaggedValue::StringToElementIndex(JSTaggedValue key, uint32_t *output)
1544 {
1545     ASSERT(key.IsString());
1546     auto strObj = static_cast<EcmaString *>(key.GetTaggedObject());
1547     return EcmaStringAccessor(strObj).ToElementIndex(output);
1548 }
1549 
GetKeyHashCode()1550 inline uint32_t JSTaggedValue::GetKeyHashCode() const
1551 {
1552     ASSERT(IsStringOrSymbol());
1553     if (IsString()) {
1554         return EcmaStringAccessor(GetTaggedObject()).GetHashcode();
1555     }
1556 
1557     return JSSymbol::Cast(GetTaggedObject())->GetHashField();
1558 }
1559 
StringToDouble(JSTaggedValue tagged)1560 inline JSTaggedNumber JSTaggedValue::StringToDouble(JSTaggedValue tagged)
1561 {
1562     auto strObj = static_cast<EcmaString *>(tagged.GetTaggedObject());
1563     size_t strLen = EcmaStringAccessor(strObj).GetLength();
1564     if (strLen == 0) {
1565         return JSTaggedNumber(0);
1566     }
1567     CVector<uint8_t> buf;
1568     Span<const uint8_t> str = EcmaStringAccessor(strObj).ToUtf8Span(buf);
1569     double d = base::NumberHelper::StringToDouble(str.begin(), str.end(), 0,
1570                                                   base::ALLOW_BINARY + base::ALLOW_OCTAL + base::ALLOW_HEX);
1571     return JSTaggedNumber(d);
1572 }
1573 
StringCompare(EcmaString * xStr,EcmaString * yStr)1574 inline bool JSTaggedValue::StringCompare(EcmaString *xStr, EcmaString *yStr)
1575 {
1576     if (EcmaStringAccessor(xStr).IsInternString() && EcmaStringAccessor(yStr).IsInternString()) {
1577         return xStr == yStr;
1578     }
1579     return EcmaStringAccessor::StringsAreEqual(xStr, yStr);
1580 }
1581 
TryCastDoubleToInt32(double d)1582 inline JSTaggedValue JSTaggedValue::TryCastDoubleToInt32(double d)
1583 {
1584     if (UNLIKELY(static_cast<int32_t>(d) != d)) {
1585         return JSTaggedValue(d);
1586     }
1587     return JSTaggedValue(static_cast<int32_t>(d));
1588 }
1589 
IsPureString(JSTaggedValue key)1590 inline bool JSTaggedValue::IsPureString(JSTaggedValue key)
1591 {
1592     if (!key.IsString()) {
1593         return false;
1594     }
1595     uint32_t idx;
1596     return !StringToElementIndex(key, &idx);
1597 }
1598 }  // namespace panda::ecmascript
1599 #endif  // ECMASCRIPT_TAGGED_VALUE_INL_H
1600