Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9cdac6f

Browse files
committed
re-structured wasm modules
1 parent dfe06c3 commit 9cdac6f

File tree

6 files changed

+94
-39
lines changed

6 files changed

+94
-39
lines changed

‎package-lock.json

Lines changed: 7 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"scripts": {
99
"build": "npm publish --dry-run",
10-
"prepare": "rm -rf dist dist.* ; tsc -p tsconfig.dist.json && webpack",
10+
"prepare": "rm -rf dist dist.* ; tsc -p tsconfig.dist.json && webpack && npm run asbuild",
1111
"prepublishOnly": "TEST_DIST=true npm run test",
1212
"clean": "rm -rf build dist dist.*",
1313
"test": "mocha 'test/**/*.test.ts'",
@@ -24,9 +24,9 @@
2424
"profile:encode": "rm -f isolate-*.log ; node --prof --require ts-node/register -e 'require(\"./benchmark/profile-encode\")' && node --prof-process --preprocess -j isolate-*.log | npx flamebearer",
2525
"profile:decode": "rm -f isolate-*.log ; node --prof --require ts-node/register -e 'require(\"./benchmark/profile-decode\")' && node --prof-process --preprocess -j isolate-*.log | npx flamebearer",
2626
"benchmark": "ts-node benchmark/benchmark-from-msgpack-lite.ts",
27-
"asbuild:untouched": "asc assembly/index.ts -b build/wasm/untouched.wasm -t build/wasm/untouched.wat --sourceMap --validate --debug",
28-
"asbuild:optimized": "asc assembly/index.ts -b build/wasm/optimized.wasm -t build/wasm/optimized.wat --sourceMap --validate -O3",
29-
"asbuild": "npm run asbuild:untouched && npm run asbuild:optimized"
27+
"asbuild:untouched": "asc assembly/index.ts -b build/wasm/untouched.wasm -t build/wasm/untouched.wat --sourceMap --validate --debug --measure",
28+
"asbuild:optimized": "asc assembly/index.ts -b build/wasm/optimized.wasm -t build/wasm/optimized.wat --sourceMap --validate -O3 --measure",
29+
"asbuild": "rm -rf build/wasm && npm run asbuild:untouched && npm run asbuild:optimized && ts-node tools/pack-wasm.ts"
3030
},
3131
"repository": {
3232
"type": "git",
@@ -45,6 +45,7 @@
4545
"homepage": "https://msgpack.org/",
4646
"devDependencies": {
4747
"@bitjourney/check-es-version-webpack-plugin": "^1.0.2",
48+
"@types/base64-js": "^1.2.5",
4849
"@types/mocha": "^5.2.6",
4950
"@types/node": "^11.13.10",
5051
"@typescript-eslint/eslint-plugin": "^1.9.0",
@@ -75,7 +76,9 @@
7576
"webpack": "^4.30.0",
7677
"webpack-cli": "^3.3.1"
7778
},
78-
"dependencies": {},
79+
"dependencies": {
80+
"base64-js": "^1.3.0"
81+
},
7982
"files": [
8083
"src/**/*.*",
8184
"dist/**/*.*",

‎src/Decoder.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { prettyByte } from "./utils/prettyByte";
22
import { ExtensionCodec } from "./ExtensionCodec";
33
import { getInt64, getUint64 } from "./utils/int";
44
import { utf8Decode } from "./utils/utf8";
5-
import { utf8Decode2} from "../wasmModule";
5+
import { utf8DecodeWasm,WASM_AVAILABLE} from "./wasmFunctions";
66
import { createDataView, ensureUint8Array } from "./utils/typedArrays";
77

88
enum State {
@@ -47,8 +47,6 @@ export const DataViewIndexOutOfBoundsError: typeof Error = (() => {
4747

4848
const MORE_DATA = new DataViewIndexOutOfBoundsError("Insufficient data");
4949

50-
const USE_WASM = process.env.USE_WASM === "true";
51-
5250
export class Decoder {
5351
totalPos = 0;
5452
pos = 0;
@@ -382,8 +380,8 @@ export class Decoder {
382380
}
383381

384382
let object: string;
385-
if (USE_WASM) {
386-
object = utf8Decode2(this.bytes, this.pos + headOffset, byteLength);
383+
if (WASM_AVAILABLE) {
384+
object = utf8DecodeWasm(this.bytes, this.pos + headOffset, byteLength);
387385
} else {
388386
object = utf8Decode(this.bytes, this.pos + headOffset, byteLength);
389387
}

‎src/wasmFunctions.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
let wasmModule: any;
2+
try {
3+
wasmModule = require("../build/wasm/optimized.wasm.js").wasmModule;
4+
} catch {
5+
// WebAssembly is not supported.
6+
}
7+
8+
declare var WebAssembly: any;
9+
const WASM_MEMORY_PAGE_SIZE = 0x10000; // 64KiB
10+
11+
const defaultWasmInstance = wasmModule && new WebAssembly.Instance(wasmModule);
12+
13+
export const WASM_AVAILABLE = !!wasmModule && process.env.NO_WASM !== "true";
14+
15+
function copyArrayBuffer(dest: ArrayBuffer, src: Uint8Array) {
16+
const destView = new Uint8Array(dest);
17+
destView.set(src);
18+
}
19+
20+
export function utf8DecodeWasm(
21+
bytes: Uint8Array,
22+
offset: number,
23+
byteLength: number,
24+
wasmInstance = defaultWasmInstance,
25+
): string {
26+
if (!wasmInstance) {
27+
throw new Error("No WebAssembly available");
28+
}
29+
30+
const currentMemorySize: number = wasmInstance.exports.memory.buffer.byteLength;
31+
const requiredMemorySize = bytes.length * 3; // input(utf8) + output(utf16)
32+
if (currentMemorySize < requiredMemorySize) {
33+
const page = Math.ceil((requiredMemorySize - currentMemorySize) / WASM_MEMORY_PAGE_SIZE);
34+
wasmInstance.exports.memory.grow(page);
35+
}
36+
37+
copyArrayBuffer(wasmInstance.exports.memory.buffer, bytes.subarray(offset, offset + byteLength));
38+
// console.log(instanceMemory.subarray(0, 10));
39+
40+
const outputStart = Math.ceil(byteLength / Uint16Array.BYTES_PER_ELEMENT) * Uint16Array.BYTES_PER_ELEMENT;
41+
const outputEnd = wasmInstance.exports.utf8ToUtf16(byteLength, outputStart);
42+
const codepoints = new Uint16Array(
43+
wasmInstance.exports.memory.buffer,
44+
outputStart,
45+
(outputEnd - outputStart) / Uint16Array.BYTES_PER_ELEMENT,
46+
);
47+
// console.log([byteLength, outputStart, outputEnd]);
48+
// console.log(instanceMemory.subarray(0, 10));
49+
// console.log(utf16array);
50+
return String.fromCharCode.apply(String, codepoints as any);
51+
}

‎tools/pack-wasm.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// pack build/wasm/*.wasm
2+
3+
import fs from "fs";
4+
import { resolve } from "path";
5+
import base64 from "base64-js";
6+
7+
const artifactDir = resolve(__dirname, "../build/wasm");
8+
for (const basename of fs.readdirSync(artifactDir)) {
9+
const file = resolve(artifactDir, basename);
10+
if (!file.endsWith(".wasm")) {
11+
continue;
12+
}
13+
14+
const blob = fs.readFileSync(file);
15+
fs.writeFileSync(
16+
`${file}.js`,
17+
`// generated from ${basename}
18+
var base64 = require("base64-js");
19+
module.exports.wasmModule = new WebAssembly.Module(
20+
base64.toByteArray(
21+
${JSON.stringify(base64.fromByteArray(blob))}
22+
));
23+
`,
24+
);
25+
}

‎wasmModule.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /