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