Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/j2w.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { resolve, basename } from 'node:path';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import path from 'path';
import { precompile } from "./precompile.mjs";

const componentizeVersion = '0.16.0';
const __filename = new URL(import.meta.url).pathname;
Expand Down Expand Up @@ -103,14 +104,15 @@ async function saveBuildData(buildDataPath, checksum, version) {
}

const source = await readFile(src, 'utf8');
const precompiledSource = precompile(source, src, true);

// Check if a non-default wit directory is supplied
const witPath = args.witPath ? resolve(args.witPath) : path.join(__dirname, 'wit');
if (args.witPath) {
console.log(`Using user-provided wit in: ${witPath}`);
}

const { component } = await componentize(source, {
const { component } = await componentize(precompiledSource, {
sourceName: basename(src),
witPath,
worldName: args.triggerType,
Expand Down
62 changes: 62 additions & 0 deletions bin/precompile.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2024 Fastly Inc.
// License: the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import regexpuc from 'regexpu-core';
import { parse } from 'acorn';
import MagicString from 'magic-string';
import { simple as simpleWalk } from 'acorn-walk';

const PREAMBLE = `;{
// Precompiled regular expressions
const precompile = (r) => { r.exec('a'); r.exec('\\u1000'); };`;
const POSTAMBLE = '}';

/// Emit a block of javascript that will pre-compile the regular expressions given. As spidermonkey
/// will intern regular expressions, duplicating them at the top level and testing them with both
/// an ascii and utf8 string should ensure that they won't be re-compiled when run in the fetch
/// handler.
export function precompile(source, filename = '<input>', moduleMode = false) {
const magicString = new MagicString(source, {
filename,
});

const ast = parse(source, {
ecmaVersion: 'latest',
sourceType: moduleMode ? 'module' : 'script',
});

const precompileCalls = [];
simpleWalk(ast, {
Literal(node) {
if (!node.regex) return;
let transpiledPattern;
try {
transpiledPattern = regexpuc(node.regex.pattern, node.regex.flags, {
unicodePropertyEscapes: 'transform',
});
} catch {
// swallow regex parse errors here to instead throw them at the engine level
// this then also avoids regex parser bugs being thrown unnecessarily
transpiledPattern = node.regex.pattern;
}
const transpiledRegex = `/${transpiledPattern}/${node.regex.flags}`;
precompileCalls.push(`precompile(${transpiledRegex});`);
magicString.overwrite(node.start, node.end, transpiledRegex);
},
});

if (!precompileCalls.length) return source;

magicString.prepend(`${PREAMBLE}${precompileCalls.join('\n')}${POSTAMBLE}`);

// When we're ready to pipe in source maps:
// const map = magicString.generateMap({
// source: 'source.js',
// file: 'converted.js.map',
// includeContent: true
// });

return magicString.toString();
}
152 changes: 150 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fermyon/spin-sdk",
"version": "3.0.0",
"version": "3.1.0",
"description": "",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -28,7 +28,11 @@
"@bytecodealliance/componentize-js": "^0.16.0",
"yargs": "^17.7.2",
"typedoc-plugin-missing-exports": "^3.0.0",
"@fermyon/knitwit": "^0.3.0"
"@fermyon/knitwit": "^0.3.0",
"acorn-walk": "^8.3.4",
"acron": "^1.0.5",
"magic-string": "^0.30.17",
"regexpu-core": "^6.2.0"
},
"files": [
"lib",
Expand Down