Skip to content

Commit f4cd945

Browse files
committed
DRY the C++ functions
1 parent 9205171 commit f4cd945

File tree

2 files changed

+26
-99
lines changed

2 files changed

+26
-99
lines changed

src/node_contextify.cc

Lines changed: 24 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,35 +1441,18 @@ void ContextifyContext::ContainsModuleSyntax(
14411441
env, "containsModuleSyntax needs at least 1 argument");
14421442
}
14431443

1444+
// Argument 1: source code
1445+
Local<String> code;
1446+
CHECK(args[0]->IsString());
1447+
code = args[0].As<String>();
1448+
14441449
// Argument 2: filename; if undefined, use empty string
14451450
Local<String> filename = String::Empty(isolate);
14461451
if (!args[1]->IsUndefined()) {
14471452
CHECK(args[1]->IsString());
14481453
filename = args[1].As<String>();
14491454
}
14501455

1451-
// Argument 1: source code; if undefined, read from filename in argument 2
1452-
Local<String> code;
1453-
if (args[0]->IsUndefined()) {
1454-
CHECK(!filename.IsEmpty());
1455-
const char* filename_str = Utf8Value(isolate, filename).out();
1456-
std::string contents;
1457-
int result = ReadFileSync(&contents, filename_str);
1458-
if (result != 0) {
1459-
isolate->ThrowException(
1460-
ERR_MODULE_NOT_FOUND(isolate, "Cannot read file %s", filename_str));
1461-
return;
1462-
}
1463-
code = String::NewFromUtf8(isolate,
1464-
contents.c_str(),
1465-
v8::NewStringType::kNormal,
1466-
contents.length())
1467-
.ToLocalChecked();
1468-
} else {
1469-
CHECK(args[0]->IsString());
1470-
code = args[0].As<String>();
1471-
}
1472-
14731456
// TODO(geoffreybooth): Centralize this rather than matching the logic in
14741457
// cjs/loader.js and translators.js
14751458
Local<String> script_id = String::Concat(
@@ -1499,91 +1482,34 @@ void ContextifyContext::ContainsModuleSyntax(
14991482

15001483
bool should_retry_as_esm = false;
15011484
if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
1502-
Utf8Value message_value(env->isolate(), try_catch.Message()->Get());
1503-
auto message = message_value.ToStringView();
1504-
1505-
for (const auto& error_message : esm_syntax_error_messages) {
1506-
if (message.find(error_message) != std::string_view::npos) {
1507-
should_retry_as_esm = true;
1508-
break;
1509-
}
1510-
}
1511-
1512-
if (!should_retry_as_esm) {
1513-
for (const auto& error_message : throws_only_in_cjs_error_messages) {
1514-
if (message.find(error_message) != std::string_view::npos) {
1515-
// Try parsing again where the CommonJS wrapper is replaced by an
1516-
// async function wrapper. If the new parse succeeds, then the error
1517-
// was caused by either a top-level declaration of one of the CommonJS
1518-
// module variables, or a top-level `await`.
1519-
TryCatchScope second_parse_try_catch(env);
1520-
code =
1521-
String::Concat(isolate,
1522-
String::NewFromUtf8(isolate, "(async function() {")
1523-
.ToLocalChecked(),
1524-
code);
1525-
code = String::Concat(
1526-
isolate,
1527-
code,
1528-
String::NewFromUtf8(isolate, "})();").ToLocalChecked());
1529-
ScriptCompiler::Source wrapped_source = GetCommonJSSourceInstance(
1530-
isolate, code, filename, 0, 0, host_defined_options, nullptr);
1531-
std::ignore = ScriptCompiler::CompileFunction(
1532-
context,
1533-
&wrapped_source,
1534-
params.size(),
1535-
params.data(),
1536-
0,
1537-
nullptr,
1538-
options,
1539-
v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason);
1540-
if (!second_parse_try_catch.HasTerminated()) {
1541-
if (second_parse_try_catch.HasCaught()) {
1542-
// If on the second parse an error is thrown by ESM syntax, then
1543-
// what happened was that the user had top-level `await` or a
1544-
// top-level declaration of one of the CommonJS module variables
1545-
// above the first `import` or `export`.
1546-
Utf8Value second_message_value(
1547-
env->isolate(), second_parse_try_catch.Message()->Get());
1548-
auto second_message = second_message_value.ToStringView();
1549-
for (const auto& error_message : esm_syntax_error_messages) {
1550-
if (second_message.find(error_message) !=
1551-
std::string_view::npos) {
1552-
should_retry_as_esm = true;
1553-
break;
1554-
}
1555-
}
1556-
} else {
1557-
// No errors thrown in the second parse, so most likely the error
1558-
// was caused by a top-level `await` or a top-level declaration of
1559-
// one of the CommonJS module variables.
1560-
should_retry_as_esm = true;
1561-
}
1562-
}
1563-
break;
1564-
}
1565-
}
1566-
}
1485+
should_retry_as_esm =
1486+
ContextifyContext::ShouldRetryAsESMInternal(env, code);
15671487
}
15681488
args.GetReturnValue().Set(should_retry_as_esm);
15691489
}
15701490

15711491
void ContextifyContext::ShouldRetryAsESM(
15721492
const FunctionCallbackInfo<Value>& args) {
15731493
Environment* env = Environment::GetCurrent(args);
1574-
Isolate* isolate = env->isolate();
1575-
Local<Context> context = env->context();
15761494

1577-
if (args.Length() != 1) {
1578-
return THROW_ERR_MISSING_ARGS(env, "shouldRetryAsESM needs 1 argument");
1579-
}
1495+
CHECK_EQ(args.Length(), 1);
1496+
15801497
// Argument 1: source code
15811498
Local<String> code;
15821499
CHECK(args[0]->IsString());
15831500
code = args[0].As<String>();
15841501

1585-
Local<String> script_id =
1586-
String::NewFromUtf8(isolate, "throwaway").ToLocalChecked();
1502+
bool should_retry_as_esm =
1503+
ContextifyContext::ShouldRetryAsESMInternal(env, code);
1504+
1505+
args.GetReturnValue().Set(should_retry_as_esm);
1506+
}
1507+
1508+
bool ContextifyContext::ShouldRetryAsESMInternal(Environment* env,
1509+
Local<String> code) {
1510+
Isolate* isolate = env->isolate();
1511+
1512+
Local<String> script_id = FIXED_ONE_BYTE_STRING(isolate, "throwaway");
15871513
Local<Symbol> id_symbol = Symbol::New(isolate, script_id);
15881514

15891515
Local<PrimitiveArray> host_defined_options =
@@ -1609,6 +1535,7 @@ void ContextifyContext::ShouldRetryAsESM(
16091535
ScriptCompiler::Source wrapped_source = GetCommonJSSourceInstance(
16101536
isolate, code, script_id, 0, 0, host_defined_options, nullptr);
16111537

1538+
Local<Context> context = env->context();
16121539
std::vector<Local<String>> params = GetCJSParameters(env->isolate_data());
16131540
std::ignore = ScriptCompiler::CompileFunction(
16141541
context,
@@ -1620,7 +1547,6 @@ void ContextifyContext::ShouldRetryAsESM(
16201547
options,
16211548
v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason);
16221549

1623-
bool should_retry_as_esm = false;
16241550
if (!try_catch.HasTerminated()) {
16251551
if (try_catch.HasCaught()) {
16261552
// If on the second parse an error is thrown by ESM syntax, then
@@ -1631,18 +1557,17 @@ void ContextifyContext::ShouldRetryAsESM(
16311557
auto message_view = message_value.ToStringView();
16321558
for (const auto& error_message : esm_syntax_error_messages) {
16331559
if (message_view.find(error_message) != std::string_view::npos) {
1634-
should_retry_as_esm = true;
1635-
break;
1560+
return true;
16361561
}
16371562
}
16381563
} else {
16391564
// No errors thrown in the second parse, so most likely the error
16401565
// was caused by a top-level `await` or a top-level declaration of
16411566
// one of the CommonJS module variables.
1642-
should_retry_as_esm = true;
1567+
return true;
16431568
}
16441569
}
1645-
args.GetReturnValue().Set(should_retry_as_esm);
1570+
return false;
16461571
}
16471572

16481573
static void CompileFunctionForCJSLoader(

src/node_contextify.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class ContextifyContext : public BaseObject {
107107
static void ContainsModuleSyntax(
108108
const v8::FunctionCallbackInfo<v8::Value>& args);
109109
static void ShouldRetryAsESM(const v8::FunctionCallbackInfo<v8::Value>& args);
110+
static bool ShouldRetryAsESMInternal(Environment* env,
111+
v8::Local<v8::String> code);
110112
static void WeakCallback(
111113
const v8::WeakCallbackInfo<ContextifyContext>& data);
112114
static void PropertyGetterCallback(

0 commit comments

Comments
 (0)