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