• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 <shared_mutex>
24 #include <string>
25 #include <vector>
26 #include <map>
27 #include <sys/time.h>
28 
29 #include "ecmascript/base/aligned_struct.h"
30 #include "ecmascript/base/config.h"
31 #include "ecmascript/mem/mem_common.h"
32 #include "ecmascript/napi/include/jsnapi_expo.h"
33 #ifndef NDEBUG
34 #include "libpandabase/utils/debug.h"
35 #endif
36 
37 #ifdef ERROR
38 #undef ERROR
39 #endif
40 
41 namespace panda {
42 class JSNApiHelper;
43 class EscapeLocalScope;
44 class PromiseRejectInfo;
45 template<typename T>
46 class CopyableGlobal;
47 template<typename T>
48 class Global;
49 class JSNApi;
50 template<typename T>
51 class Local;
52 class JSValueRef;
53 class PrimitiveRef;
54 class ArrayRef;
55 class BigIntRef;
56 class StringRef;
57 class ObjectRef;
58 class FunctionRef;
59 class NumberRef;
60 class BooleanRef;
61 class NativePointerRef;
62 class JsiRuntimeCallInfo;
63 namespace test {
64 class JSNApiTests;
65 }  // namespace test
66 class BufferRef;
67 namespace ecmascript {
68 class EcmaVM;
69 class JSTaggedValue;
70 class EcmaContext;
71 class JSRuntimeOptions;
72 class JSThread;
73 struct EcmaRuntimeCallInfo;
74 static constexpr uint32_t DEFAULT_GC_POOL_SIZE = 256_MB;
75 namespace base {
76 template<size_t ElementAlign, typename... Ts>
77 struct AlignedStruct;
78 struct AlignedPointer;
79 }
80 }  // namespace ecmascript
81 
82 using WeakRefClearCallBack = void (*)(void *);
83 using EcmaVM = ecmascript::EcmaVM;
84 using EcmaContext = ecmascript::EcmaContext;
85 using JSThread = ecmascript::JSThread;
86 using JSTaggedType = uint64_t;
87 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data);
88 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column,
89     std::string &packageName)>;
90 using DeviceDisconnectCallback = std::function<bool()>;
91 
92 static constexpr size_t DEFAULT_GC_THREAD_NUM = 7;
93 static constexpr size_t DEFAULT_LONG_PAUSE_TIME = 40;
94 
95 class ECMA_PUBLIC_API RegExpRef : public ObjectRef {
96 public:
97     Local<StringRef> GetOriginalSource(const EcmaVM *vm);
98     std::string GetOriginalFlags(const EcmaVM *vm);
99     Local<JSValueRef> IsGlobal(const EcmaVM *vm);
100     Local<JSValueRef> IsIgnoreCase(const EcmaVM *vm);
101     Local<JSValueRef> IsMultiline(const EcmaVM *vm);
102     Local<JSValueRef> IsDotAll(const EcmaVM *vm);
103     Local<JSValueRef> IsUtf16(const EcmaVM *vm);
104     Local<JSValueRef> IsStick(const EcmaVM *vm);
105 };
106 
107 class ECMA_PUBLIC_API GeneratorFunctionRef : public ObjectRef {
108 public:
109     bool IsGenerator(const EcmaVM *vm);
110 };
111 
112 class ECMA_PUBLIC_API GeneratorObjectRef : public ObjectRef {
113 public:
114     Local<JSValueRef> GetGeneratorState(const EcmaVM *vm);
115     Local<JSValueRef> GetGeneratorFunction(const EcmaVM *vm);
116     Local<JSValueRef> GetGeneratorReceiver(const EcmaVM *vm);
117 };
118 
119 class ECMA_PUBLIC_API CollatorRef : public ObjectRef {
120 public:
121     Local<JSValueRef> GetCompareFunction(const EcmaVM *vm);
122 };
123 
124 class ECMA_PUBLIC_API DataTimeFormatRef : public ObjectRef {
125 public:
126     Local<JSValueRef> GetFormatFunction(const EcmaVM *vm);
127 };
128 
129 class ECMA_PUBLIC_API NumberFormatRef : public ObjectRef {
130 public:
131     Local<JSValueRef> GetFormatFunction(const EcmaVM *vm);
132 };
133 
134 class ECMA_PUBLIC_API JSON {
135 public:
136     static Local<JSValueRef> Parse(const EcmaVM *vm, Local<StringRef> string);
137     static Local<JSValueRef> Stringify(const EcmaVM *vm, Local<JSValueRef> json);
138 };
139 
140 using LOG_PRINT = int (*)(int id, int level, const char *tag, const char *fmt, const char *message);
141 
142 class ECMA_PUBLIC_API RuntimeOption {
143 public:
144     enum class ECMA_PUBLIC_API GC_TYPE : uint8_t { EPSILON, GEN_GC, STW };
145     enum class ECMA_PUBLIC_API LOG_LEVEL : uint8_t {
146         DEBUG = 3,
147         INFO = 4,
148         WARN = 5,
149         ERROR = 6,
150         FATAL = 7,
151         FOLLOW = 100, // if hilog enabled follow hilog, otherwise use INFO level
152     };
153 
154     // This enum should follow the same value as defined in the BMS subsystem.
155     // Refer to the specification in aot-guide_zh.md.
156     enum class AOTCompileStatus {
157         NOT_COMPILED = 0,
158         COMPILE_SUCCESS = 1,
159         COMPILE_FAILED = 2,
160         COMPILE_CRASH = 3,
161         COMPILE_CANCELLED = 4,
162     };
163 
SetGcType(GC_TYPE type)164     void SetGcType(GC_TYPE type)
165     {
166         gcType_ = type;
167     }
168 
SetGcPoolSize(uint32_t size)169     void SetGcPoolSize(uint32_t size)
170     {
171         gcPoolSize_ = size;
172     }
173 
SetLogLevel(LOG_LEVEL logLevel)174     void SetLogLevel(LOG_LEVEL logLevel)
175     {
176         logLevel_ = logLevel;
177     }
178 
SetLogBufPrint(LOG_PRINT out)179     void SetLogBufPrint(LOG_PRINT out)
180     {
181         logBufPrint_ = out;
182     }
183 
SetDebuggerLibraryPath(const std::string & path)184     void SetDebuggerLibraryPath(const std::string &path)
185     {
186         debuggerLibraryPath_ = path;
187     }
188 
SetEnableArkTools(bool value)189     void SetEnableArkTools(bool value)
190     {
191         enableArkTools_ = value;
192     }
193 
SetEnableCpuprofiler(bool value)194     void SetEnableCpuprofiler(bool value)
195     {
196         enableCpuprofiler_ = value;
197     }
198 
SetArkProperties(int prop)199     void SetArkProperties(int prop)
200     {
201         arkProperties_ = prop;
202     }
203 
SetArkBundleName(const std::string & bundleName)204     void SetArkBundleName(const std::string &bundleName)
205     {
206         arkBundleName_ = bundleName;
207     }
208 
SetMemConfigProperty(std::string configProperty)209     void SetMemConfigProperty(std::string configProperty)
210     {
211         memConfigProperty_ = configProperty;
212     }
213 
SetGcThreadNum(size_t num)214     void SetGcThreadNum(size_t num)
215     {
216         gcThreadNum_ = num;
217     }
218 
SetLongPauseTime(size_t time)219     void SetLongPauseTime(size_t time)
220     {
221         longPauseTime_ = time;
222     }
223 
SetEnableAsmInterpreter(bool value)224     void SetEnableAsmInterpreter(bool value)
225     {
226         enableAsmInterpreter_ = value;
227     }
228 
SetEnableBuiltinsLazy(bool value)229     void SetEnableBuiltinsLazy(bool value)
230     {
231         enableBuiltinsLazy_ = value;
232     }
233 
SetAsmOpcodeDisableRange(const std::string & value)234     void SetAsmOpcodeDisableRange(const std::string &value)
235     {
236         asmOpcodeDisableRange_ = value;
237     }
238 
SetIsWorker()239     void SetIsWorker()
240     {
241         isWorker_ = true;
242     }
243 
GetIsWorker()244     bool GetIsWorker() const
245     {
246         return isWorker_;
247     }
248 
SetIsRestrictedWorker(bool isRestrictedWorker)249     inline void SetIsRestrictedWorker(bool isRestrictedWorker)
250     {
251         isRestrictedWorker_ = isRestrictedWorker;
252     }
253 
GetIsRestrictedWorker()254     bool GetIsRestrictedWorker() const
255     {
256         return isRestrictedWorker_;
257     }
258 
SetBundleName(const std::string & value)259     void SetBundleName(const std::string &value)
260     {
261         bundleName_ = value;
262     }
263 
SetEnableAOT(bool value)264     void SetEnableAOT(bool value)
265     {
266         enableAOT_ = value;
267     }
268 
SetAnDir(const std::string & value)269     void SetAnDir(const std::string &value)
270     {
271         anDir_ = value;
272     }
273 
SetEnableProfile(bool value)274     void SetEnableProfile(bool value)
275     {
276         enableProfile_ = value;
277     }
278 
279     // Valid only when SetEnableProfile(true)
SetProfileDir(const std::string & value)280     void SetProfileDir(const std::string &value)
281     {
282         profileDir_ = value;
283     }
284 
SetEnableJIT(bool value)285     void SetEnableJIT(bool value)
286     {
287         enableFastJIT_ = value;
288     }
289 
SetEnableBaselineJIT(bool value)290     void SetEnableBaselineJIT(bool value)
291     {
292         enableBaselineJIT_ = value;
293     }
294 
SetAOTCompileStatusMap(const std::map<std::string,int32_t> & value)295     void SetAOTCompileStatusMap(const std::map<std::string, int32_t> &value)
296     {
297         aotCompileStatusMap_ = value;
298     }
299 
GetAOTCompileStatusMap()300     const std::map<std::string, int32_t> &GetAOTCompileStatusMap() const
301     {
302         return aotCompileStatusMap_;
303     }
304 
305 private:
GetGcType()306     std::string GetGcType() const
307     {
308         std::string gcType;
309         switch (gcType_) {
310             case GC_TYPE::GEN_GC:
311                 gcType = "gen-gc";
312                 break;
313             case GC_TYPE::STW:
314                 gcType = "stw";
315                 break;
316             case GC_TYPE::EPSILON:
317                 gcType = "epsilon";
318                 break;
319             default:
320                 break;
321         }
322         return gcType;
323     }
324 
GetLogLevel()325     LOG_LEVEL GetLogLevel() const
326     {
327         return logLevel_;
328     }
329 
GetGcPoolSize()330     uint32_t GetGcPoolSize() const
331     {
332         return gcPoolSize_;
333     }
334 
GetLogBufPrint()335     LOG_PRINT GetLogBufPrint() const
336     {
337         return logBufPrint_;
338     }
339 
GetDebuggerLibraryPath()340     std::string GetDebuggerLibraryPath() const
341     {
342         return debuggerLibraryPath_;
343     }
344 
GetEnableArkTools()345     bool GetEnableArkTools() const
346     {
347         return enableArkTools_;
348     }
349 
GetEnableCpuprofiler()350     bool GetEnableCpuprofiler() const
351     {
352         return enableCpuprofiler_;
353     }
354 
GetArkProperties()355     int GetArkProperties() const
356     {
357         return arkProperties_;
358     }
359 
GetArkBundleName()360     std::string GetArkBundleName() const
361     {
362         return arkBundleName_;
363     }
364 
GetMemConfigProperty()365     std::string GetMemConfigProperty() const
366     {
367         return memConfigProperty_;
368     }
369 
GetGcThreadNum()370     size_t GetGcThreadNum() const
371     {
372         return gcThreadNum_;
373     }
374 
GetLongPauseTime()375     size_t GetLongPauseTime() const
376     {
377         return longPauseTime_;
378     }
379 
GetEnableAsmInterpreter()380     bool GetEnableAsmInterpreter() const
381     {
382         return enableAsmInterpreter_;
383     }
384 
GetEnableBuiltinsLazy()385     bool GetEnableBuiltinsLazy() const
386     {
387         return enableBuiltinsLazy_;
388     }
389 
GetAsmOpcodeDisableRange()390     std::string GetAsmOpcodeDisableRange() const
391     {
392         return asmOpcodeDisableRange_;
393     }
394 
GetBundleName()395     std::string GetBundleName() const
396     {
397         return bundleName_;
398     }
399 
GetEnableAOT()400     bool GetEnableAOT() const
401     {
402         return enableAOT_;
403     }
404 
GetAnDir()405     std::string GetAnDir() const
406     {
407         return anDir_;
408     }
409 
GetEnableProfile()410     bool GetEnableProfile() const
411     {
412         return enableProfile_;
413     }
414 
GetProfileDir()415     std::string GetProfileDir() const
416     {
417         return profileDir_;
418     }
419 
GetEnableJIT()420     bool GetEnableJIT() const
421     {
422         return enableFastJIT_;
423     }
424 
GetEnableDFXHiSysEvent()425     bool GetEnableDFXHiSysEvent() const
426     {
427         return enableDFXHiSysEvent_;
428     }
429 
GetEnableBaselineJIT()430     bool GetEnableBaselineJIT() const
431     {
432         return enableBaselineJIT_;
433     }
434 
435     GC_TYPE gcType_ = GC_TYPE::EPSILON;
436     LOG_LEVEL logLevel_ = LOG_LEVEL::DEBUG;
437     uint32_t gcPoolSize_ = ecmascript::DEFAULT_GC_POOL_SIZE;
438     LOG_PRINT logBufPrint_ {nullptr};
439     std::string debuggerLibraryPath_ {};
440     bool enableArkTools_ {false};
441     bool enableCpuprofiler_ {false};
442     int arkProperties_ {-1};
443     std::string arkBundleName_ = {""};
444     std::string memConfigProperty_ = {""};
445     size_t gcThreadNum_ {DEFAULT_GC_THREAD_NUM};
446     size_t longPauseTime_ {DEFAULT_LONG_PAUSE_TIME};
447     bool enableAsmInterpreter_ {true};
448     bool enableBuiltinsLazy_ {true};
449     bool isWorker_ {false};
450     bool isRestrictedWorker_ {false};
451     std::string asmOpcodeDisableRange_ {""};
452     std::string bundleName_ {};
453     bool enableAOT_ {false};
454     std::string anDir_ {};
455     bool enableProfile_ {false};
456     std::string profileDir_ {};
457     bool enableFastJIT_ {false};
458     bool enableDFXHiSysEvent_ {true};
459     bool enableBaselineJIT_ {false};
460     std::map<std::string, int32_t> aotCompileStatusMap_;
461     friend JSNApi;
462 };
463 
464 template<typename T>
465 template<typename S>
Global(const EcmaVM * vm,const Local<S> & current)466 Global<T>::Global(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
467 {
468     if (!current.IsEmpty()) {
469         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
470     }
471 }
472 
473 template<typename T>
474 template<typename S>
Global(const EcmaVM * vm,const Global<S> & current)475 Global<T>::Global(const EcmaVM *vm, const Global<S> &current) : vm_(vm)
476 {
477     if (!current.IsEmpty()) {
478         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
479     }
480 }
481 
482 template<typename T>
CopyableGlobal(const EcmaVM * vm,const Local<T> & current)483 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<T> &current) : vm_(vm)
484 {
485     if (!current.IsEmpty()) {
486         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
487     }
488 }
489 
490 template<typename T>
491 template<typename S>
CopyableGlobal(const EcmaVM * vm,const Local<S> & current)492 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
493 {
494     if (!current.IsEmpty()) {
495         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
496     }
497 }
498 
499 template<typename T>
Copy(const CopyableGlobal & that)500 void CopyableGlobal<T>::Copy(const CopyableGlobal &that)
501 {
502     Free();
503     vm_ = that.vm_;
504     if (!that.IsEmpty()) {
505         ECMA_ASSERT(vm_ != nullptr);
506         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
507     }
508 }
509 
510 template<typename T>
511 template<typename S>
Copy(const CopyableGlobal<S> & that)512 void CopyableGlobal<T>::Copy(const CopyableGlobal<S> &that)
513 {
514     Free();
515     vm_ = that.GetEcmaVM();
516     if (!that.IsEmpty()) {
517         ECMA_ASSERT(vm_ != nullptr);
518         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
519     }
520 }
521 
522 template<typename T>
Move(CopyableGlobal & that)523 void CopyableGlobal<T>::Move(CopyableGlobal &that)
524 {
525     Free();
526     vm_ = that.vm_;
527     address_ = that.address_;
528     that.vm_ = nullptr;
529     that.address_ = 0U;
530 }
531 
532 template<typename T>
Free()533 inline void CopyableGlobal<T>::Free()
534 {
535     if (!IsEmpty()) {
536         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
537         address_ = 0U;
538     }
539 }
540 
541 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)542 void CopyableGlobal<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
543                                         WeakRefClearCallBack nativeFinalizeCallback)
544 {
545     address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
546 }
547 
548 template<typename T>
SetWeak()549 void CopyableGlobal<T>::SetWeak()
550 {
551     address_ = JSNApi::SetWeak(vm_, address_);
552 }
553 
554 template<typename T>
ClearWeak()555 void CopyableGlobal<T>::ClearWeak()
556 {
557     address_ = JSNApi::ClearWeak(vm_, address_);
558 }
559 
560 template<typename T>
IsWeak()561 bool CopyableGlobal<T>::IsWeak() const
562 {
563     return JSNApi::IsWeak(vm_, address_);
564 }
565 
566 template<typename T>
Update(const Global & that)567 void Global<T>::Update(const Global &that)
568 {
569     if (address_ != 0) {
570         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
571     }
572     address_ = that.address_;
573     vm_ = that.vm_;
574 }
575 
576 template<typename T>
FreeGlobalHandleAddr()577 void Global<T>::FreeGlobalHandleAddr()
578 {
579     if (address_ == 0) {
580         return;
581     }
582     JSNApi::DisposeGlobalHandleAddr(vm_, address_);
583     address_ = 0;
584 }
585 
586 template<typename T>
SetWeak()587 void Global<T>::SetWeak()
588 {
589     address_ = JSNApi::SetWeak(vm_, address_);
590 }
591 
592 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)593 void Global<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
594                                 WeakRefClearCallBack nativeFinalizeCallback)
595 {
596     address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
597 }
598 
599 template<typename T>
ClearWeak()600 void Global<T>::ClearWeak()
601 {
602     address_ = JSNApi::ClearWeak(vm_, address_);
603 }
604 
605 template<typename T>
IsWeak()606 bool Global<T>::IsWeak() const
607 {
608     return JSNApi::IsWeak(vm_, address_);
609 }
610 
611 // ---------------------------------- Local --------------------------------------------
612 template<typename T>
Local(const EcmaVM * vm,const CopyableGlobal<T> & current)613 Local<T>::Local(const EcmaVM *vm, const CopyableGlobal<T> &current)
614 {
615     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
616 }
617 
618 template<typename T>
Local(const EcmaVM * vm,const Global<T> & current)619 Local<T>::Local(const EcmaVM *vm, const Global<T> &current)
620 {
621     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
622 }
623 }  // namespace panda
624 
625 #undef ECMA_ASSERT
626 #undef ECMA_PUBLIC_API
627 #endif  // ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
628