WebAssembly原理与核心技术
上QQ阅读APP看书,第一时间看更新

1.4 你好Wasm

大多数介绍编程技术的书,在第1章都会出现一个正式的“Hello,World!”程序,以致敬计算机先驱Brian Kernighan、Dennis Ritchie和他们的经典著作The C Programming Language。我已经准备好了这个程序,请看code/rust/examples/src/bin/ch01_hw.rs这个文件。


#![no_std]
#![no_main]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

extern "C" {
    fn print_char(c: u8);
}

#[no_mangle]
pub extern "C" fn main() {
    unsafe {
        let s = "Hello, World!\n";
        for c in s.as_bytes() {
            print_char(*c);
        }
    }
}

如果已经成功安装了Rust,就会编译生成Wasm二进制文件。如果没有安装Rust也没关系,因为我已经把编译好的Wasm二进制文件放在code/js目录里,文件名是ch01hw.wasm。同一目录下还有一个名为ch01hw.html的文件,代码如下所示。


<!DOCTYPE html>
<html>
  <head><title>Hello, World!</title></head>
  <body>
    <script>
      var str = "";
      var importObj = {env: {
          print_char: (c) => {
            str += String.fromCharCode(c);
            if (c == 10) {
              alert(str);
            }
          }
      }};
      fetch('ch01_hw.wasm').then(response =>
          response.arrayBuffer()
      ).then(buffer =>
          WebAssembly.instantiate(buffer, importObj)
      ).then(({module, instance}) =>
          instance.exports.main()
      );
    </script>
  </body>
</html>

现在我们已经用Rust编写了“Hello,World!”程序,然后把它编译成了Wasm二进制格式。在上面的代码里,我们通过浏览器提供的Wasm JavaScript API加载并实例化Wasm二进制模块,最后调用模块导出main()函数。请注意我们是如何在Rust代码中声明,并在JavaScript代码中定义print_char()函数的。如果觉得前面的代码不好理解也不必担心,这里只须初步认识一下Wasm即可,在后面的章节我们再仔细了解它。

把ch01hw.wasm和ch01hw.html文件上传到Web服务器(或者启动本地Web服务器),然后在浏览器中访问ch01_hw.html即可看到弹出的“Hello,World!”。