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