Zig 是一种通用编程语言和工具链,用于维护健壮、优化和可重用的软件,Zig 支持开箱即用的 Webassembly 构建,Zig
的实现是通过使用 LLVM 来提供编译目标,对Webassembly System Interface(WASI) 的支持尚处于积极开发中,可以参见官方文档。
Zig 从 0.4.0 开始提供对 WebAssembly 的实现。
Webassembly
WebAssembly 是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码而是为诸如 C、C++和 Rust 等低级源语言提供一个高效的编译目标。
Webassembly 1.0 已经在4个主要浏览器引擎中发布:
为了进一步推动模块化 WebAssembly 生态系统,Mozilla、Fastly、英特尔和红帽公司携手成立了ByteCode Alliance(字节码联盟)。ByteCode Alliance 是一个非营利组织,致力于在 WebAssembly 和 WebAssembly System Interface(WASI) 等标准的基础上创建安全的新软件基础。
Webassembly 的目标
作为 W3C WebAssembly Community Group 中的一项开放标准,WebAssembly 是为下列目标而生的:
- 快速、高效、可移植——通过利用常见的硬件能力,WebAssembly 代码在不同平台上能够以接近本地速度运行。
- 可读、可调试——WebAssembly 是一门低阶语言,但是它有确实有一种人类可读的文本格式(其标准即将得到最终版本),这允许通过手工来写代码,看代码以及调试代码。
- 保持安全——WebAssembly 被限制运行在一个安全的沙箱执行环境中。像其他网络代码一样,它遵循浏览器的同源策略和授权策略。
- 不破坏网络——WebAssembly 的设计原则是与其他网络技术和谐共处并保持向后兼容。
更多参见: MDN Webassembly概念
Zig 构建 Webassembly
1 life.zig 导出了三个函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// Advance the world by strong mutation
export fn advance() u32 {
....
WORLD.cells = cell_buf;
return num_changed;
}
export fn set_cell(index: u32) void {
if (index > NUM_CELLS) return;
WORLD.cells[index] = .Alive;
}
export fn get_char(index: u32) u32 {
if (index > NUM_CELLS) return '◻';
return switch (WORLD.cells[index]) {
.Dead => {
return '◻';
},
.Alive => {
return '◼';
},
};
}
|
2 在 life.js 中会调用这些 WASM 导出的方法
1
2
3
4
5
6
7
8
9
10
|
// Load WebAssembly module `life.wasm`
// https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/instantiateStreaming
Game = await WebAssembly.instantiateStreaming(
fetch("life.wasm"), importObject
)
set_cell = Game.instance.exports.set_cell;
advance = Game.instance.exports.advance;
get_char = Game.instance.exports.get_char;
wasm_loaed = true
...
|
3 在 index.html 加载life.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<html lang="en">
<head>
<title>Life Demo</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="button" id="button" label="button" value="BUTTON" />
<pre id="life_pre"></pre>
</body>
<script src="life.js"></script>
</html>
|
以上这些就是使用Zig 创建 WebAssemble 程序的代码。(非常感谢sleibrock/zigtoys)
4 构建 life.wasm
1
|
$ zig build-lib life.zig -target wasm32-freestanding -dynamic -rdynamic -O ReleaseSmall
|
更多构建说明参见 Ziglang.org。
5 运行
启动一个本地web server:
1
|
$ python3 -m http.server
|
在浏览器中,浏览:http://localhost:8000
参考
- Webassembly
- Webassembly developer guide
- MDN Webassembly
- Zig language Reference
- WebAssembly with Zig, Part 1
- WebAssembly With Zig, Pt. II
- ByteCode Alliance