• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
17 #define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
18 
19 #include <cassert>
20 #include <cstdint>
21 #include <functional>
22 #include <string>
23 #include <vector>
24 
25 #include "ecmascript/base/config.h"
26 #include "ecmascript/common.h"
27 #include "ecmascript/mem/mem_common.h"
28 
29 #include "libpandabase/macros.h"
30 
31 namespace panda {
32 class JSNApiHelper;
33 class EscapeLocalScope;
34 class PromiseRejectInfo;
35 template<typename T>
36 class CopyableGlobal;
37 template<typename T>
38 class Global;
39 class JSNApi;
40 template<typename T>
41 class Local;
42 class JSValueRef;
43 class PrimitiveRef;
44 class ArrayRef;
45 class StringRef;
46 class ObjectRef;
47 class FunctionRef;
48 class NumberRef;
49 class BooleanRef;
50 class NativePointerRef;
51 class JsiRuntimeCallInfo;
52 namespace test {
53 class JSNApiTests;
54 }  // namespace test
55 
56 namespace ecmascript {
57 class EcmaVM;
58 class JSRuntimeOptions;
59 class JSThread;
60 struct EcmaRuntimeCallInfo;
61 static constexpr uint32_t DEFAULT_GC_POOL_SIZE = 256_MB;
62 }  // namespace ecmascript
63 
64 using Deleter = void (*)(void *nativePointer, void *data);
65 using WeakRefClearCallBack = void (*)(void *);
66 using QuickFixQueryCallBack = bool (*)(std::string, std::string &, void **, size_t);
67 using EcmaVM = ecmascript::EcmaVM;
68 using JSThread = ecmascript::JSThread;
69 using JSTaggedType = uint64_t;
70 using ConcurrentCallback = void (*)(Local<JSValueRef> val, Local<JSValueRef> hint, void *data);
71 
72 static constexpr size_t DEFAULT_GC_THREAD_NUM = 7;
73 static constexpr size_t DEFAULT_LONG_PAUSE_TIME = 40;
74 
75 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
76 #define ECMA_DISALLOW_COPY(className)      \
77     className(const className &) = delete; \
78     className &operator=(const className &) = delete
79 
80 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
81 #define ECMA_DISALLOW_MOVE(className) \
82     className(className &&) = delete; \
83     className &operator=(className &&) = delete
84 
85 template<typename T>
86 class PUBLIC_API Local {  // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
87 public:
88     inline Local() = default;
89 
90     template<typename S>
Local(const Local<S> & current)91     inline Local(const Local<S> &current) : address_(reinterpret_cast<uintptr_t>(*current))
92     {
93         // Check
94     }
95 
96     Local(const EcmaVM *vm, const Global<T> &current);
97 
98     Local(const EcmaVM *vm, const CopyableGlobal<T> &current);
99 
100     ~Local() = default;
101 
102     inline T *operator*() const
103     {
104         return GetAddress();
105     }
106 
107     inline T *operator->() const
108     {
109         return GetAddress();
110     }
111 
IsEmpty()112     inline bool IsEmpty() const
113     {
114         return GetAddress() == nullptr;
115     }
116 
IsNull()117     inline bool IsNull() const
118     {
119         return IsEmpty() || GetAddress()->IsHole();
120     }
121 
122 private:
Local(uintptr_t addr)123     explicit inline Local(uintptr_t addr) : address_(addr) {}
GetAddress()124     inline T *GetAddress() const
125     {
126         return reinterpret_cast<T *>(address_);
127     };
128     uintptr_t address_ = 0U;
129     friend JSNApiHelper;
130     friend EscapeLocalScope;
131     friend JsiRuntimeCallInfo;
132 };
133 
134 /**
135  * A Copyable global handle, keeps a separate global handle for each CopyableGlobal.
136  *
137  * Support Copy Constructor and Assign, Move Constructor And Assign.
138  *
139  * If destructed, the global handle held will be automatically released.
140  *
141  * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or
142  *        a value passing return value and so on.
143  */
144 template<typename T>
145 class PUBLIC_API CopyableGlobal {
146 public:
147     inline CopyableGlobal() = default;
~CopyableGlobal()148     ~CopyableGlobal()
149     {
150         Free();
151     }
152 
CopyableGlobal(const CopyableGlobal & that)153     inline CopyableGlobal(const CopyableGlobal &that)
154     {
155         Copy(that);
156     }
157 
158     inline CopyableGlobal &operator=(const CopyableGlobal &that)
159     {
160         Copy(that);
161         return *this;
162     }
163 
CopyableGlobal(CopyableGlobal && that)164     inline CopyableGlobal(CopyableGlobal &&that)
165     {
166         Move(that);
167     }
168 
169     inline CopyableGlobal &operator=(CopyableGlobal &&that)
170     {
171         Move(that);
172         return *this;
173     }
174 
175     template<typename S>
176     CopyableGlobal(const EcmaVM *vm, const Local<S> &current);
177 
178     CopyableGlobal(const EcmaVM *vm, const Local<T> &current);
179 
180     template<typename S>
CopyableGlobal(const CopyableGlobal<S> & that)181     CopyableGlobal(const CopyableGlobal<S> &that)
182     {
183         Copy(that);
184     }
185 
Reset()186     void Reset()
187     {
188         Free();
189     }
190 
ToLocal()191     Local<T> ToLocal() const
192     {
193         if (IsEmpty()) {
194             return Local<T>();
195         }
196         return Local<T>(vm_, *this);
197     }
198 
Empty()199     void Empty()
200     {
201         address_ = 0;
202     }
203 
204     inline T *operator*() const
205     {
206         return GetAddress();
207     }
208 
209     inline T *operator->() const
210     {
211         return GetAddress();
212     }
213 
IsEmpty()214     inline bool IsEmpty() const
215     {
216         return GetAddress() == nullptr;
217     }
218 
219     void SetWeak();
220 
221     void ClearWeak();
222 
223     bool IsWeak() const;
224 
GetEcmaVM()225     const EcmaVM *GetEcmaVM() const
226     {
227         return vm_;
228     }
229 
230 private:
GetAddress()231     inline T *GetAddress() const
232     {
233         return reinterpret_cast<T *>(address_);
234     };
235     inline void Copy(const CopyableGlobal &that);
236     template<typename S>
237     inline void Copy(const CopyableGlobal<S> &that);
238     inline void Move(CopyableGlobal &that);
239     inline void Free();
240     uintptr_t address_ = 0U;
241     const EcmaVM *vm_ {nullptr};
242 };
243 
244 template<typename T>
245 class PUBLIC_API Global {  // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions
246 public:
247     inline Global() = default;
248 
Global(const Global & that)249     inline Global(const Global &that)
250     {
251         Update(that);
252     }
253 
254     inline Global &operator=(const Global &that)
255     {
256         Update(that);
257         return *this;
258     }
259 
Global(Global && that)260     inline Global(Global &&that)
261     {
262         Update(that);
263     }
264 
265     inline Global &operator=(Global &&that)
266     {
267         Update(that);
268         return *this;
269     }
270 
271     template<typename S>
272     Global(const EcmaVM *vm, const Local<S> &current);
273     template<typename S>
274     Global(const EcmaVM *vm, const Global<S> &current);
275 
276     ~Global() = default;
277 
ToLocal()278     Local<T> ToLocal() const
279     {
280         if (IsEmpty()) {
281             return Local<T>();
282         }
283         return Local<T>(vm_, *this);
284     }
285 
ToLocal(const EcmaVM * vm)286     Local<T> ToLocal(const EcmaVM *vm) const
287     {
288         return Local<T>(vm, *this);
289     }
290 
Empty()291     void Empty()
292     {
293         address_ = 0;
294     }
295 
296     // This method must be called before Global is released.
297     void FreeGlobalHandleAddr();
298 
299     inline T *operator*() const
300     {
301         return GetAddress();
302     }
303 
304     inline T *operator->() const
305     {
306         return GetAddress();
307     }
308 
IsEmpty()309     inline bool IsEmpty() const
310     {
311         return GetAddress() == nullptr;
312     }
313 
314     void SetWeak();
315 
316     void SetWeakCallback(void *ref, WeakRefClearCallBack firstCallback, WeakRefClearCallBack secondCallback);
317 
318     void ClearWeak();
319 
320     bool IsWeak() const;
321 
322 private:
GetAddress()323     inline T *GetAddress() const
324     {
325         return reinterpret_cast<T *>(address_);
326     };
327     inline void Update(const Global &that);
328     uintptr_t address_ = 0U;
329     const EcmaVM *vm_ {nullptr};
330 };
331 
332 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
333 class PUBLIC_API LocalScope {
334 public:
335     explicit LocalScope(const EcmaVM *vm);
336     virtual ~LocalScope();
337 
338 protected:
339     inline LocalScope(const EcmaVM *vm, JSTaggedType value);
340 
341 private:
342     void *prevNext_ = nullptr;
343     void *prevEnd_ = nullptr;
344     int prevHandleStorageIndex_ {-1};
345     void *thread_ = nullptr;
346 };
347 
348 class PUBLIC_API EscapeLocalScope final : public LocalScope {
349 public:
350     explicit EscapeLocalScope(const EcmaVM *vm);
351     ~EscapeLocalScope() override = default;
352 
353     ECMA_DISALLOW_COPY(EscapeLocalScope);
354     ECMA_DISALLOW_MOVE(EscapeLocalScope);
355 
356     template<typename T>
Escape(Local<T> current)357     inline Local<T> Escape(Local<T> current)
358     {
359         ASSERT(!alreadyEscape_);
360         alreadyEscape_ = true;
361         *(reinterpret_cast<T *>(escapeHandle_)) = **current;
362         return Local<T>(escapeHandle_);
363     }
364 
365 private:
366     bool alreadyEscape_ = false;
367     uintptr_t escapeHandle_ = 0U;
368 };
369 
370 class PUBLIC_API JSExecutionScope {
371 public:
372     explicit JSExecutionScope(const EcmaVM *vm);
373     ~JSExecutionScope();
374     ECMA_DISALLOW_COPY(JSExecutionScope);
375     ECMA_DISALLOW_MOVE(JSExecutionScope);
376 
377 private:
378     void *last_current_thread_ = nullptr;
379     bool is_revert_ = false;
380 };
381 
382 class PUBLIC_API JSValueRef {
383 public:
384     static Local<PrimitiveRef> Undefined(const EcmaVM *vm);
385     static Local<PrimitiveRef> Null(const EcmaVM *vm);
386     static Local<PrimitiveRef> True(const EcmaVM *vm);
387     static Local<PrimitiveRef> False(const EcmaVM *vm);
388 
389     bool BooleaValue();
390     int64_t IntegerValue(const EcmaVM *vm);
391     uint32_t Uint32Value(const EcmaVM *vm);
392     int32_t Int32Value(const EcmaVM *vm);
393 
394     Local<NumberRef> ToNumber(const EcmaVM *vm);
395     Local<BooleanRef> ToBoolean(const EcmaVM *vm);
396     Local<StringRef> ToString(const EcmaVM *vm);
397     Local<ObjectRef> ToObject(const EcmaVM *vm);
398     Local<NativePointerRef> ToNativePointer(const EcmaVM *vm);
399 
400     bool IsUndefined();
401     bool IsNull();
402     bool IsHole();
403     bool IsTrue();
404     bool IsFalse();
405     bool IsNumber();
406     bool IsBigInt();
407     bool IsInt();
408     bool WithinInt32();
409     bool IsBoolean();
410     bool IsString();
411     bool IsSymbol();
412     bool IsObject();
413     bool IsArray(const EcmaVM *vm);
414     bool IsConstructor();
415     bool IsFunction();
416     bool IsProxy();
417     bool IsPromise();
418     bool IsDataView();
419     bool IsTypedArray();
420     bool IsNativePointer();
421     bool IsDate();
422     bool IsError();
423     bool IsMap();
424     bool IsSet();
425     bool IsWeakRef();
426     bool IsWeakMap();
427     bool IsWeakSet();
428     bool IsRegExp();
429     bool IsArrayIterator();
430     bool IsStringIterator();
431     bool IsSetIterator();
432     bool IsMapIterator();
433     bool IsArrayBuffer();
434     bool IsUint8Array();
435     bool IsInt8Array();
436     bool IsUint8ClampedArray();
437     bool IsInt16Array();
438     bool IsUint16Array();
439     bool IsInt32Array();
440     bool IsUint32Array();
441     bool IsFloat32Array();
442     bool IsFloat64Array();
443     bool IsBigInt64Array();
444     bool IsBigUint64Array();
445     bool IsJSPrimitiveRef();
446     bool IsJSPrimitiveNumber();
447     bool IsJSPrimitiveInt();
448     bool IsJSPrimitiveBoolean();
449     bool IsJSPrimitiveString();
450 
451     bool IsGeneratorObject();
452     bool IsJSPrimitiveSymbol();
453 
454     bool IsArgumentsObject();
455     bool IsGeneratorFunction();
456     bool IsAsyncFunction();
457     bool IsJSLocale();
458     bool IsJSDateTimeFormat();
459     bool IsJSRelativeTimeFormat();
460     bool IsJSIntl();
461     bool IsJSNumberFormat();
462     bool IsJSCollator();
463     bool IsJSPluralRules();
464     bool IsJSListFormat();
465     bool IsAsyncGeneratorFunction();
466     bool IsAsyncGeneratorObject();
467 
468     bool IsModuleNamespaceObject();
469     bool IsSharedArrayBuffer();
470 
471     bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value);
472     Local<StringRef> Typeof(const EcmaVM *vm);
473     bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value);
474 
475 private:
476     JSTaggedType value_;
477     friend JSNApi;
478     template<typename T>
479     friend class Global;
480     template<typename T>
481     friend class Local;
482 };
483 
484 class PUBLIC_API PrimitiveRef : public JSValueRef {
485 public:
486     Local<JSValueRef> GetValue(const EcmaVM *vm);
487 };
488 
489 class PUBLIC_API IntegerRef : public PrimitiveRef {
490 public:
491     static Local<IntegerRef> New(const EcmaVM *vm, int input);
492     static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input);
493     int Value();
494 };
495 
496 class PUBLIC_API NumberRef : public PrimitiveRef {
497 public:
498     static Local<NumberRef> New(const EcmaVM *vm, double input);
499     static Local<NumberRef> New(const EcmaVM *vm, int32_t input);
500     static Local<NumberRef> New(const EcmaVM *vm, uint32_t input);
501     static Local<NumberRef> New(const EcmaVM *vm, int64_t input);
502 
503     double Value();
504 };
505 
506 class PUBLIC_API BigIntRef : public PrimitiveRef {
507 public:
508     static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input);
509     static Local<BigIntRef> New(const EcmaVM *vm, int64_t input);
510     static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words);
511     void BigIntToInt64(const EcmaVM *vm, int64_t *cValue, bool *lossless);
512     void BigIntToUint64(const EcmaVM *vm, uint64_t *cValue, bool *lossless);
513     void GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words);
514     uint32_t GetWordsArraySize();
515 };
516 
517 class PUBLIC_API BooleanRef : public PrimitiveRef {
518 public:
519     static Local<BooleanRef> New(const EcmaVM *vm, bool input);
520     bool Value();
521 };
522 
523 class PUBLIC_API StringRef : public PrimitiveRef {
524 public:
Cast(JSValueRef * value)525     static inline StringRef *Cast(JSValueRef *value)
526     {
527         // check
528         return static_cast<StringRef *>(value);
529     }
530     static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1);
531     std::string ToString();
532     int32_t Length();
533     int32_t Utf8Length();
534     int WriteUtf8(char *buffer, int length);
535     static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm);
536 };
537 
538 class PUBLIC_API SymbolRef : public PrimitiveRef {
539 public:
540     static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description);
541     Local<StringRef> GetDescription(const EcmaVM *vm);
542 };
543 
544 using NativePointerCallback = void (*)(void* value, void* hint);
545 class PUBLIC_API NativePointerRef : public JSValueRef {
546 public:
547     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0);
548     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack,
549                                        void *data, size_t nativeBindingsize = 0);
550     void *Value();
551 };
552 
553 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
554 class PUBLIC_API PropertyAttribute {
555 public:
Default()556     static PropertyAttribute Default()
557     {
558         return PropertyAttribute();
559     }
560     PropertyAttribute() = default;
PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)561     PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c)
562         : value_(value),
563           writable_(w),
564           enumerable_(e),
565           configurable_(c),
566           hasWritable_(true),
567           hasEnumerable_(true),
568           hasConfigurable_(true)
569     {}
570     ~PropertyAttribute() = default;
571 
IsWritable()572     bool IsWritable() const
573     {
574         return writable_;
575     }
SetWritable(bool flag)576     void SetWritable(bool flag)
577     {
578         writable_ = flag;
579         hasWritable_ = true;
580     }
IsEnumerable()581     bool IsEnumerable() const
582     {
583         return enumerable_;
584     }
SetEnumerable(bool flag)585     void SetEnumerable(bool flag)
586     {
587         enumerable_ = flag;
588         hasEnumerable_ = true;
589     }
IsConfigurable()590     bool IsConfigurable() const
591     {
592         return configurable_;
593     }
SetConfigurable(bool flag)594     void SetConfigurable(bool flag)
595     {
596         configurable_ = flag;
597         hasConfigurable_ = true;
598     }
HasWritable()599     bool HasWritable() const
600     {
601         return hasWritable_;
602     }
HasConfigurable()603     bool HasConfigurable() const
604     {
605         return hasConfigurable_;
606     }
HasEnumerable()607     bool HasEnumerable() const
608     {
609         return hasEnumerable_;
610     }
GetValue(const EcmaVM * vm)611     Local<JSValueRef> GetValue(const EcmaVM *vm) const
612     {
613         if (value_.IsEmpty()) {
614             return JSValueRef::Undefined(vm);
615         }
616         return value_;
617     }
SetValue(Local<JSValueRef> value)618     void SetValue(Local<JSValueRef> value)
619     {
620         value_ = value;
621     }
HasValue()622     inline bool HasValue() const
623     {
624         return !value_.IsEmpty();
625     }
GetGetter(const EcmaVM * vm)626     Local<JSValueRef> GetGetter(const EcmaVM *vm) const
627     {
628         if (getter_.IsEmpty()) {
629             return JSValueRef::Undefined(vm);
630         }
631         return getter_;
632     }
SetGetter(Local<JSValueRef> value)633     void SetGetter(Local<JSValueRef> value)
634     {
635         getter_ = value;
636     }
HasGetter()637     bool HasGetter() const
638     {
639         return !getter_.IsEmpty();
640     }
GetSetter(const EcmaVM * vm)641     Local<JSValueRef> GetSetter(const EcmaVM *vm) const
642     {
643         if (setter_.IsEmpty()) {
644             return JSValueRef::Undefined(vm);
645         }
646         return setter_;
647     }
SetSetter(Local<JSValueRef> value)648     void SetSetter(Local<JSValueRef> value)
649     {
650         setter_ = value;
651     }
HasSetter()652     bool HasSetter() const
653     {
654         return !setter_.IsEmpty();
655     }
656 
657 private:
658     Local<JSValueRef> value_;
659     Local<JSValueRef> getter_;
660     Local<JSValueRef> setter_;
661     bool writable_ = false;
662     bool enumerable_ = false;
663     bool configurable_ = false;
664     bool hasWritable_ = false;
665     bool hasEnumerable_ = false;
666     bool hasConfigurable_ = false;
667 };
668 
669 class PUBLIC_API ObjectRef : public JSValueRef {
670 public:
Cast(JSValueRef * value)671     static inline ObjectRef *Cast(JSValueRef *value)
672     {
673         // check
674         return static_cast<ObjectRef *>(value);
675     }
676     static Local<ObjectRef> New(const EcmaVM *vm);
677     static Local<ObjectRef> New(const EcmaVM *vm, void *attach, void *detach);
678     bool Set(const EcmaVM *vm, void *attach, void *detach);
679     bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
680     bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value);
681     bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
682                              Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default());
683     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
684     Local<JSValueRef> Get(const EcmaVM *vm, int32_t key);
685 
686     bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property);
687     Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm);
688     Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm);
689     Local<JSValueRef> GetPrototype(const EcmaVM *vm);
690 
691     bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute);
692 
693     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
694     bool Has(const EcmaVM *vm, uint32_t key);
695 
696     bool Delete(const EcmaVM *vm, Local<JSValueRef> key);
697     bool Delete(const EcmaVM *vm, uint32_t key);
698 
699     void SetNativePointerFieldCount(int32_t count);
700     int32_t GetNativePointerFieldCount();
701     void *GetNativePointerField(int32_t index);
702     void SetNativePointerField(int32_t index,
703                                void *nativePointer = nullptr,
704                                NativePointerCallback callBack = nullptr,
705                                void *data = nullptr, size_t nativeBindingsize = 0);
706 };
707 
708 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
709 class PUBLIC_API FunctionRef : public ObjectRef {
710 public:
711     static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter = nullptr,
712         void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
713     static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter,
714         void *data, bool callNapi = false, size_t nativeBindingsize = 0);
715     Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[],
716         int32_t length);
717     Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length);
718 
719     Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm);
720     // Inherit Prototype from parent function
721     // set this.Prototype.__proto__ to parent.Prototype, set this.__proto__ to parent function
722     bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent);
723     void SetName(const EcmaVM *vm, Local<StringRef> name);
724     Local<StringRef> GetName(const EcmaVM *vm);
725     Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber);
726     bool IsNative(const EcmaVM *vm);
727 };
728 
729 class PUBLIC_API ArrayRef : public ObjectRef {
730 public:
731     static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
732     int32_t Length(const EcmaVM *vm);
733     static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
734     static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
735 };
736 
737 class PUBLIC_API PromiseRef : public ObjectRef {
738 public:
739     Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler);
740     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler);
741     Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler);
742     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected);
743 };
744 
745 class PUBLIC_API PromiseCapabilityRef : public ObjectRef {
746 public:
747     static Local<PromiseCapabilityRef> New(const EcmaVM *vm);
748     bool Resolve(const EcmaVM *vm, Local<JSValueRef> value);
749     bool Reject(const EcmaVM *vm, Local<JSValueRef> reason);
750     Local<PromiseRef> GetPromise(const EcmaVM *vm);
751 };
752 
753 class PUBLIC_API ArrayBufferRef : public ObjectRef {
754 public:
755     static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length);
756     static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter,
757                                      void *data);
758 
759     int32_t ByteLength(const EcmaVM *vm);
760     void *GetBuffer();
761 };
762 
763 class PUBLIC_API DataViewRef : public ObjectRef {
764 public:
765     static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset,
766                                   uint32_t byteLength);
767     uint32_t ByteLength();
768     uint32_t ByteOffset();
769     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
770 };
771 
772 class PUBLIC_API TypedArrayRef : public ObjectRef {
773 public:
774     uint32_t ByteLength(const EcmaVM *vm);
775     uint32_t ByteOffset(const EcmaVM *vm);
776     uint32_t ArrayLength(const EcmaVM *vm);
777     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
778 };
779 
780 class PUBLIC_API Int8ArrayRef : public TypedArrayRef {
781 public:
782     static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
783 };
784 
785 class PUBLIC_API Uint8ArrayRef : public TypedArrayRef {
786 public:
787     static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
788 };
789 
790 class PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef {
791 public:
792     static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
793                                            int32_t length);
794 };
795 
796 class PUBLIC_API Int16ArrayRef : public TypedArrayRef {
797 public:
798     static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
799 };
800 
801 class PUBLIC_API Uint16ArrayRef : public TypedArrayRef {
802 public:
803     static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
804                                      int32_t length);
805 };
806 
807 class PUBLIC_API Int32ArrayRef : public TypedArrayRef {
808 public:
809     static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
810 };
811 
812 class PUBLIC_API Uint32ArrayRef : public TypedArrayRef {
813 public:
814     static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
815                                      int32_t length);
816 };
817 
818 class PUBLIC_API Float32ArrayRef : public TypedArrayRef {
819 public:
820     static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
821                                       int32_t length);
822 };
823 
824 class PUBLIC_API Float64ArrayRef : public TypedArrayRef {
825 public:
826     static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
827                                       int32_t length);
828 };
829 
830 class PUBLIC_API BigInt64ArrayRef : public TypedArrayRef {
831 public:
832     static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
833                                       int32_t length);
834 };
835 
836 class PUBLIC_API BigUint64ArrayRef : public TypedArrayRef {
837 public:
838     static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
839                                       int32_t length);
840 };
841 
842 class PUBLIC_API RegExpRef : public ObjectRef {
843 public:
844     Local<StringRef> GetOriginalSource(const EcmaVM *vm);
845     std::string GetOriginalFlags();
846     Local<JSValueRef> IsGlobal(const EcmaVM *vm);
847     Local<JSValueRef> IsIgnoreCase(const EcmaVM *vm);
848     Local<JSValueRef> IsMultiline(const EcmaVM *vm);
849     Local<JSValueRef> IsDotAll(const EcmaVM *vm);
850     Local<JSValueRef> IsUtf16(const EcmaVM *vm);
851     Local<JSValueRef> IsStick(const EcmaVM *vm);
852 };
853 
854 class PUBLIC_API DateRef : public ObjectRef {
855 public:
856     static Local<DateRef> New(const EcmaVM *vm, double time);
857     Local<StringRef> ToString(const EcmaVM *vm);
858     double GetTime();
859 };
860 
861 class PUBLIC_API MapRef : public ObjectRef {
862 public:
863     int32_t GetSize();
864     int32_t GetTotalElements();
865     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
866     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
867     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
868     static Local<MapRef> New(const EcmaVM *vm);
869     void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
870 };
871 
872 class PUBLIC_API SetRef : public ObjectRef {
873 public:
874     int32_t GetSize();
875     int32_t GetTotalElements();
876     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
877 };
878 
879 class PUBLIC_API MapIteratorRef : public ObjectRef {
880 public:
881     int32_t GetIndex();
882     Local<JSValueRef> GetKind(const EcmaVM *vm);
883 };
884 
885 class PUBLIC_API SetIteratorRef : public ObjectRef {
886 public:
887     int32_t GetIndex();
888     Local<JSValueRef> GetKind(const EcmaVM *vm);
889 };
890 
891 class PUBLIC_API GeneratorFunctionRef : public ObjectRef {
892 public:
893     bool IsGenerator();
894 };
895 
896 class PUBLIC_API GeneratorObjectRef : public ObjectRef {
897 public:
898     Local<JSValueRef> GetGeneratorState(const EcmaVM *vm);
899     Local<JSValueRef> GetGeneratorFunction(const EcmaVM *vm);
900     Local<JSValueRef> GetGeneratorReceiver(const EcmaVM *vm);
901 };
902 
903 class PUBLIC_API CollatorRef : public ObjectRef {
904 public:
905     Local<JSValueRef> GetCompareFunction(const EcmaVM *vm);
906 };
907 
908 class PUBLIC_API DataTimeFormatRef : public ObjectRef {
909 public:
910     Local<JSValueRef> GetFormatFunction(const EcmaVM *vm);
911 };
912 
913 class PUBLIC_API NumberFormatRef : public ObjectRef {
914 public:
915     Local<JSValueRef> GetFormatFunction(const EcmaVM *vm);
916 };
917 
918 class PUBLIC_API JSON {
919 public:
920     static Local<JSValueRef> Parse(const EcmaVM *vm, Local<StringRef> string);
921     static Local<JSValueRef> Stringify(const EcmaVM *vm, Local<JSValueRef> json);
922 };
923 
924 class PUBLIC_API Exception {
925 public:
926     static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message);
927     static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message);
928     static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message);
929     static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message);
930     static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message);
931     static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message);
932     static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message);
933     static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message);
934 };
935 
936 using LOG_PRINT = int (*)(int id, int level, const char *tag, const char *fmt, const char *message);
937 
938 class PUBLIC_API RuntimeOption {
939 public:
940     enum class PUBLIC_API GC_TYPE : uint8_t { EPSILON, GEN_GC, STW };
941     enum class PUBLIC_API LOG_LEVEL : uint8_t {
942         DEBUG = 3,
943         INFO = 4,
944         WARN = 5,
945         ERROR = 6,
946         FATAL = 7,
947     };
948 
SetGcType(GC_TYPE type)949     void SetGcType(GC_TYPE type)
950     {
951         gcType_ = type;
952     }
953 
SetGcPoolSize(uint32_t size)954     void SetGcPoolSize(uint32_t size)
955     {
956         gcPoolSize_ = size;
957     }
958 
SetLogLevel(LOG_LEVEL logLevel)959     void SetLogLevel(LOG_LEVEL logLevel)
960     {
961         logLevel_ = logLevel;
962     }
963 
SetLogBufPrint(LOG_PRINT out)964     void SetLogBufPrint(LOG_PRINT out)
965     {
966         logBufPrint_ = out;
967     }
968 
SetDebuggerLibraryPath(const std::string & path)969     void SetDebuggerLibraryPath(const std::string &path)
970     {
971         debuggerLibraryPath_ = path;
972     }
973 
SetEnableArkTools(bool value)974     void SetEnableArkTools(bool value) {
975         enableArkTools_ = value;
976     }
977 
SetEnableCpuprofiler(bool value)978     void SetEnableCpuprofiler(bool value) {
979         enableCpuprofiler_ = value;
980     }
981 
SetArkProperties(int prop)982     void SetArkProperties(int prop) {
983         arkProperties_ = prop;
984     }
985 
SetArkBundleName(std::string bundleName)986     void SetArkBundleName(std::string bundleName) {
987         arkBundleName_ = bundleName;
988     }
989 
SetGcThreadNum(size_t num)990     void SetGcThreadNum(size_t num)
991     {
992         gcThreadNum_ = num;
993     }
994 
SetLongPauseTime(size_t time)995     void SetLongPauseTime(size_t time)
996     {
997         longPauseTime_ = time;
998     }
999 
SetEnableAsmInterpreter(bool value)1000     void SetEnableAsmInterpreter(bool value)
1001     {
1002         enableAsmInterpreter_ = value;
1003     }
1004 
SetAsmOpcodeDisableRange(const std::string & value)1005     void SetAsmOpcodeDisableRange(const std::string &value)
1006     {
1007         asmOpcodeDisableRange_ = value;
1008     }
1009 
SetIsWorker()1010     void SetIsWorker()
1011     {
1012         isWorker_ = true;
1013     }
1014 
GetIsWorker()1015     bool GetIsWorker() const
1016     {
1017         return isWorker_;
1018     }
1019 
SetBundleName(const std::string & value)1020     void SetBundleName(const std::string &value)
1021     {
1022         bundleName_ = value;
1023     }
1024 
SetEnableAOT(bool value)1025     void SetEnableAOT(bool value)
1026     {
1027         enableAOT_ = value;
1028     }
1029 
SetAnDir(const std::string & value)1030     void SetAnDir(const std::string &value)
1031     {
1032         anDir_ = value;
1033     }
1034 
SetEnableProfile(bool value)1035     void SetEnableProfile(bool value)
1036     {
1037         enableProfile_ = value;
1038     }
1039 
1040     // Valid only when SetEnableProfile(true)
SetProfileDir(const std::string & value)1041     void SetProfileDir(const std::string &value)
1042     {
1043         profileDir_ = value;
1044     }
1045 
1046 private:
GetGcType()1047     std::string GetGcType() const
1048     {
1049         std::string gcType;
1050         switch (gcType_) {
1051             case GC_TYPE::GEN_GC:
1052                 gcType = "gen-gc";
1053                 break;
1054             case GC_TYPE::STW:
1055                 gcType = "stw";
1056                 break;
1057             case GC_TYPE::EPSILON:
1058                 gcType = "epsilon";
1059                 break;
1060             default:
1061                 UNREACHABLE();
1062         }
1063         return gcType;
1064     }
1065 
GetLogLevel()1066     std::string GetLogLevel() const
1067     {
1068         std::string logLevel;
1069         switch (logLevel_) {
1070             case LOG_LEVEL::INFO:
1071             case LOG_LEVEL::WARN:
1072                 logLevel = "info";
1073                 break;
1074             case LOG_LEVEL::ERROR:
1075                 logLevel = "error";
1076                 break;
1077             case LOG_LEVEL::FATAL:
1078                 logLevel = "fatal";
1079                 break;
1080             case LOG_LEVEL::DEBUG:
1081             default:
1082                 logLevel = "debug";
1083                 break;
1084         }
1085 
1086         return logLevel;
1087     }
1088 
GetGcPoolSize()1089     uint32_t GetGcPoolSize() const
1090     {
1091         return gcPoolSize_;
1092     }
1093 
GetLogBufPrint()1094     LOG_PRINT GetLogBufPrint() const
1095     {
1096         return logBufPrint_;
1097     }
1098 
GetDebuggerLibraryPath()1099     std::string GetDebuggerLibraryPath() const
1100     {
1101         return debuggerLibraryPath_;
1102     }
1103 
GetEnableArkTools()1104     bool GetEnableArkTools() const
1105     {
1106         return enableArkTools_;
1107     }
1108 
GetEnableCpuprofiler()1109     bool GetEnableCpuprofiler() const
1110     {
1111         return enableCpuprofiler_;
1112     }
1113 
GetArkProperties()1114     int GetArkProperties() const
1115     {
1116         return arkProperties_;
1117     }
1118 
GetArkBundleName()1119     std::string GetArkBundleName() const
1120     {
1121         return arkBundleName_;
1122     }
1123 
GetGcThreadNum()1124     size_t GetGcThreadNum() const
1125     {
1126         return gcThreadNum_;
1127     }
1128 
GetLongPauseTime()1129     size_t GetLongPauseTime() const
1130     {
1131         return longPauseTime_;
1132     }
1133 
GetEnableAsmInterpreter()1134     bool GetEnableAsmInterpreter() const
1135     {
1136         return enableAsmInterpreter_;
1137     }
1138 
GetAsmOpcodeDisableRange()1139     std::string GetAsmOpcodeDisableRange() const
1140     {
1141         return asmOpcodeDisableRange_;
1142     }
1143 
GetBundleName()1144     std::string GetBundleName() const
1145     {
1146         return bundleName_;
1147     }
1148 
GetEnableAOT()1149     bool GetEnableAOT() const
1150     {
1151         return enableAOT_;
1152     }
1153 
GetAnDir()1154     std::string GetAnDir() const
1155     {
1156         return anDir_;
1157     }
1158 
GetEnableProfile()1159     bool GetEnableProfile() const
1160     {
1161         return enableProfile_;
1162     }
1163 
GetProfileDir()1164     std::string GetProfileDir() const
1165     {
1166         return profileDir_;
1167     }
1168 
1169     GC_TYPE gcType_ = GC_TYPE::EPSILON;
1170     LOG_LEVEL logLevel_ = LOG_LEVEL::DEBUG;
1171     uint32_t gcPoolSize_ = ecmascript::DEFAULT_GC_POOL_SIZE;
1172     LOG_PRINT logBufPrint_ {nullptr};
1173     std::string debuggerLibraryPath_ {};
1174     bool enableArkTools_ {false};
1175     bool enableCpuprofiler_ {false};
1176     int arkProperties_ {-1};
1177     std::string arkBundleName_ = {""};
1178     size_t gcThreadNum_ {DEFAULT_GC_THREAD_NUM};
1179     size_t longPauseTime_ {DEFAULT_LONG_PAUSE_TIME};
1180     bool enableAsmInterpreter_ {true};
1181     bool isWorker_ {false};
1182     std::string asmOpcodeDisableRange_ {""};
1183     std::string bundleName_ {};
1184     bool enableAOT_ {false};
1185     std::string anDir_ {};
1186     bool enableProfile_ {false};
1187     std::string profileDir_ {};
1188     friend JSNApi;
1189 };
1190 
1191 class PUBLIC_API PromiseRejectInfo {
1192 public:
1193     enum class PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE };
1194     PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
1195                       PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data);
~PromiseRejectInfo()1196     ~PromiseRejectInfo() {}
1197     Local<JSValueRef> GetPromise() const;
1198     Local<JSValueRef> GetReason() const;
1199     PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const;
1200     void* GetData() const;
1201 
1202 private:
1203     Local<JSValueRef> promise_ {};
1204     Local<JSValueRef> reason_ {};
1205     PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT;
1206     void* data_ {nullptr};
1207 };
1208 
1209 class PUBLIC_API JSNApi {
1210 public:
1211     using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
1212 
1213     // JSVM
1214     // fixme: Rename SEMI_GC to YOUNG_GC
1215     enum class PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, FULL_GC };
1216     static EcmaVM *CreateJSVM(const RuntimeOption &option);
1217     static void DestroyJSVM(EcmaVM *ecmaVm);
1218     static void CleanJSVMCache();
1219 
1220     // aot load
1221     static void LoadAotFile(EcmaVM *vm, const std::string &hapPath);
1222 
1223     // JS code
1224     static bool Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false);
1225     static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
1226                         const std::string &filename = "", bool needUpdate = false);
1227     // merge abc, execute module buffer
1228     static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "",
1229                                     bool needUpdate = false);
1230     static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file);
1231     static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key);
1232     static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key);
1233 
1234     // ObjectRef Operation
1235     static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm);
1236     static void ExecutePendingJob(const EcmaVM *vm);
1237 
1238     // Memory
1239     // fixme: Rename SEMI_GC to YOUNG_GC
1240     static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1241     // Exception
1242     static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error);
1243     static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm);
1244     static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm);
1245     static bool HasPendingException(const EcmaVM *vm);
1246     static void EnableUserUncaughtErrorHandler(EcmaVM *vm);
1247 #ifndef PANDA_TARGET_IOS
1248     static bool StartDebugger(const char *libraryPath, EcmaVM *vm, bool isDebugMode, int32_t instanceId = 0,
1249         const DebuggerPostTask &debuggerPostTask = {});
1250 #else
1251     static bool StartDebugger(EcmaVM *vm, bool isDebugMode, int32_t instanceId = 0,
1252         const DebuggerPostTask &debuggerPostTask = {});
1253 #endif
1254     static bool StopDebugger(EcmaVM *vm);
1255     static bool IsMixedDebugEnabled(const EcmaVM *vm);
1256     static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress);
1257     // Serialize & Deserialize.
1258     static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer);
1259     static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1260     static void DeleteSerializationData(void *data);
1261     static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data);
1262     static void SetHostResolveBufferTracker(EcmaVM *vm,
1263         std::function<std::vector<uint8_t>(std::string dirPath, std::string requestPath)> cb);
1264     static void SetNativePtrGetter(EcmaVM *vm, void* cb);
1265     static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb);
1266     static void InitializeIcuData(const ecmascript::JSRuntimeOptions &options);
1267     static void InitializeMemMapAllocator();
1268     static void InitializePGOProfiler(const ecmascript::JSRuntimeOptions &options);
1269     static void DestoryAnDataManager();
1270     static void DestroyMemMapAllocator();
1271     static void DestroyPGOProfiler();
1272     static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);
1273     static void PreFork(EcmaVM *vm);
1274     static void PostFork(EcmaVM *vm, const RuntimeOption &option);
1275     static void addWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1276     static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1277 
1278     static bool LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName);
1279     static bool LoadPatch(EcmaVM *vm, const std::string &patchFileName, const void *patchBuffer, size_t patchSize,
1280                           const std::string &baseFileName);
1281     static bool UnloadPatch(EcmaVM *vm, const std::string &patchFileName);
1282     // check whether the exception is caused by quickfix methods.
1283     static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName);
1284     // register quickfix query function.
1285     static void RegisterQuickFixQueryFunc(EcmaVM *vm, QuickFixQueryCallBack callBack);
1286     static bool IsBundle(EcmaVM *vm);
1287     static void SetBundle(EcmaVM *vm, bool value);
1288     static void SetAssetPath(EcmaVM *vm, const std::string &assetPath);
1289     static std::string GetAssetPath(EcmaVM *vm);
1290     static void SetBundleName(EcmaVM *vm, std::string bundleName);
1291     static std::string GetBundleName(EcmaVM *vm);
1292     static void SetModuleName(EcmaVM *vm, std::string moduleName);
1293     static std::string GetModuleName(EcmaVM *vm);
1294     static void SetLoop(EcmaVM *vm, void *loop);
1295     static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func);
1296     static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data);
1297 
1298 private:
1299     static int vmCount_;
1300     static bool initialize_;
1301     static bool CreateRuntime(const RuntimeOption &option);
1302     static bool DestroyRuntime();
1303 
1304     static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1305     static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1306     static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress);
1307     static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
1308                                      WeakRefClearCallBack firstCallback, WeakRefClearCallBack secondCallback);
1309     static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress);
1310     static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress);
1311     static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr);
1312     template<typename T>
1313     friend class Global;
1314     template<typename T>
1315     friend class CopyableGlobal;
1316     template<typename T>
1317     friend class Local;
1318     friend class test::JSNApiTests;
1319 };
1320 
1321 /**
1322  * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data.
1323  */
1324 class PUBLIC_API JsiRuntimeCallInfo {
1325 public:
1326     JsiRuntimeCallInfo(ecmascript::EcmaRuntimeCallInfo* ecmaInfo, void* data);
1327     ~JsiRuntimeCallInfo() = default;
1328 
GetThread()1329     inline JSThread *GetThread() const
1330     {
1331         return thread_;
1332     }
1333 
1334     EcmaVM *GetVM() const;
1335 
GetArgsNumber()1336     inline uint32_t GetArgsNumber() const
1337     {
1338         return numArgs_;
1339     }
1340 
GetData()1341     inline void* GetData() const
1342     {
1343         return data_;
1344     }
1345 
GetFunctionRef()1346     inline Local<JSValueRef> GetFunctionRef() const
1347     {
1348         return GetArgRef(FUNC_INDEX);
1349     }
1350 
GetNewTargetRef()1351     inline Local<JSValueRef> GetNewTargetRef() const
1352     {
1353         return GetArgRef(NEW_TARGET_INDEX);
1354     }
1355 
GetThisRef()1356     inline Local<JSValueRef> GetThisRef() const
1357     {
1358         return GetArgRef(THIS_INDEX);
1359     }
1360 
GetCallArgRef(uint32_t idx)1361     inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const
1362     {
1363         return GetArgRef(FIRST_ARGS_INDEX + idx);
1364     }
1365 
1366 private:
1367     enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX };
1368 
GetArgRef(uint32_t idx)1369     Local<JSValueRef> GetArgRef(uint32_t idx) const
1370     {
1371         return Local<JSValueRef>(GetArgAddress(idx));
1372     }
1373 
GetArgAddress(uint32_t idx)1374     uintptr_t GetArgAddress(uint32_t idx) const
1375     {
1376         if (idx < static_cast<uint32_t>(numArgs_ + FIRST_ARGS_INDEX)) {
1377             return reinterpret_cast<uintptr_t>(&stackArgs_[idx]);
1378         }
1379         return 0U;
1380     }
1381 
1382 private:
1383     JSThread *thread_ {nullptr};
1384     uint32_t numArgs_ = 0;
1385     JSTaggedType *stackArgs_ {nullptr};
1386     void *data_ {nullptr};
1387     friend class FunctionRef;
1388 };
1389 
1390 template<typename T>
1391 template<typename S>
Global(const EcmaVM * vm,const Local<S> & current)1392 Global<T>::Global(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
1393 {
1394     if (!current.IsEmpty()) {
1395         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
1396     }
1397 }
1398 
1399 template<typename T>
1400 template<typename S>
Global(const EcmaVM * vm,const Global<S> & current)1401 Global<T>::Global(const EcmaVM *vm, const Global<S> &current) : vm_(vm)
1402 {
1403     if (!current.IsEmpty()) {
1404         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
1405     }
1406 }
1407 
1408 template<typename T>
CopyableGlobal(const EcmaVM * vm,const Local<T> & current)1409 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<T> &current) : vm_(vm)
1410 {
1411     if (!current.IsEmpty()) {
1412         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
1413     }
1414 }
1415 
1416 template<typename T>
1417 template<typename S>
CopyableGlobal(const EcmaVM * vm,const Local<S> & current)1418 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
1419 {
1420     if (!current.IsEmpty()) {
1421         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
1422     }
1423 }
1424 
1425 template<typename T>
Copy(const CopyableGlobal & that)1426 void CopyableGlobal<T>::Copy(const CopyableGlobal &that)
1427 {
1428     Free();
1429     vm_ = that.vm_;
1430     if (!that.IsEmpty()) {
1431         ASSERT(vm_ != nullptr);
1432         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
1433     }
1434 }
1435 
1436 template<typename T>
1437 template<typename S>
Copy(const CopyableGlobal<S> & that)1438 void CopyableGlobal<T>::Copy(const CopyableGlobal<S> &that)
1439 {
1440     Free();
1441     vm_ = that.GetEcmaVM();
1442     if (!that.IsEmpty()) {
1443         ASSERT(vm_ != nullptr);
1444         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
1445     }
1446 }
1447 
1448 template<typename T>
Move(CopyableGlobal & that)1449 void CopyableGlobal<T>::Move(CopyableGlobal &that)
1450 {
1451     Free();
1452     vm_ = that.vm_;
1453     address_ = that.address_;
1454     that.vm_ = nullptr;
1455     that.address_ = 0U;
1456 }
1457 
1458 template<typename T>
Free()1459 inline void CopyableGlobal<T>::Free()
1460 {
1461     if (!IsEmpty()) {
1462         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
1463         address_ = 0U;
1464     }
1465 }
1466 
1467 template<typename T>
SetWeak()1468 void CopyableGlobal<T>::SetWeak()
1469 {
1470     address_ = JSNApi::SetWeak(vm_, address_);
1471 }
1472 
1473 template<typename T>
ClearWeak()1474 void CopyableGlobal<T>::ClearWeak()
1475 {
1476     address_ = JSNApi::ClearWeak(vm_, address_);
1477 }
1478 
1479 template<typename T>
IsWeak()1480 bool CopyableGlobal<T>::IsWeak() const
1481 {
1482     return JSNApi::IsWeak(vm_, address_);
1483 }
1484 
1485 template<typename T>
Update(const Global & that)1486 void Global<T>::Update(const Global &that)
1487 {
1488     if (address_ != 0) {
1489         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
1490     }
1491     address_ = that.address_;
1492     vm_ = that.vm_;
1493 }
1494 
1495 template<typename T>
FreeGlobalHandleAddr()1496 void Global<T>::FreeGlobalHandleAddr()
1497 {
1498     if (address_ == 0) {
1499         return;
1500     }
1501     JSNApi::DisposeGlobalHandleAddr(vm_, address_);
1502     address_ = 0;
1503 }
1504 
1505 template<typename T>
SetWeak()1506 void Global<T>::SetWeak()
1507 {
1508     address_ = JSNApi::SetWeak(vm_, address_);
1509 }
1510 
1511 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack firstCallback,WeakRefClearCallBack secondCallback)1512 void Global<T>::SetWeakCallback(void *ref, WeakRefClearCallBack firstCallback, WeakRefClearCallBack secondCallback)
1513 {
1514     address_ = JSNApi::SetWeakCallback(vm_, address_, ref, firstCallback, secondCallback);
1515 }
1516 
1517 template<typename T>
ClearWeak()1518 void Global<T>::ClearWeak()
1519 {
1520     address_ = JSNApi::ClearWeak(vm_, address_);
1521 }
1522 
1523 template<typename T>
IsWeak()1524 bool Global<T>::IsWeak() const
1525 {
1526     return JSNApi::IsWeak(vm_, address_);
1527 }
1528 
1529 // ---------------------------------- Local --------------------------------------------
1530 template<typename T>
Local(const EcmaVM * vm,const CopyableGlobal<T> & current)1531 Local<T>::Local(const EcmaVM *vm, const CopyableGlobal<T> &current)
1532 {
1533     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
1534 }
1535 
1536 template<typename T>
Local(const EcmaVM * vm,const Global<T> & current)1537 Local<T>::Local(const EcmaVM *vm, const Global<T> &current)
1538 {
1539     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
1540 }
1541 }  // namespace panda
1542 #endif  // ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
1543