• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #include <cinttypes>
17 
18 #include "ecmascript/base/json_stringifier.h"
19 #include "ecmascript/base/typed_array_helper-inl.h"
20 #include "ecmascript/builtins/builtins_object.h"
21 #include "ecmascript/shared_objects/concurrent_api_scope.h"
22 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
23 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
24 #endif
25 #include "ecmascript/checkpoint/thread_state_transition.h"
26 #include "ecmascript/ecma_global_storage.h"
27 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
28 #include "ecmascript/interpreter/interpreter_assembly.h"
29 #include "ecmascript/jsnapi_sendable.h"
30 #include "ecmascript/jspandafile/js_pandafile_executor.h"
31 #include "ecmascript/js_hclass.h"
32 #include "ecmascript/lexical_env.h"
33 #include "ecmascript/linked_hash_table.h"
34 #include "ecmascript/mem/idle_gc_trigger.h"
35 #include "ecmascript/module/module_logger.h"
36 #include "ecmascript/module/napi_module_loader.h"
37 #include "ecmascript/napi/jsnapi_class_creation_helper.h"
38 #include "ecmascript/ohos/js_pandafile_snapshot_interfaces.h"
39 #include "ecmascript/ohos/module_snapshot_interfaces.h"
40 #include "ecmascript/ohos/ohos_constants.h"
41 #if defined(ENABLE_EXCEPTION_BACKTRACE)
42 #include "ecmascript/platform/backtrace.h"
43 #endif
44 #include "ecmascript/regexp/regexp_parser.h"
45 #include "ecmascript/serializer/base_deserializer.h"
46 #include "ecmascript/serializer/inter_op_value_deserializer.h"
47 #include "ecmascript/serializer/inter_op_value_serializer.h"
48 #include "ecmascript/serializer/value_serializer.h"
49 #include "ecmascript/platform/aot_crash_info.h"
50 #include "ecmascript/platform/dfx_crash_obj.h"
51 #ifdef ARK_SUPPORT_INTL
52 #include "ecmascript/js_bigint.h"
53 #include "ecmascript/js_collator.h"
54 #include "ecmascript/js_date_time_format.h"
55 #include "ecmascript/js_number_format.h"
56 #endif
57 #if defined(ENABLE_LOCAL_HANDLE_LEAK_DETECT)
58 #include "ecmascript/dfx/hprof/heap_profiler.h"
59 #endif
60 
61 namespace panda {
62 using ecmascript::AccessorData;
63 using ecmascript::BigInt;
64 using ecmascript::ByteArray;
65 using ecmascript::DataViewType;
66 using ecmascript::ECMAObject;
67 using ecmascript::EcmaRuntimeCallInfo;
68 using ecmascript::EcmaString;
69 using ecmascript::EcmaStringAccessor;
70 using ecmascript::ErrorType;
71 using ecmascript::FastRuntimeStub;
72 using ecmascript::GeneratorContext;
73 using ecmascript::GlobalEnv;
74 using ecmascript::GlobalEnvConstants;
75 using ecmascript::IterationKind;
76 using ecmascript::JSArray;
77 using ecmascript::JSArrayBuffer;
78 using ecmascript::JSDataView;
79 using ecmascript::JSDate;
80 using ecmascript::JSFunction;
81 using ecmascript::JSFunctionBase;
82 using ecmascript::JSGeneratorFunction;
83 using ecmascript::JSGeneratorObject;
84 using ecmascript::JSGeneratorState;
85 using ecmascript::JSHClass;
86 using ecmascript::JSIterator;
87 using ecmascript::JSMap;
88 using ecmascript::JSMapIterator;
89 using ecmascript::JSNapiSendable;
90 using ecmascript::JSNativePointer;
91 using ecmascript::JSObject;
92 using ecmascript::JSPandaFile;
93 using ecmascript::JSPandaFileManager;
94 using ecmascript::JSPrimitiveRef;
95 using ecmascript::JSPromise;
96 using ecmascript::JSProxy;
97 using ecmascript::ObjectFastOperator;
98 using ecmascript::JSRegExp;
99 using ecmascript::JSRuntimeOptions;
100 using ecmascript::JSSet;
101 using ecmascript::JSSetIterator;
102 using ecmascript::JSSymbol;
103 using ecmascript::JSTaggedNumber;
104 using ecmascript::JSTaggedType;
105 using ecmascript::JSTaggedValue;
106 using ecmascript::JSThread;
107 using ecmascript::JSType;
108 using ecmascript::JSTypedArray;
109 using ecmascript::JSNApiClassCreationHelper;
110 using ecmascript::LinkedHashMap;
111 using ecmascript::LinkedHashSet;
112 using ecmascript::LockHolder;
113 using ecmascript::MemMapAllocator;
114 using ecmascript::Method;
115 using ecmascript::NativeModuleFailureInfo;
116 using ecmascript::ObjectFactory;
117 using ecmascript::OperationResult;
118 using ecmascript::PromiseCapability;
119 using ecmascript::PropertyDescriptor;
120 using ecmascript::Region;
121 using ecmascript::TaggedArray;
122 using ecmascript::base::BuiltinsBase;
123 using ecmascript::base::JsonStringifier;
124 using ecmascript::SharedHeap;
125 using ecmascript::base::StringHelper;
126 using ecmascript::base::TypedArrayHelper;
127 using ecmascript::base::Utf16JsonParser;
128 using ecmascript::base::Utf8JsonParser;
129 using ecmascript::builtins::BuiltinsObject;
130 using ecmascript::job::MicroJobQueue;
131 using ecmascript::job::QueueType;
132 #ifdef ARK_SUPPORT_INTL
133 using ecmascript::JSCollator;
134 using ecmascript::JSDateTimeFormat;
135 using ecmascript::JSNumberFormat;
136 #endif
137 using ecmascript::DebugInfoExtractor;
138 using ecmascript::JSWeakMap;
139 using ecmascript::JSWeakSet;
140 using ecmascript::RegExpParser;
141 using ecmascript::base::NumberHelper;
142 template <typename T>
143 using JSHandle = ecmascript::JSHandle<T>;
144 template <typename T>
145 using JSMutableHandle = ecmascript::JSMutableHandle<T>;
146 
147 using PathHelper = ecmascript::base::PathHelper;
148 using ModulePathHelper = ecmascript::ModulePathHelper;
149 using JsDebuggerManager = ecmascript::tooling::JsDebuggerManager;
150 using FrameIterator = ecmascript::FrameIterator;
151 using Concurrent = ecmascript::Concurrent;
152 using EnableAotJitListHelper = ecmascript::ohos::EnableAotJitListHelper;
153 using PGOProfilerManager = ecmascript::pgo::PGOProfilerManager;
154 using AotRuntimeInfo = ecmascript::ohos::AotRuntimeInfo;
155 #if defined(ENABLE_LOCAL_HANDLE_LEAK_DETECT)
156 using HeapProfiler = ecmascript::HeapProfiler;
157 using HeapProfilerInterface = ecmascript::HeapProfilerInterface;
158 #endif
159 
160 namespace {
161 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
162 constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0";
163 }
164 
165 bool JSNApi::isForked_ = false;
166 static ecmascript::Mutex *mutex = new panda::ecmascript::Mutex();
167 StartIdleMonitorCallback JSNApi::startIdleMonitorCallback_ = nullptr;
168 const static uint32_t API_VERSION_MASK = 100;
169 
170 // ----------------------------------- ArkCrashHolder --------------------------------------
171 constexpr size_t FORMATED_FUNCPTR_LENGTH = 36; // length of dec function pointer
172 
~ArkCrashHolder()173 ArkCrashHolder::~ArkCrashHolder()
174 {
175     ecmascript::ResetCrashObject(handle_);
176     if (data_ != nullptr) {
177         delete [] data_;
178         data_ = nullptr;
179     }
180 }
181 
SetCrashObj(const char * tag,const char * info)182 void ArkCrashHolder::SetCrashObj(const char* tag, const char* info)
183 {
184     std::string data = "[";
185     data += tag,
186     data += "] Crash occured on ";
187     data += info;
188     data += ", callback: ";
189 
190     size_ = data.length();
191     const size_t bufSize = size_ + FORMATED_FUNCPTR_LENGTH;
192     data_ = new char[bufSize];
193 
194     if (memcpy_s(data_, bufSize, data.c_str(), size_) != EOK) {
195         LOG_FULL(WARN) << "Failed to init crash holder.";
196         size_ = 0;
197         data_[0] = '\0';
198     };
199 
200     handle_ = ecmascript::SetCrashObject(ecmascript::DFXObjectType::STRING, reinterpret_cast<uintptr_t>(data_));
201 }
202 
UpdateCallbackPtr(uintptr_t addr)203 void ArkCrashHolder::UpdateCallbackPtr(uintptr_t addr)
204 {
205     if (sprintf_s(data_ + size_, FORMATED_FUNCPTR_LENGTH, "%" PRIuPTR, addr) < 0) {
206         LOG_FULL(ERROR) << "Failed to update callback info: " << addr;
207     }
208 }
209 
210 #undef ENABLE_DFX_CRASH_OBJECT
211 
212 // ----------------------------------- JSValueRef --------------------------------------
Undefined(const EcmaVM * vm)213 Local<PrimitiveRef> JSValueRef::Undefined(const EcmaVM *vm)
214 {
215     return JSNApiHelper::ToLocal<PrimitiveRef>(
216         vm->GetJSThread()->GlobalConstants()->GetHandledUndefined());
217 }
218 
Null(const EcmaVM * vm)219 Local<PrimitiveRef> JSValueRef::Null(const EcmaVM *vm)
220 {
221     return JSNApiHelper::ToLocal<PrimitiveRef>(
222         vm->GetJSThread()->GlobalConstants()->GetHandledNull());
223 }
224 
Hole(const EcmaVM * vm)225 Local<PrimitiveRef> JSValueRef::Hole(const EcmaVM *vm)
226 {
227     return JSNApiHelper::ToLocal<PrimitiveRef>(
228         vm->GetJSThread()->GlobalConstants()->GetHandledHole());
229 }
230 
True(const EcmaVM * vm)231 Local<PrimitiveRef> JSValueRef::True(const EcmaVM *vm)
232 {
233     return JSNApiHelper::ToLocal<PrimitiveRef>(
234         vm->GetJSThread()->GlobalConstants()->GetHandledTrue());
235 }
236 
False(const EcmaVM * vm)237 Local<PrimitiveRef> JSValueRef::False(const EcmaVM *vm)
238 {
239     return JSNApiHelper::ToLocal<PrimitiveRef>(
240         vm->GetJSThread()->GlobalConstants()->GetHandledFalse());
241 }
242 
ToObject(const EcmaVM * vm)243 Local<ObjectRef> JSValueRef::ToObject(const EcmaVM *vm)
244 {
245     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
246     if (IsUndefined() || IsNull()) {
247         return Undefined(vm);
248     }
249     ecmascript::ThreadManagedScope managedScope(thread);
250     JSHandle<JSTaggedValue> obj(JSTaggedValue::ToObject(thread, JSNApiHelper::ToJSHandle(this)));
251     LOG_IF_SPECIAL(obj, ERROR);
252     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
253     return JSNApiHelper::ToLocal<ObjectRef>(obj);
254 }
255 
ToEcmaObject(const EcmaVM * vm)256 Local<ObjectRef> JSValueRef::ToEcmaObject(const EcmaVM *vm)
257 {
258     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
259     ecmascript::ThreadManagedScope managedScope(thread);
260     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
261     LOG_IF_SPECIAL(obj, ERROR);
262     if (obj->IsECMAObject()) {
263         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
264         return JSNApiHelper::ToLocal<ObjectRef>(obj);
265     }
266 
267     return Undefined(vm);
268 }
269 
ToEcmaObjectWithoutSwitchState(const EcmaVM * vm)270 Local<ObjectRef> JSValueRef::ToEcmaObjectWithoutSwitchState(const EcmaVM *vm)
271 {
272     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
273     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
274     LOG_IF_SPECIAL(obj, ERROR);
275     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
276     return JSNApiHelper::ToLocal<ObjectRef>(obj);
277 }
278 
ToString(const EcmaVM * vm)279 Local<StringRef> JSValueRef::ToString(const EcmaVM *vm)
280 {
281     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
282     ecmascript::ThreadManagedScope managedScope(thread);
283     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
284     LOG_IF_SPECIAL(obj, ERROR);
285     if (!obj->IsString()) {
286         obj = JSHandle<JSTaggedValue>(JSTaggedValue::ToString(thread, obj));
287         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
288     }
289     return JSNApiHelper::ToLocal<StringRef>(obj);
290 }
291 
ToNativePointer(const EcmaVM * vm)292 Local<NativePointerRef> JSValueRef::ToNativePointer(const EcmaVM *vm)
293 {
294     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
295     ecmascript::ThreadManagedScope managedScope(thread);
296     // The function just get handle' value, and will not read and write js object. Don't need to switch state.
297     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
298     LOG_IF_SPECIAL(obj, ERROR);
299     return JSNApiHelper::ToLocal<NativePointerRef>(obj);
300 }
301 
BooleaValue(const EcmaVM * vm)302 bool JSValueRef::BooleaValue(const EcmaVM *vm)
303 {
304     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
305     return JSNApiHelper::ToJSTaggedValue(this).ToBoolean();
306 }
307 
IntegerValue(const EcmaVM * vm)308 int64_t JSValueRef::IntegerValue(const EcmaVM *vm)
309 {
310     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
311     ecmascript::ThreadManagedScope managedScope(thread);
312     JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
313     LOG_IF_SPECIAL(tagged, ERROR);
314     if (tagged->IsNumber()) {
315         if (!NumberHelper::IsFinite(tagged.GetTaggedValue()) || NumberHelper::IsNaN(tagged.GetTaggedValue())) {
316             return 0;
317         } else {
318             return NumberHelper::DoubleToInt64(tagged->GetNumber());
319         }
320     }
321     JSTaggedNumber number = JSTaggedValue::ToInteger(thread, tagged);
322     RETURN_VALUE_IF_ABRUPT(thread, 0);
323     return NumberHelper::DoubleToInt64(number.GetNumber());
324 }
325 
Uint32Value(const EcmaVM * vm)326 uint32_t JSValueRef::Uint32Value(const EcmaVM *vm)
327 {
328     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
329     ecmascript::ThreadManagedScope managedScope(thread);
330     JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
331     uint32_t number = 0;
332     if (!tagged->IsECMAObject()) {
333         number = JSTaggedValue::ToUint32(thread, tagged);
334     } else {
335         // EcmaObject may call [Symbol.toPrimitive].
336         number = JSTaggedValue::ToUint32(thread, tagged);
337     }
338     RETURN_VALUE_IF_ABRUPT(thread, 0);
339     return number;
340 }
341 
Int32Value(const EcmaVM * vm)342 int32_t JSValueRef::Int32Value(const EcmaVM *vm)
343 {
344     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
345     ecmascript::ThreadManagedScope managedScope(thread);
346     JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
347     int32_t number = 0;
348     if (!tagged->IsECMAObject()) {
349         number = JSTaggedValue::ToInt32(thread, tagged);
350     } else {
351         // EcmaObject may call [Symbol.toPrimitive].
352         number = JSTaggedValue::ToInt32(thread, tagged);
353     }
354     RETURN_VALUE_IF_ABRUPT(thread, 0);
355     return number;
356 }
357 
GetValueDouble(bool & isNumber)358 double JSValueRef::GetValueDouble(bool &isNumber)
359 {
360     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
361     if (value.IsInt()) {
362         isNumber = true;
363         return static_cast<double>(value.GetInt());
364     }
365     if (value.IsDouble()) {
366         isNumber = true;
367         return value.GetDouble();
368     }
369     isNumber = false;
370     return 0.0;
371 }
372 
GetValueInt32(bool & isNumber)373 int32_t JSValueRef::GetValueInt32(bool &isNumber)
374 {
375     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
376     if (value.IsInt()) {
377         isNumber = true;
378         return value.GetInt();
379     }
380     if (value.IsDouble()) {
381         isNumber = true;
382         return static_cast<int32_t>(ecmascript::base::NumberHelper::DoubleToInt(value.GetDouble(),
383             ecmascript::base::INT32_BITS));
384     }
385     isNumber = false;
386     return 0;
387 }
388 
GetValueUint32(bool & isNumber)389 uint32_t JSValueRef::GetValueUint32(bool &isNumber)
390 {
391     return static_cast<uint32_t>(GetValueInt32(isNumber));
392 }
393 
GetValueInt64(bool & isNumber)394 int64_t JSValueRef::GetValueInt64(bool &isNumber)
395 {
396     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
397     if (value.IsInt()) {
398         isNumber = true;
399         return static_cast<int64_t>(value.GetInt());
400     }
401     if (value.IsDouble()) {
402         isNumber = true;
403         double getVale = value.GetDouble();
404         if (!std::isfinite(getVale) || std::isnan(getVale)) {
405             return 0;
406         }
407         return NumberHelper::DoubleToInt64(getVale);
408     }
409     isNumber = false;
410     return 0;
411 }
412 
GetValueBool(bool & isBool)413 bool JSValueRef::GetValueBool(bool &isBool)
414 {
415     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
416     if (value.IsTrue()) {
417         isBool = true;
418         return true;
419     }
420     if (value.IsFalse()) {
421         isBool = true;
422         return false;
423     }
424     isBool = false;
425     return false;
426 }
427 
ToBoolean(const EcmaVM * vm)428 Local<BooleanRef> JSValueRef::ToBoolean(const EcmaVM *vm)
429 {
430     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
431     ecmascript::ThreadManagedScope managedScope(thread);
432     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
433     LOG_IF_SPECIAL(obj, ERROR);
434     JSHandle<JSTaggedValue> booleanObj(thread, JSTaggedValue(obj->ToBoolean()));
435     return JSNApiHelper::ToLocal<BooleanRef>(booleanObj);
436 }
437 
ToBigInt(const EcmaVM * vm)438 Local<BigIntRef> JSValueRef::ToBigInt(const EcmaVM *vm)
439 {
440     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
441     ecmascript::ThreadManagedScope managedScope(thread);
442     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
443     LOG_IF_SPECIAL(obj, ERROR);
444     JSHandle<JSTaggedValue> bigIntObj(thread, JSTaggedValue::ToBigInt(thread, obj));
445     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
446     return JSNApiHelper::ToLocal<BigIntRef>(bigIntObj);
447 }
448 
ToNumber(const EcmaVM * vm)449 Local<NumberRef> JSValueRef::ToNumber(const EcmaVM *vm)
450 {
451     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
452     ecmascript::ThreadManagedScope managedScope(thread);
453     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
454     LOG_IF_SPECIAL(obj, ERROR);
455     JSHandle<JSTaggedValue> number(thread, JSTaggedValue::ToNumber(thread, obj));
456     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
457     return JSNApiHelper::ToLocal<NumberRef>(number);
458 }
459 
IsStrictEquals(const EcmaVM * vm,Local<JSValueRef> value)460 bool JSValueRef::IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value)
461 {
462     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
463     ecmascript::ThreadManagedScope managedScope(thread);
464     JSHandle<JSTaggedValue> xValue = JSNApiHelper::ToJSHandle(this);
465     LOG_IF_SPECIAL(xValue, ERROR);
466     JSHandle<JSTaggedValue> yValue = JSNApiHelper::ToJSHandle(value);
467     return JSTaggedValue::StrictEqual(thread, xValue, yValue);
468 }
469 
Typeof(const EcmaVM * vm)470 Local<StringRef> JSValueRef::Typeof(const EcmaVM *vm)
471 {
472     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
473     ecmascript::ThreadManagedScope managedScope(thread);
474     JSTaggedValue value = FastRuntimeStub::FastTypeOf(thread, JSNApiHelper::ToJSTaggedValue(this));
475     return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(thread, value));
476 }
477 
InstanceOf(const EcmaVM * vm,Local<JSValueRef> value)478 bool JSValueRef::InstanceOf(const EcmaVM *vm, Local<JSValueRef> value)
479 {
480     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
481     ecmascript::ThreadManagedScope managedScope(thread);
482     JSHandle<JSTaggedValue> origin = JSNApiHelper::ToJSHandle(this);
483     LOG_IF_SPECIAL(origin, ERROR);
484     JSHandle<JSTaggedValue> target = JSNApiHelper::ToJSHandle(value);
485     return JSObject::InstanceOf(thread, origin, target);
486 }
487 
488 // Omit exception check for JSValueRef::IsXxx because ark calls here may not
489 // cause side effect even pending exception exists.
IsUndefined()490 bool JSValueRef::IsUndefined()
491 {
492     return JSNApiHelper::ToJSTaggedValue(this).IsUndefined();
493 }
494 
IsNull()495 bool JSValueRef::IsNull()
496 {
497     return JSNApiHelper::ToJSTaggedValue(this).IsNull();
498 }
499 
IsHole()500 bool JSValueRef::IsHole()
501 {
502     return JSNApiHelper::ToJSTaggedValue(this).IsHole();
503 }
504 
IsTrue()505 bool JSValueRef::IsTrue()
506 {
507     return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
508 }
509 
IsFalse()510 bool JSValueRef::IsFalse()
511 {
512     return JSNApiHelper::ToJSTaggedValue(this).IsFalse();
513 }
514 
IsNumber()515 bool JSValueRef::IsNumber()
516 {
517     return JSNApiHelper::ToJSTaggedValue(this).IsNumber();
518 }
519 
IsBigInt(const EcmaVM * vm)520 bool JSValueRef::IsBigInt(const EcmaVM *vm)
521 {
522     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
523     return JSNApiHelper::ToJSTaggedValue(this).IsBigInt();
524 }
525 
IsInt()526 bool JSValueRef::IsInt()
527 {
528     return JSNApiHelper::ToJSTaggedValue(this).IsInt();
529 }
530 
WithinInt32()531 bool JSValueRef::WithinInt32()
532 {
533     return JSNApiHelper::ToJSTaggedValue(this).WithinInt32();
534 }
535 
IsBoolean()536 bool JSValueRef::IsBoolean()
537 {
538     return JSNApiHelper::ToJSTaggedValue(this).IsBoolean();
539 }
540 
IsString(const EcmaVM * vm)541 bool JSValueRef::IsString(const EcmaVM *vm)
542 {
543     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
544     return JSNApiHelper::ToJSTaggedValue(this).IsString();
545 }
546 
IsStringWithoutSwitchState(const EcmaVM * vm)547 bool JSValueRef::IsStringWithoutSwitchState(const EcmaVM *vm)
548 {
549     CROSS_THREAD_CHECK(vm);
550     return JSNApiHelper::ToJSTaggedValue(this).IsString();
551 }
552 
IsSymbol(const EcmaVM * vm)553 bool JSValueRef::IsSymbol(const EcmaVM *vm)
554 {
555     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
556     return JSNApiHelper::ToJSTaggedValue(this).IsSymbol();
557 }
558 
IsObject(const EcmaVM * vm)559 bool JSValueRef::IsObject(const EcmaVM *vm)
560 {
561     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
562     return JSNApiHelper::ToJSTaggedValue(this).IsECMAObject();
563 }
564 
IsObjectWithoutSwitchState(const EcmaVM * vm)565 bool JSValueRef::IsObjectWithoutSwitchState(const EcmaVM *vm)
566 {
567     CROSS_THREAD_CHECK(vm);
568     return JSNApiHelper::ToJSTaggedValue(this).IsECMAObject();
569 }
570 
IsNativeBindingObject(const EcmaVM * vm)571 bool JSValueRef::IsNativeBindingObject(const EcmaVM *vm)
572 {
573     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
574     JSTaggedValue object = JSNApiHelper::ToJSTaggedValue(this);
575     if (!object.IsECMAObject()) {
576         return false;
577     }
578 
579     return object.GetTaggedObject()->GetClass()->IsNativeBindingObject();
580 }
581 
IsArray(const EcmaVM * vm)582 bool JSValueRef::IsArray(const EcmaVM *vm)
583 {
584     CROSS_THREAD_CHECK(vm);
585     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
586     return JSNApiHelper::ToJSTaggedValue(this).IsArray(thread);
587 }
588 
IsJSArray(const EcmaVM * vm)589 bool JSValueRef::IsJSArray(const EcmaVM *vm)
590 {
591     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
592     return JSNApiHelper::ToJSTaggedValue(this).IsJSArray();
593 }
594 
IsConstructor(const EcmaVM * vm)595 bool JSValueRef::IsConstructor(const EcmaVM *vm)
596 {
597     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
598     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
599     return value.IsHeapObject() && value.IsConstructor();
600 }
601 
IsFunction(const EcmaVM * vm)602 bool JSValueRef::IsFunction(const EcmaVM *vm)
603 {
604     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
605     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
606     return value.IsCallable();
607 }
608 
IsJSFunction(const EcmaVM * vm)609 bool JSValueRef::IsJSFunction(const EcmaVM *vm)
610 {
611     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
612     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
613     return value.IsJSFunction();
614 }
615 
IsProxy(const EcmaVM * vm)616 bool JSValueRef::IsProxy(const EcmaVM *vm)
617 {
618     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
619     return JSNApiHelper::ToJSTaggedValue(this).IsJSProxy();
620 }
621 
IsPromise(const EcmaVM * vm)622 bool JSValueRef::IsPromise(const EcmaVM *vm)
623 {
624     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
625     return JSNApiHelper::ToJSTaggedValue(this).IsJSPromise();
626 }
627 
IsDataView(const EcmaVM * vm)628 bool JSValueRef::IsDataView(const EcmaVM *vm)
629 {
630     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
631     return JSNApiHelper::ToJSTaggedValue(this).IsDataView();
632 }
633 
IsTypedArray(const EcmaVM * vm)634 bool JSValueRef::IsTypedArray(const EcmaVM *vm)
635 {
636     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
637     return JSNApiHelper::ToJSTaggedValue(this).IsTypedArray();
638 }
639 
IsNativePointer(const EcmaVM * vm)640 bool JSValueRef::IsNativePointer(const EcmaVM *vm)
641 {
642     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
643     return JSNApiHelper::ToJSTaggedValue(this).IsJSNativePointer();
644 }
645 
IsDate(const EcmaVM * vm)646 bool JSValueRef::IsDate(const EcmaVM *vm)
647 {
648     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
649     return JSNApiHelper::ToJSTaggedValue(this).IsDate();
650 }
651 
IsError(const EcmaVM * vm)652 bool JSValueRef::IsError(const EcmaVM *vm)
653 {
654     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
655     return JSNApiHelper::ToJSTaggedValue(this).IsJSError();
656 }
657 
IsMap(const EcmaVM * vm)658 bool JSValueRef::IsMap(const EcmaVM *vm)
659 {
660     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
661     return JSNApiHelper::ToJSTaggedValue(this).IsJSMap();
662 }
663 
IsSet(const EcmaVM * vm)664 bool JSValueRef::IsSet(const EcmaVM *vm)
665 {
666     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
667     return JSNApiHelper::ToJSTaggedValue(this).IsJSSet();
668 }
669 
IsWeakRef(const EcmaVM * vm)670 bool JSValueRef::IsWeakRef(const EcmaVM *vm)
671 {
672     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
673     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakRef();
674 }
675 
IsWeakMap(const EcmaVM * vm)676 bool JSValueRef::IsWeakMap(const EcmaVM *vm)
677 {
678     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
679     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakMap();
680 }
681 
IsWeakSet(const EcmaVM * vm)682 bool JSValueRef::IsWeakSet(const EcmaVM *vm)
683 {
684     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
685     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakSet();
686 }
687 
IsRegExp(const EcmaVM * vm)688 bool JSValueRef::IsRegExp(const EcmaVM *vm)
689 {
690     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
691     return JSNApiHelper::ToJSTaggedValue(this).IsJSRegExp();
692 }
693 
IsArrayIterator(const EcmaVM * vm)694 bool JSValueRef::IsArrayIterator(const EcmaVM *vm)
695 {
696     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
697     return JSNApiHelper::ToJSTaggedValue(this).IsJSArrayIterator();
698 }
699 
IsStringIterator(const EcmaVM * vm)700 bool JSValueRef::IsStringIterator(const EcmaVM *vm)
701 {
702     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
703     return JSNApiHelper::ToJSTaggedValue(this).IsStringIterator();
704 }
705 
IsSetIterator(const EcmaVM * vm)706 bool JSValueRef::IsSetIterator(const EcmaVM *vm)
707 {
708     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
709     return JSNApiHelper::ToJSTaggedValue(this).IsJSSetIterator();
710 }
711 
IsMapIterator(const EcmaVM * vm)712 bool JSValueRef::IsMapIterator(const EcmaVM *vm)
713 {
714     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
715     return JSNApiHelper::ToJSTaggedValue(this).IsJSMapIterator();
716 }
717 
IsArrayBuffer(const EcmaVM * vm)718 bool JSValueRef::IsArrayBuffer(const EcmaVM *vm)
719 {
720     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
721     return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer();
722 }
723 
IsBuffer(const EcmaVM * vm)724 bool JSValueRef::IsBuffer(const EcmaVM *vm)
725 {
726     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
727     return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer();
728 }
729 
IsUint8Array(const EcmaVM * vm)730 bool JSValueRef::IsUint8Array(const EcmaVM *vm)
731 {
732     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
733     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8Array();
734 }
735 
IsInt8Array(const EcmaVM * vm)736 bool JSValueRef::IsInt8Array(const EcmaVM *vm)
737 {
738     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
739     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt8Array();
740 }
741 
IsUint8ClampedArray(const EcmaVM * vm)742 bool JSValueRef::IsUint8ClampedArray(const EcmaVM *vm)
743 {
744     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
745     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8ClampedArray();
746 }
747 
IsInt16Array(const EcmaVM * vm)748 bool JSValueRef::IsInt16Array(const EcmaVM *vm)
749 {
750     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
751     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt16Array();
752 }
753 
IsUint16Array(const EcmaVM * vm)754 bool JSValueRef::IsUint16Array(const EcmaVM *vm)
755 {
756     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
757     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint16Array();
758 }
759 
IsInt32Array(const EcmaVM * vm)760 bool JSValueRef::IsInt32Array(const EcmaVM *vm)
761 {
762     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
763     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt32Array();
764 }
765 
IsUint32Array(const EcmaVM * vm)766 bool JSValueRef::IsUint32Array(const EcmaVM *vm)
767 {
768     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
769     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint32Array();
770 }
771 
IsFloat32Array(const EcmaVM * vm)772 bool JSValueRef::IsFloat32Array(const EcmaVM *vm)
773 {
774     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
775     return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat32Array();
776 }
777 
IsFloat64Array(const EcmaVM * vm)778 bool JSValueRef::IsFloat64Array(const EcmaVM *vm)
779 {
780     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
781     return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat64Array();
782 }
783 
IsBigInt64Array(const EcmaVM * vm)784 bool JSValueRef::IsBigInt64Array(const EcmaVM *vm)
785 {
786     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
787     return JSNApiHelper::ToJSTaggedValue(this).IsJSBigInt64Array();
788 }
789 
IsBigUint64Array(const EcmaVM * vm)790 bool JSValueRef::IsBigUint64Array(const EcmaVM *vm)
791 {
792     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
793     return JSNApiHelper::ToJSTaggedValue(this).IsJSBigUint64Array();
794 }
795 
IsJSSharedInt8Array(const EcmaVM * vm)796 bool JSValueRef::IsJSSharedInt8Array(const EcmaVM *vm)
797 {
798     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
799     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt8Array();
800 }
801 
IsJSSharedUint8Array(const EcmaVM * vm)802 bool JSValueRef::IsJSSharedUint8Array([[maybe_unused]]const EcmaVM *vm)
803 {
804     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
805     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint8Array();
806 }
807 
IsJSSharedUint8ClampedArray(const EcmaVM * vm)808 bool JSValueRef::IsJSSharedUint8ClampedArray([[maybe_unused]]const EcmaVM *vm)
809 {
810     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
811     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint8ClampedArray();
812 }
813 
IsJSSharedInt16Array(const EcmaVM * vm)814 bool JSValueRef::IsJSSharedInt16Array(const EcmaVM *vm)
815 {
816     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
817     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt16Array();
818 }
819 
IsJSSharedUint16Array(const EcmaVM * vm)820 bool JSValueRef::IsJSSharedUint16Array(const EcmaVM *vm)
821 {
822     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
823     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint16Array();
824 }
825 
IsJSSharedInt32Array(const EcmaVM * vm)826 bool JSValueRef::IsJSSharedInt32Array(const EcmaVM *vm)
827 {
828     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
829     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt32Array();
830 }
831 
IsJSSharedFloat32Array(const EcmaVM * vm)832 bool JSValueRef::IsJSSharedFloat32Array(const EcmaVM *vm)
833 {
834     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
835     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedFloat32Array();
836 }
837 
IsJSSharedUint32Array(const EcmaVM * vm)838 bool JSValueRef::IsJSSharedUint32Array(const EcmaVM *vm)
839 {
840     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
841     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint32Array();
842 }
843 
IsJSPrimitiveRef(const EcmaVM * vm)844 bool JSValueRef::IsJSPrimitiveRef(const EcmaVM *vm)
845 {
846     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
847     return JSNApiHelper::ToJSTaggedValue(this).IsJSPrimitiveRef();
848 }
849 
IsJSPrimitiveNumber(const EcmaVM * vm)850 bool JSValueRef::IsJSPrimitiveNumber(const EcmaVM *vm)
851 {
852     JSThread *thread = vm->GetJSThread();
853     ecmascript::ThreadManagedScope managedScope(thread);
854     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
855     LOG_IF_SPECIAL(obj, FATAL);
856     return IsJSPrimitiveRef(vm) ? JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsNumber(thread) : false;
857 }
858 
IsJSPrimitiveInt(const EcmaVM * vm)859 bool JSValueRef::IsJSPrimitiveInt(const EcmaVM *vm)
860 {
861     JSThread *thread = vm->GetJSThread();
862     ecmascript::ThreadManagedScope managedScope(thread);
863     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
864     LOG_IF_SPECIAL(obj, FATAL);
865     return IsJSPrimitiveRef(vm) ? JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsInt(thread) : false;
866 }
867 
IsJSPrimitiveBoolean(const EcmaVM * vm)868 bool JSValueRef::IsJSPrimitiveBoolean(const EcmaVM *vm)
869 {
870     JSThread *thread = vm->GetJSThread();
871     ecmascript::ThreadManagedScope managedScope(thread);
872     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
873     LOG_IF_SPECIAL(obj, FATAL);
874     return IsJSPrimitiveRef(vm) ? JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsBoolean(thread) : false;
875 }
876 
IsJSPrimitiveString(const EcmaVM * vm)877 bool JSValueRef::IsJSPrimitiveString(const EcmaVM *vm)
878 {
879     JSThread *thread = vm->GetJSThread();
880     ecmascript::ThreadManagedScope managedScope(thread);
881     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
882     LOG_IF_SPECIAL(obj, FATAL);
883     return IsJSPrimitiveRef(vm) ? JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsString(thread) : false;
884 }
885 
IsJSPrimitiveSymbol(const EcmaVM * vm)886 bool JSValueRef::IsJSPrimitiveSymbol(const EcmaVM *vm)
887 {
888     JSThread *thread = vm->GetJSThread();
889     ecmascript::ThreadManagedScope managedScope(thread);
890     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
891     LOG_IF_SPECIAL(obj, FATAL);
892     return IsJSPrimitiveRef(vm) ? JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsSymbol(thread) : false;
893 }
894 
IsGeneratorObject(const EcmaVM * vm)895 bool JSValueRef::IsGeneratorObject(const EcmaVM *vm)
896 {
897     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
898     return JSNApiHelper::ToJSTaggedValue(this).IsGeneratorObject();
899 }
900 
IsModuleNamespaceObject(const EcmaVM * vm)901 bool JSValueRef::IsModuleNamespaceObject(const EcmaVM *vm)
902 {
903     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
904     return JSNApiHelper::ToJSTaggedValue(this).IsModuleNamespace();
905 }
906 
IsNativeModuleFailureInfoObject(const EcmaVM * vm)907 bool JSValueRef::IsNativeModuleFailureInfoObject(const EcmaVM *vm)
908 {
909     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
910     return JSNApiHelper::ToJSTaggedValue(this).IsNativeModuleFailureInfo();
911 }
912 
IsSharedArrayBuffer(const EcmaVM * vm)913 bool JSValueRef::IsSharedArrayBuffer(const EcmaVM *vm)
914 {
915     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
916     return JSNApiHelper::ToJSTaggedValue(this).IsSharedArrayBuffer();
917 }
918 
IsSendableArrayBuffer(const EcmaVM * vm)919 bool JSValueRef::IsSendableArrayBuffer(const EcmaVM *vm)
920 {
921     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
922     return JSNApiHelper::ToJSTaggedValue(this).IsSendableArrayBuffer();
923 }
924 
IsJSLocale(const EcmaVM * vm)925 bool JSValueRef::IsJSLocale(const EcmaVM *vm)
926 {
927     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
928     return JSNApiHelper::ToJSTaggedValue(this).IsJSLocale();
929 }
930 
IsJSDateTimeFormat(const EcmaVM * vm)931 bool JSValueRef::IsJSDateTimeFormat(const EcmaVM *vm)
932 {
933     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
934     return JSNApiHelper::ToJSTaggedValue(this).IsJSDateTimeFormat();
935 }
936 
IsJSRelativeTimeFormat(const EcmaVM * vm)937 bool JSValueRef::IsJSRelativeTimeFormat(const EcmaVM *vm)
938 {
939     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
940     return JSNApiHelper::ToJSTaggedValue(this).IsJSRelativeTimeFormat();
941 }
942 
IsJSIntl(const EcmaVM * vm)943 bool JSValueRef::IsJSIntl(const EcmaVM *vm)
944 {
945     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
946     return JSNApiHelper::ToJSTaggedValue(this).IsJSIntl();
947 }
948 
IsJSNumberFormat(const EcmaVM * vm)949 bool JSValueRef::IsJSNumberFormat(const EcmaVM *vm)
950 {
951     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
952     return JSNApiHelper::ToJSTaggedValue(this).IsJSNumberFormat();
953 }
954 
IsJSCollator(const EcmaVM * vm)955 bool JSValueRef::IsJSCollator(const EcmaVM *vm)
956 {
957     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
958     return JSNApiHelper::ToJSTaggedValue(this).IsJSCollator();
959 }
960 
IsJSPluralRules(const EcmaVM * vm)961 bool JSValueRef::IsJSPluralRules(const EcmaVM *vm)
962 {
963     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
964     return JSNApiHelper::ToJSTaggedValue(this).IsJSPluralRules();
965 }
966 
IsJSListFormat(const EcmaVM * vm)967 bool JSValueRef::IsJSListFormat(const EcmaVM *vm)
968 {
969     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
970     return JSNApiHelper::ToJSTaggedValue(this).IsJSListFormat();
971 }
972 
IsAsyncGeneratorObject(const EcmaVM * vm)973 bool JSValueRef::IsAsyncGeneratorObject(const EcmaVM *vm)
974 {
975     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
976     return JSNApiHelper::ToJSTaggedValue(this).IsAsyncGeneratorObject();
977 }
978 
IsAsyncFunction(const EcmaVM * vm)979 bool JSValueRef::IsAsyncFunction(const EcmaVM *vm)
980 {
981     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
982     return JSNApiHelper::ToJSTaggedValue(this).IsJSAsyncFunction();
983 }
984 
IsConcurrentFunction(const EcmaVM * vm)985 bool JSValueRef::IsConcurrentFunction(const EcmaVM *vm)
986 {
987     JSThread *thread = vm->GetJSThread();
988     ecmascript::ThreadManagedScope managedScope(thread);
989     JSHandle<JSTaggedValue> funcVal = JSNApiHelper::ToJSHandle(this);
990     JSHandle<JSFunction> transFunc = JSHandle<JSFunction>::Cast(funcVal);
991     return transFunc->GetFunctionKind(thread) == ecmascript::FunctionKind::CONCURRENT_FUNCTION;
992 }
993 
IsArgumentsObject(const EcmaVM * vm)994 bool JSValueRef::IsArgumentsObject(const EcmaVM *vm)
995 {
996     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
997     return JSNApiHelper::ToJSTaggedValue(this).IsArguments();
998 }
999 
IsGeneratorFunction(const EcmaVM * vm)1000 bool JSValueRef::IsGeneratorFunction(const EcmaVM *vm)
1001 {
1002     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1003     return JSNApiHelper::ToJSTaggedValue(this).IsGeneratorFunction();
1004 }
1005 
IsAsyncGeneratorFunction(const EcmaVM * vm)1006 bool JSValueRef::IsAsyncGeneratorFunction(const EcmaVM *vm)
1007 {
1008     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1009     return JSNApiHelper::ToJSTaggedValue(this).IsAsyncGeneratorFunction();
1010 }
1011 
IsArrayList(const EcmaVM * vm)1012 bool JSValueRef::IsArrayList(const EcmaVM *vm)
1013 {
1014     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1015     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIArrayList();
1016 }
1017 
IsDeque(const EcmaVM * vm)1018 bool JSValueRef::IsDeque(const EcmaVM *vm)
1019 {
1020     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1021     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIDeque();
1022 }
1023 
IsHashMap(const EcmaVM * vm)1024 bool JSValueRef::IsHashMap(const EcmaVM *vm)
1025 {
1026     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1027     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIHashMap();
1028 }
1029 
IsHashSet(const EcmaVM * vm)1030 bool JSValueRef::IsHashSet(const EcmaVM *vm)
1031 {
1032     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1033     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIHashSet();
1034 }
1035 
IsLightWeightMap(const EcmaVM * vm)1036 bool JSValueRef::IsLightWeightMap(const EcmaVM *vm)
1037 {
1038     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1039     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILightWeightMap();
1040 }
1041 
IsLightWeightSet(const EcmaVM * vm)1042 bool JSValueRef::IsLightWeightSet(const EcmaVM *vm)
1043 {
1044     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1045     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILightWeightSet();
1046 }
1047 
IsLinkedList(const EcmaVM * vm)1048 bool JSValueRef::IsLinkedList(const EcmaVM *vm)
1049 {
1050     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1051     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILinkedList();
1052 }
1053 
IsLinkedListIterator(const EcmaVM * vm)1054 bool JSValueRef::IsLinkedListIterator(const EcmaVM *vm)
1055 {
1056     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1057     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILinkedListIterator();
1058 }
1059 
IsList(const EcmaVM * vm)1060 bool JSValueRef::IsList(const EcmaVM *vm)
1061 {
1062     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1063     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIList();
1064 }
1065 
IsPlainArray(const EcmaVM * vm)1066 bool JSValueRef::IsPlainArray(const EcmaVM *vm)
1067 {
1068     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1069     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIPlainArray();
1070 }
1071 
IsQueue(const EcmaVM * vm)1072 bool JSValueRef::IsQueue(const EcmaVM *vm)
1073 {
1074     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1075     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIQueue();
1076 }
1077 
IsStack(const EcmaVM * vm)1078 bool JSValueRef::IsStack(const EcmaVM *vm)
1079 {
1080     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1081     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIStack();
1082 }
1083 
IsTreeMap(const EcmaVM * vm)1084 bool JSValueRef::IsTreeMap(const EcmaVM *vm)
1085 {
1086     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1087     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPITreeMap();
1088 }
1089 
IsTreeSet(const EcmaVM * vm)1090 bool JSValueRef::IsTreeSet(const EcmaVM *vm)
1091 {
1092     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1093     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPITreeSet();
1094 }
1095 
IsVector(const EcmaVM * vm)1096 bool JSValueRef::IsVector(const EcmaVM *vm)
1097 {
1098     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1099     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIVector();
1100 }
1101 
IsBitVector(const EcmaVM * vm)1102 bool JSValueRef::IsBitVector(const EcmaVM *vm)
1103 {
1104     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1105     return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIBitVector();
1106 }
1107 
IsSendableObject(const EcmaVM * vm)1108 bool JSValueRef::IsSendableObject(const EcmaVM *vm)
1109 {
1110     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1111     return IsJSShared(vm) && IsObject(vm);
1112 }
1113 
IsJSShared(const EcmaVM * vm)1114 bool JSValueRef::IsJSShared(const EcmaVM *vm)
1115 {
1116     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1117     return JSNApiHelper::ToJSTaggedValue(this).IsJSShared();
1118 }
1119 
IsSharedArray(const EcmaVM * vm)1120 bool JSValueRef::IsSharedArray(const EcmaVM *vm)
1121 {
1122     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1123     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedArray();
1124 }
1125 
IsSharedTypedArray(const EcmaVM * vm)1126 bool JSValueRef::IsSharedTypedArray(const EcmaVM *vm)
1127 {
1128     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1129     return JSNApiHelper::ToJSTaggedValue(this).IsSharedTypedArray();
1130 }
1131 
IsSharedSet(const EcmaVM * vm)1132 bool JSValueRef::IsSharedSet(const EcmaVM *vm)
1133 {
1134     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1135     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedSet();
1136 }
1137 
IsSharedMap(const EcmaVM * vm)1138 bool JSValueRef::IsSharedMap(const EcmaVM *vm)
1139 {
1140     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1141     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMap();
1142 }
1143 
IsSharedMapIterator(const EcmaVM * vm)1144 bool JSValueRef::IsSharedMapIterator(const EcmaVM *vm)
1145 {
1146     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1147     return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMapIterator();
1148 }
1149 
IsHeapObject()1150 bool JSValueRef::IsHeapObject()
1151 {
1152     return JSNApiHelper::ToJSTaggedValue(this).IsHeapObject();
1153 }
1154 
GetNativePointerValue(const EcmaVM * vm,bool & isNativePointer)1155 void *JSValueRef::GetNativePointerValue(const EcmaVM* vm, bool &isNativePointer)
1156 {
1157     return GetNativePointerValueImpl(vm, isNativePointer);
1158 }
1159 
1160 // private
GetNativePointerValueImpl(const EcmaVM * vm,bool & isNativePointer)1161 void *JSValueRef::GetNativePointerValueImpl(const EcmaVM* vm, bool &isNativePointer)
1162 {
1163     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1164     if (!JSNApiHelper::ToJSTaggedValue(this).IsJSNativePointer()) {
1165         isNativePointer = false;
1166         return nullptr;
1167     }
1168     isNativePointer = true;
1169     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1170     JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this);
1171     return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer();
1172 }
1173 
IsDetachedArraybuffer(const EcmaVM * vm,bool & isArrayBuffer)1174 bool JSValueRef::IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer)
1175 {
1176     JSThread *thread = vm->GetJSThread();
1177     ecmascript::ThreadManagedScope managedScope(thread);
1178     // arraybuffer is not shared. Do not need to switch state
1179     if (!IsArrayBuffer(vm)) {
1180         isArrayBuffer = false;
1181         return false;
1182     }
1183     isArrayBuffer = true;
1184     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1185     return arrayBuffer->IsDetach(thread);
1186 }
1187 
DetachedArraybuffer(const EcmaVM * vm,bool & isArrayBuffer)1188 void JSValueRef::DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer)
1189 {
1190     auto thread = vm->GetJSThread();
1191     ecmascript::ThreadManagedScope managedScope(thread);
1192     if (IsArrayBuffer(vm)) {
1193         JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1194         if (arrayBuffer->IsDetach(thread)) {
1195             return;
1196         }
1197         arrayBuffer->Detach(thread);
1198         isArrayBuffer = true;
1199     } else if (IsSendableArrayBuffer(vm)) {
1200         JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1201         if (arrayBuffer->IsDetach(thread)) {
1202             return;
1203         }
1204         arrayBuffer->Detach(thread);
1205         isArrayBuffer = true;
1206     } else {
1207         isArrayBuffer = false;
1208     }
1209 }
1210 
GetDataViewInfo(const EcmaVM * vm,bool & isDataView,size_t * byteLength,void ** data,JSValueRef ** arrayBuffer,size_t * byteOffset)1211 void JSValueRef::GetDataViewInfo(const EcmaVM *vm,
1212                                  bool &isDataView,
1213                                  size_t *byteLength,
1214                                  void **data,
1215                                  JSValueRef **arrayBuffer,
1216                                  size_t *byteOffset)
1217 {
1218     auto thread = vm->GetJSThread();
1219     ecmascript::ThreadManagedScope managedScope(thread);
1220     if (!IsDataView(vm)) {
1221         isDataView = false;
1222         return;
1223     }
1224     isDataView = true;
1225     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1226 
1227     if (byteLength) {
1228         *byteLength = dataView->GetByteLength();
1229     }
1230     if (data || arrayBuffer) {
1231         JSHandle<JSArrayBuffer> retArrayBuffer(thread, dataView->GetViewedArrayBuffer(thread));
1232         if (data) {
1233             JSTaggedValue bufferData = retArrayBuffer->GetArrayBufferData(thread);
1234             if (!bufferData.IsJSNativePointer()) {
1235                 *data = nullptr;
1236             }
1237             *data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
1238         }
1239         if (arrayBuffer) {
1240             *arrayBuffer = reinterpret_cast<JSValueRef*>(retArrayBuffer.GetAddress());
1241         }
1242     }
1243     if (byteOffset) {
1244         *byteOffset = dataView->GetByteOffset();
1245     }
1246 }
1247 
1248 // TryGetArrayLength is only for use by the Napi
TryGetArrayLength(const EcmaVM * vm,bool * isPendingException,bool * isArrayOrSharedArray,uint32_t * arrayLength)1249 void JSValueRef::TryGetArrayLength(const EcmaVM *vm, bool *isPendingException,
1250     bool *isArrayOrSharedArray, uint32_t *arrayLength)
1251 {
1252     JSThread *thread = vm->GetJSThread();
1253     *isPendingException = thread->HasPendingException();
1254     ecmascript::ThreadManagedScope managedScope(thread);
1255     JSTaggedValue thisValue = JSNApiHelper::ToJSTaggedValue(this);
1256     if (LIKELY(thisValue.IsJSArray())) {
1257         *isArrayOrSharedArray = true;
1258         *arrayLength = (*isPendingException) ?
1259             0 : JSArray::Cast(thisValue.GetTaggedObject())->GetArrayLength();
1260     } else if (thisValue.IsJSSharedArray()) {
1261         *isArrayOrSharedArray = true;
1262         *arrayLength = (*isPendingException) ?
1263             0 : ecmascript::JSSharedArray::Cast(thisValue.GetTaggedObject())->GetArrayLength();
1264     } else {
1265         *isArrayOrSharedArray = false;
1266     }
1267 }
1268 
IsJsGlobalEnv(const EcmaVM * vm)1269 bool JSValueRef::IsJsGlobalEnv(const EcmaVM *vm)
1270 {
1271     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1272     return JSNApiHelper::ToJSTaggedValue(this).IsJSGlobalEnv();
1273 }
1274 
1275 // ---------------------------------- DataView -----------------------------------
New(const EcmaVM * vm,Local<ArrayBufferRef> arrayBuffer,uint32_t byteOffset,uint32_t byteLength)1276 Local<DataViewRef> DataViewRef::New(
1277     const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, uint32_t byteLength)
1278 {
1279     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1280     ecmascript::ThreadManagedScope managedScope(thread);
1281     ObjectFactory *factory = vm->GetFactory();
1282 
1283     JSHandle<JSArrayBuffer> buffer(JSNApiHelper::ToJSHandle(arrayBuffer));
1284     JSHandle<JSDataView> dataView = factory->NewJSDataView(buffer, byteOffset, byteLength);
1285     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1286     return JSNApiHelper::ToLocal<DataViewRef>(JSHandle<JSTaggedValue>(dataView));
1287 }
1288 
NewWithoutSwitchState(const EcmaVM * vm,Local<ArrayBufferRef> arrayBuffer,uint32_t byteOffset,uint32_t byteLength)1289 Local<DataViewRef> DataViewRef::NewWithoutSwitchState(
1290     const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, uint32_t byteLength)
1291 {
1292     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1293     JSHandle<JSArrayBuffer> buffer(JSNApiHelper::ToJSHandle(arrayBuffer));
1294     LOG_IF_SPECIAL(buffer, FATAL);
1295     if (byteOffset + byteLength > buffer->GetArrayBufferByteLength()) {
1296         return JSValueRef::Hole(vm);
1297     }
1298     ObjectFactory *factory = vm->GetFactory();
1299     JSHandle<JSDataView> dataView = factory->NewJSDataView(buffer, byteOffset, byteLength);
1300     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1301     return JSNApiHelper::ToLocal<DataViewRef>(JSHandle<JSTaggedValue>(dataView));
1302 }
1303 
ByteLength()1304 uint32_t DataViewRef::ByteLength()
1305 {
1306     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1307     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1308     return dataView->GetByteLength();
1309 }
1310 
ByteOffset()1311 uint32_t DataViewRef::ByteOffset()
1312 {
1313     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1314     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1315     return dataView->GetByteOffset();
1316 }
1317 
GetArrayBuffer(const EcmaVM * vm)1318 Local<ArrayBufferRef> DataViewRef::GetArrayBuffer(const EcmaVM *vm)
1319 {
1320     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1321     ecmascript::ThreadManagedScope managedScope(thread);
1322     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1323     LOG_IF_SPECIAL(dataView, FATAL);
1324     JSHandle<JSTaggedValue> arrayBuffer(thread, dataView->GetViewedArrayBuffer(thread));
1325     return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
1326 }
1327 // ---------------------------------- DataView -----------------------------------
1328 
1329 // ----------------------------------- PritimitiveRef ---------------------------------------
GetValue(const EcmaVM * vm)1330 Local<JSValueRef> PrimitiveRef::GetValue(const EcmaVM *vm)
1331 {
1332     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1333     ecmascript::ThreadManagedScope managedScope(thread);
1334     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1335     LOG_IF_SPECIAL(obj, ERROR);
1336     if (obj->IsJSPrimitiveRef()) {
1337         JSTaggedValue primitiveValue = JSPrimitiveRef::Cast(obj->GetTaggedObject())->GetValue(thread);
1338         JSHandle<JSTaggedValue> value(thread, primitiveValue);
1339         return JSNApiHelper::ToLocal<JSValueRef>(value);
1340     }
1341     return Local<JSValueRef>();
1342 }
1343 
1344 // ----------------------------------- NumberRef ---------------------------------------
New(const EcmaVM * vm,double input)1345 Local<NumberRef> NumberRef::New(const EcmaVM *vm, double input)
1346 {
1347     // Omit exception check because ark calls here may not
1348     // cause side effect even pending exception exists.
1349     CROSS_THREAD_CHECK(vm);
1350     if (std::isnan(input)) {
1351         input = ecmascript::base::NAN_VALUE;
1352     }
1353     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1354     return JSNApiHelper::ToLocal<NumberRef>(number);
1355 }
1356 
New(const EcmaVM * vm,int32_t input)1357 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int32_t input)
1358 {
1359     // Omit exception check because ark calls here may not
1360     // cause side effect even pending exception exists.
1361     CROSS_THREAD_CHECK(vm);
1362     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1363     return JSNApiHelper::ToLocal<NumberRef>(number);
1364 }
1365 
New(const EcmaVM * vm,uint32_t input)1366 Local<NumberRef> NumberRef::New(const EcmaVM *vm, uint32_t input)
1367 {
1368     // Omit exception check because ark calls here may not
1369     // cause side effect even pending exception exists.
1370     CROSS_THREAD_CHECK(vm);
1371     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1372     return JSNApiHelper::ToLocal<NumberRef>(number);
1373 }
1374 
New(const EcmaVM * vm,int64_t input)1375 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int64_t input)
1376 {
1377     // Omit exception check because ark calls here may not
1378     // cause side effect even pending exception exists.
1379     CROSS_THREAD_CHECK(vm);
1380     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1381     return JSNApiHelper::ToLocal<NumberRef>(number);
1382 }
1383 
Value()1384 double NumberRef::Value()
1385 {
1386     // Omit exception check because ark calls here may not
1387     // cause side effect even pending exception exists.
1388     return JSTaggedNumber(JSNApiHelper::ToJSTaggedValue(this)).GetNumber();
1389 }
1390 
1391 // ----------------------------------- MapRef ---------------------------------------
Get(const EcmaVM * vm,Local<JSValueRef> key)1392 Local<JSValueRef> MapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1393 {
1394     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1395     ecmascript::ThreadManagedScope managedScope(thread);
1396     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1397     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1398                 map->Get(thread, JSNApiHelper::ToJSTaggedValue(*key))));
1399 }
1400 
Get(const EcmaVM * vm,const char * utf8)1401 Local<JSValueRef> MapRef::Get(const EcmaVM *vm, const char *utf8)
1402 {
1403     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1404     ecmascript::ThreadManagedScope managedScope(thread);
1405     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1406     ObjectFactory *factory = vm->GetFactory();
1407     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1408     auto result = JSHandle<JSTaggedValue>(thread, map->Get(thread, key.GetTaggedValue()));
1409     return JSNApiHelper::ToLocal<JSValueRef>(result);
1410 }
1411 
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1412 void MapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1413 {
1414     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1415     ecmascript::ThreadManagedScope managedScope(thread);
1416     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1417     JSMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
1418 }
1419 
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)1420 void MapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
1421 {
1422     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1423     ecmascript::ThreadManagedScope managedScope(thread);
1424     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1425     ObjectFactory *factory = vm->GetFactory();
1426     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1427     JSMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
1428 }
1429 
Has(const EcmaVM * vm,Local<JSValueRef> key)1430 bool MapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
1431 {
1432     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1433     ecmascript::ThreadManagedScope managedScope(thread);
1434     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1435     bool result = map->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
1436     return result;
1437 }
1438 
Has(const EcmaVM * vm,const char * utf8)1439 bool MapRef::Has(const EcmaVM *vm, const char *utf8)
1440 {
1441     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1442     ecmascript::ThreadManagedScope managedScope(thread);
1443     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1444     ObjectFactory *factory = vm->GetFactory();
1445     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1446     bool result = map->Has(thread, key.GetTaggedValue());
1447     return result;
1448 }
1449 
Delete(const EcmaVM * vm,Local<JSValueRef> key)1450 void MapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
1451 {
1452     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1453     ecmascript::ThreadManagedScope managedScope(thread);
1454     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1455     JSMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
1456 }
1457 
Clear(const EcmaVM * vm)1458 void MapRef::Clear(const EcmaVM *vm)
1459 {
1460     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1461     ecmascript::ThreadManagedScope managedScope(thread);
1462     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1463     JSMap::Clear(thread, map);
1464 }
1465 
New(const EcmaVM * vm)1466 Local<MapRef> MapRef::New(const EcmaVM *vm)
1467 {
1468     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1469     ecmascript::ThreadManagedScope managedScope(thread);
1470     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1471     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1472     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction();
1473     JSHandle<JSMap> map =
1474         JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1475     JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
1476     map->SetLinkedMap(thread, hashMap);
1477     JSHandle<JSTaggedValue> mapTag = JSHandle<JSTaggedValue>::Cast(map);
1478     return JSNApiHelper::ToLocal<MapRef>(mapTag);
1479 }
1480 
GetSize(const EcmaVM * vm)1481 int32_t MapRef::GetSize(const EcmaVM *vm)
1482 {
1483     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1484     JSThread *thread = vm->GetJSThread();
1485     ecmascript::ThreadManagedScope managedScope(thread);
1486     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1487     return map->GetSize(thread);
1488 }
1489 
GetTotalElements(const EcmaVM * vm)1490 int32_t MapRef::GetTotalElements(const EcmaVM *vm)
1491 {
1492     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1493     JSThread *thread = vm->GetJSThread();
1494     ecmascript::ThreadManagedScope managedScope(thread);
1495     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1496     return static_cast<int>((map->GetSize(thread))) +
1497            LinkedHashMap::Cast(map->GetLinkedMap(thread).GetTaggedObject())->NumberOfDeletedElements();
1498 }
1499 
GetKey(const EcmaVM * vm,int entry)1500 Local<JSValueRef> MapRef::GetKey(const EcmaVM *vm, int entry)
1501 {
1502     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1503     ecmascript::ThreadManagedScope managedScope(thread);
1504     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1505     LOG_IF_SPECIAL(map, FATAL);
1506     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetKey(thread, entry)));
1507 }
1508 
GetValue(const EcmaVM * vm,int entry)1509 Local<JSValueRef> MapRef::GetValue(const EcmaVM *vm, int entry)
1510 {
1511     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1512     ecmascript::ThreadManagedScope managedScope(thread);
1513     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1514     LOG_IF_SPECIAL(map, FATAL);
1515     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetValue(thread, entry)));
1516 }
1517 
GetEntries(const EcmaVM * vm)1518 Local<MapIteratorRef> MapRef::GetEntries(const EcmaVM *vm)
1519 {
1520     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1521     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1522     ecmascript::ThreadManagedScope managedScope(thread);
1523     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1524     JSHandle<JSTaggedValue> mapIter =
1525         ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
1526     return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1527 }
1528 
GetKeys(const EcmaVM * vm)1529 Local<MapIteratorRef> MapRef::GetKeys(const EcmaVM *vm)
1530 {
1531     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1532     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1533     ecmascript::ThreadManagedScope managedScope(thread);
1534     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1535     JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
1536     return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1537 }
1538 
GetValues(const EcmaVM * vm)1539 Local<MapIteratorRef> MapRef::GetValues(const EcmaVM *vm)
1540 {
1541     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1542     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1543     ecmascript::ThreadManagedScope managedScope(thread);
1544     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1545     JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
1546     return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1547 }
1548 
1549 // SendableMapRef
New(const EcmaVM * vm)1550 Local<SendableMapRef> SendableMapRef::New(const EcmaVM *vm)
1551 {
1552     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1553     ecmascript::ThreadManagedScope managedScope(thread);
1554     ObjectFactory *factory = vm->GetFactory();
1555     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1556     JSHandle<JSTaggedValue> constructor = env->GetSBuiltininMapFunction();
1557     ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap());
1558     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
1559     ASSERT(obj.GetTaggedValue().IsInSharedHeap());
1560     JSHandle<ecmascript::JSSharedMap> sharedMap = JSHandle<ecmascript::JSSharedMap>::Cast(obj);
1561     JSHandle<LinkedHashMap> linkedMap =
1562         LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, ecmascript::MemSpaceKind::SHARED);
1563     sharedMap->SetLinkedMap(thread, linkedMap);
1564     JSHandle<JSTaggedValue> sharedMapTag = JSHandle<JSTaggedValue>::Cast(sharedMap);
1565     return JSNApiHelper::ToLocal<SendableMapRef>(sharedMapTag);
1566 }
1567 
Get(const EcmaVM * vm,Local<JSValueRef> key)1568 Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1569 {
1570     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1571     ecmascript::ThreadManagedScope managedScope(thread);
1572     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1573     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1574         ecmascript::JSSharedMap::Get(thread, map, JSNApiHelper::ToJSTaggedValue(*key))));
1575 }
1576 
Get(const EcmaVM * vm,const char * utf8)1577 Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, const char *utf8)
1578 {
1579     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1580     ecmascript::ThreadManagedScope managedScope(thread);
1581     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1582     ObjectFactory *factory = vm->GetFactory();
1583     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1584     auto result = JSHandle<JSTaggedValue>(thread, ecmascript::JSSharedMap::Get(thread, map, key.GetTaggedValue()));
1585     return JSNApiHelper::ToLocal<JSValueRef>(result);
1586 }
1587 
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1588 void SendableMapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1589 {
1590     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1591     ecmascript::ThreadManagedScope managedScope(thread);
1592     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1593     ecmascript::JSSharedMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
1594 }
1595 
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)1596 void SendableMapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
1597 {
1598     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1599     ecmascript::ThreadManagedScope managedScope(thread);
1600     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1601     ObjectFactory *factory = vm->GetFactory();
1602     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1603     ecmascript::JSSharedMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
1604 }
1605 
Has(const EcmaVM * vm,Local<JSValueRef> key)1606 bool SendableMapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
1607 {
1608     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1609     ecmascript::ThreadManagedScope managedScope(thread);
1610     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1611     bool result = ecmascript::JSSharedMap::Has(thread, map, JSNApiHelper::ToJSTaggedValue(*key));
1612     return result;
1613 }
1614 
Has(const EcmaVM * vm,const char * utf8)1615 bool SendableMapRef::Has(const EcmaVM *vm, const char *utf8)
1616 {
1617     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1618     ecmascript::ThreadManagedScope managedScope(thread);
1619     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1620     ObjectFactory *factory = vm->GetFactory();
1621     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1622     bool result = ecmascript::JSSharedMap::Has(thread, map, key.GetTaggedValue());
1623     return result;
1624 }
1625 
Delete(const EcmaVM * vm,Local<JSValueRef> key)1626 void SendableMapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
1627 {
1628     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1629     ecmascript::ThreadManagedScope managedScope(thread);
1630     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1631     ecmascript::JSSharedMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
1632 }
1633 
Clear(const EcmaVM * vm)1634 void SendableMapRef::Clear(const EcmaVM *vm)
1635 {
1636     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1637     ecmascript::ThreadManagedScope managedScope(thread);
1638     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1639     ecmascript::JSSharedMap::Clear(thread, map);
1640 }
1641 
GetSize(const EcmaVM * vm)1642 uint32_t SendableMapRef::GetSize(const EcmaVM *vm)
1643 {
1644     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1645     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1646     ecmascript::ThreadManagedScope managedScope(thread);
1647     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1648     return ecmascript::JSSharedMap::GetSize(thread, map);
1649 }
1650 
GetTotalElements(const EcmaVM * vm)1651 uint32_t SendableMapRef::GetTotalElements(const EcmaVM *vm)
1652 {
1653     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1654     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1655     ecmascript::ThreadManagedScope managedScope(thread);
1656     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1657     return static_cast<int>(ecmascript::JSSharedMap::GetSize(thread, map)) +
1658            LinkedHashMap::Cast(map->GetLinkedMap(thread).GetTaggedObject())->NumberOfDeletedElements();
1659 }
1660 
GetKey(const EcmaVM * vm,int entry)1661 Local<JSValueRef> SendableMapRef::GetKey(const EcmaVM *vm, int entry)
1662 {
1663     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1664     ecmascript::ThreadManagedScope managedScope(thread);
1665     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1666     LOG_IF_SPECIAL(map, FATAL);
1667     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1668         ecmascript::JSSharedMap::GetKey(thread, map, entry)));
1669 }
1670 
GetValue(const EcmaVM * vm,int entry)1671 Local<JSValueRef> SendableMapRef::GetValue(const EcmaVM *vm, int entry)
1672 {
1673     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1674     ecmascript::ThreadManagedScope managedScope(thread);
1675     JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1676     LOG_IF_SPECIAL(map, FATAL);
1677     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1678         ecmascript::JSSharedMap::GetValue(thread, map, entry)));
1679 }
1680 
GetEntries(const EcmaVM * vm)1681 Local<SendableMapIteratorRef> SendableMapRef::GetEntries(const EcmaVM *vm)
1682 {
1683     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1684     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1685     ecmascript::ThreadManagedScope managedScope(thread);
1686     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1687     JSHandle<JSTaggedValue> sharedMapIter =
1688         ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
1689     return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1690 }
1691 
GetKeys(const EcmaVM * vm)1692 Local<SendableMapIteratorRef> SendableMapRef::GetKeys(const EcmaVM *vm)
1693 {
1694     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1695     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1696     ecmascript::ThreadManagedScope managedScope(thread);
1697     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1698     JSHandle<JSTaggedValue> sharedMapIter =
1699         ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
1700     return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1701 }
1702 
GetValues(const EcmaVM * vm)1703 Local<SendableMapIteratorRef> SendableMapRef::GetValues(const EcmaVM *vm)
1704 {
1705     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1706     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1707     ecmascript::ThreadManagedScope managedScope(thread);
1708     JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1709     JSHandle<JSTaggedValue> sharedMapIter =
1710         ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
1711     return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1712 }
1713 
1714 // SendableSetRef
New(const EcmaVM * vm)1715 Local<SendableSetRef> SendableSetRef::New(const EcmaVM *vm)
1716 {
1717     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1718     ecmascript::ThreadManagedScope managedScope(thread);
1719     ObjectFactory *factory = vm->GetFactory();
1720     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1721     JSHandle<JSTaggedValue> constructor = env->GetSBuiltininSetFunction();
1722     ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap());
1723     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
1724     ASSERT(obj.GetTaggedValue().IsInSharedHeap());
1725     JSHandle<ecmascript::JSSharedSet> set = JSHandle<ecmascript::JSSharedSet>::Cast(obj);
1726     JSHandle<LinkedHashSet> linkedSet =
1727         LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, ecmascript::MemSpaceKind::SHARED);
1728     set->SetLinkedSet(thread, linkedSet);
1729     JSHandle<JSTaggedValue> sharedSetTag = JSHandle<JSTaggedValue>::Cast(set);
1730     return JSNApiHelper::ToLocal<SendableSetRef>(sharedSetTag);
1731 }
1732 
GetSize(const EcmaVM * vm)1733 uint32_t SendableSetRef::GetSize(const EcmaVM *vm)
1734 {
1735     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1736     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1737     ecmascript::ThreadManagedScope managedScope(thread);
1738     JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1739     return ecmascript::JSSharedSet::GetSize(thread, set);
1740 }
1741 
GetTotalElements(const EcmaVM * vm)1742 uint32_t SendableSetRef::GetTotalElements(const EcmaVM *vm)
1743 {
1744     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1745     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1746     ecmascript::ThreadManagedScope managedScope(thread);
1747     JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1748     return static_cast<int>(ecmascript::JSSharedSet::GetSize(thread, set)) +
1749            LinkedHashSet::Cast(set->GetLinkedSet(thread).GetTaggedObject())->NumberOfDeletedElements();
1750 }
1751 
GetValue(const EcmaVM * vm,int entry)1752 Local<JSValueRef> SendableSetRef::GetValue(const EcmaVM *vm, int entry)
1753 {
1754     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1755     ecmascript::ThreadManagedScope managedScope(thread);
1756     JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1757     LOG_IF_SPECIAL(set, FATAL);
1758     return JSNApiHelper::ToLocal<JSValueRef>(
1759         JSHandle<JSTaggedValue>(thread, ecmascript::JSSharedSet::GetValue(thread, set, entry)));
1760 }
1761 
Add(const EcmaVM * vm,Local<JSValueRef> value)1762 void SendableSetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
1763 {
1764     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1765     ecmascript::ThreadManagedScope managedScope(thread);
1766     JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1767     LOG_IF_SPECIAL(set, FATAL);
1768     ecmascript::JSSharedSet::Add(thread, set, JSNApiHelper::ToJSHandle(value));
1769 }
1770 
1771 // ----------------------------------- MapIteratorRef ---------------------------------------
GetIndex()1772 int32_t MapIteratorRef::GetIndex()
1773 {
1774     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, -1);
1775     JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1776     return jsMapIter->GetNextIndex();
1777 }
1778 
GetKind(const EcmaVM * vm)1779 Local<JSValueRef> MapIteratorRef::GetKind(const EcmaVM *vm)
1780 {
1781     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1782     ecmascript::ThreadManagedScope managedScope(thread);
1783     JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1784     LOG_IF_SPECIAL(jsMapIter, FATAL);
1785     IterationKind iterKind = jsMapIter->GetIterationKind();
1786     Local<JSValueRef> result;
1787     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1788     switch (iterKind) {
1789         case IterationKind::KEY:
1790             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledKeysString());
1791             break;
1792         case IterationKind::VALUE:
1793             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledValuesString());
1794             break;
1795         case IterationKind::KEY_AND_VALUE:
1796             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledEntriesString());
1797             break;
1798         default:
1799             break;
1800     }
1801     return result;
1802 }
1803 
New(const EcmaVM * vm,Local<MapRef> map)1804 Local<MapIteratorRef> MapIteratorRef::New(const EcmaVM *vm, Local<MapRef> map)
1805 {
1806     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1807     ecmascript::ThreadManagedScope managedScope(thread);
1808     JSHandle<JSMap> jsMap(JSNApiHelper::ToJSHandle(map));
1809     IterationKind iterKind = IterationKind::KEY_AND_VALUE;
1810     JSHandle<JSTaggedValue> mapIteratorKeyAndValue =
1811         JSMapIterator::CreateMapIterator(vm->GetJSThread(), JSHandle<JSTaggedValue>::Cast(jsMap), iterKind);
1812     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1813     return JSNApiHelper::ToLocal<JSValueRef>(mapIteratorKeyAndValue);
1814 }
1815 
GetEcmaRuntimeCallInfo(const EcmaVM * vm)1816 ecmascript::EcmaRuntimeCallInfo *MapIteratorRef::GetEcmaRuntimeCallInfo(const EcmaVM *vm)
1817 {
1818     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1819     ecmascript::ThreadManagedScope managedScope(thread);
1820     JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1821     JSHandle<LinkedHashMap> linkedHashMap(thread, jsMapIter->GetIteratedMap(thread));
1822     uint32_t size = linkedHashMap->GetLength();
1823     return ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread,
1824         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1825         JSHandle<JSTaggedValue>(thread, jsMapIter.GetTaggedValue()),
1826         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), size);
1827 }
1828 
Next(const EcmaVM * vm,ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)1829 Local<ArrayRef> MapIteratorRef::Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
1830 {
1831     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1832     ecmascript::ThreadManagedScope managedScope(thread);
1833     JSHandle<JSTaggedValue> nextTagValResult(thread, JSMapIterator::Next(ecmaRuntimeCallInfo));
1834     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1835     JSHandle<JSTaggedValue> iteratorVal(thread,
1836         JSIterator::IteratorValue(thread, nextTagValResult).GetTaggedValue());
1837     return JSNApiHelper::ToLocal<ArrayRef>(iteratorVal);
1838 }
1839 
Next(const EcmaVM * vm)1840 Local<JSValueRef> MapIteratorRef::Next(const EcmaVM *vm)
1841 {
1842     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1843     ecmascript::ThreadManagedScope managedScope(thread);
1844     JSHandle<JSTaggedValue> mapIter(JSNApiHelper::ToJSHandle(this));
1845     auto result = JSMapIterator::NextInternal(thread, mapIter);
1846     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
1847 }
1848 
1849 // SendableMapIteratorRef
Next(const EcmaVM * vm)1850 Local<JSValueRef> SendableMapIteratorRef::Next(const EcmaVM *vm)
1851 {
1852     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1853     ecmascript::ThreadManagedScope managedScope(thread);
1854     JSHandle<JSTaggedValue> sharedMapIter(JSNApiHelper::ToJSHandle(this));
1855     auto result = ecmascript::JSSharedMapIterator::NextInternal(thread, sharedMapIter);
1856     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
1857 }
1858 
1859 // ----------------------------------- SetIteratorRef ---------------------------------------
GetIndex()1860 int32_t SetIteratorRef::GetIndex()
1861 {
1862     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, -1);
1863     JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1864     return jsSetIter->GetNextIndex();
1865 }
1866 
GetKind(const EcmaVM * vm)1867 Local<JSValueRef> SetIteratorRef::GetKind(const EcmaVM *vm)
1868 {
1869     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1870     ecmascript::ThreadManagedScope managedScope(thread);
1871     JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1872     LOG_IF_SPECIAL(jsSetIter, FATAL);
1873     IterationKind iterKind = jsSetIter->GetIterationKind();
1874     Local<JSValueRef> result;
1875     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1876     switch (iterKind) {
1877         case IterationKind::KEY:
1878             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledKeysString());
1879             break;
1880         case IterationKind::VALUE:
1881             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledValuesString());
1882             break;
1883         case IterationKind::KEY_AND_VALUE:
1884             result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledEntriesString());
1885             break;
1886         default:
1887             break;
1888     }
1889     return result;
1890 }
1891 
New(const EcmaVM * vm,Local<SetRef> set)1892 Local<SetIteratorRef> SetIteratorRef::New(const EcmaVM *vm, Local<SetRef> set)
1893 {
1894     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1895     ecmascript::ThreadManagedScope managedScope(thread);
1896     JSHandle<JSSet> jsSet(JSNApiHelper::ToJSHandle(set));
1897     IterationKind iterKind = IterationKind::KEY_AND_VALUE;
1898     JSHandle<JSTaggedValue> setIteratorKeyAndValue =
1899         JSSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>::Cast(jsSet), iterKind);
1900     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1901     return JSNApiHelper::ToLocal<JSValueRef>(setIteratorKeyAndValue);
1902 }
1903 
GetEcmaRuntimeCallInfo(const EcmaVM * vm)1904 ecmascript::EcmaRuntimeCallInfo *SetIteratorRef::GetEcmaRuntimeCallInfo(const EcmaVM *vm)
1905 {
1906     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1907     ecmascript::ThreadManagedScope managedScope(thread);
1908     JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1909     JSHandle<LinkedHashSet> linkedHashSet(thread, jsSetIter->GetIteratedSet(thread));
1910     uint32_t size = linkedHashSet->GetLength();
1911     return ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread,
1912         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1913         JSHandle<JSTaggedValue>(thread, jsSetIter.GetTaggedValue()),
1914         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), size);
1915 }
1916 
Next(const EcmaVM * vm,ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)1917 Local<ArrayRef> SetIteratorRef::Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
1918 {
1919     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1920     ecmascript::ThreadManagedScope managedScope(thread);
1921     JSHandle<JSTaggedValue> nextTagValResult(thread, JSSetIterator::Next(ecmaRuntimeCallInfo));
1922     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1923     JSHandle<JSTaggedValue> iteratorVal(thread,
1924         JSIterator::IteratorValue(thread, nextTagValResult).GetTaggedValue());
1925     return JSNApiHelper::ToLocal<ArrayRef>(iteratorVal);
1926 }
1927 
1928 // ---------------------------------- Buffer -----------------------------------
New(const EcmaVM * vm,const Local<JSValueRef> & context,int32_t length)1929 Local<BufferRef> BufferRef::New(const EcmaVM *vm, const Local<JSValueRef> &context, int32_t length)
1930 {
1931     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1932     ecmascript::ThreadManagedScope managedScope(thread);
1933     ObjectFactory *factory = vm->GetFactory();
1934     JSHandle<JSArrayBuffer> arrayBuffer = JSHandle<JSArrayBuffer>::Cast(factory->NewJSArrayBuffer(length));
1935     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1936     JSHandle<JSFunction> current =
1937         factory->NewJSFunction(env, reinterpret_cast<void *>(BufferRef::BufferToStringCallback));
1938     Local<StringRef> key = StringRef::NewFromUtf8(vm, "toString");
1939     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1940     JSHandle<JSTaggedValue> currentTaggedValue(current);
1941     JSHandle<JSTaggedValue> obj(arrayBuffer);
1942     bool result = JSTaggedValue::SetProperty(thread, obj, keyValue, currentTaggedValue);
1943     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1944     if (!result) {
1945         LOG_ECMA(ERROR) << "SetProperty failed ! ! !";
1946     }
1947     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
1948     return JSNApiHelper::ToLocal<BufferRef>(obj);
1949 }
1950 
New(const EcmaVM * vm,int32_t length)1951 Local<BufferRef> BufferRef::New(const EcmaVM *vm, int32_t length)
1952 {
1953     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1954     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
1955     return New(vm, context, length);
1956 }
1957 
New(const EcmaVM * vm,const Local<JSValueRef> & context,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)1958 Local<BufferRef> BufferRef::New(const EcmaVM *vm, const Local<JSValueRef> &context, void *buffer,
1959     int32_t length, const NativePointerCallback &deleter, void *data)
1960 {
1961     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1962     ecmascript::ThreadManagedScope managedScope(thread);
1963     ObjectFactory *factory = vm->GetFactory();
1964     JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
1965 
1966     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1967     JSHandle<JSFunction> current =
1968         factory->NewJSFunction(env, reinterpret_cast<void *>(BufferRef::BufferToStringCallback));
1969     Local<StringRef> key = StringRef::NewFromUtf8(vm, "toString");
1970     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1971     JSHandle<JSTaggedValue> currentTaggedValue(current);
1972     JSHandle<JSTaggedValue> obj(arrayBuffer);
1973     bool result = JSTaggedValue::SetProperty(thread, obj, keyValue, currentTaggedValue);
1974     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1975     if (!result) {
1976         LOG_ECMA(ERROR) << "SetProperty failed ! ! !";
1977     }
1978     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
1979     return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
1980 }
1981 
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)1982 Local<BufferRef> BufferRef::New(
1983     const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
1984 {
1985     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1986     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
1987     return New(vm, context, buffer, length, deleter, data);
1988 }
1989 
ByteLength(const EcmaVM * vm)1990 int32_t BufferRef::ByteLength(const EcmaVM *vm)
1991 {
1992     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1993     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1994     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1995     return arrayBuffer->GetArrayBufferByteLength();
1996 }
1997 
GetBuffer(const EcmaVM * vm)1998 void *BufferRef::GetBuffer(const EcmaVM *vm)
1999 {
2000     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
2001     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2002     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
2003     JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(vm->GetJSThread());
2004     if (!bufferData.IsJSNativePointer()) {
2005         return nullptr;
2006     }
2007     return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
2008 }
2009 
BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)2010 JSTaggedValue BufferRef::BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
2011 {
2012     JSThread *thread = ecmaRuntimeCallInfo->GetThread();
2013     ecmascript::ThreadManagedScope managedScope(thread);
2014     [[maybe_unused]] LocalScope scope(thread->GetEcmaVM());
2015     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2016     JSHandle<JSTaggedValue> arrayBuff = ecmaRuntimeCallInfo->GetThis();
2017     JSHandle<JSArrayBuffer> arrayBuffer(arrayBuff);
2018 
2019     uint32_t length = arrayBuffer->GetArrayBufferByteLength();
2020     JSTaggedValue data = arrayBuffer->GetArrayBufferData(thread);
2021 
2022     ecmascript::CVector<uint16_t> valueTable;
2023     valueTable.reserve(length);
2024     for (uint32_t i = 0; i < length; i++) {
2025         void* rawData = reinterpret_cast<void *>(
2026             ToUintPtr(JSNativePointer::Cast(data.GetTaggedObject())->GetExternalPointer()) + i);
2027         uint8_t *block = reinterpret_cast<uint8_t *>(rawData);
2028         uint16_t nextCv = static_cast<uint16_t>(*block);
2029         valueTable.emplace_back(nextCv);
2030     }
2031 
2032     auto *char16tData0 = reinterpret_cast<const char16_t *>(valueTable.data());
2033     std::u16string u16str(char16tData0, length);
2034 
2035     const char16_t *constChar16tData = u16str.data();
2036     auto *char16tData = const_cast<char16_t *>(constChar16tData);
2037     auto *uint16tData = reinterpret_cast<uint16_t *>(char16tData);
2038     uint32_t u16strSize = u16str.size();
2039     JSTaggedValue rString = factory->NewFromUtf16Literal(uint16tData, u16strSize).GetTaggedValue();
2040     JSHandle<EcmaString> StringHandle = JSTaggedValue::ToString(thread, rString);
2041     RETURN_VALUE_IF_ABRUPT(thread, JSTaggedValue::Undefined());
2042     return StringHandle.GetTaggedValue();
2043 }
2044 
2045 // ---------------------------------- Promise --------------------------------------
New(const EcmaVM * vm)2046 Local<PromiseCapabilityRef> PromiseCapabilityRef::New(const EcmaVM *vm)
2047 {
2048     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2049     ecmascript::ThreadManagedScope managedScope(thread);
2050     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
2051     JSHandle<JSTaggedValue> constructor(globalEnv->GetPromiseFunction());
2052     JSHandle<JSTaggedValue> capability(JSPromise::NewPromiseCapability(thread, constructor));
2053     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2054     return JSNApiHelper::ToLocal<PromiseCapabilityRef>(capability);
2055 }
2056 
GetPromise(const EcmaVM * vm)2057 Local<PromiseRef> PromiseCapabilityRef::GetPromise(const EcmaVM *vm)
2058 {
2059     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2060     ecmascript::ThreadManagedScope managedScope(thread);
2061     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
2062     LOG_IF_SPECIAL(capacity, FATAL);
2063     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, capacity->GetPromise(thread)));
2064 }
2065 
Resolve(const EcmaVM * vm,uintptr_t value)2066 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, uintptr_t value)
2067 {
2068     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2069     ecmascript::ThreadManagedScope managedScope(thread);
2070     const GlobalEnvConstants *constants = thread->GlobalConstants();
2071 
2072     JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(value);
2073 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
2074     thread->CheckJSTaggedType(arg.GetRawData());
2075 #endif
2076     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
2077     LOG_IF_SPECIAL(capacity, FATAL);
2078     JSTaggedValue resolve = capacity->GetResolve(thread);
2079     JSTaggedValue undefined = constants->GetUndefined();
2080     EcmaRuntimeCallInfo *info =
2081         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, undefined, undefined, 1);
2082     RETURN_VALUE_IF_ABRUPT(thread, false);
2083     info->SetCallArg(arg);
2084     JSFunction::Call(info);
2085     RETURN_VALUE_IF_ABRUPT(thread, false);
2086 
2087     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
2088     RETURN_VALUE_IF_ABRUPT(thread, false);
2089     EcmaVM::ClearKeptObjects(thread);
2090     return true;
2091 }
2092 
Resolve(const EcmaVM * vm,Local<JSValueRef> value)2093 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local<JSValueRef> value)
2094 {
2095     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2096     ecmascript::ThreadManagedScope managedScope(thread);
2097     const GlobalEnvConstants *constants = thread->GlobalConstants();
2098 
2099     JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(value);
2100 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
2101     thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
2102 #endif
2103     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
2104     LOG_IF_SPECIAL(capacity, FATAL);
2105     JSHandle<JSTaggedValue> resolve(thread, capacity->GetResolve(thread));
2106     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
2107     EcmaRuntimeCallInfo *info =
2108         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, undefined, undefined, 1);
2109     RETURN_VALUE_IF_ABRUPT(thread, false);
2110     info->SetCallArg(arg.GetTaggedValue());
2111     JSFunction::Call(info);
2112     RETURN_VALUE_IF_ABRUPT(thread, false);
2113 
2114     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
2115     RETURN_VALUE_IF_ABRUPT(thread, false);
2116     EcmaVM::ClearKeptObjects(thread);
2117     return true;
2118 }
2119 
Reject(const EcmaVM * vm,uintptr_t reason)2120 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, uintptr_t reason)
2121 {
2122     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2123     ecmascript::ThreadManagedScope managedScope(thread);
2124     const GlobalEnvConstants *constants = thread->GlobalConstants();
2125 
2126     JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(reason);
2127 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
2128     thread->CheckJSTaggedType(arg.GetRawData());
2129 #endif
2130     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
2131     LOG_IF_SPECIAL(capacity, FATAL);
2132     JSTaggedValue reject = capacity->GetReject(thread);
2133     JSTaggedValue undefined = constants->GetUndefined();
2134 
2135     EcmaRuntimeCallInfo *info =
2136         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, reject, undefined, undefined, 1);
2137     RETURN_VALUE_IF_ABRUPT(thread, false);
2138     info->SetCallArg(arg);
2139     JSFunction::Call(info);
2140     RETURN_VALUE_IF_ABRUPT(thread, false);
2141 
2142     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
2143     RETURN_VALUE_IF_ABRUPT(thread, false);
2144     EcmaVM::ClearKeptObjects(thread);
2145     return true;
2146 }
2147 
Reject(const EcmaVM * vm,Local<JSValueRef> reason)2148 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local<JSValueRef> reason)
2149 {
2150     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2151     ecmascript::ThreadManagedScope managedScope(thread);
2152     const GlobalEnvConstants *constants = thread->GlobalConstants();
2153 
2154     JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(reason);
2155 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
2156     thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
2157 #endif
2158     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
2159     LOG_IF_SPECIAL(capacity, FATAL);
2160     JSHandle<JSTaggedValue> reject(thread, capacity->GetReject(thread));
2161     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
2162 
2163     EcmaRuntimeCallInfo *info =
2164         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, reject, undefined, undefined, 1);
2165     RETURN_VALUE_IF_ABRUPT(thread, false);
2166     info->SetCallArg(arg.GetTaggedValue());
2167     JSFunction::Call(info);
2168     RETURN_VALUE_IF_ABRUPT(thread, false);
2169 
2170     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
2171     RETURN_VALUE_IF_ABRUPT(thread, false);
2172     EcmaVM::ClearKeptObjects(thread);
2173     return true;
2174 }
2175 
2176 // ----------------------------------- SymbolRef -----------------------------------------
New(const EcmaVM * vm,Local<StringRef> description)2177 Local<SymbolRef> SymbolRef::New(const EcmaVM *vm, Local<StringRef> description)
2178 {
2179     // Omit exception check because ark calls here may not
2180     // cause side effect even pending exception exists.
2181     CROSS_THREAD_CHECK(vm);
2182     ecmascript::ThreadManagedScope managedScope(thread);
2183     ObjectFactory *factory = vm->GetFactory();
2184     JSHandle<JSSymbol> symbol = factory->NewJSSymbol();
2185     if (!description.IsEmpty()) {
2186         JSTaggedValue desc = JSNApiHelper::ToJSTaggedValue(*description);
2187         symbol->SetDescription(thread, desc);
2188     }
2189     return JSNApiHelper::ToLocal<SymbolRef>(JSHandle<JSTaggedValue>(symbol));
2190 }
2191 
GetDescription(const EcmaVM * vm)2192 Local<StringRef> SymbolRef::GetDescription(const EcmaVM *vm)
2193 {
2194     CROSS_THREAD_CHECK(vm);
2195     ecmascript::ThreadManagedScope managedScope(thread);
2196     JSTaggedValue description =
2197         JSSymbol::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetDescription(thread);
2198     if (!description.IsString()) {
2199         auto constants = thread->GlobalConstants();
2200         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
2201     }
2202     JSHandle<JSTaggedValue> descriptionHandle(thread, description);
2203     return JSNApiHelper::ToLocal<StringRef>(descriptionHandle);
2204 }
2205 
2206 // ----------------------------------- BooleanRef ---------------------------------------
New(const EcmaVM * vm,bool value)2207 Local<BooleanRef> BooleanRef::New(const EcmaVM *vm, bool value)
2208 {
2209     // Omit exception check because ark calls here may not
2210     // cause side effect even pending exception exists.
2211     CROSS_THREAD_CHECK(vm);
2212     ecmascript::ThreadManagedScope managedScope(thread);
2213     JSHandle<JSTaggedValue> boolean(thread, JSTaggedValue(value));
2214     return JSNApiHelper::ToLocal<BooleanRef>(boolean);
2215 }
2216 
Value()2217 bool BooleanRef::Value()
2218 {
2219     // Omit exception check because ark calls here may not
2220     // cause side effect even pending exception exists.
2221     return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
2222 }
2223 
2224 // ----------------------------------- StringRef ----------------------------------------
NewFromUtf8(const EcmaVM * vm,const char * utf8,int length)2225 Local<StringRef> StringRef::NewFromUtf8(const EcmaVM *vm, const char *utf8, int length)
2226 {
2227     // Omit exception check because ark calls here may not
2228     // cause side effect even pending exception exists.
2229     CROSS_THREAD_CHECK(vm);
2230     ecmascript::ThreadManagedScope managedScope(thread);
2231     ObjectFactory *factory = vm->GetFactory();
2232     if (length < 0) {
2233         JSHandle<JSTaggedValue> current(factory->NewFromUtf8(utf8));
2234         return JSNApiHelper::ToLocal<StringRef>(current);
2235     }
2236     JSHandle<JSTaggedValue> current(factory->NewFromUtf8(reinterpret_cast<const uint8_t *>(utf8), length));
2237     return JSNApiHelper::ToLocal<StringRef>(current);
2238 }
2239 
NewFromUtf8WithoutStringTable(const EcmaVM * vm,const char * utf8,int length)2240 Local<StringRef> StringRef::NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length)
2241 {
2242     // This only supports for napi_create_string_utf8
2243     CROSS_THREAD_CHECK(vm);
2244     ecmascript::ThreadManagedScope managedScope(thread);
2245     ObjectFactory *factory = vm->GetFactory();
2246     if (length < 0) {
2247         JSHandle<JSTaggedValue> current(factory->NewFromUtf8WithoutStringTable(utf8));
2248         return JSNApiHelper::ToLocal<StringRef>(current);
2249     }
2250     JSHandle<JSTaggedValue> current(factory->NewFromUtf8WithoutStringTable(reinterpret_cast<const uint8_t *>(utf8),
2251                                                                            length));
2252     return JSNApiHelper::ToLocal<StringRef>(current);
2253 }
2254 
NewFromUtf16WithoutStringTable(const EcmaVM * vm,const char16_t * utf16,int length)2255 Local<StringRef> StringRef::NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length)
2256 {
2257     // Omit exception check because ark calls here may not
2258     // cause side effect even pending exception exists.
2259     CROSS_THREAD_CHECK(vm);
2260     ecmascript::ThreadManagedScope managedScope(thread);
2261     ObjectFactory *factory = vm->GetFactory();
2262     if (length < 0) {
2263         JSHandle<JSTaggedValue> current(factory->NewFromUtf16WithoutStringTable(utf16));
2264         return JSNApiHelper::ToLocal<StringRef>(current);
2265     }
2266     JSHandle<JSTaggedValue> current(factory->NewFromUtf16WithoutStringTable(reinterpret_cast<const uint16_t *>(utf16),
2267                                                                             length));
2268     return JSNApiHelper::ToLocal<StringRef>(current);
2269 }
2270 
NewFromUtf16(const EcmaVM * vm,const char16_t * utf16,int length)2271 Local<StringRef> StringRef::NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length)
2272 {
2273     // Omit exception check because ark calls here may not
2274     // cause side effect even pending exception exists.
2275     CROSS_THREAD_CHECK(vm);
2276     ecmascript::ThreadManagedScope managedScope(thread);
2277     ObjectFactory *factory = vm->GetFactory();
2278     if (length < 0) {
2279         JSHandle<JSTaggedValue> current(factory->NewFromUtf16(utf16));
2280         return JSNApiHelper::ToLocal<StringRef>(current);
2281     }
2282     JSHandle<JSTaggedValue> current(factory->NewFromUtf16(reinterpret_cast<const uint16_t *>(utf16), length));
2283     return JSNApiHelper::ToLocal<StringRef>(current);
2284 }
2285 
ToString(const EcmaVM * vm)2286 std::string StringRef::ToString(const EcmaVM *vm)
2287 {
2288     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
2289     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2290     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).ToStdString(vm->GetJSThread());
2291 }
2292 
DebuggerToString(const EcmaVM * vm)2293 std::string StringRef::DebuggerToString(const EcmaVM *vm)
2294 {
2295     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
2296     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2297     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).DebuggerToStdString(vm->GetJSThread());
2298 }
2299 
Length(const EcmaVM * vm)2300 uint32_t StringRef::Length(const EcmaVM *vm)
2301 {
2302     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2303     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2304     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).GetLength();
2305 }
2306 
IsCompressed(const panda::EcmaVM * vm)2307 bool StringRef::IsCompressed(const panda::EcmaVM *vm)
2308 {
2309     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
2310     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2311     return !EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).IsUtf16();
2312 }
2313 
Utf8Length(const EcmaVM * vm,bool isGetBufferSize)2314 size_t StringRef::Utf8Length(const EcmaVM *vm, bool isGetBufferSize)
2315 {
2316     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2317     auto thread = vm->GetJSThread();
2318     ecmascript::ThreadManagedScope managedScope(thread);
2319     JSHandle<EcmaString> strHandle(thread, EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this)));
2320     return EcmaStringAccessor(EcmaStringAccessor::Flatten(vm, strHandle)).GetUtf8Length(thread, isGetBufferSize);
2321 }
2322 
WriteUtf8(const EcmaVM * vm,char * buffer,uint32_t length,bool isWriteBuffer)2323 uint32_t StringRef::WriteUtf8(const EcmaVM *vm, char *buffer, uint32_t length, bool isWriteBuffer)
2324 {
2325     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2326     JSThread *thread = vm->GetJSThread();
2327     ecmascript::ThreadManagedScope managedScope(thread);
2328     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2329         .WriteToFlatUtf8(thread, reinterpret_cast<uint8_t *>(buffer), length, isWriteBuffer);
2330 }
2331 
WriteUtf16(const EcmaVM * vm,char16_t * buffer,uint32_t length)2332 uint32_t StringRef::WriteUtf16(const EcmaVM *vm, char16_t *buffer, uint32_t length)
2333 {
2334     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2335     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2336     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2337         .WriteToUtf16(vm->GetJSThread(), reinterpret_cast<uint16_t *>(buffer), length);
2338 }
2339 
WriteLatin1(const EcmaVM * vm,char * buffer,uint32_t length)2340 uint32_t StringRef::WriteLatin1(const EcmaVM *vm, char *buffer, uint32_t length)
2341 {
2342     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2343     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2344     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2345         .WriteToOneByte(vm->GetJSThread(), reinterpret_cast<uint8_t *>(buffer), length);
2346 }
2347 
WriteLatin1WithoutSwitchState(const EcmaVM * vm,char * buffer,uint32_t length)2348 uint32_t StringRef::WriteLatin1WithoutSwitchState(const EcmaVM *vm, char *buffer, uint32_t length)
2349 {
2350     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2351     CROSS_THREAD_CHECK(vm);
2352     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2353         .WriteToOneByte(vm->GetJSThread(), reinterpret_cast<uint8_t *>(buffer), length);
2354 }
2355 
GetNapiWrapperString(const EcmaVM * vm)2356 Local<StringRef> StringRef::GetNapiWrapperString(const EcmaVM *vm)
2357 {
2358     // Omit exception check because ark calls here may not
2359     // cause side effect even pending exception exists.
2360     CROSS_THREAD_CHECK(vm);
2361     JSHandle<JSTaggedValue> napiWrapperString = thread->GlobalConstants()->GetHandledNapiWrapperString();
2362     return JSNApiHelper::ToLocal<StringRef>(napiWrapperString);
2363 }
2364 
EncodeIntoUint8Array(const EcmaVM * vm)2365 Local<TypedArrayRef> StringRef::EncodeIntoUint8Array(const EcmaVM *vm)
2366 {
2367     CROSS_THREAD_CHECK(vm);
2368     ecmascript::ThreadManagedScope managedScope(thread);
2369     JSHandle<JSTaggedValue> string = JSNApiHelper::ToJSHandle(this);
2370     uint32_t length = this->Utf8Length(vm, true);
2371     // 1 because Utf8Length adds 1 for the return value
2372     if (length <= 1) {
2373         return Undefined(vm);
2374     }
2375 
2376     JSHandle<JSObject> obj =
2377         TypedArrayHelper::FastCreateTypedArray(thread, thread->GlobalConstants()->GetHandledUint8ArrayString(),
2378                                                length - 1, DataViewType::UINT8);
2379     if (JSNApi::HasPendingException(vm)) {
2380         LOG_ECMA(ERROR) << "JSNapi EncodeIntoUint8Array: Create TypedArray failed";
2381         return Undefined(vm);
2382     }
2383     JSHandle<JSObject> arrayBuffer(thread, JSTypedArray::Cast(*obj)->GetViewedArrayBufferOrByteArray(thread));
2384     JSTaggedValue bufferData = JSHandle<JSArrayBuffer>::Cast(arrayBuffer)->GetArrayBufferData(thread);
2385     void *buffer = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
2386 
2387     JSHandle<EcmaString> stringHandle = JSHandle<EcmaString>::Cast(string);
2388     EcmaStringAccessor(stringHandle).WriteToFlatUtf8(thread, reinterpret_cast<uint8_t *>(buffer), length - 1, true);
2389     JSHandle<JSTaggedValue> typedArrayTag = JSHandle<JSTaggedValue>::Cast(obj);
2390     return JSNApiHelper::ToLocal<TypedArrayRef>(typedArrayTag);
2391 }
2392 
2393 // ---------------------------------- PromiseRejectInfo ---------------------------------
PromiseRejectInfo(Local<JSValueRef> promise,Local<JSValueRef> reason,PromiseRejectInfo::PROMISE_REJECTION_EVENT operation,void * data)2394 PromiseRejectInfo::PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
2395                                      PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data)
2396     : promise_(promise), reason_(reason), operation_(operation), data_(data) {}
2397 
GetPromise() const2398 Local<JSValueRef> PromiseRejectInfo::GetPromise() const
2399 {
2400     return promise_;
2401 }
2402 
GetReason() const2403 Local<JSValueRef> PromiseRejectInfo::GetReason() const
2404 {
2405     return reason_;
2406 }
2407 
GetOperation() const2408 PromiseRejectInfo::PROMISE_REJECTION_EVENT PromiseRejectInfo::GetOperation() const
2409 {
2410     return operation_;
2411 }
2412 
GetData() const2413 void* PromiseRejectInfo::GetData() const
2414 {
2415     return data_;
2416 }
2417 
2418 // ----------------------------------- BigIntRef ---------------------------------------
New(const EcmaVM * vm,uint64_t input)2419 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, uint64_t input)
2420 {
2421     // Omit exception check because ark calls here may not
2422     // cause side effect even pending exception exists.
2423     CROSS_THREAD_CHECK(vm);
2424     ecmascript::ThreadManagedScope managedScope(thread);
2425     JSHandle<BigInt> big = BigInt::Uint64ToBigInt(thread, input);
2426     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2427     return JSNApiHelper::ToLocal<BigIntRef>(bigint);
2428 }
2429 
New(const EcmaVM * vm,int64_t input)2430 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, int64_t input)
2431 {
2432     // Omit exception check because ark calls here may not
2433     // cause side effect even pending exception exists.
2434     CROSS_THREAD_CHECK(vm);
2435     ecmascript::ThreadManagedScope managedScope(thread);
2436     JSHandle<BigInt> big = BigInt::Int64ToBigInt(thread, input);
2437     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2438     return JSNApiHelper::ToLocal<BigIntRef>(bigint);
2439 }
2440 
CreateBigWords(const EcmaVM * vm,bool sign,uint32_t size,const uint64_t * words)2441 Local<JSValueRef> BigIntRef::CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words)
2442 {
2443     // Omit exception check because ark calls here may not
2444     // cause side effect even pending exception exists.
2445     CROSS_THREAD_CHECK(vm);
2446     ecmascript::ThreadManagedScope managedScope(thread);
2447     JSHandle<BigInt> big = BigInt::CreateBigWords(thread, sign, size, words);
2448     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2449     return JSNApiHelper::ToLocal<JSValueRef>(bigint);
2450 }
2451 
BigIntToInt64(const EcmaVM * vm,int64_t * value,bool * lossless)2452 void BigIntRef::BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless)
2453 {
2454     // Omit exception check because ark calls here may not
2455     // cause side effect even pending exception exists.
2456     CROSS_THREAD_CHECK(vm);
2457     ecmascript::ThreadManagedScope managedScope(thread);
2458     JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
2459     LOG_IF_SPECIAL(bigintVal, ERROR);
2460     BigInt::BigIntToInt64(thread, bigintVal, value, lossless);
2461 }
2462 
BigIntToUint64(const EcmaVM * vm,uint64_t * value,bool * lossless)2463 void BigIntRef::BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless)
2464 {
2465     // Omit exception check because ark calls here may not
2466     // cause side effect even pending exception exists.
2467     CROSS_THREAD_CHECK(vm);
2468     ecmascript::ThreadManagedScope managedScope(thread);
2469     JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
2470     LOG_IF_SPECIAL(bigintVal, ERROR);
2471     BigInt::BigIntToUint64(thread, bigintVal, value, lossless);
2472 }
2473 
GetWordsArray(const EcmaVM * vm,bool * signBit,size_t wordCount,uint64_t * words)2474 void BigIntRef::GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words)
2475 {
2476     DCHECK_SPECIAL_VALUE(this);
2477     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2478     JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
2479     uint32_t len = bigintVal->GetLength();
2480     uint32_t count = 0;
2481     uint32_t index = 0;
2482     ASSERT(wordCount > 0);
2483     for (; index < wordCount - 1; ++index) {
2484         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2485         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
2486     }
2487     if (len % 2 == 0) { // 2 : len is odd or even
2488         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2489         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
2490     } else {
2491         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2492     }
2493     *signBit = bigintVal->GetSign();
2494 }
2495 
GetWordsArraySize(const EcmaVM * vm)2496 uint32_t BigIntRef::GetWordsArraySize(const EcmaVM *vm)
2497 {
2498     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2499     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2500     JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
2501     uint32_t len = bigintVal->GetLength();
2502     return len % 2 != 0 ? len / 2 + 1 : len / 2; // 2 : len is odd or even
2503 }
2504 
2505 // ----------------------------------- HandleScope -------------------------------------
LocalScope(const EcmaVM * vm)2506 LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread())
2507 {
2508     // Only get handle ptr here. Do not need to swtich state.
2509     prevNext_ = vm->GetHandleScopeStorageNext();
2510     prevEnd_ = vm->GetHandleScopeStorageEnd();
2511     prevHandleStorageIndex_ = vm->GetCurrentHandleStorageIndex();
2512 
2513     prevPrimitiveNext_ = vm->GetPrimitiveScopeStorageNext();
2514     prevPrimitiveEnd_ = vm->GetPrimitiveScopeStorageEnd();
2515     prevPrimitiveStorageIndex_ = vm->GetCurrentPrimitiveStorageIndex();
2516 #if defined(ENABLE_LOCAL_HANDLE_LEAK_DETECT)
2517     auto heapProfiler = reinterpret_cast<HeapProfiler *>(
2518         HeapProfilerInterface::GetInstance(const_cast<EcmaVM *>(vm)));
2519     heapProfiler->IncreaseScopeCount();
2520     heapProfiler->PushToActiveScopeStack(this, nullptr);
2521 #endif
2522 }
2523 
LocalScope(const EcmaVM * vm,JSTaggedType value)2524 LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread())
2525 {
2526     ecmascript::ThreadManagedScope managedScope(reinterpret_cast<JSThread *>(thread_));
2527     // Simply reserve a slot on the handlescope. The escaped handle will still be retained in this slot.
2528     ecmascript::EcmaHandleScope::NewHandle(reinterpret_cast<JSThread *>(thread_), value);
2529     prevNext_ = vm->GetHandleScopeStorageNext();
2530     prevEnd_ = vm->GetHandleScopeStorageEnd();
2531     prevHandleStorageIndex_ = vm->GetCurrentHandleStorageIndex();
2532 
2533     prevPrimitiveNext_ = vm->GetPrimitiveScopeStorageNext();
2534     prevPrimitiveEnd_ = vm->GetPrimitiveScopeStorageEnd();
2535     prevPrimitiveStorageIndex_ = vm->GetCurrentPrimitiveStorageIndex();
2536 #if defined(ENABLE_LOCAL_HANDLE_LEAK_DETECT)
2537     auto heapProfiler = reinterpret_cast<HeapProfiler *>(
2538         HeapProfilerInterface::GetInstance(const_cast<EcmaVM *>(vm)));
2539     heapProfiler->IncreaseScopeCount();
2540     heapProfiler->PushToActiveScopeStack(this, nullptr);
2541 #endif
2542 }
2543 
~LocalScope()2544 LocalScope::~LocalScope()
2545 {
2546     ecmascript::ThreadManagedScope managedScope(reinterpret_cast<JSThread *>(thread_));
2547     auto vm = reinterpret_cast<JSThread *>(thread_)->GetEcmaVM();
2548     vm->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_));
2549     vm->SetPrimitiveScopeStorageNext(static_cast<JSTaggedType *>(prevPrimitiveNext_));
2550 
2551     if (vm->GetHandleScopeStorageEnd() != prevEnd_) {
2552         vm->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_));
2553         vm->ShrinkHandleStorage(prevHandleStorageIndex_);
2554     }
2555 
2556     if (vm->GetPrimitiveScopeStorageEnd() != prevPrimitiveEnd_) {
2557         vm->SetPrimitiveScopeStorageEnd(static_cast<JSTaggedType *>(prevPrimitiveEnd_));
2558         vm->ShrinkPrimitiveStorage(prevPrimitiveStorageIndex_);
2559     }
2560 #if defined(ENABLE_LOCAL_HANDLE_LEAK_DETECT)
2561     auto heapProfiler = reinterpret_cast<HeapProfiler *>(HeapProfilerInterface::GetInstance(vm));
2562     heapProfiler->DecreaseScopeCount();
2563     heapProfiler->PopFromActiveScopeStack();
2564 #endif
2565 }
2566 
2567 // ----------------------------------- EscapeLocalScope ------------------------------
EscapeLocalScope(const EcmaVM * vm)2568 EscapeLocalScope::EscapeLocalScope(const EcmaVM *vm) : LocalScope(vm, JSTaggedValue::Undefined().GetRawData())
2569 {
2570     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2571     escapeHandle_ = ToUintPtr(vm->GetHandleScopeStorageNext() - 1);
2572 }
2573 
2574 // ----------------------------------- IntegerRef ---------------------------------------
New(const EcmaVM * vm,int input)2575 Local<IntegerRef> IntegerRef::New(const EcmaVM *vm, int input)
2576 {
2577     // Omit exception check because ark calls here may not
2578     // cause side effect even pending exception exists.
2579     CROSS_THREAD_CHECK(vm);
2580     ecmascript::ThreadManagedScope managedScope(thread);
2581     JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
2582     return JSNApiHelper::ToLocal<IntegerRef>(integer);
2583 }
2584 
NewFromUnsigned(const EcmaVM * vm,unsigned int input)2585 Local<IntegerRef> IntegerRef::NewFromUnsigned(const EcmaVM *vm, unsigned int input)
2586 {
2587     // Omit exception check because ark calls here may not
2588     // cause side effect even pending exception exists.
2589     CROSS_THREAD_CHECK(vm);
2590     ecmascript::ThreadManagedScope managedScope(thread);
2591     JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
2592     return JSNApiHelper::ToLocal<IntegerRef>(integer);
2593 }
2594 
Value()2595 int IntegerRef::Value()
2596 {
2597     // Omit exception check because ark calls here may not
2598     // cause side effect even pending exception exists.
2599     return JSNApiHelper::ToJSTaggedValue(this).GetInt();
2600 }
2601 
2602 // ----------------------------------- ObjectRef ----------------------------------------
New(const EcmaVM * vm)2603 Local<ObjectRef> ObjectRef::New(const EcmaVM *vm)
2604 {
2605     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2606     ecmascript::ThreadManagedScope managedScope(thread);
2607     ObjectFactory *factory = vm->GetFactory();
2608     JSHandle<JSTaggedValue> object(factory->CreateNapiObject());
2609     return JSNApiHelper::ToLocal<ObjectRef>(object);
2610 }
2611 
NewObject(const EcmaVM * vm)2612 uintptr_t ObjectRef::NewObject(const EcmaVM *vm)
2613 {
2614     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm,
2615         (thread->GlobalConstants()->GetHandledUndefined()).GetAddress());
2616     ecmascript::ThreadManagedScope managedScope(thread);
2617     JSHandle<JSTaggedValue> object(vm->GetFactory()->CreateNapiObject());
2618     return object.GetAddress();
2619 }
2620 
NewS(const EcmaVM * vm)2621 Local<ObjectRef> ObjectRef::NewS(const EcmaVM *vm)
2622 {
2623     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2624     ecmascript::ThreadManagedScope managedScope(thread);
2625     ObjectFactory *factory = vm->GetFactory();
2626     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
2627     JSHandle<JSFunction> constructor(globalEnv->GetSObjectFunction());
2628     JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
2629     return JSNApiHelper::ToLocal<ObjectRef>(object);
2630 }
2631 
NewWithProperties(const EcmaVM * vm,size_t propertyCount,const Local<JSValueRef> * keys,const PropertyAttribute * attributes)2632 Local<ObjectRef> ObjectRef::NewWithProperties(const EcmaVM *vm, size_t propertyCount,
2633                                               const Local<JSValueRef> *keys,
2634                                               const PropertyAttribute *attributes)
2635 {
2636     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2637     ecmascript::ThreadManagedScope managedScope(thread);
2638     EscapeLocalScope scope(vm);
2639     JSHandle<JSTaggedValue> obj;
2640     auto CreateObjImpl = [vm, thread, propertyCount, keys, attributes] (uintptr_t head) -> JSHandle<JSTaggedValue> {
2641         const PropertyDescriptor *desc = reinterpret_cast<const PropertyDescriptor *>(head);
2642         for (size_t i = 0; i < propertyCount; ++i) {
2643             const PropertyAttribute &attr = attributes[i];
2644             new (reinterpret_cast<void *>(head)) PropertyDescriptor(thread,
2645                                                                     JSNApiHelper::ToJSHandle(attr.GetValue(vm)),
2646                                                                     attr.IsWritable(), attr.IsEnumerable(),
2647                                                                     attr.IsConfigurable());
2648             head += sizeof(PropertyDescriptor);
2649         }
2650         ObjectFactory *factory = vm->GetFactory();
2651         return factory->CreateJSObjectWithProperties(propertyCount, keys, desc);
2652     };
2653     if (propertyCount <= MAX_PROPERTIES_ON_STACK) {
2654         char desc[sizeof(PropertyDescriptor) * MAX_PROPERTIES_ON_STACK];
2655         obj = CreateObjImpl(reinterpret_cast<uintptr_t>(desc));
2656     } else {
2657         void *desc = malloc(sizeof(PropertyDescriptor) * propertyCount);
2658         obj = CreateObjImpl(reinterpret_cast<uintptr_t>(desc));
2659         free(desc);
2660     }
2661     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2662     return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2663 }
2664 
NewSWithProperties(const EcmaVM * vm,SendablePropertiesInfo & info)2665 Local<ObjectRef> ObjectRef::NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info)
2666 {
2667     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2668     ecmascript::ThreadManagedScope managedScope(thread);
2669     EscapeLocalScope scope(vm);
2670     ObjectFactory *factory = vm->GetFactory();
2671     std::vector<PropertyDescriptor> descs;
2672     JSNapiSendable::InitWithPropertiesInfo(thread, info, descs);
2673     auto obj = factory->CreateSObjectWithProperties(descs);
2674     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2675     return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2676 }
2677 
NewWithNamedProperties(const EcmaVM * vm,size_t propertyCount,const char ** keys,const Local<JSValueRef> * values)2678 Local<ObjectRef> ObjectRef::NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount,
2679                                                    const char **keys, const Local<JSValueRef> *values)
2680 {
2681     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2682     ecmascript::ThreadManagedScope managedScope(thread);
2683     EscapeLocalScope scope(vm);
2684     ObjectFactory *factory = vm->GetFactory();
2685     JSHandle<JSTaggedValue> obj = factory->CreateJSObjectWithNamedProperties(propertyCount, keys, values);
2686     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2687     return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2688 }
2689 
CreateNativeModuleFailureInfo(const EcmaVM * vm,const std::string & failureInfo)2690 Local<ObjectRef> ObjectRef::CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo)
2691 {
2692     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2693     ecmascript::ThreadManagedScope managedScope(thread);
2694     if (EcmaVM::GetErrorInfoEnhance()) {
2695         JSHandle<NativeModuleFailureInfo> nativeModuleErrorFailureInfo =
2696             NativeModuleFailureInfo::CreateNativeModuleFailureInfo(vm, failureInfo);
2697         return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(nativeModuleErrorFailureInfo));
2698     }
2699     return JSValueRef::Undefined(vm);
2700 }
2701 
CreateAccessorData(const EcmaVM * vm,Local<FunctionRef> getter,Local<FunctionRef> setter)2702 Local<ObjectRef> ObjectRef::CreateAccessorData(const EcmaVM *vm,
2703                                                Local<FunctionRef> getter, Local<FunctionRef> setter)
2704 {
2705     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2706     ecmascript::ThreadManagedScope managedScope(thread);
2707     JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2708     JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2709     JSHandle<AccessorData> accessor = thread->GetEcmaVM()->GetFactory()->NewAccessorData();
2710     accessor->SetGetter(thread, getterValue);
2711     accessor->SetSetter(thread, setterValue);
2712     return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(accessor));
2713 }
2714 
CreateSendableAccessorData(const EcmaVM * vm,Local<FunctionRef> getter,Local<FunctionRef> setter)2715 Local<ObjectRef> ObjectRef::CreateSendableAccessorData(const EcmaVM *vm,
2716                                                        Local<FunctionRef> getter,
2717                                                        Local<FunctionRef> setter)
2718 {
2719     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2720     ecmascript::ThreadManagedScope managedScope(thread);
2721     JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2722     JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2723     JSHandle<AccessorData> accessor = thread->GetEcmaVM()->GetFactory()->NewSAccessorData();
2724     accessor->SetGetter(thread, getterValue);
2725     accessor->SetSetter(thread, setterValue);
2726     return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(accessor));
2727 }
2728 
ConvertToNativeBindingObject(const EcmaVM * vm,Local<NativePointerRef> value)2729 bool ObjectRef::ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value)
2730 {
2731     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2732     ecmascript::ThreadManagedScope managedScope(thread);
2733     [[maybe_unused]] LocalScope scope(vm);
2734     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
2735     LOG_IF_SPECIAL(object, ERROR);
2736     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
2737     JSHandle<JSTaggedValue> keyValue = env->GetNativeBindingSymbol();
2738     auto key = JSNApiHelper::ToLocal<JSValueRef>(keyValue);
2739     PropertyAttribute attr(Local<JSValueRef>(value), true, false, false);
2740     bool result = DefineProperty(vm, key, attr);
2741     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2742     object->GetTaggedObject()->GetClass()->SetIsNativeBindingObject(true);
2743     return result;
2744 }
2745 
GetNativeBindingPointer(const EcmaVM * vm)2746 Local<NativePointerRef> ObjectRef::GetNativeBindingPointer(const EcmaVM *vm)
2747 {
2748     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2749     ecmascript::ThreadManagedScope managedScope(thread);
2750     EscapeLocalScope scope(vm);
2751     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
2752     LOG_IF_SPECIAL(object, ERROR);
2753     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
2754     JSHandle<JSTaggedValue> keyValue = env->GetNativeBindingSymbol();
2755     OperationResult ret = JSTaggedValue::GetProperty(thread, object, keyValue);
2756     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2757     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()));
2758 }
2759 
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)2760 bool ObjectRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
2761 {
2762     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2763     ecmascript::ThreadManagedScope managedScope(thread);
2764     [[maybe_unused]] LocalScope scope(vm);
2765     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2766     LOG_IF_SPECIAL(obj, ERROR);
2767     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2768     JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
2769     if (!obj->IsHeapObject()) {
2770         return JSTaggedValue::SetProperty(thread, obj, keyValue, valueValue);
2771     }
2772     return ObjectFastOperator::FastSetPropertyByValue(thread, obj.GetTaggedValue(),
2773                                                       keyValue.GetTaggedValue(),
2774                                                       valueValue.GetTaggedValue());
2775 }
2776 
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)2777 bool ObjectRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
2778 {
2779     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2780     ecmascript::ThreadManagedScope managedScope(thread);
2781     [[maybe_unused]] LocalScope scope(vm);
2782     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2783     LOG_IF_SPECIAL(obj, ERROR);
2784     ObjectFactory *factory = vm->GetFactory();
2785     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
2786     JSHandle<JSTaggedValue> val = JSNApiHelper::ToJSHandle(value);
2787     if (!obj->IsHeapObject()) {
2788         return JSTaggedValue::SetProperty(thread, obj, key, val);
2789     }
2790     JSTaggedValue res = ObjectFastOperator::TrySetPropertyByNameThroughCacheAtLocal(thread, obj, key, val);
2791     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2792     if (!res.IsHole()) {
2793         return !res.IsException();
2794     }
2795     if (!JSNApi::KeyIsNumber(utf8)) {
2796         res = ObjectFastOperator::SetPropertyByName(thread, obj.GetTaggedValue(), key.GetTaggedValue(),
2797                                                     val.GetTaggedValue());
2798         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2799         if (!res.IsHole()) {
2800             return !res.IsException();
2801         }
2802         return JSTaggedValue::SetProperty(thread, obj, key, val, true);
2803     }
2804     return ObjectFastOperator::FastSetPropertyByValue(thread, obj.GetTaggedValue(),
2805                                                       key.GetTaggedValue(),
2806                                                       val.GetTaggedValue());
2807 }
2808 
SetWithoutSwitchState(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)2809 bool ObjectRef::SetWithoutSwitchState(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
2810 {
2811     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2812     [[maybe_unused]] LocalScope scope(vm);
2813     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2814     LOG_IF_SPECIAL(obj, ERROR);
2815     ObjectFactory *factory = vm->GetFactory();
2816     JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
2817     JSHandle<JSTaggedValue> val = JSNApiHelper::ToJSHandle(value);
2818     JSTaggedValue res = ObjectFastOperator::TrySetPropertyByNameThroughCacheAtLocal(thread, obj, key, val);
2819     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2820     if (!res.IsHole()) {
2821         return !res.IsException();
2822     }
2823     if (!JSNApi::KeyIsNumber(utf8)) {
2824         res = ObjectFastOperator::SetPropertyByName(thread, obj.GetTaggedValue(), key.GetTaggedValue(),
2825                                                     val.GetTaggedValue());
2826         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2827         if (!res.IsHole()) {
2828             return !res.IsException();
2829         }
2830         return JSTaggedValue::SetProperty(thread, obj, key, val, true);
2831     }
2832     return ObjectFastOperator::FastSetPropertyByValue(thread, obj.GetTaggedValue(),
2833                                                       key.GetTaggedValue(),
2834                                                       val.GetTaggedValue());
2835 }
2836 
GetImplements(const EcmaVM * vm,Local<JSValueRef> instance)2837 Local<JSValueRef> JSNApi::GetImplements(const EcmaVM *vm, Local<JSValueRef> instance)
2838 {
2839     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2840     ecmascript::ThreadManagedScope managedScope(thread);
2841     JSTaggedValue result;
2842     {
2843         LocalScope scope(vm);
2844         if (!instance->IsObject(vm)) {
2845             return JSValueRef::Undefined(vm);
2846         }
2847         JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(instance));
2848         OperationResult constructorValue = JSTaggedValue::GetProperty(
2849             thread, obj, thread->GlobalConstants()->GetHandledConstructorString());
2850         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2851         result = constructorValue.GetValue().GetTaggedValue();
2852         if (!result.IsJSFunction()) {
2853             return JSValueRef::Undefined(vm);
2854         }
2855         JSHandle<JSTaggedValue> resultValue(thread, result);
2856         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
2857         JSHandle<JSTaggedValue> interfaceTypeSymbol = env->GetInterfaceTypeSymbol();
2858         OperationResult interfaceTypeValue = JSObject::GetProperty(thread, resultValue, interfaceTypeSymbol);
2859         result = interfaceTypeValue.GetValue().GetTaggedValue();
2860         if (result.IsUndefined()) {
2861             return JSValueRef::Undefined(vm);
2862         }
2863     }
2864     JSHandle<JSTaggedValue> implementRet(thread, result);
2865     return JSNApiHelper::ToLocal<JSValueRef>(implementRet);
2866 }
2867 
Set(const EcmaVM * vm,uint32_t key,Local<JSValueRef> value)2868 bool ObjectRef::Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value)
2869 {
2870     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2871     ecmascript::ThreadManagedScope managedScope(thread);
2872     [[maybe_unused]] LocalScope scope(vm);
2873     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2874     LOG_IF_SPECIAL(obj, ERROR);
2875     JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
2876     if (!obj->IsHeapObject()) {
2877         return JSTaggedValue::SetProperty(thread, obj, key, valueValue);
2878     }
2879     return ObjectFastOperator::FastSetPropertyByIndex(thread, obj.GetTaggedValue(),
2880                                                       key, valueValue.GetTaggedValue());
2881 }
2882 
SetAccessorProperty(const EcmaVM * vm,Local<JSValueRef> key,Local<FunctionRef> getter,Local<FunctionRef> setter,PropertyAttribute attribute)2883 bool ObjectRef::SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
2884     Local<FunctionRef> setter, PropertyAttribute attribute)
2885 {
2886     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2887     ecmascript::ThreadManagedScope managedScope(thread);
2888     [[maybe_unused]] LocalScope scope(vm);
2889     JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2890     JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2891     PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
2892     desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
2893     desc.SetSetter(setterValue);
2894     desc.SetGetter(getterValue);
2895     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2896     LOG_IF_SPECIAL(obj, ERROR);
2897     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2898     return JSTaggedValue::DefineOwnProperty(thread, obj, keyValue, desc);
2899 }
2900 
Get(const EcmaVM * vm,Local<JSValueRef> key)2901 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
2902 {
2903     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2904     ecmascript::ThreadManagedScope managedScope(thread);
2905     JSTaggedValue result;
2906     {
2907         LocalScope scope(vm);
2908         JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2909         LOG_IF_SPECIAL(obj, ERROR);
2910         JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2911         if (UNLIKELY(!obj->IsHeapObject())) {
2912             OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
2913             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2914             result = ret.GetValue().GetTaggedValue();
2915         } else {
2916             result = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
2917                                                                 keyValue.GetTaggedValue());
2918             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2919         }
2920     }
2921     JSHandle<JSTaggedValue> resultValue(thread, result);
2922     return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2923 }
2924 
Get(const EcmaVM * vm,const char * utf8)2925 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, const char *utf8)
2926 {
2927     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2928     ecmascript::ThreadManagedScope managedScope(thread);
2929     JSTaggedValue result;
2930     {
2931         LocalScope scope(vm);
2932         JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2933         LOG_IF_SPECIAL(obj, ERROR);
2934         ObjectFactory *factory = vm->GetFactory();
2935         JSHandle<JSTaggedValue> keyValue(factory->NewFromUtf8(utf8));
2936         if (UNLIKELY(!obj->IsHeapObject())) {
2937             OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
2938             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2939             result = ret.GetValue().GetTaggedValue();
2940         } else {
2941             result = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
2942                                                                 keyValue.GetTaggedValue());
2943             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2944         }
2945     }
2946     JSHandle<JSTaggedValue> resultValue(thread, result);
2947     return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2948 }
2949 
Get(const EcmaVM * vm,int32_t key)2950 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, int32_t key)
2951 {
2952     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2953     ecmascript::ThreadManagedScope managedScope(thread);
2954     JSTaggedValue result;
2955     {
2956         LocalScope scope(vm);
2957         JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2958         LOG_IF_SPECIAL(obj, ERROR);
2959         if (!obj->IsHeapObject()) {
2960             OperationResult ret = JSTaggedValue::GetProperty(thread, obj, key);
2961             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2962             result = ret.GetValue().GetTaggedValue();
2963         } else {
2964             result = ObjectFastOperator::FastGetPropertyByIndex(thread, obj.GetTaggedValue(), key);
2965             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2966         }
2967     }
2968     JSHandle<JSTaggedValue> resultValue(thread, result);
2969     return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2970 }
2971 
GetOwnProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute & property)2972 bool ObjectRef::GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property)
2973 {
2974     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2975     ecmascript::ThreadManagedScope managedScope(thread);
2976     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2977     LOG_IF_SPECIAL(obj, ERROR);
2978     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2979     PropertyDescriptor desc(thread);
2980     bool ret = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(obj), keyValue, desc);
2981     if (!ret) {
2982         return false;
2983     }
2984     property.SetValue(JSNApiHelper::ToLocal<JSValueRef>(desc.GetValue()));
2985     if (desc.HasGetter()) {
2986         property.SetGetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetGetter()));
2987     }
2988     if (desc.HasSetter()) {
2989         property.SetSetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetSetter()));
2990     }
2991     if (desc.HasWritable()) {
2992         property.SetWritable(desc.IsWritable());
2993     }
2994     if (desc.HasEnumerable()) {
2995         property.SetEnumerable(desc.IsEnumerable());
2996     }
2997     if (desc.HasConfigurable()) {
2998         property.SetConfigurable(desc.IsConfigurable());
2999     }
3000 
3001     return true;
3002 }
3003 
GetOwnPropertyNames(const EcmaVM * vm)3004 Local<ArrayRef> ObjectRef::GetOwnPropertyNames(const EcmaVM *vm)
3005 {
3006     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3007     ecmascript::ThreadManagedScope managedScope(thread);
3008     JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this));
3009     LOG_IF_SPECIAL(obj, ERROR);
3010     JSHandle<TaggedArray> array(JSTaggedValue::GetOwnPropertyKeys(thread, obj));
3011     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3012     JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
3013     return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
3014 }
3015 
GetAllPropertyNames(const EcmaVM * vm,uint32_t filter)3016 Local<ArrayRef> ObjectRef::GetAllPropertyNames(const EcmaVM *vm, uint32_t filter)
3017 {
3018     // This interface is only used by napi.
3019     // This interface currently only supports normal objects.
3020     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3021     ecmascript::ThreadManagedScope managedScope(thread);
3022     JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this));
3023     LOG_IF_SPECIAL(obj, ERROR);
3024     JSHandle<TaggedArray> array(JSTaggedValue::GetAllPropertyKeys(thread, obj, filter));
3025     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3026     JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
3027     return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
3028 }
3029 
GetOwnEnumerablePropertyNames(const EcmaVM * vm)3030 Local<ArrayRef> ObjectRef::GetOwnEnumerablePropertyNames(const EcmaVM *vm)
3031 {
3032     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3033     ecmascript::ThreadManagedScope managedScope(thread);
3034     JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(this));
3035     LOG_IF_SPECIAL(obj, ERROR);
3036     JSHandle<TaggedArray> array(JSObject::EnumerableOwnNames(thread, obj));
3037     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3038     JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
3039     return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
3040 }
3041 
GetPrototype(const EcmaVM * vm)3042 Local<JSValueRef> ObjectRef::GetPrototype(const EcmaVM *vm)
3043 {
3044     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3045     ecmascript::ThreadManagedScope managedScope(thread);
3046     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3047     LOG_IF_SPECIAL(object, ERROR);
3048     JSHandle<JSTaggedValue> prototype(thread, JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(object)));
3049     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3050     return JSNApiHelper::ToLocal<JSValueRef>(prototype);
3051 }
3052 
SetPrototype(const EcmaVM * vm,Local<ObjectRef> prototype)3053 bool ObjectRef::SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype)
3054 {
3055     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3056     ecmascript::ThreadManagedScope managedScope(thread);
3057     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3058     JSHandle<JSObject> proto(JSNApiHelper::ToJSHandle(prototype));
3059     return JSTaggedValue::SetPrototype(thread, JSHandle<JSTaggedValue>(object), JSHandle<JSTaggedValue>(proto));
3060 }
3061 
DefineProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute attribute)3062 bool ObjectRef::DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute)
3063 {
3064     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3065     ecmascript::ThreadManagedScope managedScope(thread);
3066     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3067     LOG_IF_SPECIAL(object, ERROR);
3068     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
3069     PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
3070     desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
3071     return JSTaggedValue::DefinePropertyOrThrow(thread, object, keyValue, desc);
3072 }
3073 
Has(const EcmaVM * vm,Local<JSValueRef> key)3074 bool ObjectRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
3075 {
3076     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3077     ecmascript::ThreadManagedScope managedScope(thread);
3078     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3079     LOG_IF_SPECIAL(object, ERROR);
3080     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
3081     return JSTaggedValue::HasProperty(thread, object, keyValue);
3082 }
3083 
Has(const EcmaVM * vm,uint32_t key)3084 bool ObjectRef::Has(const EcmaVM *vm, uint32_t key)
3085 {
3086     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3087     ecmascript::ThreadManagedScope managedScope(thread);
3088     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3089     LOG_IF_SPECIAL(object, ERROR);
3090     return JSTaggedValue::HasProperty(thread, object, key);
3091 }
3092 
HasOwnProperty(const EcmaVM * vm,Local<JSValueRef> key)3093 bool ObjectRef::HasOwnProperty(const EcmaVM *vm, Local<JSValueRef> key)
3094 {
3095     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3096     ecmascript::ThreadManagedScope managedScope(thread);
3097     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3098     LOG_IF_SPECIAL(object, ERROR);
3099     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
3100     return JSTaggedValue::HasOwnProperty(thread, object, keyValue);
3101 }
3102 
Delete(const EcmaVM * vm,Local<JSValueRef> key)3103 bool ObjectRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
3104 {
3105     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3106     ecmascript::ThreadManagedScope managedScope(thread);
3107     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3108     LOG_IF_SPECIAL(object, ERROR);
3109     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
3110     return JSTaggedValue::DeleteProperty(thread, object, keyValue);
3111 }
3112 
Delete(const EcmaVM * vm,uint32_t key)3113 bool ObjectRef::Delete(const EcmaVM *vm, uint32_t key)
3114 {
3115     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3116     ecmascript::ThreadManagedScope managedScope(thread);
3117     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
3118     LOG_IF_SPECIAL(object, ERROR);
3119     JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(key));
3120     return JSTaggedValue::DeleteProperty(thread, object, keyHandle);
3121 }
3122 
Freeze(const EcmaVM * vm)3123 Local<JSValueRef> ObjectRef::Freeze(const EcmaVM *vm)
3124 {
3125     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3126     ecmascript::ThreadManagedScope managedScope(thread);
3127     EscapeLocalScope scope(vm);
3128     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
3129     LOG_IF_SPECIAL(object, ERROR);
3130     JSHandle<JSObject> obj(object);
3131     bool status = JSObject::SetIntegrityLevel(thread, obj, ecmascript::IntegrityLevel::FROZEN);
3132     if (JSNApi::HasPendingException(vm)) {
3133         JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
3134         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
3135     }
3136     if (!status) {
3137         LOG_ECMA(ERROR) << "Freeze: freeze failed";
3138         Local<StringRef> message = StringRef::NewFromUtf8(vm, "Freeze: freeze failed");
3139         Local<JSValueRef> error = Exception::Error(vm, message);
3140         JSNApi::ThrowException(vm, error);
3141         JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
3142         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
3143     }
3144     JSHandle<JSTaggedValue> resultValue(obj);
3145     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
3146 }
3147 
Seal(const EcmaVM * vm)3148 Local<JSValueRef> ObjectRef::Seal(const EcmaVM *vm)
3149 {
3150     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3151     ecmascript::ThreadManagedScope managedScope(thread);
3152     EscapeLocalScope scope(vm);
3153     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
3154     LOG_IF_SPECIAL(object, ERROR);
3155     JSHandle<JSObject> obj(object);
3156     bool status = JSObject::SetIntegrityLevel(thread, obj, ecmascript::IntegrityLevel::SEALED);
3157     if (JSNApi::HasPendingException(vm)) {
3158         JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
3159         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
3160     }
3161     if (!status) {
3162         LOG_ECMA(ERROR) << "Seal: seal failed";
3163         Local<StringRef> message = StringRef::NewFromUtf8(vm, "Freeze: freeze failed");
3164         Local<JSValueRef> error = Exception::Error(vm, message);
3165         JSNApi::ThrowException(vm, error);
3166         JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
3167         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
3168     }
3169     JSHandle<JSTaggedValue> resultValue(obj);
3170     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
3171 }
3172 
SetNativePointerFieldCount(const EcmaVM * vm,int32_t count)3173 void ObjectRef::SetNativePointerFieldCount(const EcmaVM *vm, int32_t count)
3174 {
3175     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3176     ecmascript::ThreadManagedScope managedScope(thread);
3177     // ObjectRef::New may return special value if exception occurs.
3178     // So we need do special value check before use it.
3179     DCHECK_SPECIAL_VALUE(this);
3180     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3181     ECMAObject::SetNativePointerFieldCount(thread, object, count);
3182 }
3183 
GetNativePointerFieldCount(const EcmaVM * vm)3184 int32_t ObjectRef::GetNativePointerFieldCount(const EcmaVM *vm)
3185 {
3186     // ObjectRef::New may return special value if exception occurs.
3187     // So we need do special value check before use it.
3188     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
3189     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3190     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3191     return object->GetNativePointerFieldCount(vm->GetJSThread());
3192 }
3193 
GetNativePointerField(const EcmaVM * vm,int32_t index)3194 void *ObjectRef::GetNativePointerField(const EcmaVM *vm, int32_t index)
3195 {
3196     // ObjectRef::New may return special value if exception occurs.
3197     // So we need do special value check before use it.
3198     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3199     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3200     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3201     return object->GetNativePointerField(vm->GetJSThread(), index);
3202 }
3203 
SetNativePointerField(const EcmaVM * vm,int32_t index,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)3204 void ObjectRef::SetNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer,
3205     NativePointerCallback callBack, void *data, size_t nativeBindingsize)
3206 {
3207     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3208     ecmascript::ThreadManagedScope managedScope(thread);
3209     // ObjectRef::New may return special value if exception occurs.
3210     // So we need do special value check before use it.
3211     DCHECK_SPECIAL_VALUE(this);
3212     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3213     ECMAObject::SetNativePointerField(thread, object, index, nativePointer, callBack, data, nativeBindingsize);
3214 }
3215 
SetConcurrentNativePointerField(const EcmaVM * vm,int32_t index,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)3216 void ObjectRef::SetConcurrentNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer,
3217     NativePointerCallback callBack, void *data, size_t nativeBindingsize)
3218 {
3219     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3220     ecmascript::ThreadManagedScope managedScope(thread);
3221     // ObjectRef::New may return special value if exception occurs.
3222     // So we need do special value check before use it.
3223     DCHECK_SPECIAL_VALUE(this);
3224     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
3225     ECMAObject::SetNativePointerField(thread, object, index, nativePointer, callBack, data,
3226                                       nativeBindingsize, Concurrent::YES);
3227 }
3228 
3229 // -------------------------------- NativePointerRef ------------------------------------
New(const EcmaVM * vm,void * nativePointer,size_t nativeBindingsize)3230 Local<NativePointerRef> NativePointerRef::New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize)
3231 {
3232     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3233     ecmascript::ThreadManagedScope managedScope(thread);
3234     ObjectFactory *factory = vm->GetFactory();
3235     JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, nullptr, nullptr,
3236         false, nativeBindingsize);
3237     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
3238 }
3239 
New(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)3240 Local<NativePointerRef> NativePointerRef::New(
3241     const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
3242 {
3243     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3244     ecmascript::ThreadManagedScope managedScope(thread);
3245     ObjectFactory *factory = vm->GetFactory();
3246     JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, callBack, data,
3247         false, nativeBindingsize);
3248     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
3249 }
3250 
NewConcurrent(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)3251 Local<NativePointerRef> NativePointerRef::NewConcurrent(
3252     const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
3253 {
3254     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3255     ecmascript::ThreadManagedScope managedScope(thread);
3256     ObjectFactory *factory = vm->GetFactory();
3257     JSHandle<JSNativePointer> obj =
3258         factory->NewJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize, Concurrent::YES);
3259     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
3260 }
3261 
NewSendable(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)3262 Local<NativePointerRef> NativePointerRef::NewSendable(
3263     const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
3264 {
3265     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3266     ecmascript::ThreadManagedScope managedScope(thread);
3267     ObjectFactory *factory = vm->GetFactory();
3268     JSHandle<JSNativePointer> obj =
3269         factory->NewSJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize);
3270     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
3271 }
3272 
Value()3273 void *NativePointerRef::Value()
3274 {
3275     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3276     JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this);
3277     return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer();
3278 }
3279 
3280 // ---------------------------------- Buffer -----------------------------------
New(const EcmaVM * vm,int32_t length)3281 Local<ArrayBufferRef> ArrayBufferRef::New(const EcmaVM *vm, int32_t length)
3282 {
3283     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3284     ecmascript::ThreadManagedScope managedScope(thread);
3285     ObjectFactory *factory = vm->GetFactory();
3286     JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(length);
3287     return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3288 }
3289 
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)3290 Local<ArrayBufferRef> ArrayBufferRef::New(
3291     const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
3292 {
3293     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3294     ecmascript::ThreadManagedScope managedScope(thread);
3295     ObjectFactory *factory = vm->GetFactory();
3296     JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
3297     return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3298 }
3299 
ByteLength(const EcmaVM * vm)3300 int32_t ArrayBufferRef::ByteLength(const EcmaVM *vm)
3301 {
3302     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3303     ecmascript::ThreadManagedScope managedScope(thread);
3304     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3305     LOG_IF_SPECIAL(arrayBuffer, FATAL);
3306     return arrayBuffer->GetArrayBufferByteLength();
3307 }
3308 
GetBuffer(const EcmaVM * vm)3309 void *ArrayBufferRef::GetBuffer(const EcmaVM *vm)
3310 {
3311     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3312     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3313     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3314     JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(vm->GetJSThread());
3315     if (!bufferData.IsJSNativePointer()) {
3316         return nullptr;
3317     }
3318     return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
3319 }
3320 
GetBufferAndLength(const EcmaVM * vm,int32_t * length)3321 void *ArrayBufferRef::GetBufferAndLength(const EcmaVM *vm, int32_t *length)
3322 {
3323     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3324     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3325     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3326     JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(vm->GetJSThread());
3327     void *data = nullptr;
3328     if (bufferData.IsJSNativePointer()) {
3329         data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
3330     }
3331     LOG_IF_SPECIAL(arrayBuffer, FATAL);
3332     *length = arrayBuffer->GetArrayBufferByteLength();
3333     return data;
3334 }
3335 
Detach(const EcmaVM * vm)3336 void ArrayBufferRef::Detach(const EcmaVM *vm)
3337 {
3338     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3339     ecmascript::ThreadManagedScope managedScope(thread);
3340     // arraybuffer is not shared. Do not need to switch state
3341     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3342     arrayBuffer->Detach(thread);
3343 }
3344 
IsDetach(const EcmaVM * vm)3345 bool ArrayBufferRef::IsDetach(const EcmaVM *vm)
3346 {
3347     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
3348     JSThread *thread = vm->GetJSThread();
3349     ecmascript::ThreadManagedScope managedScope(thread);
3350     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3351     return arrayBuffer->IsDetach(thread);
3352 }
3353 
New(const EcmaVM * vm,int32_t length)3354 Local<SendableArrayBufferRef> SendableArrayBufferRef::New(const EcmaVM *vm, int32_t length)
3355 {
3356     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3357     ecmascript::ThreadManagedScope managedScope(thread);
3358     ObjectFactory *factory = vm->GetFactory();
3359     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer = factory->NewJSSendableArrayBuffer(length);
3360     return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3361 }
3362 
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)3363 Local<SendableArrayBufferRef> SendableArrayBufferRef::New(
3364     const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
3365 {
3366     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3367     ecmascript::ThreadManagedScope managedScope(thread);
3368     ObjectFactory *factory = vm->GetFactory();
3369     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer =
3370         factory->NewJSSendableArrayBuffer(buffer, length, deleter, data);
3371     return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3372 }
3373 
ByteLength(const EcmaVM * vm)3374 int32_t SendableArrayBufferRef::ByteLength(const EcmaVM *vm)
3375 {
3376     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3377     ecmascript::ThreadManagedScope managedScope(thread);
3378     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3379     LOG_IF_SPECIAL(arrayBuffer, FATAL);
3380     return arrayBuffer->GetArrayBufferByteLength();
3381 }
3382 
Detach(const EcmaVM * vm)3383 void SendableArrayBufferRef::Detach(const EcmaVM *vm)
3384 {
3385     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3386     ecmascript::ThreadManagedScope managedScope(thread);
3387     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3388     arrayBuffer->Detach(thread);
3389 }
3390 
IsDetach(const EcmaVM * vm)3391 bool SendableArrayBufferRef::IsDetach(const EcmaVM *vm)
3392 {
3393     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
3394     JSThread *thread = vm->GetJSThread();
3395     ecmascript::ThreadManagedScope managedScope(thread);
3396     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3397     return arrayBuffer->IsDetach(thread);
3398 }
3399 
GetBuffer(const EcmaVM * vm)3400 void *SendableArrayBufferRef::GetBuffer(const EcmaVM *vm)
3401 {
3402     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3403     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3404     JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3405     JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(vm->GetJSThread());
3406     if (!bufferData.IsJSNativePointer()) {
3407         return nullptr;
3408     }
3409     return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
3410 }
3411 
3412 // ---------------------------------- DateRef -----------------------------------
New(const EcmaVM * vm,double time)3413 Local<DateRef> DateRef::New(const EcmaVM *vm, double time)
3414 {
3415     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3416     ecmascript::ThreadManagedScope managedScope(thread);
3417     ObjectFactory *factory = vm->GetFactory();
3418     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
3419     JSHandle<JSFunction> dateFunction(globalEnv->GetDateFunction());
3420     JSHandle<JSDate> dateObject(factory->NewJSObjectByConstructor(dateFunction));
3421     dateObject->SetTimeValue(thread, JSTaggedValue(time));
3422     return JSNApiHelper::ToLocal<DateRef>(JSHandle<JSTaggedValue>(dateObject));
3423 }
3424 
ToString(const EcmaVM * vm)3425 Local<StringRef> DateRef::ToString(const EcmaVM *vm)
3426 {
3427     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3428     ecmascript::ThreadManagedScope managedScope(thread);
3429     JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
3430     LOG_IF_SPECIAL(date, ERROR);
3431     JSTaggedValue dateStr = date->ToString(thread);
3432     if (!dateStr.IsString()) {
3433         auto constants = thread->GlobalConstants();
3434         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
3435     }
3436     JSHandle<JSTaggedValue> dateStrHandle(thread, dateStr);
3437     return JSNApiHelper::ToLocal<StringRef>(dateStrHandle);
3438 }
3439 
GetTime(const EcmaVM * vm)3440 double DateRef::GetTime(const EcmaVM *vm)
3441 {
3442     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0.0);
3443     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3444     JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
3445     if (!date->IsDate()) {
3446         LOG_ECMA(ERROR) << "Not a Date Object";
3447     }
3448     return date->GetTime(vm->GetJSThread()).GetDouble();
3449 }
3450 
3451 // ---------------------------------- TypedArray -----------------------------------
ByteLength(const EcmaVM * vm)3452 uint32_t TypedArrayRef::ByteLength(const EcmaVM *vm)
3453 {
3454     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3455     ecmascript::ThreadManagedScope managedScope(thread);
3456     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3457     LOG_IF_SPECIAL(typedArray, FATAL);
3458     return typedArray->GetByteLength();
3459 }
3460 
ByteOffset(const EcmaVM * vm)3461 uint32_t TypedArrayRef::ByteOffset(const EcmaVM *vm)
3462 {
3463     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3464     ecmascript::ThreadManagedScope managedScope(thread);
3465     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3466     LOG_IF_SPECIAL(typedArray, FATAL);
3467     return typedArray->GetByteOffset();
3468 }
3469 
ArrayLength(const EcmaVM * vm)3470 uint32_t TypedArrayRef::ArrayLength(const EcmaVM *vm)
3471 {
3472     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3473     ecmascript::ThreadManagedScope managedScope(thread);
3474     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3475     LOG_IF_SPECIAL(typedArray, FATAL);
3476     return typedArray->GetArrayLength();
3477 }
3478 
GetArrayBuffer(const EcmaVM * vm)3479 Local<ArrayBufferRef> TypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
3480 {
3481     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3482     ecmascript::ThreadManagedScope managedScope(thread);
3483     JSHandle<JSTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
3484     LOG_IF_SPECIAL(typeArray, ERROR);
3485     JSHandle<JSTaggedValue> arrayBuffer(thread, JSTypedArray::GetOffHeapBuffer(thread, typeArray));
3486     return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
3487 }
3488 
ByteLength(const EcmaVM * vm)3489 uint32_t SendableTypedArrayRef::ByteLength(const EcmaVM *vm)
3490 {
3491     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3492     ecmascript::ThreadManagedScope managedScope(thread);
3493     JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3494     LOG_IF_SPECIAL(typedArray, FATAL);
3495     return typedArray->GetByteLength();
3496 }
3497 
ByteOffset(const EcmaVM * vm)3498 uint32_t SendableTypedArrayRef::ByteOffset(const EcmaVM *vm)
3499 {
3500     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3501     ecmascript::ThreadManagedScope managedScope(thread);
3502     JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3503     LOG_IF_SPECIAL(typedArray, FATAL);
3504     return typedArray->GetByteOffset();
3505 }
3506 
ArrayLength(const EcmaVM * vm)3507 uint32_t SendableTypedArrayRef::ArrayLength(const EcmaVM *vm)
3508 {
3509     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3510     ecmascript::ThreadManagedScope managedScope(thread);
3511     JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3512     LOG_IF_SPECIAL(typedArray, FATAL);
3513     return typedArray->GetArrayLength();
3514 }
3515 
GetArrayBuffer(const EcmaVM * vm)3516 Local<SendableArrayBufferRef> SendableTypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
3517 {
3518     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3519     ecmascript::ThreadManagedScope managedScope(thread);
3520     JSHandle<ecmascript::JSSharedTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
3521     LOG_IF_SPECIAL(typeArray, ERROR);
3522     JSHandle<JSTaggedValue> arrayBuffer(thread,
3523         ecmascript::JSSharedTypedArray::GetSharedOffHeapBuffer(thread, typeArray));
3524     return JSNApiHelper::ToLocal<SendableArrayBufferRef>(arrayBuffer);
3525 }
3526 
3527 // ----------------------------------- FunctionRef --------------------------------------
New(EcmaVM * vm,const Local<JSValueRef> & context,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3528 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, const Local<JSValueRef> &context, FunctionCallback nativeFunc,
3529     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3530 {
3531     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3532     ecmascript::ThreadManagedScope managedScope(thread);
3533     ObjectFactory *factory = vm->GetFactory();
3534     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3535     JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback)));
3536     JSFunction::SetFunctionExtraInfo(thread, current, reinterpret_cast<void *>(nativeFunc),
3537                                      deleter, data, nativeBindingsize);
3538     current->SetCallNapi(callNapi);
3539     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3540     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3541 }
3542 
New(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3543 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc,
3544     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3545 {
3546     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3547     ecmascript::ThreadManagedScope managedScope(thread);
3548     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3549     return New(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3550 }
3551 
NewConcurrent(EcmaVM * vm,const Local<JSValueRef> & context,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3552 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, const Local<JSValueRef> &context, FunctionCallback nativeFunc,
3553     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3554 {
3555     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3556     ecmascript::ThreadManagedScope managedScope(thread);
3557     ObjectFactory *factory = vm->GetFactory();
3558     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3559     JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback)));
3560     JSFunction::SetFunctionExtraInfo(thread, current, reinterpret_cast<void *>(nativeFunc), deleter,
3561                                      data, nativeBindingsize, Concurrent::YES);
3562     current->SetCallNapi(callNapi);
3563     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3564     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3565 }
3566 
NewConcurrent(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3567 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, FunctionCallback nativeFunc,
3568     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3569 {
3570     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3571     ecmascript::ThreadManagedScope managedScope(thread);
3572     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3573     return NewConcurrent(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3574 }
3575 
New(EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3576 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, const Local<JSValueRef> &context, InternalFunctionCallback nativeFunc,
3577     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3578 {
3579     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3580     ecmascript::ThreadManagedScope managedScope(thread);
3581     ObjectFactory *factory = vm->GetFactory();
3582     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3583     JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3584     JSFunction::SetFunctionExtraInfo(thread, current, nullptr, deleter, data, nativeBindingsize);
3585     current->SetCallNapi(callNapi);
3586     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3587     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3588 }
3589 
New(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3590 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3591     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3592 {
3593     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3594     ecmascript::ThreadManagedScope managedScope(thread);
3595     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3596     return New(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3597 }
3598 
NewSendable(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3599 Local<FunctionRef> FunctionRef::NewSendable(EcmaVM *vm,
3600                                             InternalFunctionCallback nativeFunc,
3601                                             NativePointerCallback deleter,
3602                                             void *data,
3603                                             bool callNapi,
3604                                             size_t nativeBindingsize)
3605 {
3606     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3607     ecmascript::ThreadManagedScope managedScope(thread);
3608     ObjectFactory *factory = vm->GetFactory();
3609     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3610     JSHandle<JSFunction> current(factory->NewSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3611     JSFunction::SetSFunctionExtraInfo(thread, current, nullptr, deleter, data, nativeBindingsize);
3612     current->SetCallNapi(callNapi);
3613     // for naive SendableFunction, it's lexicalEnv should be undefined
3614     ASSERT(current->GetLexicalEnv(thread) == JSTaggedValue::Undefined());
3615     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3616 }
3617 
NewConcurrent(EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3618 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, const Local<JSValueRef> &context,
3619     InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi,
3620     size_t nativeBindingsize)
3621 {
3622     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3623     ecmascript::ThreadManagedScope managedScope(thread);
3624     ObjectFactory *factory = vm->GetFactory();
3625     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3626     JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3627     JSFunction::SetFunctionExtraInfo(thread, current, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3628     current->SetCallNapi(callNapi);
3629     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3630     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3631 }
3632 
NewConcurrent(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3633 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3634     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3635 {
3636     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3637     ecmascript::ThreadManagedScope managedScope(thread);
3638     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3639     return NewConcurrent(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3640 }
3641 
NewConcurrentWithName(EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,const char * name,void * data,bool callNapi,size_t nativeBindingsize)3642 Local<FunctionRef> FunctionRef::NewConcurrentWithName(EcmaVM *vm, const Local<JSValueRef> &context,
3643                                                       InternalFunctionCallback nativeFunc,
3644                                                       NativePointerCallback deleter, const char *name, void *data,
3645                                                       bool callNapi, size_t nativeBindingsize)
3646 {
3647     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3648     ecmascript::ThreadManagedScope managedScope(thread);
3649 
3650     ObjectFactory *factory = vm->GetFactory();
3651     JSHandle<JSTaggedValue> functionName(factory->NewFromUtf8(name));
3652     PropertyDescriptor nameDesc(thread, functionName, false, false, true);
3653     ecmascript::PropertyAttributes attr(nameDesc);
3654     attr.SetIsInlinedProps(true);
3655     attr.SetOffset(0);
3656     attr.SetRepresentation(ecmascript::Representation::TAGGED);
3657 
3658     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3659     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetNormalFunctionClass());
3660     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
3661     ecmascript::Representation rep =
3662         ecmascript::PropertyAttributes::TranslateToRep(nameDesc.GetValue().GetTaggedValue());
3663     hclass = JSHClass::SetPropertyOfObjHClass<true>(thread, hclass, globalConst->GetHandledNameString(), attr, rep,
3664                                                     true, JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS);
3665     JSHandle<JSFunction> func = factory->NewNativeFunctionByHClass(hclass, reinterpret_cast<void *>(nativeFunc),
3666                                                                    ecmascript::FunctionKind::NORMAL_FUNCTION);
3667     func->SetPropertyInlinedProps<true>(thread, 0, nameDesc.GetValue().GetTaggedValue());
3668     JSFunction::SetFunctionExtraInfo(thread, func, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3669     ASSERT_PRINT(func->IsExtensible(), "Function must be extensible");
3670 
3671     func->SetCallNapi(callNapi);
3672     func->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3673     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(func));
3674 }
3675 
NewClassFunction(EcmaVM * vm,const Local<JSValueRef> & context,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3676 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, const Local<JSValueRef> &context,
3677     FunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3678 {
3679     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3680     ecmascript::ThreadManagedScope managedScope(thread);
3681     EscapeLocalScope scope(vm);
3682     ObjectFactory *factory = vm->GetFactory();
3683     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3684     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3685     JSHandle<JSFunction> current =
3686         factory->NewJSFunctionByHClass(reinterpret_cast<void *>(Callback::RegisterCallback),
3687         hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3688     JSFunction::InitClassFunction(thread, current, callNapi);
3689     JSFunction::SetFunctionExtraInfo(thread, current, reinterpret_cast<void *>(nativeFunc),
3690                                      deleter, data, nativeBindingsize);
3691     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3692     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3693     return scope.Escape(result);
3694 }
3695 
NewClassFunction(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3696 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc,
3697     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3698 {
3699     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3700     ecmascript::ThreadManagedScope managedScope(thread);
3701     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3702     return NewClassFunction(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3703 }
3704 
NewConcurrentClassFunction(EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3705 Local<FunctionRef> FunctionRef::NewConcurrentClassFunction(EcmaVM *vm, const Local<JSValueRef> &context,
3706     InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi,
3707     size_t nativeBindingsize)
3708 {
3709     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3710     ecmascript::ThreadManagedScope managedScope(thread);
3711     EscapeLocalScope scope(vm);
3712     ObjectFactory *factory = vm->GetFactory();
3713     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3714     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3715     JSHandle<JSFunction> current =
3716         factory->NewJSFunctionByHClass(reinterpret_cast<void *>(nativeFunc),
3717         hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3718     JSFunction::InitClassFunction(thread, current, callNapi);
3719     JSFunction::SetFunctionExtraInfo(thread, current, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3720     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3721     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3722     return scope.Escape(result);
3723 }
3724 
NewConcurrentClassFunctionWithName(const EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,const char * name,void * data,bool callNapi,size_t propertyCount,size_t staticPropCount,Local<panda::JSValueRef> * keys,PropertyAttribute * attrs,size_t nativeBindingsize)3725 Local<FunctionRef> FunctionRef::NewConcurrentClassFunctionWithName(
3726     const EcmaVM *vm, const Local<JSValueRef> &context, InternalFunctionCallback nativeFunc,
3727     NativePointerCallback deleter, const char *name, void *data, bool callNapi, size_t propertyCount,
3728     size_t staticPropCount, Local<panda::JSValueRef> *keys, PropertyAttribute *attrs, size_t nativeBindingsize)
3729 {
3730     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3731     ecmascript::ThreadManagedScope managedScope(thread);
3732     EscapeLocalScope scope(vm);
3733     ObjectFactory *factory = vm->GetFactory();
3734     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3735 
3736     JSHandle<JSFunction> classFunc;
3737     if (propertyCount <= MAX_PROPERTIES_ON_STACK) {
3738         char descs[sizeof(PropertyDescriptor) * MAX_PROPERTIES_ON_STACK];
3739         classFunc = JSNApiClassCreationHelper::CreateClassFuncWithProperties(
3740             thread, name, nativeFunc, callNapi, propertyCount, staticPropCount, keys, attrs,
3741             reinterpret_cast<PropertyDescriptor *>(&descs[0]));
3742     } else {
3743         PropertyDescriptor *descs =
3744             reinterpret_cast<PropertyDescriptor *>(malloc(sizeof(PropertyDescriptor) * propertyCount));
3745         if (descs != nullptr) {
3746             classFunc = JSNApiClassCreationHelper::CreateClassFuncWithProperties(
3747                 thread, name, nativeFunc, callNapi, propertyCount, staticPropCount, keys, attrs, descs);
3748             free(descs);
3749         } else {
3750             THROW_RANGE_ERROR_AND_RETURN(thread, "Malloc descriptors failed!", JSValueRef::Undefined(vm));
3751         }
3752     }
3753     classFunc->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3754     JSFunction::SetFunctionExtraInfo(thread, classFunc, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3755     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(classFunc));
3756     return scope.Escape(result);
3757 }
3758 
NewConcurrentClassFunction(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3759 Local<FunctionRef> FunctionRef::NewConcurrentClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3760     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3761 {
3762     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3763     ecmascript::ThreadManagedScope managedScope(thread);
3764     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3765     return NewConcurrentClassFunction(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3766 }
3767 
NewClassFunction(EcmaVM * vm,const Local<JSValueRef> & context,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3768 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, const Local<JSValueRef> &context,
3769     InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi,
3770     size_t nativeBindingsize)
3771 {
3772     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3773     ecmascript::ThreadManagedScope managedScope(thread);
3774     EscapeLocalScope scope(vm);
3775     ObjectFactory *factory = vm->GetFactory();
3776     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3777     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3778     JSHandle<JSFunction> current =
3779         factory->NewJSFunctionByHClass(reinterpret_cast<void *>(nativeFunc),
3780         hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3781     JSFunction::InitClassFunction(thread, current, callNapi);
3782     JSFunction::SetFunctionExtraInfo(thread, current, nullptr, deleter, data, nativeBindingsize);
3783     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3784     current->SetLexicalEnv(thread, JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context)));
3785     return scope.Escape(result);
3786 }
3787 
NewClassFunction(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3788 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3789     NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3790 {
3791     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3792     ecmascript::ThreadManagedScope managedScope(thread);
3793     Local<JSValueRef> context = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread->GetGlobalEnv()));
3794     return NewClassFunction(vm, context, nativeFunc, deleter, data, callNapi, nativeBindingsize);
3795 }
3796 
NewSendableClassFunction(const EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,Local<StringRef> name,SendablePropertiesInfos & infos,Local<FunctionRef> parent,bool callNapi,size_t nativeBindingSize)3797 Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
3798                                                          InternalFunctionCallback nativeFunc,
3799                                                          NativePointerCallback deleter,
3800                                                          void *data,
3801                                                          Local<StringRef> name,
3802                                                          SendablePropertiesInfos &infos,
3803                                                          Local<FunctionRef> parent,
3804                                                          bool callNapi,
3805                                                          size_t nativeBindingSize)
3806 {
3807     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3808     ecmascript::ThreadManagedScope managedScope(thread);
3809     EscapeLocalScope scope(vm);
3810     ObjectFactory *factory = vm->GetFactory();
3811 
3812     JSNapiSendable sendable(thread, infos, name);
3813     JSHandle<JSHClass> prototypeHClass = JSHClass::CreateSPrototypeHClass(thread, sendable.GetNonStaticDescs());
3814     JSHandle<JSObject> prototype = factory->NewSharedOldSpaceJSObject(prototypeHClass);
3815     JSHandle<JSHClass> constructorHClass = JSHClass::CreateSConstructorHClass(thread, sendable.GetStaticDescs());
3816     JSHandle<JSFunction> constructor = factory->NewSFunctionByHClass(
3817         reinterpret_cast<void *>(nativeFunc), constructorHClass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3818 
3819     sendable.SetSConstructor(constructor);
3820     JSObject::SetSProperties(thread, prototype, sendable.GetNonStaticDescs());
3821     JSObject::SetSProperties(thread, JSHandle<JSObject>::Cast(constructor), sendable.GetStaticDescs());
3822 
3823     if (parent->IsHole()) {
3824         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3825         prototypeHClass->SetPrototype(thread, env->GetSObjectFunctionPrototype());
3826         constructorHClass->SetPrototype(thread, env->GetSFunctionPrototype());
3827     } else if (parent->IsNull()) {
3828         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3829         prototypeHClass->SetPrototype(thread, JSTaggedValue::Null());
3830         constructorHClass->SetPrototype(thread, env->GetSFunctionPrototype());
3831     } else {
3832         auto parentPrototype = parent->GetFunctionPrototype(vm);
3833         prototypeHClass->SetPrototype(thread, JSNApiHelper::ToJSHandle(parentPrototype));
3834         constructorHClass->SetPrototype(thread, JSNApiHelper::ToJSHandle(parent));
3835     }
3836     prototypeHClass->SetExtensible(false);
3837     constructor->SetHomeObject(thread, prototype);
3838     constructor->SetProtoOrHClass(thread, prototype);
3839     // for naive SendableClassFunction, it doesn't need to store itself to lexicalEnv
3840     ASSERT(constructor->GetLexicalEnv(thread) == JSTaggedValue::Undefined());
3841     constructor->SetCallNapi(callNapi);
3842     JSFunction::SetSFunctionExtraInfo(thread, constructor, nullptr, deleter, data, nativeBindingSize);
3843 
3844     JSHClass *parentIHClass{nullptr};
3845     if (!parent->IsHole() && !parent->IsNull()) {
3846         JSHandle<JSFunction> parentHandle(JSNApiHelper::ToJSHandle(parent));
3847         parentIHClass = reinterpret_cast<JSHClass *>(parentHandle->GetProtoOrHClass(thread).GetTaggedObject());
3848     }
3849     JSHandle<JSHClass> iHClass = JSHClass::CreateSHClass(thread, sendable.GetInstanceDescs(), parentIHClass);
3850     iHClass->SetPrototype(thread, JSHandle<JSTaggedValue>(prototype));
3851     iHClass->SetExtensible(false);
3852     constructor->SetProtoOrHClass(thread, iHClass);
3853     constructorHClass->SetExtensible(false);
3854 
3855     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(constructor));
3856     return scope.Escape(result);
3857 }
3858 
Call(const EcmaVM * vm,Local<JSValueRef> thisObj,const Local<JSValueRef> argv[],int32_t length)3859 Local<JSValueRef> FunctionRef::Call(const EcmaVM *vm, Local<JSValueRef> thisObj,
3860     const Local<JSValueRef> argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3861     int32_t length)
3862 {
3863     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3864     ecmascript::ThreadManagedScope managedScope(thread);
3865     EscapeLocalScope scope(vm);
3866     FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3867     if (!IsFunction(vm)) {
3868         return JSValueRef::Undefined(vm);
3869     }
3870     vm->GetJsDebuggerManager()->ClearSingleStepper();
3871     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
3872     LOG_IF_SPECIAL(func, ERROR);
3873     JSHandle<JSTaggedValue> thisValue = JSNApiHelper::ToJSHandle(thisObj);
3874     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
3875     EcmaRuntimeCallInfo *info =
3876         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, thisValue, undefined, length);
3877     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3878     for (int32_t i = 0; i < length; i++) {
3879         JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
3880 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
3881         thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
3882 #endif
3883         info->SetCallArg(i, arg.GetTaggedValue());
3884     }
3885     JSTaggedValue result = JSFunction::Call(info);
3886 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
3887     thread->CheckJSTaggedType(result.GetRawData());
3888 #endif
3889     if (thread->HasPendingException()) {
3890         ecmascript::JsStackInfo::BuildCrashInfo(thread);
3891     }
3892     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3893     JSHandle<JSTaggedValue> resultValue(thread, result);
3894 
3895     EcmaVM::ClearKeptObjects(thread);
3896     vm->GetJsDebuggerManager()->NotifyReturnNative();
3897     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
3898 }
3899 
CallForNapi(const EcmaVM * vm,JSValueRef * thisObj,JSValueRef * const argv[],int32_t length)3900 JSValueRef* FunctionRef::CallForNapi(const EcmaVM *vm, JSValueRef *thisObj,
3901     JSValueRef *const argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3902     int32_t length)
3903 {
3904     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, *JSValueRef::Hole(vm));
3905     ecmascript::ThreadManagedScope managedScope(thread);
3906     JSTaggedValue result;
3907     FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3908     ASSERT(IsFunction(vm)); // IsFunction check has been done in napi.
3909     {
3910         LocalScope scope(vm);
3911         ecmascript::tooling::JsDebuggerManager *dm = vm->GetJsDebuggerManager();
3912         bool isDebugApp = dm->IsDebugApp();
3913         if (isDebugApp) {
3914             dm->ClearSingleStepper();
3915         }
3916         JSTaggedValue func = *reinterpret_cast<JSTaggedValue *>(this);
3917         JSTaggedValue undefined = thread->GlobalConstants()->GetUndefined();
3918         JSTaggedValue thisValue = undefined;
3919         if (thisObj != nullptr) {
3920             thisValue = *reinterpret_cast<JSTaggedValue *>(thisObj);
3921         }
3922         EcmaRuntimeCallInfo *info =
3923             ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, thisValue, undefined, length);
3924         RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
3925         for (int32_t i = 0; i < length; i++) {
3926             if (argv[i]) {
3927 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
3928                 thread->CheckJSTaggedType(JSNApiHelper::ToJSTaggedValue(argv[i]).GetRawData());
3929 #endif
3930                 // NewRuntimeCallInfo has set Undefined defaultly in Argv's slot.
3931                 info->SetCallArg(i, JSNApiHelper::ToJSTaggedValue(argv[i]));
3932             }
3933         }
3934         if (LIKELY(thread->IsAsmInterpreter())) {
3935             STACK_LIMIT_CHECK(thread, reinterpret_cast<JSValueRef *>(*JSValueRef::Hole(vm)));
3936             auto *hclass = func.GetTaggedObject()->GetClass();
3937             if (hclass->IsClassConstructor()) {
3938                 RETURN_STACK_BEFORE_THROW_IF_ASM(thread);
3939                 THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot call",
3940                     reinterpret_cast<JSValueRef *>(*JSValueRef::Hole(vm)));
3941             }
3942             result = ecmascript::InterpreterAssembly::Execute(info);
3943         } else {
3944             result = JSFunction::Call(info);
3945         }
3946 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
3947         thread->CheckJSTaggedType(result.GetRawData());
3948 #endif
3949         RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
3950         EcmaVM::ClearKeptObjects(thread);
3951         if (isDebugApp && dm->IsMixedDebugEnabled()) {
3952             dm->NotifyReturnNative();
3953         }
3954     }
3955     JSHandle<JSTaggedValue> resultValue(thread, result);
3956     return reinterpret_cast<JSValueRef *>(resultValue.GetAddress());
3957 }
3958 
Constructor(const EcmaVM * vm,const Local<JSValueRef> argv[],int32_t length)3959 Local<JSValueRef> FunctionRef::Constructor(const EcmaVM *vm,
3960     const Local<JSValueRef> argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3961     int32_t length)
3962 {
3963     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3964     ecmascript::ThreadManagedScope managedScope(thread);
3965     FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3966     if (!IsFunction(vm)) {
3967         return JSValueRef::Undefined(vm);
3968     }
3969     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
3970     LOG_IF_SPECIAL(func, ERROR);
3971     JSHandle<JSTaggedValue> newTarget = func;
3972     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
3973     EcmaRuntimeCallInfo *info =
3974         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length);
3975     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3976     for (int32_t i = 0; i < length; i++) {
3977         JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
3978 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
3979         thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
3980 #endif
3981         info->SetCallArg(i, arg.GetTaggedValue());
3982     }
3983     JSTaggedValue result = JSFunction::Construct(info);
3984 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
3985     thread->CheckJSTaggedType(result.GetRawData());
3986 #endif
3987     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3988     JSHandle<JSTaggedValue> resultValue(thread, result);
3989     return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
3990 }
3991 
ConstructorOptimize(const EcmaVM * vm,JSValueRef * argv[],int32_t length)3992 JSValueRef* FunctionRef::ConstructorOptimize(const EcmaVM *vm,
3993     JSValueRef* argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3994     int32_t length)
3995 {
3996     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, *JSValueRef::Undefined(vm));
3997     ecmascript::ThreadManagedScope managedScope(thread);
3998     JSTaggedValue result;
3999     FunctionCallScope callScope(EcmaVM::ConstCast(vm));
4000     ASSERT(IsFunction(vm)); // IsFunction check has been done in napi.
4001     {
4002         LocalScope scope(vm);
4003         JSTaggedValue func = *reinterpret_cast<JSTaggedValue*>(this);
4004         JSTaggedValue newTarget = func;
4005         JSTaggedValue undefined = thread->GlobalConstants()->GetUndefined();
4006         EcmaRuntimeCallInfo *info =
4007             ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length);
4008         RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Undefined(vm));
4009         for (int32_t i = 0; i < length; ++i) {
4010             JSTaggedValue arg =
4011                 argv[i] == nullptr ? JSTaggedValue::Undefined() : JSNApiHelper::ToJSTaggedValue(argv[i]);
4012 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
4013                 thread->CheckJSTaggedType(arg.GetRawData());
4014 #endif
4015             info->SetCallArg(i, arg);
4016         }
4017         result = JSFunction::ConstructInternal(info);
4018         RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Undefined(vm));
4019     }
4020 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
4021     thread->CheckJSTaggedType(result.GetRawData());
4022 #endif
4023     JSHandle<JSTaggedValue> resultValue(thread, result);
4024     return reinterpret_cast<JSValueRef*>(resultValue.GetAddress());
4025 }
4026 
GetFunctionPrototype(const EcmaVM * vm)4027 Local<JSValueRef> FunctionRef::GetFunctionPrototype(const EcmaVM *vm)
4028 {
4029     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4030     ecmascript::ThreadManagedScope managedScope(thread);
4031     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
4032     LOG_IF_SPECIAL(func, FATAL);
4033     JSHandle<JSTaggedValue> prototype(thread, JSHandle<JSFunction>(func)->GetFunctionPrototype(thread));
4034     return JSNApiHelper::ToLocal<JSValueRef>(prototype);
4035 }
4036 
Inherit(const EcmaVM * vm,Local<FunctionRef> parent)4037 bool FunctionRef::Inherit(const EcmaVM *vm, Local<FunctionRef> parent)
4038 {
4039     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4040     ecmascript::ThreadManagedScope managedScope(thread);
4041     [[maybe_unused]] LocalScope scope(vm);
4042     JSHandle<JSTaggedValue> parentValue = JSNApiHelper::ToJSHandle(parent);
4043     JSHandle<JSObject> parentHandle = JSHandle<JSObject>::Cast(parentValue);
4044     JSHandle<JSObject> thisHandle = JSHandle<JSObject>::Cast(JSNApiHelper::ToJSHandle(this));
4045     LOG_IF_SPECIAL(thisHandle, ERROR);
4046     // Set this.__proto__ to parent
4047     bool res = JSObject::SetPrototype(thread, thisHandle, parentValue);
4048     if (!res) {
4049         return false;
4050     }
4051     // Set this.Prototype.__proto__ to parent.Prototype
4052     JSHandle<JSTaggedValue> parentPrototype(thread, JSFunction::PrototypeGetter(thread, parentHandle));
4053     JSHandle<JSTaggedValue> thisPrototype(thread, JSFunction::PrototypeGetter(thread, thisHandle));
4054     return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisPrototype), parentPrototype);
4055 }
4056 
SetName(const EcmaVM * vm,Local<StringRef> name)4057 void FunctionRef::SetName(const EcmaVM *vm, Local<StringRef> name)
4058 {
4059     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4060     ecmascript::ThreadManagedScope managedScope(thread);
4061     [[maybe_unused]] LocalScope scope(vm);
4062     JSFunction *func = JSFunction::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject());
4063     JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name);
4064     JSFunction::SetFunctionNameNoPrefix(thread, func, key);
4065 }
4066 
GetName(const EcmaVM * vm)4067 Local<StringRef> FunctionRef::GetName(const EcmaVM *vm)
4068 {
4069     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4070     ecmascript::ThreadManagedScope managedScope(thread);
4071     EscapeLocalScope scope(vm);
4072     JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
4073     JSHandle<JSTaggedValue> name = JSFunctionBase::GetFunctionName(thread, func);
4074     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
4075     return scope.Escape(JSNApiHelper::ToLocal<StringRef>(name));
4076 }
4077 
GetSourceCode(const EcmaVM * vm,int lineNumber)4078 Local<StringRef> FunctionRef::GetSourceCode(const EcmaVM *vm, int lineNumber)
4079 {
4080     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4081     ecmascript::ThreadManagedScope managedScope(thread);
4082     EscapeLocalScope scope(vm);
4083     JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
4084     JSHandle<Method> method(thread, func->GetMethod(thread));
4085     const JSPandaFile *jsPandaFile = method->GetJSPandaFile(thread);
4086     DebugInfoExtractor *debugExtractor = JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile);
4087     ecmascript::CString entry = JSPandaFile::ENTRY_FUNCTION_NAME;
4088     if (!jsPandaFile->IsBundlePack()) {
4089         JSFunction *function = JSFunction::Cast(func.GetTaggedValue().GetTaggedObject());
4090         ecmascript::CString recordName = function->GetRecordName(thread);
4091         ASSERT(!recordName.empty());
4092         entry = recordName;
4093     }
4094 
4095     uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(entry);
4096     JSMutableHandle<JSTaggedValue> sourceCodeHandle(thread, BuiltinsBase::GetTaggedString(thread, ""));
4097     if (mainMethodIndex == 0) {
4098         return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
4099     }
4100 
4101     const std::string &allSourceCode = debugExtractor->GetSourceCode(panda_file::File::EntityId(mainMethodIndex));
4102     std::string sourceCode = StringHelper::GetSpecifiedLine(allSourceCode, lineNumber);
4103     uint32_t codeLen = sourceCode.length();
4104     if (codeLen == 0) {
4105         return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
4106     }
4107 
4108     if (sourceCode[codeLen - 1] == '\r') {
4109         sourceCode = sourceCode.substr(0, codeLen - 1);
4110     }
4111     sourceCodeHandle.Update(BuiltinsBase::GetTaggedString(thread, sourceCode.c_str()));
4112     return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
4113 }
4114 
IsNative(const EcmaVM * vm)4115 bool FunctionRef::IsNative(const EcmaVM *vm)
4116 {
4117     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4118     ecmascript::ThreadManagedScope managedScope(thread);
4119     JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
4120     JSHandle<Method> method(thread, func->GetMethod(thread));
4121     return method->IsNativeWithCallField();
4122 }
4123 
SetData(const EcmaVM * vm,void * data,NativePointerCallback deleter,bool callNapi)4124 void FunctionRef::SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter, [[maybe_unused]] bool callNapi)
4125 {
4126     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4127     ecmascript::ThreadManagedScope managedScope(thread);
4128     JSHandle<JSTaggedValue> funcValue = JSNApiHelper::ToJSHandle(this);
4129     JSHandle<JSFunction> function(funcValue);
4130     if (function->IsJSShared()) {
4131         JSFunction::SetSFunctionExtraInfo(thread, function, nullptr, deleter, data, 0);
4132     } else {
4133         JSFunction::SetFunctionExtraInfo(thread, function, nullptr, deleter, data, 0);
4134     }
4135 }
4136 
GetData(const EcmaVM * vm)4137 void* FunctionRef::GetData(const EcmaVM *vm)
4138 {
4139     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
4140     ecmascript::ThreadManagedScope managedScope(thread);
4141     JSHandle<JSTaggedValue> funcValue = JSNApiHelper::ToJSHandle(this);
4142     JSHandle<JSFunctionBase> function(funcValue);
4143     JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo(thread);
4144     if (!extraInfoValue.IsNativePointer()) {
4145         return nullptr;
4146     }
4147     auto extraInfo = JSNativePointer::Cast(extraInfoValue.GetTaggedObject());
4148     return extraInfo->GetData();
4149 }
4150 
4151 // ----------------------------------- ArrayRef ----------------------------------------
New(const EcmaVM * vm,uint32_t length)4152 Local<ArrayRef> ArrayRef::New(const EcmaVM *vm, uint32_t length)
4153 {
4154     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4155     ecmascript::ThreadManagedScope managedScope(thread);
4156     JSTaggedNumber arrayLen(length);
4157     JSHandle<JSTaggedValue> array = JSArray::ArrayCreate(thread, arrayLen);
4158     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
4159     return JSNApiHelper::ToLocal<ArrayRef>(array);
4160 }
4161 
Length(const EcmaVM * vm)4162 uint32_t ArrayRef::Length(const EcmaVM *vm)
4163 {
4164     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
4165     return JSArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
4166 }
4167 
GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)4168 Local<JSValueRef> ArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
4169 {
4170     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4171     ecmascript::ThreadManagedScope managedScope(thread);
4172     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
4173     JSHandle<JSTaggedValue> result = JSArray::FastGetPropertyByValue(thread, object, index);
4174     return JSNApiHelper::ToLocal<JSValueRef>(result);
4175 }
4176 
SetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)4177 bool ArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
4178 {
4179     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4180     ecmascript::ThreadManagedScope managedScope(thread);
4181     JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
4182     JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
4183     return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle);
4184 }
4185 
4186 // ----------------------------------- SendableArrayRef ----------------------------------------
New(const EcmaVM * vm,uint32_t length)4187 Local<SendableArrayRef> SendableArrayRef::New(const EcmaVM *vm, uint32_t length)
4188 {
4189     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4190     ecmascript::ThreadManagedScope managedScope(thread);
4191     JSTaggedNumber arrayLen(length);
4192     JSHandle<JSTaggedValue> array = ecmascript::JSSharedArray::ArrayCreate(thread, arrayLen);
4193     JSHandle<JSTaggedValue> initialValue(thread, JSTaggedValue::Undefined());
4194     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
4195     for (uint32_t i = 0; i < length; i++) {
4196         key.Update(JSTaggedValue(i));
4197         JSObject::CreateDataPropertyOrThrow(
4198             thread, JSHandle<JSObject>(array), key, initialValue, ecmascript::JSShared::SCheckMode::SKIP);
4199     }
4200     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
4201     return JSNApiHelper::ToLocal<SendableArrayRef>(array);
4202 }
4203 
Length(const EcmaVM * vm)4204 uint32_t SendableArrayRef::Length(const EcmaVM *vm)
4205 {
4206     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
4207     ecmascript::ThreadManagedScope managedScope(thread);
4208     return ecmascript::JSSharedArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
4209 }
4210 
GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)4211 Local<JSValueRef> SendableArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
4212 {
4213     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
4214     ecmascript::ThreadManagedScope managedScope(thread);
4215     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
4216     // Add Concurrent check for shared array
4217     [[maybe_unused]] ecmascript::ConcurrentApiScope<ecmascript::JSSharedArray> scope(thread, object);
4218     JSHandle<JSTaggedValue> result = ecmascript::JSSharedArray::FastGetPropertyByValue(thread, object, index);
4219     return JSNApiHelper::ToLocal<JSValueRef>(result);
4220 }
4221 
SetProperty(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)4222 bool SendableArrayRef::SetProperty(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
4223 {
4224     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4225     ecmascript::ThreadManagedScope managedScope(thread);
4226     JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
4227     JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
4228     return ecmascript::JSSharedArray::SetProperty(
4229         thread, objectHandle, index, valueHandle, true, ecmascript::SCheckMode::CHECK);
4230 }
4231 
4232 // ---------------------------------- Error ---------------------------------------
4233 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
4234 #define EXCEPTION_ERROR_NEW(name, type)                                                                 \
4235     Local<JSValueRef> Exception::name(const EcmaVM *vm, Local<StringRef> message)                       \
4236     {                                                                                                   \
4237         CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));                    \
4238         ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());                                 \
4239         ObjectFactory *factory = vm->GetFactory();                                                      \
4240                                                                                                         \
4241         JSHandle<EcmaString> messageValue(JSNApiHelper::ToJSHandle(message));                           \
4242         JSHandle<JSTaggedValue> result(factory->NewJSError(ErrorType::type,                             \
4243                                                            messageValue, ecmascript::StackCheck::NO));  \
4244         return JSNApiHelper::ToLocal<JSValueRef>(result);                                               \
4245     }
4246 
EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)4247 EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)
4248 
4249 #undef EXCEPTION_ERROR_NEW
4250 // ---------------------------------- Error ---------------------------------------
4251 
4252 // ---------------------------------- FunctionCallScope ---------------------------------------
4253 FunctionCallScope::FunctionCallScope(EcmaVM *vm) : vm_(vm)
4254 {
4255     vm_->IncreaseCallDepth();
4256 }
4257 
~FunctionCallScope()4258 FunctionCallScope::~FunctionCallScope()
4259 {
4260     vm_->DecreaseCallDepth();
4261     if (vm_->IsTopLevelCallDepth()) {
4262         ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread());
4263         vm_->ExecutePromisePendingJob();
4264     }
4265 }
4266 
4267 // -------------------------------------  JSExecutionScope ------------------------------
JSExecutionScope(const EcmaVM * vm)4268 JSExecutionScope::JSExecutionScope([[maybe_unused]] const EcmaVM *vm)
4269 {
4270 }
4271 
~JSExecutionScope()4272 JSExecutionScope::~JSExecutionScope()
4273 {
4274     lastCurrentThread_ = nullptr;
4275     isRevert_ = false;
4276 }
4277 
4278 // ------------------------------------ JsiNativeScope -----------------------------------------------
4279 
JsiNativeScope(const EcmaVM * vm)4280 JsiNativeScope::JsiNativeScope(const EcmaVM *vm)
4281 {
4282     thread_ = vm->GetAssociatedJSThread();
4283 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
4284     if (vm->IsCollectingScopeLockStats()) {
4285         const_cast<EcmaVM*>(vm)->IncreaseEnterJsiNativeScopeCount();
4286         const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
4287     }
4288 #endif
4289     if (LIKELY(!vm->IsEnableCMCGC())) {
4290         oldThreadState_ = static_cast<uint16_t>(thread_->TransferToNonRunning(ecmascript::ThreadState::NATIVE));
4291         hasSwitchState_ = oldThreadState_ != static_cast<uint16_t>(ecmascript::ThreadState::NATIVE);
4292     } else {
4293         isEnableCMCGC_ = true;
4294         hasSwitchState_ = thread_->GetThreadHolder()->TransferToNativeIfInRunning();
4295     }
4296 }
4297 
~JsiNativeScope()4298 JsiNativeScope::~JsiNativeScope()
4299 {
4300     if (hasSwitchState_) {
4301         if (LIKELY(!isEnableCMCGC_)) {
4302             thread_->TransferInNonRunning(static_cast<ecmascript::ThreadState>(oldThreadState_));
4303         } else {
4304             thread_->GetThreadHolder()->TransferToRunning();
4305         }
4306     }
4307 }
4308 
4309 // ------------------------------------ JsiFastNativeScope -----------------------------------------------
4310 
JsiFastNativeScope(const EcmaVM * vm)4311 JsiFastNativeScope::JsiFastNativeScope(const EcmaVM *vm)
4312 {
4313     thread_ = vm->GetAssociatedJSThread();
4314 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
4315     if (vm->IsCollectingScopeLockStats()) {
4316         const_cast<EcmaVM*>(vm)->IncreaseEnterFastNativeScopeCount();
4317         const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
4318     }
4319 #endif
4320     if (LIKELY(!vm->IsEnableCMCGC())) {
4321         oldThreadState_ = static_cast<uint16_t>(thread_->TransferToRunningIfNonRunning());
4322         hasSwitchState_ = oldThreadState_ != static_cast<uint16_t>(ecmascript::ThreadState::RUNNING);
4323     } else {
4324         isEnableCMCGC_ = true;
4325         hasSwitchState_ = thread_->GetThreadHolder()->TransferToRunningIfInNative();
4326     }
4327 }
4328 
~JsiFastNativeScope()4329 JsiFastNativeScope::~JsiFastNativeScope()
4330 {
4331     if (hasSwitchState_) {
4332         if (LIKELY(!isEnableCMCGC_)) {
4333             thread_->TransferToNonRunningInRunning(static_cast<ecmascript::ThreadState>(oldThreadState_));
4334         } else {
4335             thread_->GetThreadHolder()->TransferToNative();
4336         }
4337     }
4338 }
4339 
4340 // ------------------------------------ JsiRuntimeCallInfo -----------------------------------------------
GetData()4341 void *JsiRuntimeCallInfo::GetData()
4342 {
4343     ecmascript::ThreadManagedScope managedScope(thread_);
4344     JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(reinterpret_cast<EcmaRuntimeCallInfo *>(this));
4345     if (!constructor->IsJSFunction()) {
4346         return nullptr;
4347     }
4348     JSHandle<JSFunctionBase> function(constructor);
4349     JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo(thread_);
4350     if (!extraInfoValue.IsJSNativePointer()) {
4351         return nullptr;
4352     }
4353     return JSNativePointer::Cast(extraInfoValue.GetTaggedObject())->GetData();
4354 }
4355 
GetVM() const4356 EcmaVM *JsiRuntimeCallInfo::GetVM() const
4357 {
4358     return thread_->GetEcmaVM();
4359 }
4360 
4361 // ---------------------------------------JSNApi-------------------------------------------
LoadPatch(EcmaVM * vm,const std::string & patchFileName,const std::string & baseFileName)4362 PatchErrorCode JSNApi::LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName)
4363 {
4364     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
4365     ecmascript::ThreadManagedScope managedScope(thread);
4366     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
4367     return quickFixManager->LoadPatch(thread, patchFileName, baseFileName);
4368 }
4369 
LoadPatch(EcmaVM * vm,const std::string & patchFileName,uint8_t * patchBuffer,size_t patchSize,const std::string & baseFileName,uint8_t * baseBuffer,size_t baseSize)4370 PatchErrorCode JSNApi::LoadPatch(EcmaVM *vm,
4371                                  const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize,
4372                                  const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize)
4373 {
4374     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
4375     ecmascript::ThreadManagedScope managedScope(thread);
4376     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
4377     return quickFixManager->LoadPatch(
4378         thread, patchFileName, patchBuffer, patchSize, baseFileName, baseBuffer, baseSize);
4379 }
4380 
UnloadPatch(EcmaVM * vm,const std::string & patchFileName)4381 PatchErrorCode JSNApi::UnloadPatch(EcmaVM *vm, const std::string &patchFileName)
4382 {
4383     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
4384     ecmascript::ThreadManagedScope managedScope(thread);
4385     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
4386     return quickFixManager->UnloadPatch(thread, patchFileName);
4387 }
4388 
4389 /*
4390  * check whether the exception is caused by quickfix methods.
4391  */
IsQuickFixCausedException(EcmaVM * vm,Local<ObjectRef> exception,const std::string & patchFileName)4392 bool JSNApi::IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName)
4393 {
4394     if (exception.IsEmpty()) {
4395         return false;
4396     }
4397     CROSS_THREAD_CHECK(vm);
4398     ecmascript::ThreadManagedScope managedScope(thread);
4399     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
4400     JSHandle<JSTaggedValue> exceptionInfo = JSNApiHelper::ToJSHandle(exception);
4401     return quickFixManager->IsQuickFixCausedException(thread, exceptionInfo, patchFileName);
4402 }
4403 
4404 /*
4405  * register quickfix query function.
4406  */
RegisterQuickFixQueryFunc(EcmaVM * vm,std::function<bool (std::string baseFileName,std::string & patchFileName,uint8_t ** patchBuffer,size_t & patchSize)> callBack)4407 void JSNApi::RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName,
4408                         std::string &patchFileName,
4409                         uint8_t **patchBuffer,
4410                         size_t &patchSize)> callBack)
4411 {
4412     CROSS_THREAD_CHECK(vm);
4413     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
4414     quickFixManager->RegisterQuickFixQueryFunc(callBack);
4415 }
4416 
IsBundle(EcmaVM * vm)4417 bool JSNApi::IsBundle(EcmaVM *vm)
4418 {
4419     return vm->IsBundlePack();
4420 }
4421 
SetBundle(EcmaVM * vm,bool value)4422 void JSNApi::SetBundle(EcmaVM *vm, bool value)
4423 {
4424     vm->SetIsBundlePack(value);
4425 }
4426 
IsNormalizedOhmUrlPack(EcmaVM * vm)4427 bool JSNApi::IsNormalizedOhmUrlPack(EcmaVM *vm)
4428 {
4429     return vm->IsNormalizedOhmUrlPack();
4430 }
4431 
IsOhmUrl(const std::string & srcName)4432 bool JSNApi::IsOhmUrl(const std::string &srcName)
4433 {
4434     return ModulePathHelper::IsOhmUrl(srcName.c_str());
4435 }
4436 
SetModuleInfo(EcmaVM * vm,const std::string & assetPath,const std::string & entryPoint)4437 void JSNApi::SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint)
4438 {
4439     SetAssetPath(vm, assetPath);
4440     size_t pos = entryPoint.find_first_of("/");
4441     if (pos != std::string::npos) {
4442         SetBundleName(vm, entryPoint.substr(0, pos));
4443         ecmascript::CString moduleName = ModulePathHelper::GetModuleName(entryPoint.c_str());
4444         if (!moduleName.empty()) {
4445             SetModuleName(vm, moduleName.c_str());
4446             return;
4447         }
4448     }
4449     std::string errmsg = "SetModuleInfo: entryPoint:" + entryPoint + "is invalid.";
4450     LOG_ECMA(ERROR) << errmsg;
4451     Local<StringRef> message = StringRef::NewFromUtf8(vm, errmsg.c_str());
4452     Local<JSValueRef> error = Exception::Error(vm, message);
4453     JSNApi::ThrowException(vm, error);
4454 }
4455 
4456 // note: The function SetAssetPath is a generic interface for previewing and physical machines.
SetAssetPath(EcmaVM * vm,const std::string & assetPath)4457 void JSNApi::SetAssetPath(EcmaVM *vm, const std::string &assetPath)
4458 {
4459     ecmascript::CString path = assetPath.c_str();
4460     // check input assetPath
4461 #if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
4462     if (!ModulePathHelper::ValidateAbcPath(path, ecmascript::ValidateFilePath::ABC)) {
4463         LOG_FULL(FATAL) << "Invalid input assetPath: " << assetPath.c_str();
4464     }
4465 #endif
4466     vm->SetAssetPath(path);
4467 }
4468 
SetLoop(EcmaVM * vm,void * loop)4469 void JSNApi::SetLoop(EcmaVM *vm, void *loop)
4470 {
4471     vm->SetLoop(loop);
4472 }
4473 
SetWeakFinalizeTaskCallback(EcmaVM * vm,const WeakFinalizeTaskCallback & callback)4474 void JSNApi::SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback)
4475 {
4476     vm->GetAssociatedJSThread()->SetWeakFinalizeTaskCallback(callback);
4477 }
4478 
SetAsyncCleanTaskCallback(EcmaVM * vm,const NativePointerTaskCallback & callback)4479 void JSNApi::SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback)
4480 {
4481     vm->GetAssociatedJSThread()->SetAsyncCleanTaskCallback(callback);
4482 }
4483 
SetTriggerGCTaskCallback(EcmaVM * vm,const TriggerGCTaskCallback & callback)4484 void JSNApi::SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback)
4485 {
4486     vm->GetHeap()->GetIdleGCTrigger()->SetTriggerGCTaskCallback(callback);
4487 }
4488 
GetAssetPath(EcmaVM * vm)4489 std::string JSNApi::GetAssetPath(EcmaVM *vm)
4490 {
4491     return vm->GetAssetPath().c_str();
4492 }
4493 
SetMockModuleList(EcmaVM * vm,const std::map<std::string,std::string> & list)4494 void JSNApi::SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4495 {
4496     vm->SetMockModuleList(list);
4497 }
4498 
SetHmsModuleList(EcmaVM * vm,const std::vector<panda::HmsMap> & list)4499 void JSNApi::SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list)
4500 {
4501     vm->SetHmsModuleList(list);
4502 }
4503 
SetPkgAliasList(EcmaVM * vm,const std::map<std::string,std::string> & list)4504 void JSNApi::SetPkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4505 {
4506     ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgAliasList;
4507     for (auto it = list.begin(); it != list.end(); ++it) {
4508         pkgAliasList.emplace(it->first.c_str(), it->second.c_str());
4509     }
4510     vm->SetPkgAliasList(pkgAliasList);
4511 }
4512 
UpdatePkgAliasList(EcmaVM * vm,const std::map<std::string,std::string> & list)4513 void JSNApi::UpdatePkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4514 {
4515     ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgAliasList;
4516     for (auto &[alias, pkgName]: list) {
4517         pkgAliasList.emplace(alias, pkgName);
4518     }
4519     vm->UpdatePkgAliasList(pkgAliasList);
4520     ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();
4521     for (auto &[workerId, workerVm]: workerList) {
4522         workerVm->UpdatePkgAliasList(pkgAliasList);
4523     }
4524 }
4525 
SetPkgNameList(EcmaVM * vm,const std::map<std::string,std::string> & list)4526 void JSNApi::SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4527 {
4528     ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgNameList;
4529     for (auto it = list.begin(); it != list.end(); ++it) {
4530         pkgNameList.emplace(it->first.c_str(), it->second.c_str());
4531     }
4532     vm->SetPkgNameList(pkgNameList);
4533 }
4534 
UpdatePkgNameList(EcmaVM * vm,const std::map<std::string,std::string> & list)4535 void JSNApi::UpdatePkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4536 {
4537     ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgNameList;
4538     for (auto &[moduleName, pkgName]: list) {
4539         pkgNameList.emplace(moduleName, pkgName);
4540     }
4541     vm->UpdatePkgNameList(pkgNameList);
4542     ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();
4543     for (auto &[workerId, workerVm]: workerList) {
4544         workerVm->UpdatePkgNameList(pkgNameList);
4545     }
4546 }
4547 
GetPkgName(EcmaVM * vm,const std::string & moduleName)4548 std::string JSNApi::GetPkgName(EcmaVM *vm, const std::string &moduleName)
4549 {
4550     return vm->GetPkgName(moduleName.c_str()).c_str();
4551 }
4552 
SetpkgContextInfoList(EcmaVM * vm,const std::map<std::string,std::vector<std::vector<std::string>>> & list)4553 void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
4554     std::vector<std::vector<std::string>>> &list)
4555 {
4556     ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
4557         ecmascript::CVector<ecmascript::CString>>> pkgContextInfoList;
4558     for (auto it = list.begin(); it != list.end(); it++) {
4559         const std::vector<std::vector<std::string>> vec = it->second;
4560         ecmascript::CMap<ecmascript::CString, ecmascript::CVector<ecmascript::CString>> map;
4561         for (size_t i = 0; i < vec.size(); i++) {
4562             ecmascript::CString pkgName = vec[i][0].c_str();
4563             ecmascript::CVector<ecmascript::CString> pkgContextInfo;
4564             for (size_t j = 1; j < vec[i].size(); j++) {
4565                 pkgContextInfo.emplace_back(vec[i][j].c_str());
4566             }
4567             map.emplace(pkgName, pkgContextInfo);
4568         }
4569         pkgContextInfoList.emplace(it->first.c_str(), map);
4570     }
4571     vm->SetpkgContextInfoList(pkgContextInfoList);
4572 }
4573 
UpdatePkgContextInfoList(EcmaVM * vm,const std::map<std::string,std::vector<std::vector<std::string>>> & list)4574 void JSNApi::UpdatePkgContextInfoList(EcmaVM *vm,
4575     const std::map<std::string, std::vector<std::vector<std::string>>> &list)
4576 {
4577     ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
4578         ecmascript::CVector<ecmascript::CString>>> pkgContextInfoList;
4579     for (auto &[moduleName, pkgContextInfos]: list) {
4580         ecmascript::CMap<ecmascript::CString, ecmascript::CVector<ecmascript::CString>> map;
4581         for (auto &datas: pkgContextInfos) {
4582             if (datas.empty()) {
4583                 continue;
4584             }
4585             ecmascript::CString pkgName = datas[0].c_str();
4586             ecmascript::CVector<ecmascript::CString> pkgContextInfo;
4587             for (size_t i = 1; i < datas.size(); i++) {
4588                 pkgContextInfo.emplace_back(datas[i].c_str());
4589             }
4590             map.emplace(pkgName, pkgContextInfo);
4591         }
4592         pkgContextInfoList.emplace(moduleName, map);
4593     }
4594     vm->UpdatePkgContextInfoList(pkgContextInfoList);
4595 
4596     ecmascript::CMap<uint32_t, EcmaVM *> workerList = vm->GetWorkList();
4597     for (auto &[workerId, workerVm]: workerList) {
4598         workerVm->UpdatePkgContextInfoList(pkgContextInfoList);
4599     }
4600 }
4601 // Only used for env created by napi to set module execution mode
SetExecuteBufferMode(const EcmaVM * vm)4602 void JSNApi::SetExecuteBufferMode(const EcmaVM *vm)
4603 {
4604     ecmascript::ModuleManager *moduleManager =
4605         vm->GetAssociatedJSThread()->GetModuleManager();
4606     moduleManager->SetExecuteMode(ecmascript::ModuleExecuteMode::ExecuteBufferMode);
4607 }
4608 
SetStopPreLoadSoCallback(EcmaVM * vm,const StopPreLoadSoCallback & callback)4609 void JSNApi::SetStopPreLoadSoCallback(EcmaVM *vm, const StopPreLoadSoCallback &callback)
4610 {
4611     vm->AddStopPreLoadCallback(callback);
4612 }
4613 
InitForConcurrentThread(EcmaVM * vm,ConcurrentCallback cb,void * data)4614 bool JSNApi::InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data)
4615 {
4616     vm->SetConcurrentCallback(cb, data);
4617 
4618     return true;
4619 }
4620 
InitForConcurrentFunction(EcmaVM * vm,Local<JSValueRef> function,void * taskInfo)4621 bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function, void *taskInfo)
4622 {
4623     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4624     ecmascript::ThreadManagedScope managedScope(thread);
4625     [[maybe_unused]] LocalScope scope(vm);
4626     JSHandle<JSTaggedValue> funcVal = JSNApiHelper::ToJSHandle(function);
4627     JSHandle<JSFunction> transFunc = JSHandle<JSFunction>::Cast(funcVal);
4628     if (transFunc->GetFunctionKind(thread) != ecmascript::FunctionKind::CONCURRENT_FUNCTION) {
4629         LOG_ECMA(ERROR) << "Function is not concurrent";
4630         return false;
4631     }
4632     JSFunction::SetFunctionExtraInfo(thread, transFunc, nullptr, nullptr, taskInfo);
4633     transFunc->SetTaskConcurrentFuncFlag(1); // 1 : concurrent function flag
4634     thread->SetTaskInfo(reinterpret_cast<uintptr_t>(taskInfo));
4635     thread->SetIsInConcurrentScope(true);
4636     return true;
4637 }
4638 
GetCurrentTaskInfo(const EcmaVM * vm)4639 void* JSNApi::GetCurrentTaskInfo(const EcmaVM *vm)
4640 {
4641     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
4642     return reinterpret_cast<void*>(thread->GetTaskInfo());
4643 }
4644 
ClearCurrentTaskInfo(const EcmaVM * vm)4645 void JSNApi::ClearCurrentTaskInfo(const EcmaVM *vm)
4646 {
4647     JSThread *thread = vm->GetJSThread();
4648     thread->SetTaskInfo(reinterpret_cast<uintptr_t>(nullptr));
4649     thread->SetIsInConcurrentScope(false);
4650 }
4651 
SetLargeHeap(bool isLargeHeap)4652 void JSNApi::SetLargeHeap(bool isLargeHeap)
4653 {
4654     LOG_ECMA(DEBUG) << "Set large heap: " << isLargeHeap;
4655     auto instance = ecmascript::Runtime::GetInstance();
4656     ASSERT(instance != nullptr);
4657     instance->SetEnableLargeHeap(isLargeHeap);
4658 }
4659 
SetBundleName(EcmaVM * vm,const std::string & bundleName)4660 void JSNApi::SetBundleName(EcmaVM *vm, const std::string &bundleName)
4661 {
4662     ecmascript::CString name = bundleName.c_str();
4663     vm->SetBundleName(name);
4664 }
4665 
GetBundleName(EcmaVM * vm)4666 std::string JSNApi::GetBundleName(EcmaVM *vm)
4667 {
4668     return vm->GetBundleName().c_str();
4669 }
4670 
SetModuleName(EcmaVM * vm,const std::string & moduleName)4671 void JSNApi::SetModuleName(EcmaVM *vm, const std::string &moduleName)
4672 {
4673     ecmascript::CString name = moduleName.c_str();
4674     ecmascript::pgo::PGOProfilerManager::GetInstance()->SetModuleName(moduleName);
4675     vm->SetModuleName(name);
4676 }
4677 
GetModuleName(EcmaVM * vm)4678 std::string JSNApi::GetModuleName(EcmaVM *vm)
4679 {
4680     return vm->GetModuleName().c_str();
4681 }
4682 
GetCurrentModuleInfo(EcmaVM * vm,bool needRecordName)4683 std::pair<std::string, std::string> JSNApi::GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName)
4684 {
4685     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4686     return vm->GetCurrentModuleInfo(needRecordName);
4687 }
4688 
NormalizePath(const std::string & string)4689 std::string JSNApi::NormalizePath(const std::string &string)
4690 {
4691     return PathHelper::NormalizePath(string.c_str()).c_str();
4692 }
4693 
4694 // Enable cross thread execution.
AllowCrossThreadExecution(EcmaVM * vm)4695 void JSNApi::AllowCrossThreadExecution(EcmaVM *vm)
4696 {
4697     LOG_ECMA(WARN) << "enable cross thread execution";
4698     vm->GetAssociatedJSThread()->EnableCrossThreadExecution();
4699 }
4700 
4701 // Enable cross thread execution except in gc process.
CheckAndSetAllowCrossThreadExecution(EcmaVM * vm)4702 bool JSNApi::CheckAndSetAllowCrossThreadExecution(EcmaVM *vm)
4703 {
4704     if (ecmascript::g_isEnableCMCGC) {
4705         return false;
4706     } else {
4707         if (vm->GetHeap()->InGC() || SharedHeap::GetInstance()->InGC()) {
4708             return false;
4709         }
4710         LOG_ECMA(WARN) << "enable cross thread execution when not in gc process";
4711         vm->GetAssociatedJSThread()->EnableCrossThreadExecution();
4712         return true;
4713     }
4714 }
4715 
GetEnv(EcmaVM * vm)4716 void* JSNApi::GetEnv(EcmaVM *vm)
4717 {
4718     JSThread *thread = vm->GetJSThread();
4719     return thread->GetEnv();
4720 }
4721 
SetEnv(EcmaVM * vm,void * env)4722 void JSNApi::SetEnv(EcmaVM *vm, void *env)
4723 {
4724     JSThread *thread = vm->GetJSThread();
4725     thread->SetEnv(env);
4726 }
4727 
SynchronizVMInfo(EcmaVM * vm,const EcmaVM * hostVM)4728 void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM)
4729 {
4730     std::atomic_thread_fence(std::memory_order_seq_cst);
4731     vm->SetBundleName(hostVM->GetBundleName());
4732     vm->SetModuleName(hostVM->GetModuleName());
4733     vm->SetAssetPath(hostVM->GetAssetPath());
4734     vm->SetIsBundlePack(hostVM->IsBundlePack());
4735     vm->SetPkgNameList(const_cast<EcmaVM *>(hostVM)->GetPkgNameList());
4736     vm->SetPkgAliasList(const_cast<EcmaVM *>(hostVM)->GetPkgAliasList());
4737     vm->SetpkgContextInfoList(const_cast<EcmaVM *>(hostVM)->GetPkgContextInfoList());
4738 
4739     ecmascript::ModuleManager *vmModuleManager =
4740         vm->GetAssociatedJSThread()->GetModuleManager();
4741     ecmascript::ModuleManager *hostVMModuleManager =
4742         hostVM->GetAssociatedJSThread()->GetModuleManager();
4743     vmModuleManager->SetExecuteMode(hostVMModuleManager->GetExecuteMode());
4744     vm->SetResolveBufferCallback(hostVM->GetResolveBufferCallback());
4745     vm->SetResolveBufferCallbackForHybridApp(hostVM->GetResolveBufferCallbackForHybridApp());
4746 }
4747 
IsProfiling(EcmaVM * vm)4748 bool JSNApi::IsProfiling(EcmaVM *vm)
4749 {
4750     return vm->GetProfilerState();
4751 }
4752 
SetProfilerState(const EcmaVM * vm,bool value)4753 void JSNApi::SetProfilerState(const EcmaVM *vm, bool value)
4754 {
4755     const_cast<EcmaVM*>(vm)->SetProfilerState(value);
4756 }
4757 
SetSourceMapTranslateCallback(EcmaVM * vm,SourceMapTranslateCallback callback)4758 void JSNApi::SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback callback)
4759 {
4760     vm->SetSourceMapTranslateCallback(callback);
4761 }
4762 
SetSourceMapCallback(EcmaVM * vm,SourceMapCallback callback)4763 void JSNApi::SetSourceMapCallback(EcmaVM *vm, SourceMapCallback callback)
4764 {
4765     vm->SetSourceMapCallback(callback);
4766 }
4767 
GetStackBeforeCallNapiSuccess(EcmaVM * vm,bool & getStackBeforeCallNapiSuccess)4768 void JSNApi::GetStackBeforeCallNapiSuccess([[maybe_unused]] EcmaVM *vm,
4769                                            [[maybe_unused]] bool &getStackBeforeCallNapiSuccess)
4770 {
4771 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
4772     JSThread *thread = vm->GetJSThread();
4773     if (thread->GetIsProfiling()) {
4774         ecmascript::ThreadManagedScope managedScope(thread);
4775         getStackBeforeCallNapiSuccess = vm->GetProfiler()->GetStackBeforeCallNapi(thread);
4776     }
4777 #endif
4778 }
4779 
GetStackAfterCallNapi(EcmaVM * vm)4780 void JSNApi::GetStackAfterCallNapi([[maybe_unused]] EcmaVM *vm)
4781 {
4782 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
4783     JSThread *thread = vm->GetJSThread();
4784     if (thread->GetIsProfiling()) {
4785         ecmascript::ThreadManagedScope managedScope(thread);
4786         vm->GetProfiler()->GetStackAfterCallNapi(thread);
4787     }
4788 #endif
4789 }
4790 
CreateJSVM(const RuntimeOption & option)4791 EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
4792 {
4793     JSRuntimeOptions runtimeOptions;
4794     runtimeOptions.SetArkProperties(option.GetArkProperties());
4795     runtimeOptions.SetMemConfigProperty(option.GetMemConfigProperty());
4796     runtimeOptions.SetArkBundleName(option.GetArkBundleName());
4797     runtimeOptions.SetLongPauseTime(option.GetLongPauseTime());
4798     runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
4799     runtimeOptions.SetIsWorker(option.GetIsWorker());
4800     runtimeOptions.SetIsRestrictedWorker(option.GetIsRestrictedWorker());
4801 // Disable the asm-interpreter of ark-engine for ios-platform temporarily.
4802 #if !defined(PANDA_TARGET_IOS)
4803     // asmInterpreter
4804     runtimeOptions.SetEnableAsmInterpreter(option.GetEnableAsmInterpreter());
4805 #else
4806     runtimeOptions.SetEnableAsmInterpreter(false);
4807 #endif
4808     runtimeOptions.SetEnableBuiltinsLazy(option.GetEnableBuiltinsLazy());
4809     runtimeOptions.SetAsmOpcodeDisableRange(option.GetAsmOpcodeDisableRange());
4810     // aot
4811     runtimeOptions.SetEnableAOT(option.GetEnableAOT());
4812     runtimeOptions.SetEnablePGOProfiler(option.GetEnableProfile());
4813     runtimeOptions.SetPGOProfilerPath(option.GetProfileDir());
4814     // Dfx
4815     runtimeOptions.SetLogLevel(common::Log::LevelToString(common::Log::ConvertFromRuntime(option.GetLogLevel())));
4816     runtimeOptions.SetEnableArkTools(option.GetEnableArkTools());
4817     runtimeOptions.SetLargeHeap(option.GetLargeHeap());
4818     return CreateEcmaVM(runtimeOptions);
4819 }
4820 
CreateEcmaVM(const JSRuntimeOptions & options)4821 EcmaVM *JSNApi::CreateEcmaVM(const JSRuntimeOptions &options)
4822 {
4823     return EcmaVM::Create(options);
4824 }
4825 
DestroyJSVM(EcmaVM * ecmaVm)4826 void JSNApi::DestroyJSVM(EcmaVM *ecmaVm)
4827 {
4828     if (UNLIKELY(ecmaVm == nullptr)) {
4829         return;
4830     }
4831     ecmaVm->GetJSThread()->ManagedCodeBegin();
4832     EcmaVM::Destroy(ecmaVm);
4833 }
4834 
IgnoreFinalizeCallback(EcmaVM * ecmaVm)4835 void JSNApi::IgnoreFinalizeCallback(EcmaVM *ecmaVm)
4836 {
4837     CROSS_THREAD_CHECK(ecmaVm);
4838     ecmascript::ThreadManagedScope scope(thread);
4839     if (ecmascript::g_isEnableCMCGC) {
4840         thread->IgnoreFinalizeCallback();
4841     }
4842 }
4843 
RegisterUncatchableErrorHandler(EcmaVM * ecmaVm,const UncatchableErrorHandler & handler)4844 void JSNApi::RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler)
4845 {
4846     ecmaVm->RegisterUncatchableErrorHandler(handler);
4847 }
4848 
TriggerGC(const EcmaVM * vm,TRIGGER_GC_TYPE gcType)4849 void JSNApi::TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType)
4850 {
4851     TriggerGC(vm, ecmascript::GCReason::EXTERNAL_TRIGGER, gcType);
4852 }
4853 
TriggerGC(const EcmaVM * vm,ecmascript::GCReason reason,TRIGGER_GC_TYPE gcType)4854 void JSNApi::TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason, TRIGGER_GC_TYPE gcType)
4855 {
4856     CROSS_THREAD_CHECK(vm);
4857     ecmascript::ThreadManagedScope managedScope(thread);
4858     if (thread != nullptr && vm->IsInitialized()) {
4859 #if defined(ENABLE_EXCEPTION_BACKTRACE)
4860         if (thread->IsMainThreadFast()) {
4861             LOG_ECMA(INFO) << "JSNApi::TriggerGC gcType: " << static_cast<int>(gcType);
4862             std::ostringstream stack;
4863             ecmascript::Backtrace(stack, true);
4864             LOG_ECMA(INFO) << stack.str();
4865         }
4866 #endif
4867         if (ecmascript::g_isEnableCMCGC) {
4868             common::GCReason cmcReason = common::GC_REASON_USER;
4869             bool async = true;
4870             if (gcType == TRIGGER_GC_TYPE::FULL_GC || gcType == TRIGGER_GC_TYPE::SHARED_FULL_GC ||
4871                 reason == ecmascript::GCReason::ALLOCATION_FAILED) {
4872                 cmcReason = common::GC_REASON_BACKUP;
4873                 async = false;
4874             }
4875             common::BaseRuntime::RequestGC(cmcReason, async, common::GC_TYPE_FULL);
4876         } else {
4877             auto sHeap = ecmascript::SharedHeap::GetInstance();
4878             switch (gcType) {
4879                 case TRIGGER_GC_TYPE::SEMI_GC:
4880                     vm->CollectGarbage(vm->GetHeap()->SelectGCType(), reason);
4881                     break;
4882                 case TRIGGER_GC_TYPE::OLD_GC:
4883                     vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC, reason);
4884                     break;
4885                 case TRIGGER_GC_TYPE::FULL_GC:
4886                     vm->CollectGarbage(ecmascript::TriggerGCType::FULL_GC, reason);
4887                     break;
4888                 case TRIGGER_GC_TYPE::SHARED_GC:
4889                     sHeap->CollectGarbage<ecmascript::TriggerGCType::SHARED_GC,
4890                         ecmascript::GCReason::EXTERNAL_TRIGGER>(thread);
4891                     break;
4892                 case TRIGGER_GC_TYPE::SHARED_FULL_GC:
4893                     sHeap->CollectGarbage<ecmascript::TriggerGCType::SHARED_FULL_GC,
4894                         ecmascript::GCReason::EXTERNAL_TRIGGER>(thread);
4895                     break;
4896                 default:
4897                     break;
4898             }
4899         }
4900     }
4901 }
4902 
HintGC(const EcmaVM * vm,MemoryReduceDegree degree,ecmascript::GCReason reason)4903 void JSNApi::HintGC(const EcmaVM *vm, MemoryReduceDegree degree, ecmascript::GCReason reason)
4904 {
4905     CROSS_THREAD_CHECK(vm);
4906     ecmascript::ThreadManagedScope managedScope(thread);
4907     if (thread != nullptr && vm->IsInitialized()) {
4908         const_cast<ecmascript::Heap *>(vm->GetHeap())->CheckAndTriggerHintGC(degree, reason);
4909     }
4910 }
4911 
TriggerIdleGC(const EcmaVM * vm,TRIGGER_IDLE_GC_TYPE gcType)4912 void JSNApi::TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType)
4913 {
4914     CROSS_THREAD_CHECK(vm);
4915     if (thread != nullptr && vm->IsInitialized()) {
4916         ecmascript::ThreadManagedScope managedScope(thread);
4917         vm->GetHeap()->GetIdleGCTrigger()->TryTriggerIdleGC(gcType);
4918     }
4919 }
4920 
SetStartIdleMonitorCallback(const StartIdleMonitorCallback & callback)4921 void JSNApi::SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback)
4922 {
4923     startIdleMonitorCallback_ = callback;
4924 }
4925 
GetStartIdleMonitorCallback()4926 StartIdleMonitorCallback JSNApi::GetStartIdleMonitorCallback()
4927 {
4928     return startIdleMonitorCallback_;
4929 }
4930 
ThrowException(const EcmaVM * vm,Local<JSValueRef> error)4931 void JSNApi::ThrowException(const EcmaVM *vm, Local<JSValueRef> error)
4932 {
4933     auto thread = vm->GetJSThread();
4934     ecmascript::ThreadManagedScope managedScope(thread);
4935     if (thread->HasPendingException()) {
4936         LOG_ECMA(DEBUG) << "An exception has already occurred before, keep old exception here.";
4937         return;
4938     }
4939     thread->SetException(JSNApiHelper::ToJSTaggedValue(*error));
4940 }
4941 
PrintExceptionInfo(const EcmaVM * vm)4942 void JSNApi::PrintExceptionInfo(const EcmaVM *vm)
4943 {
4944     JSThread* thread = vm->GetJSThread();
4945     ecmascript::ThreadManagedScope managedScope(thread);
4946     [[maybe_unused]] ecmascript::EcmaHandleScope handleScope(thread);
4947 
4948     if (!HasPendingException(vm)) {
4949         return;
4950     }
4951     Local<ObjectRef> exception = GetAndClearUncaughtException(vm);
4952     JSHandle<JSTaggedValue> exceptionHandle = JSNApiHelper::ToJSHandle(exception);
4953     if (exceptionHandle->IsJSError()) {
4954         ecmascript::base::ErrorHelper::PrintJSErrorInfo(thread, exceptionHandle);
4955         ThrowException(vm, exception);
4956         return;
4957     }
4958     JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, exceptionHandle);
4959     ecmascript::CString string = ConvertToString(thread, *result);
4960     LOG_ECMA(WARN) << string;
4961     ThrowException(vm, exception);
4962 }
4963 
SetOnErrorCallback(EcmaVM * vm,OnErrorCallback cb,void * data)4964 void JSNApi::SetOnErrorCallback(EcmaVM *vm, OnErrorCallback cb, void* data)
4965 {
4966     JSThread* thread = vm->GetJSThread();
4967     thread->SetOnErrorCallback(cb, data);
4968 }
4969 
4970 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER) && !defined(PANDA_TARGET_IOS)
StartDebuggerCheckParameters(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)4971 bool JSNApi::StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId,
4972                                           const DebuggerPostTask &debuggerPostTask)
4973 {
4974     if (vm == nullptr) {
4975         LOG_ECMA(ERROR) << "[StartDebugger] vm is nullptr";
4976         return false;
4977     }
4978 
4979     if (option.port < 0) {
4980         LOG_ECMA(ERROR) << "[StartDebugger] option.port is -1" ;
4981         return false;
4982     }
4983     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4984     const auto &handler = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
4985     if (handler.IsValid()) {
4986         LOG_ECMA(ERROR) << "[StartDebugger] handler has already loaded";
4987         return false;
4988     }
4989     if (option.libraryPath == nullptr) {
4990         LOG_ECMA(ERROR) << "[StartDebugger] option.libraryPath is nullptr";
4991         return false;
4992     }
4993     auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
4994     if (!handle) {
4995         LOG_ECMA(ERROR) << "[StartDebugger] Load library fail: " << option.libraryPath << " " << errno;
4996         return false;
4997     }
4998     auto sym = panda::os::library_loader::ResolveSymbol(handle.Value(), "StartDebug");
4999     if (!sym) {
5000         LOG_ECMA(ERROR) << "[StartDebugger] Resolve symbol fail: " << sym.Error().ToString();
5001         return false;
5002     }
5003     using StartDebugger = bool (*)(
5004         const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &, int);
5005 
5006     vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
5007     vm->GetJsDebuggerManager()->SetIsDebugApp(true);
5008     vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(handle.Value()));
5009     vm->GetJsDebuggerManager()->SetFaApp(option.isFaApp);
5010     bool ret = reinterpret_cast<StartDebugger>(sym.Value())(
5011         "PandaDebugger", vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
5012     if (!ret) {
5013         // Reset the config
5014         vm->GetJsDebuggerManager()->SetDebugMode(false);
5015         panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
5016         vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(libraryHandle));
5017     }
5018     return ret;
5019 }
5020 #endif
5021 
5022 // for previewer, cross platform and testcase debugger
StartDebugger(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)5023 bool JSNApi::StartDebugger([[maybe_unused]] EcmaVM *vm, [[maybe_unused]] const DebugOption &option,
5024                            [[maybe_unused]] int32_t instanceId,
5025                            [[maybe_unused]] const DebuggerPostTask &debuggerPostTask)
5026 {
5027 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5028 #if !defined(PANDA_TARGET_IOS)
5029     LOG_ECMA(INFO) << "JSNApi::StartDebugger, isDebugMode = " << option.isDebugMode
5030         << ", port = " << option.port << ", instanceId = " << instanceId;
5031     return StartDebuggerCheckParameters(vm, option, instanceId, debuggerPostTask);
5032 #else
5033     if (vm == nullptr) {
5034         return false;
5035     }
5036     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5037     vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
5038     vm->GetJsDebuggerManager()->SetFaApp(option.isFaApp);
5039     bool ret = OHOS::ArkCompiler::Toolchain::StartDebug(
5040         DEBUGGER_NAME, vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
5041     if (!ret) {
5042         // Reset the config
5043         vm->GetJsDebuggerManager()->SetDebugMode(false);
5044     }
5045     return ret;
5046 #endif // PANDA_TARGET_IOS
5047 #else
5048     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5049     return false;
5050 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5051 }
5052 
5053 // rk
5054 // FA or Stage
StartDebuggerForOldProcess(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)5055 bool JSNApi::StartDebuggerForOldProcess([[maybe_unused]] EcmaVM *vm, [[maybe_unused]] const DebugOption &option,
5056                                         [[maybe_unused]] int32_t instanceId,
5057                                         [[maybe_unused]] const DebuggerPostTask &debuggerPostTask)
5058 {
5059 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5060 #if !defined(PANDA_TARGET_IOS)
5061     LOG_ECMA(INFO) << "JSNApi::StartDebuggerForOldProcess, isDebugMode = " << option.isDebugMode
5062         << ", instanceId = " << instanceId;
5063     if (vm == nullptr) {
5064         LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] vm is nullptr";
5065         return false;
5066     }
5067     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5068     const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
5069     if (!handle.IsValid()) {
5070         LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] Get library handle fail: " << option.libraryPath;
5071         return false;
5072     }
5073 
5074     using StartDebug = bool (*)(
5075         const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &, int);
5076 
5077     auto sym = panda::os::library_loader::ResolveSymbol(handle, "StartDebug");
5078     if (!sym) {
5079         LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] Resolve symbol fail: " << sym.Error().ToString();
5080         return false;
5081     }
5082 
5083     bool ret = reinterpret_cast<StartDebug>(sym.Value())(
5084         "PandaDebugger", vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
5085     if (!ret) {
5086         // Reset the config
5087         vm->GetJsDebuggerManager()->SetDebugMode(false);
5088         panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
5089         vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(libraryHandle));
5090     }
5091     return ret;
5092 #else
5093     if (vm == nullptr) {
5094         LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] vm is nullptr";
5095         return false;
5096     }
5097     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5098     vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
5099     bool ret = OHOS::ArkCompiler::Toolchain::StartDebug(
5100         DEBUGGER_NAME, vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
5101     if (!ret) {
5102         // Reset the config
5103         vm->GetJsDebuggerManager()->SetDebugMode(false);
5104     }
5105     return ret;
5106 #endif // PANDA_TARGET_IOS
5107 #else
5108     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5109     return false;
5110 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5111 }
5112 
5113 // ohos or emulator
5114 // FA or Stage
StartDebuggerForSocketPair(int tid,int socketfd)5115 bool JSNApi::StartDebuggerForSocketPair([[maybe_unused]] int tid, [[maybe_unused]] int socketfd)
5116 {
5117 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5118     LOG_ECMA(INFO) << "JSNApi::StartDebuggerForSocketPair, tid = " << tid << ", socketfd = " << socketfd;
5119     JsDebuggerManager *jsDebuggerManager = JsDebuggerManager::GetJsDebuggerManager(tid);
5120     if (jsDebuggerManager == nullptr) {
5121         LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] jsDebuggerManager is nullptr";
5122         return false;
5123     }
5124     const auto &handle = jsDebuggerManager->GetDebugLibraryHandle();
5125     if (!handle.IsValid()) {
5126         LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] Get library handle fail";
5127         return false;
5128     }
5129 
5130     using StartDebugForSocketpair = bool (*)(int, int, bool);
5131 
5132     auto sym = panda::os::library_loader::ResolveSymbol(handle, "StartDebugForSocketpair");
5133     if (!sym) {
5134         LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] Resolve symbol fail: " << sym.Error().ToString();
5135         return false;
5136     }
5137     // false: not hybrid
5138     bool ret = reinterpret_cast<StartDebugForSocketpair>(sym.Value())(tid, socketfd, false);
5139     if (!ret) {
5140         // Reset the config
5141         jsDebuggerManager->SetDebugMode(false);
5142         panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
5143         jsDebuggerManager->SetDebugLibraryHandle(std::move(libraryHandle));
5144     }
5145     return ret;
5146 #else
5147     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5148     return false;
5149 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5150 }
5151 
5152 // ohos or emulator
5153 // FA or Stage
5154 // release or debug hap : aa start
5155 //                        aa start -D
5156 //                        aa start -p
5157 //                        new worker
NotifyDebugMode(int tid,EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask,bool debugApp)5158 bool JSNApi::NotifyDebugMode([[maybe_unused]] int tid,
5159                              [[maybe_unused]] EcmaVM *vm,
5160                              [[maybe_unused]] const DebugOption &option,
5161                              [[maybe_unused]] int32_t instanceId,
5162                              [[maybe_unused]] const DebuggerPostTask &debuggerPostTask,
5163                              [[maybe_unused]] bool debugApp)
5164 {
5165 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5166     LOG_ECMA(INFO) << "JSNApi::NotifyDebugMode, tid = " << tid << ", debugApp = " << debugApp
5167         << ", isDebugMode = " << option.isDebugMode << ", instanceId = " << instanceId;
5168     if (vm == nullptr) {
5169         LOG_ECMA(ERROR) << "[NotifyDebugMode] vm is nullptr";
5170         return false;
5171     }
5172     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5173 
5174     bool ret = false;
5175     if (!debugApp) {
5176         return true;
5177     }
5178 
5179     if (option.libraryPath == nullptr) {
5180         LOG_ECMA(ERROR) << "[NotifyDebugMode] option.libraryPath is nullptr";
5181         return false;
5182     }
5183     JsDebuggerManager *jsDebuggerManager = vm->GetJsDebuggerManager();
5184     auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
5185     if (!handle) {
5186         LOG_ECMA(ERROR) << "[NotifyDebugMode] Load library fail: " << option.libraryPath << " " << errno;
5187         return false;
5188     }
5189     JsDebuggerManager::AddJsDebuggerManager(tid, jsDebuggerManager);
5190     jsDebuggerManager->SetDebugLibraryHandle(std::move(handle.Value()));
5191     jsDebuggerManager->SetDebugMode(option.isDebugMode && debugApp);
5192     jsDebuggerManager->SetIsDebugApp(debugApp);
5193     jsDebuggerManager->SetFaApp(option.isFaApp);
5194 #ifdef PANDA_TARGET_ARM32
5195     ret = StartDebuggerForOldProcess(vm, option, instanceId, debuggerPostTask);
5196 #else
5197     ret = true;
5198 #endif
5199 
5200     // store debugger postTask in inspector.
5201     using StoreDebuggerInfo = void (*)(int, EcmaVM *, const DebuggerPostTask &);
5202     auto symOfStoreDebuggerInfo = panda::os::library_loader::ResolveSymbol(
5203         jsDebuggerManager->GetDebugLibraryHandle(), "StoreDebuggerInfo");
5204     if (!symOfStoreDebuggerInfo) {
5205         LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve StoreDebuggerInfo symbol fail: " <<
5206             symOfStoreDebuggerInfo.Error().ToString();
5207         return false;
5208     }
5209     reinterpret_cast<StoreDebuggerInfo>(symOfStoreDebuggerInfo.Value())(tid, vm, debuggerPostTask);
5210 
5211 #ifndef PANDA_TARGET_ARM32
5212     // Initialize debugger
5213     using InitializeDebuggerForSocketpair = bool(*)(void*, bool);
5214     auto sym = panda::os::library_loader::ResolveSymbol(
5215         jsDebuggerManager->GetDebugLibraryHandle(), "InitializeDebuggerForSocketpair");
5216     if (!sym) {
5217         LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve InitializeDebuggerForSocketpair symbol fail: "
5218             << sym.Error().ToString();
5219         return false;
5220     }
5221     // false: not hybrid
5222     if (!reinterpret_cast<InitializeDebuggerForSocketpair>(sym.Value())(vm, false)) {
5223         LOG_ECMA(ERROR) << "[NotifyDebugMode] InitializeDebuggerForSocketpair fail";
5224         return false;
5225     }
5226 #endif
5227 
5228     if (option.isDebugMode) {
5229         using WaitForDebugger = void (*)(EcmaVM *);
5230         auto symOfWaitForDebugger = panda::os::library_loader::ResolveSymbol(
5231             jsDebuggerManager->GetDebugLibraryHandle(), "WaitForDebugger");
5232         if (!symOfWaitForDebugger) {
5233             LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve symbol WaitForDebugger fail: " <<
5234                 symOfWaitForDebugger.Error().ToString();
5235             return false;
5236         }
5237         reinterpret_cast<WaitForDebugger>(symOfWaitForDebugger.Value())(vm);
5238     }
5239     auto anFileDataMgr = ecmascript::AnFileDataManager::GetInstance();
5240     if (anFileDataMgr != nullptr && anFileDataMgr->SafeGetStubFileInfo()) {
5241         anFileDataMgr->SafeGetStubFileInfo()->RegisterToDebugger();
5242     }
5243     return ret;
5244 
5245 #else
5246     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5247     return false;
5248 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5249 }
5250 
StoreDebugInfo(int tid,EcmaVM * vm,const DebugOption & option,const DebuggerPostTask & debuggerPostTask,bool debugApp)5251 bool JSNApi::StoreDebugInfo([[maybe_unused]] int tid,
5252                             [[maybe_unused]] EcmaVM *vm,
5253                             [[maybe_unused]] const DebugOption &option,
5254                             [[maybe_unused]] const DebuggerPostTask &debuggerPostTask,
5255                             [[maybe_unused]] bool debugApp)
5256 {
5257 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5258     LOG_ECMA(INFO) << "JSNApi::StoreDebugInfo, tid = " << tid;
5259     if (vm == nullptr) {
5260         LOG_ECMA(ERROR) << "[StoreDebugInfo] vm is nullptr";
5261         return false;
5262     }
5263 
5264     JsDebuggerManager *jsDebuggerManager = vm->GetJsDebuggerManager();
5265     const auto &handler = jsDebuggerManager->GetDebugLibraryHandle();
5266     if (handler.IsValid()) {
5267         LOG_ECMA(INFO) << "[StoreDebugInfo] handler has already loaded";
5268         return false;
5269     }
5270 
5271     if (option.libraryPath == nullptr) {
5272         LOG_ECMA(ERROR) << "[StoreDebugInfo] option.libraryPath is nullptr";
5273         return false;
5274     }
5275     auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
5276     if (!handle) {
5277         LOG_ECMA(ERROR) << "[StoreDebugInfo] Load library fail: " << option.libraryPath << " " << errno;
5278         return false;
5279     }
5280     JsDebuggerManager::AddJsDebuggerManager(tid, jsDebuggerManager);
5281     jsDebuggerManager->SetDebugLibraryHandle(std::move(handle.Value()));
5282     jsDebuggerManager->SetDebugMode(option.isDebugMode && debugApp);
5283     jsDebuggerManager->SetIsDebugApp(debugApp);
5284     // store debugger postTask in inspector.
5285     using StoreDebuggerInfo = void (*)(int, EcmaVM *, const DebuggerPostTask &);
5286     auto symOfStoreDebuggerInfo = panda::os::library_loader::ResolveSymbol(
5287         jsDebuggerManager->GetDebugLibraryHandle(), "StoreDebuggerInfo");
5288     if (!symOfStoreDebuggerInfo) {
5289         LOG_ECMA(ERROR) << "[StoreDebugInfo] Resolve StoreDebuggerInfo symbol fail: " <<
5290             symOfStoreDebuggerInfo.Error().ToString();
5291         return false;
5292     }
5293     reinterpret_cast<StoreDebuggerInfo>(symOfStoreDebuggerInfo.Value())(tid, vm, debuggerPostTask);
5294     bool ret = false;
5295     using InitializeDebuggerForSocketpair = bool(*)(void*, bool);
5296     auto sym = panda::os::library_loader::ResolveSymbol(handler, "InitializeDebuggerForSocketpair");
5297     if (!sym) {
5298         LOG_ECMA(ERROR) << "[InitializeDebuggerForSocketpair] Resolve symbol fail: " << sym.Error().ToString();
5299         return false;
5300     }
5301     // false: not hybrid
5302     ret = reinterpret_cast<InitializeDebuggerForSocketpair>(sym.Value())(vm, false);
5303     if (!ret) {
5304     // Reset the config
5305         vm->GetJsDebuggerManager()->SetDebugMode(false);
5306         return false;
5307     }
5308     return ret;
5309 #else
5310     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5311     return false;
5312 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5313 }
5314 
StopDebugger(EcmaVM * vm)5315 bool JSNApi::StopDebugger([[maybe_unused]] EcmaVM *vm)
5316 {
5317 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5318 #if !defined(PANDA_TARGET_IOS)
5319     LOG_ECMA(DEBUG) << "JSNApi::StopDebugger";
5320     if (vm == nullptr) {
5321         LOG_ECMA(ERROR) << "[StopDebugger] vm is nullptr";
5322         return false;
5323     }
5324     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5325 
5326     const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
5327 
5328     using StopDebug = void (*)(void *, bool);
5329 
5330     auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopDebug");
5331     if (!sym) {
5332         LOG_ECMA(WARN) << sym.Error().ToString();
5333         return false;
5334     }
5335     // false: not hybrid
5336     reinterpret_cast<StopDebug>(sym.Value())(vm, false);
5337 
5338     vm->GetJsDebuggerManager()->SetDebugMode(false);
5339     uint32_t tid = vm->GetTid();
5340     JsDebuggerManager::DeleteJsDebuggerManager(tid);
5341     return true;
5342 #else
5343     if (vm == nullptr) {
5344         LOG_ECMA(ERROR) << "[StopDebugger] vm is nullptr";
5345         return false;
5346     }
5347     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5348 
5349     OHOS::ArkCompiler::Toolchain::StopDebug(vm);
5350     vm->GetJsDebuggerManager()->SetDebugMode(false);
5351     return true;
5352 #endif // PANDA_TARGET_IOS
5353 #else
5354     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5355     return false;
5356 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5357 }
5358 
StopDebugger(int tid)5359 bool JSNApi::StopDebugger([[maybe_unused]] int tid)
5360 {
5361 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5362     LOG_ECMA(DEBUG) << "JSNApi::StopDebugger, tid = " << tid;
5363     JsDebuggerManager *jsDebuggerManager = JsDebuggerManager::GetJsDebuggerManager(tid);
5364     if (jsDebuggerManager == nullptr) {
5365         LOG_ECMA(ERROR) << "[StopDebugger] jsDebuggerManager is nullptr";
5366         return false;
5367     }
5368 
5369     const auto &handle = jsDebuggerManager->GetDebugLibraryHandle();
5370 
5371     using StopOldDebug = void (*)(int, const std::string &);
5372 
5373     auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopOldDebug");
5374     if (!sym) {
5375         LOG_ECMA(ERROR) << sym.Error().ToString();
5376         return false;
5377     }
5378 
5379     reinterpret_cast<StopOldDebug>(sym.Value())(tid, "PandaDebugger");
5380 
5381     return true;
5382 #else
5383     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5384     return false;
5385 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
5386 }
5387 
IsMixedDebugEnabled(const EcmaVM * vm)5388 bool JSNApi::IsMixedDebugEnabled([[maybe_unused]] const EcmaVM *vm)
5389 {
5390 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5391     return vm->GetJsDebuggerManager()->IsMixedDebugEnabled();
5392 #else
5393     return false;
5394 #endif
5395 }
5396 
IsDebugModeEnabled(const EcmaVM * vm)5397 bool JSNApi::IsDebugModeEnabled([[maybe_unused]] const EcmaVM *vm)
5398 {
5399 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5400     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5401     if (vm != nullptr && vm->GetJsDebuggerManager() != nullptr) {
5402         return vm->GetJsDebuggerManager()->IsDebugMode();
5403     }
5404     return false;
5405 #else
5406     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5407     return false;
5408 #endif
5409 }
5410 
NotifyNativeCalling(const EcmaVM * vm,const void * nativeAddress)5411 void JSNApi::NotifyNativeCalling([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] const void *nativeAddress)
5412 {
5413 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5414     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5415     vm->GetJsDebuggerManager()->GetNotificationManager()->NativeCallingEvent(nativeAddress);
5416 #else
5417     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5418 #endif
5419 }
5420 
NotifyNativeReturn(const EcmaVM * vm,const void * nativeAddress)5421 void JSNApi::NotifyNativeReturn([[maybe_unused]] const EcmaVM *vm,  [[maybe_unused]] const void *nativeAddress)
5422 {
5423 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5424     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5425     vm->GetJsDebuggerManager()->GetNotificationManager()->NativeReturnEvent(nativeAddress);
5426 #else
5427     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5428 #endif
5429 }
5430 
NotifyLoadModule(const EcmaVM * vm)5431 void JSNApi::NotifyLoadModule([[maybe_unused]] const EcmaVM *vm)
5432 {
5433 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
5434     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5435     // if load module, it needs to check whether clear singlestepper_
5436     vm->GetJsDebuggerManager()->ClearSingleStepper();
5437 #else
5438     LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
5439 #endif
5440 }
5441 
NotifyUIIdle(const EcmaVM * vm,int idleTime)5442 void JSNApi::NotifyUIIdle(const EcmaVM *vm, [[maybe_unused]] int idleTime)
5443 {
5444     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5445     vm->GetHeap()->GetIdleGCTrigger()->NotifyVsyncIdleStart();
5446 }
5447 
NotifyLooperIdleStart(const EcmaVM * vm,int64_t timestamp,int idleTime)5448 bool JSNApi::NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime)
5449 {
5450     if (vm->IsPostForked()) {
5451         return vm->GetHeap()->GetIdleGCTrigger()->NotifyLooperIdleStart(timestamp, idleTime);
5452     }
5453     return false;
5454 }
5455 
NotifyLooperIdleEnd(const EcmaVM * vm,int64_t timestamp)5456 void JSNApi::NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp)
5457 {
5458     if (vm->IsPostForked()) {
5459         vm->GetHeap()->GetIdleGCTrigger()->NotifyLooperIdleEnd(timestamp);
5460     }
5461 }
5462 
IsJSMainThreadOfEcmaVM(const EcmaVM * vm)5463 bool JSNApi::IsJSMainThreadOfEcmaVM(const EcmaVM *vm)
5464 {
5465     return vm->GetJSThread()->IsMainThreadFast();
5466 }
5467 
SetDeviceDisconnectCallback(EcmaVM * vm,DeviceDisconnectCallback cb)5468 void JSNApi::SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb)
5469 {
5470     vm->SetDeviceDisconnectCallback(cb);
5471 }
5472 
KeyIsNumber(const char * utf8)5473 bool JSNApi::KeyIsNumber(const char* utf8)
5474 {
5475     const char *ptr = utf8;
5476     for (char c = *ptr; c; c = *++ptr) {
5477         if (c >= '0' && c <= '9') {
5478             continue;
5479         } else {
5480             return false;
5481         }
5482     }
5483     return true;
5484 }
5485 
IsSerializationTimeoutCheckEnabled(const EcmaVM * vm)5486 bool JSNApi::IsSerializationTimeoutCheckEnabled(const EcmaVM *vm)
5487 {
5488     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5489     // Open Control Timeout Consumption
5490     if (const_cast<EcmaVM *>(vm)->GetJSOptions().EnableSerializationTimeoutCheck()) {
5491         return thread->IsMainThread();
5492     }
5493 
5494     // Currently only log trace on main thread
5495     auto jsDebuggerManager = vm->GetJsDebuggerManager();
5496     if (jsDebuggerManager != nullptr) {
5497         if (jsDebuggerManager->IsSerializationTimeoutCheckEnabled()) {
5498             return thread->IsMainThread();
5499         }
5500     }
5501     return false;
5502 }
5503 
GenerateTimeoutTraceIfNeeded(const EcmaVM * vm,std::chrono::system_clock::time_point & start,std::chrono::system_clock::time_point & end,bool isSerialization)5504 void JSNApi::GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start,
5505                                           std::chrono::system_clock::time_point &end, bool isSerialization)
5506 {
5507     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5508     ecmascript::ThreadManagedScope scope(thread);
5509     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
5510     auto threshold = std::chrono::duration_cast<std::chrono::milliseconds>
5511             (std::chrono::milliseconds(vm->GetJsDebuggerManager()->GetSerializationCheckThreshold())).count();
5512     LOG_ECMA(DEBUG) << "JSNAPI::" << (isSerialization ? "SerializeValue" : "DeserializeValue") << " tid: "
5513         << thread->GetThreadId() << " threshold: " << threshold << " duration: " << duration;
5514     if (duration >= threshold) {
5515         std::stringstream tagMsg;
5516         auto startTimeMS = std::chrono::time_point_cast<std::chrono::nanoseconds>(start);
5517         tagMsg << (isSerialization ? "SerializationTimeout::tid=" : "DeserializationTimeout::tid=");
5518         tagMsg << thread->GetThreadId();
5519         tagMsg << (isSerialization ? ";task=serialization;startTime=" : ";task=deserialization;startTime=");
5520         tagMsg << startTimeMS.time_since_epoch().count() << ";duration=" << duration;
5521         ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, tagMsg.str().c_str(), "");
5522     }
5523 }
5524 
LoadAotFile(EcmaVM * vm,const std::string & moduleName)5525 void JSNApi::LoadAotFile(EcmaVM *vm, const std::string &moduleName)
5526 {
5527     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5528     ecmascript::ThreadManagedScope scope(thread);
5529 
5530     std::string aotFileName = ecmascript::AOTFileManager::GetAOTFileFullPath(vm, moduleName);
5531     if (aotFileName.empty()) {
5532         LOG_ECMA(INFO) << "can not find aot file";
5533         return;
5534     }
5535     // Disable PGO for applications when an/ai file exists
5536     if (isForked_) {
5537         vm->DisablePGOProfilerWithAOTFile(aotFileName);
5538     }
5539     LOG_ECMA(INFO) << "start to load aot file: " << aotFileName;
5540     vm->LoadAOTFiles(aotFileName);
5541 }
5542 
5543 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
LoadAotFile(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,std::function<bool (std::string fileName,uint8_t ** buff,size_t * buffSize)> cb)5544 void JSNApi::LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, const std::string &moduleName,
5545                          std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb)
5546 {
5547     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5548     ecmascript::ThreadManagedScope scope(thread);
5549 
5550     std::string aotFileName = ecmascript::AOTFileManager::GetAOTFileFullPath(vm, moduleName);
5551     if (aotFileName.empty()) {
5552         LOG_ECMA(INFO) << "can not find aot file";
5553         return;
5554     }
5555     LOG_ECMA(INFO) << "start to load aot file: " << aotFileName;
5556     vm->LoadAOTFiles(aotFileName, cb);
5557 }
5558 #endif
5559 
5560 // function for bundle abc
ExecuteForAbsolutePath(const EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate,const ecmascript::ExecuteTypes & executeType)5561 bool JSNApi::ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName, const std::string &entry,
5562                                     bool needUpdate, const ecmascript::ExecuteTypes &executeType)
5563 {
5564     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5565     LOG_ECMA(DEBUG) << "start to execute absolute path ark file: " << fileName;
5566     ecmascript::ThreadManagedScope scope(thread);
5567     if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbsolutePathAbcFile(
5568         thread, fileName.c_str(), entry, needUpdate, executeType)) {
5569         if (thread->HasPendingException()) {
5570             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5571             thread->HandleUncaughtException();
5572         }
5573         LOG_ECMA(ERROR) << "Cannot execute absolute path ark file '" << fileName
5574                         << "' with entry '" << entry << "'" << std::endl;
5575         return false;
5576     }
5577     return true;
5578 }
5579 
Execute(const EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate,const ecmascript::ExecuteTypes & executeType)5580 bool JSNApi::Execute(const EcmaVM *vm, const std::string &fileName, const std::string &entry,
5581                      bool needUpdate, const ecmascript::ExecuteTypes &executeType)
5582 {
5583     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5584     LOG_ECMA(DEBUG) << "start to execute ark file: " << fileName;
5585     ecmascript::ThreadManagedScope scope(thread);
5586     if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbcFile(
5587         thread, fileName.c_str(), entry, needUpdate, executeType)) {
5588         if (thread->HasPendingException()) {
5589             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5590             thread->HandleUncaughtException();
5591         }
5592         LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName
5593                         << "' with entry '" << entry << "'" << std::endl;
5594         return false;
5595     }
5596     return true;
5597 }
5598 
5599 // The security interface needs to be modified accordingly.
Execute(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & entry,const std::string & filename,bool needUpdate,void * fileMapper)5600 bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
5601                      const std::string &filename, bool needUpdate, [[maybe_unused]] void* fileMapper)
5602 {
5603     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5604     LOG_ECMA(DEBUG) << "start to execute ark buffer: " << filename;
5605     ecmascript::ThreadManagedScope scope(thread);
5606     if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, entry, filename.c_str(), needUpdate)) {
5607         if (thread->HasPendingException()) {
5608             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5609             thread->HandleUncaughtException();
5610         }
5611         LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename
5612                         << "' with entry '" << entry << "'" << std::endl;
5613         return false;
5614     }
5615     return true;
5616 }
5617 
ExecuteWithSingletonPatternFlag(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,const std::string & ohmurl,bool isSingletonPattern)5618 int JSNApi::ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName,
5619     const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern)
5620 {
5621     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, ecmascript::JSPandaFileExecutor::ROUTE_INTERNAL_ERROR);
5622     ecmascript::ThreadManagedScope scope(thread);
5623     int result = ecmascript::JSPandaFileExecutor::ExecuteAbcFileWithSingletonPatternFlag(thread, bundleName.c_str(),
5624         moduleName.c_str(), ohmurl.c_str(), isSingletonPattern);
5625     if (!result) {
5626         if (thread->HasPendingException()) {
5627             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5628             thread->HandleUncaughtException();
5629         }
5630     }
5631     return result;
5632 }
5633 
IsExecuteModuleInAbcFile(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,const std::string & ohmurl)5634 bool JSNApi::IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName,
5635     const std::string &moduleName, const std::string &ohmurl)
5636 {
5637     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5638     ecmascript::ThreadManagedScope scope(thread);
5639     bool result = ecmascript::JSPandaFileExecutor::IsExecuteModuleInAbcFile(thread, bundleName.c_str(),
5640         moduleName.c_str(), ohmurl.c_str());
5641     return result;
5642 }
5643 
5644 // The security interface needs to be modified accordingly.
ExecuteModuleBuffer(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)5645 bool JSNApi::ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename,
5646                                  bool needUpdate)
5647 {
5648     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5649     LOG_ECMA(DEBUG) << "start to execute module buffer: " << filename;
5650     ecmascript::ThreadManagedScope scope(thread);
5651     if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBuffer(thread, data, size, filename.c_str(), needUpdate)) {
5652         if (thread->HasPendingException()) {
5653             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5654             thread->HandleUncaughtException();
5655         }
5656         LOG_ECMA(ERROR) << "Cannot execute module buffer file '" << filename;
5657         return false;
5658     }
5659     return true;
5660 }
5661 
5662 /*
5663  * srcFilename: data/storage/el1/bundle/modulename/ets/modules.abc
5664  * ohmUrl :     1. @bundle:bundleName/moduleName@namespace/ets/pages/Index
5665  *              2. @package:pkg_modules/.ohpm/pkgName/pkg_modules/pkgName/xxx/xxx
5666  *              3. @normalized:N&moduleName&bundleName&entryPath&version
5667  *              4. @normalized:N&moduleName&bundleName&entryPath&
5668  */
ExecuteSecureWithOhmUrl(EcmaVM * vm,uint8_t * data,int32_t size,const std::string & srcFilename,const std::string & ohmUrl)5669 bool JSNApi::ExecuteSecureWithOhmUrl(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &srcFilename,
5670                                      const std::string &ohmUrl)
5671 {
5672     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5673     LOG_ECMA(INFO) << "start to execute ark buffer with secure memory use file: " << srcFilename <<
5674                       ", entrypoint: " << ohmUrl;
5675     ecmascript::ThreadManagedScope scope(thread);
5676     ecmascript::CString filename = PathHelper::NormalizePath(srcFilename.c_str());
5677     // check input filePath
5678 #if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
5679     if (!ModulePathHelper::ValidateAbcPath(filename, ecmascript::ValidateFilePath::ETS_MODULES)) {
5680         LOG_FULL(FATAL) << "ExecuteSecureWithOhmUrl: Invalid input filePath: " << srcFilename <<
5681                            ", input OhmUrl:" << ohmUrl;
5682     }
5683 #endif
5684     ecmascript::CString entryPoint;
5685     // Check and translate OhmUrl to recordName
5686     if (!ModulePathHelper::CheckAndGetRecordName(thread, ohmUrl.c_str(), entryPoint)) {
5687         LOG_FULL(FATAL) << "ExecuteSecureWithOhmUrl: Invalid input OhmUrl: " << ohmUrl <<
5688                            ", input filePath:" << filename;
5689     }
5690     if (!ecmascript::JSPandaFileExecutor::ExecuteSecureWithOhmUrl(thread, data, size, filename, entryPoint)) {
5691         if (thread->HasPendingException()) {
5692             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5693             thread->HandleUncaughtException();
5694         }
5695         LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << srcFilename
5696                         << "' with entry '" << ohmUrl << "'" << std::endl;
5697         return false;
5698     }
5699     return true;
5700 }
5701 
5702 // file mapper only used for secure memory
ExecuteSecure(EcmaVM * vm,uint8_t * data,int32_t size,const std::string & entry,const std::string & filename,bool needUpdate,void * fileMapper)5703 bool JSNApi::ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry,
5704                            const std::string &filename, bool needUpdate, void *fileMapper)
5705 {
5706     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5707     LOG_ECMA(INFO) << "start to execute ark buffer with secure memory: " << filename;
5708     ecmascript::ThreadManagedScope scope(thread);
5709     if (!ecmascript::JSPandaFileExecutor::ExecuteFromBufferSecure(
5710         thread, data, size, entry, filename.c_str(), needUpdate, fileMapper)) {
5711         if (thread->HasPendingException()) {
5712             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5713             thread->HandleUncaughtException();
5714         }
5715         LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename
5716                         << "' with entry '" << entry << "'" << std::endl;
5717         return false;
5718     }
5719     return true;
5720 }
5721 
ExecuteModuleBufferSecure(EcmaVM * vm,uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)5722 bool JSNApi::ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t* data, int32_t size, const std::string &filename,
5723                                        bool needUpdate)
5724 {
5725     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5726     LOG_ECMA(INFO) << "start to execute module buffer with secure memory: " << filename;
5727     ecmascript::ThreadManagedScope scope(thread);
5728     if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBufferSecure(thread, data, size, filename.c_str(),
5729                                                                     needUpdate)) {
5730         if (thread->HasPendingException()) {
5731             ecmascript::JsStackInfo::BuildCrashInfo(thread);
5732             thread->HandleUncaughtException();
5733         }
5734         LOG_ECMA(ERROR) << "Cannot execute module buffer file '" << filename;
5735         return false;
5736     }
5737     return true;
5738 }
5739 
PreFork(EcmaVM * vm)5740 void JSNApi::PreFork(EcmaVM *vm)
5741 {
5742     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5743     vm->PreFork();
5744 }
5745 
UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions & jsOption,const RuntimeOption & option)5746 void JSNApi::UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option)
5747 {
5748     // When AOT compilation failed, disable PGO and JIT
5749     bool aotHasException = false;
5750     for (const auto &value : option.GetAOTCompileStatusMap()) {
5751         auto moduleCompileStatus = static_cast<RuntimeOption::AOTCompileStatus>(value.second);
5752         if (moduleCompileStatus == RuntimeOption::AOTCompileStatus::COMPILE_FAILED ||
5753             moduleCompileStatus == RuntimeOption::AOTCompileStatus::COMPILE_CRASH) {
5754             aotHasException = true;
5755             break;
5756         }
5757     }
5758     jsOption.SetAOTHasException(aotHasException);
5759 }
5760 
PostFork(EcmaVM * vm,const RuntimeOption & option)5761 void JSNApi::PostFork(EcmaVM *vm, const RuntimeOption &option)
5762 {
5763     isForked_ = true;
5764     JSRuntimeOptions &jsOption = vm->GetJSOptions();
5765     jsOption.SetEnablePGOProfiler(option.GetEnableProfile());
5766     jsOption.SetEnableJIT(option.GetEnableJIT());
5767     jsOption.SetEnableDFXHiSysEvent(option.GetEnableDFXHiSysEvent());
5768     jsOption.SetEnableBaselineJIT(option.GetEnableBaselineJIT());
5769     jsOption.SetMaxAotMethodSize(JSRuntimeOptions::MAX_APP_COMPILE_METHOD_SIZE);
5770     ecmascript::pgo::PGOProfilerManager::GetInstance()->SetBundleName(option.GetBundleName());
5771     ecmascript::pgo::PGOProfilerManager::GetInstance()->SetMaxAotMethodSize(jsOption.GetMaxAotMethodSize());
5772     JSRuntimeOptions runtimeOptions;
5773     runtimeOptions.SetLogLevel(common::Log::LevelToString(common::Log::ConvertFromRuntime(option.GetLogLevel())));
5774     common::Log::Initialize(runtimeOptions.GetLogOptions());
5775 
5776     // 1. system switch 2. an file dir exits 3. whitelist 4. escape mechanism
5777     bool enableAOT = jsOption.GetEnableAOT() &&
5778                      !option.GetAnDir().empty() &&
5779                      EnableAotJitListHelper::GetInstance()->IsEnableAot(option.GetBundleName()) &&
5780                      !ecmascript::AotCrashInfo::IsAotEscaped();
5781     if (enableAOT) {
5782         ecmascript::AnFileDataManager::GetInstance()->SetDir(option.GetAnDir());
5783         ecmascript::AnFileDataManager::GetInstance()->SetEnable(true);
5784     }
5785     UpdateAOTCompileStatus(jsOption, option);
5786 
5787     LOG_ECMA(INFO) << "asmint: " << jsOption.GetEnableAsmInterpreter()
5788                     << ", aot: " << enableAOT
5789                     << ", jit: " << option.GetEnableJIT()
5790                     << ", baseline jit: " << option.GetEnableBaselineJIT()
5791                     << ", bundle name: " <<  option.GetBundleName();
5792     jsOption.SetEnableWarmStartupSmartGC(option.GetEnableWarmStartupSmartGC());
5793     vm->PostFork(jsOption);
5794 }
5795 
AddWorker(EcmaVM * hostVm,EcmaVM * workerVm)5796 void JSNApi::AddWorker(EcmaVM *hostVm, EcmaVM *workerVm)
5797 {
5798     if (hostVm != nullptr && workerVm != nullptr) {
5799         hostVm->WorkersetInfo(workerVm);
5800         workerVm->SetBundleName(hostVm->GetBundleName());
5801     }
5802 }
5803 
DeleteWorker(EcmaVM * hostVm,EcmaVM * workerVm)5804 bool JSNApi::DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm)
5805 {
5806     if (hostVm != nullptr && workerVm != nullptr) {
5807         return hostVm->DeleteWorker(workerVm);
5808     }
5809     return false;
5810 }
5811 
GetUncaughtException(const EcmaVM * vm)5812 Local<ObjectRef> JSNApi::GetUncaughtException(const EcmaVM *vm)
5813 {
5814     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5815     return JSNApiHelper::ToLocal<ObjectRef>(vm->GetEcmaUncaughtException());
5816 }
5817 
GetAndClearUncaughtException(const EcmaVM * vm)5818 Local<ObjectRef> JSNApi::GetAndClearUncaughtException(const EcmaVM *vm)
5819 {
5820     if (LIKELY(!HasPendingException(vm))) {
5821         return Local<ObjectRef>();
5822     }
5823     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5824     return JSNApiHelper::ToLocal<ObjectRef>(vm->GetAndClearEcmaUncaughtException());
5825 }
5826 
HasPendingException(const EcmaVM * vm)5827 bool JSNApi::HasPendingException(const EcmaVM *vm)
5828 {
5829     return vm->GetJSThread()->HasPendingException();
5830 }
5831 
IsExecutingPendingJob(const EcmaVM * vm)5832 bool JSNApi::IsExecutingPendingJob(const EcmaVM *vm)
5833 {
5834     return EcmaVM::ConstCast(vm)->IsExecutingPendingJob();
5835 }
5836 
HasPendingJob(const EcmaVM * vm)5837 bool JSNApi::HasPendingJob(const EcmaVM *vm)
5838 {
5839     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5840     return EcmaVM::ConstCast(vm)->HasPendingJob();
5841 }
5842 
EnableUserUncaughtErrorHandler(EcmaVM * vm)5843 void JSNApi::EnableUserUncaughtErrorHandler(EcmaVM *vm)
5844 {
5845     return vm->GetJSThread()->EnableUserUncaughtErrorHandler();
5846 }
5847 
GetGlobalObject(const EcmaVM * vm)5848 Local<ObjectRef> JSNApi::GetGlobalObject(const EcmaVM *vm)
5849 {
5850     auto thread = vm->GetJSThread();
5851     ecmascript::ThreadManagedScope scope(thread);
5852     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
5853     JSHandle<JSTaggedValue> global(thread, globalEnv->GetGlobalObject());
5854     return JSNApiHelper::ToLocal<ObjectRef>(global);
5855 }
5856 
GetGlobalObject(const EcmaVM * vm,const Local<JSValueRef> & context)5857 Local<ObjectRef> JSNApi::GetGlobalObject(const EcmaVM *vm, const Local<JSValueRef> &context)
5858 {
5859     JSThread* thread = vm->GetJSThread();
5860     ecmascript::ThreadManagedScope scope(thread);
5861     if (!context->IsJsGlobalEnv(vm)) {
5862         return JSValueRef::Undefined(vm);
5863     }
5864     JSHandle<GlobalEnv> globalEnv = JSHandle<GlobalEnv>(JSNApiHelper::ToJSHandle(context));
5865     JSHandle<JSTaggedValue> global(thread, globalEnv->GetGlobalObject());
5866     return JSNApiHelper::ToLocal<ObjectRef>(global);
5867 }
5868 
ExecutePendingJob(const EcmaVM * vm)5869 void JSNApi::ExecutePendingJob(const EcmaVM *vm)
5870 {
5871     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5872     ecmascript::ThreadManagedScope managedScope(thread);
5873     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
5874 }
5875 
GetHandleAddr(const EcmaVM * vm,uintptr_t localAddress)5876 uintptr_t JSNApi::GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
5877 {
5878     if (localAddress == 0) {
5879         return 0;
5880     }
5881     CROSS_THREAD_CHECK(vm);
5882     ecmascript::ThreadManagedScope scope(thread);
5883     JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
5884     return ecmascript::EcmaHandleScope::NewHandle(thread, value);
5885 }
5886 
GetGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)5887 uintptr_t JSNApi::GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
5888 {
5889     if (localAddress == 0) {
5890         return 0;
5891     }
5892     CROSS_THREAD_CHECK(vm);
5893     ecmascript::ThreadManagedScope scope(thread);
5894     JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
5895     return thread->NewGlobalHandle(value);
5896 }
5897 
GetStartRealTime(const EcmaVM * vm)5898 int JSNApi::GetStartRealTime(const EcmaVM *vm)
5899 {
5900     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5901     return vm->GetProcessStartRealtime();
5902 }
5903 
NotifyTaskBegin(const EcmaVM * vm)5904 void JSNApi::NotifyTaskBegin(const EcmaVM *vm)
5905 {
5906     const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyRecordMemorySize();
5907 }
5908 
NotifyTaskFinished(const EcmaVM * vm)5909 void JSNApi::NotifyTaskFinished(const EcmaVM *vm)
5910 {
5911     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5912     const_cast<ecmascript::Heap *>(vm->GetHeap())->CheckAndTriggerTaskFinishedGC();
5913 }
5914 
IsMultiThreadCheckEnabled(const EcmaVM * vm)5915 bool JSNApi::IsMultiThreadCheckEnabled(const EcmaVM *vm)
5916 {
5917     return vm->GetThreadCheckStatus();
5918 }
5919 
GetCurrentThreadId()5920 uint32_t JSNApi::GetCurrentThreadId()
5921 {
5922     return JSThread::GetCurrentThreadId();
5923 }
5924 
SetVMAPIVersion(EcmaVM * vm,const int32_t apiVersion)5925 void JSNApi::SetVMAPIVersion(EcmaVM *vm, const int32_t apiVersion)
5926 {
5927     vm->SetVMAPIVersion(static_cast<uint32_t>(apiVersion) % API_VERSION_MASK);
5928 }
5929 
UpdateStackInfo(EcmaVM * vm,void * currentStackInfo,uint32_t opKind)5930 void JSNApi::UpdateStackInfo(EcmaVM *vm, void *currentStackInfo, uint32_t opKind)
5931 {
5932     vm->GetJSThread()->UpdateStackInfo(currentStackInfo, static_cast<ecmascript::JSThread::StackInfoOpKind>(opKind));
5933 }
5934 
CreateContext(const EcmaVM * vm)5935 Local<JSValueRef> JSNApi::CreateContext(const EcmaVM *vm)
5936 {
5937     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5938     ecmascript::ThreadManagedScope managedScope(thread);
5939     thread->SetMultiContextTriggered(true);
5940     ObjectFactory *factory = vm->GetFactory();
5941     JSHandle<GlobalEnv> globalEnv = factory->NewGlobalEnv();
5942     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(globalEnv));
5943 }
5944 
GetCurrentContext(const EcmaVM * vm)5945 Local<JSValueRef> JSNApi::GetCurrentContext(const EcmaVM *vm)
5946 {
5947     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5948     ecmascript::ThreadManagedScope managedScope(thread);
5949     JSHandle<GlobalEnv> currentGlobalEnv = thread->GetGlobalEnv();
5950     JSHandle<JSTaggedValue> envContext = JSHandle<JSTaggedValue>(currentGlobalEnv);
5951     return JSNApiHelper::ToLocal<JSValueRef>(envContext);
5952 }
5953 
SwitchContext(const EcmaVM * vm,const Local<JSValueRef> & context)5954 void JSNApi::SwitchContext(const EcmaVM *vm, const Local<JSValueRef> &context)
5955 {
5956     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5957     ecmascript::ThreadManagedScope managedScope(thread);
5958     JSHandle<JSTaggedValue> contextValue = JSNApiHelper::ToJSHandle(context);
5959     JSHandle<GlobalEnv> globalEnv = JSHandle<GlobalEnv>(contextValue);
5960     thread->SetGlueGlobalEnv(globalEnv.GetTaggedValue());
5961 }
5962 
SetWeak(const EcmaVM * vm,uintptr_t localAddress)5963 uintptr_t JSNApi::SetWeak(const EcmaVM *vm, uintptr_t localAddress)
5964 {
5965     if (localAddress == 0) {
5966         return 0;
5967     }
5968     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5969     CROSS_THREAD_CHECK(vm);
5970     return thread->SetWeak(localAddress);
5971 }
5972 
SetWeakCallback(const EcmaVM * vm,uintptr_t localAddress,void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)5973 uintptr_t JSNApi::SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
5974                                   WeakRefClearCallBack freeGlobalCallBack, WeakRefClearCallBack nativeFinalizeCallback)
5975 {
5976     if (localAddress == 0) {
5977         return 0;
5978     }
5979     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5980     CROSS_THREAD_CHECK(vm);
5981     return thread->SetWeak(localAddress, ref, freeGlobalCallBack, nativeFinalizeCallback);
5982 }
5983 
ClearWeak(const EcmaVM * vm,uintptr_t localAddress)5984 uintptr_t JSNApi::ClearWeak(const EcmaVM *vm, uintptr_t localAddress)
5985 {
5986     if (localAddress == 0) {
5987         return 0;
5988     }
5989     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5990     if (JSTaggedValue(reinterpret_cast<ecmascript::Node *>(localAddress)->GetObject())
5991         .IsUndefined()) {
5992         LOG_ECMA(ERROR) << "The object of weak reference has been recycled!";
5993         return 0;
5994     }
5995     CROSS_THREAD_CHECK(vm);
5996     return thread->ClearWeak(localAddress);
5997 }
5998 
IsWeak(const EcmaVM * vm,uintptr_t localAddress)5999 bool JSNApi::IsWeak(const EcmaVM *vm, uintptr_t localAddress)
6000 {
6001     if (localAddress == 0) {
6002         return false;
6003     }
6004     CROSS_THREAD_CHECK(vm);
6005     ecmascript::ThreadManagedScope scope(thread);
6006     return thread->IsWeak(localAddress);
6007 }
6008 
DisposeGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)6009 void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr)
6010 {
6011     if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
6012         return;
6013     }
6014     CROSS_THREAD_CHECK(vm);
6015     ecmascript::ThreadManagedScope scope(thread);
6016     thread->DisposeGlobalHandle(addr);
6017 }
6018 
InterOpSerializeValue(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer,Local<JSValueRef> cloneList,bool defaultTransfer,bool defaultCloneShared)6019 void *JSNApi::InterOpSerializeValue(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer,
6020                                     Local<JSValueRef> cloneList, bool defaultTransfer, bool defaultCloneShared)
6021 {
6022     if (!ecmascript::Runtime::GetInstance()->IsHybridVm()) {
6023         return SerializeValue(vm, value, transfer, cloneList, defaultTransfer, defaultCloneShared);
6024     }
6025     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
6026     ecmascript::ThreadManagedScope scope(thread);
6027     JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value);
6028     JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer);
6029     JSHandle<JSTaggedValue> arkCloneList = JSNApiHelper::ToJSHandle(cloneList);
6030     bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
6031     std::chrono::system_clock::time_point startTime;
6032     std::chrono::system_clock::time_point endTime;
6033     if (serializationTimeoutCheckEnabled) {
6034         startTime = std::chrono::system_clock::now();
6035     }
6036     ecmascript::InterOpValueSerializer serializer(thread, defaultTransfer, defaultCloneShared);
6037     std::unique_ptr<ecmascript::SerializeData> data;
6038     if (serializer.WriteValue(thread, arkValue, arkTransfer, arkCloneList)) {
6039         data = serializer.Release();
6040     }
6041     if (serializationTimeoutCheckEnabled) {
6042         endTime = std::chrono::system_clock::now();
6043         GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, true);
6044     }
6045     if (data == nullptr) {
6046         return nullptr;
6047     } else {
6048         return reinterpret_cast<void *>(data.release());
6049     }
6050 }
6051 
InterOpDeserializeValue(const EcmaVM * vm,void * recoder,void * hint)6052 Local<JSValueRef> JSNApi::InterOpDeserializeValue(const EcmaVM *vm, void *recoder, void *hint)
6053 {
6054     if (!ecmascript::Runtime::GetInstance()->IsHybridVm()) {
6055         return DeserializeValue(vm, recoder, hint);
6056     }
6057     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6058     ecmascript::ThreadManagedScope scope(thread);
6059     EscapeLocalScope escapeScope(vm);
6060     std::unique_ptr<ecmascript::SerializeData> data(reinterpret_cast<ecmascript::SerializeData *>(recoder));
6061     ecmascript::InterOpValueDeserializer deserializer(thread, data.release(), hint);
6062     bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
6063     std::chrono::system_clock::time_point startTime;
6064     std::chrono::system_clock::time_point endTime;
6065     if (serializationTimeoutCheckEnabled) {
6066         startTime = std::chrono::system_clock::now();
6067     }
6068     JSHandle<JSTaggedValue> result = deserializer.ReadValue();
6069     if (serializationTimeoutCheckEnabled) {
6070         endTime = std::chrono::system_clock::now();
6071         GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, false);
6072     }
6073     return escapeScope.Escape(JSNApiHelper::ToLocal<JSValueRef>(result));
6074 }
6075 
SerializeValue(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer,Local<JSValueRef> cloneList,bool defaultTransfer,bool defaultCloneShared)6076 void *JSNApi::SerializeValue(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer,
6077                              Local<JSValueRef> cloneList, bool defaultTransfer, bool defaultCloneShared)
6078 {
6079     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
6080     ecmascript::ThreadManagedScope scope(thread);
6081     JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value);
6082     JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer);
6083     JSHandle<JSTaggedValue> arkCloneList = JSNApiHelper::ToJSHandle(cloneList);
6084     bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
6085     std::chrono::system_clock::time_point startTime;
6086     std::chrono::system_clock::time_point endTime;
6087     if (serializationTimeoutCheckEnabled) {
6088         startTime = std::chrono::system_clock::now();
6089     }
6090     ecmascript::ValueSerializer serializer(thread, defaultTransfer, defaultCloneShared);
6091     std::unique_ptr<ecmascript::SerializeData> data;
6092     if (serializer.WriteValue(thread, arkValue, arkTransfer, arkCloneList)) {
6093         data = serializer.Release();
6094     }
6095     if (serializationTimeoutCheckEnabled) {
6096         endTime = std::chrono::system_clock::now();
6097         GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, true);
6098     }
6099     if (data == nullptr) {
6100         return nullptr;
6101     } else {
6102         return reinterpret_cast<void *>(data.release());
6103     }
6104 }
6105 
SerializeValueWithError(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer,Local<JSValueRef> cloneList,std::string & error,bool defaultTransfer,bool defaultCloneShared)6106 void *JSNApi::SerializeValueWithError(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer,
6107                                       Local<JSValueRef> cloneList, std::string &error, bool defaultTransfer,
6108                                       bool defaultCloneShared)
6109 {
6110     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
6111     ecmascript::ThreadManagedScope scope(thread);
6112     JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value);
6113     JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer);
6114     JSHandle<JSTaggedValue> arkCloneList = JSNApiHelper::ToJSHandle(cloneList);
6115     bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
6116     std::chrono::system_clock::time_point startTime;
6117     std::chrono::system_clock::time_point endTime;
6118     if (serializationTimeoutCheckEnabled) {
6119         startTime = std::chrono::system_clock::now();
6120     }
6121     ecmascript::ValueSerializer serializer(thread, defaultTransfer, defaultCloneShared);
6122     std::unique_ptr<ecmascript::SerializeData> data;
6123     if (serializer.WriteValue(thread, arkValue, arkTransfer, arkCloneList)) {
6124         data = serializer.Release();
6125     }
6126     if (serializationTimeoutCheckEnabled) {
6127         endTime = std::chrono::system_clock::now();
6128         GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, true);
6129     }
6130     if (data == nullptr) {
6131         error = serializer.Release()->GetErrorMessage();
6132         return nullptr;
6133     } else {
6134         return reinterpret_cast<void *>(data.release());
6135     }
6136 }
6137 
DeserializeValue(const EcmaVM * vm,void * recoder,void * hint)6138 Local<JSValueRef> JSNApi::DeserializeValue(const EcmaVM *vm, void *recoder, void *hint)
6139 {
6140     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6141     ecmascript::ThreadManagedScope scope(thread);
6142     EscapeLocalScope escapeScope(vm);
6143     std::unique_ptr<ecmascript::SerializeData> data(reinterpret_cast<ecmascript::SerializeData *>(recoder));
6144     ecmascript::BaseDeserializer deserializer(thread, data.release(), hint);
6145     bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
6146     std::chrono::system_clock::time_point startTime;
6147     std::chrono::system_clock::time_point endTime;
6148     if (serializationTimeoutCheckEnabled) {
6149         startTime = std::chrono::system_clock::now();
6150     }
6151     JSHandle<JSTaggedValue> result = deserializer.ReadValue();
6152     if (serializationTimeoutCheckEnabled) {
6153         endTime = std::chrono::system_clock::now();
6154         GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, false);
6155     }
6156     return escapeScope.Escape(JSNApiHelper::ToLocal<JSValueRef>(result));
6157 }
6158 
DeleteSerializationData(void * data)6159 void JSNApi::DeleteSerializationData(void *data)
6160 {
6161     ecmascript::SerializeData *value = reinterpret_cast<ecmascript::SerializeData *>(data);
6162     delete value;
6163     value = nullptr;
6164 }
6165 
HostPromiseRejectionTracker(const EcmaVM * vm,const JSHandle<JSPromise> promise,const JSHandle<JSTaggedValue> reason,const ecmascript::PromiseRejectionEvent operation,void * data)6166 void HostPromiseRejectionTracker(const EcmaVM *vm,
6167                                  const JSHandle<JSPromise> promise,
6168                                  const JSHandle<JSTaggedValue> reason,
6169                                  const ecmascript::PromiseRejectionEvent operation,
6170                                  void* data)
6171 {
6172     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6173     ecmascript::PromiseRejectCallback promiseRejectCallback = vm->GetPromiseRejectCallback();
6174     if (promiseRejectCallback != nullptr) {
6175         Local<JSValueRef> promiseVal = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>::Cast(promise));
6176         PromiseRejectInfo promiseRejectInfo(promiseVal, JSNApiHelper::ToLocal<JSValueRef>(reason),
6177                               static_cast<PromiseRejectInfo::PROMISE_REJECTION_EVENT>(operation), data);
6178         promiseRejectCallback(reinterpret_cast<void*>(&promiseRejectInfo));
6179     }
6180 }
6181 
SetHostPromiseRejectionTracker(EcmaVM * vm,void * cb,void * data)6182 void JSNApi::SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data)
6183 {
6184     CROSS_THREAD_CHECK(vm);
6185     vm->SetHostPromiseRejectionTracker(HostPromiseRejectionTracker);
6186     vm->SetPromiseRejectCallback(reinterpret_cast<ecmascript::PromiseRejectCallback>(cb));
6187     vm->SetPromiseRejectInfoData(data);
6188 }
6189 
SetTimerTaskCallback(EcmaVM * vm,TimerTaskCallback callback)6190 void JSNApi::SetTimerTaskCallback(EcmaVM *vm, TimerTaskCallback callback)
6191 {
6192     CROSS_THREAD_CHECK(vm);
6193     // register TimerTask to ark_js_runtime
6194     vm->SetTimerTaskCallback(callback);
6195 }
6196 
SetCancelTimerCallback(EcmaVM * vm,CancelTimerCallback callback)6197 void JSNApi::SetCancelTimerCallback(EcmaVM *vm, CancelTimerCallback callback)
6198 {
6199     CROSS_THREAD_CHECK(vm);
6200     // register CancelTimerCallback to ark_js_runtime
6201     vm->SetCancelTimerCallback(callback);
6202 }
6203 
6204 // post task after runtime initialized
NotifyEnvInitialized(EcmaVM * vm)6205 void JSNApi::NotifyEnvInitialized(EcmaVM *vm)
6206 {
6207     ecmascript::ModuleLogger::SetModuleLoggerTask(vm);
6208 }
6209 
SetReleaseSecureMemCallback(ReleaseSecureMemCallback releaseSecureMemFunc)6210 void JSNApi::SetReleaseSecureMemCallback(ReleaseSecureMemCallback releaseSecureMemFunc)
6211 {
6212     // register release secure mem func to ark_js_runtime
6213     ecmascript::Runtime::GetInstance()->SetReleaseSecureMemCallback(releaseSecureMemFunc);
6214 }
6215 
6216 // Arkui trigger jsPandafile Seralize when cold start is end.
PandaFileSerialize(const EcmaVM * vm)6217 void JSNApi::PandaFileSerialize(const EcmaVM *vm)
6218 {
6219     if (const_cast<EcmaVM *>(vm)->GetJSOptions().DisableJSPandaFileAndModuleSnapshot()) {
6220         return;
6221     }
6222     ecmascript::CString path(ecmascript::ohos::OhosConstants::PANDAFILE_AND_MODULE_SNAPSHOT_DIR);
6223     ecmascript::ohos::JSPandaFileSnapshotInterfaces::Serialize(vm, path);
6224 }
6225 
6226 // Arkui trigger module Seralize when cold start is end.
ModuleSerialize(const EcmaVM * vm)6227 void JSNApi::ModuleSerialize(const EcmaVM *vm)
6228 {
6229     JSRuntimeOptions &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
6230     if (options.DisableJSPandaFileAndModuleSnapshot() || options.DisableModuleSnapshot()) {
6231         return;
6232     }
6233     ecmascript::CString path(ecmascript::ohos::OhosConstants::PANDAFILE_AND_MODULE_SNAPSHOT_DIR);
6234     ecmascript::ohos::ModuleSnapshotInterfaces::Serialize(vm, path);
6235 }
6236 
6237 // Ability Runtime trigger module Deseralize when application start.
ModuleDeserialize(EcmaVM * vm,const uint32_t appVersion)6238 void JSNApi::ModuleDeserialize(EcmaVM *vm, const uint32_t appVersion)
6239 {
6240     if (vm->GetJSOptions().DisableJSPandaFileAndModuleSnapshot()) {
6241         return;
6242     }
6243     vm->SetApplicationVersionCode(appVersion);
6244     ecmascript::CString path(ecmascript::ohos::OhosConstants::PANDAFILE_AND_MODULE_SNAPSHOT_DIR);
6245     ecmascript::ohos::ModuleSnapshotInterfaces::Deserialize(vm, path);
6246 }
6247 
SetHostResolveBufferTracker(EcmaVM * vm,std::function<bool (std::string dirPath,uint8_t ** buff,size_t * buffSize,std::string & errorMsg)> cb)6248 void JSNApi::SetHostResolveBufferTracker(EcmaVM *vm,
6249     std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb)
6250 {
6251     vm->SetResolveBufferCallback(cb);
6252 }
6253 
SetHostResolveBufferTrackerForHybridApp(EcmaVM * vm,std::function<bool (std::string dirPath,uint8_t ** buff,size_t * buffSize,std::string & errorMsg)> cb)6254 void JSNApi::SetHostResolveBufferTrackerForHybridApp(EcmaVM *vm,
6255     std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb)
6256 {
6257     vm->SetResolveBufferCallbackForHybridApp(cb);
6258 }
6259 
6260 
SetSearchHapPathTracker(EcmaVM * vm,std::function<bool (const std::string moduleName,std::string & hapPath)> cb)6261 void JSNApi::SetSearchHapPathTracker(EcmaVM *vm,
6262     std::function<bool(const std::string moduleName, std::string &hapPath)> cb)
6263 {
6264     vm->SetSearchHapPathCallBack(cb);
6265 }
6266 
SetMultiThreadCheck(bool multiThreadCheck)6267 void JSNApi::SetMultiThreadCheck(bool multiThreadCheck)
6268 {
6269     EcmaVM::SetMultiThreadCheck(multiThreadCheck);
6270 }
6271 
SetErrorInfoEnhance(bool errorInfoEnhance)6272 void JSNApi::SetErrorInfoEnhance(bool errorInfoEnhance)
6273 {
6274     EcmaVM::SetErrorInfoEnhance(errorInfoEnhance);
6275 }
6276 
SetRequestAotCallback(EcmaVM * vm,const std::function<int32_t (const std::string & bundleName,const std::string & moduleName,int32_t triggerMode)> & cb)6277 void JSNApi::SetRequestAotCallback([[maybe_unused]] EcmaVM *vm, const std::function<int32_t
6278     (const std::string &bundleName, const std::string &moduleName, int32_t triggerMode)> &cb)
6279 {
6280     ecmascript::pgo::PGOProfilerManager::GetInstance()->SetRequestAotCallback(cb);
6281 }
6282 
SetUnloadNativeModuleCallback(EcmaVM * vm,const std::function<bool (const std::string & moduleKey)> & cb)6283 void JSNApi::SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb)
6284 {
6285     vm->SetUnloadNativeModuleCallback(cb);
6286 }
6287 
SetNativePtrGetter(EcmaVM * vm,void * cb)6288 void JSNApi::SetNativePtrGetter(EcmaVM *vm, void* cb)
6289 {
6290     vm->SetNativePtrGetter(reinterpret_cast<ecmascript::NativePtrGetter>(cb));
6291 }
6292 
SetHostEnqueueJob(const EcmaVM * vm,Local<JSValueRef> cb,QueueType queueType)6293 void JSNApi::SetHostEnqueueJob(const EcmaVM *vm, Local<JSValueRef> cb, QueueType queueType)
6294 {
6295     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6296     ecmascript::ThreadManagedScope scope(thread);
6297     JSHandle<JSFunction> fun = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(cb));
6298     JSHandle<TaggedArray> array = vm->GetFactory()->EmptyArray();
6299     JSHandle<MicroJobQueue> job = vm->GetMicroJobQueue();
6300     MicroJobQueue::EnqueueJob(thread, job, queueType, fun, array);
6301 }
6302 
ExecuteModuleFromBuffer(EcmaVM * vm,const void * data,int32_t size,const std::string & file)6303 bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file)
6304 {
6305     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
6306     ecmascript::ThreadManagedScope scope(thread);
6307     if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, file.c_str(), false,
6308         ecmascript::ExecuteTypes::NATIVE_MODULE)) {
6309         if (thread->HasPendingException()) {
6310             ecmascript::JsStackInfo::BuildCrashInfo(thread);
6311         }
6312         std::cerr << "Cannot execute panda file from memory" << std::endl;
6313         return false;
6314     }
6315     return true;
6316 }
6317 
GetFileType(const uint8_t * data,int32_t size)6318 JSNApi::PandaFileType JSNApi::GetFileType(const uint8_t *data, int32_t size)
6319 {
6320     panda_file::PandaFileType fileType = panda_file::GetFileType(data, size);
6321     switch (fileType) {
6322         case panda_file::PandaFileType::FILE_FORMAT_INVALID: {
6323             return JSNApi::PandaFileType::FILE_FORMAT_INVALID;
6324         }
6325         case panda_file::PandaFileType::FILE_DYNAMIC: {
6326             return JSNApi::PandaFileType::FILE_DYNAMIC;
6327         }
6328         case panda_file::PandaFileType::FILE_STATIC: {
6329             return JSNApi::PandaFileType::FILE_STATIC;
6330         }
6331         default: {
6332             UNREACHABLE();
6333         }
6334     }
6335 }
6336 
NapiHasProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)6337 Local<JSValueRef> JSNApi::NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
6338 {
6339     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6340     ecmascript::ThreadManagedScope managedScope(thread);
6341     EscapeLocalScope scope(vm);
6342     JSHandle<JSTaggedValue> obj(nativeObj);
6343     if (!(obj->IsECMAObject() || obj->IsCallable())) {
6344         // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
6345         // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
6346         JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
6347         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
6348     }
6349     LOG_IF_SPECIAL(obj, ERROR);
6350     JSMutableHandle<JSTaggedValue> keyValue(key);
6351     JSTaggedValue res = ObjectFastOperator::TryFastHasProperty(thread, obj.GetTaggedValue(),
6352                                                                keyValue);
6353     if (!res.IsHole()) {
6354         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6355         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6356     }
6357     auto ret = JSTaggedValue(JSTaggedValue::HasProperty(thread, obj, keyValue));
6358     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
6359 }
6360 
NapiHasOwnProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)6361 Local<JSValueRef> JSNApi::NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
6362 {
6363     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6364     ecmascript::ThreadManagedScope managedScope(thread);
6365     EscapeLocalScope scope(vm);
6366     JSHandle<JSTaggedValue> obj(nativeObj);
6367     if (!(obj->IsECMAObject() || obj->IsCallable())) {
6368         // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
6369         // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
6370         JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
6371         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
6372     }
6373     LOG_IF_SPECIAL(obj, ERROR);
6374     JSMutableHandle<JSTaggedValue> keyValue(key);
6375     JSTaggedValue res = ObjectFastOperator::TryFastHasProperty(thread, obj.GetTaggedValue(),
6376                                                                keyValue);
6377     if (!res.IsHole()) {
6378         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6379         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6380     }
6381     auto ret = JSTaggedValue(JSTaggedValue::HasProperty(thread, obj, keyValue));
6382     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
6383 }
6384 
NapiGetProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)6385 Local<JSValueRef> JSNApi::NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
6386 {
6387     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6388     ecmascript::ThreadManagedScope managedScope(thread);
6389     EscapeLocalScope scope(vm);
6390     JSHandle<JSTaggedValue> obj(nativeObj);
6391     if (!(obj->IsECMAObject() || obj->IsCallable())) {
6392         // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
6393         // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
6394         JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
6395         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
6396     }
6397     LOG_IF_SPECIAL(obj, ERROR);
6398     JSMutableHandle<JSTaggedValue> keyValue(key);
6399     if (!obj->IsHeapObject()) {
6400         OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
6401         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6402         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()));
6403     }
6404 
6405     JSTaggedValue res = ObjectFastOperator::TryFastGetPropertyByValue(thread, obj.GetTaggedValue(),
6406                                                                       keyValue);
6407     if (!res.IsHole()) {
6408         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6409         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6410     }
6411 
6412     JSTaggedValue ret = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
6413                                                                    keyValue.GetTaggedValue());
6414     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6415     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
6416 }
6417 
NapiDeleteProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)6418 Local<JSValueRef> JSNApi::NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
6419 {
6420     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6421     ecmascript::ThreadManagedScope managedScope(thread);
6422     EscapeLocalScope scope(vm);
6423     JSHandle<JSTaggedValue> obj(nativeObj);
6424     if (!(obj->IsECMAObject() || obj->IsCallable())) {
6425         // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
6426         // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
6427         JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
6428         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
6429     }
6430     LOG_IF_SPECIAL(obj, ERROR);
6431     JSMutableHandle<JSTaggedValue> keyValue(key);
6432     if (keyValue->IsString() && !EcmaStringAccessor(keyValue.GetTaggedValue()).IsInternString()) {
6433         [[maybe_unused]] ecmascript::EcmaHandleScope handleScope(thread);
6434         auto string = thread->GetEcmaVM()->GetFactory()->InternString(keyValue);
6435         EcmaStringAccessor(string).SetInternString();
6436         keyValue.Update(JSTaggedValue(string));
6437     }
6438     auto ret = JSTaggedValue(JSTaggedValue::DeleteProperty(thread, obj, keyValue));
6439     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
6440 }
6441 
NapiGetNamedProperty(const EcmaVM * vm,uintptr_t nativeObj,const char * utf8Key)6442 Local<JSValueRef> JSNApi::NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key)
6443 {
6444     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6445     ecmascript::ThreadManagedScope managedScope(thread);
6446     EscapeLocalScope scope(vm);
6447     JSHandle<JSTaggedValue> obj(nativeObj);
6448     if (UNLIKELY(!(obj->IsECMAObject() || obj->IsCallable()))) {
6449         // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
6450         // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
6451         JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
6452         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
6453     }
6454     LOG_IF_SPECIAL(obj, ERROR);
6455     ObjectFactory *factory = vm->GetFactory();
6456     JSHandle<JSTaggedValue> keyValue(factory->NewFromUtf8(utf8Key));
6457 
6458     // FastPath - Try find key entry in cache directly.
6459     JSTaggedValue res = ObjectFastOperator::TryGetPropertyByNameThroughCacheAtLocal(thread, obj.GetTaggedValue(),
6460                                                                                     keyValue.GetTaggedValue());
6461     if (!res.IsHole()) {
6462         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6463         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6464     }
6465     if (!KeyIsNumber(utf8Key)) {
6466         res = ObjectFastOperator::GetPropertyByName(thread, obj.GetTaggedValue(), keyValue.GetTaggedValue());
6467         if (res.IsHole()) {
6468             res = JSTaggedValue::GetProperty(thread, obj, keyValue).GetValue().GetTaggedValue();
6469             RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6470             return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6471         }
6472         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6473         return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6474     }
6475     res = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(), keyValue.GetTaggedValue());
6476     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6477     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
6478 }
6479 
CreateLocal(const EcmaVM * vm,panda::JSValueRef src)6480 Local<JSValueRef> JSNApi::CreateLocal(const EcmaVM *vm, panda::JSValueRef src)
6481 {
6482     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6483     JSHandle<JSTaggedValue> handle(thread, JSNApiHelper::ToJSTaggedValue(&src));
6484     return JSNApiHelper::ToLocal<JSValueRef>(handle);
6485 }
6486 
GetExportObject(EcmaVM * vm,const std::string & file,const std::string & key)6487 Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key)
6488 {
6489     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6490     ecmascript::ThreadManagedScope scope(thread);
6491     ecmascript::CString entry = file.c_str();
6492     ecmascript::CString name = vm->GetAssetPath();
6493     if (!vm->IsBundlePack()) {
6494         ModulePathHelper::ParseAbcPathAndOhmUrl(vm, entry, name, entry);
6495         std::shared_ptr<JSPandaFile> jsPandaFile =
6496             JSPandaFileManager::GetInstance()->LoadJSPandaFile(
6497                 thread, name, entry.c_str(), false, ecmascript::ExecuteTypes::STATIC);
6498         if (jsPandaFile == nullptr) {
6499             JSHandle<JSTaggedValue> exportObj(thread, JSTaggedValue::Null());
6500             return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6501         }
6502         if (!jsPandaFile->IsRecordWithBundleName()) {
6503             PathHelper::AdaptOldIsaRecord(entry);
6504         }
6505     }
6506     ecmascript::ModuleManager *moduleManager = thread->GetModuleManager();
6507     JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->GetImportedModule(entry);
6508     if (ecmaModule->GetIsNewBcVersion()) {
6509         int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key.c_str());
6510         JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
6511         JSHandle<JSTaggedValue> exportObj(thread, result);
6512         return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6513     }
6514     ObjectFactory *factory = vm->GetFactory();
6515     JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
6516 
6517     JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
6518     JSHandle<JSTaggedValue> exportObj(thread, result);
6519     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6520 }
6521 
GetExportObjectFromBuffer(EcmaVM * vm,const std::string & file,const std::string & key)6522 Local<ObjectRef> JSNApi::GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file,
6523                                                    const std::string &key)
6524 {
6525     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6526     ecmascript::ThreadManagedScope scope(thread);
6527     ecmascript::ModuleManager *moduleManager = thread->GetModuleManager();
6528     JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->GetImportedModule(file.c_str());
6529     if (ecmaModule->GetIsNewBcVersion()) {
6530         int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key.c_str());
6531         JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
6532         JSHandle<JSTaggedValue> exportObj(thread, result);
6533         return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6534     }
6535 
6536     ObjectFactory *factory = vm->GetFactory();
6537     JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
6538     JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
6539     JSHandle<JSTaggedValue> exportObj(thread, result);
6540     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6541 }
6542 
GetExportObjectFromOhmUrl(EcmaVM * vm,const std::string & ohmUrl,const std::string & key)6543 Local<ObjectRef> JSNApi::GetExportObjectFromOhmUrl(EcmaVM *vm, const std::string &ohmUrl, const std::string &key)
6544 {
6545     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6546     ecmascript::ThreadManagedScope scope(thread);
6547     ecmascript::CString recordName;
6548     // Check and translate OhmUrl to recordName
6549     if (!ModulePathHelper::CheckAndGetRecordName(thread, ohmUrl.c_str(), recordName)) {
6550         LOG_FULL(FATAL) << "ExecuteSecureWithOhmUrl: Invalid input OhmUrl: " << ohmUrl;
6551         return JSValueRef::Undefined(vm);
6552     }
6553     ecmascript::ModuleManager *moduleManager = thread->GetModuleManager();
6554     JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->GetImportedModule(recordName.c_str());
6555     int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key.c_str());
6556     JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
6557     JSHandle<JSTaggedValue> exportObj(thread, result);
6558     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6559 }
6560 
ExecuteNativeModule(EcmaVM * vm,const std::string & key)6561 Local<ObjectRef> JSNApi::ExecuteNativeModule(EcmaVM *vm, const std::string &key)
6562 {
6563     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
6564     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6565     ecmascript::ModuleManager *moduleManager = thread->GetModuleManager();
6566     JSHandle<JSTaggedValue> exportObj = moduleManager->LoadNativeModule(thread, key.c_str());
6567     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
6568 }
6569 
GetModuleNameSpaceFromFile(EcmaVM * vm,const std::string & file)6570 Local<ObjectRef> JSNApi::GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file)
6571 {
6572     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6573     ecmascript::ThreadManagedScope managedScope(thread);
6574     std::pair<std::string, std::string> moduleInfo = vm->GetCurrentModuleInfo(false);
6575     if (thread->HasPendingException()) {
6576         thread->HandleUncaughtException();
6577         return JSValueRef::Undefined(vm);
6578     }
6579     ecmascript::CString moduleName = moduleInfo.first.c_str();
6580     ecmascript::CString abcPath = moduleInfo.second.c_str();
6581     JSHandle<JSTaggedValue> moduleNamespace =
6582         ecmascript::NapiModuleLoader::LoadModuleNameSpace(vm, file.c_str(), moduleName, abcPath);
6583     return JSNApiHelper::ToLocal<ObjectRef>(moduleNamespace);
6584 }
6585 
6586 
6587 template<ForHybridApp isHybrid>
GetModuleNameSpaceWithModuleInfo(EcmaVM * vm,const std::string & file,const std::string & module_path)6588 Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file,
6589                                                           const std::string &module_path)
6590 {
6591     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6592     ecmascript::ThreadManagedScope managedScope(thread);
6593     ecmascript::CString requestPath = file.c_str();
6594     ecmascript::CString modulePath = module_path.c_str();
6595     JSHandle<JSTaggedValue> nameSp =
6596         ecmascript::NapiModuleLoader::LoadModuleNameSpace<isHybrid>(vm, requestPath, modulePath);
6597     return JSNApiHelper::ToLocal<ObjectRef>(nameSp);
6598 }
6599 template Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfo<ForHybridApp::Normal>(EcmaVM *vm,
6600     const std::string &file, const std::string &module_path);
6601 template Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfo<ForHybridApp::Hybrid>(EcmaVM *vm,
6602     const std::string &file, const std::string &module_path);
6603 
GetModuleNameSpaceWithModuleInfoForNormalApp(EcmaVM * vm,const std::string & file,const std::string & module_path)6604 Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfoForNormalApp(EcmaVM *vm, const std::string &file,
6605     const std::string &module_path)
6606 {
6607     return JSNApi::GetModuleNameSpaceWithModuleInfo<ForHybridApp::Normal>(vm, file, module_path);
6608 }
GetModuleNameSpaceWithModuleInfoForHybridApp(EcmaVM * vm,const std::string & file,const std::string & module_path)6609 Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfoForHybridApp(EcmaVM *vm, const std::string &file,
6610     const std::string &module_path)
6611 {
6612     return JSNApi::GetModuleNameSpaceWithModuleInfo<ForHybridApp::Hybrid>(vm, file, module_path);
6613 }
6614 
6615 // ---------------------------------- Promise -------------------------------------
Catch(const EcmaVM * vm,Local<FunctionRef> handler)6616 Local<PromiseRef> PromiseRef::Catch(const EcmaVM *vm, Local<FunctionRef> handler)
6617 {
6618     ecmascript::ThreadManagedScope scope(vm->GetJSThread());
6619     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6620     const GlobalEnvConstants *constants = thread->GlobalConstants();
6621 
6622     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
6623     LOG_IF_SPECIAL(promise, ERROR);
6624     JSHandle<JSTaggedValue> catchKey(thread, constants->GetPromiseCatchString());
6625     JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(handler);
6626     JSHandle<JSTaggedValue> undefined = constants->GetHandledUndefined();
6627     EcmaRuntimeCallInfo *info =
6628         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 1);
6629     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6630 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
6631     thread->CheckJSTaggedType(reject.GetTaggedValue().GetRawData());
6632 #endif
6633     info->SetCallArg(reject.GetTaggedValue());
6634     JSTaggedValue result = JSFunction::Invoke(info, catchKey);
6635 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
6636     thread->CheckJSTaggedType(result.GetRawData());
6637 #endif
6638     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6639     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
6640 }
6641 
Finally(const EcmaVM * vm,Local<FunctionRef> handler)6642 Local<PromiseRef> PromiseRef::Finally(const EcmaVM *vm, Local<FunctionRef> handler)
6643 {
6644     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6645     ecmascript::ThreadManagedScope scope(thread);
6646     const GlobalEnvConstants *constants = thread->GlobalConstants();
6647 
6648     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
6649     LOG_IF_SPECIAL(promise, ERROR);
6650     JSHandle<JSTaggedValue> finallyKey = constants->GetHandledPromiseFinallyString();
6651     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
6652     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
6653     EcmaRuntimeCallInfo *info =
6654         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
6655     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6656 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
6657     thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
6658     thread->CheckJSTaggedType(undefined.GetTaggedValue().GetRawData());
6659 #endif
6660     info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
6661     JSTaggedValue result = JSFunction::Invoke(info, finallyKey);
6662 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
6663     thread->CheckJSTaggedType(result.GetRawData());
6664 #endif
6665     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6666     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
6667 }
6668 
Then(const EcmaVM * vm,Local<FunctionRef> handler)6669 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> handler)
6670 {
6671     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6672     ecmascript::ThreadManagedScope scope(thread);
6673     const GlobalEnvConstants *constants = thread->GlobalConstants();
6674 
6675     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
6676     LOG_IF_SPECIAL(promise, ERROR);
6677     JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
6678     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
6679     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
6680     EcmaRuntimeCallInfo *info =
6681         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
6682     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6683 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
6684     thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
6685     thread->CheckJSTaggedType(undefined.GetTaggedValue().GetRawData());
6686 #endif
6687     info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
6688     JSTaggedValue result = JSFunction::Invoke(info, thenKey);
6689 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
6690     thread->CheckJSTaggedType(result.GetRawData());
6691 #endif
6692     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6693     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
6694 }
6695 
Then(const EcmaVM * vm,Local<FunctionRef> onFulfilled,Local<FunctionRef> onRejected)6696 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected)
6697 {
6698     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6699     ecmascript::ThreadManagedScope scope(thread);
6700     const GlobalEnvConstants *constants = thread->GlobalConstants();
6701 
6702     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
6703     LOG_IF_SPECIAL(promise, ERROR);
6704     JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
6705     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(onFulfilled);
6706     JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(onRejected);
6707     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
6708     EcmaRuntimeCallInfo *info =
6709         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
6710     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6711 #if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
6712     thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
6713     thread->CheckJSTaggedType(reject.GetTaggedValue().GetRawData());
6714 #endif
6715     info->SetCallArg(resolver.GetTaggedValue(), reject.GetTaggedValue());
6716     JSTaggedValue result = JSFunction::Invoke(info, thenKey);
6717 #if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
6718     thread->CheckJSTaggedType(result.GetRawData());
6719 #endif
6720     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
6721     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
6722 }
6723 
GetPromiseState(const EcmaVM * vm)6724 Local<JSValueRef> PromiseRef::GetPromiseState(const EcmaVM *vm)
6725 {
6726     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6727     ecmascript::ThreadManagedScope scope(thread);
6728     JSHandle<JSPromise> promise(JSNApiHelper::ToJSHandle(this));
6729     LOG_IF_SPECIAL(promise, ERROR);
6730 
6731     ecmascript::PromiseState state = promise->GetPromiseState();
6732     std::string promiseStateStr;
6733     switch (state) {
6734         case ecmascript::PromiseState::PENDING:
6735             promiseStateStr = "Pending";
6736             break;
6737         case ecmascript::PromiseState::FULFILLED:
6738             promiseStateStr = "Fulfilled";
6739             break;
6740         case ecmascript::PromiseState::REJECTED:
6741             promiseStateStr = "Rejected";
6742             break;
6743     }
6744 
6745     ObjectFactory *factory = vm->GetFactory();
6746     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(factory->NewFromStdString(promiseStateStr)));
6747 }
6748 
GetPromiseResult(const EcmaVM * vm)6749 Local<JSValueRef> PromiseRef::GetPromiseResult(const EcmaVM *vm)
6750 {
6751     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6752     ecmascript::ThreadManagedScope scope(thread);
6753     JSHandle<JSPromise> promise(JSNApiHelper::ToJSHandle(this));
6754     LOG_IF_SPECIAL(promise, ERROR);
6755 
6756     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, promise->GetPromiseResult(thread)));
6757 }
6758 // ---------------------------------- ProxyRef -----------------------------------------
GetHandler(const EcmaVM * vm)6759 Local<JSValueRef> ProxyRef::GetHandler(const EcmaVM *vm)
6760 {
6761     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6762     ecmascript::ThreadManagedScope scope(thread);
6763     JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
6764     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, jsProxy->GetHandler(thread)));
6765 }
6766 
GetTarget(const EcmaVM * vm)6767 Local<JSValueRef> ProxyRef::GetTarget(const EcmaVM *vm)
6768 {
6769     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6770     ecmascript::ThreadManagedScope scope(thread);
6771     JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
6772     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, jsProxy->GetTarget(thread)));
6773 }
6774 
IsRevoked()6775 bool ProxyRef::IsRevoked()
6776 {
6777     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
6778     JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
6779     return jsProxy->GetIsRevoked();
6780 }
6781 
6782 // ---------------------------------- SetRef --------------------------------------
GetSize(const EcmaVM * vm)6783 int32_t SetRef::GetSize(const EcmaVM *vm)
6784 {
6785     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6786     JSThread *thread = vm->GetJSThread();
6787     ecmascript::ThreadManagedScope managedScope(thread);
6788     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
6789     return set->GetSize(thread);
6790 }
6791 
GetTotalElements(const EcmaVM * vm)6792 int32_t SetRef::GetTotalElements(const EcmaVM *vm)
6793 {
6794     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6795     JSThread *thread = vm->GetJSThread();
6796     ecmascript::ThreadManagedScope managedScope(thread);
6797     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
6798     return static_cast<int>(set->GetSize(thread)) +
6799            LinkedHashSet::Cast(set->GetLinkedSet(thread).GetTaggedObject())->NumberOfDeletedElements();
6800 }
6801 
GetValue(const EcmaVM * vm,int entry)6802 Local<JSValueRef> SetRef::GetValue(const EcmaVM *vm, int entry)
6803 {
6804     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6805     ecmascript::ThreadManagedScope managedScope(thread);
6806     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
6807     LOG_IF_SPECIAL(set, FATAL);
6808     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, set->GetValue(thread, entry)));
6809 }
6810 
New(const EcmaVM * vm)6811 Local<SetRef> SetRef::New(const EcmaVM *vm)
6812 {
6813     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6814     ecmascript::ThreadManagedScope managedScope(thread);
6815     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
6816     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
6817     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsSetFunction();
6818     JSHandle<JSSet> set =
6819         JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
6820     JSHandle<LinkedHashSet> hashSet = LinkedHashSet::Create(thread);
6821     set->SetLinkedSet(thread, hashSet);
6822     JSHandle<JSTaggedValue> setTag = JSHandle<JSTaggedValue>::Cast(set);
6823     return JSNApiHelper::ToLocal<SetRef>(setTag);
6824 }
6825 
Add(const EcmaVM * vm,Local<JSValueRef> value)6826 void SetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
6827 {
6828     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6829     ecmascript::ThreadManagedScope managedScope(thread);
6830     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
6831     LOG_IF_SPECIAL(set, ERROR);
6832     JSSet::Add(thread, set, JSNApiHelper::ToJSHandle(value));
6833 }
6834 
6835 // ---------------------------------- WeakMapRef --------------------------------------
GetSize(const EcmaVM * vm)6836 int32_t WeakMapRef::GetSize(const EcmaVM *vm)
6837 {
6838     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6839     JSThread *thread = vm->GetJSThread();
6840     ecmascript::ThreadManagedScope managedScope(thread);
6841     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6842     return weakMap->GetSize(thread);
6843 }
6844 
GetTotalElements(const EcmaVM * vm)6845 int32_t WeakMapRef::GetTotalElements(const EcmaVM *vm)
6846 {
6847     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6848     JSThread *thread = vm->GetJSThread();
6849     ecmascript::ThreadManagedScope managedScope(thread);
6850     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6851     return weakMap->GetSize(thread) +
6852            LinkedHashMap::Cast(weakMap->GetLinkedMap(thread).GetTaggedObject())->NumberOfDeletedElements();
6853 }
6854 
GetKey(const EcmaVM * vm,int entry)6855 Local<JSValueRef> WeakMapRef::GetKey(const EcmaVM *vm, int entry)
6856 {
6857     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6858     ecmascript::ThreadManagedScope managedScope(thread);
6859     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6860     LOG_IF_SPECIAL(weakMap, FATAL);
6861     JSTaggedValue key = weakMap->GetKey(thread, entry);
6862     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, key.GetWeakRawValue()));
6863 }
6864 
GetValue(const EcmaVM * vm,int entry)6865 Local<JSValueRef> WeakMapRef::GetValue(const EcmaVM *vm, int entry)
6866 {
6867     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6868     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6869     LOG_IF_SPECIAL(weakMap, FATAL);
6870     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, weakMap->GetValue(thread, entry)));
6871 }
6872 
New(const EcmaVM * vm)6873 Local<WeakMapRef> WeakMapRef::New(const EcmaVM *vm)
6874 {
6875     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6876     ecmascript::ThreadManagedScope managedScope(thread);
6877     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
6878     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
6879     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakMapFunction();
6880     JSHandle<JSWeakMap> weakMap =
6881         JSHandle<JSWeakMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
6882     JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
6883     weakMap->SetLinkedMap(thread, hashMap);
6884     JSHandle<JSTaggedValue> weakMapTag = JSHandle<JSTaggedValue>::Cast(weakMap);
6885     return JSNApiHelper::ToLocal<WeakMapRef>(weakMapTag);
6886 }
6887 
Set(const EcmaVM * vm,const Local<JSValueRef> & key,const Local<JSValueRef> & value)6888 void WeakMapRef::Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value)
6889 {
6890     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6891     ecmascript::ThreadManagedScope managedScope(thread);
6892     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6893     LOG_IF_SPECIAL(weakMap, FATAL);
6894     JSWeakMap::Set(thread, weakMap, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
6895 }
6896 
Has(const EcmaVM * vm,Local<JSValueRef> key)6897 bool WeakMapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
6898 {
6899     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
6900     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
6901     ecmascript::ThreadManagedScope managedScope(thread);
6902     JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6903     return weakMap->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
6904 }
6905 
6906 // ---------------------------------- WeakSetRef --------------------------------------
GetSize(const EcmaVM * vm)6907 int32_t WeakSetRef::GetSize(const EcmaVM *vm)
6908 {
6909     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6910     JSThread *thread = vm->GetJSThread();
6911     ecmascript::ThreadManagedScope managedScope(thread);
6912     JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6913     return weakSet->GetSize(thread);
6914 }
6915 
GetTotalElements(const EcmaVM * vm)6916 int32_t WeakSetRef::GetTotalElements(const EcmaVM *vm)
6917 {
6918     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6919     JSThread *thread = vm->GetJSThread();
6920     ecmascript::ThreadManagedScope managedScope(thread);
6921     JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6922     return weakSet->GetSize(thread) +
6923            LinkedHashSet::Cast(weakSet->GetLinkedSet(thread).GetTaggedObject())->NumberOfDeletedElements();
6924 }
6925 
GetValue(const EcmaVM * vm,int entry)6926 Local<JSValueRef> WeakSetRef::GetValue(const EcmaVM *vm, int entry)
6927 {
6928     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6929     ecmascript::ThreadManagedScope managedScope(thread);
6930     JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6931     LOG_IF_SPECIAL(weakSet, FATAL);
6932     JSTaggedValue value = weakSet->GetValue(thread, entry);
6933     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, value.GetWeakRawValue()));
6934 }
6935 
New(const EcmaVM * vm)6936 Local<WeakSetRef> WeakSetRef::New(const EcmaVM *vm)
6937 {
6938     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6939     ecmascript::ThreadManagedScope managedScope(thread);
6940     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
6941     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
6942     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakSetFunction();
6943     JSHandle<JSWeakSet> weakSet =
6944         JSHandle<JSWeakSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
6945     JSHandle<LinkedHashSet> hashWeakSet = LinkedHashSet::Create(thread);
6946     weakSet->SetLinkedSet(thread, hashWeakSet);
6947     JSHandle<JSTaggedValue> setTag = JSHandle<JSTaggedValue>::Cast(weakSet);
6948     return JSNApiHelper::ToLocal<WeakSetRef>(setTag);
6949 }
6950 
Add(const EcmaVM * vm,Local<JSValueRef> value)6951 void WeakSetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
6952 {
6953     CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6954     ecmascript::ThreadManagedScope managedScope(thread);
6955     JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6956     LOG_IF_SPECIAL(weakSet, ERROR);
6957     JSWeakSet::Add(thread, weakSet, JSNApiHelper::ToJSHandle(value));
6958 }
6959 
~TryCatch()6960 TryCatch::~TryCatch() {}
6961 
HasCaught() const6962 bool TryCatch::HasCaught() const
6963 {
6964     return ecmaVm_->GetJSThread()->HasPendingException();
6965 }
6966 
Rethrow()6967 void TryCatch::Rethrow()
6968 {
6969     rethrow_ = true;
6970 }
6971 
GetAndClearException()6972 Local<ObjectRef> TryCatch::GetAndClearException()
6973 {
6974     ecmascript::ThreadManagedScope managedScope(ecmaVm_->GetJSThread());
6975     return JSNApiHelper::ToLocal<ObjectRef>(ecmaVm_->GetAndClearEcmaUncaughtException());
6976 }
6977 
GetException()6978 Local<ObjectRef> TryCatch::GetException()
6979 {
6980     ecmascript::ThreadManagedScope managedScope(ecmaVm_->GetJSThread());
6981     return JSNApiHelper::ToLocal<ObjectRef>(ecmaVm_->GetEcmaUncaughtException());
6982 }
6983 
ClearException()6984 void TryCatch::ClearException()
6985 {
6986     ecmaVm_->GetJSThread()->ClearException();
6987 }
6988 
RegisterStringCacheTable(const EcmaVM * vm,uint32_t size)6989 bool ExternalStringCache::RegisterStringCacheTable(const EcmaVM *vm, uint32_t size)
6990 {
6991     auto instance = ecmascript::Runtime::GetInstance();
6992     ASSERT(instance != nullptr);
6993 
6994     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6995     return instance->CreateStringCacheTable(size);
6996 }
6997 
SetCachedString(const EcmaVM * vm,const char * name,uint32_t propertyIndex)6998 bool ExternalStringCache::SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex)
6999 {
7000     auto instance = ecmascript::Runtime::GetInstance();
7001     ASSERT(instance != nullptr);
7002 
7003     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
7004     [[maybe_unused]] LocalScope scope(vm);
7005     ObjectFactory *factory = vm->GetFactory();
7006     JSHandle<EcmaString> str = factory->NewFromUtf8(name);
7007     return instance->SetCachedString(str, propertyIndex);
7008 }
7009 
GetCachedString(const EcmaVM * vm,uint32_t propertyIndex)7010 Local<StringRef> ExternalStringCache::GetCachedString(const EcmaVM *vm, uint32_t propertyIndex)
7011 {
7012     auto instance = ecmascript::Runtime::GetInstance();
7013     ASSERT(instance != nullptr);
7014     auto thread = vm->GetJSThread();
7015     ecmascript::ThreadManagedScope managedScope(thread);
7016     JSHandle<EcmaString> str = instance->GetCachedString(thread, propertyIndex);
7017     return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(str));
7018 }
7019 
HasCachedString(const EcmaVM * vm,uint32_t propertyIndex)7020 bool ExternalStringCache::HasCachedString([[maybe_unused]] const EcmaVM *vm, uint32_t propertyIndex)
7021 {
7022     auto instance = ecmascript::Runtime::GetInstance();
7023     ASSERT(instance != nullptr);
7024     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
7025     return instance->HasCachedString(propertyIndex);
7026 }
7027 
7028 } // namespace panda
7029