Skip to content
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

feat: add initSync() to initialize WASM synchronously #100

Merged
merged 1 commit into from
Aug 25, 2024
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ When using the ESM version, Wasm is supported instead:

```js
import { parse, init } from 'cjs-module-lexer';
// init needs to be called and waited upon
// init() needs to be called and waited upon, or use initSync() to compile
// Wasm blockingly and synchronously.
await init();
const { exports, reexports } = parse(source);
```
Expand Down
1 change: 1 addition & 0 deletions lexer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export interface Exports {

export declare function parse(source: string, name?: string): Exports;
export declare function init(): Promise<void>;
export declare function initSync(): void;
1 change: 1 addition & 0 deletions lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1439,4 +1439,5 @@ function isExpressionTerminator (curPos) {
const initPromise = Promise.resolve();

module.exports.init = () => initPromise;
module.exports.initSync = () => {};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why dist/lexer.js was never documented in the README, despite being what Node.js core has been using. But anyway this is added to lexer.js for parity.

module.exports.parse = parseCJS;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"scripts": {
"test-js": "mocha -b -u tdd test/*.js",
"test-wasm": "cross-env WASM=1 mocha -b -u tdd test/*.js",
"test": "npm run test-wasm && npm run test-js",
"test-wasm-sync": "cross-env WASM_SYNC=1 mocha -b -u tdd test/*.js",
"test": "npm run test-wasm && npm run test-wasm-sync && npm run test-js",
"bench": "node --expose-gc bench/index.mjs",
"build": "node build.js ; babel dist/lexer.mjs -o dist/lexer.js ; terser dist/lexer.js -o dist/lexer.js",
"build-wasm": "make lib/lexer.wasm && node build.js",
Expand Down
22 changes: 18 additions & 4 deletions src/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,30 @@ function copyLE (src, outBuf16) {
outBuf16[i] = src.charCodeAt(i++);
}

function getWasmBytes() {
const binary = 'WASM_BINARY'; // This string will be replaced by build.js.
if (typeof window !== 'undefined' && typeof atob === 'function')
return Uint8Array.from(atob(binary), x => x.charCodeAt(0));
joyeecheung marked this conversation as resolved.
Show resolved Hide resolved
return Buffer.from(binary, 'base64');
}

let initPromise;
export function init () {
if (initPromise)
return initPromise;
return initPromise = (async () => {
const compiled = await WebAssembly.compile(
(binary => typeof window !== 'undefined' && typeof atob === 'function' ? Uint8Array.from(atob(binary), x => x.charCodeAt(0)) : Buffer.from(binary, 'base64'))
('WASM_BINARY')
)
const compiled = await WebAssembly.compile(getWasmBytes());
const { exports } = await WebAssembly.instantiate(compiled);
wasm = exports;
})();
}

export function initSync () {
if (wasm) {
return;
}
const compiled = new WebAssembly.Module(getWasmBytes());
const { exports } = new WebAssembly.Instance(compiled);
wasm = exports;
return;
}
4 changes: 4 additions & 0 deletions test/_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ async function loadParser () {
const m = await import('../dist/lexer.mjs');
await m.init();
parse = m.parse;
} else if (process.env.WASM_SYNC) {
const m = require('../dist/lexer.js');
m.initSync();
parse = m.parse;
}
else {
parse = require('../lexer.js').parse;
Expand Down
6 changes: 5 additions & 1 deletion test/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ async function loadParser () {
const m = await import('../dist/lexer.mjs');
await m.init();
parse = m.parse;
} else if (process.env.WASM_SYNC) {
const m = require('../dist/lexer.js');
m.initSync();
parse = m.parse;
}
else {
parse = require('../lexer.js').parse;
Expand All @@ -31,7 +35,7 @@ suite('Samples', () => {
const selfSource = fs.readFileSync(process.cwd() + '/lexer.js').toString();
test('Self test', async () => {
const { exports } = parse(selfSource);
assert.deepStrictEqual(exports, ['init', 'parse']);
assert.deepStrictEqual(exports, ['init', 'initSync', 'parse']);
});

files.forEach(({ file, code }) => {
Expand Down
Loading