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