Skip to content

Commit 370d044

Browse files
committed
src: improve CompileFunctionAndCacheResult error handling
1 parent d2a1369 commit 370d044

File tree

4 files changed

+87
-67
lines changed

4 files changed

+87
-67
lines changed

src/node_contextify.cc

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,11 @@ void ContextifyContext::CreatePerIsolateProperties(
365365
IsolateData* isolate_data, Local<ObjectTemplate> target) {
366366
Isolate* isolate = isolate_data->isolate();
367367
SetMethod(isolate, target, "makeContext", MakeContext);
368-
SetMethod(isolate, target, "compileFunction", CompileFunction);
369368
}
370369

371370
void ContextifyContext::RegisterExternalReferences(
372371
ExternalReferenceRegistry* registry) {
373372
registry->Register(MakeContext);
374-
registry->Register(CompileFunction);
375373
registry->Register(PropertyQueryCallback);
376374
registry->Register(PropertyGetterCallback);
377375
registry->Register(PropertySetterCallback);
@@ -1163,22 +1161,6 @@ Maybe<void> StoreCodeCacheResult(
11631161
return JustVoid();
11641162
}
11651163

1166-
// TODO(RaisinTen): Reuse in ContextifyContext::CompileFunction().
1167-
MaybeLocal<Function> CompileFunction(Local<Context> context,
1168-
Local<String> filename,
1169-
Local<String> content,
1170-
LocalVector<String>* parameters) {
1171-
ScriptOrigin script_origin(filename, 0, 0, true);
1172-
ScriptCompiler::Source script_source(content, script_origin);
1173-
1174-
return ScriptCompiler::CompileFunction(context,
1175-
&script_source,
1176-
parameters->size(),
1177-
parameters->data(),
1178-
0,
1179-
nullptr);
1180-
}
1181-
11821164
bool ContextifyScript::InstanceOf(Environment* env,
11831165
const Local<Value>& value) {
11841166
return !value.IsEmpty() &&
@@ -1392,7 +1374,19 @@ ContextifyScript::ContextifyScript(Environment* env, Local<Object> object) {
13921374

13931375
ContextifyScript::~ContextifyScript() {}
13941376

1395-
void ContextifyContext::CompileFunction(
1377+
void ContextifyFunction::RegisterExternalReferences(
1378+
ExternalReferenceRegistry* registry) {
1379+
registry->Register(CompileFunction);
1380+
}
1381+
1382+
void ContextifyFunction::CreatePerIsolateProperties(
1383+
IsolateData* isolate_data, Local<ObjectTemplate> target) {
1384+
Isolate* isolate = isolate_data->isolate();
1385+
1386+
SetMethod(isolate, target, "compileFunction", CompileFunction);
1387+
}
1388+
1389+
void ContextifyFunction::CompileFunction(
13961390
const FunctionCallbackInfo<Value>& args) {
13971391
Environment* env = Environment::GetCurrent(args);
13981392
Isolate* isolate = env->isolate();
@@ -1511,24 +1505,22 @@ void ContextifyContext::CompileFunction(
15111505
}
15121506

15131507
TryCatchScope try_catch(env);
1514-
Local<Object> result = CompileFunctionAndCacheResult(env,
1515-
parsing_context,
1516-
&source,
1517-
params,
1518-
context_extensions,
1519-
options,
1520-
produce_cached_data,
1521-
id_symbol,
1522-
try_catch);
1523-
1524-
if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
1508+
MaybeLocal<Object> maybe_result =
1509+
CompileFunctionAndCacheResult(env,
1510+
parsing_context,
1511+
&source,
1512+
params,
1513+
context_extensions,
1514+
options,
1515+
produce_cached_data,
1516+
id_symbol,
1517+
try_catch);
1518+
Local<Object> result;
1519+
if (!maybe_result.ToLocal(&result)) {
1520+
CHECK(try_catch.HasCaught());
15251521
try_catch.ReThrow();
15261522
return;
15271523
}
1528-
1529-
if (result.IsEmpty()) {
1530-
return;
1531-
}
15321524
args.GetReturnValue().Set(result);
15331525
}
15341526

@@ -1544,7 +1536,7 @@ static LocalVector<String> GetCJSParameters(IsolateData* data) {
15441536
return result;
15451537
}
15461538

1547-
Local<Object> ContextifyContext::CompileFunctionAndCacheResult(
1539+
MaybeLocal<Object> ContextifyFunction::CompileFunctionAndCacheResult(
15481540
Environment* env,
15491541
Local<Context> parsing_context,
15501542
ScriptCompiler::Source* source,
@@ -1566,28 +1558,29 @@ Local<Object> ContextifyContext::CompileFunctionAndCacheResult(
15661558

15671559
Local<Function> fn;
15681560
if (!maybe_fn.ToLocal(&fn)) {
1569-
if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
1561+
CHECK(try_catch.HasCaught());
1562+
if (!try_catch.HasTerminated()) {
15701563
errors::DecorateErrorStack(env, try_catch);
1571-
return Object::New(env->isolate());
15721564
}
1565+
return {};
15731566
}
15741567

15751568
Local<Context> context = env->context();
15761569
if (fn->SetPrivate(context, env->host_defined_option_symbol(), id_symbol)
15771570
.IsNothing()) {
1578-
return Object::New(env->isolate());
1571+
return {};
15791572
}
15801573

15811574
Isolate* isolate = env->isolate();
15821575
Local<Object> result = Object::New(isolate);
15831576
if (result->Set(parsing_context, env->function_string(), fn).IsNothing())
1584-
return Object::New(env->isolate());
1577+
return {};
15851578
if (result
15861579
->Set(parsing_context,
15871580
env->source_map_url_string(),
15881581
fn->GetScriptOrigin().SourceMapUrl())
15891582
.IsNothing())
1590-
return Object::New(env->isolate());
1583+
return {};
15911584

15921585
std::unique_ptr<ScriptCompiler::CachedData> new_cached_data;
15931586
if (produce_cached_data) {
@@ -1600,7 +1593,7 @@ Local<Object> ContextifyContext::CompileFunctionAndCacheResult(
16001593
produce_cached_data,
16011594
std::move(new_cached_data))
16021595
.IsNothing()) {
1603-
return Object::New(env->isolate());
1596+
return {};
16041597
}
16051598

16061599
return result;
@@ -1974,6 +1967,7 @@ void CreatePerIsolateProperties(IsolateData* isolate_data,
19741967

19751968
ContextifyContext::CreatePerIsolateProperties(isolate_data, target);
19761969
ContextifyScript::CreatePerIsolateProperties(isolate_data, target);
1970+
ContextifyFunction::CreatePerIsolateProperties(isolate_data, target);
19771971

19781972
SetMethod(isolate, target, "startSigintWatchdog", StartSigintWatchdog);
19791973
SetMethod(isolate, target, "stopSigintWatchdog", StopSigintWatchdog);
@@ -2026,6 +2020,7 @@ static void CreatePerContextProperties(Local<Object> target,
20262020
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
20272021
ContextifyContext::RegisterExternalReferences(registry);
20282022
ContextifyScript::RegisterExternalReferences(registry);
2023+
ContextifyFunction::RegisterExternalReferences(registry);
20292024

20302025
registry->Register(CompileFunctionForCJSLoader);
20312026
registry->Register(StartSigintWatchdog);

src/node_contextify.h

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,6 @@ class ContextifyContext final : CPPGC_MIXIN(ContextifyContext) {
144144
static bool IsStillInitializing(const ContextifyContext* ctx);
145145
static void MakeContext(const v8::FunctionCallbackInfo<v8::Value>& args);
146146
static void IsContext(const v8::FunctionCallbackInfo<v8::Value>& args);
147-
static void CompileFunction(
148-
const v8::FunctionCallbackInfo<v8::Value>& args);
149-
static v8::Local<v8::Object> CompileFunctionAndCacheResult(
150-
Environment* env,
151-
v8::Local<v8::Context> parsing_context,
152-
v8::ScriptCompiler::Source* source,
153-
v8::LocalVector<v8::String> params,
154-
v8::LocalVector<v8::Object> context_extensions,
155-
v8::ScriptCompiler::CompileOptions options,
156-
bool produce_cached_data,
157-
v8::Local<v8::Symbol> id_symbol,
158-
const errors::TryCatchScope& try_catch);
159147
static v8::Intercepted PropertyQueryCallback(
160148
v8::Local<v8::Name> property,
161149
const v8::PropertyCallbackInfo<v8::Integer>& args);
@@ -234,6 +222,29 @@ class ContextifyScript final : CPPGC_MIXIN(ContextifyScript) {
234222
v8::TracedReference<v8::UnboundScript> script_;
235223
};
236224

225+
class ContextifyFunction final {
226+
public:
227+
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
228+
static void CreatePerIsolateProperties(IsolateData* isolate_data,
229+
v8::Local<v8::ObjectTemplate> target);
230+
231+
static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
232+
static v8::MaybeLocal<v8::Object> CompileFunctionAndCacheResult(
233+
Environment* env,
234+
v8::Local<v8::Context> parsing_context,
235+
v8::ScriptCompiler::Source* source,
236+
v8::LocalVector<v8::String> params,
237+
v8::LocalVector<v8::Object> context_extensions,
238+
v8::ScriptCompiler::CompileOptions options,
239+
bool produce_cached_data,
240+
v8::Local<v8::Symbol> id_symbol,
241+
const errors::TryCatchScope& try_catch);
242+
243+
private:
244+
ContextifyFunction() = delete;
245+
~ContextifyFunction() = delete;
246+
};
247+
237248
v8::Maybe<void> StoreCodeCacheResult(
238249
Environment* env,
239250
v8::Local<v8::Object> target,
@@ -242,12 +253,6 @@ v8::Maybe<void> StoreCodeCacheResult(
242253
bool produce_cached_data,
243254
std::unique_ptr<v8::ScriptCompiler::CachedData> new_cached_data);
244255

245-
v8::MaybeLocal<v8::Function> CompileFunction(
246-
v8::Local<v8::Context> context,
247-
v8::Local<v8::String> filename,
248-
v8::Local<v8::String> content,
249-
v8::LocalVector<v8::String>* parameters);
250-
251256
} // namespace contextify
252257
} // namespace node
253258

src/node_sea.cc

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ using v8::MaybeLocal;
4141
using v8::NewStringType;
4242
using v8::Object;
4343
using v8::ScriptCompiler;
44+
using v8::ScriptOrigin;
4445
using v8::String;
4546
using v8::Value;
4647

@@ -460,16 +461,23 @@ std::optional<std::string> GenerateCodeCache(std::string_view main_path,
460461
FIXED_ONE_BYTE_STRING(isolate, "__filename"),
461462
FIXED_ONE_BYTE_STRING(isolate, "__dirname"),
462463
});
463-
464-
// TODO(RaisinTen): Using the V8 code cache prevents us from using `import()`
465-
// in the SEA code. Support it.
466-
// Refs: https://github.com/nodejs/node/pull/48191#discussion_r1213271430
464+
ScriptOrigin script_origin(filename, 0, 0, true);
465+
ScriptCompiler::Source script_source(content, script_origin);
466+
MaybeLocal<Function> maybe_fn =
467+
ScriptCompiler::CompileFunction(context,
468+
&script_source,
469+
parameters.size(),
470+
parameters.data(),
471+
0,
472+
nullptr);
467473
Local<Function> fn;
468-
if (!contextify::CompileFunction(context, filename, content, &parameters)
469-
.ToLocal(&fn)) {
474+
if (!maybe_fn.ToLocal(&fn)) {
470475
return std::nullopt;
471476
}
472477

478+
// TODO(RaisinTen): Using the V8 code cache prevents us from using `import()`
479+
// in the SEA code. Support it.
480+
// Refs: https://github.com/nodejs/node/pull/48191#discussion_r1213271430
473481
std::unique_ptr<ScriptCompiler::CachedData> cache{
474482
ScriptCompiler::CreateCodeCacheForFunction(fn)};
475483
std::string code_cache(cache->data, cache->data + cache->length);

src/node_snapshotable.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ using v8::HandleScope;
4242
using v8::Isolate;
4343
using v8::Local;
4444
using v8::LocalVector;
45+
using v8::MaybeLocal;
4546
using v8::Object;
4647
using v8::ObjectTemplate;
48+
using v8::ScriptCompiler;
49+
using v8::ScriptOrigin;
4750
using v8::SnapshotCreator;
4851
using v8::StartupData;
4952
using v8::String;
@@ -1488,9 +1491,18 @@ void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
14881491
FIXED_ONE_BYTE_STRING(isolate, "__filename"),
14891492
FIXED_ONE_BYTE_STRING(isolate, "__dirname"),
14901493
});
1494+
1495+
ScriptOrigin script_origin(filename, 0, 0, true);
1496+
ScriptCompiler::Source script_source(source, script_origin);
1497+
MaybeLocal<Function> maybe_fn =
1498+
ScriptCompiler::CompileFunction(context,
1499+
&script_source,
1500+
parameters.size(),
1501+
parameters.data(),
1502+
0,
1503+
nullptr);
14911504
Local<Function> fn;
1492-
if (contextify::CompileFunction(context, filename, source, &parameters)
1493-
.ToLocal(&fn)) {
1505+
if (maybe_fn.ToLocal(&fn)) {
14941506
args.GetReturnValue().Set(fn);
14951507
}
14961508
}

0 commit comments

Comments
 (0)