-
Notifications
You must be signed in to change notification settings - Fork 19
add regex precompilation to build step #361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,16 @@ | |
| import { componentize } from '@bytecodealliance/componentize-js'; | ||
| import { version as componentizeVersion } from '@bytecodealliance/componentize-js'; | ||
| import { getPackagesWithWasiDeps, processWasiDeps } from './wasiDepsParser.js'; | ||
|
|
||
| import { | ||
| calculateChecksum, | ||
| saveBuildData, | ||
| } from './utils.js'; | ||
| import { getCliArgs } from './cli.js'; | ||
| import { getBuildDataPath, ShouldComponentize } from './build.js'; | ||
| import { writeFile } from 'node:fs/promises'; | ||
| import { readFile, writeFile } from 'node:fs/promises'; | ||
| import { mergeWit } from '../lib/wit_tools.js'; | ||
| //@ts-ignore | ||
| import { precompile } from "./precompile.js" | ||
|
|
||
| async function main() { | ||
| try { | ||
|
|
@@ -61,10 +62,12 @@ async function main() { | |
| 'combined-wit:[email protected]', | ||
| ); | ||
|
|
||
| const { component } = await componentize({ | ||
| sourcePath: src, | ||
| // @ts-ignore | ||
| witWorld: inlineWit, | ||
| const source = await readFile(src, 'utf8'); | ||
| const precompiledSource = precompile(source, src, true) as string; | ||
|
|
||
| // Using the old syntax because the new sytnax does not allow passing in the precompiled string | ||
| //@ts-ignore | ||
| const { component } = await componentize(precompiledSource, inlineWit, { | ||
| runtimeArgs, | ||
| enableAot: CliArgs.aot, | ||
| }); | ||
|
|
||
| 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(); | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,6 @@ echo "built the test app successfully" | |
| # Start the spin app in the background | ||
| echo "Starting Spin app" | ||
| spin up & | ||
| SPIN_PID=$! | ||
|
|
||
| # wait for app to be up and running | ||
| echo "Waiting for Spin app to be ready" | ||
|
|
@@ -36,7 +35,7 @@ echo "\n\nTest completed" | |
|
|
||
| # kill the spin app | ||
| echo "Stopping Spin" | ||
| kill -9 $SPIN_PID | ||
| killall spin | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can keep this to the specific process by changing from
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This did not work, I can take a look at how to fix this in a separate PR. |
||
|
|
||
|
|
||
| if [ "$isFailed" = true ] ; then | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.