1 #ifndef SRC_NODE_REALM_H_ 2 #define SRC_NODE_REALM_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include <v8.h> 7 #include <unordered_map> 8 #include "cleanup_queue.h" 9 #include "env_properties.h" 10 #include "memory_tracker.h" 11 #include "node_snapshotable.h" 12 13 namespace node { 14 15 struct RealmSerializeInfo { 16 std::vector<PropInfo> persistent_values; 17 std::vector<PropInfo> native_objects; 18 19 SnapshotIndex context; 20 friend std::ostream& operator<<(std::ostream& o, const RealmSerializeInfo& i); 21 }; 22 23 using BindingDataStore = std::unordered_map<FastStringKey, 24 BaseObjectPtr<BaseObject>, 25 FastStringKey::Hash>; 26 27 /** 28 * node::Realm is a container for a set of JavaScript objects and functions 29 * that associated with a particular global environment. 30 * 31 * An ECMAScript realm (https://tc39.es/ecma262/#sec-code-realms) representing 32 * a global environment in which script is run. Each ECMAScript realm comes 33 * with a global object and a set of intrinsic objects. An ECMAScript realm has 34 * a [[HostDefined]] field, which contains the node::Realm object. 35 * 36 * Realm can be a principal realm or a synthetic realm. A principal realm is 37 * created with an Environment as its principal global environment to evaluate 38 * scripts. A synthetic realm is created with JS APIs like ShadowRealm. 39 * 40 * Native bindings and builtin modules can be evaluated in either a principal 41 * realm or a synthetic realm. 42 */ 43 class Realm : public MemoryRetainer { 44 public: 45 static inline Realm* GetCurrent(v8::Isolate* isolate); 46 static inline Realm* GetCurrent(v8::Local<v8::Context> context); 47 static inline Realm* GetCurrent( 48 const v8::FunctionCallbackInfo<v8::Value>& info); 49 template <typename T> 50 static inline Realm* GetCurrent(const v8::PropertyCallbackInfo<T>& info); 51 52 Realm(Environment* env, 53 v8::Local<v8::Context> context, 54 const RealmSerializeInfo* realm_info); 55 ~Realm(); 56 57 Realm(const Realm&) = delete; 58 Realm& operator=(const Realm&) = delete; 59 Realm(Realm&&) = delete; 60 Realm& operator=(Realm&&) = delete; 61 62 SET_MEMORY_INFO_NAME(Realm) 63 SET_SELF_SIZE(Realm) 64 void MemoryInfo(MemoryTracker* tracker) const override; 65 66 void CreateProperties(); 67 RealmSerializeInfo Serialize(v8::SnapshotCreator* creator); 68 void DeserializeProperties(const RealmSerializeInfo* info); 69 70 v8::MaybeLocal<v8::Value> ExecuteBootstrapper( 71 const char* id, std::vector<v8::Local<v8::Value>>* arguments); 72 v8::MaybeLocal<v8::Value> BootstrapInternalLoaders(); 73 v8::MaybeLocal<v8::Value> BootstrapNode(); 74 v8::MaybeLocal<v8::Value> RunBootstrapping(); 75 76 inline void AddCleanupHook(CleanupQueue::Callback cb, void* arg); 77 inline void RemoveCleanupHook(CleanupQueue::Callback cb, void* arg); 78 inline bool HasCleanupHooks() const; 79 void RunCleanup(); 80 81 template <typename T> 82 void ForEachBaseObject(T&& iterator) const; 83 84 void PrintInfoForSnapshot(); 85 void VerifyNoStrongBaseObjects(); 86 87 inline IsolateData* isolate_data() const; 88 inline Environment* env() const; 89 inline v8::Isolate* isolate() const; 90 inline v8::Local<v8::Context> context() const; 91 inline bool has_run_bootstrapping_code() const; 92 93 // Methods created using SetMethod(), SetPrototypeMethod(), etc. inside 94 // this scope can access the created T* object using 95 // GetBindingData<T>(args) later. 96 template <typename T> 97 T* AddBindingData(v8::Local<v8::Context> context, 98 v8::Local<v8::Object> target); 99 template <typename T, typename U> 100 static inline T* GetBindingData(const v8::PropertyCallbackInfo<U>& info); 101 template <typename T> 102 static inline T* GetBindingData( 103 const v8::FunctionCallbackInfo<v8::Value>& info); 104 template <typename T> 105 static inline T* GetBindingData(v8::Local<v8::Context> context); 106 inline BindingDataStore* binding_data_store(); 107 108 // The BaseObject count is a debugging helper that makes sure that there are 109 // no memory leaks caused by BaseObjects staying alive longer than expected 110 // (in particular, no circular BaseObjectPtr references). 111 inline void modify_base_object_count(int64_t delta); 112 inline int64_t base_object_count() const; 113 114 // Base object count created after the bootstrap of the realm. 115 inline int64_t base_object_created_after_bootstrap() const; 116 117 #define V(PropertyName, TypeName) \ 118 inline v8::Local<TypeName> PropertyName() const; \ 119 inline void set_##PropertyName(v8::Local<TypeName> value); 120 PER_REALM_STRONG_PERSISTENT_VALUES(V) 121 #undef V 122 123 private: 124 void InitializeContext(v8::Local<v8::Context> context, 125 const RealmSerializeInfo* realm_info); 126 void DoneBootstrapping(); 127 128 Environment* env_; 129 // Shorthand for isolate pointer. 130 v8::Isolate* isolate_; 131 v8::Global<v8::Context> context_; 132 bool has_run_bootstrapping_code_ = false; 133 134 int64_t base_object_count_ = 0; 135 int64_t base_object_created_by_bootstrap_ = 0; 136 137 BindingDataStore binding_data_store_; 138 139 CleanupQueue cleanup_queue_; 140 141 #define V(PropertyName, TypeName) v8::Global<TypeName> PropertyName##_; 142 PER_REALM_STRONG_PERSISTENT_VALUES(V) 143 #undef V 144 }; 145 146 } // namespace node 147 148 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 149 150 #endif // SRC_NODE_REALM_H_ 151