溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么在WebAssembly中寫(xiě) “Hello World”

發(fā)布時(shí)間:2021-06-14 16:38:16 來(lái)源:億速云 閱讀:224 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹了怎么在WebAssembly中寫(xiě) “Hello World”,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

通過(guò)這個(gè)分步教程,開(kāi)始用人類(lèi)可讀的文本編寫(xiě) WebAssembly。

WebAssembly 是一種字節(jié)碼格式,幾乎所有的瀏覽器 都可以將它編譯成其宿主操作系統(tǒng)的機(jī)器代碼。除了  JavaScript 和 WebGL 之外,WebAssembly 還滿足了將應(yīng)用移植到瀏覽器中以實(shí)現(xiàn)平臺(tái)獨(dú)立的需求。作為 C++ 和  Rust 的編譯目標(biāo),WebAssembly 使 Web 瀏覽器能夠以接近原生的速度執(zhí)行代碼。

當(dāng)談?wù)?WebAssembly 應(yīng)用時(shí),你必須區(qū)分三種狀態(tài):

  1. 源碼(如 C++ 或 Rust): 你有一個(gè)用兼容語(yǔ)言編寫(xiě)的應(yīng)用,你想把它在瀏覽器中執(zhí)行。

  2. WebAssembly 字節(jié)碼: 你選擇 WebAssembly 字節(jié)碼作為編譯目標(biāo)。最后,你得到一個(gè) .wasm 文件。

  3. 機(jī)器碼(opcode): 瀏覽器加載 .wasm 文件,并將其編譯成主機(jī)系統(tǒng)的相應(yīng)機(jī)器碼。

WebAssembly 還有一種文本格式,用人類(lèi)可讀的文本表示二進(jìn)制格式。為了簡(jiǎn)單起見(jiàn),我將其稱(chēng)為 WASM-text。WASM-text 可以比作高級(jí)匯編語(yǔ)言。當(dāng)然,你不會(huì)基于 WASM-text 來(lái)編寫(xiě)一個(gè)完整的應(yīng)用,但了解它的底層工作原理是很好的(特別是對(duì)于調(diào)試和性能優(yōu)化)。

本文將指導(dǎo)你在 WASM-text 中創(chuàng)建經(jīng)典的 “Hello World” 程序。

創(chuàng)建 .wat 文件

WASM-text 文件通常以 .wat 結(jié)尾。第一步創(chuàng)建一個(gè)名為 helloworld.wat 的空文本文件,用你最喜歡的文本編輯器打開(kāi)它,然后粘貼進(jìn)去:

(module    ;; 從 JavaScript 命名空間導(dǎo)入    (import  "console"  "log" (func  $log (param  i32  i32))) ;; 導(dǎo)入 log 函數(shù)    (import  "js"  "mem" (memory  1)) ;; 導(dǎo)入 1 頁(yè) 內(nèi)存(64kb)       ;; 我們的模塊的數(shù)據(jù)段    (data (i32.const 0) "Hello World from WebAssembly!")       ;; 函數(shù)聲明:導(dǎo)出 helloWorld(),無(wú)參數(shù)    (func (export  "helloWorld")        i32.const 0  ;; 傳遞偏移 0 到 log        i32.const 29  ;; 傳遞長(zhǎng)度 29 到 log(示例文本的字符串長(zhǎng)度)        call  $log        ))

WASM-text 格式是基于 S 表達(dá)式的。為了實(shí)現(xiàn)交互,JavaScript 函數(shù)用 import 語(yǔ)句導(dǎo)入,WebAssembly 函數(shù)用 export 語(yǔ)句導(dǎo)出。在這個(gè)例子中,從 console 模塊中導(dǎo)入 log 函數(shù),它需要兩個(gè)類(lèi)型為 i32 的參數(shù)作為輸入,以及一頁(yè)內(nèi)存(64KB)來(lái)存儲(chǔ)字符串。

字符串將被寫(xiě)入偏移量 為 0 的數(shù)據(jù)段。數(shù)據(jù)段是你的內(nèi)存的疊加投影overlay,內(nèi)存是在 JavaScript 部分分配的。

函數(shù)用關(guān)鍵字 func 標(biāo)記。當(dāng)進(jìn)入函數(shù)時(shí),棧是空的。在調(diào)用另一個(gè)函數(shù)之前,函數(shù)參數(shù)會(huì)被壓入棧中(這里是偏移量和長(zhǎng)度)(見(jiàn) call $log)。當(dāng)一個(gè)函數(shù)返回一個(gè) f32 類(lèi)型時(shí)(例如),當(dāng)離開(kāi)函數(shù)時(shí),一個(gè) f32 變量必須保留在棧中(但在本例中不是這樣)。

創(chuàng)建 .wasm 文件

WASM-text 和 WebAssembly 字節(jié)碼是 1:1 對(duì)應(yīng)的,這意味著你可以將 WASM-text 轉(zhuǎn)換成字節(jié)碼(反之亦然)。你已經(jīng)有了 WASM-text,現(xiàn)在將創(chuàng)建字節(jié)碼。

轉(zhuǎn)換可以通過(guò) WebAssembly Binary Toolkit(WABT)來(lái)完成。從該鏈接克隆倉(cāng)庫(kù),并按照安裝說(shuō)明進(jìn)行安裝。

建立工具鏈后,打開(kāi)控制臺(tái)并輸入以下內(nèi)容,將 WASM-text 轉(zhuǎn)換為字節(jié)碼:

wat2wasm helloworld.wat -o helloworld.wasm

你也可以用以下方法將字節(jié)碼轉(zhuǎn)換為 WASM-text:

wasm2wat helloworld.wasm -o helloworld_reverse.wat

一個(gè)從 .wasm 文件創(chuàng)建的 .wat 文件不包括任何函數(shù)或參數(shù)名稱(chēng)。默認(rèn)情況下,WebAssembly 用它們的索引來(lái)識(shí)別函數(shù)和參數(shù)。

編譯 .wasm 文件

目前,WebAssembly 只與 JavaScript 共存,所以你必須編寫(xiě)一個(gè)簡(jiǎn)短的腳本來(lái)加載和編譯 .wasm 文件并進(jìn)行函數(shù)調(diào)用。你還需要在 WebAssembly 模塊中定義你要導(dǎo)入的函數(shù)。

創(chuàng)建一個(gè)空的文本文件,并將其命名為 helloworld.html,然后打開(kāi)你喜歡的文本編輯器并粘貼進(jìn)去:

<!DOCTYPE  html><html>  <head>    <meta  charset="utf-8">    <title>Simple template</title>  </head>  <body>    <script>         var memory = new  WebAssembly.Memory({initial:1});       function  consoleLogString(offset, length) {        var  bytes = new  Uint8Array(memory.buffer, offset, length);        var  string = new  TextDecoder('utf8').decode(bytes);        console.log(string);      };       var  importObject = {        console: {          log:  consoleLogString        },        js : {          mem:  memory        }      };           WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)      .then(obj  => {        obj.instance.exports.helloWorld();      });         </script>  </body></html>

WebAssembly.Memory(...) 方法返回一個(gè)大小為 64KB 的內(nèi)存頁(yè)。函數(shù) consoleLogString 根據(jù)長(zhǎng)度和偏移量從該內(nèi)存頁(yè)讀取一個(gè)字符串。這兩個(gè)對(duì)象作為 importObject 的一部分傳遞給你的 WebAssembly 模塊。

在你運(yùn)行這個(gè)例子之前,你可能必須允許 Firefox 從這個(gè)目錄中訪問(wèn)文件,在地址欄輸入 about:config,并將 privacy.file_unique_origin 設(shè)置為 true

怎么在WebAssembly中寫(xiě) “Hello World”

Firefox setting

注意: 這樣做會(huì)使你容易受到 CVE-2019-11730 安全問(wèn)題的影響。

現(xiàn)在,在 Firefox 中打開(kāi) helloworld.html,按下 Ctrl+K 打開(kāi)開(kāi)發(fā)者控制臺(tái)。

怎么在WebAssembly中寫(xiě) “Hello World”

Debugger output

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“怎么在WebAssembly中寫(xiě) “Hello World””這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI