@@ -103,29 +103,54 @@ void NativeModuleLoader::CompileCodeCache(
103103
104104 // TODO(joyeecheung): allow compiling cache for bootstrapper by
105105 // switching on id
106- Local<Value> result = CompileAsModule (env, *id, true );
106+ MaybeLocal<Value> result =
107+ CompileAsModule (env, *id, CompilationResultType::kCodeCache );
107108 if (!result.IsEmpty ()) {
108- args.GetReturnValue ().Set (result);
109+ args.GetReturnValue ().Set (result. ToLocalChecked () );
109110 }
110111}
111112
112113void NativeModuleLoader::CompileFunction (
113114 const FunctionCallbackInfo<Value>& args) {
114115 Environment* env = Environment::GetCurrent (args);
115-
116116 CHECK (args[0 ]->IsString ());
117117 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 );
119121 if (!result.IsEmpty ()) {
120- args.GetReturnValue ().Set (result);
122+ args.GetReturnValue ().Set (result. ToLocalChecked () );
121123 }
122124}
123125
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 ()};
127152 return per_process_loader.LookupAndCompile (
128- env->context (), id, produce_code_cache , env);
153+ env->context (), id, ¶meters, result , env);
129154}
130155
131156// Currently V8 only checks that the length of the source code is the
@@ -183,15 +208,18 @@ ScriptCompiler::CachedData* NativeModuleLoader::GetCachedData(
183208 return new ScriptCompiler::CachedData (code_cache_value, code_cache_length);
184209}
185210
186- // Returns Local<Function> of the compiled module if produce_code_cache
211+ // Returns Local<Function> of the compiled module if return_code_cache
187212// is false (we are only compiling the function).
188213// 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) {
193220 Isolate* isolate = context->GetIsolate ();
194221 EscapableHandleScope scope (isolate);
222+ Local<Value> ret; // Used to convert to MaybeLocal before return
195223
196224 Local<String> source = GetSource (isolate, id);
197225
@@ -209,7 +237,7 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
209237 // built with them.
210238 // 2. If we are generating code cache for tools/general_code_cache.js, we
211239 // 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 ) {
213241 cached_data = GetCachedData (id);
214242 if (cached_data != nullptr ) {
215243 use_cache = true ;
@@ -219,50 +247,33 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
219247 ScriptCompiler::Source script_source (source, origin, cached_data);
220248
221249 ScriptCompiler::CompileOptions options;
222- if (produce_code_cache ) {
250+ if (result_type == CompilationResultType:: kCodeCache ) {
223251 options = ScriptCompiler::kEagerCompile ;
224252 } else if (use_cache) {
225253 options = ScriptCompiler::kConsumeCodeCache ;
226254 } else {
227255 options = ScriptCompiler::kNoCompileOptions ;
228256 }
229257
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);
255266
256- Local<Function> fun;
257267 // This could fail when there are early errors in the native modules,
258268 // e.g. the syntax errors
259- if (maybe_fun.IsEmpty () || !maybe_fun. ToLocal (&fun) ) {
269+ if (maybe_fun.IsEmpty ()) {
260270 // In the case of early errors, v8 is already capable of
261271 // decorating the stack for us - note that we use CompileFunctionInContext
262272 // so there is no need to worry about wrappers.
263- return scope. Escape (Local <Value>() );
273+ return MaybeLocal <Value>();
264274 }
265275
276+ Local<Function> fun = maybe_fun.ToLocalChecked ();
266277 if (use_cache) {
267278 if (optional_env != nullptr ) {
268279 // This could happen when Node is run with any v8 flag, but
@@ -279,7 +290,7 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
279290 }
280291 }
281292
282- if (produce_code_cache ) {
293+ if (result_type == CompilationResultType:: kCodeCache ) {
283294 std::unique_ptr<ScriptCompiler::CachedData> cached_data (
284295 ScriptCompiler::CreateCodeCacheForFunction (fun));
285296 CHECK_NE (cached_data, nullptr );
@@ -296,10 +307,12 @@ Local<Value> NativeModuleLoader::LookupAndCompile(Local<Context> context,
296307 copied.release (),
297308 cached_data_length,
298309 ArrayBufferCreationMode::kInternalized );
299- return scope. Escape ( Uint8Array::New (buf, 0 , cached_data_length) );
310+ ret = Uint8Array::New (buf, 0 , cached_data_length);
300311 } else {
301- return scope. Escape ( fun) ;
312+ ret = fun;
302313 }
314+
315+ return scope.Escape (ret);
303316}
304317
305318void NativeModuleLoader::Initialize (Local<Object> target,
0 commit comments