| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 45de8d1 commit 92311a0
13 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -778,6 +778,7 @@ void Environment::set_process_exit_handler( | |||
| 778 | 778 | #undef VY | |
| 779 | 779 | #undef VP | |
| 780 | 780 | ||
| 781 | + #define VM(PropertyName) V(PropertyName##_binding, v8::FunctionTemplate) | ||
| 781 | 782 | #define V(PropertyName, TypeName) \ | |
| 782 | 783 | inline v8::Local<TypeName> IsolateData::PropertyName() const { \ | |
| 783 | 784 | return PropertyName##_.Get(isolate_); \ | |
@@ -786,7 +787,9 @@ void Environment::set_process_exit_handler( | |||
| 786 | 787 | PropertyName##_.Set(isolate_, value); \ | |
| 787 | 788 | } | |
| 788 | 789 | PER_ISOLATE_TEMPLATE_PROPERTIES(V) | |
| 790 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) | ||
| 789 | 791 | #undef V | |
| 792 | + #undef VM | ||
| 790 | 793 | ||
| 791 | 794 | #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) | |
| 792 | 795 | #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -311,6 +311,7 @@ IsolateDataSerializeInfo IsolateData::Serialize(SnapshotCreator* creator) { | |||
| 311 | 311 | info.primitive_values.push_back(creator->AddData(async_wrap_provider(i))); | |
| 312 | 312 | ||
| 313 | 313 | uint32_t id = 0; | |
| 314 | + #define VM(PropertyName) V(PropertyName##_binding, FunctionTemplate) | ||
| 314 | 315 | #define V(PropertyName, TypeName) \ | |
| 315 | 316 | do { \ | |
| 316 | 317 | Local<TypeName> field = PropertyName(); \ | |
@@ -321,6 +322,7 @@ IsolateDataSerializeInfo IsolateData::Serialize(SnapshotCreator* creator) { | |||
| 321 | 322 | id++; \ | |
| 322 | 323 | } while (0); | |
| 323 | 324 | PER_ISOLATE_TEMPLATE_PROPERTIES(V) | |
| 325 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) | ||
| 324 | 326 | #undef V | |
| 325 | 327 | ||
| 326 | 328 | return info; | |
@@ -370,6 +372,7 @@ void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) { | |||
| 370 | 372 | const std::vector<PropInfo>& values = info->template_values; | |
| 371 | 373 | i = 0; // index to the array | |
| 372 | 374 | uint32_t id = 0; | |
| 375 | + #define VM(PropertyName) V(PropertyName##_binding, FunctionTemplate) | ||
| 373 | 376 | #define V(PropertyName, TypeName) \ | |
| 374 | 377 | do { \ | |
| 375 | 378 | if (values.size() > i && id == values[i].id) { \ | |
@@ -390,6 +393,7 @@ void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) { | |||
| 390 | 393 | } while (0); | |
| 391 | 394 | ||
| 392 | 395 | PER_ISOLATE_TEMPLATE_PROPERTIES(V); | |
| 396 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM); | ||
| 393 | 397 | #undef V | |
| 394 | 398 | } | |
| 395 | 399 | ||
@@ -456,12 +460,12 @@ void IsolateData::CreateProperties() { | |||
| 456 | 460 | NODE_ASYNC_PROVIDER_TYPES(V) | |
| 457 | 461 | #undef V | |
| 458 | 462 | ||
| 459 | - // TODO(legendecas): eagerly create per isolate templates. | ||
| 460 | 463 | Local<FunctionTemplate> templ = FunctionTemplate::New(isolate()); | |
| 461 | 464 | templ->InstanceTemplate()->SetInternalFieldCount( | |
| 462 | 465 | BaseObject::kInternalFieldCount); | |
| 463 | 466 | templ->Inherit(BaseObject::GetConstructorTemplate(this)); | |
| 464 | 467 | set_binding_data_ctor_template(templ); | |
| 468 | + binding::CreateInternalBindingTemplates(this); | ||
| 465 | 469 | ||
| 466 | 470 | contextify::ContextifyContext::InitializeGlobalTemplates(this); | |
| 467 | 471 | } | |
@@ -1585,30 +1589,13 @@ void Environment::PrintInfoForSnapshotIfDebug() { | |||
| 1585 | 1589 | if (enabled_debug_list()->enabled(DebugCategory::MKSNAPSHOT)) { | |
| 1586 | 1590 | fprintf(stderr, "At the exit of the Environment:\n"); | |
| 1587 | 1591 | principal_realm()->PrintInfoForSnapshot(); | |
| 1588 | - fprintf(stderr, "\nBuiltins without cache:\n"); | ||
| 1589 | - for (const auto& s : builtins_without_cache) { | ||
| 1590 | - fprintf(stderr, "%s\n", s.c_str()); | ||
| 1591 | - } | ||
| 1592 | - fprintf(stderr, "\nBuiltins with cache:\n"); | ||
| 1593 | - for (const auto& s : builtins_with_cache) { | ||
| 1594 | - fprintf(stderr, "%s\n", s.c_str()); | ||
| 1595 | - } | ||
| 1596 | - fprintf(stderr, "\nStatic bindings (need to be registered):\n"); | ||
| 1597 | - for (const auto mod : internal_bindings) { | ||
| 1598 | - fprintf(stderr, "%s:%s\n", mod->nm_filename, mod->nm_modname); | ||
| 1599 | - } | ||
| 1600 | 1592 | } | |
| 1601 | 1593 | } | |
| 1602 | 1594 | ||
| 1603 | 1595 | EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { | |
| 1604 | 1596 | EnvSerializeInfo info; | |
| 1605 | 1597 | Local<Context> ctx = context(); | |
| 1606 | 1598 | ||
| 1607 | - // Currently all modules are compiled without cache in builtin snapshot | ||
| 1608 | - // builder. | ||
| 1609 | - info.builtins = std::vector<std::string>(builtins_without_cache.begin(), | ||
| 1610 | - builtins_without_cache.end()); | ||
| 1611 | - | ||
| 1612 | 1599 | info.async_hooks = async_hooks_.Serialize(ctx, creator); | |
| 1613 | 1600 | info.immediate_info = immediate_info_.Serialize(ctx, creator); | |
| 1614 | 1601 | info.timeout_info = timeout_info_.Serialize(ctx, creator); | |
@@ -1660,7 +1647,6 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) { | |||
| 1660 | 1647 | ||
| 1661 | 1648 | RunDeserializeRequests(); | |
| 1662 | 1649 | ||
| 1663 | - builtins_in_snapshot = info->builtins; | ||
| 1664 | 1650 | async_hooks_.Deserialize(ctx); | |
| 1665 | 1651 | immediate_info_.Deserialize(ctx); | |
| 1666 | 1652 | timeout_info_.Deserialize(ctx); | |
@@ -1844,8 +1830,6 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const { | |||
| 1844 | 1830 | // Iteratable STLs have their own sizes subtracted from the parent | |
| 1845 | 1831 | // by default. | |
| 1846 | 1832 | tracker->TrackField("isolate_data", isolate_data_); | |
| 1847 | - tracker->TrackField("builtins_with_cache", builtins_with_cache); | ||
| 1848 | - tracker->TrackField("builtins_without_cache", builtins_without_cache); | ||
| 1849 | 1833 | tracker->TrackField("destroy_async_id_list", destroy_async_id_list_); | |
| 1850 | 1834 | tracker->TrackField("exec_argv", exec_argv_); | |
| 1851 | 1835 | tracker->TrackField("exiting", exiting_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -154,11 +154,14 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { | |||
| 154 | 154 | #undef VS | |
| 155 | 155 | #undef VP | |
| 156 | 156 | ||
| 157 | + #define VM(PropertyName) V(PropertyName##_binding, v8::FunctionTemplate) | ||
| 157 | 158 | #define V(PropertyName, TypeName) \ | |
| 158 | 159 | inline v8::Local<TypeName> PropertyName() const; \ | |
| 159 | 160 | inline void set_##PropertyName(v8::Local<TypeName> value); | |
| 160 | 161 | PER_ISOLATE_TEMPLATE_PROPERTIES(V) | |
| 162 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) | ||
| 161 | 163 | #undef V | |
| 164 | + #undef VM | ||
| 162 | 165 | ||
| 163 | 166 | inline v8::Local<v8::String> async_wrap_provider(int index) const; | |
| 164 | 167 | ||
@@ -178,15 +181,17 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { | |||
| 178 | 181 | #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) | |
| 179 | 182 | #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) | |
| 180 | 183 | #define VS(PropertyName, StringValue) V(v8::String, PropertyName) | |
| 184 | + #define VM(PropertyName) V(v8::FunctionTemplate, PropertyName##_binding) | ||
| 181 | 185 | #define VT(PropertyName, TypeName) V(TypeName, PropertyName) | |
| 182 | 186 | #define V(TypeName, PropertyName) \ | |
| 183 | 187 | v8::Eternal<TypeName> PropertyName ## _; | |
| 184 | 188 | PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) | |
| 185 | 189 | PER_ISOLATE_SYMBOL_PROPERTIES(VY) | |
| 186 | 190 | PER_ISOLATE_STRING_PROPERTIES(VS) | |
| 187 | 191 | PER_ISOLATE_TEMPLATE_PROPERTIES(VT) | |
| 192 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) | ||
| 188 | 193 | #undef V | |
| 189 | - #undef V | ||
| 194 | + #undef VM | ||
| 190 | 195 | #undef VT | |
| 191 | 196 | #undef VS | |
| 192 | 197 | #undef VY | |
@@ -456,7 +461,6 @@ struct DeserializeRequest { | |||
| 456 | 461 | }; | |
| 457 | 462 | ||
| 458 | 463 | struct EnvSerializeInfo { | |
| 459 | - std::vector<std::string> builtins; | ||
| 460 | 464 | AsyncHooks::SerializeInfo async_hooks; | |
| 461 | 465 | TickInfo::SerializeInfo tick_info; | |
| 462 | 466 | ImmediateInfo::SerializeInfo immediate_info; | |
@@ -691,13 +695,6 @@ class Environment : public MemoryRetainer { | |||
| 691 | 695 | // List of id's that have been destroyed and need the destroy() cb called. | |
| 692 | 696 | inline std::vector<double>* destroy_async_id_list(); | |
| 693 | 697 | ||
| 694 | - std::set<struct node_module*> internal_bindings; | ||
| 695 | - std::set<std::string> builtins_with_cache; | ||
| 696 | - std::set<std::string> builtins_without_cache; | ||
| 697 | - // This is only filled during deserialization. We use a vector since | ||
| 698 | - // it's only used for tests. | ||
| 699 | - std::vector<std::string> builtins_in_snapshot; | ||
| 700 | - | ||
| 701 | 698 | std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map; | |
| 702 | 699 | std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map; | |
| 703 | 700 | std::unordered_map<uint32_t, contextify::ContextifyScript*> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -110,6 +110,12 @@ | |||
| 110 | 110 | NODE_BUILTIN_BINDINGS(V) | |
| 111 | 111 | #undef V | |
| 112 | 112 | ||
| 113 | + #define V(modname) \ | ||
| 114 | + void _register_isolate_##modname(node::IsolateData* isolate_data, \ | ||
| 115 | + v8::Local<v8::FunctionTemplate> target); | ||
| 116 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) | ||
| 117 | + #undef V | ||
| 118 | + | ||
| 113 | 119 | #ifdef _AIX | |
| 114 | 120 | // On AIX, dlopen() behaves differently from other operating systems, in that | |
| 115 | 121 | // it returns unique values from each call, rather than identical values, when | |
@@ -237,9 +243,12 @@ static bool libc_may_be_musl() { return false; } | |||
| 237 | 243 | namespace node { | |
| 238 | 244 | ||
| 239 | 245 | using v8::Context; | |
| 246 | + using v8::EscapableHandleScope; | ||
| 240 | 247 | using v8::Exception; | |
| 241 | - using v8::Function; | ||
| 242 | 248 | using v8::FunctionCallbackInfo; | |
| 249 | + using v8::FunctionTemplate; | ||
| 250 | + using v8::HandleScope; | ||
| 251 | + using v8::Isolate; | ||
| 243 | 252 | using v8::Local; | |
| 244 | 253 | using v8::Object; | |
| 245 | 254 | using v8::String; | |
@@ -571,50 +580,86 @@ inline struct node_module* FindModule(struct node_module* list, | |||
| 571 | 580 | return mp; | |
| 572 | 581 | } | |
| 573 | 582 | ||
| 574 | - static Local<Object> InitInternalBinding(Environment* env, | ||
| 575 | - node_module* mod, | ||
| 576 | - Local<String> module) { | ||
| 577 | - // Internal bindings don't have a "module" object, only exports. | ||
| 578 | - Local<Function> ctor = env->binding_data_ctor_template() | ||
| 579 | - ->GetFunction(env->context()) | ||
| 580 | - .ToLocalChecked(); | ||
| 581 | - Local<Object> exports = ctor->NewInstance(env->context()).ToLocalChecked(); | ||
| 583 | + void CreateInternalBindingTemplates(IsolateData* isolate_data) { | ||
| 584 | + #define V(modname) \ | ||
| 585 | + do { \ | ||
| 586 | + Local<FunctionTemplate> templ = \ | ||
| 587 | + FunctionTemplate::New(isolate_data->isolate()); \ | ||
| 588 | + templ->InstanceTemplate()->SetInternalFieldCount( \ | ||
| 589 | + BaseObject::kInternalFieldCount); \ | ||
| 590 | + templ->Inherit(BaseObject::GetConstructorTemplate(isolate_data)); \ | ||
| 591 | + _register_isolate_##modname(isolate_data, templ); \ | ||
| 592 | + isolate_data->set_##modname##_binding(templ); \ | ||
| 593 | + } while (0); | ||
| 594 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) | ||
| 595 | + #undef V | ||
| 596 | + } | ||
| 597 | + | ||
| 598 | + static Local<Object> GetInternalBindingExportObject(IsolateData* isolate_data, | ||
| 599 | + const char* mod_name, | ||
| 600 | + Local<Context> context) { | ||
| 601 | + Local<FunctionTemplate> ctor; | ||
| 602 | + #define V(name) \ | ||
| 603 | + if (strcmp(mod_name, #name) == 0) { \ | ||
| 604 | + ctor = isolate_data->name##_binding(); \ | ||
| 605 | + } else // NOLINT(readability/braces) | ||
| 606 | + NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) | ||
| 607 | + #undef V | ||
| 608 | + { | ||
| 609 | + ctor = isolate_data->binding_data_ctor_template(); | ||
| 610 | + } | ||
| 611 | + | ||
| 612 | + Local<Object> obj = ctor->GetFunction(context) | ||
| 613 | + .ToLocalChecked() | ||
| 614 | + ->NewInstance(context) | ||
| 615 | + .ToLocalChecked(); | ||
| 616 | + return obj; | ||
| 617 | + } | ||
| 618 | + | ||
| 619 | + static Local<Object> InitInternalBinding(Realm* realm, node_module* mod) { | ||
| 620 | + EscapableHandleScope scope(realm->isolate()); | ||
| 621 | + Local<Context> context = realm->context(); | ||
| 622 | + Local<Object> exports = GetInternalBindingExportObject( | ||
| 623 | + realm->isolate_data(), mod->nm_modname, context); | ||
| 582 | 624 | CHECK_NULL(mod->nm_register_func); | |
| 583 | 625 | CHECK_NOT_NULL(mod->nm_context_register_func); | |
| 584 | - Local<Value> unused = Undefined(env->isolate()); | ||
| 585 | - mod->nm_context_register_func(exports, unused, env->context(), mod->nm_priv); | ||
| 586 | - return exports; | ||
| 626 | + Local<Value> unused = Undefined(realm->isolate()); | ||
| 627 | + // Internal bindings don't have a "module" object, only exports. | ||
| 628 | + mod->nm_context_register_func(exports, unused, context, mod->nm_priv); | ||
| 629 | + return scope.Escape(exports); | ||
| 587 | 630 | } | |
| 588 | 631 | ||
| 589 | 632 | void GetInternalBinding(const FunctionCallbackInfo<Value>& args) { | |
| 590 | - Environment* env = Environment::GetCurrent(args); | ||
| 633 | + Realm* realm = Realm::GetCurrent(args); | ||
| 634 | + Isolate* isolate = realm->isolate(); | ||
| 635 | + HandleScope scope(isolate); | ||
| 636 | + Local<Context> context = realm->context(); | ||
| 591 | 637 | ||
| 592 | 638 | CHECK(args[0]->IsString()); | |
| 593 | 639 | ||
| 594 | 640 | Local<String> module = args[0].As<String>(); | |
| 595 | - node::Utf8Value module_v(env->isolate(), module); | ||
| 641 | + node::Utf8Value module_v(isolate, module); | ||
| 596 | 642 | Local<Object> exports; | |
| 597 | 643 | ||
| 598 | 644 | node_module* mod = FindModule(modlist_internal, *module_v, NM_F_INTERNAL); | |
| 599 | 645 | if (mod != nullptr) { | |
| 600 | - exports = InitInternalBinding(env, mod, module); | ||
| 601 | - env->internal_bindings.insert(mod); | ||
| 646 | + exports = InitInternalBinding(realm, mod); | ||
| 647 | + realm->internal_bindings.insert(mod); | ||
| 602 | 648 | } else if (!strcmp(*module_v, "constants")) { | |
| 603 | - exports = Object::New(env->isolate()); | ||
| 604 | - CHECK( | ||
| 605 | - exports->SetPrototype(env->context(), Null(env->isolate())).FromJust()); | ||
| 606 | - DefineConstants(env->isolate(), exports); | ||
| 649 | + exports = Object::New(isolate); | ||
| 650 | + CHECK(exports->SetPrototype(context, Null(isolate)).FromJust()); | ||
| 651 | + DefineConstants(isolate, exports); | ||
| 607 | 652 | } else if (!strcmp(*module_v, "natives")) { | |
| 608 | - exports = builtins::BuiltinLoader::GetSourceObject(env->context()); | ||
| 653 | + exports = builtins::BuiltinLoader::GetSourceObject(context); | ||
| 609 | 654 | // Legacy feature: process.binding('natives').config contains stringified | |
| 610 | 655 | // config.gypi | |
| 611 | 656 | CHECK(exports | |
| 612 | - ->Set(env->context(), | ||
| 613 | - env->config_string(), | ||
| 614 | - builtins::BuiltinLoader::GetConfigString(env->isolate())) | ||
| 657 | + ->Set(context, | ||
| 658 | + realm->isolate_data()->config_string(), | ||
| 659 | + builtins::BuiltinLoader::GetConfigString(isolate)) | ||
| 615 | 660 | .FromJust()); | |
| 616 | 661 | } else { | |
| 617 | - return THROW_ERR_INVALID_MODULE(env, "No such binding: %s", *module_v); | ||
| 662 | + return THROW_ERR_INVALID_MODULE(isolate, "No such binding: %s", *module_v); | ||
| 618 | 663 | } | |
| 619 | 664 | ||
| 620 | 665 | args.GetReturnValue().Set(exports); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,8 @@ static_assert(static_cast<int>(NM_F_LINKED) == | |||
| 24 | 24 | static_cast<int>(node::ModuleFlags::kLinked), | |
| 25 | 25 | "NM_F_LINKED != node::ModuleFlags::kLinked"); | |
| 26 | 26 | ||
| 27 | + #define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) V(builtins) | ||
| 28 | + | ||
| 27 | 29 | #define NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \ | |
| 28 | 30 | static node::node_module _module = { \ | |
| 29 | 31 | NODE_MODULE_VERSION, \ | |
@@ -51,9 +53,20 @@ node::addon_context_register_func get_node_api_context_register_func( | |||
| 51 | 53 | ||
| 52 | 54 | namespace node { | |
| 53 | 55 | ||
| 56 | + // Define a node internal binding that may be loaded in a context of | ||
| 57 | + // a node::Environment. | ||
| 58 | + // If an internal binding needs initializing per-isolate templates, define | ||
| 59 | + // with NODE_BINDING_PER_ISOLATE_INIT too. | ||
| 54 | 60 | #define NODE_BINDING_CONTEXT_AWARE_INTERNAL(modname, regfunc) \ | |
| 55 | 61 | NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_INTERNAL) | |
| 56 | 62 | ||
| 63 | + // Define a per-isolate initialization function for a node internal binding. | ||
| 64 | + #define NODE_BINDING_PER_ISOLATE_INIT(modname, per_isolate_func) \ | ||
| 65 | + void _register_isolate_##modname(node::IsolateData* isolate_data, \ | ||
| 66 | + v8::Local<v8::FunctionTemplate> target) { \ | ||
| 67 | + per_isolate_func(isolate_data, target); \ | ||
| 68 | + } | ||
| 69 | + | ||
| 57 | 70 | // Globals per process | |
| 58 | 71 | // This is set by node::Init() which is used by embedders | |
| 59 | 72 | extern bool node_is_initialized; | |
@@ -94,6 +107,8 @@ class DLib { | |||
| 94 | 107 | // use the __attribute__((constructor)). Need to | |
| 95 | 108 | // explicitly call the _register* functions. | |
| 96 | 109 | void RegisterBuiltinBindings(); | |
| 110 | + // Create per-isolate templates for the internal bindings. | ||
| 111 | + void CreateInternalBindingTemplates(IsolateData* isolate_data); | ||
| 97 | 112 | void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 98 | 113 | void GetLinkedBinding(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 99 | 114 | void DLOpen(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments