引子
Any application that can be written in JavaScript, will eventually be written in JavaScript. ——Atwood's Law
有人用 JavaScript 做語法詞法解析烟很,有人寫了 x86 模擬器, 還有人用 JavaScript 寫了可自舉的 JavaScript 引擎。JavaScript 早已經(jīng)在”重新發(fā)明一切”的路上一騎絕塵了裳凸,JavaScript 的流行也使它始終位于各大語言排行榜上的前列壹甥,這無疑是屬于 JavaScript 程序yuan們最好的時代银还。
這并非是因為 JavaScript 是門優(yōu)秀的語言 (恰恰相反),而是因為當(dāng)今的世界是 Web 的世界度硝,Web 的載體瀏覽器只會說 JavaScript。這難免使人眼紅荡碾,王侯將相,世人無數(shù)次想要取代 JavaScript 的地位局装,目前為止的歷史我們都看到了坛吁,無一不鎩羽而歸。求上不得铐尚,得其中拨脉,最新成果是大家(伙兒)齊心協(xié)力把 JavaScript 變成了新一代的匯編語言。請移步這里看大家的最新成果宣增。
WebAssembly
去年 11 月 13 日玫膀,Mozilla 在其官方博客上發(fā)表了一篇文章,WebAssembly support now shipping in all major browsers爹脾,指出當(dāng)今世界四大主流瀏覽器 Firefox匆骗,Chrome劳景,Safari誉简,Edge(排名分先后)碉就,都已經(jīng)支持了名為 WebAssembly 的新技術(shù),并回顧了一路走來的艱難歷程闷串。最后指出這是新時代的開端瓮钥,大家一起歡呼吧。那么烹吵,WebAssembly 到底是啥碉熄?讓我們發(fā)出發(fā)聾振聵的三連問:
可以吃嗎?
請移步 WebAssembly 官網(wǎng)肋拔。官網(wǎng)解釋如下:
WebAssembly or wasm is a new portable, size- and load-time-efficient format suitable for compilation to the web.
關(guān)鍵詞:
- 可移植: WebAssembly 是一種可移植的二進(jìn)制格式锈津,它不依賴于具體的瀏覽器平臺。
- 高效:WebAssembly 被設(shè)計為針對 Size 和 Load Time 進(jìn)行優(yōu)化的格式凉蜂,可以在各個硬件平臺上以 native speed 運(yùn)行琼梆。
- 安全:WebAssembly 是運(yùn)行在沙盒內(nèi)的,甚至可以和當(dāng)前的 JavaScript 虛擬機(jī)共享一套環(huán)境窿吩,并且也遵守瀏覽器各種跨域不跨域的規(guī)章制度茎杂。
- 開放:WebAssembly 是開放標(biāo)準(zhǔn),不受某一家廠商控制(Oracle你聽到了嗎)纫雁。并且被設(shè)計為可以和 JavaScript API 和 Context 交互煌往。
簡而言之,WebAssembly 可以被看做是通過瀏覽器運(yùn)行的某種高效的開放的二進(jìn)制格式轧邪,并且可以和 JavaScript 環(huán)境互通刽脖。
WebAssembly 的目的是取代 JavaScript 嗎?FAQ 這樣回答:不忌愚,WebAssembly 是被設(shè)計來補(bǔ)充而不是替代 JavaScript曲管。隨著時間推移,越來越多的語言可以被編譯為 WebAssembly菜循,但是 JavaScript 還是作為 Web 唯一的動態(tài)語言而存在翘地。
這樣看來老二的位置擺得很正嘛。對于 WebAssembly癌幕, 筆者最看重的一點(diǎn)是作為開放標(biāo)準(zhǔn)的同時有粗大腿的支持 (M$ Google Apple Mozilla)衙耕,這才是它有可能活下來的原因。問題是可以吃嗎勺远,答案當(dāng)然是可以吃(佛系碼農(nóng)也可以不吃)橙喘。
怎么吃?
WebAssembly 同時存在一個二進(jìn)制格式和一個文本的描述格式胶逢,這很像是機(jī)器語言和匯編語言的關(guān)系厅瞎。這里我們用一個例子解釋一下饰潜。
事實(shí)上,WebAssembly 可以被看作是運(yùn)行在一個 structured stack virtual machine 里和簸,懂行的朋友一眼就可以看出這和 Java bytecode 非常的像彭雾。所以大家不要以為 WebAssembly 是在重新發(fā)明 Flash 了,這貨明明是在重新發(fā)明 Java Applet 啊锁保,好吧 Silverlight 也有點(diǎn)像...薯酝。順帶一提,Android 的 Dalvik 為了效率爽柒,使用的是 register-based virtual machine吴菠。對 WebAssembly spec 感興趣的朋友可以移步這里。
作為 WebAssembly 的 MVP浩村,C/C++ 及其類庫的支持是首當(dāng)其沖的做葵。因為基于 LLVM 的平臺,所以理論 LLVM 支持的語言都可以編譯為 WebAssembly心墅,C/C++酿矢,rust,甚至 .net 和 Java 也可以編譯到 WebAssembly嗓化,只不過托管語言都需要附帶一個巨大的runtime棠涮。
下面我們以 C/C++ 為例,我們寫一個函數(shù)給 JavaScript 使用刺覆。
步驟:
安裝 WebAssembly 構(gòu)建工具鏈 emscripten严肪,針對 macOS,請參考這里
安裝后谦屑,執(zhí)行
emcc --version
判斷是否成功-
創(chuàng)建 C++ source:
cat random.cc
include <random>
include <cmath>
extern "C" {
long normal_rand() {
static std::random_device rd{};
static std::mt19937 gen{rd()};return std::lround(std::normal_distribution<>(0, 100)(gen));
}
}
`</pre>這里用 C++ 產(chǎn)生一個正態(tài)分布驳糯,期望為
0
,方差100
的隨機(jī)數(shù)氢橙,然后導(dǎo)出為一個 C 函數(shù)normal_rand
執(zhí)行
emcc --bind -std=c++14 --emrun -s WASM=1 -s EXPORTED_FUNCTIONS='["_normal_rand"]' -O3 -o random.html random.cc
順利的話會在當(dāng)前目錄生成如下文件
<pre>`$ ls -l
total 496
-rw-r--r-- 1 haoli staff 810 Dec 24 21:44 random.cc
-rw-r--r-- 1 haoli staff 102728 Dec 24 22:17 random.html
-rw-r--r-- 1 haoli staff 120624 Dec 24 22:17 random.js
-rw-r--r-- 1 haoli staff 20130 Dec 24 22:17 random.wasm
random.wasm
就是我們的 WebAssembly酝枢,random.js
和 random.html
是模板代碼,幫助我們加載 WebAssembly悍手。
執(zhí)行 emrun --no_browser --port 8821 random.html
啟動一個 WebServer
用支持 WebAssembly 的瀏覽器訪問http://localhost:8821/random.html帘睦,然后在 console 里面執(zhí)行 Module._normal_rand()
即可看到結(jié)果
怎么做好吃?
古往今來坦康,在瀏覽器里面嘗試改善 JavaScript 性能和增強(qiáng)功能的嘗試大約都失敗了吧竣付,前有 ActiveX,Java Applet滞欠,F(xiàn)lash古胆,后有 Silverlight,F(xiàn)lex筛璧,NaCl逸绎。WebAssembly 應(yīng)該是各個瀏覽器大佬的最新嘗試惹恃。不過這次大家都學(xué)乖了,沒人指(xi)望一個私有標(biāo)準(zhǔn)會成功棺牧,于是聯(lián)合起來開發(fā)一個開放的標(biāo)準(zhǔn)巫糙。
至少目前看來,結(jié)果還是很讓人欣喜的陨帆。因為開放標(biāo)準(zhǔn)的緣故曲秉,除了上面的 emscripten,還有大量的工具開始支持 WebAssembly疲牵,甚至 clang 可以直接指定 target 為 WebAssembly。加上瀏覽器把諸如 DOM API 以及 WebGL API 都暴露給了 WebAssembly榆鼠,應(yīng)用場景相當(dāng)可觀纲爸。首當(dāng)其沖的就是游戲廠商,Epic 和 Unity 都是 WebAssembly 的早期嘗試者妆够,他們已經(jīng)把自己的游戲引擎移植到 Web 平臺而不用重寫代碼识啦。不僅如此, WebAssembly 還支持 non-web 的場景神妹,比如 NodeJs 也開始支持 WebAssembly颓哮。WebAssembly 官網(wǎng)有個 use case 清單,列舉了可能的應(yīng)用場景鸵荠。圖形圖像的處理冕茅,計算機(jī)輔助設(shè)計,AR/VR蛹找,VPN姨伤,加解密等等。到那時庸疾,前端可以玩出的花樣乍楚,想象空間實(shí)在太大。
有點(diǎn)過于美好了哈届慈,我們還是就此打住徒溪,拭目以待吧。
Reference
這里列舉一些 WebAssembly 相關(guān)的資源金顿,各位隨喜:
- Funky Karts, 移植到 WebAssembly 的網(wǎng)頁游戲臊泌,作者在網(wǎng)站記錄了學(xué)習(xí) WebAssembly 到移植成功的全過程。
- WasmExplorer串绩,在線的 C/C++ to WebAssembly 編輯器缺虐,同時也可以查看 Assembly 內(nèi)容。
- WasmFiddle礁凡,另一個在線編輯 WebAssembly 的工具
- WasmRocks WebAssembly 新聞?wù)?/a>高氮。
- emscripten 官網(wǎng)慧妄。
文/ThoughtWorks李好