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 #include "ecmascript/common_enum.h" 33 34 #ifndef NDEBUG 35 #include "libpandabase/utils/debug.h" 36 #endif 37 38 #ifdef ERROR 39 #undef ERROR 40 #endif 41 42 namespace panda { 43 class JSNApiHelper; 44 class EscapeLocalScope; 45 class PromiseRejectInfo; 46 template<typename T> 47 class CopyableGlobal; 48 template<typename T> 49 class Global; 50 class JSNApi; 51 class SymbolRef; 52 template<typename T> 53 class Local; 54 class JSValueRef; 55 class PrimitiveRef; 56 class ArrayRef; 57 class BigIntRef; 58 class StringRef; 59 class ObjectRef; 60 class FunctionRef; 61 class NumberRef; 62 class MapIteratorRef; 63 class SendableMapIteratorRef; 64 class BooleanRef; 65 class NativePointerRef; 66 class JsiRuntimeCallInfo; 67 class RuntimeOption; 68 namespace test { 69 class JSNApiTests; 70 } // namespace test 71 class BufferRef; 72 namespace ecmascript { 73 class EcmaVM; 74 class JSTaggedValue; 75 class EcmaContext; 76 class JSRuntimeOptions; 77 class JSThread; 78 struct EcmaRuntimeCallInfo; 79 namespace base { 80 template<size_t ElementAlign, typename... Ts> 81 struct AlignedStruct; 82 struct AlignedPointer; 83 } 84 namespace job { 85 enum class QueueType : uint8_t { 86 QUEUE_PROMISE, 87 QUEUE_SCRIPT, 88 }; 89 } 90 } // namespace ecmascript 91 92 struct HmsMap { 93 std::string originalPath; 94 std::string targetPath; 95 uint32_t sinceVersion; 96 }; 97 98 using WeakRefClearCallBack = void (*)(void *); 99 using WeakFinalizeTaskCallback = std::function<void()>; 100 using NativePointerCallback = void (*)(void *env, void* data, void* hint); 101 using NativePointerCallbackFinishNotify = std::function<void(size_t totalBindSize_)>; 102 using NativePointerCallbackData = std::pair<NativePointerCallback, std::tuple<void*, void*, void*>>; 103 using TriggerGCData = std::pair<void*, uint8_t>; 104 using TriggerGCTaskCallback = std::function<void(TriggerGCData& data)>; 105 using StartIdleMonitorCallback = std::function<void()>; 106 using EcmaVM = ecmascript::EcmaVM; 107 using EcmaContext = ecmascript::EcmaContext; 108 using JSThread = ecmascript::JSThread; 109 using JSTaggedType = uint64_t; 110 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data); 111 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>; 112 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column)>; 113 using DeviceDisconnectCallback = std::function<bool()>; 114 using QueueType = ecmascript::job::QueueType; 115 116 #define ECMA_DISALLOW_COPY(className) \ 117 className(const className &) = delete; \ 118 className &operator=(const className &) = delete 119 120 #define ECMA_DISALLOW_MOVE(className) \ 121 className(className &&) = delete; \ 122 className &operator=(className &&) = delete 123 124 #ifdef PANDA_TARGET_WINDOWS 125 #define ECMA_PUBLIC_API __declspec(dllexport) 126 #else 127 #define ECMA_PUBLIC_API __attribute__((visibility ("default"))) 128 #endif 129 130 #ifndef NDEBUG 131 #define ECMA_ASSERT(cond) \ 132 if (!(cond)) { \ 133 panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \ 134 } 135 #else 136 #define ECMA_ASSERT(cond) static_cast<void>(0) 137 #endif 138 139 class ECMA_PUBLIC_API AsyncNativeCallbacksPack { 140 public: 141 AsyncNativeCallbacksPack() = default; 142 ~AsyncNativeCallbacksPack() = default; 143 AsyncNativeCallbacksPack(AsyncNativeCallbacksPack&&) = default; 144 AsyncNativeCallbacksPack& operator=(AsyncNativeCallbacksPack&&) = default; 145 AsyncNativeCallbacksPack(const AsyncNativeCallbacksPack &) = default; 146 AsyncNativeCallbacksPack &operator=(const AsyncNativeCallbacksPack &) = default; 147 Clear()148 void Clear() 149 { 150 callBacks_.clear(); 151 totalBindingSize_ = 0; 152 notify_ = nullptr; 153 } 154 TotallyEmpty()155 bool TotallyEmpty() const 156 { 157 return callBacks_.empty() && totalBindingSize_ == 0 && notify_ == nullptr; 158 } 159 Empty()160 bool Empty() const 161 { 162 return callBacks_.empty(); 163 } 164 RegisterFinishNotify(NativePointerCallbackFinishNotify notify)165 void RegisterFinishNotify(NativePointerCallbackFinishNotify notify) 166 { 167 notify_ = notify; 168 } 169 GetNumCallBacks()170 size_t GetNumCallBacks() const 171 { 172 return callBacks_.size(); 173 } 174 ProcessAll()175 void ProcessAll() 176 { 177 for (auto iter : callBacks_) { 178 NativePointerCallback callback = iter.first; 179 std::tuple<void*, void*, void*> ¶m = iter.second; 180 if (callback != nullptr) { 181 callback(std::get<0>(param), std::get<1>(param), std::get<2>(param)); // 2 is the param. 182 } 183 } 184 NotifyFinish(); 185 } 186 GetTotalBindingSize()187 size_t GetTotalBindingSize() const 188 { 189 return totalBindingSize_; 190 } 191 AddCallback(NativePointerCallbackData callback,size_t bindingSize)192 void AddCallback(NativePointerCallbackData callback, size_t bindingSize) 193 { 194 callBacks_.emplace_back(callback); 195 totalBindingSize_ += bindingSize; 196 } 197 private: NotifyFinish()198 void NotifyFinish() const 199 { 200 if (notify_ != nullptr) { 201 notify_(totalBindingSize_); 202 } 203 } 204 205 std::vector<NativePointerCallbackData> callBacks_ {}; 206 size_t totalBindingSize_ {0}; 207 NativePointerCallbackFinishNotify notify_ {nullptr}; 208 }; 209 using NativePointerTaskCallback = std::function<void(AsyncNativeCallbacksPack *callbacksPack)>; 210 211 template<typename T> 212 class ECMA_PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 213 public: 214 inline Local() = default; 215 216 template<typename S> Local(const Local<S> & current)217 inline Local(const Local<S> ¤t) : address_(reinterpret_cast<uintptr_t>(*current)) 218 { 219 // Check 220 } 221 222 Local(const EcmaVM *vm, const Global<T> ¤t); 223 224 Local(const EcmaVM *vm, const CopyableGlobal<T> ¤t); 225 226 ~Local() = default; 227 228 inline T *operator*() const 229 { 230 return GetAddress(); 231 } 232 233 inline T *operator->() const 234 { 235 return GetAddress(); 236 } 237 IsEmpty()238 inline bool IsEmpty() const 239 { 240 return GetAddress() == nullptr; 241 } 242 Empty()243 inline void Empty() 244 { 245 address_ = 0; 246 } 247 IsNull()248 inline bool IsNull() const 249 { 250 return IsEmpty() || GetAddress()->IsHole(); 251 } 252 Local(uintptr_t addr)253 explicit inline Local(uintptr_t addr) : address_(addr) {} 254 255 private: GetAddress()256 inline T *GetAddress() const 257 { 258 return reinterpret_cast<T *>(address_); 259 }; 260 uintptr_t address_ = 0U; 261 friend JSNApiHelper; 262 friend EscapeLocalScope; 263 friend JsiRuntimeCallInfo; 264 }; 265 266 /** 267 * A Copyable global handle, keeps a separate global handle for each CopyableGlobal. 268 * 269 * Support Copy Constructor and Assign, Move Constructor And Assign. 270 * 271 * If destructed, the global handle held will be automatically released. 272 * 273 * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or 274 * a value passing return value and so on. 275 */ 276 template<typename T> 277 class ECMA_PUBLIC_API CopyableGlobal { 278 public: 279 inline CopyableGlobal() = default; ~CopyableGlobal()280 ~CopyableGlobal() 281 { 282 Free(); 283 } 284 CopyableGlobal(const CopyableGlobal & that)285 inline CopyableGlobal(const CopyableGlobal &that) 286 { 287 Copy(that); 288 } 289 290 inline CopyableGlobal &operator=(const CopyableGlobal &that) 291 { 292 Copy(that); 293 return *this; 294 } 295 CopyableGlobal(CopyableGlobal && that)296 inline CopyableGlobal(CopyableGlobal &&that) 297 { 298 Move(that); 299 } 300 301 inline CopyableGlobal &operator=(CopyableGlobal &&that) 302 { 303 Move(that); 304 return *this; 305 } 306 307 template<typename S> 308 CopyableGlobal(const EcmaVM *vm, const Local<S> ¤t); 309 310 CopyableGlobal(const EcmaVM *vm, const Local<T> ¤t); 311 312 template<typename S> CopyableGlobal(const CopyableGlobal<S> & that)313 CopyableGlobal(const CopyableGlobal<S> &that) 314 { 315 Copy(that); 316 } 317 Reset()318 void Reset() 319 { 320 Free(); 321 } 322 ToLocal()323 Local<T> ToLocal() const 324 { 325 if (IsEmpty()) { 326 return Local<T>(); 327 } 328 return Local<T>(vm_, *this); 329 } 330 Empty()331 void Empty() 332 { 333 address_ = 0; 334 } 335 336 inline T *operator*() const 337 { 338 return GetAddress(); 339 } 340 341 inline T *operator->() const 342 { 343 return GetAddress(); 344 } 345 IsEmpty()346 inline bool IsEmpty() const 347 { 348 return GetAddress() == nullptr; 349 } 350 351 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, 352 WeakRefClearCallBack nativeFinalizeCallback); 353 void SetWeak(); 354 355 void ClearWeak(); 356 357 bool IsWeak() const; 358 GetEcmaVM()359 const EcmaVM *GetEcmaVM() const 360 { 361 return vm_; 362 } 363 364 private: GetAddress()365 inline T *GetAddress() const 366 { 367 return reinterpret_cast<T *>(address_); 368 }; 369 inline void Copy(const CopyableGlobal &that); 370 template<typename S> 371 inline void Copy(const CopyableGlobal<S> &that); 372 inline void Move(CopyableGlobal &that); 373 inline void Free(); 374 uintptr_t address_ = 0U; 375 const EcmaVM *vm_ {nullptr}; 376 }; 377 378 template<typename T> 379 class ECMA_PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions 380 public: 381 inline Global() = default; 382 Global(const Global & that)383 inline Global(const Global &that) 384 { 385 Update(that); 386 } 387 388 inline Global &operator=(const Global &that) 389 { 390 Update(that); 391 return *this; 392 } 393 Global(Global && that)394 inline Global(Global &&that) 395 { 396 Update(that); 397 } 398 399 inline Global &operator=(Global &&that) 400 { 401 Update(that); 402 return *this; 403 } 404 405 template<typename S> 406 Global(const EcmaVM *vm, const Local<S> ¤t); 407 template<typename S> 408 Global(const EcmaVM *vm, const Global<S> ¤t); 409 410 ~Global() = default; 411 ToLocal()412 Local<T> ToLocal() const 413 { 414 if (IsEmpty()) { 415 return Local<T>(); 416 } 417 return Local<T>(vm_, *this); 418 } 419 ToLocal(const EcmaVM * vm)420 Local<T> ToLocal(const EcmaVM *vm) const 421 { 422 return Local<T>(vm, *this); 423 } 424 Empty()425 void Empty() 426 { 427 address_ = 0; 428 } 429 430 // This method must be called before Global is released. 431 void FreeGlobalHandleAddr(); 432 433 inline T *operator*() const 434 { 435 return GetAddress(); 436 } 437 438 inline T *operator->() const 439 { 440 return GetAddress(); 441 } 442 IsEmpty()443 inline bool IsEmpty() const 444 { 445 return GetAddress() == nullptr; 446 } 447 448 void SetWeak(); 449 450 void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, 451 WeakRefClearCallBack nativeFinalizeCallback); 452 453 void ClearWeak(); 454 455 bool IsWeak() const; 456 GetEcmaVM()457 const EcmaVM *GetEcmaVM() const 458 { 459 return vm_; 460 } 461 462 private: GetAddress()463 inline T *GetAddress() const 464 { 465 return reinterpret_cast<T *>(address_); 466 }; 467 inline void Update(const Global &that); 468 uintptr_t address_ = 0U; 469 const EcmaVM *vm_ {nullptr}; 470 }; 471 472 class ECMA_PUBLIC_API JSValueRef { 473 public: 474 static Local<PrimitiveRef> Undefined(const EcmaVM *vm); 475 static Local<PrimitiveRef> Null(const EcmaVM *vm); 476 static Local<PrimitiveRef> Hole(const EcmaVM *vm); 477 static Local<PrimitiveRef> True(const EcmaVM *vm); 478 static Local<PrimitiveRef> False(const EcmaVM *vm); 479 480 bool BooleaValue(const EcmaVM *vm); 481 int64_t IntegerValue(const EcmaVM *vm); 482 uint32_t Uint32Value(const EcmaVM *vm); 483 int32_t Int32Value(const EcmaVM *vm); 484 double GetValueDouble(bool &isNumber); 485 int32_t GetValueInt32(bool &isNumber); 486 uint32_t GetValueUint32(bool &isNumber); 487 int64_t GetValueInt64(bool &isNumber); 488 bool GetValueBool(bool &isBool); 489 490 Local<NumberRef> ToNumber(const EcmaVM *vm); 491 Local<BooleanRef> ToBoolean(const EcmaVM *vm); 492 Local<BigIntRef> ToBigInt(const EcmaVM *vm); 493 Local<StringRef> ToString(const EcmaVM *vm); 494 Local<ObjectRef> ToObject(const EcmaVM *vm); 495 Local<ObjectRef> ToEcmaObject(const EcmaVM *vm); 496 Local<NativePointerRef> ToNativePointer(const EcmaVM *vm); 497 498 bool IsUndefined(); 499 bool IsNull(); 500 bool IsHole(); 501 bool IsTrue(); 502 bool IsFalse(); 503 bool IsNumber(); 504 bool IsBigInt(const EcmaVM *vm); 505 bool IsInt(); 506 bool WithinInt32(); 507 bool IsBoolean(); 508 bool IsString(const EcmaVM *vm); 509 bool IsSymbol(const EcmaVM *vm); 510 bool IsObject(const EcmaVM *vm); 511 bool IsArray(const EcmaVM *vm); 512 bool IsJSArray(const EcmaVM *vm); 513 bool IsConstructor(const EcmaVM *vm); 514 bool IsFunction(const EcmaVM *vm); 515 516 bool IsJSFunction(const EcmaVM *vm); 517 bool IsProxy(const EcmaVM *vm); 518 bool IsPromise(const EcmaVM *vm); 519 bool IsDataView(const EcmaVM *vm); 520 bool IsTypedArray(const EcmaVM *vm); 521 bool IsNativePointer(const EcmaVM *vm); 522 bool IsDate(const EcmaVM *vm); 523 bool IsError(const EcmaVM *vm); 524 bool IsMap(const EcmaVM *vm); 525 bool IsSet(const EcmaVM *vm); 526 bool IsWeakRef(const EcmaVM *vm); 527 bool IsWeakMap(const EcmaVM *vm); 528 bool IsWeakSet(const EcmaVM *vm); 529 bool IsRegExp(const EcmaVM *vm); 530 bool IsArrayIterator(const EcmaVM *vm); 531 bool IsStringIterator(const EcmaVM *vm); 532 bool IsSetIterator(const EcmaVM *vm); 533 bool IsMapIterator(const EcmaVM *vm); 534 bool IsArrayBuffer(const EcmaVM *vm); 535 bool IsBuffer(const EcmaVM *vm); 536 bool IsUint8Array(const EcmaVM *vm); 537 bool IsInt8Array(const EcmaVM *vm); 538 bool IsUint8ClampedArray(const EcmaVM *vm); 539 bool IsInt16Array(const EcmaVM *vm); 540 bool IsUint16Array(const EcmaVM *vm); 541 bool IsInt32Array(const EcmaVM *vm); 542 bool IsUint32Array(const EcmaVM *vm); 543 bool IsFloat32Array(const EcmaVM *vm); 544 bool IsFloat64Array(const EcmaVM *vm); 545 bool IsBigInt64Array(const EcmaVM *vm); 546 bool IsBigUint64Array(const EcmaVM *vm); 547 bool IsJSPrimitiveRef(const EcmaVM *vm); 548 bool IsJSPrimitiveNumber(const EcmaVM *vm); 549 bool IsJSPrimitiveInt(const EcmaVM *vm); 550 bool IsJSPrimitiveBoolean(const EcmaVM *vm); 551 bool IsJSPrimitiveString(const EcmaVM *vm); 552 553 bool IsJSSharedInt8Array(const EcmaVM *vm); 554 bool IsJSSharedUint8Array(const EcmaVM *vm); 555 bool IsJSSharedUint8ClampedArray(const EcmaVM *vm); 556 bool IsJSSharedInt16Array(const EcmaVM *vm); 557 bool IsJSSharedUint16Array(const EcmaVM *vm); 558 bool IsJSSharedInt32Array(const EcmaVM *vm); 559 bool IsJSSharedUint32Array(const EcmaVM *vm); 560 bool IsJSSharedFloat32Array(const EcmaVM *vm); 561 562 bool IsGeneratorObject(const EcmaVM *vm); 563 bool IsJSPrimitiveSymbol(const EcmaVM *vm); 564 565 bool IsArgumentsObject(const EcmaVM *vm); 566 bool IsGeneratorFunction(const EcmaVM *vm); 567 bool IsAsyncFunction(const EcmaVM *vm); 568 bool IsConcurrentFunction(const EcmaVM *vm); 569 bool IsJSLocale(const EcmaVM *vm); 570 bool IsJSDateTimeFormat(const EcmaVM *vm); 571 bool IsJSRelativeTimeFormat(const EcmaVM *vm); 572 bool IsJSIntl(const EcmaVM *vm); 573 bool IsJSNumberFormat(const EcmaVM *vm); 574 bool IsJSCollator(const EcmaVM *vm); 575 bool IsJSPluralRules(const EcmaVM *vm); 576 bool IsJSListFormat(const EcmaVM *vm); 577 bool IsAsyncGeneratorFunction(const EcmaVM *vm); 578 bool IsAsyncGeneratorObject(const EcmaVM *vm); 579 580 bool IsModuleNamespaceObject(const EcmaVM *vm); 581 bool IsNativeModuleFailureInfoObject(const EcmaVM *vm); 582 bool IsSharedArrayBuffer(const EcmaVM *vm); 583 bool IsSendableArrayBuffer(const EcmaVM *vm); 584 585 bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value); 586 Local<StringRef> Typeof(const EcmaVM *vm); 587 bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value); 588 589 bool IsArrayList(const EcmaVM *vm); 590 bool IsDeque(const EcmaVM *vm); 591 bool IsHashMap(const EcmaVM *vm); 592 bool IsHashSet(const EcmaVM *vm); 593 bool IsLightWeightMap(const EcmaVM *vm); 594 bool IsLightWeightSet(const EcmaVM *vm); 595 bool IsLinkedList(const EcmaVM *vm); 596 bool IsLinkedListIterator(const EcmaVM *vm); 597 bool IsList(const EcmaVM *vm); 598 bool IsPlainArray(const EcmaVM *vm); 599 bool IsQueue(const EcmaVM *vm); 600 bool IsStack(const EcmaVM *vm); 601 bool IsTreeMap(const EcmaVM *vm); 602 bool IsTreeSet(const EcmaVM *vm); 603 bool IsVector(const EcmaVM *vm); 604 bool IsBitVector(const EcmaVM *vm); 605 bool IsSendableObject(const EcmaVM *vm); 606 bool IsJSShared(const EcmaVM *vm); 607 bool IsSharedArray(const EcmaVM *vm); 608 bool IsSharedTypedArray(const EcmaVM *vm); 609 bool IsSharedSet(const EcmaVM *vm); 610 bool IsSharedMap(const EcmaVM *vm); 611 bool IsSharedMapIterator(const EcmaVM *vm); 612 bool IsHeapObject(); 613 void *GetNativePointerValue(const EcmaVM *vm, bool &isNativePointer); 614 bool IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer); 615 void DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer); 616 void GetDataViewInfo(const EcmaVM *vm, 617 bool &isDataView, 618 size_t *byteLength, 619 void **data, 620 JSValueRef **arrayBuffer, 621 size_t *byteOffset); 622 623 private: 624 JSTaggedType value_; 625 friend JSNApi; 626 template<typename T> 627 friend class Global; 628 template<typename T> 629 friend class Local; 630 void *GetNativePointerValueImpl(const EcmaVM *vm, bool &isNativePointer); 631 }; 632 633 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 634 class ECMA_PUBLIC_API PropertyAttribute { 635 public: Default()636 static PropertyAttribute Default() 637 { 638 return PropertyAttribute(); 639 } 640 PropertyAttribute() = default; PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)641 PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c) 642 : value_(value), 643 writable_(w), 644 enumerable_(e), 645 configurable_(c), 646 hasWritable_(true), 647 hasEnumerable_(true), 648 hasConfigurable_(true) 649 {} 650 ~PropertyAttribute() = default; 651 IsWritable()652 bool IsWritable() const 653 { 654 return writable_; 655 } SetWritable(bool flag)656 void SetWritable(bool flag) 657 { 658 writable_ = flag; 659 hasWritable_ = true; 660 } IsEnumerable()661 bool IsEnumerable() const 662 { 663 return enumerable_; 664 } SetEnumerable(bool flag)665 void SetEnumerable(bool flag) 666 { 667 enumerable_ = flag; 668 hasEnumerable_ = true; 669 } IsConfigurable()670 bool IsConfigurable() const 671 { 672 return configurable_; 673 } SetConfigurable(bool flag)674 void SetConfigurable(bool flag) 675 { 676 configurable_ = flag; 677 hasConfigurable_ = true; 678 } HasWritable()679 bool HasWritable() const 680 { 681 return hasWritable_; 682 } HasConfigurable()683 bool HasConfigurable() const 684 { 685 return hasConfigurable_; 686 } HasEnumerable()687 bool HasEnumerable() const 688 { 689 return hasEnumerable_; 690 } GetValue(const EcmaVM * vm)691 Local<JSValueRef> GetValue(const EcmaVM *vm) const 692 { 693 if (value_.IsEmpty()) { 694 return JSValueRef::Undefined(vm); 695 } 696 return value_; 697 } SetValue(Local<JSValueRef> value)698 void SetValue(Local<JSValueRef> value) 699 { 700 value_ = value; 701 } HasValue()702 inline bool HasValue() const 703 { 704 return !value_.IsEmpty(); 705 } GetGetter(const EcmaVM * vm)706 Local<JSValueRef> GetGetter(const EcmaVM *vm) const 707 { 708 if (getter_.IsEmpty()) { 709 return JSValueRef::Undefined(vm); 710 } 711 return getter_; 712 } SetGetter(Local<JSValueRef> value)713 void SetGetter(Local<JSValueRef> value) 714 { 715 getter_ = value; 716 } HasGetter()717 bool HasGetter() const 718 { 719 return !getter_.IsEmpty(); 720 } GetSetter(const EcmaVM * vm)721 Local<JSValueRef> GetSetter(const EcmaVM *vm) const 722 { 723 if (setter_.IsEmpty()) { 724 return JSValueRef::Undefined(vm); 725 } 726 return setter_; 727 } SetSetter(Local<JSValueRef> value)728 void SetSetter(Local<JSValueRef> value) 729 { 730 setter_ = value; 731 } HasSetter()732 bool HasSetter() const 733 { 734 return !setter_.IsEmpty(); 735 } 736 737 private: 738 Local<JSValueRef> value_; 739 Local<JSValueRef> getter_; 740 Local<JSValueRef> setter_; 741 bool writable_ = false; 742 bool enumerable_ = false; 743 bool configurable_ = false; 744 bool hasWritable_ = false; 745 bool hasEnumerable_ = false; 746 bool hasConfigurable_ = false; 747 }; 748 749 class ECMA_PUBLIC_API NativePointerRef : public JSValueRef { 750 public: 751 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0); 752 static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, 753 void *data, size_t nativeBindingsize = 0); 754 static Local<NativePointerRef> NewConcurrent(const EcmaVM *vm, void *nativePointer, 755 NativePointerCallback callBack, 756 void *data, size_t nativeBindingsize = 0); 757 static Local<NativePointerRef> NewSendable(const EcmaVM *vm, 758 void *nativePointer, 759 NativePointerCallback callBack = nullptr, 760 void *data = nullptr, 761 size_t nativeBindingsize = 0); 762 void *Value(); 763 }; 764 765 class ECMA_PUBLIC_API ObjectRef : public JSValueRef { 766 public: 767 enum class SendableType { 768 NONE, 769 OBJECT, 770 GENERIC, 771 }; 772 struct SendablePropertiesInfo { 773 std::vector<Local<JSValueRef>> keys; 774 std::vector<SendableType> types; 775 std::vector<PropertyAttribute> attributes; 776 }; 777 static constexpr int MAX_PROPERTIES_ON_STACK = 32; Cast(JSValueRef * value)778 static inline ObjectRef *Cast(JSValueRef *value) 779 { 780 return static_cast<ObjectRef *>(value); 781 } 782 static Local<ObjectRef> New(const EcmaVM *vm); 783 static uintptr_t NewObject(const EcmaVM *vm); 784 static Local<ObjectRef> NewS(const EcmaVM *vm); 785 static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys, 786 const PropertyAttribute *attributes); 787 static Local<ObjectRef> NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info); 788 static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys, 789 const Local<JSValueRef> *values); 790 static Local<ObjectRef> CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo); 791 static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter); 792 static Local<ObjectRef> CreateSendableAccessorData(const EcmaVM *vm, 793 Local<FunctionRef> getter, 794 Local<FunctionRef> setter); 795 bool ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value); 796 bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value); 797 bool Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value); 798 bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value); 799 bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter, 800 Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default()); 801 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key); 802 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8); 803 Local<JSValueRef> Get(const EcmaVM *vm, int32_t key); 804 805 bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property); 806 Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm); 807 Local<ArrayRef> GetAllPropertyNames(const EcmaVM *vm, uint32_t filter); 808 Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm); 809 Local<JSValueRef> GetPrototype(const EcmaVM *vm); 810 bool SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype); 811 812 bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute); 813 814 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 815 bool Has(const EcmaVM *vm, uint32_t key); 816 817 bool HasOwnProperty(const EcmaVM *vm, Local<JSValueRef> key); 818 819 bool Delete(const EcmaVM *vm, Local<JSValueRef> key); 820 bool Delete(const EcmaVM *vm, uint32_t key); 821 822 Local<JSValueRef> Freeze(const EcmaVM *vm); 823 Local<JSValueRef> Seal(const EcmaVM *vm); 824 825 void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count); 826 int32_t GetNativePointerFieldCount(const EcmaVM *vm); 827 void *GetNativePointerField(const EcmaVM *vm, int32_t index); 828 void SetNativePointerField(const EcmaVM *vm, 829 int32_t index, 830 void *nativePointer = nullptr, 831 NativePointerCallback callBack = nullptr, 832 void *data = nullptr, size_t nativeBindingsize = 0); 833 void SetConcurrentNativePointerField(const EcmaVM *vm, 834 int32_t index, 835 void *nativePointer = nullptr, 836 NativePointerCallback callBack = nullptr, 837 void *data = nullptr, size_t nativeBindingsize = 0); 838 }; 839 840 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*); 841 using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*); 842 class ECMA_PUBLIC_API FunctionRef : public ObjectRef { 843 public: 844 struct SendablePropertiesInfos { 845 SendablePropertiesInfo instancePropertiesInfo; 846 SendablePropertiesInfo staticPropertiesInfo; 847 SendablePropertiesInfo nonStaticPropertiesInfo; 848 }; 849 static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter = nullptr, 850 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); 851 static Local<FunctionRef> NewConcurrent(EcmaVM *vm, 852 FunctionCallback nativeFunc, 853 NativePointerCallback deleter = nullptr, 854 void *data = nullptr, 855 bool callNapi = false, 856 size_t nativeBindingsize = 0); 857 static Local<FunctionRef> New(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, 858 void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); 859 static Local<FunctionRef> NewConcurrent(EcmaVM *vm, 860 InternalFunctionCallback nativeFunc, 861 NativePointerCallback deleter, 862 void *data = nullptr, 863 bool callNapi = false, 864 size_t nativeBindingsize = 0); 865 static Local<FunctionRef> NewSendable(EcmaVM *vm, 866 InternalFunctionCallback nativeFunc, 867 NativePointerCallback deleter, 868 void *data = nullptr, 869 bool callNapi = false, 870 size_t nativeBindingsize = 0); 871 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter, 872 void *data, bool callNapi = false, size_t nativeBindingsize = 0); 873 static Local<FunctionRef> NewConcurrentClassFunction(EcmaVM *vm, 874 InternalFunctionCallback nativeFunc, 875 NativePointerCallback deleter, 876 void *data, 877 bool callNapi = false, 878 size_t nativeBindingsize = 0); 879 static Local<FunctionRef> NewClassFunction(EcmaVM *vm, 880 InternalFunctionCallback nativeFunc, 881 NativePointerCallback deleter, 882 void *data, 883 bool callNapi = false, 884 size_t nativeBindingsize = 0); 885 static Local<FunctionRef> NewSendableClassFunction(const EcmaVM *vm, 886 InternalFunctionCallback nativeFunc, 887 NativePointerCallback deleter, 888 void *data, 889 Local<StringRef> name, 890 SendablePropertiesInfos &infos, 891 Local<FunctionRef> parent, 892 bool callNapi = false, 893 size_t nativeBindingsize = 0); 894 JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[], 895 int32_t length); 896 Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[], 897 int32_t length); 898 Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length); 899 JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length); 900 901 Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm); 902 bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent); 903 void SetName(const EcmaVM *vm, Local<StringRef> name); 904 Local<StringRef> GetName(const EcmaVM *vm); 905 Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber); 906 bool IsNative(const EcmaVM *vm); 907 void SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter = nullptr, bool callNapi = false); 908 void* GetData(const EcmaVM *vm); 909 }; 910 911 class ECMA_PUBLIC_API PrimitiveRef : public JSValueRef { 912 public: 913 Local<JSValueRef> GetValue(const EcmaVM *vm); 914 }; 915 916 class ECMA_PUBLIC_API SymbolRef : public PrimitiveRef { 917 public: 918 static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description = Local<StringRef>()); 919 Local<StringRef> GetDescription(const EcmaVM *vm); 920 }; 921 922 class ECMA_PUBLIC_API BooleanRef : public PrimitiveRef { 923 public: 924 static Local<BooleanRef> New(const EcmaVM *vm, bool input); 925 bool Value(); 926 }; 927 928 class ECMA_PUBLIC_API StringRef : public PrimitiveRef { 929 public: Cast(JSValueRef * value)930 static inline StringRef *Cast(JSValueRef *value) 931 { 932 // check 933 return static_cast<StringRef *>(value); 934 } 935 static Local<StringRef> NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length = -1); 936 static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1); 937 static Local<StringRef> NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length = -1); 938 static Local<StringRef> NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1); 939 std::string ToString(const EcmaVM *vm); 940 std::string DebuggerToString(const EcmaVM *vm); 941 uint32_t Length(const EcmaVM *vm); 942 int32_t Utf8Length(const EcmaVM *vm, bool isGetBufferSize = false); 943 int WriteUtf8(const EcmaVM *vm, char *buffer, int length, bool isWriteBuffer = false); 944 int WriteUtf16(const EcmaVM *vm, char16_t *buffer, int length); 945 int WriteLatin1(const EcmaVM *vm, char *buffer, int length); 946 static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm); 947 }; 948 949 class ECMA_PUBLIC_API PromiseRejectInfo { 950 public: 951 enum class ECMA_PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE }; 952 PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason, 953 PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data); ~PromiseRejectInfo()954 ~PromiseRejectInfo() {} 955 Local<JSValueRef> GetPromise() const; 956 Local<JSValueRef> GetReason() const; 957 PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const; 958 void* GetData() const; 959 960 private: 961 Local<JSValueRef> promise_ {}; 962 Local<JSValueRef> reason_ {}; 963 PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT; 964 void* data_ {nullptr}; 965 }; 966 967 /** 968 * An external exception handler. 969 */ 970 class ECMA_PUBLIC_API TryCatch { 971 public: TryCatch(const EcmaVM * ecmaVm)972 explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {}; 973 974 /** 975 * Consumes the exception by default if not rethrow explicitly. 976 */ 977 ~TryCatch(); 978 979 bool HasCaught() const; 980 void Rethrow(); 981 Local<ObjectRef> GetAndClearException(); 982 Local<ObjectRef> GetException(); 983 void ClearException(); 984 985 ECMA_DISALLOW_COPY(TryCatch); 986 ECMA_DISALLOW_MOVE(TryCatch); 987 getrethrow_()988 bool getrethrow_() 989 { 990 return rethrow_; 991 } 992 993 private: 994 // Disable dynamic allocation 995 void* operator new(size_t size) = delete; 996 void operator delete(void*, size_t) = delete; 997 void* operator new[](size_t size) = delete; 998 void operator delete[](void*, size_t) = delete; 999 1000 const EcmaVM *ecmaVm_ {nullptr}; 1001 bool rethrow_ {false}; 1002 }; 1003 1004 class ECMA_PUBLIC_API BigIntRef : public PrimitiveRef { 1005 public: 1006 static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input); 1007 static Local<BigIntRef> New(const EcmaVM *vm, int64_t input); 1008 static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words); 1009 void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless); 1010 void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless); 1011 void GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words); 1012 uint32_t GetWordsArraySize(const EcmaVM *vm); 1013 }; 1014 1015 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) 1016 class ECMA_PUBLIC_API LocalScope { 1017 public: 1018 explicit LocalScope(const EcmaVM *vm); 1019 virtual ~LocalScope(); 1020 1021 protected: 1022 inline LocalScope(const EcmaVM *vm, JSTaggedType value); 1023 1024 private: 1025 void *prevNext_ = nullptr; 1026 void *prevEnd_ = nullptr; 1027 int prevHandleStorageIndex_ {-1}; 1028 void *prevPrimitiveNext_ = nullptr; 1029 void *prevPrimitiveEnd_ = nullptr; 1030 int prevPrimitiveStorageIndex_ {-1}; 1031 void *thread_ = nullptr; 1032 }; 1033 1034 class ECMA_PUBLIC_API EscapeLocalScope final : public LocalScope { 1035 public: 1036 explicit EscapeLocalScope(const EcmaVM *vm); 1037 ~EscapeLocalScope() override = default; 1038 1039 ECMA_DISALLOW_COPY(EscapeLocalScope); 1040 ECMA_DISALLOW_MOVE(EscapeLocalScope); 1041 1042 template<typename T> Escape(Local<T> current)1043 inline Local<T> Escape(Local<T> current) 1044 { 1045 ECMA_ASSERT(!alreadyEscape_); 1046 alreadyEscape_ = true; 1047 *(reinterpret_cast<T *>(escapeHandle_)) = **current; 1048 return Local<T>(escapeHandle_); 1049 } 1050 1051 private: 1052 bool alreadyEscape_ = false; 1053 uintptr_t escapeHandle_ = 0U; 1054 }; 1055 1056 class ECMA_PUBLIC_API IntegerRef : public PrimitiveRef { 1057 public: 1058 static Local<IntegerRef> New(const EcmaVM *vm, int input); 1059 static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input); 1060 int Value(); 1061 }; 1062 1063 class ECMA_PUBLIC_API ArrayBufferRef : public ObjectRef { 1064 public: 1065 static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length); 1066 static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, 1067 const NativePointerCallback &deleter, void *data); 1068 1069 int32_t ByteLength(const EcmaVM *vm); 1070 void *GetBuffer(const EcmaVM *vm); 1071 1072 void Detach(const EcmaVM *vm); 1073 bool IsDetach(const EcmaVM *vm); 1074 }; 1075 1076 class ECMA_PUBLIC_API SendableArrayBufferRef : public ObjectRef { 1077 public: 1078 static Local<SendableArrayBufferRef> New(const EcmaVM *vm, int32_t length); 1079 static Local<SendableArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, 1080 const NativePointerCallback &deleter, void *data); 1081 1082 int32_t ByteLength(const EcmaVM *vm); 1083 void *GetBuffer(const EcmaVM *vm); 1084 1085 void Detach(const EcmaVM *vm); 1086 bool IsDetach(const EcmaVM *vm); 1087 }; 1088 1089 class ECMA_PUBLIC_API DateRef : public ObjectRef { 1090 public: 1091 static Local<DateRef> New(const EcmaVM *vm, double time); 1092 Local<StringRef> ToString(const EcmaVM *vm); 1093 double GetTime(const EcmaVM *vm); 1094 }; 1095 1096 class ECMA_PUBLIC_API TypedArrayRef : public ObjectRef { 1097 public: 1098 uint32_t ByteLength(const EcmaVM *vm); 1099 uint32_t ByteOffset(const EcmaVM *vm); 1100 uint32_t ArrayLength(const EcmaVM *vm); 1101 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm); 1102 }; 1103 1104 class ECMA_PUBLIC_API SendableTypedArrayRef : public ObjectRef { 1105 public: 1106 uint32_t ByteLength(const EcmaVM *vm); 1107 uint32_t ByteOffset(const EcmaVM *vm); 1108 uint32_t ArrayLength(const EcmaVM *vm); 1109 Local<SendableArrayBufferRef> GetArrayBuffer(const EcmaVM *vm); 1110 }; 1111 1112 class ECMA_PUBLIC_API ArrayRef : public ObjectRef { 1113 public: 1114 static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0); 1115 uint32_t Length(const EcmaVM *vm); 1116 static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value); 1117 static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index); 1118 }; 1119 1120 class ECMA_PUBLIC_API SendableArrayRef : public ObjectRef { 1121 public: 1122 static Local<SendableArrayRef> New(const EcmaVM *vm, uint32_t length = 0); 1123 uint32_t Length(const EcmaVM *vm); 1124 static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index); 1125 static bool SetProperty(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value); 1126 }; 1127 1128 class ECMA_PUBLIC_API Int8ArrayRef : public TypedArrayRef { 1129 public: 1130 static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 1131 }; 1132 1133 class ECMA_PUBLIC_API SharedInt8ArrayRef : public SendableTypedArrayRef { 1134 public: 1135 static Local<SharedInt8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1136 int32_t byteOffset, int32_t length); 1137 }; 1138 1139 class ECMA_PUBLIC_API Uint8ArrayRef : public TypedArrayRef { 1140 public: 1141 static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 1142 }; 1143 1144 class ECMA_PUBLIC_API SharedUint8ArrayRef : public SendableTypedArrayRef { 1145 public: 1146 static Local<SharedUint8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1147 int32_t byteOffset, int32_t length); 1148 }; 1149 1150 class ECMA_PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef { 1151 public: 1152 static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1153 int32_t length); 1154 }; 1155 1156 class ECMA_PUBLIC_API Int16ArrayRef : public TypedArrayRef { 1157 public: 1158 static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 1159 }; 1160 1161 class ECMA_PUBLIC_API SharedInt16ArrayRef : public SendableTypedArrayRef { 1162 public: 1163 static Local<SharedInt16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1164 int32_t byteOffset, int32_t length); 1165 }; 1166 1167 class ECMA_PUBLIC_API Uint16ArrayRef : public TypedArrayRef { 1168 public: 1169 static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1170 int32_t length); 1171 }; 1172 1173 class ECMA_PUBLIC_API SharedUint16ArrayRef : public SendableTypedArrayRef { 1174 public: 1175 static Local<SharedUint16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1176 int32_t byteOffset, int32_t length); 1177 }; 1178 1179 class ECMA_PUBLIC_API Int32ArrayRef : public TypedArrayRef { 1180 public: 1181 static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length); 1182 }; 1183 1184 class ECMA_PUBLIC_API SharedInt32ArrayRef : public SendableTypedArrayRef { 1185 public: 1186 static Local<SharedInt32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1187 int32_t byteOffset, int32_t length); 1188 }; 1189 1190 class ECMA_PUBLIC_API SharedFloat32ArrayRef : public SendableTypedArrayRef { 1191 public: 1192 static Local<SharedFloat32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1193 int32_t byteOffset, int32_t length); 1194 }; 1195 1196 class ECMA_PUBLIC_API SharedUint8ClampedArrayRef : public SendableTypedArrayRef { 1197 public: 1198 static Local<SharedUint8ClampedArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1199 int32_t byteOffset, int32_t length); 1200 }; 1201 1202 class ECMA_PUBLIC_API Uint32ArrayRef : public TypedArrayRef { 1203 public: 1204 static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1205 int32_t length); 1206 }; 1207 1208 class ECMA_PUBLIC_API SharedUint32ArrayRef : public SendableTypedArrayRef { 1209 public: 1210 static Local<SharedUint32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, 1211 int32_t byteOffset, int32_t length); 1212 }; 1213 1214 class ECMA_PUBLIC_API Float32ArrayRef : public TypedArrayRef { 1215 public: 1216 static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1217 int32_t length); 1218 }; 1219 1220 class ECMA_PUBLIC_API Float64ArrayRef : public TypedArrayRef { 1221 public: 1222 static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1223 int32_t length); 1224 }; 1225 1226 class ECMA_PUBLIC_API BigInt64ArrayRef : public TypedArrayRef { 1227 public: 1228 static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1229 int32_t length); 1230 }; 1231 1232 class ECMA_PUBLIC_API BigUint64ArrayRef : public TypedArrayRef { 1233 public: 1234 static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, 1235 int32_t length); 1236 }; 1237 1238 class ECMA_PUBLIC_API Exception { 1239 public: 1240 static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message); 1241 static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message); 1242 static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message); 1243 static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message); 1244 static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message); 1245 static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message); 1246 static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message); 1247 static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message); 1248 static Local<JSValueRef> TerminationError(const EcmaVM *vm, Local<StringRef> message); 1249 }; 1250 1251 class ECMA_PUBLIC_API FunctionCallScope { 1252 public: 1253 FunctionCallScope(EcmaVM *vm); 1254 ~FunctionCallScope(); 1255 1256 private: 1257 EcmaVM *vm_; 1258 }; 1259 1260 class ECMA_PUBLIC_API JSExecutionScope { 1261 public: 1262 explicit JSExecutionScope(const EcmaVM *vm); 1263 ~JSExecutionScope(); 1264 ECMA_DISALLOW_COPY(JSExecutionScope); 1265 ECMA_DISALLOW_MOVE(JSExecutionScope); 1266 1267 private: 1268 void *lastCurrentThread_ = nullptr; 1269 bool isRevert_ = false; 1270 }; 1271 1272 class ECMA_PUBLIC_API JsiNativeScope { 1273 public: 1274 explicit JsiNativeScope(const EcmaVM *vm); 1275 ~JsiNativeScope(); 1276 ECMA_DISALLOW_COPY(JsiNativeScope); 1277 ECMA_DISALLOW_MOVE(JsiNativeScope); 1278 1279 private: 1280 JSThread *thread_; 1281 uint16_t oldThreadState_; 1282 }; 1283 1284 class ECMA_PUBLIC_API JsiFastNativeScope { 1285 public: 1286 explicit JsiFastNativeScope(const EcmaVM *vm); 1287 ~JsiFastNativeScope(); 1288 ECMA_DISALLOW_COPY(JsiFastNativeScope); 1289 ECMA_DISALLOW_MOVE(JsiFastNativeScope); 1290 1291 private: 1292 JSThread *thread_ {nullptr}; 1293 uint16_t oldThreadState_ {0}; 1294 bool hasSwitchState_ {false}; 1295 }; 1296 1297 /** 1298 * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data. 1299 */ 1300 class ECMA_PUBLIC_API JsiRuntimeCallInfo 1301 : public ecmascript::base::AlignedStruct<ecmascript::base::AlignedPointer::Size(), 1302 ecmascript::base::AlignedPointer, 1303 ecmascript::base::AlignedPointer, 1304 ecmascript::base::AlignedPointer> { 1305 enum class Index : size_t { 1306 ThreadIndex = 0, 1307 NumArgsIndex, 1308 StackArgsIndex, 1309 NumOfMembers 1310 }; 1311 public: 1312 JsiRuntimeCallInfo() = default; 1313 ~JsiRuntimeCallInfo() = default; 1314 GetThread()1315 inline JSThread *GetThread() const 1316 { 1317 return thread_; 1318 } 1319 1320 EcmaVM *GetVM() const; 1321 GetArgsNumber()1322 inline uint32_t GetArgsNumber() const 1323 { 1324 ECMA_ASSERT(numArgs_ >= FIRST_ARGS_INDEX); 1325 return numArgs_ - FIRST_ARGS_INDEX; 1326 } 1327 1328 void* GetData(); 1329 GetFunctionRef()1330 inline Local<JSValueRef> GetFunctionRef() const 1331 { 1332 return GetArgRef(FUNC_INDEX); 1333 } 1334 GetNewTargetRef()1335 inline Local<JSValueRef> GetNewTargetRef() const 1336 { 1337 return GetArgRef(NEW_TARGET_INDEX); 1338 } 1339 GetThisRef()1340 inline Local<JSValueRef> GetThisRef() const 1341 { 1342 return GetArgRef(THIS_INDEX); 1343 } 1344 GetCallArgRef(uint32_t idx)1345 inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const 1346 { 1347 return GetArgRef(FIRST_ARGS_INDEX + idx); 1348 } 1349 1350 private: 1351 enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX }; 1352 GetArgRef(uint32_t idx)1353 Local<JSValueRef> GetArgRef(uint32_t idx) const 1354 { 1355 return Local<JSValueRef>(GetArgAddress(idx)); 1356 } 1357 GetArgAddress(uint32_t idx)1358 uintptr_t GetArgAddress(uint32_t idx) const 1359 { 1360 if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) { 1361 return reinterpret_cast<uintptr_t>(&stackArgs_[idx]); 1362 } 1363 return 0U; 1364 } 1365 1366 private: 1367 alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr}; 1368 alignas(sizeof(JSTaggedType)) uint32_t numArgs_ = 0; 1369 __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0]; 1370 friend class FunctionRef; 1371 }; 1372 1373 class ECMA_PUBLIC_API MapRef : public ObjectRef { 1374 public: 1375 int32_t GetSize(const EcmaVM *vm); 1376 int32_t GetTotalElements(const EcmaVM *vm); 1377 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key); 1378 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8); 1379 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry); 1380 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1381 static Local<MapRef> New(const EcmaVM *vm); 1382 void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value); 1383 void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value); 1384 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 1385 bool Has(const EcmaVM *vm, const char *utf8); 1386 void Delete(const EcmaVM *vm, Local<JSValueRef> key); 1387 void Clear(const EcmaVM *vm); 1388 Local<MapIteratorRef> GetEntries(const EcmaVM *vm); 1389 Local<MapIteratorRef> GetKeys(const EcmaVM *vm); 1390 Local<MapIteratorRef> GetValues(const EcmaVM *vm); 1391 }; 1392 1393 class ECMA_PUBLIC_API SendableMapRef : public ObjectRef { 1394 public: 1395 static Local<SendableMapRef> New(const EcmaVM *vm); 1396 uint32_t GetSize(const EcmaVM *vm); 1397 uint32_t GetTotalElements(const EcmaVM *vm); 1398 Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key); 1399 Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8); 1400 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry); 1401 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1402 void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value); 1403 void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value); 1404 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 1405 bool Has(const EcmaVM *vm, const char *utf8); 1406 void Delete(const EcmaVM *vm, Local<JSValueRef> key); 1407 void Clear(const EcmaVM *vm); 1408 Local<SendableMapIteratorRef> GetEntries(const EcmaVM *vm); 1409 Local<SendableMapIteratorRef> GetKeys(const EcmaVM *vm); 1410 Local<SendableMapIteratorRef> GetValues(const EcmaVM *vm); 1411 }; 1412 1413 class ECMA_PUBLIC_API SendableSetRef : public ObjectRef { 1414 public: 1415 static Local<SendableSetRef> New(const EcmaVM *vm); 1416 uint32_t GetSize(const EcmaVM *vm); 1417 uint32_t GetTotalElements(const EcmaVM *vm); 1418 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1419 void Add(const EcmaVM *vm, Local<JSValueRef> value); 1420 }; 1421 1422 class ECMA_PUBLIC_API BufferRef : public ObjectRef { 1423 public: 1424 static Local<BufferRef> New(const EcmaVM *vm, int32_t length); 1425 static Local<BufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, 1426 void *data); 1427 1428 int32_t ByteLength(const EcmaVM *vm); 1429 void *GetBuffer(const EcmaVM *vm); 1430 static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); 1431 }; 1432 1433 class ECMA_PUBLIC_API PromiseRef : public ObjectRef { 1434 public: 1435 Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler); 1436 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler); 1437 Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler); 1438 Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected); 1439 1440 Local<JSValueRef> GetPromiseState(const EcmaVM *vm); 1441 Local<JSValueRef> GetPromiseResult(const EcmaVM *vm); 1442 }; 1443 1444 class ECMA_PUBLIC_API PromiseCapabilityRef : public ObjectRef { 1445 public: 1446 static Local<PromiseCapabilityRef> New(const EcmaVM *vm); 1447 bool Resolve(const EcmaVM *vm, uintptr_t value); 1448 bool Resolve(const EcmaVM *vm, Local<JSValueRef> value); 1449 bool Reject(const EcmaVM *vm, uintptr_t reason); 1450 bool Reject(const EcmaVM *vm, Local<JSValueRef> reason); 1451 Local<PromiseRef> GetPromise(const EcmaVM *vm); 1452 }; 1453 1454 class ECMA_PUBLIC_API NumberRef : public PrimitiveRef { 1455 public: 1456 static Local<NumberRef> New(const EcmaVM *vm, double input); 1457 static Local<NumberRef> New(const EcmaVM *vm, int32_t input); 1458 static Local<NumberRef> New(const EcmaVM *vm, uint32_t input); 1459 static Local<NumberRef> New(const EcmaVM *vm, int64_t input); 1460 1461 double Value(); 1462 }; 1463 1464 class ECMA_PUBLIC_API DataViewRef : public ObjectRef { 1465 public: 1466 static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, 1467 uint32_t byteLength); 1468 uint32_t ByteLength(); 1469 uint32_t ByteOffset(); 1470 Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm); 1471 }; 1472 1473 class ECMA_PUBLIC_API MapIteratorRef : public ObjectRef { 1474 public: 1475 int32_t GetIndex(); 1476 Local<JSValueRef> GetKind(const EcmaVM *vm); 1477 static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map); 1478 ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm); 1479 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo); 1480 Local<JSValueRef> Next(const EcmaVM *vm); 1481 }; 1482 1483 class ECMA_PUBLIC_API SendableMapIteratorRef : public ObjectRef { 1484 public: 1485 Local<JSValueRef> Next(const EcmaVM *vm); 1486 }; 1487 1488 class ECMA_PUBLIC_API JSNApi { 1489 public: 1490 struct DebugOption { 1491 const char *libraryPath; 1492 bool isDebugMode = false; 1493 int port = -1; 1494 }; 1495 using DebuggerPostTask = std::function<void(std::function<void()>&&)>; 1496 1497 using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>; 1498 1499 struct NativeBindingInfo { CreateNewInstanceNativeBindingInfo1500 static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); } 1501 void *env = nullptr; 1502 void *nativeValue = nullptr; 1503 void *attachFunc = nullptr; 1504 void *attachData = nullptr; 1505 void *detachFunc = nullptr; 1506 void *detachData = nullptr; 1507 void *hint = nullptr; 1508 }; 1509 1510 // JSVM 1511 // fixme: Rename SEMI_GC to YOUNG_GC 1512 enum class ECMA_PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, FULL_GC }; 1513 enum class ECMA_PUBLIC_API TRIGGER_IDLE_GC_TYPE : uint8_t { 1514 OLD_GC = 1, 1515 FULL_GC = 1 << 2, 1516 SHARED_GC = 1 << 3, 1517 SHARED_FULL_GC = 1 << 4, 1518 LOCAL_CONCURRENT_MARK = 1 << 5, 1519 LOCAL_REMARK = 1 << 6, 1520 }; 1521 1522 enum class PatchErrorCode : uint8_t { 1523 SUCCESS = 0, 1524 PATCH_HAS_LOADED, 1525 PATCH_NOT_LOADED, 1526 FILE_NOT_EXECUTED, 1527 FILE_NOT_FOUND, 1528 PACKAGE_NOT_ESMODULE, 1529 MODIFY_IMPORT_EXPORT_NOT_SUPPORT, 1530 INTERNAL_ERROR 1531 }; 1532 1533 static EcmaVM *CreateJSVM(const RuntimeOption &option); 1534 static void DestroyJSVM(EcmaVM *ecmaVm); 1535 static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler); 1536 1537 // aot load 1538 static void LoadAotFileInternal(EcmaVM *vm, const std::string &moduleName, std::string &aotFileName); 1539 static void LoadAotFile(EcmaVM *vm, const std::string &moduleName); 1540 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 1541 static void LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, 1542 const std::string &moduleName, 1543 std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb); 1544 #endif 1545 // context 1546 static EcmaContext *CreateJSContext(EcmaVM *vm); 1547 static void SwitchCurrentContext(EcmaVM *vm, EcmaContext *context); 1548 static void DestroyJSContext(EcmaVM *vm, EcmaContext *context); 1549 1550 // context execute 1551 static bool ExecuteInContext(EcmaVM *vm, const std::string &fileName, const std::string &entry, 1552 bool needUpdate = false); 1553 // JS code 1554 static bool ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName, const std::string &entry, 1555 bool needUpdate = false, bool executeFromJob = false); 1556 static bool Execute(const EcmaVM *vm, const std::string &fileName, const std::string &entry, 1557 bool needUpdate = false, bool executeFromJob = false); 1558 static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry, 1559 const std::string &filename = "", bool needUpdate = false); 1560 static int ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName, 1561 const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern); 1562 static bool IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName, 1563 const std::string &moduleName, const std::string &ohmurl); 1564 // merge abc, execute module buffer 1565 static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "", 1566 bool needUpdate = false); 1567 static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file); 1568 static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key); 1569 static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key); 1570 static Local<ObjectRef> ExecuteNativeModule(EcmaVM *vm, const std::string &key); 1571 static Local<ObjectRef> GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file, 1572 const std::string &module_path); 1573 static Local<ObjectRef> GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file, 1574 const std::string &module_path); 1575 1576 /* 1577 * Execute panda file from secure mem. secure memory lifecycle managed externally. 1578 * The data parameter needs to be created externally by an external caller and managed externally 1579 * by the external caller. The size parameter is the size of the data memory. The entry parameter 1580 * is the name of the entry function. The filename parameter is used to uniquely identify this 1581 * memory internally. 1582 */ 1583 static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry, 1584 const std::string &filename = "", bool needUpdate = false); 1585 /* 1586 * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally. 1587 * The data parameter needs to be created externally by an external caller and managed externally 1588 * by the external caller. The size parameter is the size of the data memory. The filename parameter 1589 * is used to uniquely identify this memory internally. 1590 */ 1591 static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "", 1592 bool needUpdate = false); 1593 1594 // ObjectRef Operation 1595 static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm); 1596 static void ExecutePendingJob(const EcmaVM *vm); 1597 1598 // Memory 1599 // fixme: Rename SEMI_GC to YOUNG_GC 1600 static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC); 1601 static void TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason, 1602 TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC); 1603 static void TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType); 1604 static void SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback); 1605 static StartIdleMonitorCallback GetStartIdleMonitorCallback(); 1606 // Exception 1607 static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error); 1608 static void PrintExceptionInfo(const EcmaVM *vm); 1609 static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm); 1610 static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm); 1611 static bool IsExecutingPendingJob(const EcmaVM *vm); 1612 static bool HasPendingException(const EcmaVM *vm); 1613 static bool HasPendingJob(const EcmaVM *vm); 1614 static void EnableUserUncaughtErrorHandler(EcmaVM *vm); 1615 // prevewer debugger. 1616 static bool StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId, 1617 const DebuggerPostTask &debuggerPostTask); 1618 static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1619 const DebuggerPostTask &debuggerPostTask = {}); 1620 // To be compatible with the old process. 1621 static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1622 const DebuggerPostTask &debuggerPostTask = {}); 1623 // socketpair process in ohos platform. 1624 static bool StartDebuggerForSocketPair(int tid, int socketfd = -1); 1625 static bool StopDebugger(int tid); 1626 static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, 1627 const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false); 1628 static bool StoreDebugInfo( 1629 int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp); 1630 static bool StopDebugger(EcmaVM *vm); 1631 static bool IsMixedDebugEnabled(const EcmaVM *vm); 1632 static bool IsDebugModeEnabled(const EcmaVM *vm); 1633 static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress); 1634 static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress); 1635 static void NotifyLoadModule(const EcmaVM *vm); 1636 static void NotifyUIIdle(const EcmaVM *vm, int idleTime); 1637 static void NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime); 1638 static void NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp); 1639 static bool IsJSMainThreadOfEcmaVM(const EcmaVM *vm); 1640 static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb); 1641 // Serialize & Deserialize. 1642 static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer, 1643 Local<JSValueRef> cloneList, 1644 bool defaultTransfer = false, 1645 bool defaultCloneShared = true); 1646 static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint); 1647 static void DeleteSerializationData(void *data); 1648 static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data); 1649 static void SetHostResolveBufferTracker(EcmaVM *vm, 1650 std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb); 1651 static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb); 1652 static void SetNativePtrGetter(EcmaVM *vm, void* cb); 1653 static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb); 1654 static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb); 1655 static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb, 1656 QueueType queueType = QueueType::QUEUE_PROMISE); 1657 static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options); 1658 static void PreFork(EcmaVM *vm); 1659 static void PostFork(EcmaVM *vm, const RuntimeOption &option); 1660 static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm); 1661 static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm); 1662 static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess); 1663 static void GetStackAfterCallNapi(EcmaVM *vm); 1664 static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName); 1665 static PatchErrorCode LoadPatch(EcmaVM *vm, 1666 const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize, 1667 const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize); 1668 static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName); 1669 // check whether the exception is caused by quickfix methods. 1670 static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName); 1671 // register quickfix query function. 1672 static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName, 1673 std::string &patchFileName, 1674 uint8_t **patchBuffer, 1675 size_t &patchSize)> callBack); 1676 static bool IsBundle(EcmaVM *vm); 1677 static void SetBundle(EcmaVM *vm, bool value); 1678 static bool IsNormalizedOhmUrlPack(EcmaVM *vm); 1679 static void SetAssetPath(EcmaVM *vm, const std::string &assetPath); 1680 static void SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list); 1681 static void SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list); 1682 static std::string GetPkgName(EcmaVM *vm, const std::string &moduleName); 1683 static void SetPkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list); 1684 static void SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list); 1685 static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint); 1686 static void SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string, 1687 std::vector<std::vector<std::string>>> &list); 1688 static void SetExecuteBufferMode(const EcmaVM *vm); 1689 static void SetLoop(EcmaVM *vm, void *loop); 1690 static void SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback); 1691 static void SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback); 1692 static void SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback); 1693 static void SetStartIdleMonitorCallback(EcmaVM *vm, const StartIdleMonitorCallback& callback); 1694 static std::string GetAssetPath(EcmaVM *vm); 1695 static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data); 1696 static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func, void *taskInfo); 1697 static void* GetCurrentTaskInfo(const EcmaVM *vm); 1698 static void ClearCurrentTaskInfo(const EcmaVM *vm); 1699 static void SetBundleName(EcmaVM *vm, const std::string &bundleName); 1700 static std::string GetBundleName(EcmaVM *vm); 1701 static void SetModuleName(EcmaVM *vm, const std::string &moduleName); 1702 static std::string GetModuleName(EcmaVM *vm); 1703 static std::pair<std::string, std::string> GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false); 1704 static std::string NormalizePath(const std::string &string); 1705 static void AllowCrossThreadExecution(EcmaVM *vm); 1706 static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM); 1707 static bool IsProfiling(EcmaVM *vm); 1708 static void SetProfilerState(const EcmaVM *vm, bool value); 1709 static void SetRequestAotCallback(EcmaVM *vm, const std::function<int32_t(const std::string &bundleName, 1710 const std::string &moduleName, 1711 int32_t triggerMode)> &cb); 1712 static void SetSearchHapPathTracker(EcmaVM *vm, std::function<bool(const std::string moduleName, 1713 std::string &hapPath)> cb); 1714 static void *GetEnv(EcmaVM *vm); 1715 static void SetEnv(EcmaVM *vm, void *env); 1716 static void SetMultiThreadCheck(bool multiThreadCheck = true); 1717 static void SetErrorInfoEnhance(bool errorInfoEnhance = true); 1718 1719 // Napi Heavy Logics fast path 1720 static Local<JSValueRef> NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); 1721 static Local<JSValueRef> NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); 1722 static Local<JSValueRef> NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); 1723 static Local<JSValueRef> NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); 1724 static Local<JSValueRef> NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key); 1725 1726 static Local<JSValueRef> CreateLocal(const EcmaVM *vm, JSValueRef src); 1727 1728 // Napi helper function 1729 static bool KeyIsNumber(const char* utf8); 1730 static int GetStartRealTime(const EcmaVM *vm); 1731 static void NotifyTaskBegin(const EcmaVM *vm); 1732 static void NotifyTaskFinished(const EcmaVM *vm); 1733 static bool IsMultiThreadCheckEnabled(const EcmaVM *vm); 1734 static uint32_t GetCurrentThreadId(); 1735 private: 1736 static int vmCount_; 1737 static bool initialize_; 1738 static bool CreateRuntime(const RuntimeOption &option); 1739 static bool DestroyRuntime(); 1740 static StartIdleMonitorCallback startIdleMonitorCallback_; 1741 1742 static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress); 1743 static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress); 1744 static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress); 1745 static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref, 1746 WeakRefClearCallBack freeGlobalCallBack, 1747 WeakRefClearCallBack nativeFinalizeCallback); 1748 static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress); 1749 static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress); 1750 static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr); 1751 static bool IsSerializationTimeoutCheckEnabled(const EcmaVM *vm); 1752 static void GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start, 1753 std::chrono::system_clock::time_point &end, bool isSerialization); 1754 static void UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option); 1755 template<typename T> 1756 friend class Global; 1757 template<typename T> 1758 friend class CopyableGlobal; 1759 template<typename T> 1760 friend class Local; 1761 friend class test::JSNApiTests; 1762 }; 1763 1764 class ECMA_PUBLIC_API ProxyRef : public ObjectRef { 1765 public: 1766 Local<JSValueRef> GetHandler(const EcmaVM *vm); 1767 Local<JSValueRef> GetTarget(const EcmaVM *vm); 1768 bool IsRevoked(); 1769 }; 1770 1771 class ECMA_PUBLIC_API WeakMapRef : public ObjectRef { 1772 public: 1773 int32_t GetSize(const EcmaVM *vm); 1774 int32_t GetTotalElements(const EcmaVM *vm); 1775 Local<JSValueRef> GetKey(const EcmaVM *vm, int entry); 1776 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1777 static Local<WeakMapRef> New(const EcmaVM *vm); 1778 void Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value); 1779 bool Has(const EcmaVM *vm, Local<JSValueRef> key); 1780 }; 1781 1782 class ECMA_PUBLIC_API SetRef : public ObjectRef { 1783 public: 1784 int32_t GetSize(const EcmaVM *vm); 1785 int32_t GetTotalElements(const EcmaVM *vm); 1786 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1787 static Local<SetRef> New(const EcmaVM *vm); 1788 void Add(const EcmaVM *vm, Local<JSValueRef> value); 1789 }; 1790 1791 class ECMA_PUBLIC_API WeakSetRef : public ObjectRef { 1792 public: 1793 int32_t GetSize(const EcmaVM *vm); 1794 int32_t GetTotalElements(const EcmaVM *vm); 1795 Local<JSValueRef> GetValue(const EcmaVM *vm, int entry); 1796 static Local<WeakSetRef> New(const EcmaVM *vm); 1797 void Add(const EcmaVM *vm, Local<JSValueRef> value); 1798 }; 1799 1800 class ECMA_PUBLIC_API SetIteratorRef : public ObjectRef { 1801 public: 1802 int32_t GetIndex(); 1803 Local<JSValueRef> GetKind(const EcmaVM *vm); 1804 static Local<SetIteratorRef> New(const EcmaVM *vm, Local<SetRef> set); 1805 ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm); 1806 static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); 1807 }; 1808 1809 /* Attention pls, ExternalStringCache only can be utilized in main thread. Threads of Worker or Taskpool call 1810 * functions of this class will cause data race. 1811 */ 1812 class ECMA_PUBLIC_API ExternalStringCache final { 1813 public: 1814 static bool RegisterStringCacheTable(const EcmaVM *vm, uint32_t size); 1815 static bool SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex); 1816 static bool HasCachedString(const EcmaVM *vm, uint32_t propertyIndex); 1817 static Local<StringRef> GetCachedString(const EcmaVM *vm, uint32_t propertyIndex); 1818 }; 1819 } 1820 #endif 1821