Skip to content

Commit 5f7526c

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

File tree

2 files changed

+23
-99
lines changed

2 files changed

+23
-99
lines changed

src/node_contextify.cc

Lines changed: 22 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,32 @@ 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 = ContextifyContext::ShouldRetryAsESMInternal(env, code);
15671486
}
15681487
args.GetReturnValue().Set(should_retry_as_esm);
15691488
}
15701489

15711490
void ContextifyContext::ShouldRetryAsESM(
15721491
const FunctionCallbackInfo<Value>& args) {
15731492
Environment* env = Environment::GetCurrent(args);
1574-
Isolate* isolate = env->isolate();
1575-
Local<Context> context = env->context();
15761493

1577-
if (args.Length() != 1) {
1578-
return THROW_ERR_MISSING_ARGS(env, "shouldRetryAsESM needs 1 argument");
1579-
}
1494+
CHECK_EQ(args.Length(), 1);
1495+
15801496
// Argument 1: source code
15811497
Local<String> code;
15821498
CHECK(args[0]->IsString());
15831499
code = args[0].As<String>();
15841500

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

15891513
Local<PrimitiveArray> host_defined_options =
@@ -1609,6 +1533,7 @@ void ContextifyContext::ShouldRetryAsESM(
16091533
ScriptCompiler::Source wrapped_source = GetCommonJSSourceInstance(
16101534
isolate, code, script_id, 0, 0, host_defined_options, nullptr);
16111535

1536+
Local<Context> context = env->context();
16121537
std::vector<Local<String>> params = GetCJSParameters(env->isolate_data());
16131538
std::ignore = ScriptCompiler::CompileFunction(
16141539
context,
@@ -1620,7 +1545,6 @@ void ContextifyContext::ShouldRetryAsESM(
16201545
options,
16211546
v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason);
16221547

1623-
bool should_retry_as_esm = false;
16241548
if (!try_catch.HasTerminated()) {
16251549
if (try_catch.HasCaught()) {
16261550
// If on the second parse an error is thrown by ESM syntax, then
@@ -1631,18 +1555,17 @@ void ContextifyContext::ShouldRetryAsESM(
16311555
auto message_view = message_value.ToStringView();
16321556
for (const auto& error_message : esm_syntax_error_messages) {
16331557
if (message_view.find(error_message) != std::string_view::npos) {
1634-
should_retry_as_esm = true;
1635-
break;
1558+
return true;
16361559
}
16371560
}
16381561
} else {
16391562
// No errors thrown in the second parse, so most likely the error
16401563
// was caused by a top-level `await` or a top-level declaration of
16411564
// one of the CommonJS module variables.
1642-
should_retry_as_esm = true;
1565+
return true;
16431566
}
16441567
}
1645-
args.GetReturnValue().Set(should_retry_as_esm);
1568+
return false;
16461569
}
16471570

16481571
static void CompileFunctionForCJSLoader(

src/node_contextify.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ 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, v8::Local<v8::String> code);
110111
static void WeakCallback(
111112
const v8::WeakCallbackInfo<ContextifyContext>& data);
112113
static void PropertyGetterCallback(

0 commit comments

Comments
 (0)