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