[譯]使用JavaScript建立一個WebAssembly模塊的實例

原文連接:https://fanmingfei.com/posts/...html

這是系列文章第一篇:web


WebAssembly是在Web上運行代碼的新途徑。使用它,你可使用C/C++編寫一些模塊,並在瀏覽器上運行閉包

目前,模塊不能自動運行。隨着ES模塊的發展,瀏覽器逐步開始支持ES模塊。WebAssembly 模塊將會像加載 ES 模塊同樣被加載。好比:<script type="module">函數

不過如今,你須要使用 JavaScript 來加載運行 WebAssembly 模塊。首先建立一個 WebAssembly 模塊的實例。而後,JavaScript 能夠調用 WebAssembly 實例上的方法。post

例如,咱們來看看React 如何實例化 WebAssembly模塊。(能夠看這個視頻來了解 React 如何實例化 WebAssembly 模塊。)spa

用戶加載頁面這個過程都是相同的。.net

頁面加載之後,瀏覽器開始下載JS文件。而後,一個 .wasm 文件將會被請求。這個文件裏包含了二進制的 WebAssembly 代碼。

Browser downloading a .js file and a .wasm file

咱們學要加載這些代碼文件才能運行它們。首先是 .js 文件,使用 React 的 JavaScript 文件。JavaScript 將會建立 WebAssembly 模塊的實例。

須要使用 WebAssembly.instantiate 方法來建立實例。

React.js robot calling WebAssembly.instantiate

咱們來仔細看看這個。

第一步,.wasm 文件裏的代碼其實就是模塊代碼,咱們將從 .wasm 文件中的二進制代碼傳遞給WebAssembly.instantiate

因此咱們須要將二進制代碼轉換成buffer,而且傳遞給 WebAssembly.instantiate 方法。

Binary code being passed in as the source parameter to WebAssembly.instantiate

而後,引擎就會將這個模塊編譯成當前的機器所能運行的東西。

可是咱們不想讓它在主線程運行。主進程已經很是忙了,由於它要處理 JavaScript、DOM、layout。咱們不想佔用主線程,因此,WebAssembly.instantiate 返回一個 promise。

Promise being returned as module compiles

這樣,主進程就能夠去作一些別的事情了。一旦模塊實例化完成,主進程就會拿到 promise 返回的實例。

若是建立一個實例,你還須要其它的參數。我以爲模塊就像是王者榮耀的裝備合成圖譜。

實例就像是合成後的裝備。若是想合成一個高級裝備,須要一些低級裝備。因此咱們須要一些其它的東西才能實例化一個 WebAssembly 模塊。

Instruction book next to WebAssembly robot

也就是WebAssembly.instantiate的第二個參數。這是一個須要導入到 WebAssembly 實例的對象:import object

Arrow pointing to importObject param of WebAssembly.instantiate

咱們將 import object 當作低級裝備。使用這些低級裝備(這些import object)來構建實例。就像裝備打造圖譜同樣,每個 WebAssembly 模塊都須要特殊的 imports。

Imports box next to WebAssembly robot

因此,若是你想實例化一個模塊的話,你須要傳入這個對象。傳入的對象的屬性值能夠是一下幾種類型:

  • values

  • function closures

  • memory

  • tables

Values

它能夠是一個變量。WebAssembly 的數據類型只有兩種,int 類型和 float 類型,因此 values 必須是這兩種類型中的一種。固然 WebAssembly 規範若是增長了其它類型,這裏就會變化。

Function closures

咱們也能夠傳遞函數閉包。也就是說,你傳遞一個 JavaScript 函數過去,WebAssembly 能夠調用。

這很是的有用,由於當前版本的 WebAssembly 不能直接調用 DOM 方法。直接修改 DOM 在 WebAssembly 的規劃中,不過如今規範裏尚未。

你能夠經過傳遞 JavaScript 函數過去,讓 WebAssembly 調用,達到修改DOM的目的。因此 WebAssembly 能夠調用一個 JS 函數

Memory

另一個類型是 memory 對象。這個對象可讓 WebAssembly 模擬手動內存管理。Memory 對象的概念讓人感到困惑,因此我在另外一篇文章中進一步深刻了解,這是本系列的下一篇文章。

Tables

最後能夠導入的類型和安全有關。它叫作 table。它可讓你使用叫作函數指針。這個東西比較複雜,將會在這個系列文章中的第三篇中講述。

這是全部你能夠導入 WebAssembly 實例的類型。

Different kinds of imports going into the imports box

WebAssembly.instantiate 的狀態變爲 resolved。它返回了兩個內容:一個實例,和一個編譯後的模塊。

返回一個編譯後的模塊的好處是你能夠隨時拿它來生成一個新的實例。你只須要將 WebAssembly.instantiatesource 這個參數替換成拿到的 module 來生成實例。模塊自己沒有任何狀態。也就是說,編譯後的模塊能夠生成不少實例。

你的實例已經整裝待發。你能夠調用它的方法。

WebAssembly robot is booted

下一篇將會深刻去講解memory importtable import

About

Lin Clark

Lin 是Mozilla Developer Relations團隊的工程師。她使用 JavaScript、WebAssembly、Rust 和 Servo,也畫一些漫畫。

相關文章
相關標籤/搜索