#!/usr/bin/env node /* Embeds the Node island host (packages/runtime/src/scr_node_island_host.cjs) * into scr_node_island_host.h as a C string, which scr_node_island.c passes * to `node -e` when it starts the helper. * * node scripts/node-island-host.mjs rewrite the header * node scripts/node-island-host.mjs --check fail when it is stale */ import { readFileSync, writeFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; const srcDir = fileURLToPath(new URL("../packages/runtime/src/", import.meta.url)); const SOURCE = `${srcDir}scr_node_island_host.cjs`; // The loader hooks of shared modules (NI-6) run in the bootstrap's scope. const HOOKS = `${srcDir}scr_node_island_hooks.cjs`; const HEADER = `${srcDir}scr_node_island_host.h`; /** One C string literal per source line, every byte outside printable * ASCII as a three-digit octal escape. */ function cLiteral(line) { let out = ""; for (const byte of Buffer.from(line, "utf8")) { if (byte === 0x22 || byte === 0x5c) out += `\\${String.fromCharCode(byte)}`; else if (byte >= 0x20 && byte < 0x7f && byte !== 0x3f) out += String.fromCharCode(byte); else out += `\\${byte.toString(8).padStart(3, "0")}`; } return `"${out}"`; } export function renderHeader(source) { const lines = source.split("\n"); if (lines.at(-1) === "") lines.pop(); const body = lines.map((line) => ` ${cLiteral(`${line}\n`)}`).join("\n"); return `/* Generated by scripts/node-island-host.mjs from scr_node_island_host.cjs * and scr_node_island_hooks.cjs. * Do not edit: change the .cjs file and rerun the script. */ #ifndef SCR_NODE_ISLAND_HOST_H #define SCR_NODE_ISLAND_HOST_H static const char scr_node_island_host_js[] = ${body}; #endif /* SCR_NODE_ISLAND_HOST_H */ `; } if (process.argv[1] === fileURLToPath(import.meta.url)) { const expected = renderHeader(`${readFileSync(SOURCE, "utf8")}\n${readFileSync(HOOKS, "utf8")}`); if (process.argv.includes("--check")) { if (readFileSync(HEADER, "utf8") !== expected) { console.error(`${HEADER} is stale: run node scripts/node-island-host.mjs`); process.exit(1); } } else { writeFileSync(HEADER, expected); } }