@@ -102,9 +102,17 @@ ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
102
102
return nullptr ;
103
103
}
104
104
105
- // new ModuleWrap(url, context, source, lineOffset, columnOffset, cachedData)
105
+ Local<PrimitiveArray> ModuleWrap::GetHostDefinedOptions (
106
+ Isolate* isolate, Local<Symbol> id_symbol) {
107
+ Local<PrimitiveArray> host_defined_options =
108
+ PrimitiveArray::New (isolate, HostDefinedOptions::kLength );
109
+ host_defined_options->Set (isolate, HostDefinedOptions::kID , id_symbol);
110
+ return host_defined_options;
111
+ }
112
+
113
+ // new ModuleWrap(url, context, source, lineOffset, columnOffset[, cachedData]);
106
114
// new ModuleWrap(url, context, source, lineOffset, columOffset,
107
- // hostDefinedOption)
115
+ // idSymbol);
108
116
// new ModuleWrap(url, context, exportNames, evaluationCallback[, cjsModule])
109
117
void ModuleWrap::New (const FunctionCallbackInfo<Value>& args) {
110
118
CHECK (args.IsConstructCall ());
@@ -143,9 +151,10 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
143
151
// cjsModule])
144
152
CHECK (args[3 ]->IsFunction ());
145
153
} else {
146
- // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
154
+ // new ModuleWrap(url, context, source, lineOffset, columOffset[,
155
+ // cachedData]);
147
156
// new ModuleWrap(url, context, source, lineOffset, columOffset,
148
- // hostDefinedOption)
157
+ // idSymbol);
149
158
CHECK (args[2 ]->IsString ());
150
159
CHECK (args[3 ]->IsNumber ());
151
160
line_offset = args[3 ].As <Int32>()->Value ();
@@ -159,7 +168,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
159
168
} else {
160
169
id_symbol = Symbol::New (isolate, url);
161
170
}
162
- host_defined_options-> Set (isolate, HostDefinedOptions:: kID , id_symbol);
171
+ host_defined_options = GetHostDefinedOptions (isolate, id_symbol);
163
172
164
173
if (that->SetPrivate (context,
165
174
realm->isolate_data ()->host_defined_option_symbol (),
@@ -192,50 +201,34 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
192
201
module = Module::CreateSyntheticModule (isolate, url, export_names,
193
202
SyntheticModuleEvaluationStepsCallback);
194
203
} else {
195
- ScriptCompiler::CachedData* cached_data = nullptr ;
196
- bool used_cache_from_user = false ;
204
+ // When we are compiling for the default loader, this will be
205
+ // std::nullopt, and CompileSourceTextModule() should use
206
+ // on-disk cache.
207
+ std::optional<v8::ScriptCompiler::CachedData*> user_cached_data;
208
+ if (id_symbol !=
209
+ realm->isolate_data ()->source_text_module_default_hdo ()) {
210
+ user_cached_data = nullptr ;
211
+ }
197
212
if (args[5 ]->IsArrayBufferView ()) {
198
- DCHECK (!can_use_builtin_cache); // We don't use this option internally.
199
- used_cache_from_user = true ;
213
+ CHECK (!can_use_builtin_cache); // We don't use this option internally.
200
214
Local<ArrayBufferView> cached_data_buf = args[5 ].As <ArrayBufferView>();
201
215
uint8_t * data =
202
216
static_cast <uint8_t *>(cached_data_buf->Buffer ()->Data ());
203
- cached_data =
217
+ user_cached_data =
204
218
new ScriptCompiler::CachedData (data + cached_data_buf->ByteOffset (),
205
219
cached_data_buf->ByteLength ());
206
220
}
207
-
208
221
Local<String> source_text = args[2 ].As <String>();
209
- ScriptOrigin origin (isolate,
210
- url,
211
- line_offset,
212
- column_offset,
213
- true , // is cross origin
214
- -1 , // script id
215
- Local<Value>(), // source map URL
216
- false , // is opaque (?)
217
- false , // is WASM
218
- true , // is ES Module
219
- host_defined_options);
220
-
221
- CompileCacheEntry* cache_entry = nullptr ;
222
- if (can_use_builtin_cache && realm->env ()->use_compile_cache ()) {
223
- cache_entry = realm->env ()->compile_cache_handler ()->GetOrInsert (
224
- source_text, url, CachedCodeType::kESM );
225
- }
226
- if (cache_entry != nullptr && cache_entry->cache != nullptr ) {
227
- // source will take ownership of cached_data.
228
- cached_data = cache_entry->CopyCache ();
229
- }
230
222
231
- ScriptCompiler::Source source (source_text, origin, cached_data);
232
- ScriptCompiler::CompileOptions options;
233
- if (source.GetCachedData () == nullptr ) {
234
- options = ScriptCompiler::kNoCompileOptions ;
235
- } else {
236
- options = ScriptCompiler::kConsumeCodeCache ;
237
- }
238
- if (!ScriptCompiler::CompileModule (isolate, &source, options)
223
+ bool cache_rejected = false ;
224
+ if (!CompileSourceTextModule (realm,
225
+ source_text,
226
+ url,
227
+ line_offset,
228
+ column_offset,
229
+ host_defined_options,
230
+ user_cached_data,
231
+ &cache_rejected)
239
232
.ToLocal (&module)) {
240
233
if (try_catch.HasCaught () && !try_catch.HasTerminated ()) {
241
234
CHECK (!try_catch.Message ().IsEmpty ());
@@ -249,18 +242,8 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
249
242
return ;
250
243
}
251
244
252
- bool cache_rejected = false ;
253
- if (options == ScriptCompiler::kConsumeCodeCache ) {
254
- cache_rejected = source.GetCachedData ()->rejected ;
255
- }
256
-
257
- if (cache_entry != nullptr ) {
258
- realm->env ()->compile_cache_handler ()->MaybeSave (
259
- cache_entry, module, cache_rejected);
260
- }
261
-
262
- // If the cache comes from builtin compile cache, fail silently.
263
- if (cache_rejected && used_cache_from_user) {
245
+ if (user_cached_data.has_value () && user_cached_data.value () != nullptr &&
246
+ cache_rejected) {
264
247
THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED (
265
248
realm, " cachedData buffer was rejected" );
266
249
try_catch.ReThrow ();
@@ -303,6 +286,71 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
303
286
args.GetReturnValue ().Set (that);
304
287
}
305
288
289
+ MaybeLocal<Module> ModuleWrap::CompileSourceTextModule (
290
+ Realm* realm,
291
+ Local<String> source_text,
292
+ Local<String> url,
293
+ int line_offset,
294
+ int column_offset,
295
+ Local<PrimitiveArray> host_defined_options,
296
+ std::optional<ScriptCompiler::CachedData*> user_cached_data,
297
+ bool * cache_rejected) {
298
+ Isolate* isolate = realm->isolate ();
299
+ EscapableHandleScope scope (isolate);
300
+ ScriptOrigin origin (isolate,
301
+ url,
302
+ line_offset,
303
+ column_offset,
304
+ true , // is cross origin
305
+ -1 , // script id
306
+ Local<Value>(), // source map URL
307
+ false , // is opaque (?)
308
+ false , // is WASM
309
+ true , // is ES Module
310
+ host_defined_options);
311
+ ScriptCompiler::CachedData* cached_data = nullptr ;
312
+ CompileCacheEntry* cache_entry = nullptr ;
313
+ // When compiling for the default loader, user_cached_data is std::nullptr.
314
+ // When compiling for vm.Module, it's either nullptr or a pointer to the
315
+ // cached data.
316
+ if (user_cached_data.has_value ()) {
317
+ cached_data = user_cached_data.value ();
318
+ } else if (realm->env ()->use_compile_cache ()) {
319
+ cache_entry = realm->env ()->compile_cache_handler ()->GetOrInsert (
320
+ source_text, url, CachedCodeType::kESM );
321
+ }
322
+
323
+ if (cache_entry != nullptr && cache_entry->cache != nullptr ) {
324
+ // source will take ownership of cached_data.
325
+ cached_data = cache_entry->CopyCache ();
326
+ }
327
+
328
+ ScriptCompiler::Source source (source_text, origin, cached_data);
329
+ ScriptCompiler::CompileOptions options;
330
+ if (cached_data == nullptr ) {
331
+ options = ScriptCompiler::kNoCompileOptions ;
332
+ } else {
333
+ options = ScriptCompiler::kConsumeCodeCache ;
334
+ }
335
+
336
+ Local<Module> module;
337
+ if (!ScriptCompiler::CompileModule (isolate, &source, options)
338
+ .ToLocal (&module)) {
339
+ return scope.EscapeMaybe (MaybeLocal<Module>());
340
+ }
341
+
342
+ if (options == ScriptCompiler::kConsumeCodeCache ) {
343
+ *cache_rejected = source.GetCachedData ()->rejected ;
344
+ }
345
+
346
+ if (cache_entry != nullptr ) {
347
+ realm->env ()->compile_cache_handler ()->MaybeSave (
348
+ cache_entry, module, *cache_rejected);
349
+ }
350
+
351
+ return scope.Escape (module);
352
+ }
353
+
306
354
static Local<Object> createImportAttributesContainer (
307
355
Realm* realm,
308
356
Isolate* isolate,
0 commit comments