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