@@ -103,29 +103,54 @@ void NativeModuleLoader::CompileCodeCache(
103
103
104
104
// TODO(joyeecheung): allow compiling cache for bootstrapper by
105
105
// switching on id
106
- Local<Value> result = CompileAsModule (env, *id, true );
106
+ MaybeLocal<Value> result =
107
+ CompileAsModule (env, *id, CompilationResultType::kCodeCache );
107
108
if (!result.IsEmpty ()) {
108
- args.GetReturnValue ().Set (result);
109
+ args.GetReturnValue ().Set (result. ToLocalChecked () );
109
110
}
110
111
}
111
112
112
113
void NativeModuleLoader::CompileFunction (
113
114
const FunctionCallbackInfo<Value>& args) {
114
115
Environment* env = Environment::GetCurrent (args);
115
-
116
116
CHECK (args[0 ]->IsString ());
117
117
node::Utf8Value id (env->isolate (), args[0 ].As <String>());
118
- Local<Value> result = CompileAsModule (env, *id, false );
118
+
119
+ MaybeLocal<Value> result =
120
+ CompileAsModule (env, *id, CompilationResultType::kFunction );
119
121
if (!result.IsEmpty ()) {
120
- args.GetReturnValue ().Set (result);
122
+ args.GetReturnValue ().Set (result. ToLocalChecked () );
121
123
}
122
124
}
123
125
124
- Local<Value> NativeModuleLoader::CompileAsModule (Environment* env,
125
- const char * id,
126
- bool produce_code_cache) {
126
+ // TODO(joyeecheung): it should be possible to generate the argument names
127
+ // from some special comments for the bootstrapper case.
128
+ MaybeLocal<Value> NativeModuleLoader::CompileAndCall (
129
+ Local<Context> context,
130
+ const char * id,
131
+ std::vector<Local<String>>* parameters,
132
+ std::vector<Local<Value>>* arguments,
133
+ Environment* optional_env) {
134
+ Isolate* isolate = context->GetIsolate ();
135
+ MaybeLocal<Value> compiled = per_process_loader.LookupAndCompile (
136
+ context, id, parameters, CompilationResultType::kFunction , nullptr );
137
+ if (compiled.IsEmpty ()) {
138
+ return compiled;
139
+ }
140
+ Local<Function> fn = compiled.ToLocalChecked ().As <Function>();
141
+ return fn->Call (
142
+ context, v8::Null (isolate), arguments->size (), arguments->data ());
143
+ }
144
+
145
+ MaybeLocal<Value> NativeModuleLoader::CompileAsModule (
146
+ Environment* env, const char * id, CompilationResultType result) {
147
+ std::vector<Local<String>> parameters = {env->exports_string (),
148
+ env->require_string (),
149
+ env->module_string (),
150
+ env->process_string (),
151
+ env->internal_binding_string ()};
127
152
return per_process_loader.LookupAndCompile (
128
- env->context (), id, produce_code_cache , env);
153
+ env->context (), id, ¶meters, result , env);
129
154
}
130
155
131
156
// Currently V8 only checks that the length of the source code is the
@@ -183,15 +208,18 @@ ScriptCompiler::CachedData* NativeModuleLoader::GetCachedData(
183
208
return new ScriptCompiler::CachedData (code_cache_value, code_cache_length);
184
209
}
185
210
186
- // Returns Local<Function> of the compiled module if produce_code_cache
211
+ // Returns Local<Function> of the compiled module if return_code_cache
187
212
// is false (we are only compiling the function).
188
213
// Otherwise return a Local<Object> containing the cache.
189
- Local<Value> NativeModuleLoader::LookupAndCompile (Local<Context> context,
190
- const char * id,
191
- bool produce_code_cache,
192
- Environment* optional_env) {
214
+ MaybeLocal<Value> NativeModuleLoader::LookupAndCompile (
215
+ Local<Context> context,
216
+ const char * id,
217
+ std::vector<Local<String>>* parameters,
218
+ CompilationResultType result_type,
219
+ Environment* optional_env) {
193
220
Isolate* isolate = context->GetIsolate ();
194
221
EscapableHandleScope scope (isolate);
222
+ Local<Value> ret; // Used to convert to MaybeLocal before return
195
223
196
224
Local<String> source = GetSource (isolate, id);
197
225
@@ -209,7 +237,7 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
209
237
// built with them.
210
238
// 2. If we are generating code cache for tools/general_code_cache.js, we
211
239
// are not going to use any cache ourselves.
212
- if (has_code_cache_ && !produce_code_cache ) {
240
+ if (has_code_cache_ && result_type == CompilationResultType:: kFunction ) {
213
241
cached_data = GetCachedData (id);
214
242
if (cached_data != nullptr ) {
215
243
use_cache = true ;
@@ -219,50 +247,33 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
219
247
ScriptCompiler::Source script_source (source, origin, cached_data);
220
248
221
249
ScriptCompiler::CompileOptions options;
222
- if (produce_code_cache ) {
250
+ if (result_type == CompilationResultType:: kCodeCache ) {
223
251
options = ScriptCompiler::kEagerCompile ;
224
252
} else if (use_cache) {
225
253
options = ScriptCompiler::kConsumeCodeCache ;
226
254
} else {
227
255
options = ScriptCompiler::kNoCompileOptions ;
228
256
}
229
257
230
- MaybeLocal<Function> maybe_fun;
231
- // Currently we assume if Environment is ready, then we must be compiling
232
- // native modules instead of bootstrappers.
233
- if (optional_env != nullptr ) {
234
- Local<String> parameters[] = {optional_env->exports_string (),
235
- optional_env->require_string (),
236
- optional_env->module_string (),
237
- optional_env->process_string (),
238
- optional_env->internal_binding_string ()};
239
- maybe_fun = ScriptCompiler::CompileFunctionInContext (context,
240
- &script_source,
241
- arraysize (parameters),
242
- parameters,
243
- 0 ,
244
- nullptr ,
245
- options);
246
- } else {
247
- // Until we migrate bootstrappers compilations here this is unreachable
248
- // TODO(joyeecheung): it should be possible to generate the argument names
249
- // from some special comments for the bootstrapper case.
250
- // Note that for bootstrappers we may not be able to get the argument
251
- // names as env->some_string() because we might be compiling before
252
- // those strings are initialized.
253
- UNREACHABLE ();
254
- }
258
+ MaybeLocal<Function> maybe_fun =
259
+ ScriptCompiler::CompileFunctionInContext (context,
260
+ &script_source,
261
+ parameters->size (),
262
+ parameters->data (),
263
+ 0 ,
264
+ nullptr ,
265
+ options);
255
266
256
- Local<Function> fun;
257
267
// This could fail when there are early errors in the native modules,
258
268
// e.g. the syntax errors
259
- if (maybe_fun.IsEmpty () || !maybe_fun. ToLocal (&fun) ) {
269
+ if (maybe_fun.IsEmpty ()) {
260
270
// In the case of early errors, v8 is already capable of
261
271
// decorating the stack for us - note that we use CompileFunctionInContext
262
272
// so there is no need to worry about wrappers.
263
- return scope. Escape (Local <Value>() );
273
+ return MaybeLocal <Value>();
264
274
}
265
275
276
+ Local<Function> fun = maybe_fun.ToLocalChecked ();
266
277
if (use_cache) {
267
278
if (optional_env != nullptr ) {
268
279
// This could happen when Node is run with any v8 flag, but
@@ -279,7 +290,7 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
279
290
}
280
291
}
281
292
282
- if (produce_code_cache ) {
293
+ if (result_type == CompilationResultType:: kCodeCache ) {
283
294
std::unique_ptr<ScriptCompiler::CachedData> cached_data (
284
295
ScriptCompiler::CreateCodeCacheForFunction (fun));
285
296
CHECK_NE (cached_data, nullptr );
@@ -296,10 +307,12 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
296
307
copied.release (),
297
308
cached_data_length,
298
309
ArrayBufferCreationMode::kInternalized );
299
- return scope. Escape ( Uint8Array::New (buf, 0 , cached_data_length) );
310
+ ret = Uint8Array::New (buf, 0 , cached_data_length);
300
311
} else {
301
- return scope. Escape ( fun) ;
312
+ ret = fun;
302
313
}
314
+
315
+ return scope.Escape (ret);
303
316
}
304
317
305
318
void NativeModuleLoader::Initialize (Local<Object> target,
0 commit comments