AssemblyScript 初次使用

AssemblyScript

记一次AssemblyScript 的使用记录,

AssemblyScript 是使用 BinaryenTypeScript 编译成 WebAssembly

前言

WebAssembly 是一种接近机器语言的跨平台二进制格式。2017年3月份,四大主流浏览器厂商 Google Chrome、Apple Safari、Microsoft Edge 和 Mozilla FireFox 均宣布已经于最新版本的浏览器中支持了 WebAssembly

AssemblyScript 是使用 BinaryenTypeScript 编译成 WebAssembly

安装

1
npm i assemblyscript -D

脚手架

1
npx asinit .

自动生成

  • assembly/index.ts 入口文件

    1
    2
    3
    4
    // The entry file of your WebAssembly module.export 
    function add(a: i32, b: i32): i32 {
    return a + b;
    }
  • build目录 编译后 wasm文件存放

编译

1
npm run asbuild

node下使用

引用

脚手架会自动生成引入文件index.js

1
2
3
4
5
6
7
const fs = require("fs");
// 加载wasm模块
const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));
const imports = {};
Object.defineProperty(module, "exports", {
get: () => new WebAssembly.Instance(compiled, imports).exports
});

使用

新建个js

1
2
3
const { add } = require('./index.js');
const sum = add(1,1);
console.log(sum); // node运行输出: 2

浏览器下使用

引用

新建个js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 封装 https://github.com/torch2424/wasm-by-example/blob/master/demo-util/
const wasmBrowserInstantiate = async (wasmModuleUrl, importObject) => {
let response = undefined;

if (!importObject) {
importObject = {
env: {
abort: () => console.log("Abort!")
}
};
}

// Check if the browser supports streaming instantiation
if (WebAssembly.instantiateStreaming) {
// Fetch the module, and instantiate it as it is downloading
response = await WebAssembly.instantiateStreaming(
fetch(wasmModuleUrl),
importObject
);
} else {
// Fallback to using fetch to download the entire module
// And then instantiate the module
const fetchAndInstantiateTask = async () => {
const wasmArrayBuffer = await fetch(wasmModuleUrl).then(response =>
response.arrayBuffer()
);
return WebAssembly.instantiate(wasmArrayBuffer, importObject);
};
response = await fetchAndInstantiateTask();
}

return response;
};

// 引用
let wasmModule;
(async () => {
// Instantiate our wasm module
wasmModule = await wasmBrowserInstantiate('./build/optimized.wasm');
return wasmModule;
})();

使用

新建个html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dome</title>
</head>
<body>
<input type="text" id="a">
<span>+</span>
<input type="text" id="b">
<button id="btn">=</button>
<span id="sum">?</span>
<script src="index.js"></script>
<script>
const a = document.getElementById('a');
const b = document.getElementById('b');
const sum = document.getElementById('sum');
const btn = document.getElementById('btn');
btn.addEventListener('click', click);
function click() {
const result = wasmModule.instance.exports.add(parseFloat(a.value), parseFloat(b.value));
sum.innerText = result;
}
</script>
</body>
</html>