Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4dae68c

Browse files
joyeecheungmarco-ippolito
authored andcommitted
module: centralize SourceTextModule compilation for builtin loader
This refactors the code that compiles SourceTextModule for thebuilt-in ESM loader to use a common routine so that it's easierto customize cache handling for the ESM loader. In additionthis introduces a common symbol for import.meta and import()so that we don't need to create additional closures as handlers,since we can get all the information we need from the V8 callbackalready. This should reduce the memory footprint of ESM as well.PR-URL:#52291Backport-PR-URL:#53500Refs:#47472Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
1 parentcad46af commit4dae68c

File tree

7 files changed

+109
-91
lines changed

7 files changed

+109
-91
lines changed

‎lib/internal/modules/esm/create_dynamic_module.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ ${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')}
5555
${ArrayPrototypeJoin(ArrayPrototypeMap(exports,createExport),'\n')}
5656
import.meta.done();
5757
`;
58-
const{ModuleWrap}=internalBinding('module_wrap');
59-
constm=newModuleWrap(`${url}`,undefined,source,0,0);
58+
const{registerModule, compileSourceTextModule}=require('internal/modules/esm/utils');
59+
constm=compileSourceTextModule(`${url}`,source);
6060

6161
constreadyfns=newSafeSet();
6262
/**@type {DynamicModuleReflect} */
@@ -68,7 +68,6 @@ import.meta.done();
6868
if(imports.length){
6969
reflect.imports={__proto__:null};
7070
}
71-
const{ registerModule}=require('internal/modules/esm/utils');
7271
registerModule(m,{
7372
__proto__:null,
7473
initializeImportMeta:(meta,wrap)=>{

‎lib/internal/modules/esm/loader.js

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ const { getOptionValue } = require('internal/options');
2525
const{ isURL, pathToFileURL,URL}=require('internal/url');
2626
const{ emitExperimentalWarning, kEmptyObject}=require('internal/util');
2727
const{
28-
registerModule,
28+
compileSourceTextModule,
2929
getDefaultConditions,
3030
}=require('internal/modules/esm/utils');
3131
const{ kImplicitAssertType}=require('internal/modules/esm/assert');
32-
const{
33-
maybeCacheSourceMap,
34-
}=require('internal/source_map/source_map_cache');
3532
const{ canParse}=internalBinding('url');
3633
const{ ModuleWrap}=internalBinding('module_wrap');
3734
letdefaultResolve,defaultLoad,defaultLoadSync,importMetaInitializer;
@@ -193,16 +190,7 @@ class ModuleLoader {
193190

194191
asynceval(source,url){
195192
constevalInstance=(url)=>{
196-
constmodule=newModuleWrap(url,undefined,source,0,0);
197-
registerModule(module,{
198-
__proto__:null,
199-
initializeImportMeta:(meta,wrap)=>this.importMetaInitialize(meta,{ url}),
200-
importModuleDynamically:(specifier,{ url},importAttributes)=>{
201-
returnthis.import(specifier,url,importAttributes);
202-
},
203-
});
204-
205-
returnmodule;
193+
returncompileSourceTextModule(url,source,this);
206194
};
207195
const{ ModuleJob}=require('internal/modules/esm/module_job');
208196
constjob=newModuleJob(
@@ -273,26 +261,10 @@ class ModuleLoader {
273261
if(job!==undefined){
274262
returnjob.module.getNamespaceSync();
275263
}
276-
277264
// TODO(joyeecheung): refactor this so that we pre-parse in C++ and hit the
278265
// cache here, or use a carrier object to carry the compiled module script
279266
// into the constructor to ensure cache hit.
280-
constwrap=newModuleWrap(url,undefined,source,0,0);
281-
// Cache the source map for the module if present.
282-
if(wrap.sourceMapURL){
283-
maybeCacheSourceMap(url,source,null,false,undefined,wrap.sourceMapURL);
284-
}
285-
const{ registerModule}=require('internal/modules/esm/utils');
286-
// TODO(joyeecheung): refactor so that the default options are shared across
287-
// the built-in loaders.
288-
registerModule(wrap,{
289-
__proto__:null,
290-
initializeImportMeta:(meta,wrap)=>this.importMetaInitialize(meta,{ url}),
291-
importModuleDynamically:(specifier,wrap,importAttributes)=>{
292-
returnthis.import(specifier,url,importAttributes);
293-
},
294-
});
295-
267+
constwrap=compileSourceTextModule(url,source,this);
296268
constinspectBrk=(isMain&&getOptionValue('--inspect-brk'));
297269

298270
const{ ModuleJobSync}=require('internal/modules/esm/module_job');

‎lib/internal/modules/esm/translators.js

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,35 +156,13 @@ function errPath(url) {
156156
returnurl;
157157
}
158158

159-
/**
160-
* Dynamically imports a module using the ESM loader.
161-
*@param {string} specifier - The module specifier to import.
162-
*@param {object} options - An object containing options for the import.
163-
*@param {string} options.url - The URL of the module requesting the import.
164-
*@param {Record<string, string>} [attributes] - An object containing attributes for the import.
165-
*@returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} The imported module.
166-
*/
167-
asyncfunctionimportModuleDynamically(specifier,{ url},attributes){
168-
constcascadedLoader=require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
169-
returncascadedLoader.import(specifier,url,attributes);
170-
}
171-
172159
// Strategy for loading a standard JavaScript module.
173160
translators.set('module',functionmoduleStrategy(url,source,isMain){
174161
assertBufferSource(source,true,'load');
175162
source=stringify(source);
176163
debug(`Translating StandardModule${url}`);
177-
constmodule=newModuleWrap(url,undefined,source,0,0);
178-
// Cache the source map for the module if present.
179-
if(module.sourceMapURL){
180-
maybeCacheSourceMap(url,source,null,false,undefined,module.sourceMapURL);
181-
}
182-
const{ registerModule}=require('internal/modules/esm/utils');
183-
registerModule(module,{
184-
__proto__:null,
185-
initializeImportMeta:(meta,wrap)=>this.importMetaInitialize(meta,{ url}),
186-
importModuleDynamically,
187-
});
164+
const{ compileSourceTextModule}=require('internal/modules/esm/utils');
165+
constmodule=compileSourceTextModule(url,source,this);
188166
returnmodule;
189167
});
190168

‎lib/internal/modules/esm/utils.js

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@ const {
1313
},
1414
}=internalBinding('util');
1515
const{
16+
source_text_module_default_hdo,
1617
vm_dynamic_import_default_internal,
1718
vm_dynamic_import_main_context_default,
1819
vm_dynamic_import_missing_flag,
1920
vm_dynamic_import_no_callback,
2021
}=internalBinding('symbols');
2122

23+
const{ ModuleWrap}=internalBinding('module_wrap');
24+
const{
25+
maybeCacheSourceMap,
26+
}=require('internal/source_map/source_map_cache');
27+
2228
const{
2329
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG,
2430
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
@@ -167,28 +173,55 @@ function registerModule(referrer, registry) {
167173
moduleRegistries.set(idSymbol,registry);
168174
}
169175

176+
/**
177+
* Proxy the import meta handling to the default loader for source text modules.
178+
*@param {Record<string, string | Function>} meta - The import.meta object to initialize.
179+
*@param {ModuleWrap} wrap - The ModuleWrap of the SourceTextModule where `import.meta` is referenced.
180+
*/
181+
functiondefaultInitializeImportMetaForModule(meta,wrap){
182+
constcascadedLoader=require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
183+
returncascadedLoader.importMetaInitialize(meta,{url:wrap.url});
184+
}
185+
170186
/**
171187
* Defines the `import.meta` object for a given module.
172188
*@param {symbol} symbol - Reference to the module.
173189
*@param {Record<string, string | Function>} meta - The import.meta object to initialize.
190+
*@param {ModuleWrap} wrap - The ModuleWrap of the SourceTextModule where `import.meta` is referenced.
174191
*/
175-
functioninitializeImportMetaObject(symbol,meta){
176-
if(moduleRegistries.has(symbol)){
177-
const{ initializeImportMeta, callbackReferrer}=moduleRegistries.get(symbol);
178-
if(initializeImportMeta!==undefined){
179-
meta=initializeImportMeta(meta,callbackReferrer);
180-
}
192+
functioninitializeImportMetaObject(symbol,meta,wrap){
193+
if(symbol===source_text_module_default_hdo){
194+
defaultInitializeImportMetaForModule(meta,wrap);
195+
return;
196+
}
197+
constdata=moduleRegistries.get(symbol);
198+
assert(data,`import.meta registry not found for${wrap.url}`);
199+
const{ initializeImportMeta, callbackReferrer}=data;
200+
if(initializeImportMeta!==undefined){
201+
meta=initializeImportMeta(meta,callbackReferrer);
181202
}
182203
}
183204

184205
/**
185-
* Proxy the dynamic import to the default loader.
206+
* Proxy the dynamic import handling to the default loader for source text modules.
207+
*@param {string} specifier - The module specifier string.
208+
*@param {Record<string, string>} attributes - The import attributes object.
209+
*@param {string|null|undefined} referrerName - name of the referrer.
210+
*@returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} - The imported module object.
211+
*/
212+
functiondefaultImportModuleDynamicallyForModule(specifier,attributes,referrerName){
213+
constcascadedLoader=require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
214+
returncascadedLoader.import(specifier,referrerName,attributes);
215+
}
216+
217+
/**
218+
* Proxy the dynamic import to the default loader for classic scripts.
186219
*@param {string} specifier - The module specifier string.
187220
*@param {Record<string, string>} attributes - The import attributes object.
188221
*@param {string|null|undefined} referrerName - name of the referrer.
189222
*@returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} - The imported module object.
190223
*/
191-
functiondefaultImportModuleDynamically(specifier,attributes,referrerName){
224+
functiondefaultImportModuleDynamicallyForScript(specifier,attributes,referrerName){
192225
constparentURL=normalizeReferrerURL(referrerName);
193226
constcascadedLoader=require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
194227
returncascadedLoader.import(specifier,parentURL,attributes);
@@ -208,12 +241,16 @@ async function importModuleDynamicallyCallback(referrerSymbol, specifier, attrib
208241
// and fall back to the default loader.
209242
if(referrerSymbol===vm_dynamic_import_main_context_default){
210243
emitExperimentalWarning('vm.USE_MAIN_CONTEXT_DEFAULT_LOADER');
211-
returndefaultImportModuleDynamically(specifier,attributes,referrerName);
244+
returndefaultImportModuleDynamicallyForScript(specifier,attributes,referrerName);
212245
}
213246
// For script compiled internally that should use the default loader to handle dynamic
214247
// import, proxy the request to the default loader without the warning.
215248
if(referrerSymbol===vm_dynamic_import_default_internal){
216-
returndefaultImportModuleDynamically(specifier,attributes,referrerName);
249+
returndefaultImportModuleDynamicallyForScript(specifier,attributes,referrerName);
250+
}
251+
// For SourceTextModules compiled internally, proxy the request to the default loader.
252+
if(referrerSymbol===source_text_module_default_hdo){
253+
returndefaultImportModuleDynamicallyForModule(specifier,attributes,referrerName);
217254
}
218255

219256
if(moduleRegistries.has(referrerSymbol)){
@@ -288,6 +325,29 @@ async function initializeHooks() {
288325
return{__proto__:null, hooks, preloadScripts};
289326
}
290327

328+
/**
329+
* Compile a SourceTextModule for the built-in ESM loader. Register it for default
330+
* source map and import.meta and dynamic import() handling if cascadedLoader is provided.
331+
*@param {string} url URL of the module.
332+
*@param {string} source Source code of the module.
333+
*@param {typeof import('./loader.js').ModuleLoader|undefined} cascadedLoader If provided,
334+
* register the module for default handling.
335+
*@returns {ModuleWrap}
336+
*/
337+
functioncompileSourceTextModule(url,source,cascadedLoader){
338+
consthostDefinedOption=cascadedLoader ?source_text_module_default_hdo :undefined;
339+
constwrap=newModuleWrap(url,undefined,source,0,0,hostDefinedOption);
340+
341+
if(!cascadedLoader){
342+
returnwrap;
343+
}
344+
// Cache the source map for the module if present.
345+
if(wrap.sourceMapURL){
346+
maybeCacheSourceMap(url,source,null,false,undefined,wrap.sourceMapURL);
347+
}
348+
returnwrap;
349+
}
350+
291351
module.exports={
292352
registerModule,
293353
initializeESM,
@@ -296,4 +356,5 @@ module.exports = {
296356
getConditionsSet,
297357
loaderWorkerId:'internal/modules/esm/worker',
298358
forceDefaultLoader,
359+
compileSourceTextModule,
299360
};

‎lib/internal/vm/module.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,18 @@ class Module {
131131
importModuleDynamicallyWrap(options.importModuleDynamically) :
132132
undefined,
133133
};
134+
// This will take precedence over the referrer as the object being
135+
// passed into the callbacks.
136+
registry.callbackReferrer=this;
137+
const{ registerModule}=require('internal/modules/esm/utils');
138+
registerModule(this[kWrap],registry);
134139
}else{
135140
assert(syntheticEvaluationSteps);
136141
this[kWrap]=newModuleWrap(identifier,context,
137142
syntheticExportNames,
138143
syntheticEvaluationSteps);
139144
}
140145

141-
// This will take precedence over the referrer as the object being
142-
// passed into the callbacks.
143-
registry.callbackReferrer=this;
144-
const{ registerModule}=require('internal/modules/esm/utils');
145-
registerModule(this[kWrap],registry);
146-
147146
this[kContext]=context;
148147
}
149148

‎src/env_properties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
V(onpskexchange_symbol, "onpskexchange") \
4646
V(resource_symbol, "resource_symbol") \
4747
V(trigger_async_id_symbol, "trigger_async_id_symbol") \
48+
V(source_text_module_default_hdo, "source_text_module_default_hdo") \
4849
V(vm_dynamic_import_default_internal, "vm_dynamic_import_default_internal") \
4950
V(vm_dynamic_import_main_context_default, \
5051
"vm_dynamic_import_main_context_default") \

‎src/module_wrap.cc

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
102102
returnnullptr;
103103
}
104104

105-
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
106-
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
105+
// new ModuleWrap(url, context, source, lineOffset, columnOffset, cachedData)
106+
// new ModuleWrap(url, context, source, lineOffset, columOffset,
107+
// hostDefinedOption) new ModuleWrap(url, context, exportNames,
108+
// syntheticExecutionFunction)
107109
voidModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
108110
CHECK(args.IsConstructCall());
109111
CHECK_GE(args.Length(),3);
@@ -132,22 +134,36 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
132134
int column_offset =0;
133135

134136
bool synthetic = args[2]->IsArray();
137+
138+
Local<PrimitiveArray> host_defined_options =
139+
PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
140+
Local<Symbol> id_symbol;
135141
if (synthetic) {
136142
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
137143
CHECK(args[3]->IsFunction());
138144
}else {
139145
// new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
146+
// new ModuleWrap(url, context, source, lineOffset, columOffset,
147+
// hostDefinedOption)
140148
CHECK(args[2]->IsString());
141149
CHECK(args[3]->IsNumber());
142150
line_offset = args[3].As<Int32>()->Value();
143151
CHECK(args[4]->IsNumber());
144152
column_offset = args[4].As<Int32>()->Value();
145-
}
153+
if (args[5]->IsSymbol()) {
154+
id_symbol = args[5].As<Symbol>();
155+
}else {
156+
id_symbol =Symbol::New(isolate, url);
157+
}
158+
host_defined_options->Set(isolate, HostDefinedOptions::kID, id_symbol);
146159

147-
Local<PrimitiveArray> host_defined_options =
148-
PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
149-
Local<Symbol> id_symbol =Symbol::New(isolate, url);
150-
host_defined_options->Set(isolate, HostDefinedOptions::kID, id_symbol);
160+
if (that->SetPrivate(context,
161+
realm->isolate_data()->host_defined_option_symbol(),
162+
id_symbol)
163+
.IsNothing()) {
164+
return;
165+
}
166+
}
151167

152168
ShouldNotAbortOnUncaughtScopeno_abort_scope(realm->env());
153169
TryCatchScopetry_catch(realm->env());
@@ -173,8 +189,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
173189
SyntheticModuleEvaluationStepsCallback);
174190
}else {
175191
ScriptCompiler::CachedData* cached_data =nullptr;
176-
if (!args[5]->IsUndefined()) {
177-
CHECK(args[5]->IsArrayBufferView());
192+
if (args[5]->IsArrayBufferView()) {
178193
Local<ArrayBufferView> cached_data_buf = args[5].As<ArrayBufferView>();
179194
uint8_t* data =
180195
static_cast<uint8_t*>(cached_data_buf->Buffer()->Data());
@@ -237,13 +252,6 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
237252
return;
238253
}
239254

240-
if (that->SetPrivate(context,
241-
realm->isolate_data()->host_defined_option_symbol(),
242-
id_symbol)
243-
.IsNothing()) {
244-
return;
245-
}
246-
247255
// Use the extras object as an object whose GetCreationContext() will be the
248256
// original `context`, since the `Context` itself strictly speaking cannot
249257
// be stored in an internal field.
@@ -837,7 +845,7 @@ void ModuleWrap::HostInitializeImportMetaObjectCallback(
837845
return;
838846
}
839847
DCHECK(id->IsSymbol());
840-
Local<Value> args[] = {id, meta};
848+
Local<Value> args[] = {id, meta, wrap};
841849
TryCatchScopetry_catch(env);
842850
USE(callback->Call(
843851
context,Undefined(realm->isolate()),arraysize(args), args));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp