@@ -142,9 +142,17 @@ v8::Maybe<bool> ModuleWrap::CheckUnsettledTopLevelAwait() {
142
142
return v8::Just (false );
143
143
}
144
144
145
- // new ModuleWrap(url, context, source, lineOffset, columnOffset, cachedData)
145
+ Local<PrimitiveArray> ModuleWrap::GetHostDefinedOptions (
146
+ Isolate* isolate, Local<Symbol> id_symbol) {
147
+ Local<PrimitiveArray> host_defined_options =
148
+ PrimitiveArray::New (isolate, HostDefinedOptions::kLength );
149
+ host_defined_options->Set (isolate, HostDefinedOptions::kID , id_symbol);
150
+ return host_defined_options;
151
+ }
152
+
153
+ // new ModuleWrap(url, context, source, lineOffset, columnOffset[, cachedData]);
146
154
// new ModuleWrap(url, context, source, lineOffset, columOffset,
147
- // hostDefinedOption)
155
+ // idSymbol);
148
156
// new ModuleWrap(url, context, exportNames, evaluationCallback[, cjsModule])
149
157
void ModuleWrap::New (const FunctionCallbackInfo<Value>& args) {
150
158
CHECK (args.IsConstructCall ());
@@ -183,9 +191,10 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
183
191
// cjsModule])
184
192
CHECK (args[3 ]->IsFunction ());
185
193
} else {
186
- // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
194
+ // new ModuleWrap(url, context, source, lineOffset, columOffset[,
195
+ // cachedData]);
187
196
// new ModuleWrap(url, context, source, lineOffset, columOffset,
188
- // hostDefinedOption)
197
+ // idSymbol);
189
198
CHECK (args[2 ]->IsString ());
190
199
CHECK (args[3 ]->IsNumber ());
191
200
line_offset = args[3 ].As <Int32>()->Value ();
@@ -199,7 +208,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
199
208
} else {
200
209
id_symbol = Symbol::New (isolate, url);
201
210
}
202
- host_defined_options-> Set (isolate, HostDefinedOptions:: kID , id_symbol);
211
+ host_defined_options = GetHostDefinedOptions (isolate, id_symbol);
203
212
204
213
if (that->SetPrivate (context,
205
214
realm->isolate_data ()->host_defined_option_symbol (),
@@ -234,50 +243,34 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
234
243
module = Module::CreateSyntheticModule (
235
244
isolate, url, span, SyntheticModuleEvaluationStepsCallback);
236
245
} else {
237
- ScriptCompiler::CachedData* cached_data = nullptr ;
238
- bool used_cache_from_user = false ;
246
+ // When we are compiling for the default loader, this will be
247
+ // std::nullopt, and CompileSourceTextModule() should use
248
+ // on-disk cache.
249
+ std::optional<v8::ScriptCompiler::CachedData*> user_cached_data;
250
+ if (id_symbol !=
251
+ realm->isolate_data ()->source_text_module_default_hdo ()) {
252
+ user_cached_data = nullptr ;
253
+ }
239
254
if (args[5 ]->IsArrayBufferView ()) {
240
- DCHECK (!can_use_builtin_cache); // We don't use this option internally.
241
- used_cache_from_user = true ;
255
+ CHECK (!can_use_builtin_cache); // We don't use this option internally.
242
256
Local<ArrayBufferView> cached_data_buf = args[5 ].As <ArrayBufferView>();
243
257
uint8_t * data =
244
258
static_cast <uint8_t *>(cached_data_buf->Buffer ()->Data ());
245
- cached_data =
259
+ user_cached_data =
246
260
new ScriptCompiler::CachedData (data + cached_data_buf->ByteOffset (),
247
261
cached_data_buf->ByteLength ());
248
262
}
249
-
250
263
Local<String> source_text = args[2 ].As <String>();
251
- ScriptOrigin origin (isolate,
252
- url,
253
- line_offset,
254
- column_offset,
255
- true , // is cross origin
256
- -1 , // script id
257
- Local<Value>(), // source map URL
258
- false , // is opaque (?)
259
- false , // is WASM
260
- true , // is ES Module
261
- host_defined_options);
262
-
263
- CompileCacheEntry* cache_entry = nullptr ;
264
- if (can_use_builtin_cache && realm->env ()->use_compile_cache ()) {
265
- cache_entry = realm->env ()->compile_cache_handler ()->GetOrInsert (
266
- source_text, url, CachedCodeType::kESM );
267
- }
268
- if (cache_entry != nullptr && cache_entry->cache != nullptr ) {
269
- // source will take ownership of cached_data.
270
- cached_data = cache_entry->CopyCache ();
271
- }
272
264
273
- ScriptCompiler::Source source (source_text, origin, cached_data);
274
- ScriptCompiler::CompileOptions options;
275
- if (source.GetCachedData () == nullptr ) {
276
- options = ScriptCompiler::kNoCompileOptions ;
277
- } else {
278
- options = ScriptCompiler::kConsumeCodeCache ;
279
- }
280
- if (!ScriptCompiler::CompileModule (isolate, &source, options)
265
+ bool cache_rejected = false ;
266
+ if (!CompileSourceTextModule (realm,
267
+ source_text,
268
+ url,
269
+ line_offset,
270
+ column_offset,
271
+ host_defined_options,
272
+ user_cached_data,
273
+ &cache_rejected)
281
274
.ToLocal (&module)) {
282
275
if (try_catch.HasCaught () && !try_catch.HasTerminated ()) {
283
276
CHECK (!try_catch.Message ().IsEmpty ());
@@ -291,18 +284,8 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
291
284
return ;
292
285
}
293
286
294
- bool cache_rejected = false ;
295
- if (options == ScriptCompiler::kConsumeCodeCache ) {
296
- cache_rejected = source.GetCachedData ()->rejected ;
297
- }
298
-
299
- if (cache_entry != nullptr ) {
300
- realm->env ()->compile_cache_handler ()->MaybeSave (
301
- cache_entry, module, cache_rejected);
302
- }
303
-
304
- // If the cache comes from builtin compile cache, fail silently.
305
- if (cache_rejected && used_cache_from_user) {
287
+ if (user_cached_data.has_value () && user_cached_data.value () != nullptr &&
288
+ cache_rejected) {
306
289
THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED (
307
290
realm, " cachedData buffer was rejected" );
308
291
try_catch.ReThrow ();
@@ -345,6 +328,71 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
345
328
args.GetReturnValue ().Set (that);
346
329
}
347
330
331
+ MaybeLocal<Module> ModuleWrap::CompileSourceTextModule (
332
+ Realm* realm,
333
+ Local<String> source_text,
334
+ Local<String> url,
335
+ int line_offset,
336
+ int column_offset,
337
+ Local<PrimitiveArray> host_defined_options,
338
+ std::optional<ScriptCompiler::CachedData*> user_cached_data,
339
+ bool * cache_rejected) {
340
+ Isolate* isolate = realm->isolate ();
341
+ EscapableHandleScope scope (isolate);
342
+ ScriptOrigin origin (isolate,
343
+ url,
344
+ line_offset,
345
+ column_offset,
346
+ true , // is cross origin
347
+ -1 , // script id
348
+ Local<Value>(), // source map URL
349
+ false , // is opaque (?)
350
+ false , // is WASM
351
+ true , // is ES Module
352
+ host_defined_options);
353
+ ScriptCompiler::CachedData* cached_data = nullptr ;
354
+ CompileCacheEntry* cache_entry = nullptr ;
355
+ // When compiling for the default loader, user_cached_data is std::nullptr.
356
+ // When compiling for vm.Module, it's either nullptr or a pointer to the
357
+ // cached data.
358
+ if (user_cached_data.has_value ()) {
359
+ cached_data = user_cached_data.value ();
360
+ } else if (realm->env ()->use_compile_cache ()) {
361
+ cache_entry = realm->env ()->compile_cache_handler ()->GetOrInsert (
362
+ source_text, url, CachedCodeType::kESM );
363
+ }
364
+
365
+ if (cache_entry != nullptr && cache_entry->cache != nullptr ) {
366
+ // source will take ownership of cached_data.
367
+ cached_data = cache_entry->CopyCache ();
368
+ }
369
+
370
+ ScriptCompiler::Source source (source_text, origin, cached_data);
371
+ ScriptCompiler::CompileOptions options;
372
+ if (cached_data == nullptr ) {
373
+ options = ScriptCompiler::kNoCompileOptions ;
374
+ } else {
375
+ options = ScriptCompiler::kConsumeCodeCache ;
376
+ }
377
+
378
+ Local<Module> module;
379
+ if (!ScriptCompiler::CompileModule (isolate, &source, options)
380
+ .ToLocal (&module)) {
381
+ return scope.EscapeMaybe (MaybeLocal<Module>());
382
+ }
383
+
384
+ if (options == ScriptCompiler::kConsumeCodeCache ) {
385
+ *cache_rejected = source.GetCachedData ()->rejected ;
386
+ }
387
+
388
+ if (cache_entry != nullptr ) {
389
+ realm->env ()->compile_cache_handler ()->MaybeSave (
390
+ cache_entry, module, *cache_rejected);
391
+ }
392
+
393
+ return scope.Escape (module);
394
+ }
395
+
348
396
static Local<Object> createImportAttributesContainer (
349
397
Realm* realm,
350
398
Isolate* isolate,
0 commit comments