Skip to content

特点:

  • WebAssembly 是一种新的编码方式,可以在现代的 Web 浏览器中运行
  • 一种低级的类汇编语言, 二进制格式,可以接近原生的性能运行,并为诸如 C/C++、C# 和 Rust 等语言提供编译目标,以便它们可以在 Web 上运行
  • 它提供了一条使得以各种语言编写的代码都可以接近原生的速度在 Web 中运行的途径
  • 它可以嵌入到浏览器中、作为独立的虚拟机运行,或集成到其他环境中。

前置知识

S-表达式

“S-表达式/运算式”(S-expression)或“sexp”(其中“S”代表“符号的”),是指一种以人类可读的文本形式表达半结构化数据的约定。

在编程中,S-表达式通常用作代码和数据的表示形式。它具有以下特点:

  • 简单的语法:S-表达式使用括号表示嵌套的列表,例如(1 2 (3 4))
  • 通用性:S-表达式不偏袒特定的语言,可以用于多种编程环境。
  • 易于解析:相对于其他格式(如XML),S-表达式的语法更简单,更容易解析。

一个简单的 S-表达式示例:

lisp
<!-- 表示模块 -->
(module)
<!-- 函数定义 -->
( func <signature> <locals> <body> )

; Common Lisp 中的 S-表达式
(+ 1 2 3) ; 表示将 1、2 和 3 相加,结果为 6

在这个示例中,(+ 1 2 3) 是一个 S-表达式,其中 + 是一个函数,它将后面的数字相加。这种表示形式在 Lisp 等语言中非常常见。

基本语法

实例化的方式

js
// 实例化一个模块  , steam的可以直接接受一个远端的文件
WebAssembly.instantiate(file)
WebAssembly.instantiateStreaming(fetch(file))
// 只编译成 WebAssembly.Module , 不进行实例化。
WebAssembly.compile()
WebAssembly.compileStreaming()

// 验证用的
WebAssembly.validate()

实例对象的使用

js
// 给定 ,返回一个数组,其中包含所有声明的导出的描述
instance.Module.exports()
// 给定 ,返回一个数组,其中包含所有声明的导入的描述。
instance.Module.imports()

代码实例

当然可以,这里有一个简单的WebAssembly的例子。这个例子是一个简单的加法函数。

wasm
(module
  (func $add (param $a i32) (param $b i32) (result i32)
    get_local $a
    get_local $b
    i32.add)
  (export "add" (func $add))
)

这个WebAssembly模块定义了一个名为add的函数,它接受两个32位整数作为参数,并返回它们的和。这个函数被导出,所以可以从JavaScript中调用它。

要在JavaScript中使用这个WebAssembly模块,你需要将上述代码保存为.wat文件,然后使用wat2wasm工具将其转换为.wasm文件。然后,你可以在JavaScript中加载和实例化这个.wasm文件,如下所示:

javascript
const fs = require('fs').promises;
const util = require('util');

async function main() {
  const buffer = await fs.readFile('add.wasm');
  const module = await WebAssembly.compile(buffer);
  // {} 是一个 importObj,这个对象是传入的,.wasm 文件可以来获取我们传入的参数
  const instance = await WebAssembly.instantiate(module,{});

  console.log(instance.exports.add(2, 3));  // 输出:5
}

main().catch(console.error);

这段JavaScript代码首先读取.wasm文件,然后编译和实例化WebAssembly模块。然后,它调用导出的add函数,并打印结果。