摘要:在當前階段,僅僅只是字節碼規范。如果都沒有將代碼編譯為字節碼的工具,要起步就很困難了。接下來要做的是使用將格式的代碼轉換為二進制碼。運行文件,最后就能得到瀏覽器需要的真正的二進制碼。
本文轉載自:眾成翻譯
譯者:文藺
鏈接:http://www.zcfy.cc/article/1031
原文:http://cultureofdevelopment.com/blog/build-your-first-thing-with-web-assembly
拖拖拉拉好久,終于把個人博客整出來了。鳴謝 @pinggod。厚著臉安利一下,地址是 http://www.wemlion.com/。歡迎訪問,歡迎收藏。
頭一次聽說 WebAssembly 的時候就覺得很酷,然后就超興奮地開始嘗試。但從一開始嘗試的過程就不順利,越來越讓人灰心。本文的目的就是解決問題,讓你免受困擾。
讀者須知本文寫作于 2016 年 6 月 24 日。WebAssembly 是一項很新的、不穩定的技術;隨著其標準化過程發展,本文中的任何內容都可能是錯誤的。
不過先不管了....
WebAssembly 是什么好吧,官網是這么描述的:
WebAssembly,或者稱作 wasm,是一項適用于 Web 編譯的可移植的、體積與加載高效的格式。(WebAssembly or wasm is a new portable, size- and load-time-efficient format suitable for compilation to the web.)
嗯...什么鬼?什么格式?文本(Text)?二進制(Binary)?老實說,這個描述真糟糕。所以不管它,收起那些 binggo 游戲卡(buzzword bingo cards,一種填詞游戲,這些詞通常都是流行語,閱讀https://en.wikipedia.org/wiki/Buzzword_bingo了解更多 —— 譯者注),根據我所有的經驗來描述吧:
WebAssembly/wasm 是用來編寫高性能的、瀏覽器無關的 Web 組件的一種字節碼規范。(WebAssembly or wasm is a bytecode specification for writing performant, browser agnostic web components.)
有此妙語,聽起來超棒,但仍然沒 get 到點,接下來重點來了。WebAssembly 通過靜態類型變量實現性能提升,運行時靜態類型變量引用比動態類型變量更有效率。WebAssembly 由 W3C Community Group 制定,最終將被所有規范兼容的瀏覽器支持。還有殺手锏,最終我們可以使用任何語言編寫這些 Web 組件(web components)。
聽起來酷了很多,不是么?
一起開始吧學習新東西的時候,我通常會找盡可能最簡單的例子來看它是如何工作的。不幸的是,對 WebAssembly 來說,這不太現實。在當前階段,wasm 僅僅只是字節碼規范。想象回到 1996 年,假如太陽公司(Sun Microsystems)的一些工程師們帶來了 JVM,但卻...沒有 Java....若果真如此,我想當時的對話可能是這樣的:
—— “伙計們,快來看看我們做的這個執行字節碼的虛擬機!”
—— “真棒!但我們給它怎么寫代碼?”
圖:字節碼形式的 HelloWorld
—— “嗯..這問題提得好。等會兒我查查看。”
—— “真棒,如果遇到了任何問題,告訴我們你的想法,在我們的 github page 上貼出來。”
—— “你說對啦。我們現在先去看看其他項目。”
這個例子有些糟糕,因為 JVM 是基于 Java 語言的;盡管如此,希望你還是 get 到點了。如果都沒有將代碼編譯為字節碼的工具,要起步就很困難了。那我們要怎么開始?
WebAssembly 之前有什么多數技術都是創新的結果,特別是當合理的嘗試成為正式規范時。wasm 也不例外,它實際上是 asm.js 的工作的延續, asm.js 是一個編寫 javascript 組件的的規范,可編譯為靜態類型。wasm 的規范拓展了這些創意,它接受任何語言編譯而成的字節碼,這些字節碼作為二進制文件而非文本文件通過網絡傳輸;規范由很多來自主流瀏覽器廠商的代表們一起制定,而非僅僅是 Mozilla。
asm.js 僅僅是一個使用 javascript 語言特征的最小子集編寫 javascript 的規范。你可以手寫一些簡單的 asm.js 代碼,如果你想弄臟你的手,這正是極好的方式。(等會兒最好將這放在多帶帶的文件中,通常約定文件名格式為 your-module-name.asm.js。))
function MyMathModule(global) { "use asm"; var exp = global.Math.exp; function doubleExp(value) { value = +value; return +(+exp(+value) * 2.0); } return { doubleExp: doubleExp }; }
這還不是一個特別有用的函數,但符合規范。如果你覺得這很二,別人也是這么覺得的,不過基本上每一個字符都是必須的。在這當中,一元運算符 + 的作用是類型注解,這樣編譯器會知道那些變量是 double 類型的,運行時就不必再次分辨它們是什么。它相當挑剔,如果你把什么地方弄得一團糟,火狐控制臺會給你一些合理的錯誤信息。
如果你想在瀏覽器中使用,像下面這樣:
var myMath = new MyMathModule(window); for(var i = 0; i < 5; i++) { console.log(myMath.doubleExp(i)); }
一切正常的話,結果大概像下圖這樣:
開始嘗試 WebAssembly現在我們已經有了一個可以工作的 asm.js 代碼片段,可以使用 WebAssembly github page 提供的工具將其編譯為 wasm。自己克隆代碼倉庫構建工具吧。這最麻煩了。這些工具一直在不斷發展,代碼會時不時掛掉,特別是在 Windows 環境下。
不管你是用 Windows 還是 Mac,電腦上必須要安裝 make 和 cmake 命令行工具。如果你在使用 Windows,你還需要安裝 Visual Studio 2015。Mac 用戶按照這里的說明 操作;Windows 用戶按照這個說明操作。
圖: Windows 下的工具構建
對 WebAssembly 團隊來說,發布可以工作的二進制文件意味著朝著正確的方向前進了一大步。
構建成功之后,binaryen 目錄下會有一個 bin 文件夾,其中有一些用來將 asm.js 轉換為 wasm 的工具。第一個工具是 asm2wasm.exe。它將 asm.js 代碼轉換為 .s 格式的代碼,這些代碼是生成 wasm 所需的抽象語法樹(AST)的文本表現形式。運行工具,最終會得到類似下面的東西:
(module (memory 256 256) (export "memory" memory) (type $FUNCSIG$dd (func (param f64) (result f64))) (import $exp "global.Math" "exp" (param f64) (result f64)) (export "doubleExp" $doubleExp) (func $doubleExp (param $0 f64) (result f64) (f64.mul (call_import $exp (get_local $0) ) (f64.const 2) ) ) )
以后我們可以逐行分析上面的代碼,但現在我只想讓你看下它的樣子。我還得提醒你一點,因為 wasm 是二進制格式的,所以像你今天對 javascript 所做的那樣右擊、查看源碼是行不通的。從頭到尾都是二進制碼。目前的計劃是查看 wasm 模塊源碼時對二進制格式進行反匯編,讓人能讀懂。
接下來要做的是使用 wasm-as.exe 將 .s 格式的代碼轉換為 wasm 二進制碼。運行文件,最后就能得到瀏覽器需要的真正的 wasm 二進制碼。
圖:將 asm.js 轉換為 wasm 二進制碼
圖:wasm 二進制碼
緊接著,安裝最新版的 Firefox 或 Chrome Canary,并啟用 WebAssembly。
如果你使用的是 Firefox,在地址欄中輸入 about:config,點擊“確認我會保證小心”。然后在搜索框中輸入 wasm,雙擊 javascript.options.wasm 將值設置為 true,然后重啟瀏覽器。
如果你使用的是 Chrome Canary,打開 chrome://flags,往下翻,找到 Experimental WebAssembly,點擊“啟用”鏈接,再重啟瀏覽器。
最后一步就是讓模塊在瀏覽器中跑起來。初次嘗試時,這又是一大痛點,完全不知道怎么做。在規范中使用 wasm 模塊的 API 一點都沒找到。最后我在 Canary 的控制臺上輸入 WebAsse,并沒有任何提示。接著輸入 Was 的時候,提示出來了!控制臺上打印出的對象大概最簡陋的文檔了,不過這時候我突然想到,可以用一些其他工具 (emscripten) 將代碼編譯為 wasm。不過這是另外一篇博客的話題了。
一段時間之后,鼠標落在了 WebAssembly 的設計文檔倉庫上。我看到了一個名為 JS.md 的文件,點擊之后,有一個 API 的說明。仔細看頂部斜體的文字。但最精彩的部分還是最底部的代碼片段,演示了如何最低限度地加載模塊。我所需要做的就是拆出相關部分進行嘗試。
fetch("my-math-module.wasm") .then(function(response) { return response.arrayBuffer(); }) .then(function(buffer) { var dependencies = { "global": {}, "env": {} }; dependencies["global.Math"] = window.Math; var moduleBufferView = new Uint8Array(buffer); var myMathModule = Wasm.instantiateModule(moduleBufferView, dependencies); console.log(myMathModule.exports.doubleExp); for(var i = 0; i < 5; i++) { console.log(myMathModule.exports.doubleExp(i)); } });
把代碼放到 html 文件中,啟動本地文件服務器,在瀏覽器中加載頁面。下面是在瀏覽器中的結果:
瀏覽器中運行的 wasm (至少嘗試運行了)
我估計需要去提交一個 bug 報告了。記著,一切都是實驗性的、不穩定的,所以當此類事情發生的時候,別灰心喪氣。
恭喜你你已經完成了第一個 WebAssembly 組件。接下來做些什么?目前我們碰到的還只是皮毛而已。在本例中手寫 asm.js 很重要,但需要時間和耐心。使用 emscripten 將應用轉換為 asm.js 要簡單多了。關于這一點,我強烈建議你閱讀 asm.js 規范,特別是內存模型的部分,因為其中的許多概念都被遷移到 WebAssembly 上了。另外一個怪異的事情是,目前還不能直接將數組作為函數參數。人們已經達成共識,這需要改變,但規范中尚未有關于這一點的。去看看指針邏輯吧。
還有一點,在 wasm 中做一些工作的時候,你可能發展實際上 WebAssembly 還沒普通的 javascript 運行得快。記住,現代的 javascript 引擎已經是高度優化的,wasm 要趕上這速度還需要時間。WebAssembly 還尚未進入準備生產的階段。
如果你有任何關于 wasm 或者本文中提到的工具的問題,在 Stack Overflow 中提出來,記得標上恰當的 tag。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87853.html
摘要:使用,您可以直接訪問原始字節碼這可能令人擔憂。可以根據索引從中拿到字符串現在,很多人并不知道如何在中使用字節碼。你需要將字節碼轉換為有用的內容,比如說字符串。通過防止瀏覽器級內存泄漏并提供內存隔離,使事情變得更安全。 原文鏈接:https://fanmingfei.com/posts/... 這是系列文章第二篇: 使用 JavaScript 創建一個 WebAssembly 模塊的實...
摘要:原文鏈接這是系列文章第一篇使用創建一個模塊的實例。將會創建模塊的實例。一旦模塊實例化完成,主進程就會拿到返回的實例。如果創建一個實例,你還需要其它的參數。使用這些低級裝備這些來構建實例。模塊本身沒有任何狀態。 原文鏈接:https://fanmingfei.com/posts/... 這是系列文章第一篇: 使用 JavaScript 創建一個 WebAssembly 模塊的實例。 W...
摘要:中的什么是在第一篇文章中,我介紹了可以導入的四中不同的類型。可能是以某種方式插入到內存中的惡意代碼,可能嵌入到字符串中。是存在于內存之外的數組。如果模塊想要調用這些函數,它將該索引傳遞給一個名為的操作。 原文鏈接: https://fanmingfei.com/posts/... 這是系列文章第三篇: 使用 JavaScript 創建一個 WebAssembly 模塊的實例。 Web...
摘要:有哪些新特性有哪些改進學著使用這個新版本,來構建更快的應用吧。繼版本之后,花了將近八個月的時間來發布。的創始人之一,,建議用戶使用,以便使用最優的性能,是因為源代碼使用了新特性。全新的插件系統配備了全新整改的插件系統。 本文原文地址:https://auth0.com/blog/webpac...第一次翻譯,不當之處,歡迎指正 官方已經發布了Webpack 4.0。有哪些新特性?有哪些...
摘要:你可以從內存中直接拿東西,也可以直接往內存里存東西當你把或者其它語言編譯為時,編譯工具會在里增加一些輔助代碼。 作者:Lin Clark 譯者:Cody Chan 原帖鏈接:A crash course in memory management 這是圖解 SharedArrayBuffers 系列的第一篇: 內存管理碰撞課程 圖解 ArrayBuffers 和 SharedA...
閱讀 996·2023-04-25 14:45
閱讀 2772·2021-09-30 09:59
閱讀 3114·2021-09-22 15:48
閱讀 2425·2019-08-30 15:55
閱讀 3467·2019-08-30 15:44
閱讀 535·2019-08-29 14:07
閱讀 3412·2019-08-26 13:45
閱讀 536·2019-08-26 11:31