1 /*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H
17 #define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H
18
19 #include <cassert>
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <map>
24 #include <shared_mutex>
25 #include <string>
26 #include <unordered_map>
27 #include <vector>
28
29 #include "ecmascript/base/aligned_struct.h"
30 #include "ecmascript/base/config.h"
31 #include "ecmascript/common.h"
32 #include "ecmascript/cross_vm/jsnapi_expo_hybrid.h"
33 #include "ecmascript/module/js_module_execute_type.h"
34 #include "ecmascript/napi/include/jsnapi_internals.h"
35
36 #ifndef NDEBUG
37 #include "libpandabase/utils/debug.h"
38 #endif
39
40 #ifdef ERROR
41 #undef ERROR
42 #endif
43 namespace panda {
44 class JSNApiHelper;
45 class EscapeLocalScope;
46 class PromiseRejectInfo;
47 template<typename T>
48 class CopyableGlobal;
49 template<typename T>
50 class Global;
51 class JSNApi;
52 class SymbolRef;
53 template<typename T>
54 class Local;
55 class JSValueRef;
56 class PrimitiveRef;
57 class ArrayRef;
58 class BigIntRef;
59 class StringRef;
60 class ObjectRef;
61 class FunctionRef;
62 class NumberRef;
63 class MapIteratorRef;
64 class SendableMapIteratorRef;
65 class BooleanRef;
66 class NativePointerRef;
67 class TypedArrayRef;
68 class JsiRuntimeCallInfo;
69 class RuntimeOption;
70 namespace test {
71 class JSNApiTests;
72 } // namespace test
73 class BufferRef;
74 namespace ecmascript {
75 class EcmaVM;
76 class JSTaggedValue;
77 class JSRuntimeOptions;
78 class EcmaContext;
79 class JSThread;
80 struct EcmaRuntimeCallInfo;
81 namespace base {
82 template<size_t ElementAlign, typename... Ts>
83 struct AlignedStruct;
84 struct AlignedPointer;
85 }
86 namespace job {
87 enum class QueueType : uint8_t {
88 QUEUE_PROMISE,
89 QUEUE_SCRIPT,
90 };
91 }
92 } // namespace ecmascript
93
94 enum class ForHybridApp {
95 Normal,
96 Hybrid
97 };
98
99 struct HmsMap {
100 std::string originalPath;
101 std::string targetPath;
102 uint32_t sinceVersion;
103 };
104
105 struct StackInfo {
106 size_t stackStart;
107 size_t stackSize;
108 };
109
110 using WeakRefClearCallBack = void (*)(void *);
111 using WeakFinalizeTaskCallback = std::function<void()>;
112 using NativePointerCallbackFinishNotify = std::function<void(size_t totalBindSize_)>;
113 using NativePointerCallbackData = std::pair<NativePointerCallback, std::tuple<void*, void*, void*>>;
114 using TriggerGCData = std::pair<void*, uint8_t>;
115 using TriggerGCTaskCallback = std::function<void(TriggerGCData& data)>;
116 using StartIdleMonitorCallback = std::function<void()>;
117 using EcmaVM = ecmascript::EcmaVM;
118 using JSThread = ecmascript::JSThread;
119 using JSTaggedType = uint64_t;
120 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data);
121 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
122 using TimerCallbackFunc = void (*)(void *data);
123 using TimerTaskCallback = void* (*)(EcmaVM *vm, void *data, TimerCallbackFunc func, uint64_t timeout, bool repeat);
124 using CancelTimerCallback = void (*)(void *timerCallbackInfo);
125 using ReleaseSecureMemCallback = std::function<void(void* fileMapper)>;
126 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column,
127 std::string& packageName)>;
128 using DeviceDisconnectCallback = std::function<bool()>;
129 using QueueType = ecmascript::job::QueueType;
130 using OnErrorCallback = std::function<void(Local<ObjectRef> value, void *data)>;
131 using StopPreLoadSoCallback = std::function<void()>;
132
133 #define ECMA_DISALLOW_COPY(className) \
134 className(const className &) = delete; \
135 className &operator=(const className &) = delete
136
137 #define ECMA_DISALLOW_MOVE(className) \
138 className(className &&) = delete; \
139 className &operator=(className &&) = delete
140
141 #ifndef NDEBUG
142 #define ECMA_ASSERT(cond) \
143 if (!(cond)) { \
144 panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \
145 }
146 #else
147 #define ECMA_ASSERT(cond) static_cast<void>(0)
148 #endif
149
150 #define INIT_CRASH_HOLDER(holder, tag) \
151 ArkCrashHolder holder(tag, __FUNCTION__)
152
153 class PUBLIC_API ArkCrashHolder {
154 public:
ArkCrashHolder(const std::string & tag,const std::string & info)155 ArkCrashHolder(const std::string& tag, const std::string& info)
156 {
157 SetCrashObj(tag.c_str(), info.c_str());
158 }
159
ArkCrashHolder(const char * tag,const char * info)160 ArkCrashHolder(const char* tag, const char* info)
161 {
162 SetCrashObj(tag, info);
163 }
164
165 ~ArkCrashHolder();
166
167 void UpdateCallbackPtr(uintptr_t addr);
168
169 private:
170 void SetCrashObj(const char* tag, const char* info);
171
172 uintptr_t handle_ {0};
173
174 char* data_ {nullptr};
175 size_t size_ {0};
176 };
177
178 class PUBLIC_API AsyncNativeCallbacksPack {
179 public:
180 AsyncNativeCallbacksPack() = default;
181 ~AsyncNativeCallbacksPack() = default;
182 AsyncNativeCallbacksPack(AsyncNativeCallbacksPack&&) = default;
183 AsyncNativeCallbacksPack& operator=(AsyncNativeCallbacksPack&&) = default;
184 AsyncNativeCallbacksPack(const AsyncNativeCallbacksPack &) = default;
185 AsyncNativeCallbacksPack &operator=(const AsyncNativeCallbacksPack &) = default;
186
Clear()187 void Clear()
188 {
189 callBacks_.clear();
190 totalBindingSize_ = 0;
191 notify_ = nullptr;
192 }
193
TotallyEmpty()194 bool TotallyEmpty() const
195 {
196 return callBacks_.empty() && totalBindingSize_ == 0 && notify_ == nullptr;
197 }
198
Empty()199 bool Empty() const
200 {
201 return callBacks_.empty();
202 }
203
RegisterFinishNotify(NativePointerCallbackFinishNotify notify)204 void RegisterFinishNotify(NativePointerCallbackFinishNotify notify)
205 {
206 notify_ = notify;
207 }
208
GetNumCallBacks()209 size_t GetNumCallBacks() const
210 {
211 return callBacks_.size();
212 }
213
ProcessAll(const char * tag)214 void ProcessAll(const char* tag)
215 {
216 INIT_CRASH_HOLDER(holder, tag);
217 for (auto &iter : callBacks_) {
218 NativePointerCallback callback = iter.first;
219 std::tuple<void*, void*, void*> ¶m = iter.second;
220 if (callback != nullptr) {
221 holder.UpdateCallbackPtr(reinterpret_cast<uintptr_t>(callback));
222 callback(std::get<0>(param), std::get<1>(param), std::get<2>(param)); // 2 is the param.
223 }
224 }
225 NotifyFinish();
226 }
227
GetTotalBindingSize()228 size_t GetTotalBindingSize() const
229 {
230 return totalBindingSize_;
231 }
232
AddCallback(NativePointerCallbackData callback,size_t bindingSize)233 void AddCallback(NativePointerCallbackData callback, size_t bindingSize)
234 {
235 callBacks_.emplace_back(callback);
236 totalBindingSize_ += bindingSize;
237 }
238 private:
NotifyFinish()239 void NotifyFinish() const
240 {
241 if (notify_ != nullptr) {
242 notify_(totalBindingSize_);
243 }
244 }
245
246 std::vector<NativePointerCallbackData> callBacks_ {};
247 size_t totalBindingSize_ {0};
248 NativePointerCallbackFinishNotify notify_ {nullptr};
249 };
250 using NativePointerTaskCallback = std::function<void(AsyncNativeCallbacksPack *callbacksPack)>;
251
252 template<typename T>
253 class PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
254 public:
255 inline Local() = default;
256
257 template<typename S>
Local(const Local<S> & current)258 inline Local(const Local<S> ¤t) : address_(reinterpret_cast<uintptr_t>(*current))
259 {
260 // Check
261 }
262
263 Local(const EcmaVM *vm, const Global<T> ¤t);
264
265 Local(const EcmaVM *vm, const CopyableGlobal<T> ¤t);
266
267 ~Local() = default;
268
269 inline T *operator*() const
270 {
271 return GetAddress();
272 }
273
274 inline T *operator->() const
275 {
276 return GetAddress();
277 }
278
IsEmpty()279 inline bool IsEmpty() const
280 {
281 return GetAddress() == nullptr;
282 }
283
Empty()284 inline void Empty()
285 {
286 address_ = 0;
287 }
288
IsNull()289 inline bool IsNull() const
290 {
291 return IsEmpty() || GetAddress()->IsHole();
292 }
293
Local(uintptr_t addr)294 explicit inline Local(uintptr_t addr) : address_(addr) {}
295
296 inline bool operator==(const Local<T> &other) const
297 {
298 return *reinterpret_cast<JSTaggedType *>(GetAddress()) ==
299 *reinterpret_cast<JSTaggedType *>(other.GetAddress());
300 }
301
302 private:
GetAddress()303 inline T *GetAddress() const
304 {
305 return reinterpret_cast<T *>(address_);
306 };
307 uintptr_t address_ = 0U;
308 friend JSNApiHelper;
309 friend EscapeLocalScope;
310 friend JsiRuntimeCallInfo;
311 };
312
313 /**
314 * A Copyable global handle, keeps a separate global handle for each CopyableGlobal.
315 *
316 * Support Copy Constructor and Assign, Move Constructor And Assign.
317 *
318 * If destructed, the global handle held will be automatically released.
319 *
320 * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or
321 * a value passing return value and so on.
322 */
323 template<typename T>
324 class PUBLIC_API CopyableGlobal {
325 public:
326 inline CopyableGlobal() = default;
~CopyableGlobal()327 ~CopyableGlobal()
328 {
329 Free();
330 }
331
CopyableGlobal(const CopyableGlobal & that)332 inline CopyableGlobal(const CopyableGlobal &that)
333 {
334 Copy(that);
335 }
336
337 inline CopyableGlobal &operator=(const CopyableGlobal &that)
338 {
339 Copy(that);
340 return *this;
341 }
342
CopyableGlobal(CopyableGlobal && that)343 inline CopyableGlobal(CopyableGlobal &&that)
344 {
345 Move(that);
346 }
347
348 inline CopyableGlobal &operator=(CopyableGlobal &&that)
349 {
350 Move(that);
351 return *this;
352 }
353
354 template<typename S>
355 CopyableGlobal(const EcmaVM *vm, const Local<S> ¤t);
356
357 CopyableGlobal(const EcmaVM *vm, const Local<T> ¤t);
358
359 template<typename S>
CopyableGlobal(const CopyableGlobal<S> & that)360 CopyableGlobal(const CopyableGlobal<S> &that)
361 {
362 Copy(that);
363 }
364
Reset()365 void Reset()
366 {
367 Free();
368 }
369
ToLocal()370 Local<T> ToLocal() const
371 {
372 if (IsEmpty()) {
373 return Local<T>();
374 }
375 return Local<T>(vm_, *this);
376 }
377
Empty()378 void Empty()
379 {
380 address_ = 0;
381 }
382
383 inline T *operator*() const
384 {
385 return GetAddress();
386 }
387
388 inline T *operator->() const
389 {
390 return GetAddress();
391 }
392
IsEmpty()393 inline bool IsEmpty() const
394 {
395 return GetAddress() == nullptr;
396 }
397
398 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
399 WeakRefClearCallBack nativeFinalizeCallback);
400 void SetWeak();
401
402 void ClearWeak();
403
404 bool IsWeak() const;
405
GetEcmaVM()406 const EcmaVM *GetEcmaVM() const
407 {
408 return vm_;
409 }
410
411 private:
GetAddress()412 inline T *GetAddress() const
413 {
414 return reinterpret_cast<T *>(address_);
415 };
416 inline void Copy(const CopyableGlobal &that);
417 template<typename S>
418 inline void Copy(const CopyableGlobal<S> &that);
419 inline void Move(CopyableGlobal &that);
420 inline void Free();
421 uintptr_t address_ = 0U;
422 const EcmaVM *vm_ {nullptr};
423 };
424
425 template<typename T>
426 class PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions
427 public:
428 inline Global() = default;
429
Global(const Global & that)430 inline Global(const Global &that)
431 {
432 Update(that);
433 }
434
435 inline Global &operator=(const Global &that)
436 {
437 Update(that);
438 return *this;
439 }
440
Global(Global && that)441 inline Global(Global &&that)
442 {
443 Update(that);
444 }
445
446 inline Global &operator=(Global &&that)
447 {
448 Update(that);
449 return *this;
450 }
451
452 template<typename S>
453 Global(const EcmaVM *vm, const Local<S> ¤t);
454 template<typename S>
455 Global(const EcmaVM *vm, const Global<S> ¤t);
456
457 ~Global() = default;
458
ToLocal()459 Local<T> ToLocal() const
460 {
461 if (IsEmpty()) {
462 return Local<T>();
463 }
464 return Local<T>(vm_, *this);
465 }
466
ToLocal(const EcmaVM * vm)467 Local<T> ToLocal(const EcmaVM *vm) const
468 {
469 return Local<T>(vm, *this);
470 }
471
Empty()472 void Empty()
473 {
474 address_ = 0;
475 }
476
477 inline T *operator*() const
478 {
479 return GetAddress();
480 }
481
482 inline T *operator->() const
483 {
484 return GetAddress();
485 }
486
IsEmpty()487 inline bool IsEmpty() const
488 {
489 return GetAddress() == nullptr;
490 }
491
492 void SetWeak();
493
494 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
495 WeakRefClearCallBack nativeFinalizeCallback);
496
497 void ClearWeak();
498
499 bool IsWeak() const;
500
GetEcmaVM()501 const EcmaVM *GetEcmaVM() const
502 {
503 return vm_;
504 }
505
506 // This method must be called before Global is released.
507 GLOBAL_PUBLIC_HYBRID_EXTENSION();
508 private:
GetAddress()509 inline T *GetAddress() const
510 {
511 return reinterpret_cast<T *>(address_);
512 };
513 inline void Update(const Global &that);
514 uintptr_t address_ = 0U;
515 const EcmaVM *vm_ {nullptr};
516 };
517
518 class PUBLIC_API JSValueRef {
519 public:
520 static Local<PrimitiveRef> Undefined(const EcmaVM *vm);
521 static Local<PrimitiveRef> Null(const EcmaVM *vm);
522 static Local<PrimitiveRef> Hole(const EcmaVM *vm);
523 static Local<PrimitiveRef> True(const EcmaVM *vm);
524 static Local<PrimitiveRef> False(const EcmaVM *vm);
525
526 bool BooleaValue(const EcmaVM *vm);
527 int64_t IntegerValue(const EcmaVM *vm);
528 uint32_t Uint32Value(const EcmaVM *vm);
529 int32_t Int32Value(const EcmaVM *vm);
530 double GetValueDouble(bool &isNumber);
531 int32_t GetValueInt32(bool &isNumber);
532 uint32_t GetValueUint32(bool &isNumber);
533 int64_t GetValueInt64(bool &isNumber);
534 bool GetValueBool(bool &isBool);
535
536 Local<NumberRef> ToNumber(const EcmaVM *vm);
537 Local<BooleanRef> ToBoolean(const EcmaVM *vm);
538 Local<BigIntRef> ToBigInt(const EcmaVM *vm);
539 Local<StringRef> ToString(const EcmaVM *vm);
540 Local<ObjectRef> ToObject(const EcmaVM *vm);
541 Local<ObjectRef> ToEcmaObject(const EcmaVM *vm);
542 Local<ObjectRef> ToEcmaObjectWithoutSwitchState(const EcmaVM *vm);
543 Local<NativePointerRef> ToNativePointer(const EcmaVM *vm);
544
545 bool IsUndefined();
546 bool IsNull();
547 bool IsHole();
548 bool IsTrue();
549 bool IsFalse();
550 bool IsNumber();
551 bool IsBigInt(const EcmaVM *vm);
552 bool IsInt();
553 bool WithinInt32();
554 bool IsBoolean();
555 bool IsString(const EcmaVM *vm);
556 bool IsStringWithoutSwitchState(const EcmaVM *vm);
557 bool IsSymbol(const EcmaVM *vm);
558 bool IsObject(const EcmaVM *vm);
559 bool IsObjectWithoutSwitchState(const EcmaVM *vm);
560 bool IsNativeBindingObject(const EcmaVM *vm);
561 bool IsArray(const EcmaVM *vm);
562 bool IsJSArray(const EcmaVM *vm);
563 bool IsConstructor(const EcmaVM *vm);
564 bool IsFunction(const EcmaVM *vm);
565
566 bool IsJSFunction(const EcmaVM *vm);
567 bool IsProxy(const EcmaVM *vm);
568 bool IsPromise(const EcmaVM *vm);
569 bool IsDataView(const EcmaVM *vm);
570 bool IsTypedArray(const EcmaVM *vm);
571 bool IsNativePointer(const EcmaVM *vm);
572 bool IsDate(const EcmaVM *vm);
573 bool IsError(const EcmaVM *vm);
574 bool IsMap(const EcmaVM *vm);
575 bool IsSet(const EcmaVM *vm);
576 bool IsWeakRef(const EcmaVM *vm);
577 bool IsWeakMap(const EcmaVM *vm);
578 bool IsWeakSet(const EcmaVM *vm);
579 bool IsRegExp(const EcmaVM *vm);
580 bool IsArrayIterator(const EcmaVM *vm);
581 bool IsStringIterator(const EcmaVM *vm);
582 bool IsSetIterator(const EcmaVM *vm);
583 bool IsMapIterator(const EcmaVM *vm);
584 bool IsArrayBuffer(const EcmaVM *vm);
585 bool IsBuffer(const EcmaVM *vm);
586 bool IsUint8Array(const EcmaVM *vm);
587 bool IsInt8Array(const EcmaVM *vm);
588 bool IsUint8ClampedArray(const EcmaVM *vm);
589 bool IsInt16Array(const EcmaVM *vm);
590 bool IsUint16Array(const EcmaVM *vm);
591 bool IsInt32Array(const EcmaVM *vm);
592 bool IsUint32Array(const EcmaVM *vm);
593 bool IsFloat32Array(const EcmaVM *vm);
594 bool IsFloat64Array(const EcmaVM *vm);
595 bool IsBigInt64Array(const EcmaVM *vm);
596 bool IsBigUint64Array(const EcmaVM *vm);
597 bool IsJSPrimitiveRef(const EcmaVM *vm);
598 bool IsJSPrimitiveNumber(const EcmaVM *vm);
599 bool IsJSPrimitiveInt(const EcmaVM *vm);
600 bool IsJSPrimitiveBoolean(const EcmaVM *vm);
601 bool IsJSPrimitiveString(const EcmaVM *vm);
602
603 bool IsJSSharedInt8Array(const EcmaVM *vm);
604 bool IsJSSharedUint8Array(const EcmaVM *vm);
605 bool IsJSSharedUint8ClampedArray(const EcmaVM *vm);
606 bool IsJSSharedInt16Array(const EcmaVM *vm);
607 bool IsJSSharedUint16Array(const EcmaVM *vm);
608 bool IsJSSharedInt32Array(const EcmaVM *vm);
609 bool IsJSSharedUint32Array(const EcmaVM *vm);
610 bool IsJSSharedFloat32Array(const EcmaVM *vm);
611
612 bool IsGeneratorObject(const EcmaVM *vm);
613 bool IsJSPrimitiveSymbol(const EcmaVM *vm);
614
615 bool IsArgumentsObject(const EcmaVM *vm);
616 bool IsGeneratorFunction(const EcmaVM *vm);
617 bool IsAsyncFunction(const EcmaVM *vm);
618 bool IsConcurrentFunction(const EcmaVM *vm);
619 bool IsJSLocale(const EcmaVM *vm);
620 bool IsJSDateTimeFormat(const EcmaVM *vm);
621 bool IsJSRelativeTimeFormat(const EcmaVM *vm);
622 bool IsJSIntl(const EcmaVM *vm);
623 bool IsJSNumberFormat(const EcmaVM *vm);
624 bool IsJSCollator(const EcmaVM *vm);
625 bool IsJSPluralRules(const EcmaVM *vm);
626 bool IsJSListFormat(const EcmaVM *vm);
627 bool IsAsyncGeneratorFunction(const EcmaVM *vm);
628 bool IsAsyncGeneratorObject(const EcmaVM *vm);
629
630 bool IsModuleNamespaceObject(const EcmaVM *vm);
631 bool IsNativeModuleFailureInfoObject(const EcmaVM *vm);
632 bool IsSharedArrayBuffer(const EcmaVM *vm);
633 bool IsSendableArrayBuffer(const EcmaVM *vm);
634
635 bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value);
636 Local<StringRef> Typeof(const EcmaVM *vm);
637 bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value);
638
639 bool IsArrayList(const EcmaVM *vm);
640 bool IsDeque(const EcmaVM *vm);
641 bool IsHashMap(const EcmaVM *vm);
642 bool IsHashSet(const EcmaVM *vm);
643 bool IsLightWeightMap(const EcmaVM *vm);
644 bool IsLightWeightSet(const EcmaVM *vm);
645 bool IsLinkedList(const EcmaVM *vm);
646 bool IsLinkedListIterator(const EcmaVM *vm);
647 bool IsList(const EcmaVM *vm);
648 bool IsPlainArray(const EcmaVM *vm);
649 bool IsQueue(const EcmaVM *vm);
650 bool IsStack(const EcmaVM *vm);
651 bool IsTreeMap(const EcmaVM *vm);
652 bool IsTreeSet(const EcmaVM *vm);
653 bool IsVector(const EcmaVM *vm);
654 bool IsBitVector(const EcmaVM *vm);
655 bool IsSendableObject(const EcmaVM *vm);
656 bool IsJSShared(const EcmaVM *vm);
657 bool IsSharedArray(const EcmaVM *vm);
658 bool IsSharedTypedArray(const EcmaVM *vm);
659 bool IsSharedSet(const EcmaVM *vm);
660 bool IsSharedMap(const EcmaVM *vm);
661 bool IsSharedMapIterator(const EcmaVM *vm);
662 bool IsHeapObject();
663 void *GetNativePointerValue(const EcmaVM *vm, bool &isNativePointer);
664 bool IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer);
665 void DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer);
666 void GetDataViewInfo(const EcmaVM *vm,
667 bool &isDataView,
668 size_t *byteLength,
669 void **data,
670 JSValueRef **arrayBuffer,
671 size_t *byteOffset);
672 void TryGetArrayLength(const EcmaVM *vm, bool *isPendingException,
673 bool *isArrayOrSharedArray, uint32_t *arrayLength);
674 bool IsJsGlobalEnv(const EcmaVM *vm);
675
676 private:
677 JSTaggedType value_;
678 friend JSNApi;
679 template<typename T>
680 friend class Global;
681 template<typename T>
682 friend class Local;
683 void *GetNativePointerValueImpl(const EcmaVM *vm, bool &isNativePointer);
684 };
685
686 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
687 class PUBLIC_API PropertyAttribute {
688 public:
Default()689 static PropertyAttribute Default()
690 {
691 return PropertyAttribute();
692 }
693 PropertyAttribute() = default;
PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)694 PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c)
695 : value_(value),
696 writable_(w),
697 enumerable_(e),
698 configurable_(c),
699 hasWritable_(true),
700 hasEnumerable_(true),
701 hasConfigurable_(true)
702 {}
703 ~PropertyAttribute() = default;
704
IsWritable()705 bool IsWritable() const
706 {
707 return writable_;
708 }
SetWritable(bool flag)709 void SetWritable(bool flag)
710 {
711 writable_ = flag;
712 hasWritable_ = true;
713 }
IsEnumerable()714 bool IsEnumerable() const
715 {
716 return enumerable_;
717 }
SetEnumerable(bool flag)718 void SetEnumerable(bool flag)
719 {
720 enumerable_ = flag;
721 hasEnumerable_ = true;
722 }
IsConfigurable()723 bool IsConfigurable() const
724 {
725 return configurable_;
726 }
SetConfigurable(bool flag)727 void SetConfigurable(bool flag)
728 {
729 configurable_ = flag;
730 hasConfigurable_ = true;
731 }
HasWritable()732 bool HasWritable() const
733 {
734 return hasWritable_;
735 }
HasConfigurable()736 bool HasConfigurable() const
737 {
738 return hasConfigurable_;
739 }
HasEnumerable()740 bool HasEnumerable() const
741 {
742 return hasEnumerable_;
743 }
GetValue(const EcmaVM * vm)744 Local<JSValueRef> GetValue(const EcmaVM *vm) const
745 {
746 if (value_.IsEmpty()) {
747 return JSValueRef::Undefined(vm);
748 }
749 return value_;
750 }
SetValue(Local<JSValueRef> value)751 void SetValue(Local<JSValueRef> value)
752 {
753 value_ = value;
754 }
HasValue()755 inline bool HasValue() const
756 {
757 return !value_.IsEmpty();
758 }
GetGetter(const EcmaVM * vm)759 Local<JSValueRef> GetGetter(const EcmaVM *vm) const
760 {
761 if (getter_.IsEmpty()) {
762 return JSValueRef::Undefined(vm);
763 }
764 return getter_;
765 }
SetGetter(Local<JSValueRef> value)766 void SetGetter(Local<JSValueRef> value)
767 {
768 getter_ = value;
769 }
HasGetter()770 bool HasGetter() const
771 {
772 return !getter_.IsEmpty();
773 }
GetSetter(const EcmaVM * vm)774 Local<JSValueRef> GetSetter(const EcmaVM *vm) const
775 {
776 if (setter_.IsEmpty()) {
777 return JSValueRef::Undefined(vm);
778 }
779 return setter_;
780 }
SetSetter(Local<JSValueRef> value)781 void SetSetter(Local<JSValueRef> value)
782 {
783 setter_ = value;
784 }
HasSetter()785 bool HasSetter() const
786 {
787 return !setter_.IsEmpty();
788 }
789
790 private:
791 Local<JSValueRef> value_;
792 Local<JSValueRef> getter_;
793 Local<JSValueRef> setter_;
794 bool writable_ = false;
795 bool enumerable_ = false;
796 bool configurable_ = false;
797 bool hasWritable_ = false;
798 bool hasEnumerable_ = false;
799 bool hasConfigurable_ = false;
800 };
801
802 class PUBLIC_API NativePointerRef : public JSValueRef {
803 public:
804 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0);
805 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack,
806 void *data, size_t nativeBindingsize = 0);
807 static Local<NativePointerRef> NewConcurrent(const EcmaVM *vm, void *nativePointer,
808 NativePointerCallback callBack,
809 void *data, size_t nativeBindingsize = 0);
810 static Local<NativePointerRef> NewSendable(const EcmaVM *vm,
811 void *nativePointer,
812 NativePointerCallback callBack = nullptr,
813 void *data = nullptr,
814 size_t nativeBindingsize = 0);
815 void *Value();
816 };
817
818 class PUBLIC_API ObjectRef : public JSValueRef {
819 public:
820 enum class SendableType {
821 NONE,
822 OBJECT,
823 GENERIC,
824 };
825 struct SendablePropertiesInfo {
826 std::vector<Local<JSValueRef>> keys;
827 std::vector<SendableType> types;
828 std::vector<PropertyAttribute> attributes;
829 };
830 static constexpr int MAX_PROPERTIES_ON_STACK = 32;
Cast(JSValueRef * value)831 static inline ObjectRef *Cast(JSValueRef *value)
832 {
833 return static_cast<ObjectRef *>(value);
834 }
835 static Local<ObjectRef> New(const EcmaVM *vm);
836 static uintptr_t NewObject(const EcmaVM *vm);
837 static Local<ObjectRef> NewS(const EcmaVM *vm);
838 static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys,
839 const PropertyAttribute *attributes);
840 static Local<ObjectRef> NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info);
841 static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys,
842 const Local<JSValueRef> *values);
843 static Local<ObjectRef> CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo);
844 static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter);
845 static Local<ObjectRef> CreateSendableAccessorData(const EcmaVM *vm,
846 Local<FunctionRef> getter,
847 Local<FunctionRef> setter);
848 bool ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value);
849 Local<NativePointerRef> GetNativeBindingPointer(const EcmaVM *vm);
850 bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
851 bool Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
852 bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value);
853 bool SetWithoutSwitchState(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
854 bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
855 Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default());
856 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
857 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
858 Local<JSValueRef> Get(const EcmaVM *vm, int32_t key);
859
860 bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property);
861 Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm);
862 Local<ArrayRef> GetAllPropertyNames(const EcmaVM *vm, uint32_t filter);
863 Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm);
864 Local<JSValueRef> GetPrototype(const EcmaVM *vm);
865 bool SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype);
866
867 bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute);
868
869 bool Has(const EcmaVM *vm, Local<JSValueRef> key);
870 bool Has(const EcmaVM *vm, uint32_t key);
871
872 bool HasOwnProperty(const EcmaVM *vm, Local<JSValueRef> key);
873
874 bool Delete(const EcmaVM *vm, Local<JSValueRef> key);
875 bool Delete(const EcmaVM *vm, uint32_t key);
876
877 Local<JSValueRef> Freeze(const EcmaVM *vm);
878 Local<JSValueRef> Seal(const EcmaVM *vm);
879 void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count);
880 int32_t GetNativePointerFieldCount(const EcmaVM *vm);
881 void *GetNativePointerField(const EcmaVM *vm, int32_t index);
882 void SetNativePointerField(const EcmaVM *vm,
883 int32_t index,
884 void *nativePointer = nullptr,
885 NativePointerCallback callBack = nullptr,
886 void *data = nullptr, size_t nativeBindingsize = 0);
887 void SetConcurrentNativePointerField(const EcmaVM *vm,
888 int32_t index,
889 void *nativePointer = nullptr,
890 NativePointerCallback callBack = nullptr,
891 void *data = nullptr, size_t nativeBindingsize = 0);
892 OBJECTREF_PUBLIC_HYBRID_EXTENSION();
893 };
894
895 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
896 using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*);
897 class PUBLIC_API FunctionRef : public ObjectRef {
898 public:
899 struct SendablePropertiesInfos {
900 SendablePropertiesInfo instancePropertiesInfo;
901 SendablePropertiesInfo staticPropertiesInfo;
902 SendablePropertiesInfo nonStaticPropertiesInfo;
903 };
904 static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter = nullptr,
905 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
906 static Local<FunctionRef> New(EcmaVM *vm, const Local<JSValueRef> &context, FunctionCallback nativeFunc,
907 NativePointerCallback deleter = nullptr, void *data = nullptr, bool callNapi = false,
908 size_t nativeBindingsize = 0);
909 static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
910 FunctionCallback nativeFunc,
911 NativePointerCallback deleter = nullptr,
912 void *data = nullptr,
913 bool callNapi = false,
914 size_t nativeBindingsize = 0);
915 static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
916 const Local<JSValueRef> &context,
917 FunctionCallback nativeFunc,
918 NativePointerCallback deleter = nullptr,
919 void *data = nullptr,
920 bool callNapi = false,
921 size_t nativeBindingsize = 0);
922 static Local<FunctionRef> New(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter,
923 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
924 static Local<FunctionRef> New(EcmaVM *vm, const Local<JSValueRef> &context, InternalFunctionCallback nativeFunc,
925 NativePointerCallback deleter, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
926 static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
927 const Local<JSValueRef> &context,
928 InternalFunctionCallback nativeFunc,
929 NativePointerCallback deleter,
930 void *data = nullptr,
931 bool callNapi = false,
932 size_t nativeBindingsize = 0);
933 static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
934 InternalFunctionCallback nativeFunc,
935 NativePointerCallback deleter,
936 void *data = nullptr,
937 bool callNapi = false,
938 size_t nativeBindingsize = 0);
939 static Local<FunctionRef> NewConcurrentWithName(EcmaVM *vm, const Local<JSValueRef> &context,
940 InternalFunctionCallback nativeFunc, NativePointerCallback deleter,
941 const char *name, void *data = nullptr, bool callNapi = false,
942 size_t nativeBindingsize = 0);
943 static Local<FunctionRef> NewSendable(EcmaVM *vm,
944 InternalFunctionCallback nativeFunc,
945 NativePointerCallback deleter,
946 void *data = nullptr,
947 bool callNapi = false,
948 size_t nativeBindingsize = 0);
949 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter,
950 void *data, bool callNapi = false, size_t nativeBindingsize = 0);
951 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, const Local<JSValueRef> &context,
952 FunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi = false,
953 size_t nativeBindingsize = 0);
954 static Local<FunctionRef> NewConcurrentClassFunction(EcmaVM *vm,
955 InternalFunctionCallback nativeFunc,
956 NativePointerCallback deleter,
957 void *data,
958 bool callNapi = false,
959 size_t nativeBindingsize = 0);
960 static Local<FunctionRef> NewConcurrentClassFunction(EcmaVM *vm,
961 const Local<JSValueRef> &context,
962 InternalFunctionCallback nativeFunc,
963 NativePointerCallback deleter,
964 void *data,
965 bool callNapi = false,
966 size_t nativeBindingsize = 0);
967 static Local<FunctionRef> NewConcurrentClassFunctionWithName(const EcmaVM *vm, const Local<JSValueRef> &context,
968 InternalFunctionCallback nativeFunc,
969 NativePointerCallback deleter, const char *name,
970 void *data, bool callNapi = false,
971 size_t propertyCount = 0,
972 size_t staticPropCount = 0,
973 Local<panda::JSValueRef> *keys = nullptr,
974 PropertyAttribute *attrs = nullptr,
975 size_t nativeBindingsize = 0);
976
977 static Local<FunctionRef> NewClassFunction(EcmaVM *vm,
978 InternalFunctionCallback nativeFunc,
979 NativePointerCallback deleter,
980 void *data,
981 bool callNapi = false,
982 size_t nativeBindingsize = 0);
983 static Local<FunctionRef> NewClassFunction(EcmaVM *vm,
984 const Local<JSValueRef> &context,
985 InternalFunctionCallback nativeFunc,
986 NativePointerCallback deleter,
987 void *data,
988 bool callNapi = false,
989 size_t nativeBindingsize = 0);
990 static Local<FunctionRef> NewSendableClassFunction(const EcmaVM *vm,
991 InternalFunctionCallback nativeFunc,
992 NativePointerCallback deleter,
993 void *data,
994 Local<StringRef> name,
995 SendablePropertiesInfos &infos,
996 Local<FunctionRef> parent,
997 bool callNapi = false,
998 size_t nativeBindingsize = 0);
999 JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[],
1000 int32_t length);
1001 Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[],
1002 int32_t length);
1003 Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length);
1004 JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length);
1005
1006 Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm);
1007 bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent);
1008 void SetName(const EcmaVM *vm, Local<StringRef> name);
1009 Local<StringRef> GetName(const EcmaVM *vm);
1010 Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber);
1011 bool IsNative(const EcmaVM *vm);
1012 void SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter = nullptr, bool callNapi = false);
1013 void* GetData(const EcmaVM *vm);
1014 };
1015
1016 class PUBLIC_API PrimitiveRef : public JSValueRef {
1017 public:
1018 Local<JSValueRef> GetValue(const EcmaVM *vm);
1019 };
1020
1021 class PUBLIC_API SymbolRef : public PrimitiveRef {
1022 public:
1023 static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description = Local<StringRef>());
1024 Local<StringRef> GetDescription(const EcmaVM *vm);
1025 };
1026
1027 class PUBLIC_API BooleanRef : public PrimitiveRef {
1028 public:
1029 static Local<BooleanRef> New(const EcmaVM *vm, bool input);
1030 bool Value();
1031 };
1032
1033 class PUBLIC_API StringRef : public PrimitiveRef {
1034 public:
Cast(JSValueRef * value)1035 static inline StringRef *Cast(JSValueRef *value)
1036 {
1037 // check
1038 return static_cast<StringRef *>(value);
1039 }
1040 static Local<StringRef> NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length = -1);
1041 static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1);
1042 static Local<StringRef> NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length = -1);
1043 static Local<StringRef> NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1);
1044 std::string ToString(const EcmaVM *vm);
1045 std::string DebuggerToString(const EcmaVM *vm);
1046 uint32_t Length(const EcmaVM *vm);
1047 bool IsCompressed(const EcmaVM *vm);
1048 size_t Utf8Length(const EcmaVM *vm, bool isGetBufferSize = false);
1049 uint32_t WriteUtf8(const EcmaVM *vm, char *buffer, uint32_t length, bool isWriteBuffer = false);
1050 uint32_t WriteUtf16(const EcmaVM *vm, char16_t *buffer, uint32_t length);
1051 uint32_t WriteLatin1(const EcmaVM *vm, char *buffer, uint32_t length);
1052 uint32_t WriteLatin1WithoutSwitchState(const EcmaVM *vm, char *buffer, uint32_t length);
1053 static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm);
1054 Local<TypedArrayRef> EncodeIntoUint8Array(const EcmaVM *vm);
1055 STRINGREF_PUBLIC_HYBRID_EXTENSION();
1056 };
1057
1058 class PUBLIC_API PromiseRejectInfo {
1059 public:
1060 enum class PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE };
1061 PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
1062 PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data);
~PromiseRejectInfo()1063 ~PromiseRejectInfo() {}
1064 Local<JSValueRef> GetPromise() const;
1065 Local<JSValueRef> GetReason() const;
1066 PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const;
1067 void* GetData() const;
1068
1069 private:
1070 Local<JSValueRef> promise_ {};
1071 Local<JSValueRef> reason_ {};
1072 PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT;
1073 void* data_ {nullptr};
1074 };
1075
1076 /**
1077 * An external exception handler.
1078 */
1079 class PUBLIC_API TryCatch {
1080 public:
TryCatch(const EcmaVM * ecmaVm)1081 explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {};
1082
1083 /**
1084 * Consumes the exception by default if not rethrow explicitly.
1085 */
1086 ~TryCatch();
1087
1088 bool HasCaught() const;
1089 void Rethrow();
1090 Local<ObjectRef> GetAndClearException();
1091 Local<ObjectRef> GetException();
1092 void ClearException();
1093
1094 ECMA_DISALLOW_COPY(TryCatch);
1095 ECMA_DISALLOW_MOVE(TryCatch);
1096
getrethrow_()1097 bool getrethrow_()
1098 {
1099 return rethrow_;
1100 }
1101
1102 private:
1103 // Disable dynamic allocation
1104 void* operator new(size_t size) = delete;
1105 void operator delete(void*, size_t) = delete;
1106 void* operator new[](size_t size) = delete;
1107 void operator delete[](void*, size_t) = delete;
1108
1109 const EcmaVM *ecmaVm_ {nullptr};
1110 bool rethrow_ {false};
1111 };
1112
1113 class PUBLIC_API BigIntRef : public PrimitiveRef {
1114 public:
1115 static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input);
1116 static Local<BigIntRef> New(const EcmaVM *vm, int64_t input);
1117 static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words);
1118 void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless);
1119 void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless);
1120 void GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words);
1121 uint32_t GetWordsArraySize(const EcmaVM *vm);
1122 };
1123
1124 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
1125 class PUBLIC_API LocalScope {
1126 public:
1127 explicit LocalScope(const EcmaVM *vm);
1128 virtual ~LocalScope();
1129
1130 protected:
1131 inline LocalScope(const EcmaVM *vm, JSTaggedType value);
1132
1133 private:
1134 void *prevNext_ = nullptr;
1135 void *prevEnd_ = nullptr;
1136 int32_t prevHandleStorageIndex_ {-1};
1137 int32_t prevPrimitiveStorageIndex_ {-1};
1138 void *prevPrimitiveNext_ = nullptr;
1139 void *prevPrimitiveEnd_ = nullptr;
1140 void *thread_ = nullptr;
1141 };
1142
1143 class PUBLIC_API EscapeLocalScope final : public LocalScope {
1144 public:
1145 explicit EscapeLocalScope(const EcmaVM *vm);
1146 ~EscapeLocalScope() override = default;
1147
1148 ECMA_DISALLOW_COPY(EscapeLocalScope);
1149 ECMA_DISALLOW_MOVE(EscapeLocalScope);
1150
1151 template<typename T>
Escape(Local<T> current)1152 inline Local<T> Escape(Local<T> current)
1153 {
1154 ECMA_ASSERT(!alreadyEscape_);
1155 alreadyEscape_ = true;
1156 *(reinterpret_cast<T *>(escapeHandle_)) = **current;
1157 return Local<T>(escapeHandle_);
1158 }
1159
1160 private:
1161 bool alreadyEscape_ = false;
1162 uintptr_t escapeHandle_ = 0U;
1163 };
1164
1165 class PUBLIC_API IntegerRef : public PrimitiveRef {
1166 public:
1167 static Local<IntegerRef> New(const EcmaVM *vm, int input);
1168 static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input);
1169 int Value();
1170 };
1171
1172 class PUBLIC_API ArrayBufferRef : public ObjectRef {
1173 public:
1174 static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length);
1175 static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length,
1176 const NativePointerCallback &deleter, void *data);
1177
1178 int32_t ByteLength(const EcmaVM *vm);
1179 void *GetBuffer(const EcmaVM *vm);
1180 void *GetBufferAndLength(const EcmaVM *vm, int32_t *length);
1181 void Detach(const EcmaVM *vm);
1182 bool IsDetach(const EcmaVM *vm);
1183 };
1184
1185 class PUBLIC_API SendableArrayBufferRef : public ObjectRef {
1186 public:
1187 static Local<SendableArrayBufferRef> New(const EcmaVM *vm, int32_t length);
1188 static Local<SendableArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length,
1189 const NativePointerCallback &deleter, void *data);
1190
1191 int32_t ByteLength(const EcmaVM *vm);
1192 void *GetBuffer(const EcmaVM *vm);
1193
1194 void Detach(const EcmaVM *vm);
1195 bool IsDetach(const EcmaVM *vm);
1196 };
1197
1198 class PUBLIC_API DateRef : public ObjectRef {
1199 public:
1200 static Local<DateRef> New(const EcmaVM *vm, double time);
1201 Local<StringRef> ToString(const EcmaVM *vm);
1202 double GetTime(const EcmaVM *vm);
1203 };
1204
1205 class PUBLIC_API TypedArrayRef : public ObjectRef {
1206 public:
1207 uint32_t ByteLength(const EcmaVM *vm);
1208 uint32_t ByteOffset(const EcmaVM *vm);
1209 uint32_t ArrayLength(const EcmaVM *vm);
1210 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1211 };
1212
1213 class PUBLIC_API SendableTypedArrayRef : public ObjectRef {
1214 public:
1215 uint32_t ByteLength(const EcmaVM *vm);
1216 uint32_t ByteOffset(const EcmaVM *vm);
1217 uint32_t ArrayLength(const EcmaVM *vm);
1218 Local<SendableArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1219 };
1220
1221 class PUBLIC_API ArrayRef : public ObjectRef {
1222 public:
1223 static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
1224 uint32_t Length(const EcmaVM *vm);
1225 static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
1226 static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
1227 };
1228
1229 class PUBLIC_API SendableArrayRef : public ObjectRef {
1230 public:
1231 static Local<SendableArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
1232 uint32_t Length(const EcmaVM *vm);
1233 static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
1234 static bool SetProperty(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
1235 };
1236
1237 class PUBLIC_API Int8ArrayRef : public TypedArrayRef {
1238 public:
1239 static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1240 };
1241
1242 class PUBLIC_API SharedInt8ArrayRef : public SendableTypedArrayRef {
1243 public:
1244 static Local<SharedInt8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1245 int32_t byteOffset, int32_t length);
1246 };
1247
1248 class PUBLIC_API Uint8ArrayRef : public TypedArrayRef {
1249 public:
1250 static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1251 };
1252
1253 class PUBLIC_API SharedUint8ArrayRef : public SendableTypedArrayRef {
1254 public:
1255 static Local<SharedUint8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1256 int32_t byteOffset, int32_t length);
1257 };
1258
1259 class PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef {
1260 public:
1261 static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1262 int32_t length);
1263 };
1264
1265 class PUBLIC_API Int16ArrayRef : public TypedArrayRef {
1266 public:
1267 static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1268 };
1269
1270 class PUBLIC_API SharedInt16ArrayRef : public SendableTypedArrayRef {
1271 public:
1272 static Local<SharedInt16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1273 int32_t byteOffset, int32_t length);
1274 };
1275
1276 class PUBLIC_API Uint16ArrayRef : public TypedArrayRef {
1277 public:
1278 static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1279 int32_t length);
1280 };
1281
1282 class PUBLIC_API SharedUint16ArrayRef : public SendableTypedArrayRef {
1283 public:
1284 static Local<SharedUint16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1285 int32_t byteOffset, int32_t length);
1286 };
1287
1288 class PUBLIC_API Int32ArrayRef : public TypedArrayRef {
1289 public:
1290 static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1291 };
1292
1293 class PUBLIC_API SharedInt32ArrayRef : public SendableTypedArrayRef {
1294 public:
1295 static Local<SharedInt32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1296 int32_t byteOffset, int32_t length);
1297 };
1298
1299 class PUBLIC_API SharedFloat32ArrayRef : public SendableTypedArrayRef {
1300 public:
1301 static Local<SharedFloat32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1302 int32_t byteOffset, int32_t length);
1303 };
1304
1305 class PUBLIC_API SharedUint8ClampedArrayRef : public SendableTypedArrayRef {
1306 public:
1307 static Local<SharedUint8ClampedArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1308 int32_t byteOffset, int32_t length);
1309 };
1310
1311 class PUBLIC_API Uint32ArrayRef : public TypedArrayRef {
1312 public:
1313 static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1314 int32_t length);
1315 };
1316
1317 class PUBLIC_API SharedUint32ArrayRef : public SendableTypedArrayRef {
1318 public:
1319 static Local<SharedUint32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1320 int32_t byteOffset, int32_t length);
1321 };
1322
1323 class PUBLIC_API Float32ArrayRef : public TypedArrayRef {
1324 public:
1325 static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1326 int32_t length);
1327 };
1328
1329 class PUBLIC_API Float64ArrayRef : public TypedArrayRef {
1330 public:
1331 static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1332 int32_t length);
1333 };
1334
1335 class PUBLIC_API BigInt64ArrayRef : public TypedArrayRef {
1336 public:
1337 static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1338 int32_t length);
1339 };
1340
1341 class PUBLIC_API BigUint64ArrayRef : public TypedArrayRef {
1342 public:
1343 static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1344 int32_t length);
1345 };
1346
1347 class PUBLIC_API Exception {
1348 public:
1349 static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message);
1350 static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message);
1351 static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message);
1352 static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message);
1353 static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message);
1354 static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message);
1355 static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message);
1356 static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message);
1357 static Local<JSValueRef> TerminationError(const EcmaVM *vm, Local<StringRef> message);
1358 };
1359
1360 class PUBLIC_API FunctionCallScope {
1361 public:
1362 FunctionCallScope(EcmaVM *vm);
1363 ~FunctionCallScope();
1364
1365 private:
1366 EcmaVM *vm_;
1367 };
1368
1369 class PUBLIC_API JSExecutionScope {
1370 public:
1371 explicit JSExecutionScope(const EcmaVM *vm);
1372 ~JSExecutionScope();
1373 ECMA_DISALLOW_COPY(JSExecutionScope);
1374 ECMA_DISALLOW_MOVE(JSExecutionScope);
1375
1376 private:
1377 void *lastCurrentThread_ = nullptr;
1378 bool isRevert_ = false;
1379 };
1380
1381 class PUBLIC_API JsiNativeScope {
1382 public:
1383 explicit JsiNativeScope(const EcmaVM *vm);
1384 ~JsiNativeScope();
1385 ECMA_DISALLOW_COPY(JsiNativeScope);
1386 ECMA_DISALLOW_MOVE(JsiNativeScope);
1387
1388 private:
1389 JSThread *thread_;
1390 uint16_t oldThreadState_ {0};
1391 uint32_t isEnableCMCGC_ {0};
1392 uint32_t hasSwitchState_ {0};
1393 };
1394
1395 class PUBLIC_API JsiFastNativeScope {
1396 public:
1397 explicit JsiFastNativeScope(const EcmaVM *vm);
1398 ~JsiFastNativeScope();
1399 ECMA_DISALLOW_COPY(JsiFastNativeScope);
1400 ECMA_DISALLOW_MOVE(JsiFastNativeScope);
1401
1402 private:
1403 JSThread *thread_ {nullptr};
1404 uint16_t oldThreadState_ {0};
1405 uint32_t isEnableCMCGC_ {0};
1406 uint32_t hasSwitchState_ {0};
1407 };
1408
1409 /**
1410 * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data.
1411 */
1412 class PUBLIC_API JsiRuntimeCallInfo
1413 : public ecmascript::base::AlignedStruct<ecmascript::base::AlignedPointer::Size(),
1414 ecmascript::base::AlignedPointer,
1415 ecmascript::base::AlignedPointer,
1416 ecmascript::base::AlignedPointer> {
1417 enum class Index : size_t {
1418 ThreadIndex = 0,
1419 NumArgsIndex,
1420 StackArgsIndex,
1421 NumOfMembers
1422 };
1423 public:
1424 JsiRuntimeCallInfo() = default;
1425 ~JsiRuntimeCallInfo() = default;
1426
GetThread()1427 inline JSThread *GetThread() const
1428 {
1429 return thread_;
1430 }
1431
1432 EcmaVM *GetVM() const;
1433
GetArgsNumber()1434 inline uint32_t GetArgsNumber() const
1435 {
1436 ECMA_ASSERT(numArgs_ >= FIRST_ARGS_INDEX);
1437 return numArgs_ - FIRST_ARGS_INDEX;
1438 }
1439
1440 void* GetData();
1441
GetFunctionRef()1442 inline Local<JSValueRef> GetFunctionRef() const
1443 {
1444 return GetArgRef(FUNC_INDEX);
1445 }
1446
GetNewTargetRef()1447 inline Local<JSValueRef> GetNewTargetRef() const
1448 {
1449 return GetArgRef(NEW_TARGET_INDEX);
1450 }
1451
GetThisRef()1452 inline Local<JSValueRef> GetThisRef() const
1453 {
1454 return GetArgRef(THIS_INDEX);
1455 }
1456
GetCallArgRef(uint32_t idx)1457 inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const
1458 {
1459 return GetArgRef(FIRST_ARGS_INDEX + idx);
1460 }
1461
1462 private:
1463 enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX };
1464
GetArgRef(uint32_t idx)1465 Local<JSValueRef> GetArgRef(uint32_t idx) const
1466 {
1467 return Local<JSValueRef>(GetArgAddress(idx));
1468 }
1469
GetArgAddress(uint32_t idx)1470 uintptr_t GetArgAddress(uint32_t idx) const
1471 {
1472 if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) {
1473 return reinterpret_cast<uintptr_t>(&stackArgs_[idx]);
1474 }
1475 return 0U;
1476 }
1477
1478 private:
1479 alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr};
1480 alignas(sizeof(JSTaggedType)) uint32_t numArgs_ = 0;
1481 __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0];
1482 friend class FunctionRef;
1483 };
1484
1485 class PUBLIC_API MapRef : public ObjectRef {
1486 public:
1487 int32_t GetSize(const EcmaVM *vm);
1488 int32_t GetTotalElements(const EcmaVM *vm);
1489 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
1490 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
1491 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1492 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1493 static Local<MapRef> New(const EcmaVM *vm);
1494 void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
1495 void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
1496 bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1497 bool Has(const EcmaVM *vm, const char *utf8);
1498 void Delete(const EcmaVM *vm, Local<JSValueRef> key);
1499 void Clear(const EcmaVM *vm);
1500 Local<MapIteratorRef> GetEntries(const EcmaVM *vm);
1501 Local<MapIteratorRef> GetKeys(const EcmaVM *vm);
1502 Local<MapIteratorRef> GetValues(const EcmaVM *vm);
1503 };
1504
1505 class PUBLIC_API SendableMapRef : public ObjectRef {
1506 public:
1507 static Local<SendableMapRef> New(const EcmaVM *vm);
1508 uint32_t GetSize(const EcmaVM *vm);
1509 uint32_t GetTotalElements(const EcmaVM *vm);
1510 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
1511 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
1512 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1513 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1514 void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
1515 void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
1516 bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1517 bool Has(const EcmaVM *vm, const char *utf8);
1518 void Delete(const EcmaVM *vm, Local<JSValueRef> key);
1519 void Clear(const EcmaVM *vm);
1520 Local<SendableMapIteratorRef> GetEntries(const EcmaVM *vm);
1521 Local<SendableMapIteratorRef> GetKeys(const EcmaVM *vm);
1522 Local<SendableMapIteratorRef> GetValues(const EcmaVM *vm);
1523 };
1524
1525 class PUBLIC_API SendableSetRef : public ObjectRef {
1526 public:
1527 static Local<SendableSetRef> New(const EcmaVM *vm);
1528 uint32_t GetSize(const EcmaVM *vm);
1529 uint32_t GetTotalElements(const EcmaVM *vm);
1530 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1531 void Add(const EcmaVM *vm, Local<JSValueRef> value);
1532 };
1533
1534 class PUBLIC_API BufferRef : public ObjectRef {
1535 public:
1536 static Local<BufferRef> New(const EcmaVM *vm, int32_t length);
1537 static Local<BufferRef> New(const EcmaVM *vm, const Local<JSValueRef> &context, int32_t length);
1538 static Local<BufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter,
1539 void *data);
1540 static Local<BufferRef> New(const EcmaVM *vm, const Local<JSValueRef> &context, void *buffer, int32_t length,
1541 const NativePointerCallback &deleter, void *data);
1542
1543 int32_t ByteLength(const EcmaVM *vm);
1544 void *GetBuffer(const EcmaVM *vm);
1545 static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1546 };
1547
1548 class PUBLIC_API PromiseRef : public ObjectRef {
1549 public:
1550 Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler);
1551 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler);
1552 Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler);
1553 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected);
1554
1555 Local<JSValueRef> GetPromiseState(const EcmaVM *vm);
1556 Local<JSValueRef> GetPromiseResult(const EcmaVM *vm);
1557 };
1558
1559 class PUBLIC_API PromiseCapabilityRef : public ObjectRef {
1560 public:
1561 static Local<PromiseCapabilityRef> New(const EcmaVM *vm);
1562 bool Resolve(const EcmaVM *vm, uintptr_t value);
1563 bool Resolve(const EcmaVM *vm, Local<JSValueRef> value);
1564 bool Reject(const EcmaVM *vm, uintptr_t reason);
1565 bool Reject(const EcmaVM *vm, Local<JSValueRef> reason);
1566 Local<PromiseRef> GetPromise(const EcmaVM *vm);
1567 };
1568
1569 class PUBLIC_API NumberRef : public PrimitiveRef {
1570 public:
1571 static Local<NumberRef> New(const EcmaVM *vm, double input);
1572 static Local<NumberRef> New(const EcmaVM *vm, int32_t input);
1573 static Local<NumberRef> New(const EcmaVM *vm, uint32_t input);
1574 static Local<NumberRef> New(const EcmaVM *vm, int64_t input);
1575
1576 double Value();
1577 };
1578
1579 class PUBLIC_API DataViewRef : public ObjectRef {
1580 public:
1581 static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset,
1582 uint32_t byteLength);
1583 static Local<DataViewRef> NewWithoutSwitchState(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer,
1584 uint32_t byteOffset, uint32_t byteLength);
1585 uint32_t ByteLength();
1586 uint32_t ByteOffset();
1587 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1588 };
1589
1590 class PUBLIC_API MapIteratorRef : public ObjectRef {
1591 public:
1592 int32_t GetIndex();
1593 Local<JSValueRef> GetKind(const EcmaVM *vm);
1594 static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map);
1595 ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1596 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo);
1597 Local<JSValueRef> Next(const EcmaVM *vm);
1598 };
1599
1600 class PUBLIC_API SendableMapIteratorRef : public ObjectRef {
1601 public:
1602 Local<JSValueRef> Next(const EcmaVM *vm);
1603 };
1604
1605 class PUBLIC_API JSNApi {
1606 public:
1607 struct DebugOption {
1608 const char *libraryPath;
1609 bool isDebugMode = false;
1610 int port = -1;
1611 bool isFaApp = false;
1612 };
1613 using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
1614 using PatchErrorCode = panda::PatchErrorCode;
1615 using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>;
1616
1617 struct NativeBindingInfo {
CreateNewInstanceNativeBindingInfo1618 static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); }
1619 void *env = nullptr;
1620 void *nativeValue = nullptr;
1621 void *attachFunc = nullptr;
1622 void *attachData = nullptr;
1623 void *detachFunc = nullptr;
1624 void *detachData = nullptr;
1625 void *hint = nullptr;
1626 void *detachedFinalizer = nullptr;
1627 void *detachedHint = nullptr;
1628 };
1629
1630 struct XRefBindingInfo {
CreateNewInstanceXRefBindingInfo1631 static XRefBindingInfo* CreateNewInstance() { return new(std::nothrow) XRefBindingInfo(); }
1632 void *attachXRefFunc = nullptr;
1633 void *attachXRefData = nullptr;
1634 };
1635
1636 // JSVM
1637 // fixme: Rename SEMI_GC to YOUNG_GC
1638 enum class PUBLIC_API TRIGGER_GC_TYPE : uint8_t {
1639 SEMI_GC,
1640 OLD_GC,
1641 FULL_GC,
1642 SHARED_GC,
1643 SHARED_FULL_GC
1644 };
1645
1646 enum class PUBLIC_API TRIGGER_IDLE_GC_TYPE : uint8_t {
1647 LOCAL_CONCURRENT_YOUNG_MARK = 1,
1648 LOCAL_CONCURRENT_FULL_MARK = 1 << 1,
1649 LOCAL_REMARK = 1 << 2,
1650 FULL_GC = 1 << 3,
1651 SHARED_CONCURRENT_MARK = 1 << 4,
1652 SHARED_CONCURRENT_PARTIAL_MARK = 1 << 5,
1653 SHARED_FULL_GC = 1 << 6,
1654 };
1655
1656 enum class PUBLIC_API MemoryReduceDegree : uint8_t {
1657 LOW = 0,
1658 MIDDLE,
1659 HIGH,
1660 };
1661
1662 enum class PUBLIC_API PandaFileType : int8_t {
1663 FILE_FORMAT_INVALID = -1,
1664 FILE_DYNAMIC = 0,
1665 FILE_STATIC = 1,
1666 };
1667
1668 static EcmaVM *CreateJSVM(const RuntimeOption &option);
1669 static void DestroyJSVM(EcmaVM *ecmaVm);
1670 static void IgnoreFinalizeCallback(EcmaVM *ecmaVm);
1671 static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler);
1672
1673 // aot load
1674 static void LoadAotFile(EcmaVM *vm, const std::string &moduleName);
1675 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
1676 static void LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName,
1677 const std::string &moduleName,
1678 std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb);
1679 #endif
1680 // JS code
1681 static bool ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName,
1682 const std::string &entry, bool needUpdate = false,
1683 const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC);
1684 static bool Execute(const EcmaVM *vm, const std::string &fileName,
1685 const std::string &entry, bool needUpdate = false,
1686 const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC);
1687 static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
1688 const std::string &filename = "", bool needUpdate = false,
1689 [[maybe_unused]] void* fileMapper = nullptr);
1690 static int ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName,
1691 const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern);
1692 static bool IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName,
1693 const std::string &moduleName, const std::string &ohmurl);
1694 // merge abc, execute module buffer
1695 static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "",
1696 bool needUpdate = false);
1697 static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file);
1698 /**
1699 * @brief Return the abc file type
1700 * @param[in] data : begin pos of abc file
1701 * @param[in] size : length of abc file
1702 * @return -1 indicates the abc file format invalid
1703 * 0 indicates the abc file is dynamic
1704 * 1 indicates the abc file is static
1705 */
1706 static PandaFileType GetFileType(const uint8_t *data, int32_t size);
1707 static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key);
1708 static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key);
1709 static Local<ObjectRef> GetExportObjectFromOhmUrl(EcmaVM *vm, const std::string &ohmUrl, const std::string &key);
1710 static Local<ObjectRef> ExecuteNativeModule(EcmaVM *vm, const std::string &key);
1711 static Local<ObjectRef> GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file);
1712 template<ForHybridApp isHybrid = ForHybridApp::Normal>
1713 static Local<ObjectRef> GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file,
1714 const std::string &module_path);
1715 static Local<ObjectRef> GetModuleNameSpaceWithModuleInfoForNormalApp(EcmaVM *vm, const std::string &file,
1716 const std::string &module_path);
1717 static Local<ObjectRef> GetModuleNameSpaceWithModuleInfoForHybridApp(EcmaVM *vm, const std::string &file,
1718 const std::string &module_path);
1719
1720 /*
1721 * Execute panda file from secure mem. secure memory lifecycle managed externally.
1722 * The data parameter needs to be created externally by an external caller and managed externally
1723 * by the external caller. The size parameter is the size of the data memory. The entry parameter
1724 * is the name of the entry function. The filename parameter is used to uniquely identify this
1725 * memory internally.
1726 */
1727 static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry,
1728 const std::string &filename = "", bool needUpdate = false, void* fileMapper = nullptr);
1729 /*
1730 * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally.
1731 * The data parameter needs to be created externally by an external caller and managed externally
1732 * by the external caller. The size parameter is the size of the data memory. The filename parameter
1733 * is used to uniquely identify this memory internally.
1734 */
1735 static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "",
1736 bool needUpdate = false);
1737
1738 static bool ExecuteSecureWithOhmUrl(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &srcFilename,
1739 const std::string &ohmUrl);
1740
1741 // ObjectRef Operation
1742 static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm);
1743 static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm, const Local<JSValueRef> &context);
1744 static void ExecutePendingJob(const EcmaVM *vm);
1745
1746 // Memory
1747 // fixme: Rename SEMI_GC to YOUNG_GC
1748 static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1749 static void TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason,
1750 TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1751 static void HintGC(const EcmaVM *vm, MemoryReduceDegree degree, ecmascript::GCReason reason);
1752 static void TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType);
1753 static void SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback);
1754 static StartIdleMonitorCallback GetStartIdleMonitorCallback();
1755 // Exception
1756 static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error);
1757 static void PrintExceptionInfo(const EcmaVM *vm);
1758 static void SetOnErrorCallback(EcmaVM *vm, OnErrorCallback cb, void* data);
1759 static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm);
1760 static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm);
1761 static bool IsExecutingPendingJob(const EcmaVM *vm);
1762 static bool HasPendingException(const EcmaVM *vm);
1763 static bool HasPendingJob(const EcmaVM *vm);
1764 static void EnableUserUncaughtErrorHandler(EcmaVM *vm);
1765 // prevewer debugger.
1766 static bool StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId,
1767 const DebuggerPostTask &debuggerPostTask);
1768 static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1769 const DebuggerPostTask &debuggerPostTask = {});
1770 // To be compatible with the old process.
1771 static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1772 const DebuggerPostTask &debuggerPostTask = {});
1773 // socketpair process in ohos platform.
1774 static bool StartDebuggerForSocketPair(int tid, int socketfd = -1);
1775 static bool StopDebugger(int tid);
1776 static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1777 const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false);
1778 static bool StoreDebugInfo(
1779 int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp);
1780 static bool StopDebugger(EcmaVM *vm);
1781 static bool IsMixedDebugEnabled(const EcmaVM *vm);
1782 static bool IsDebugModeEnabled(const EcmaVM *vm);
1783 static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress);
1784 static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress);
1785 static void NotifyLoadModule(const EcmaVM *vm);
1786 static void NotifyUIIdle(const EcmaVM *vm, int idleTime);
1787 static bool NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime);
1788 static void NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp);
1789 static bool IsJSMainThreadOfEcmaVM(const EcmaVM *vm);
1790 static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb);
1791 // Serialize & Deserialize.
1792 static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1793 Local<JSValueRef> cloneList,
1794 bool defaultTransfer = false,
1795 bool defaultCloneShared = true);
1796 static void* SerializeValueWithError(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1797 Local<JSValueRef> cloneList, std::string &error, bool defaultTransfer = false,
1798 bool defaultCloneShared = true);
1799 static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1800 // InterOp Serialize & Deserialize.
1801 static void* InterOpSerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1802 Local<JSValueRef> cloneList, bool defaultTransfer = false, bool defaultCloneShared = true);
1803 static Local<JSValueRef> InterOpDeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1804 static void DeleteSerializationData(void *data);
1805 static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data);
1806 static void SetTimerTaskCallback(EcmaVM *vm, TimerTaskCallback callback);
1807 static void SetCancelTimerCallback(EcmaVM *vm, CancelTimerCallback callback);
1808 static void NotifyEnvInitialized(EcmaVM *vm);
1809 static void SetReleaseSecureMemCallback(ReleaseSecureMemCallback releaseSecureMemFunc);
1810 static void PandaFileSerialize(const EcmaVM *vm);
1811 static void ModuleSerialize(const EcmaVM *vm);
1812 static void ModuleDeserialize(EcmaVM *vm, const uint32_t appVersion);
1813 static void SetHostResolveBufferTrackerForHybridApp(EcmaVM *vm, std::function<bool(std::string dirPath,
1814 uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb);
1815 static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb);
1816 static void SetNativePtrGetter(EcmaVM *vm, void* cb);
1817 static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb);
1818 static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb);
1819 static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb,
1820 QueueType queueType = QueueType::QUEUE_PROMISE);
1821 static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);
1822 static void PreFork(EcmaVM *vm);
1823 static void PostFork(EcmaVM *vm, const RuntimeOption &option);
1824 static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1825 static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1826 static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess);
1827 static void GetStackAfterCallNapi(EcmaVM *vm);
1828 static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName);
1829 static PatchErrorCode LoadPatch(EcmaVM *vm,
1830 const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize,
1831 const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize);
1832 static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName);
1833 // check whether the exception is caused by quickfix methods.
1834 static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName);
1835 // register quickfix query function.
1836 static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName,
1837 std::string &patchFileName,
1838 uint8_t **patchBuffer,
1839 size_t &patchSize)> callBack);
1840 static bool IsBundle(EcmaVM *vm);
1841 static void SetBundle(EcmaVM *vm, bool value);
1842 static bool IsNormalizedOhmUrlPack(EcmaVM *vm);
1843 static bool IsOhmUrl(const std::string &srcName);
1844 static void SetAssetPath(EcmaVM *vm, const std::string &assetPath);
1845 static void SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1846 static void SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1847 static void UpdatePkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1848 static std::string GetPkgName(EcmaVM *vm, const std::string &moduleName);
1849 static void SetPkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1850 static void UpdatePkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1851 static void SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list);
1852 static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint);
1853 static void SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
1854 std::vector<std::vector<std::string>>> &list);
1855 static void UpdatePkgContextInfoList(EcmaVM *vm,
1856 const std::map<std::string, std::vector<std::vector<std::string>>> &list);
1857 static void SetExecuteBufferMode(const EcmaVM *vm);
1858 // Stop preloading so task callback.
1859 static void SetStopPreLoadSoCallback(EcmaVM *vm, const StopPreLoadSoCallback &callback);
1860 static void SetLoop(EcmaVM *vm, void *loop);
1861 static void SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback);
1862 static void SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback);
1863 static void SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback);
1864 static void SetStartIdleMonitorCallback(EcmaVM *vm, const StartIdleMonitorCallback& callback);
1865 static std::string GetAssetPath(EcmaVM *vm);
1866 static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data);
1867 static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func, void *taskInfo);
1868 static void* GetCurrentTaskInfo(const EcmaVM *vm);
1869 static void ClearCurrentTaskInfo(const EcmaVM *vm);
1870 static void SetBundleName(EcmaVM *vm, const std::string &bundleName);
1871 static std::string GetBundleName(EcmaVM *vm);
1872 static void SetModuleName(EcmaVM *vm, const std::string &moduleName);
1873 static std::string GetModuleName(EcmaVM *vm);
1874 static void SetLargeHeap(bool isLargeHeap);
1875 static std::pair<std::string, std::string> GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false);
1876 static std::string NormalizePath(const std::string &string);
1877 static void AllowCrossThreadExecution(EcmaVM *vm);
1878 static bool CheckAndSetAllowCrossThreadExecution(EcmaVM *vm);
1879 static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM);
1880 static bool IsProfiling(EcmaVM *vm);
1881 static void SetProfilerState(const EcmaVM *vm, bool value);
1882 static void SetRequestAotCallback(EcmaVM *vm, const std::function<int32_t(const std::string &bundleName,
1883 const std::string &moduleName,
1884 int32_t triggerMode)> &cb);
1885 static void SetSearchHapPathTracker(EcmaVM *vm, std::function<bool(const std::string moduleName,
1886 std::string &hapPath)> cb);
1887 static void *GetEnv(EcmaVM *vm);
1888 static void SetEnv(EcmaVM *vm, void *env);
1889 static void SetMultiThreadCheck(bool multiThreadCheck = true);
1890 static void SetErrorInfoEnhance(bool errorInfoEnhance = true);
1891
1892 // Napi Heavy Logics fast path
1893 static Local<JSValueRef> NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1894 static Local<JSValueRef> NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1895 static Local<JSValueRef> NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1896 static Local<JSValueRef> NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1897 static Local<JSValueRef> NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key);
1898 static Local<JSValueRef> CreateLocal(const EcmaVM *vm, JSValueRef src);
1899
1900 // Napi helper function
1901 static bool KeyIsNumber(const char* utf8);
1902 static int GetStartRealTime(const EcmaVM *vm);
1903 static void NotifyTaskBegin(const EcmaVM *vm);
1904 static void NotifyTaskFinished(const EcmaVM *vm);
1905 static bool IsMultiThreadCheckEnabled(const EcmaVM *vm);
1906 static uint32_t GetCurrentThreadId();
1907
1908 //set VM apiVersion
1909 static void SetVMAPIVersion(EcmaVM *vm, const int32_t apiVersion);
1910
1911 // Napi Update SubStackInfo
1912 static void UpdateStackInfo(EcmaVM *vm, void *currentStackInfo, uint32_t opKind);
1913
1914 static Local<JSValueRef> CreateContext(const EcmaVM *vm);
1915
1916 static Local<JSValueRef> GetCurrentContext(const EcmaVM *vm);
1917
1918 static void SwitchContext(const EcmaVM *vm, const Local<JSValueRef> &context);
1919 // 1.2runtime interface info
1920 static Local<JSValueRef> GetImplements(const EcmaVM *vm, Local<JSValueRef> instance);
1921
1922 JSNAPI_PUBLIC_HYBRID_EXTENSION();
1923 private:
1924 static bool isForked_;
1925 static bool CreateRuntime(const RuntimeOption &option);
1926 static bool DestroyRuntime();
1927 static StartIdleMonitorCallback startIdleMonitorCallback_;
1928
1929 static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1930 static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1931 static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress);
1932 static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
1933 WeakRefClearCallBack freeGlobalCallBack,
1934 WeakRefClearCallBack nativeFinalizeCallback);
1935 static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress);
1936 static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress);
1937 static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr);
1938
1939 static bool IsSerializationTimeoutCheckEnabled(const EcmaVM *vm);
1940 static void GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start,
1941 std::chrono::system_clock::time_point &end, bool isSerialization);
1942 static void UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option);
1943 template<typename T>
1944 friend class Global;
1945 template<typename T>
1946 friend class CopyableGlobal;
1947 template<typename T>
1948 friend class Local;
1949 friend class test::JSNApiTests;
1950 JSNAPI_PRIVATE_HYBRID_EXTENSION();
1951 #ifdef PANDA_JS_ETS_HYBRID_MODE
1952 JSNAPI_PRIVATE_HYBRID_MODE_EXTENSION();
1953 #endif // PANDA_JS_ETS_HYBRID_MODE
1954 };
1955
1956 class PUBLIC_API ProxyRef : public ObjectRef {
1957 public:
1958 Local<JSValueRef> GetHandler(const EcmaVM *vm);
1959 Local<JSValueRef> GetTarget(const EcmaVM *vm);
1960 bool IsRevoked();
1961 };
1962
1963 class PUBLIC_API WeakMapRef : public ObjectRef {
1964 public:
1965 int32_t GetSize(const EcmaVM *vm);
1966 int32_t GetTotalElements(const EcmaVM *vm);
1967 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1968 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1969 static Local<WeakMapRef> New(const EcmaVM *vm);
1970 void Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value);
1971 bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1972 };
1973
1974 class PUBLIC_API SetRef : public ObjectRef {
1975 public:
1976 int32_t GetSize(const EcmaVM *vm);
1977 int32_t GetTotalElements(const EcmaVM *vm);
1978 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1979 static Local<SetRef> New(const EcmaVM *vm);
1980 void Add(const EcmaVM *vm, Local<JSValueRef> value);
1981 };
1982
1983 class PUBLIC_API WeakSetRef : public ObjectRef {
1984 public:
1985 int32_t GetSize(const EcmaVM *vm);
1986 int32_t GetTotalElements(const EcmaVM *vm);
1987 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1988 static Local<WeakSetRef> New(const EcmaVM *vm);
1989 void Add(const EcmaVM *vm, Local<JSValueRef> value);
1990 };
1991
1992 class PUBLIC_API SetIteratorRef : public ObjectRef {
1993 public:
1994 int32_t GetIndex();
1995 Local<JSValueRef> GetKind(const EcmaVM *vm);
1996 static Local<SetIteratorRef> New(const EcmaVM *vm, Local<SetRef> set);
1997 ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1998 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1999 };
2000
2001 /* Attention pls, ExternalStringCache only can be utilized in main thread. Threads of Worker or Taskpool call
2002 * functions of this class will cause data race.
2003 */
2004 class PUBLIC_API ExternalStringCache final {
2005 public:
2006 static bool RegisterStringCacheTable(const EcmaVM *vm, uint32_t size);
2007 static bool SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex);
2008 static bool HasCachedString(const EcmaVM *vm, uint32_t propertyIndex);
2009 static Local<StringRef> GetCachedString(const EcmaVM *vm, uint32_t propertyIndex);
2010 };
2011
2012 template<typename T>
2013 template<typename S>
Global(const EcmaVM * vm,const Local<S> & current)2014 Global<T>::Global(const EcmaVM *vm, const Local<S> ¤t) : vm_(vm)
2015 {
2016 if (!current.IsEmpty()) {
2017 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2018 }
2019 }
2020
2021 template<typename T>
2022 template<typename S>
Global(const EcmaVM * vm,const Global<S> & current)2023 Global<T>::Global(const EcmaVM *vm, const Global<S> ¤t) : vm_(vm)
2024 {
2025 if (!current.IsEmpty()) {
2026 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2027 }
2028 }
2029
2030 template<typename T>
CopyableGlobal(const EcmaVM * vm,const Local<T> & current)2031 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<T> ¤t) : vm_(vm)
2032 {
2033 if (!current.IsEmpty()) {
2034 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2035 }
2036 }
2037
2038 template<typename T>
2039 template<typename S>
CopyableGlobal(const EcmaVM * vm,const Local<S> & current)2040 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<S> ¤t) : vm_(vm)
2041 {
2042 if (!current.IsEmpty()) {
2043 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2044 }
2045 }
2046
2047 template<typename T>
Copy(const CopyableGlobal & that)2048 void CopyableGlobal<T>::Copy(const CopyableGlobal &that)
2049 {
2050 Free();
2051 vm_ = that.vm_;
2052 if (!that.IsEmpty()) {
2053 ECMA_ASSERT(vm_ != nullptr);
2054 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
2055 }
2056 }
2057
2058 template<typename T>
2059 template<typename S>
Copy(const CopyableGlobal<S> & that)2060 void CopyableGlobal<T>::Copy(const CopyableGlobal<S> &that)
2061 {
2062 Free();
2063 vm_ = that.GetEcmaVM();
2064 if (!that.IsEmpty()) {
2065 ECMA_ASSERT(vm_ != nullptr);
2066 address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
2067 }
2068 }
2069
2070 template<typename T>
Move(CopyableGlobal & that)2071 void CopyableGlobal<T>::Move(CopyableGlobal &that)
2072 {
2073 Free();
2074 vm_ = that.vm_;
2075 address_ = that.address_;
2076 that.vm_ = nullptr;
2077 that.address_ = 0U;
2078 }
2079
2080 template<typename T>
Free()2081 inline void CopyableGlobal<T>::Free()
2082 {
2083 if (!IsEmpty()) {
2084 JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2085 address_ = 0U;
2086 }
2087 }
2088
2089 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)2090 void CopyableGlobal<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
2091 WeakRefClearCallBack nativeFinalizeCallback)
2092 {
2093 address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
2094 }
2095
2096 template<typename T>
SetWeak()2097 void CopyableGlobal<T>::SetWeak()
2098 {
2099 address_ = JSNApi::SetWeak(vm_, address_);
2100 }
2101
2102 template<typename T>
ClearWeak()2103 void CopyableGlobal<T>::ClearWeak()
2104 {
2105 address_ = JSNApi::ClearWeak(vm_, address_);
2106 }
2107
2108 template<typename T>
IsWeak()2109 bool CopyableGlobal<T>::IsWeak() const
2110 {
2111 return JSNApi::IsWeak(vm_, address_);
2112 }
2113
2114 template<typename T>
Update(const Global & that)2115 void Global<T>::Update(const Global &that)
2116 {
2117 if (address_ != 0) {
2118 JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2119 }
2120 address_ = that.address_;
2121 vm_ = that.vm_;
2122 }
2123
2124 template<typename T>
FreeGlobalHandleAddr()2125 void Global<T>::FreeGlobalHandleAddr()
2126 {
2127 if (address_ == 0) {
2128 return;
2129 }
2130 JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2131 address_ = 0;
2132 }
2133
2134 template<typename T>
SetWeak()2135 void Global<T>::SetWeak()
2136 {
2137 address_ = JSNApi::SetWeak(vm_, address_);
2138 }
2139
2140 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)2141 void Global<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
2142 WeakRefClearCallBack nativeFinalizeCallback)
2143 {
2144 address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
2145 }
2146
2147 template<typename T>
ClearWeak()2148 void Global<T>::ClearWeak()
2149 {
2150 address_ = JSNApi::ClearWeak(vm_, address_);
2151 }
2152
2153 template<typename T>
IsWeak()2154 bool Global<T>::IsWeak() const
2155 {
2156 return JSNApi::IsWeak(vm_, address_);
2157 }
2158
2159 // ---------------------------------- Local --------------------------------------------
2160 template<typename T>
Local(const EcmaVM * vm,const CopyableGlobal<T> & current)2161 Local<T>::Local(const EcmaVM *vm, const CopyableGlobal<T> ¤t)
2162 {
2163 address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
2164 }
2165
2166 template<typename T>
Local(const EcmaVM * vm,const Global<T> & current)2167 Local<T>::Local(const EcmaVM *vm, const Global<T> ¤t)
2168 {
2169 address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
2170 }
2171 GLOBAL_PUBLIC_DEF_HYBRID_EXTENSION();
2172 #ifdef PANDA_JS_ETS_HYBRID_MODE
2173 GLOBAL_PUBLIC_DEF_HYBRID_MODE_EXTENSION();
2174 #endif // PANDA_JS_ETS_HYBRID_MODE
2175 } // namespace panda
2176 #endif
2177