| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5e42651 commit 6291c10
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // This benchmarks compiling scripts that hit the in-isolate compilation | ||
| 4 | + // cache (by having the same source). | ||
| 5 | + const common = require('../common.js'); | ||
| 6 | + const fs = require('fs'); | ||
| 7 | + const vm = require('vm'); | ||
| 8 | + const fixtures = require('../../test/common/fixtures.js'); | ||
| 9 | + const scriptPath = fixtures.path('snapshot', 'typescript.js'); | ||
| 10 | + | ||
| 11 | + const bench = common.createBenchmark(main, { | ||
| 12 | + type: ['with-dynamic-import-callback', 'without-dynamic-import-callback'], | ||
| 13 | + n: [100], | ||
| 14 | + }); | ||
| 15 | + | ||
| 16 | + const scriptSource = fs.readFileSync(scriptPath, 'utf8'); | ||
| 17 | + | ||
| 18 | + function main({ n, type }) { | ||
| 19 | + let script; | ||
| 20 | + bench.start(); | ||
| 21 | + const options = {}; | ||
| 22 | + switch (type) { | ||
| 23 | + case 'with-dynamic-import-callback': | ||
| 24 | + // Use a dummy callback for now until we really need to benchmark it. | ||
| 25 | + options.importModuleDynamically = async () => {}; | ||
| 26 | + break; | ||
| 27 | + case 'without-dynamic-import-callback': | ||
| 28 | + break; | ||
| 29 | + } | ||
| 30 | + for (let i = 0; i < n; i++) { | ||
| 31 | + script = new vm.Script(scriptSource, options); | ||
| 32 | + } | ||
| 33 | + bench.end(n); | ||
| 34 | + script.runInThisContext(); | ||
| 35 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,10 @@ const { | |||
| 12 | 12 | host_defined_option_symbol, | |
| 13 | 13 | }, | |
| 14 | 14 | } = internalBinding('util'); | |
| 15 | + const { | ||
| 16 | + default_host_defined_options, | ||
| 17 | + } = internalBinding('symbols'); | ||
| 18 | + | ||
| 15 | 19 | const { | |
| 16 | 20 | ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, | |
| 17 | 21 | ERR_INVALID_ARG_VALUE, | |
@@ -128,6 +132,13 @@ const moduleRegistries = new SafeWeakMap(); | |||
| 128 | 132 | */ | |
| 129 | 133 | function registerModule(referrer, registry) { | |
| 130 | 134 | const idSymbol = referrer[host_defined_option_symbol]; | |
| 135 | + if (idSymbol === default_host_defined_options) { | ||
| 136 | + // The referrer is compiled without custom callbacks, so there is | ||
| 137 | + // no registry to hold on to. We'll throw | ||
| 138 | + // ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING when a callback is | ||
| 139 | + // needed. | ||
| 140 | + return; | ||
| 141 | + } | ||
| 131 | 142 | // To prevent it from being GC'ed. | |
| 132 | 143 | registry.callbackReferrer ??= referrer; | |
| 133 | 144 | moduleRegistries.set(idSymbol, registry); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -87,6 +87,12 @@ class Script extends ContextifyScript { | |||
| 87 | 87 | } | |
| 88 | 88 | validateBoolean(produceCachedData, 'options.produceCachedData'); | |
| 89 | 89 | ||
| 90 | + if (importModuleDynamically !== undefined) { | ||
| 91 | + // Check that it's either undefined or a function before we pass | ||
| 92 | + // it into the native constructor. | ||
| 93 | + validateFunction(importModuleDynamically, | ||
| 94 | + 'options.importModuleDynamically'); | ||
| 95 | + } | ||
| 90 | 96 | // Calling `ReThrow()` on a native TryCatch does not generate a new | |
| 91 | 97 | // abort-on-uncaught-exception check. A dummy try/catch in JS land | |
| 92 | 98 | // protects against that. | |
@@ -97,14 +103,13 @@ class Script extends ContextifyScript { | |||
| 97 | 103 | columnOffset, | |
| 98 | 104 | cachedData, | |
| 99 | 105 | produceCachedData, | |
| 100 | - parsingContext); | ||
| 106 | + parsingContext, | ||
| 107 | + importModuleDynamically !== undefined); | ||
| 101 | 108 | } catch (e) { | |
| 102 | 109 | throw e; /* node-do-not-add-exception-line */ | |
| 103 | 110 | } | |
| 104 | 111 | ||
| 105 | 112 | if (importModuleDynamically !== undefined) { | |
| 106 | - validateFunction(importModuleDynamically, | ||
| 107 | - 'options.importModuleDynamically'); | ||
| 108 | 113 | const { importModuleDynamicallyWrap } = require('internal/vm/module'); | |
| 109 | 114 | const { registerModule } = require('internal/modules/esm/utils'); | |
| 110 | 115 | registerModule(this, { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,6 +31,7 @@ | |||
| 31 | 31 | // Symbols are per-isolate primitives but Environment proxies them | |
| 32 | 32 | // for the sake of convenience. | |
| 33 | 33 | #define PER_ISOLATE_SYMBOL_PROPERTIES(V) \ | |
| 34 | + V(default_host_defined_options, "default_host_defined_options") \ | ||
| 34 | 35 | V(fs_use_promises_symbol, "fs_use_promises_symbol") \ | |
| 35 | 36 | V(async_id_symbol, "async_id_symbol") \ | |
| 36 | 37 | V(handle_onclose_symbol, "handle_onclose") \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -787,10 +787,12 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) { | |||
| 787 | 787 | bool produce_cached_data = false; | |
| 788 | 788 | Local<Context> parsing_context = context; | |
| 789 | 789 | ||
| 790 | + bool needs_custom_host_defined_options = false; | ||
| 790 | 791 | if (argc > 2) { | |
| 791 | 792 | // new ContextifyScript(code, filename, lineOffset, columnOffset, | |
| 792 | - // cachedData, produceCachedData, parsingContext) | ||
| 793 | - CHECK_EQ(argc, 7); | ||
| 793 | + // cachedData, produceCachedData, parsingContext, | ||
| 794 | + // needsCustomHostDefinedOptions) | ||
| 795 | + CHECK_EQ(argc, 8); | ||
| 794 | 796 | CHECK(args[2]->IsNumber()); | |
| 795 | 797 | line_offset = args[2].As<Int32>()->Value(); | |
| 796 | 798 | CHECK(args[3]->IsNumber()); | |
@@ -809,6 +811,9 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) { | |||
| 809 | 811 | CHECK_NOT_NULL(sandbox); | |
| 810 | 812 | parsing_context = sandbox->context(); | |
| 811 | 813 | } | |
| 814 | + if (args[7]->IsTrue()) { | ||
| 815 | + needs_custom_host_defined_options = true; | ||
| 816 | + } | ||
| 812 | 817 | } | |
| 813 | 818 | ||
| 814 | 819 | ContextifyScript* contextify_script = | |
@@ -832,7 +837,12 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) { | |||
| 832 | 837 | ||
| 833 | 838 | Local<PrimitiveArray> host_defined_options = | |
| 834 | 839 | PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); | |
| 835 | - Local<Symbol> id_symbol = Symbol::New(isolate, filename); | ||
| 840 | + // We need a default host defined options that's the same for all scripts | ||
| 841 | + // not needing custom module callbacks for so that the isolate compilation | ||
| 842 | + // cache can be hit. | ||
| 843 | + Local<Symbol> id_symbol = needs_custom_host_defined_options | ||
| 844 | + ? Symbol::New(isolate, filename) | ||
| 845 | + : env->default_host_defined_options(); | ||
| 836 | 846 | host_defined_options->Set( | |
| 837 | 847 | isolate, loader::HostDefinedOptions::kID, id_symbol); | |
| 838 | 848 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + require('../common'); | ||
| 4 | + const { Script } = require('vm'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + assert.rejects(async () => { | ||
| 8 | + const script = new Script('import("fs")'); | ||
| 9 | + const imported = script.runInThisContext(); | ||
| 10 | + await imported; | ||
| 11 | + }, { | ||
| 12 | + code: 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING' | ||
| 13 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments