真实世界的 WebAssembly
Posted 刘祺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了真实世界的 WebAssembly 相关的知识,希望对你有一定的参考价值。
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议(https://creativecommons.org/licenses/by-nc/4.0/deed.zh)进行许可。
致歉
在本次更新时第1章的部分内容仍未完成,在此给各位读者带来的不便表示歉意
第2章 从模块到函数
我们在第1章中了解到了 WebAssembly 的运行与编译机制。(更新时未完成)那么从这里开始我们开始逐渐接触真正的 WebAssembly 程序设计的知识。当然说到底 WebAssembly 仍然是一种汇编语言,很可惜它并不像微软的 ILAsm 那样支持带有继承性的面向对象的程序设计(注1)。它和其他汇编语言一样,通过跳转来实现流程控制,也就是留给我们了很大的发挥空间。一个好的汇编语言的初步学习途径自然是和某种高级语言进行对比。相信一些学习过汇编语言的读者都是和 C 语言进行对比学习的。当然一些学习 ILAsm 的读者可能是和 C# 对比学习的。那么我们学习 WebAssembly 当然就是和 Rust 语言进行对比学习了,不过考虑到很多读者对 Rust 语言可能并不熟悉,这里我们也给出一种尽量不使用继承(注2)的 C# 语言作为参考。我们之所以选择 C# 是因为绝大多数读者都可以看懂 C# 的语法,而它有具有几乎现代高级语言的大多数特性。除此之外诸如 Unity 引擎主要是使用 C# 语言做脚本的,而 WebAssembly 在游戏开发上恰恰能大显身手。
注1:在《真实世界的 WebAssembly》指的面向对象是没有继承的面向对象,这符合编程语言的目前较为流行的观点。例如 Rust 语言是没有继承性的,而是通过特征实现继承所解决的代码复用问题。
注2:毕竟在 C# 中想要完全不使用继承还是很难做到的,而且这样也并不方便。
2.1 什么是模块
一个 WebAssembly 必须要有一个模块,模块是 WebAssembly 的基础。即使它只有一个空模块。
;; 这只是一个空模块,没有任何意义 (module) |
此外用两个分号引导的是注释行,您可以用它来代替 Rust 和 C# 中的双斜线进行注释。
我们现在来给它加上一些东西,让它用一点儿用途。这里我们发现了模块里面包含了两条子句。import 子句导入了一个函数,并把这个函数绑定到了一个内部标识符 $hello 上面,在 WebAssembly 中标识符需要以 $ 开头。
;; 这是一个示例欢迎程序 (module (import "io" "hello" (func $hello)) (func (export "print") call $hello ) ) |
另一条子句定义了一个函数,并没有绑定到任何的标识符上,不过将其自身通过 export 子句导出到了一个名为 print 的标识符上。那么这个 print 在 javascript 里面是可以使用的。
我们来看一下 JavaScript 这方面的写法。我们看到我们引入的东西是通过 importObject 进行引入的。我们引入了一个函数,它的功能是在控制台输出“hello, wasm”的字样。
var importObject = { io: { hello: function() { console.log("hello, wasm"); } } }; fetchAndInstantiate('demo.wasm', importObject).then(function(instance) { instance.exports.print() }); |
现在编译并运行这个程序,打开您的 Web 控制台相信您一定能够看到预期的结果。
笔者在写这一部分的时候一直在调整程序,目前一部分程序在笔者的计算机上已经能够自己处理内存中的信息并返回字符串了。而笔者调试完这些程序的时候已经快凌晨三点了,所以就没有更新。还请各位读者谅解
关于封面: 一些著名的技术出版商都会以较为统一的封面设计来标识自己的系列图书,譬如 O'Reilly 的动物书、Packt 的一张照片以及 Manning 的人像画。所以笔者自己的系列就以知名艺术品作为封面了,所以下回去博物馆就不要只围着《蒙娜丽莎》了。同时笔者也希望大家能够在关注技术的同时,多留意生活中的美。
以上是关于真实世界的 WebAssembly 的主要内容,如果未能解决你的问题,请参考以下文章
探索WebAssembly实现iOS热修复/第一篇/WebAssembly快速上手