diff --git a/src/async_wrap.cc b/src/async_wrap.cc index b24c160156c280..25c0eede96ed7e 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -23,6 +23,7 @@ #include "async_wrap-inl.h" #include "env-inl.h" #include "node_errors.h" +#include "node_external_reference.h" #include "tracing/traced_value.h" #include "util-inl.h" @@ -576,6 +577,21 @@ void AsyncWrap::Initialize(Local target, } } +void AsyncWrap::RegisterExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(SetupHooks); + registry->Register(PushAsyncContext); + registry->Register(PopAsyncContext); + registry->Register(QueueDestroyAsyncId); + registry->Register(EnablePromiseHook); + registry->Register(DisablePromiseHook); + registry->Register(PromiseWrap::getIsChainedPromise); + registry->Register(RegisterDestroyHook); + registry->Register(AsyncWrapObject::New); + registry->Register(AsyncWrap::GetAsyncId); + registry->Register(AsyncWrap::AsyncReset); + registry->Register(AsyncWrap::GetProviderType); +} AsyncWrap::AsyncWrap(Environment* env, Local object, diff --git a/src/async_wrap.h b/src/async_wrap.h index 34e84fde6d4823..89147b69b25fda 100644 --- a/src/async_wrap.h +++ b/src/async_wrap.h @@ -99,6 +99,7 @@ namespace node { class Environment; class DestroyParam; +class ExternalReferenceRegistry; class AsyncWrap : public BaseObject { public: @@ -128,6 +129,7 @@ class AsyncWrap : public BaseObject { static v8::Local GetConstructorTemplate( Environment* env); + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static void Initialize(v8::Local target, v8::Local unused, v8::Local context, diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 5c9ad5e946424b..778916181495bc 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -2,9 +2,10 @@ #include "inspector_agent.h" #include "inspector_io.h" #include "memory_tracker-inl.h" +#include "node_external_reference.h" #include "util-inl.h" -#include "v8.h" #include "v8-inspector.h" +#include "v8.h" #include @@ -346,6 +347,31 @@ void Initialize(Local target, Local unused, } } // namespace + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(InspectorConsoleCall); + registry->Register(SetConsoleExtensionInstaller); + registry->Register(CallAndPauseOnStart); + registry->Register(Open); + registry->Register(Url); + registry->Register(WaitForDebugger); + + registry->Register(AsyncTaskScheduledWrapper); + registry->Register(InvokeAsyncTaskFnWithId<&Agent::AsyncTaskCanceled>); + registry->Register(InvokeAsyncTaskFnWithId<&Agent::AsyncTaskStarted>); + registry->Register(InvokeAsyncTaskFnWithId<&Agent::AsyncTaskFinished>); + + registry->Register(RegisterAsyncHookWrapper); + registry->Register(IsEnabled); + + registry->Register(JSBindingsConnection::New); + registry->Register(JSBindingsConnection::Dispatch); + registry->Register(JSBindingsConnection::Disconnect); + registry->Register(JSBindingsConnection::New); + registry->Register(JSBindingsConnection::Dispatch); + registry->Register(JSBindingsConnection::Disconnect); +} + } // namespace inspector } // namespace node diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 77120d6af4a811..571622f6939be8 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -22,6 +22,7 @@ #include "node_buffer.h" #include "node.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" #include "env-inl.h" @@ -1197,6 +1198,7 @@ void Initialize(Local target, env->SetMethod(target, "ucs2Write", StringWrite); env->SetMethod(target, "utf8Write", StringWrite); + // TODO(joyee): re-initialize upon snapshot deserialization // It can be a nullptr when running inside an isolate where we // do not own the ArrayBuffer allocator. if (NodeArrayBufferAllocator* allocator = @@ -1222,6 +1224,42 @@ void Initialize(Local target, } } // anonymous namespace + +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(SetBufferPrototype); + registry->Register(CreateFromString); + + registry->Register(ByteLengthUtf8); + registry->Register(Copy); + registry->Register(Compare); + registry->Register(CompareOffset); + registry->Register(Fill); + registry->Register(IndexOfBuffer); + registry->Register(IndexOfNumber); + registry->Register(IndexOfString); + + registry->Register(Swap16); + registry->Register(Swap32); + registry->Register(Swap64); + + registry->Register(EncodeInto); + registry->Register(EncodeUtf8String); + + registry->Register(StringSlice); + registry->Register(StringSlice); + registry->Register(StringSlice); + registry->Register(StringSlice); + registry->Register(StringSlice); + registry->Register(StringSlice); + + registry->Register(StringWrite); + registry->Register(StringWrite); + registry->Register(StringWrite); + registry->Register(StringWrite); + registry->Register(StringWrite); + registry->Register(StringWrite); +} + } // namespace Buffer } // namespace node diff --git a/src/node_credentials.cc b/src/node_credentials.cc index ad0e1dbb9bb68e..c2d91349e5c3dd 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -1,4 +1,5 @@ #include "env-inl.h" +#include "node_external_reference.h" #include "node_internals.h" #include "util-inl.h" @@ -373,6 +374,25 @@ static void InitGroups(const FunctionCallbackInfo& args) { #endif // NODE_IMPLEMENTS_POSIX_CREDENTIALS +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(SafeGetenv); + +#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS + registry->Register(GetUid); + registry->Register(GetEUid); + registry->Register(GetGid); + registry->Register(GetEGid); + registry->Register(GetGroups); + + registry->Register(InitGroups); + registry->Register(SetEGid); + registry->Register(SetEUid); + registry->Register(SetGid); + registry->Register(SetUid); + registry->Register(SetGroups); +#endif // NODE_IMPLEMENTS_POSIX_CREDENTIALS +} + static void Initialize(Local target, Local unused, Local context, diff --git a/src/node_env_var.cc b/src/node_env_var.cc index 6ae24909343379..08a13b6c0d81da 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -1,6 +1,7 @@ #include "debug_utils-inl.h" #include "env-inl.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_process.h" #include // tzset(), _tzset() @@ -387,4 +388,13 @@ MaybeLocal CreateEnvVarProxy(Local context, PropertyHandlerFlags::kHasNoSideEffect)); return scope.EscapeMaybe(env_proxy_template->NewInstance(context)); } + +void RegisterEnvVarExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(EnvGetter); + registry->Register(EnvSetter); + registry->Register(EnvQuery); + registry->Register(EnvDeleter); + registry->Register(EnvEnumerator); +} + } // namespace node diff --git a/src/node_errors.cc b/src/node_errors.cc index 4e13c24e15e1d0..45db47c10160df 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -3,9 +3,10 @@ #include "debug_utils-inl.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" -#include "node_report.h" #include "node_process.h" +#include "node_report.h" #include "node_v8_platform-inl.h" #include "util-inl.h" @@ -833,6 +834,13 @@ static void TriggerUncaughtException(const FunctionCallbackInfo& args) { errors::TriggerUncaughtException(isolate, exception, message, from_promise); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(SetPrepareStackTraceCallback); + registry->Register(SetEnhanceStackForFatalException); + registry->Register(NoSideEffectsToString); + registry->Register(TriggerUncaughtException); +} + void Initialize(Local target, Local unused, Local context, diff --git a/src/node_errors.h b/src/node_errors.h index 3c57f4b8b02fee..a8f400f77fb691 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -161,8 +161,11 @@ inline v8::Local ERR_STRING_TOO_LONG(v8::Isolate* isolate) { prefix " must be a string"); \ } while (0) +class ExternalReferenceRegistry; namespace errors { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); + class TryCatchScope : public v8::TryCatch { public: enum class CatchMode { kNormal, kFatal }; diff --git a/src/node_external_reference.h b/src/node_external_reference.h index 2d1be7a5e999dc..1017987c41a0a9 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -5,6 +5,7 @@ #include #include +#include "v8.h" namespace node { @@ -14,10 +15,22 @@ class ExternalReferenceRegistry { public: ExternalReferenceRegistry() {} - template - void Register(T* address) { - external_references_.push_back(reinterpret_cast(address)); - } +#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \ + V(v8::FunctionCallback) \ + V(v8::AccessorGetterCallback) \ + V(v8::AccessorSetterCallback) \ + V(v8::AccessorNameGetterCallback) \ + V(v8::AccessorNameSetterCallback) \ + V(v8::GenericNamedPropertyDefinerCallback) \ + V(v8::GenericNamedPropertyDeleterCallback) \ + V(v8::GenericNamedPropertyEnumeratorCallback) \ + V(v8::GenericNamedPropertyQueryCallback) \ + V(v8::GenericNamedPropertySetterCallback) + +#define V(ExternalReferenceType) \ + void Register(ExternalReferenceType addr) { RegisterT(addr); } + ALLOWED_EXTERNAL_REFERENCE_TYPES(V) +#undef V // This can be called only once. const std::vector& external_references(); @@ -25,10 +38,48 @@ class ExternalReferenceRegistry { bool is_empty() { return external_references_.empty(); } private: + template + void RegisterT(T* address) { + external_references_.push_back(reinterpret_cast(address)); + } bool is_finalized_ = false; std::vector external_references_; }; - +namespace errors { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +#if HAVE_INSPECTOR +namespace inspector { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +#endif // HAVE_INSPECTOR +namespace Buffer { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +namespace credentials { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +namespace i18n { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +namespace task_queue { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +namespace url { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +namespace util { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); +} +void RegisterNodeCategorySetExternalReferences( + ExternalReferenceRegistry* registry); +void RegisterProcessMethodsExternalReferences( + ExternalReferenceRegistry* registry); +void RegisterTypesExternalReferences(ExternalReferenceRegistry* registry); +void RegisterStringDecoderExternalReferences( + ExternalReferenceRegistry* registry); +void RegisterTimerExternalReferences(ExternalReferenceRegistry* registry); +void RegisterEnvVarExternalReferences(ExternalReferenceRegistry* registry); } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 169374aa5de441..e84126dd6a9554 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -41,6 +41,7 @@ #include "node_i18n.h" +#include "node_external_reference.h" #if defined(NODE_HAVE_I18N_SUPPORT) @@ -824,6 +825,17 @@ void Initialize(Local target, env->SetMethod(target, "hasConverter", ConverterObject::Has); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(ToUnicode); + registry->Register(ToASCII); + registry->Register(GetStringWidth); + registry->Register(ICUErrorName); + registry->Register(Transcode); + registry->Register(ConverterObject::Create); + registry->Register(ConverterObject::Decode); + registry->Register(ConverterObject::Has); +} + } // namespace i18n } // namespace node diff --git a/src/node_i18n.h b/src/node_i18n.h index 5c1501ea1908e0..3817a6fc54efa8 100644 --- a/src/node_i18n.h +++ b/src/node_i18n.h @@ -36,8 +36,9 @@ #include namespace node { - +class ExternalReferenceRegistry; namespace i18n { +void RegisterExternalReferences(ExternalReferenceRegistry* registry); bool InitializeICUDirectory(const std::string& path); diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index 0f46dbd6fac347..65b6fff415533a 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -1,6 +1,7 @@ #include #include +#include "async_wrap.h" #include "debug_utils-inl.h" #include "node_errors.h" #include "node_external_reference.h" @@ -59,8 +60,24 @@ const std::vector& NodeMainInstance::CollectExternalReferences() { registry_->Register(node::RawDebug); registry_->Register(node::binding::GetLinkedBinding); registry_->Register(node::binding::GetInternalBinding); + node::native_module::NativeModuleEnv::RegisterExternalReferences( registry_.get()); + node::AsyncWrap::RegisterExternalReferences(registry_.get()); + node::errors::RegisterExternalReferences(registry_.get()); + node::Buffer::RegisterExternalReferences(registry_.get()); + node::credentials::RegisterExternalReferences(registry_.get()); + node::inspector::RegisterExternalReferences(registry_.get()); + node::i18n::RegisterExternalReferences(registry_.get()); + node::task_queue::RegisterExternalReferences(registry_.get()); + node::url::RegisterExternalReferences(registry_.get()); + node::util::RegisterExternalReferences(registry_.get()); + RegisterNodeCategorySetExternalReferences(registry_.get()); + RegisterProcessMethodsExternalReferences(registry_.get()); + RegisterTypesExternalReferences(registry_.get()); + RegisterStringDecoderExternalReferences(registry_.get()); + RegisterTimerExternalReferences(registry_.get()); + RegisterEnvVarExternalReferences(registry_.get()); // TODO(joyeecheung): collect more external references here. return registry_->external_references(); } @@ -291,9 +308,9 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code, return nullptr; } - if (deserialize_mode_ && env->BootstrapNode().IsEmpty()) { - return nullptr; - } + // if (deserialize_mode_ && env->BootstrapNode().IsEmpty()) { + // return nullptr; + // } CHECK(env->req_wrap_queue()->IsEmpty()); CHECK(env->handle_wrap_queue()->IsEmpty()); diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index 88f4c1cfbd0249..cebb4cda5a0082 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -3,6 +3,7 @@ #include "env-inl.h" #include "node.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" #include "node_process.h" #include "util-inl.h" @@ -492,6 +493,36 @@ static void InitializeProcessMethods(Local target, env->SetMethod(target, "patchProcessObject", PatchProcessObject); } +void RegisterProcessMethodsExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(DebugProcess); + registry->Register(DebugEnd); + registry->Register(Abort); + registry->Register(CauseSegfault); + registry->Register(Chdir); + + registry->Register(StartProfilerIdleNotifier); + registry->Register(StopProfilerIdleNotifier); + + registry->Register(Umask); + registry->Register(RawDebug); + registry->Register(MemoryUsage); + registry->Register(CPUUsage); + registry->Register(Hrtime); + registry->Register(HrtimeBigInt); + registry->Register(ResourceUsage); + + registry->Register(GetActiveRequests); + registry->Register(GetActiveHandles); + registry->Register(Kill); + + registry->Register(Cwd); + registry->Register(binding::DLOpen); + registry->Register(ReallyExit); + registry->Register(Uptime); + registry->Register(PatchProcessObject); +} + } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods, diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc index b295dffd9d7bba..66236d49b1397b 100644 --- a/src/node_task_queue.cc +++ b/src/node_task_queue.cc @@ -1,6 +1,7 @@ #include "env-inl.h" #include "node.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_internals.h" #include "node_process.h" #include "util-inl.h" @@ -146,6 +147,13 @@ static void Initialize(Local target, SetPromiseRejectCallback); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(EnqueueMicrotask); + registry->Register(SetTickCallback); + registry->Register(RunMicrotasks); + registry->Register(SetPromiseRejectCallback); +} + } // namespace task_queue } // namespace node diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc index 9adee9e458ccc0..3300dfafa0c4c3 100644 --- a/src/node_trace_events.cc +++ b/src/node_trace_events.cc @@ -2,6 +2,7 @@ #include "env-inl.h" #include "memory_tracker-inl.h" #include "node.h" +#include "node_external_reference.h" #include "node_internals.h" #include "node_v8_platform-inl.h" #include "tracing/agent.h" @@ -12,6 +13,8 @@ namespace node { +class ExternalReferenceRegistry; + using v8::Array; using v8::Context; using v8::Function; @@ -153,6 +156,15 @@ void NodeCategorySet::Initialize(Local target, binding->Get(context, trace).ToLocalChecked()).Check(); } +void RegisterNodeCategorySetExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(GetEnabledCategories); + registry->Register(SetTraceCategoryStateUpdateHandler); + registry->Register(NodeCategorySet::New); + registry->Register(NodeCategorySet::Enable); + registry->Register(NodeCategorySet::Disable); +} + } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(trace_events, diff --git a/src/node_types.cc b/src/node_types.cc index 9643a66668144e..99bd15e542de7e 100644 --- a/src/node_types.cc +++ b/src/node_types.cc @@ -1,5 +1,6 @@ #include "env-inl.h" #include "node.h" +#include "node_external_reference.h" using v8::Context; using v8::FunctionCallbackInfo; @@ -77,6 +78,15 @@ void InitializeTypes(Local target, } } // anonymous namespace + +void RegisterTypesExternalReferences(ExternalReferenceRegistry* registry) { +#define V(type) registry->Register(Is##type); + VALUE_METHOD_MAP(V) +#undef V + + registry->Register(IsAnyArrayBuffer); + registry->Register(IsBoxedPrimitive); +} } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(types, node::InitializeTypes) diff --git a/src/node_url.cc b/src/node_url.cc index 27e89e8d9b7652..a9a720e3ac07cd 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1,6 +1,7 @@ #include "node_url.h" #include "base_object-inl.h" #include "node_errors.h" +#include "node_external_reference.h" #include "node_i18n.h" #include "util-inl.h" @@ -2333,6 +2334,15 @@ void Initialize(Local target, } } // namespace +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(Parse); + registry->Register(EncodeAuthSet); + registry->Register(ToUSVString); + registry->Register(DomainToASCII); + registry->Register(DomainToUnicode); + registry->Register(SetURLConstructor); +} + std::string URL::ToFilePath() const { if (context_.scheme != "file:") { return ""; diff --git a/src/node_util.cc b/src/node_util.cc index db9b8ec8d65f51..2de0aa204c4f1b 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -1,6 +1,7 @@ +#include "base_object-inl.h" #include "node_errors.h" +#include "node_external_reference.h" #include "util-inl.h" -#include "base_object-inl.h" namespace node { namespace util { @@ -263,6 +264,23 @@ static void GuessHandleType(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(OneByteString(env->isolate(), type)); } +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(GetHiddenValue); + registry->Register(SetHiddenValue); + registry->Register(GetPromiseDetails); + registry->Register(GetProxyDetails); + registry->Register(PreviewEntries); + registry->Register(GetOwnNonIndexProperties); + registry->Register(GetConstructorName); + registry->Register(Sleep); + registry->Register(ArrayBufferViewHasBuffer); + registry->Register(WeakReference::New); + registry->Register(WeakReference::Get); + registry->Register(WeakReference::IncRef); + registry->Register(WeakReference::DecRef); + registry->Register(GuessHandleType); +} + void Initialize(Local target, Local unused, Local context, diff --git a/src/string_decoder.cc b/src/string_decoder.cc index 6ec84e0e11ed31..39b464cc2806c7 100644 --- a/src/string_decoder.cc +++ b/src/string_decoder.cc @@ -3,6 +3,7 @@ #include "env-inl.h" #include "node_buffer.h" +#include "node_external_reference.h" #include "string_bytes.h" #include "util.h" @@ -322,6 +323,12 @@ void InitializeStringDecoder(Local target, } // anonymous namespace +void RegisterStringDecoderExternalReferences( + ExternalReferenceRegistry* registry) { + registry->Register(DecodeData); + registry->Register(FlushData); +} + } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(string_decoder, diff --git a/src/timers.cc b/src/timers.cc index fab1b12018a921..5c313e6f945c78 100644 --- a/src/timers.cc +++ b/src/timers.cc @@ -1,4 +1,5 @@ #include "env-inl.h" +#include "node_external_reference.h" #include "util-inl.h" #include "v8.h" @@ -57,9 +58,15 @@ void Initialize(Local target, FIXED_ONE_BYTE_STRING(env->isolate(), "immediateInfo"), env->immediate_info()->fields().GetJSArray()).Check(); } - - } // anonymous namespace +void RegisterTimerExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(GetLibuvNow); + registry->Register(SetupTimers); + registry->Register(ScheduleTimer); + registry->Register(ToggleTimerRef); + registry->Register(ToggleImmediateRef); +} + } // namespace node NODE_MODULE_CONTEXT_AWARE_INTERNAL(timers, node::Initialize) diff --git a/tools/snapshot/snapshot_builder.cc b/tools/snapshot/snapshot_builder.cc index a7d93d7ec81045..63a63fa1bdfba4 100644 --- a/tools/snapshot/snapshot_builder.cc +++ b/tools/snapshot/snapshot_builder.cc @@ -210,7 +210,7 @@ std::string SnapshotBuilder::Generate( env->PrintAllBaseObjects(); printf("Environment = %p\n", env); } - env->BootstrapInternalLoaders().ToLocalChecked(); + env->RunBootstrapping().ToLocalChecked(); env_info = env->Serialize(&creator); size_t index = creator.AddContext( context, {SerializeNodeContextInternalFields, env});