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