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_EXPO_H 17 #define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H 18 19 #include <cassert> 20 #include <cstdint> 21 #include <functional> 22 #include <memory> 23 #include <map> 24 #include <shared_mutex> 25 #include <string> 26 #include <unordered_map> 27 #include <vector> 28 29 #include "ecmascript/base/aligned_struct.h" 30 #include "ecmascript/base/config.h" 31 #include "ecmascript/mem/mem_common.h" 32 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 class SymbolRef; 51 template<typename T> 52 class Local; 53 class JSValueRef; 54 class PrimitiveRef; 55 class ArrayRef; 56 class BigIntRef; 57 class StringRef; 58 class ObjectRef; 59 class FunctionRef; 60 class NumberRef; 61 class MapIteratorRef; 62 class BooleanRef; 63 class NativePointerRef; 64 class JsiRuntimeCallInfo; 65 class RuntimeOption; 66 namespace test { 67 class JSNApiTests; 68 } // namespace test 69 class BufferRef; 70 namespace ecmascript { 71 class EcmaVM; 72 class JSTaggedValue; 73 class EcmaContext; 74 class JSRuntimeOptions; 75 class JSThread; 76 struct EcmaRuntimeCallInfo; 77 namespace base { 78 template<size_t ElementAlign, typename... Ts> 79 struct AlignedStruct; 80 struct AlignedPointer; 81 } 82 } // namespace ecmascript 83 84 struct HmsMap { 85 std::string originalPath; 86 std::string targetPath; 87 uint32_t sinceVersion; 88 }; 89 90 using Deleter = void (*)(void *nativePointer, void *data); 91 using WeakRefClearCallBack = void (*)(void *); 92 using EcmaVM = ecmascript::EcmaVM; 93 using EcmaContext = ecmascript::EcmaContext; 94 using JSThread = ecmascript::JSThread; 95 using JSTaggedType = uint64_t; 96 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data); 97 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>; 98 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column)>; 99 using DeviceDisconnectCallback = std::function<bool()>; 100 101 #define ECMA_DISALLOW_COPY(className) \ 102 className(const className &) = delete; \ 103 className &operator=(const className &) = delete 104 105 #define ECMA_DISALLOW_MOVE(className) \ 106 className(className &&) = delete; \ 107 className &operator=(className &&) = delete 108 109 #ifdef PANDA_TARGET_WINDOWS 110 #define ECMA_PUBLIC_API __declspec(dllexport) 111 #else 112 #define ECMA_PUBLIC_API __attribute__((visibility ("default"))) 113 #endif 114 115 #ifndef NDEBUG 116 #define ECMA_ASSERT(cond) \ 117 if (!(cond)) { \ 118 panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \ 119 } 120 #else 121 #define ECMA_ASSERT(cond) static_cast<void>(0) 122 #endif 123 124 template<typename T> 125 class ECMA_PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 126 public: 127 inline Local() = default; 128 129 template<typename S> Local(const Local<S> & current)130 inline Local(const Local<S> ¤t) : address_(reinterpret_cast<uintptr_t>(*current)) 131 { 132 // Check 133 } 134 135 Local(const EcmaVM *vm, const Global<T> ¤t); 136 137 Local(const EcmaVM *vm, const CopyableGlobal<T> ¤t); 138 139 ~Local() = default; 140 141 inline T *operator*() const 142 { 143 return GetAddress(); 144 } 145 146 inline T *operator->() const 147 { 148 return GetAddress(); 149 } 150 IsEmpty()151 inline bool IsEmpty() const 152 { 153 return GetAddress() == nullptr; 154 } 155 Empty()156 inline void Empty() 157 { 158 address_ = 0; 159 } 160 IsNull()161 inline bool IsNull() const 162 { 163 return IsEmpty() || GetAddress()->IsHole(); 164 } 165 Local(uintptr_t addr)166 explicit inline Local(uintptr_t addr) : address_(addr) {} 167 168 private: GetAddress()169 inline T *GetAddress() const 170 { 171 return reinterpret_cast<T *>(address_); 172 }; 173 uintptr_t address_ = 0U; 174 friend JSNApiHelper; 175 friend EscapeLocalScope; 176 friend JsiRuntimeCallInfo; 177 }; 178 179 /** 180 * A Copyable global handle, keeps a separate global handle for each CopyableGlobal. 181 * 182 * Support Copy Constructor and Assign, Move Constructor And Assign. 183 * 184 * If destructed, the global handle held will be automatically released. 185 * 186 * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or 187 * a value passing return value and so on. 188 */ 189 template<typename T> 190 class ECMA_PUBLIC_API CopyableGlobal { 191 public: 192 inline CopyableGlobal() = default; ~CopyableGlobal()193 ~CopyableGlobal() 194 { 195 Free(); 196 } 197 CopyableGlobal(const CopyableGlobal & that)198 inline CopyableGlobal(const CopyableGlobal &that) 199 { 200 Copy(that); 201 } 202 203 inline CopyableGlobal &operator=(const CopyableGlobal &that) 204 { 205 Copy(that); 206 return *this; 207 } 208 CopyableGlobal(CopyableGlobal && that)209 inline CopyableGlobal(CopyableGlobal &&that) 210 { 211 Move(that); 212 } 213 214 inline CopyableGlobal &operator=(CopyableGlobal &&that) 215 { 216 Move(that); 217 return *this; 218 } 219 220 template<typename S> 221 CopyableGlobal(const EcmaVM *vm, const Local<S> ¤t); 222 223 CopyableGlobal(const EcmaVM *vm, const Local<T> ¤t); 224 225 template<typename S> CopyableGlobal(const CopyableGlobal<S> & that)226 CopyableGlobal(const CopyableGlobal<S> &that) 227 { 228 Copy(that); 229 } 230 Reset()231 void Reset() 232 { 233 Free(); 234 } 235 ToLocal()236 Local<T> ToLocal() const 237 { 238 if (IsEmpty()) { 239 return Local<T>(); 240 } 241 return Local<T>(vm_, *this); 242 } 243 Empty()244 void Empty() 245 { 246 address_ = 0; 247 } 248 249 inline T *operator*() const 250 { 251 return GetAddress(); 252 } 253 254 inline T *operator->() const 255 { 256 return GetAddress(); 257 } 258 IsEmpty()259 inline bool IsEmpty() const 260 { 261 return GetAddress() == nullptr; 262 } 263 264 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, 265 WeakRefClearCallBack nativeFinalizeCallback); 266 void SetWeak(); 267 268 void ClearWeak(); 269 270 bool IsWeak() const; 271 GetEcmaVM()272 const EcmaVM *GetEcmaVM() const 273 { 274 return vm_; 275 } 276 277 private: GetAddress()278 inline T *GetAddress() const 279 { 280 return reinterpret_cast<T *>(address_); 281 }; 282 inline void Copy(const CopyableGlobal &that); 283 template<typename S> 284 inline void Copy(const CopyableGlobal<S> &that); 285 inline void Move(CopyableGlobal &that); 286 inline void Free(); 287 uintptr_t address_ = 0U; 288 const EcmaVM *vm_ {nullptr}; 289 }; 290 291 template<typename T> 292 class ECMA_PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions 293 public: 294 inline Global() = default; 295 Global(const Global & that)296 inline Global(const Global &that) 297 { 298 Update(that); 299 } 300 301 inline Global &operator=(const Global &that) 302 { 303 Update(that); 304 return *this; 305 } 306 Global(Global && that)307 inline Global(Global &&that) 308 { 309 Update(that); 310 } 311 312 inline Global &operator=(Global &&that) 313 { 314 Update(that); 315 return *this; 316 } 317 318 template<typename S> 319 Global(const EcmaVM *vm, const Local<S> ¤t); 320 template<typename S> 321 Global(const EcmaVM *vm, const Global<S> ¤t); 322 323 ~Global() = default; 324 ToLocal()325 Local<T> ToLocal() const 326 { 327 if (IsEmpty()) { 328 return Local<T>(); 329 } 330 return Local<T>(vm_, *this); 331 } 332 ToLocal(const EcmaVM * vm)333 Local<T> ToLocal(const EcmaVM *vm) const 334 { 335 return Local<T>(vm, *this); 336 } 337 Empty()338 void Empty() 339 { 340 address_ = 0; 341 } 342 343 // This method must be called before Global is released. 344 void FreeGlobalHandleAddr(); 345 346 inline T *operator*() const 347 { 348 return GetAddress(); 349 } 350 351 inline T *operator->() const 352 { 353 return GetAddress(); 354 } 355 IsEmpty()356 inline bool IsEmpty() const 357 { 358 return GetAddress() == nullptr; 359 } 360 361 void SetWeak(); 362 363 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, 364 WeakRefClearCallBack nativeFinalizeCallback); 365 366 void ClearWeak(); 367 368 bool IsWeak() const; 369 370 private: GetAddress()371 inline T *GetAddress() const 372 { 373 return reinterpret_cast<T *>(address_); 374 }; 375 inline void Update(const Global &that); 376 uintptr_t address_ = 0U; 377 const EcmaVM *vm_ {nullptr}; 378 }; 379 380 class ECMA_PUBLIC_API JSValueRef { 381 public: 382 static Local<PrimitiveRef> Undefined(const EcmaVM *vm); 383 static Local<PrimitiveRef> Null(const EcmaVM *vm); 384 static Local<PrimitiveRef> True(const EcmaVM *vm); 385 static Local<PrimitiveRef> False(const EcmaVM *vm); 386 387 bool BooleaValue(); 388 int64_t IntegerValue(const EcmaVM *vm); 389 uint32_t Uint32Value(const EcmaVM *vm); 390 int32_t Int32Value(const EcmaVM *vm); 391 392 Local<NumberRef> ToNumber(const EcmaVM *vm); 393 Local<BooleanRef> ToBoolean(const EcmaVM *vm); 394 Local<BigIntRef> ToBigInt(const EcmaVM *vm); 395 Local<StringRef> ToString(const EcmaVM *vm); 396 Local<ObjectRef> ToObject(const EcmaVM *vm); 397 Local<NativePointerRef> ToNativePointer(const EcmaVM *vm); 398 399 bool IsUndefined(); 400 bool IsNull(); 401 bool IsHole(); 402 bool IsTrue(); 403 bool IsFalse(); 404 bool IsNumber(); 405 bool IsBigInt(); 406 bool IsInt(); 407 bool WithinInt32(); 408 bool IsBoolean(); 409 bool IsString(); 410 bool IsSymbol(); 411 bool IsObject(); 412 bool IsArray(const EcmaVM *vm); 413 bool IsJSArray(const EcmaVM *vm); 414 bool IsConstructor(); 415 bool IsFunction(); 416 bool IsJSFunction(); 417 bool IsProxy(); 418 bool IsPromise(); 419 bool IsDataView(); 420 bool IsTypedArray(); 421 bool IsNativePointer(); 422 bool IsDate(); 423 bool IsError(); 424 bool IsMap(); 425 bool IsSet(); 426 bool IsWeakRef(); 427 bool IsWeakMap(); 428 bool IsWeakSet(); 429 bool IsRegExp(); 430 bool IsArrayIterator(); 431 bool IsStringIterator(); 432 bool IsSetIterator(); 433 bool IsMapIterator(); 434 bool IsArrayBuffer(); 435 bool IsBuffer(); 436 bool IsUint8Array(); 437 bool IsInt8Array(); 438 bool IsUint8ClampedArray(); 439 bool IsInt16Array(); 440 bool IsUint16Array(); 441 bool IsInt32Array(); 442 bool IsUint32Array(); 443 bool IsFloat32Array(); 444 bool IsFloat64Array(); 445 bool IsBigInt64Array(); 446 bool IsBigUint64Array(); 447 bool IsJSPrimitiveRef(); 448 bool IsJSPrimitiveNumber(); 449 bool IsJSPrimitiveInt(); 450 bool IsJSPrimitiveBoolean(); 451 bool IsJSPrimitiveString(); 452 453 bool IsGeneratorObject(); 454 bool IsJSPrimitiveSymbol(); 455 456 bool IsArgumentsObject(); 457 bool IsGeneratorFunction(); 458 bool IsAsyncFunction(); 459 bool IsJSLocale(); 460 bool IsJSDateTimeFormat(); 461 bool IsJSRelativeTimeFormat(); 462 bool IsJSIntl(); 463 bool IsJSNumberFormat(); 464 bool IsJSCollator(); 465 bool IsJSPluralRules(); 466 bool IsJSListFormat(); 467 bool IsAsyncGeneratorFunction(); 468 bool IsAsyncGeneratorObject(); 469 470 bool IsModuleNamespaceObject(); 471 bool IsSharedArrayBuffer(); 472 473 bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value); 474 Local<StringRef> Typeof(const EcmaVM *vm); 475 bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value); 476 477 bool IsArrayList(); 478 bool IsDeque(); 479 bool IsHashMap(); 480 bool IsHashSet(); 481 bool IsLightWeightMap(); 482 bool IsLightWeightSet(); 483 bool IsLinkedList(); 484 bool IsLinkedListIterator(); 485 bool IsList(); 486 bool IsPlainArray(); 487 bool IsQueue(); 488 bool IsStack(); 489 bool IsTreeMap(); 490 bool IsTreeSet(); 491 bool IsVector(); 492 bool IsSharedObject(); 493 494 private: 495 JSTaggedType value_; 496 friend JSNApi; 497 template<typename T> 498 friend class Global; 499 template<typename T> 500 friend class Local; 501 }; 502 503 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 504 class ECMA_PUBLIC_API PropertyAttribute { 505 public: Default()506 static PropertyAttribute Default() 507 { 508 return PropertyAttribute(); 509 } 510 PropertyAttribute() = default; PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)511 PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c) 512 : value_(value), 513 writable_(w), 514 enumerable_(e), 515 configurable_(c), 516 hasWritable_(true), 517 hasEnumerable_(true), 518 hasConfigurable_(true) 519 {} 520 ~PropertyAttribute() = default; 521 IsWritable()522 bool IsWritable() const 523 { 524 return writable_; 525 } SetWritable(bool flag)526 void SetWritable(bool flag) 527 { 528 writable_ = flag; 529 hasWritable_ = true; 530 } IsEnumerable()531 bool IsEnumerable() const 532 { 533 return enumerable_; 534 } SetEnumerable(bool flag)535 void SetEnumerable(bool flag) 536 { 537 enumerable_ = flag; 538 hasEnumerable_ = true; 539 } IsConfigurable()540 bool IsConfigurable() const 541 { 542 return configurable_; 543 } SetConfigurable(bool flag)544 void SetConfigurable(bool flag) 545 { 546 configurable_ = flag; 547 hasConfigurable_ = true; 548 } HasWritable()549 bool HasWritable() const 550 { 551 return hasWritable_; 552 } HasConfigurable()553 bool HasConfigurable() const 554 { 555 return hasConfigurable_; 556 } HasEnumerable()557 bool HasEnumerable() const 558 { 559 return hasEnumerable_; 560 } GetValue(const EcmaVM * vm)561 Local<JSValueRef> GetValue(const EcmaVM *vm) const 562 { 563 if (value_.IsEmpty()) { 564 return JSValueRef::Undefined(vm); 565 } 566 return value_; 567 } SetValue(Local<JSValueRef> value)568 void SetValue(Local<JSValueRef> value) 569 { 570 value_ = value; 571 } HasValue()572 inline bool HasValue() const 573 { 574 return !value_.IsEmpty(); 575 } GetGetter(const EcmaVM * vm)576 Local<JSValueRef> GetGetter(const EcmaVM *vm) const 577 { 578 if (getter_.IsEmpty()) { 579 return JSValueRef::Undefined(vm); 580 } 581 return getter_; 582 } SetGetter(Local<JSValueRef> value)583 void SetGetter(Local<JSValueRef> value) 584 { 585 getter_ = value; 586 } HasGetter()587 bool HasGetter() const 588 { 589 return !getter_.IsEmpty(); 590 } GetSetter(const EcmaVM * vm)591 Local<JSValueRef> GetSetter(const EcmaVM *vm) const 592 { 593 if (setter_.IsEmpty()) { 594 return JSValueRef::Undefined(vm); 595 } 596 return setter_; 597 } SetSetter(Local<JSValueRef> value)598 void SetSetter(Local<JSValueRef> value) 599 { 600 setter_ = value; 601 } HasSetter()602 bool HasSetter() const 603 { 604 return !setter_.IsEmpty(); 605 } 606 607 private: 608 Local<JSValueRef> value_; 609 Local<JSValueRef> getter_; 610 Local<JSValueRef> setter_; 611 bool writable_ = false; 612 bool enumerable_ = false; 613 bool configurable_ = false; 614 bool hasWritable_ = false; 615 bool hasEnumerable_ = false; 616 bool hasConfigurable_ = false; 617 }; 618 619 using NativePointerCallback = void (*)(void* value, void* hint); 620 class ECMA_PUBLIC_API NativePointerRef : public JSValueRef { 621 public: 622 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0); 623 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, 624 void *data, size_t nativeBindingsize = 0); 625 void *Value(); 626 }; 627 628 class ECMA_PUBLIC_API ObjectRef : public JSValueRef { 629 public: 630 static constexpr int MAX_PROPERTIES_ON_STACK = 32; Cast(JSValueRef * value)631 static inline ObjectRef *Cast(JSValueRef *value) 632 { 633 return static_cast<ObjectRef *>(value); 634 } 635 static Local<ObjectRef> New(const EcmaVM *vm); 636 static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys, 637 const PropertyAttribute *attributes); 638 static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys, 639 const Local<JSValueRef> *values); 640 static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter); 641 bool ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value); 642 bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value); 643 bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value); 644 bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter, 645 Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default()); 646 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key); 647 Local<JSValueRef> Get(const EcmaVM *vm, int32_t key); 648 649 bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property); 650 Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm); 651 Local<ArrayRef> GetAllPropertyNames(const EcmaVM *vm, uint32_t filter); 652 Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm); 653 Local<JSValueRef> GetPrototype(const EcmaVM *vm); 654 bool SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype); 655 656 bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute); 657 658 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 659 bool Has(const EcmaVM *vm, uint32_t key); 660 661 bool Delete(const EcmaVM *vm, Local<JSValueRef> key); 662 bool Delete(const EcmaVM *vm, uint32_t key); 663 664 Local<JSValueRef> Freeze(const EcmaVM *vm); 665 Local<JSValueRef> Seal(const EcmaVM *vm); 666 667 void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count); 668 int32_t GetNativePointerFieldCount(); 669 void *GetNativePointerField(int32_t index); 670 void SetNativePointerField(const EcmaVM *vm, 671 int32_t index, 672 void *nativePointer = nullptr, 673 NativePointerCallback callBack = nullptr, 674 void *data = nullptr, size_t nativeBindingsize = 0); 675 }; 676 677 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*); 678 using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*); 679 class ECMA_PUBLIC_API FunctionRef : public ObjectRef { 680 public: 681 static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter = nullptr, 682 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); 683 static Local<FunctionRef> New(EcmaVM *vm, InternalFunctionCallback nativeFunc, Deleter deleter, 684 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); 685 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter, 686 void *data, bool callNapi = false, size_t nativeBindingsize = 0); 687 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc, Deleter deleter, 688 void *data, bool callNapi = false, size_t nativeBindingsize = 0); 689 JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[], 690 int32_t length); 691 Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[], 692 int32_t length); 693 Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length); 694 JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length); 695 696 Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm); 697 bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent); 698 void SetName(const EcmaVM *vm, Local<StringRef> name); 699 Local<StringRef> GetName(const EcmaVM *vm); 700 Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber); 701 bool IsNative(const EcmaVM *vm); 702 void SetData(const EcmaVM *vm, void *data, Deleter deleter = nullptr, bool callNapi = false); 703 void* GetData(const EcmaVM *vm); 704 }; 705 706 class ECMA_PUBLIC_API PrimitiveRef : public JSValueRef { 707 public: 708 Local<JSValueRef> GetValue(const EcmaVM *vm); 709 }; 710 711 class ECMA_PUBLIC_API SymbolRef : public PrimitiveRef { 712 public: 713 static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description = Local<StringRef>()); 714 Local<StringRef> GetDescription(const EcmaVM *vm); 715 }; 716 717 class ECMA_PUBLIC_API BooleanRef : public PrimitiveRef { 718 public: 719 static Local<BooleanRef> New(const EcmaVM *vm, bool input); 720 bool Value(); 721 }; 722 723 class ECMA_PUBLIC_API StringRef : public PrimitiveRef { 724 public: Cast(JSValueRef * value)725 static inline StringRef *Cast(JSValueRef *value) 726 { 727 // check 728 return static_cast<StringRef *>(value); 729 } 730 static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1); 731 static Local<StringRef> NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1); 732 std::string ToString(); 733 std::string DebuggerToString(); 734 uint32_t Length(); 735 int32_t Utf8Length(const EcmaVM *vm); 736 int WriteUtf8(char *buffer, int length, bool isWriteBuffer = false); 737 int WriteUtf16(char16_t *buffer, int length); 738 int WriteLatin1(char *buffer, int length); 739 static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm); 740 }; 741 742 class ECMA_PUBLIC_API PromiseRejectInfo { 743 public: 744 enum class ECMA_PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE }; 745 PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason, 746 PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data); ~PromiseRejectInfo()747 ~PromiseRejectInfo() {} 748 Local<JSValueRef> GetPromise() const; 749 Local<JSValueRef> GetReason() const; 750 PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const; 751 void* GetData() const; 752 753 private: 754 Local<JSValueRef> promise_ {}; 755 Local<JSValueRef> reason_ {}; 756 PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT; 757 void* data_ {nullptr}; 758 }; 759 760 /** 761 * An external exception handler. 762 */ 763 class ECMA_PUBLIC_API TryCatch { 764 public: TryCatch(const EcmaVM * ecmaVm)765 explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {}; 766 767 /** 768 * Consumes the exception by default if not rethrow explicitly. 769 */ 770 ~TryCatch(); 771 772 bool HasCaught() const; 773 void Rethrow(); 774 Local<ObjectRef> GetAndClearException(); 775 Local<ObjectRef> GetException(); 776 void ClearException(); 777 778 ECMA_DISALLOW_COPY(TryCatch); 779 ECMA_DISALLOW_MOVE(TryCatch); 780 getrethrow_()781 bool getrethrow_() 782 { 783 return rethrow_; 784 } 785 786 private: 787 // Disable dynamic allocation 788 void* operator new(size_t size) = delete; 789 void operator delete(void*, size_t) = delete; 790 void* operator new[](size_t size) = delete; 791 void operator delete[](void*, size_t) = delete; 792 793 const EcmaVM *ecmaVm_ {nullptr}; 794 bool rethrow_ {false}; 795 }; 796 797 class ECMA_PUBLIC_API BigIntRef : public PrimitiveRef { 798 public: 799 static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input); 800 static Local<BigIntRef> New(const EcmaVM *vm, int64_t input); 801 static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words); 802 void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless); 803 void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless); 804 void GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words); 805 uint32_t GetWordsArraySize(); 806 }; 807 808 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 809 class ECMA_PUBLIC_API LocalScope { 810 public: 811 explicit LocalScope(const EcmaVM *vm); 812 virtual ~LocalScope(); 813 814 protected: 815 inline LocalScope(const EcmaVM *vm, JSTaggedType value); 816 817 private: 818 void *prevNext_ = nullptr; 819 void *prevEnd_ = nullptr; 820 int prevHandleStorageIndex_ {-1}; 821 void *thread_ = nullptr; 822 }; 823 824 class ECMA_PUBLIC_API EscapeLocalScope final : public LocalScope { 825 public: 826 explicit EscapeLocalScope(const EcmaVM *vm); 827 ~EscapeLocalScope() override = default; 828 829 ECMA_DISALLOW_COPY(EscapeLocalScope); 830 ECMA_DISALLOW_MOVE(EscapeLocalScope); 831 832 template<typename T> Escape(Local<T> current)833 inline Local<T> Escape(Local<T> current) 834 { 835 ECMA_ASSERT(!alreadyEscape_); 836 alreadyEscape_ = true; 837 *(reinterpret_cast<T *>(escapeHandle_)) = **current; 838 return Local<T>(escapeHandle_); 839 } 840 841 private: 842 bool alreadyEscape_ = false; 843 uintptr_t escapeHandle_ = 0U; 844 }; 845 846 class ECMA_PUBLIC_API IntegerRef : public PrimitiveRef { 847 public: 848 static Local<IntegerRef> New(const EcmaVM *vm, int input); 849 static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input); 850 int Value(); 851 }; 852 853 class ECMA_PUBLIC_API ArrayBufferRef : public ObjectRef { 854 public: 855 static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length); 856 static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter, 857 void *data); 858 859 int32_t ByteLength(const EcmaVM *vm); 860 void *GetBuffer(); 861 862 void Detach(const EcmaVM *vm); 863 bool IsDetach(); 864 }; 865 866 class ECMA_PUBLIC_API DateRef : public ObjectRef { 867 public: 868 static Local<DateRef> New(const EcmaVM *vm, double time); 869 Local<StringRef> ToString(const EcmaVM *vm); 870 double GetTime(); 871 }; 872 873 class ECMA_PUBLIC_API TypedArrayRef : public ObjectRef { 874 public: 875 uint32_t ByteLength(const EcmaVM *vm); 876 uint32_t ByteOffset(const EcmaVM *vm); 877 uint32_t ArrayLength(const EcmaVM *vm); 878 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm); 879 }; 880 881 class ECMA_PUBLIC_API ArrayRef : public ObjectRef { 882 public: 883 static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0); 884 uint32_t Length(const EcmaVM *vm); 885 static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value); 886 static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index); 887 }; 888 889 class ECMA_PUBLIC_API Int8ArrayRef : public TypedArrayRef { 890 public: 891 static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 892 }; 893 894 class ECMA_PUBLIC_API Uint8ArrayRef : public TypedArrayRef { 895 public: 896 static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 897 }; 898 899 class ECMA_PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef { 900 public: 901 static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 902 int32_t length); 903 }; 904 905 class ECMA_PUBLIC_API Int16ArrayRef : public TypedArrayRef { 906 public: 907 static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 908 }; 909 910 class ECMA_PUBLIC_API Uint16ArrayRef : public TypedArrayRef { 911 public: 912 static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 913 int32_t length); 914 }; 915 916 class ECMA_PUBLIC_API Int32ArrayRef : public TypedArrayRef { 917 public: 918 static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 919 }; 920 921 class ECMA_PUBLIC_API Uint32ArrayRef : public TypedArrayRef { 922 public: 923 static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 924 int32_t length); 925 }; 926 927 class ECMA_PUBLIC_API Float32ArrayRef : public TypedArrayRef { 928 public: 929 static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 930 int32_t length); 931 }; 932 933 class ECMA_PUBLIC_API Float64ArrayRef : public TypedArrayRef { 934 public: 935 static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 936 int32_t length); 937 }; 938 939 class ECMA_PUBLIC_API BigInt64ArrayRef : public TypedArrayRef { 940 public: 941 static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 942 int32_t length); 943 }; 944 945 class ECMA_PUBLIC_API BigUint64ArrayRef : public TypedArrayRef { 946 public: 947 static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 948 int32_t length); 949 }; 950 951 class ECMA_PUBLIC_API Exception { 952 public: 953 static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message); 954 static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message); 955 static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message); 956 static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message); 957 static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message); 958 static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message); 959 static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message); 960 static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message); 961 static Local<JSValueRef> TerminationError(const EcmaVM *vm, Local<StringRef> message); 962 }; 963 964 class ECMA_PUBLIC_API FunctionCallScope { 965 public: 966 FunctionCallScope(EcmaVM *vm); 967 ~FunctionCallScope(); 968 969 private: 970 EcmaVM *vm_; 971 }; 972 973 class ECMA_PUBLIC_API JSExecutionScope { 974 public: 975 explicit JSExecutionScope(const EcmaVM *vm); 976 ~JSExecutionScope(); 977 ECMA_DISALLOW_COPY(JSExecutionScope); 978 ECMA_DISALLOW_MOVE(JSExecutionScope); 979 980 private: 981 void *lastCurrentThread_ = nullptr; 982 bool isRevert_ = false; 983 }; 984 985 /** 986 * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data. 987 */ 988 class ECMA_PUBLIC_API JsiRuntimeCallInfo 989 : public ecmascript::base::AlignedStruct<ecmascript::base::AlignedPointer::Size(), 990 ecmascript::base::AlignedPointer, 991 ecmascript::base::AlignedPointer, 992 ecmascript::base::AlignedPointer> { 993 enum class Index : size_t { 994 ThreadIndex = 0, 995 NumArgsIndex, 996 StackArgsIndex, 997 NumOfMembers 998 }; 999 public: 1000 JsiRuntimeCallInfo() = default; 1001 ~JsiRuntimeCallInfo() = default; 1002 GetThread()1003 inline JSThread *GetThread() const 1004 { 1005 return thread_; 1006 } 1007 1008 EcmaVM *GetVM() const; 1009 GetArgsNumber()1010 inline uint32_t GetArgsNumber() const 1011 { 1012 return numArgs_ - FIRST_ARGS_INDEX; 1013 } 1014 1015 void* GetData(); 1016 GetFunctionRef()1017 inline Local<JSValueRef> GetFunctionRef() const 1018 { 1019 return GetArgRef(FUNC_INDEX); 1020 } 1021 GetNewTargetRef()1022 inline Local<JSValueRef> GetNewTargetRef() const 1023 { 1024 return GetArgRef(NEW_TARGET_INDEX); 1025 } 1026 GetThisRef()1027 inline Local<JSValueRef> GetThisRef() const 1028 { 1029 return GetArgRef(THIS_INDEX); 1030 } 1031 GetCallArgRef(uint32_t idx)1032 inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const 1033 { 1034 return GetArgRef(FIRST_ARGS_INDEX + idx); 1035 } 1036 1037 private: 1038 enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX }; 1039 GetArgRef(uint32_t idx)1040 Local<JSValueRef> GetArgRef(uint32_t idx) const 1041 { 1042 return Local<JSValueRef>(GetArgAddress(idx)); 1043 } 1044 GetArgAddress(uint32_t idx)1045 uintptr_t GetArgAddress(uint32_t idx) const 1046 { 1047 if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) { 1048 return reinterpret_cast<uintptr_t>(&stackArgs_[idx]); 1049 } 1050 return 0U; 1051 } 1052 1053 private: 1054 alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr}; 1055 alignas(sizeof(JSTaggedType)) uint32_t numArgs_ = 0; 1056 __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0]; 1057 friend class FunctionRef; 1058 }; 1059 1060 class ECMA_PUBLIC_API MapRef : public ObjectRef { 1061 public: 1062 int32_t GetSize(); 1063 int32_t GetTotalElements(); 1064 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key); 1065 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry); 1066 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1067 static Local<MapRef> New(const EcmaVM *vm); 1068 void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value); 1069 }; 1070 1071 class ECMA_PUBLIC_API BufferRef : public ObjectRef { 1072 public: 1073 static Local<BufferRef> New(const EcmaVM *vm, int32_t length); 1074 static Local<BufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter, 1075 void *data); 1076 1077 int32_t ByteLength(const EcmaVM *vm); 1078 void *GetBuffer(); 1079 static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); 1080 }; 1081 1082 class ECMA_PUBLIC_API PromiseRef : public ObjectRef { 1083 public: 1084 Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler); 1085 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler); 1086 Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler); 1087 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected); 1088 1089 Local<JSValueRef> GetPromiseState(const EcmaVM *vm); 1090 Local<JSValueRef> GetPromiseResult(const EcmaVM *vm); 1091 }; 1092 1093 class ECMA_PUBLIC_API PromiseCapabilityRef : public ObjectRef { 1094 public: 1095 static Local<PromiseCapabilityRef> New(const EcmaVM *vm); 1096 bool Resolve(const EcmaVM *vm, Local<JSValueRef> value); 1097 bool Reject(const EcmaVM *vm, Local<JSValueRef> reason); 1098 Local<PromiseRef> GetPromise(const EcmaVM *vm); 1099 }; 1100 1101 class ECMA_PUBLIC_API NumberRef : public PrimitiveRef { 1102 public: 1103 static Local<NumberRef> New(const EcmaVM *vm, double input); 1104 static Local<NumberRef> New(const EcmaVM *vm, int32_t input); 1105 static Local<NumberRef> New(const EcmaVM *vm, uint32_t input); 1106 static Local<NumberRef> New(const EcmaVM *vm, int64_t input); 1107 1108 double Value(); 1109 }; 1110 1111 class ECMA_PUBLIC_API DataViewRef : public ObjectRef { 1112 public: 1113 static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, 1114 uint32_t byteLength); 1115 uint32_t ByteLength(); 1116 uint32_t ByteOffset(); 1117 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm); 1118 }; 1119 1120 class ECMA_PUBLIC_API MapIteratorRef : public ObjectRef { 1121 public: 1122 int32_t GetIndex(); 1123 Local<JSValueRef> GetKind(const EcmaVM *vm); 1124 static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map); 1125 ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm); 1126 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo); 1127 }; 1128 1129 class ECMA_PUBLIC_API JSNApi { 1130 public: 1131 struct DebugOption { 1132 const char *libraryPath; 1133 bool isDebugMode = false; 1134 int port = -1; 1135 }; 1136 using DebuggerPostTask = std::function<void(std::function<void()>&&)>; 1137 1138 using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>; 1139 1140 struct NativeBindingInfo { CreateNewInstanceNativeBindingInfo1141 static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); } 1142 void *env = nullptr; 1143 void *nativeValue = nullptr; 1144 void *attachFunc = nullptr; 1145 void *attachData = nullptr; 1146 void *detachFunc = nullptr; 1147 void *detachData = nullptr; 1148 void *hint = nullptr; 1149 }; 1150 1151 // JSVM 1152 // fixme: Rename SEMI_GC to YOUNG_GC 1153 enum class ECMA_PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, FULL_GC }; 1154 1155 enum class PatchErrorCode : uint8_t { 1156 SUCCESS = 0, 1157 PATCH_HAS_LOADED, 1158 PATCH_NOT_LOADED, 1159 FILE_NOT_EXECUTED, 1160 FILE_NOT_FOUND, 1161 PACKAGE_NOT_ESMODULE, 1162 MODIFY_IMPORT_EXPORT_NOT_SUPPORT, 1163 INTERNAL_ERROR 1164 }; 1165 1166 static EcmaVM *CreateJSVM(const RuntimeOption &option); 1167 static void DestroyJSVM(EcmaVM *ecmaVm); 1168 static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler); 1169 1170 // aot load 1171 static void LoadAotFile(EcmaVM *vm, const std::string &moduleName); 1172 // context 1173 static EcmaContext *CreateJSContext(EcmaVM *vm); 1174 static void SwitchCurrentContext(EcmaVM *vm, EcmaContext *context); 1175 static void DestroyJSContext(EcmaVM *vm, EcmaContext *context); 1176 1177 // context execute 1178 static bool ExecuteInContext(EcmaVM *vm, const std::string &fileName, const std::string &entry, 1179 bool needUpdate = false); 1180 // JS code 1181 static bool Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false); 1182 static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry, 1183 const std::string &filename = "", bool needUpdate = false); 1184 // merge abc, execute module buffer 1185 static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "", 1186 bool needUpdate = false); 1187 static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file); 1188 static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key); 1189 static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key); 1190 static Local<ObjectRef> ExecuteNativeModule(EcmaVM *vm, const std::string &key); 1191 // secure memory check 1192 static bool CheckSecureMem(uintptr_t mem); 1193 1194 /* 1195 * Execute panda file from secure mem. secure memory lifecycle managed externally. 1196 * The data parameter needs to be created externally by an external caller and managed externally 1197 * by the external caller. The size parameter is the size of the data memory. The entry parameter 1198 * is the name of the entry function. The filename parameter is used to uniquely identify this 1199 * memory internally. 1200 */ 1201 static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry, 1202 const std::string &filename = "", bool needUpdate = false); 1203 /* 1204 * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally. 1205 * The data parameter needs to be created externally by an external caller and managed externally 1206 * by the external caller. The size parameter is the size of the data memory. The filename parameter 1207 * is used to uniquely identify this memory internally. 1208 */ 1209 static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "", 1210 bool needUpdate = false); 1211 1212 // ObjectRef Operation 1213 static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm); 1214 static void ExecutePendingJob(const EcmaVM *vm); 1215 1216 // Memory 1217 // fixme: Rename SEMI_GC to YOUNG_GC 1218 static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC); 1219 // Exception 1220 static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error); 1221 static void PrintExceptionInfo(const EcmaVM *vm); 1222 static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm); 1223 static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm); 1224 static bool IsExecutingPendingJob(const EcmaVM *vm); 1225 static bool HasPendingException(const EcmaVM *vm); 1226 static bool HasPendingJob(const EcmaVM *vm); 1227 static void EnableUserUncaughtErrorHandler(EcmaVM *vm); 1228 // prevewer debugger. 1229 static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1230 const DebuggerPostTask &debuggerPostTask = {}); 1231 // To be compatible with the old process. 1232 static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1233 const DebuggerPostTask &debuggerPostTask = {}); 1234 // socketpair process in ohos platform. 1235 static bool StartDebuggerForSocketPair(int tid, int socketfd = -1); 1236 static bool StopDebugger(int tid); 1237 static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1238 const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false); 1239 static bool StoreDebugInfo( 1240 int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp); 1241 static bool StopDebugger(EcmaVM *vm); 1242 static bool IsMixedDebugEnabled(const EcmaVM *vm); 1243 static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress); 1244 static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress); 1245 static void NotifyLoadModule(const EcmaVM *vm); 1246 static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb); 1247 // Serialize & Deserialize. 1248 static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer, 1249 Local<JSValueRef> cloneList, 1250 bool defaultTransfer = false, 1251 bool defaultCloneShared = true); 1252 static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint); 1253 static void DeleteSerializationData(void *data); 1254 static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data); 1255 static void SetHostResolveBufferTracker(EcmaVM *vm, 1256 std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize)> cb); 1257 static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb); 1258 static void SetNativePtrGetter(EcmaVM *vm, void* cb); 1259 static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb); 1260 static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb); 1261 static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb); 1262 static void InitializeIcuData(const ecmascript::JSRuntimeOptions &options); 1263 static void InitializeMemMapAllocator(); 1264 static void InitializePGOProfiler(const ecmascript::JSRuntimeOptions &options); 1265 static void DestroyAnDataManager(); 1266 static void DestroyMemMapAllocator(); 1267 static void DestroyPGOProfiler(); 1268 static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options); 1269 static void PreFork(EcmaVM *vm); 1270 static void PostFork(EcmaVM *vm, const RuntimeOption &option); 1271 static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm); 1272 static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm); 1273 static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess); 1274 static void GetStackAfterCallNapi(EcmaVM *vm); 1275 1276 static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName); 1277 static PatchErrorCode LoadPatch(EcmaVM *vm, 1278 const std::string &patchFileName, const void *patchBuffer, size_t patchSize, 1279 const std::string &baseFileName, const void *baseBuffer, size_t baseSize); 1280 static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName); 1281 // check whether the exception is caused by quickfix methods. 1282 static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName); 1283 // register quickfix query function. 1284 static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName, 1285 std::string &patchFileName, 1286 void **patchBuffer, 1287 size_t &patchSize)> callBack); 1288 static bool IsBundle(EcmaVM *vm); 1289 static void SetBundle(EcmaVM *vm, bool value); 1290 static void SetAssetPath(EcmaVM *vm, const std::string &assetPath); 1291 static void SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list); 1292 static void SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list); 1293 static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint); 1294 1295 static void SetLoop(EcmaVM *vm, void *loop); 1296 static std::string GetAssetPath(EcmaVM *vm); 1297 static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data); 1298 static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func, void *taskInfo); 1299 static void* GetCurrentTaskInfo(const EcmaVM *vm); 1300 static void SetBundleName(EcmaVM *vm, const std::string &bundleName); 1301 static std::string GetBundleName(EcmaVM *vm); 1302 static void SetModuleName(EcmaVM *vm, const std::string &moduleName); 1303 static std::string GetModuleName(EcmaVM *vm); 1304 static std::pair<std::string, std::string> GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false); 1305 static void AllowCrossThreadExecution(EcmaVM *vm); 1306 static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM); 1307 static bool IsProfiling(EcmaVM *vm); 1308 static void SetProfilerState(const EcmaVM *vm, bool value); 1309 static void SetRequestAotCallback(EcmaVM *vm, const std::function<int32_t(const std::string &bundleName, 1310 const std::string &moduleName, 1311 int32_t triggerMode)> &cb); 1312 static void SetSearchHapPathTracker(EcmaVM *vm, std::function<bool(const std::string moduleName, 1313 std::string &hapPath)> cb); 1314 1315 private: 1316 static int vmCount_; 1317 static bool initialize_; 1318 static bool CreateRuntime(const RuntimeOption &option); 1319 static bool DestroyRuntime(); 1320 1321 static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress); 1322 static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress); 1323 static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress); 1324 static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref, 1325 WeakRefClearCallBack freeGlobalCallBack, 1326 WeakRefClearCallBack nativeFinalizeCallback); 1327 static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress); 1328 static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress); 1329 static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr); 1330 template<typename T> 1331 friend class Global; 1332 template<typename T> 1333 friend class CopyableGlobal; 1334 template<typename T> 1335 friend class Local; 1336 friend class test::JSNApiTests; 1337 }; 1338 1339 class ECMA_PUBLIC_API ProxyRef : public ObjectRef { 1340 public: 1341 Local<JSValueRef> GetHandler(const EcmaVM *vm); 1342 Local<JSValueRef> GetTarget(const EcmaVM *vm); 1343 bool IsRevoked(); 1344 }; 1345 1346 class ECMA_PUBLIC_API WeakMapRef : public ObjectRef { 1347 public: 1348 int32_t GetSize(); 1349 int32_t GetTotalElements(); 1350 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry); 1351 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1352 static Local<WeakMapRef> New(const EcmaVM *vm); 1353 void Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value); 1354 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 1355 }; 1356 1357 class ECMA_PUBLIC_API SetRef : public ObjectRef { 1358 public: 1359 int32_t GetSize(); 1360 int32_t GetTotalElements(); 1361 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1362 static Local<SetRef> New(const EcmaVM *vm); 1363 void Add(const EcmaVM *vm, Local<JSValueRef> value); 1364 }; 1365 1366 class ECMA_PUBLIC_API WeakSetRef : public ObjectRef { 1367 public: 1368 int32_t GetSize(); 1369 int32_t GetTotalElements(); 1370 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1371 static Local<WeakSetRef> New(const EcmaVM *vm); 1372 void Add(const EcmaVM *vm, Local<JSValueRef> value); 1373 }; 1374 1375 class ECMA_PUBLIC_API SetIteratorRef : public ObjectRef { 1376 public: 1377 int32_t GetIndex(); 1378 Local<JSValueRef> GetKind(const EcmaVM *vm); 1379 static Local<SetIteratorRef> New(const EcmaVM *vm, Local<SetRef> set); 1380 ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm); 1381 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); 1382 }; 1383 } 1384 #endif