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> ¤t) : address_(reinterpret_cast<uintptr_t>(*current))
95 {
96 // Check
97 }
98
99 Local(const EcmaVM *vm, const Global<T> ¤t);
100
101 Local(const EcmaVM *vm, const CopyableGlobal<T> ¤t);
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> ¤t);
180
181 CopyableGlobal(const EcmaVM *vm, const Local<T> ¤t);
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> ¤t);
278 template<typename S>
279 Global(const EcmaVM *vm, const Global<S> ¤t);
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> ¤t) : 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> ¤t) : 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> ¤t) : 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> ¤t) : 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> ¤t)
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> ¤t)
1665 {
1666 address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
1667 }
1668 } // namespace panda
1669 #endif // ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
1670