|
28 | 28 | #include "node_errors.h"
|
29 | 29 | #include "node_external_reference.h"
|
30 | 30 | #include "node_internals.h"
|
| 31 | +#include "node_sea.h" |
31 | 32 | #include "node_snapshot_builder.h"
|
32 | 33 | #include "node_watchdog.h"
|
33 | 34 | #include "util-inl.h"
|
@@ -1150,6 +1151,15 @@ ContextifyScript::ContextifyScript(Environment* env, Local<Object> object)
|
1150 | 1151 |
|
1151 | 1152 | ContextifyScript::~ContextifyScript() {}
|
1152 | 1153 |
|
| 1154 | +static Local<PrimitiveArray> GetHostDefinedOptions(Isolate* isolate, |
| 1155 | + Local<Symbol> id_symbol) { |
| 1156 | + Local<PrimitiveArray> host_defined_options = |
| 1157 | + PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); |
| 1158 | + host_defined_options->Set( |
| 1159 | + isolate, loader::HostDefinedOptions::kID, id_symbol); |
| 1160 | + return host_defined_options; |
| 1161 | +} |
| 1162 | + |
1153 | 1163 | void ContextifyContext::CompileFunction(
|
1154 | 1164 | const FunctionCallbackInfo<Value>& args) {
|
1155 | 1165 | Environment* env = Environment::GetCurrent(args);
|
@@ -1280,15 +1290,6 @@ void ContextifyContext::CompileFunction(
|
1280 | 1290 | args.GetReturnValue().Set(result);
|
1281 | 1291 | }
|
1282 | 1292 |
|
1283 |
| -Local<PrimitiveArray> ContextifyContext::GetHostDefinedOptions( |
1284 |
| - Isolate* isolate, Local<Symbol> id_symbol) { |
1285 |
| - Local<PrimitiveArray> host_defined_options = |
1286 |
| - PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); |
1287 |
| - host_defined_options->Set( |
1288 |
| - isolate, loader::HostDefinedOptions::kID, id_symbol); |
1289 |
| - return host_defined_options; |
1290 |
| -} |
1291 |
| - |
1292 | 1293 | ScriptCompiler::Source ContextifyContext::GetCommonJSSourceInstance(
|
1293 | 1294 | Isolate* isolate,
|
1294 | 1295 | Local<String> code,
|
@@ -1322,6 +1323,16 @@ ScriptCompiler::CompileOptions ContextifyContext::GetCompileOptions(
|
1322 | 1323 | return options;
|
1323 | 1324 | }
|
1324 | 1325 |
|
| 1326 | +static std::vector<Local<String>> GetCJSParameters(IsolateData* data) { |
| 1327 | + return { |
| 1328 | + data->exports_string(), |
| 1329 | + data->require_string(), |
| 1330 | + data->module_string(), |
| 1331 | + data->__filename_string(), |
| 1332 | + data->__dirname_string(), |
| 1333 | + }; |
| 1334 | +} |
| 1335 | + |
1325 | 1336 | Local<Object> ContextifyContext::CompileFunctionAndCacheResult(
|
1326 | 1337 | Environment* env,
|
1327 | 1338 | Local<Context> parsing_context,
|
@@ -1450,12 +1461,7 @@ void ContextifyContext::ContainsModuleSyntax(
|
1450 | 1461 | isolate, code, filename, 0, 0, host_defined_options, nullptr);
|
1451 | 1462 | ScriptCompiler::CompileOptions options = GetCompileOptions(source);
|
1452 | 1463 |
|
1453 |
| - std::vector<Local<String>> params = { |
1454 |
| - String::NewFromUtf8(isolate, "exports").ToLocalChecked(), |
1455 |
| - String::NewFromUtf8(isolate, "require").ToLocalChecked(), |
1456 |
| - String::NewFromUtf8(isolate, "module").ToLocalChecked(), |
1457 |
| - String::NewFromUtf8(isolate, "__filename").ToLocalChecked(), |
1458 |
| - String::NewFromUtf8(isolate, "__dirname").ToLocalChecked()}; |
| 1464 | + std::vector<Local<String>> params = GetCJSParameters(env->isolate_data()); |
1459 | 1465 |
|
1460 | 1466 | TryCatchScope try_catch(env);
|
1461 | 1467 | ShouldNotAbortOnUncaughtScope no_abort_scope(env);
|
@@ -1485,6 +1491,96 @@ void ContextifyContext::ContainsModuleSyntax(
|
1485 | 1491 | args.GetReturnValue().Set(found_error_message_caused_by_module_syntax);
|
1486 | 1492 | }
|
1487 | 1493 |
|
| 1494 | +static void CompileFunctionForCJSLoader( |
| 1495 | + const FunctionCallbackInfo<Value>& args) { |
| 1496 | + CHECK(args[0]->IsString()); |
| 1497 | + CHECK(args[1]->IsString()); |
| 1498 | + Local<String> code = args[0].As<String>(); |
| 1499 | + Local<String> filename = args[1].As<String>(); |
| 1500 | + Isolate* isolate = args.GetIsolate(); |
| 1501 | + Local<Context> context = isolate->GetCurrentContext(); |
| 1502 | + Environment* env = Environment::GetCurrent(context); |
| 1503 | + |
| 1504 | + Local<Symbol> symbol = env->vm_dynamic_import_default_internal(); |
| 1505 | + Local<PrimitiveArray> hdo = GetHostDefinedOptions(isolate, symbol); |
| 1506 | + ScriptOrigin origin(isolate, |
| 1507 | + filename, |
| 1508 | + 0, // line offset |
| 1509 | + 0, // column offset |
| 1510 | + true, // is cross origin |
| 1511 | + -1, // script id |
| 1512 | + Local<Value>(), // source map URL |
| 1513 | + false, // is opaque |
| 1514 | + false, // is WASM |
| 1515 | + false, // is ES Module |
| 1516 | + hdo); |
| 1517 | + ScriptCompiler::CachedData* cached_data = nullptr; |
| 1518 | + |
| 1519 | +#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION |
| 1520 | + bool used_cache_from_sea = false; |
| 1521 | + if (sea::IsSingleExecutable()) { |
| 1522 | + sea::SeaResource sea = sea::FindSingleExecutableResource(); |
| 1523 | + if (sea.use_code_cache()) { |
| 1524 | + std::string_view data = sea.code_cache.value(); |
| 1525 | + cached_data = new ScriptCompiler::CachedData( |
| 1526 | + reinterpret_cast<const uint8_t*>(data.data()), |
| 1527 | + static_cast<int>(data.size()), |
| 1528 | + v8::ScriptCompiler::CachedData::BufferNotOwned); |
| 1529 | + used_cache_from_sea = true; |
| 1530 | + } |
| 1531 | + } |
| 1532 | +#endif |
| 1533 | + ScriptCompiler::Source source(code, origin, cached_data); |
| 1534 | + |
| 1535 | + TryCatchScope try_catch(env); |
| 1536 | + |
| 1537 | + std::vector<Local<String>> params = GetCJSParameters(env->isolate_data()); |
| 1538 | + |
| 1539 | + MaybeLocal<Function> maybe_fn = ScriptCompiler::CompileFunction( |
| 1540 | + context, |
| 1541 | + &source, |
| 1542 | + params.size(), |
| 1543 | + params.data(), |
| 1544 | + 0, /* context extensions size */ |
| 1545 | + nullptr, /* context extensions data */ |
| 1546 | + // TODO(joyeecheung): allow optional eager compilation. |
| 1547 | + cached_data == nullptr ? ScriptCompiler::kNoCompileOptions |
| 1548 | + : ScriptCompiler::kConsumeCodeCache, |
| 1549 | + v8::ScriptCompiler::NoCacheReason::kNoCacheNoReason); |
| 1550 | + |
| 1551 | + Local<Function> fn; |
| 1552 | + if (!maybe_fn.ToLocal(&fn)) { |
| 1553 | + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { |
| 1554 | + errors::DecorateErrorStack(env, try_catch); |
| 1555 | + if (!try_catch.HasTerminated()) { |
| 1556 | + try_catch.ReThrow(); |
| 1557 | + } |
| 1558 | + return; |
| 1559 | + } |
| 1560 | + } |
| 1561 | + |
| 1562 | + bool cache_rejected = false; |
| 1563 | +#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION |
| 1564 | + if (used_cache_from_sea) { |
| 1565 | + cache_rejected = source.GetCachedData()->rejected; |
| 1566 | + } |
| 1567 | +#endif |
| 1568 | + |
| 1569 | + std::vector<Local<Name>> names = { |
| 1570 | + env->cached_data_rejected_string(), |
| 1571 | + env->source_map_url_string(), |
| 1572 | + env->function_string(), |
| 1573 | + }; |
| 1574 | + std::vector<Local<Value>> values = { |
| 1575 | + Boolean::New(isolate, cache_rejected), |
| 1576 | + fn->GetScriptOrigin().SourceMapUrl(), |
| 1577 | + fn, |
| 1578 | + }; |
| 1579 | + Local<Object> result = Object::New( |
| 1580 | + isolate, v8::Null(isolate), names.data(), values.data(), names.size()); |
| 1581 | + args.GetReturnValue().Set(result); |
| 1582 | +} |
| 1583 | + |
1488 | 1584 | static void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
|
1489 | 1585 | int ret = SigintWatchdogHelper::GetInstance()->Start();
|
1490 | 1586 | args.GetReturnValue().Set(ret == 0);
|
@@ -1537,6 +1633,10 @@ void CreatePerIsolateProperties(IsolateData* isolate_data,
|
1537 | 1633 | isolate, target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
|
1538 | 1634 |
|
1539 | 1635 | SetMethod(isolate, target, "measureMemory", MeasureMemory);
|
| 1636 | + SetMethod(isolate, |
| 1637 | + target, |
| 1638 | + "compileFunctionForCJSLoader", |
| 1639 | + CompileFunctionForCJSLoader); |
1540 | 1640 | }
|
1541 | 1641 |
|
1542 | 1642 | static void CreatePerContextProperties(Local<Object> target,
|
@@ -1576,6 +1676,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
1576 | 1676 | ContextifyContext::RegisterExternalReferences(registry);
|
1577 | 1677 | ContextifyScript::RegisterExternalReferences(registry);
|
1578 | 1678 |
|
| 1679 | + registry->Register(CompileFunctionForCJSLoader); |
1579 | 1680 | registry->Register(StartSigintWatchdog);
|
1580 | 1681 | registry->Register(StopSigintWatchdog);
|
1581 | 1682 | registry->Register(WatchdogHasPendingSigint);
|
|
0 commit comments