|
5 | 5 | #ifndef INCLUDE_V8_OBJECT_H_ |
6 | 6 | #define INCLUDE_V8_OBJECT_H_ |
7 | 7 |
|
| 8 | +#include "v8-internal.h" // NOLINT(build/include_directory) |
8 | 9 | #include "v8-local-handle.h" // NOLINT(build/include_directory) |
9 | 10 | #include "v8-maybe.h" // NOLINT(build/include_directory) |
10 | 11 | #include "v8-persistent-handle.h" // NOLINT(build/include_directory) |
11 | 12 | #include "v8-primitive.h" // NOLINT(build/include_directory) |
| 13 | +#include "v8-sandbox.h" // NOLINT(build/include_directory) |
12 | 14 | #include "v8-traced-handle.h" // NOLINT(build/include_directory) |
13 | 15 | #include "v8-value.h" // NOLINT(build/include_directory) |
14 | 16 | #include "v8config.h" // NOLINT(build/include_directory) |
@@ -528,7 +530,50 @@ class V8_EXPORT Object : public Value { |
528 | 530 | void* values[]); |
529 | 531 |
|
530 | 532 | /** |
531 | | - * HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty(). |
| 533 | + * Unwraps a JS wrapper object. |
| 534 | + * |
| 535 | + * \param tag The tag for retrieving the wrappable instance. Must match the |
| 536 | + * tag that has been used for a previous `Wrap()` operation. |
| 537 | + * \param isolate The Isolate for the `wrapper` object. |
| 538 | + * \param wrapper The JS wrapper object that should be unwrapped. |
| 539 | + * \returns the C++ wrappable instance, or nullptr if the JS object has never |
| 540 | + * been wrapped. |
| 541 | + */ |
| 542 | + template <CppHeapPointerTag tag, typename T = void> |
| 543 | + static V8_INLINE T* Unwrap(v8::Isolate* isolate, |
| 544 | + const v8::Local<v8::Object>& wrapper); |
| 545 | + template <CppHeapPointerTag tag, typename T = void> |
| 546 | + static V8_INLINE T* Unwrap(v8::Isolate* isolate, |
| 547 | + const PersistentBase<Object>& wrapper); |
| 548 | + template <CppHeapPointerTag tag, typename T = void> |
| 549 | + static V8_INLINE T* Unwrap(v8::Isolate* isolate, |
| 550 | + const BasicTracedReference<Object>& wrapper); |
| 551 | + |
| 552 | + /** |
| 553 | + * Wraps a JS wrapper with a C++ instance. |
| 554 | + * |
| 555 | + * \param tag The pointer tag that should be used for storing this object. |
| 556 | + * Future `Unwrap()` operations must provide a matching tag. |
| 557 | + * \param isolate The Isolate for the `wrapper` object. |
| 558 | + * \param wrapper The JS wrapper object. |
| 559 | + * \param wrappable The C++ object instance that is wrapped by the JS object. |
| 560 | + */ |
| 561 | + template <CppHeapPointerTag tag> |
| 562 | + static V8_INLINE void Wrap(v8::Isolate* isolate, |
| 563 | + const v8::Local<v8::Object>& wrapper, |
| 564 | + void* wrappable); |
| 565 | + template <CppHeapPointerTag tag> |
| 566 | + static V8_INLINE void Wrap(v8::Isolate* isolate, |
| 567 | + const PersistentBase<Object>& wrapper, |
| 568 | + void* wrappable); |
| 569 | + template <CppHeapPointerTag tag> |
| 570 | + static V8_INLINE void Wrap(v8::Isolate* isolate, |
| 571 | + const BasicTracedReference<Object>& wrapper, |
| 572 | + void* wrappable); |
| 573 | + |
| 574 | + /** |
| 575 | + * HasOwnProperty() is like JavaScript's |
| 576 | + * Object.prototype.hasOwnProperty(). |
532 | 577 | * |
533 | 578 | * See also v8::Object::Has() and v8::Object::HasRealNamedProperty(). |
534 | 579 | */ |
@@ -731,6 +776,11 @@ class V8_EXPORT Object : public Value { |
731 | 776 | bool IsCodeLike(Isolate* isolate) const; |
732 | 777 |
|
733 | 778 | private: |
| 779 | + static void* Unwrap(v8::Isolate* isolate, internal::Address wrapper_obj, |
| 780 | + CppHeapPointerTag tag); |
| 781 | + static void Wrap(v8::Isolate* isolate, internal::Address wrapper_obj, |
| 782 | + CppHeapPointerTag tag, void* wrappable); |
| 783 | + |
734 | 784 | Object(); |
735 | 785 | static void CheckCast(Value* obj); |
736 | 786 | Local<Data> SlowGetInternalField(int index); |
@@ -810,6 +860,73 @@ void* Object::GetAlignedPointerFromInternalField(int index) { |
810 | 860 | return SlowGetAlignedPointerFromInternalField(index); |
811 | 861 | } |
812 | 862 |
|
| 863 | +// static |
| 864 | +template <CppHeapPointerTag tag, typename T> |
| 865 | +T* Object::Unwrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper) { |
| 866 | + auto obj = internal::ValueHelper::ValueAsAddress(*wrapper); |
| 867 | +#if !defined(V8_ENABLE_CHECKS) |
| 868 | + return internal::ReadCppHeapPointerField<tag, T>( |
| 869 | + isolate, obj, internal::Internals::kJSObjectHeaderSize); |
| 870 | +#else // defined(V8_ENABLE_CHECKS) |
| 871 | + return reinterpret_cast<T*>(Unwrap(isolate, obj, tag)); |
| 872 | +#endif // defined(V8_ENABLE_CHECKS) |
| 873 | +} |
| 874 | + |
| 875 | +// static |
| 876 | +template <CppHeapPointerTag tag, typename T> |
| 877 | +T* Object::Unwrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper) { |
| 878 | + auto obj = |
| 879 | + internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>()); |
| 880 | +#if !defined(V8_ENABLE_CHECKS) |
| 881 | + return internal::ReadCppHeapPointerField<tag, T>( |
| 882 | + isolate, obj, internal::Internals::kJSObjectHeaderSize); |
| 883 | +#else // defined(V8_ENABLE_CHECKS) |
| 884 | + |
| 885 | + return reinterpret_cast<T*>(Unwrap(isolate, obj, tag)); |
| 886 | +#endif // defined(V8_ENABLE_CHECKS) |
| 887 | +} |
| 888 | + |
| 889 | +// static |
| 890 | +template <CppHeapPointerTag tag, typename T> |
| 891 | +T* Object::Unwrap(v8::Isolate* isolate, |
| 892 | + const BasicTracedReference<Object>& wrapper) { |
| 893 | + auto obj = |
| 894 | + internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>()); |
| 895 | +#if !defined(V8_ENABLE_CHECKS) |
| 896 | + return internal::ReadCppHeapPointerField<tag, T>( |
| 897 | + isolate, obj, internal::Internals::kJSObjectHeaderSize); |
| 898 | +#else // defined(V8_ENABLE_CHECKS) |
| 899 | + return reinterpret_cast<T*>(Unwrap(isolate, obj, tag)); |
| 900 | +#endif // defined(V8_ENABLE_CHECKS) |
| 901 | +} |
| 902 | + |
| 903 | +// static |
| 904 | +template <CppHeapPointerTag tag> |
| 905 | +void Object::Wrap(v8::Isolate* isolate, const v8::Local<v8::Object>& wrapper, |
| 906 | + void* wrappable) { |
| 907 | + auto obj = internal::ValueHelper::ValueAsAddress(*wrapper); |
| 908 | + Wrap(isolate, obj, tag, wrappable); |
| 909 | +} |
| 910 | + |
| 911 | +// static |
| 912 | +template <CppHeapPointerTag tag> |
| 913 | +void Object::Wrap(v8::Isolate* isolate, const PersistentBase<Object>& wrapper, |
| 914 | + void* wrappable) { |
| 915 | + auto obj = |
| 916 | + internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>()); |
| 917 | + Wrap(isolate, obj, tag, wrappable); |
| 918 | +} |
| 919 | + |
| 920 | +// static |
| 921 | +template <CppHeapPointerTag tag> |
| 922 | +void Object::Wrap(v8::Isolate* isolate, |
| 923 | + const BasicTracedReference<Object>& wrapper, |
| 924 | + void* wrappable) { |
| 925 | + auto obj = |
| 926 | + internal::ValueHelper::ValueAsAddress(wrapper.template value<Object>()); |
| 927 | + Wrap(isolate, obj, tag, wrappable); |
| 928 | +} |
| 929 | + |
813 | 930 | Private* Private::Cast(Data* data) { |
814 | 931 | #ifdef V8_ENABLE_CHECKS |
815 | 932 | CheckCast(data); |
|
0 commit comments