WebAssembly - WASM

  • 简述

    WebAssembly 也称为 wasm,是对 Javascript 的改进。它被设计为在浏览器中运行,就像 javascript 和 nodejs 一样。当编译任何高级语言(如 C、C++、Rust)时,您碰巧得到了 wasm 输出。
    考虑以下 C 程序 -
    
    int factorial(int n) {
       if (n == 0) 
          return 1; 
       else 
          return n * factorial(n-1); 
    }
    
    利用https://mbebenita.github.io/WasmExplorer/上提供的 WasmExplorer来获取编译后的代码,如下所示 -
    Wasm 浏览器
    阶乘程序的 WebAssembly 文本格式如下所述 -
    
    (module 
       (table 0 anyfunc) 
       (memory $0 1) 
       (export "memory" (memory $0)) (export "factorial" (func $factorial)) 
       (func $factorial (; 0 ;) (param $0 i32) (result i32)
          (local $1 i32) 
          (local $2 i32) 
          (block $label$0 
             (br_if $label$0 
                (i32.eqz 
                   (get_local $0) 
                )
             )
             (set_local $2 
                (i32.const 1) 
             ) 
             (loop $label$1 
                (set_local $2 
                   (i32.mul 
                      (get_local $0) (get_local $2) 
                   ) 
                ) 
                (set_local $0 
                   (tee_local $1        (i32.add 
                      (get_local $0) (i32.const -1) 
                   ) 
                   ) 
                ) 
                (br_if $label$1      (get_local $1) 
                ) 
             ) 
             (return 
                (get_local $2)
             ) 
          ) 
          (i32.const 1) 
       )
    )
    
    使用 Wat2Wasm 工具,您可以查看 WASM 代码,就像下面提到的一样 -
    Wat2Wasm 工具
    开发人员不应该在 wasm 中编写代码或学习在其中编写代码,因为它主要是在您编译高级语言时生成的。
  • 堆垛机型号

    在 WASM 中,所有指令都被压入堆栈。参数被弹出,结果被推回堆栈。
    考虑以下添加 2 个数字的 WebAssembly 文本格式 -
    
    (module
       (func $add (param $a i32) (param $b i32) (result i32) 
          get_local $a 
          get_local $b 
          i32.add
       )
       (export "add" (func $add))
    )
    
    函数的名称是$add,它有 2 个参数 $a 和 $b。结果是一个 32 位整数类型。使用 get_local 访问局部变量,使用 i32.add 执行添加操作。
    执行时添加 2 个数字的堆栈表示如下 -
    堆
    步骤 1 - get_local $a 指令的执行,第一个参数,即 $a 被压入堆栈。
    步骤 2 - 在执行 get_local $b 指令期间,第二个参数,即 $b 被压入堆栈。
    步骤 3- i32.add 的执行将从堆栈中弹出元素并将结果推回堆栈。堆栈内最后保留的值是函数 $add 的结果。