您好,登錄后才能下訂單哦!
這篇文章主要介紹了怎么在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):
源碼(如 C++ 或 Rust): 你有一個(gè)用兼容語(yǔ)言編寫(xiě)的應(yīng)用,你想把它在瀏覽器中執(zhí)行。
WebAssembly 字節(jié)碼: 你選擇 WebAssembly 字節(jié)碼作為編譯目標(biāo)。最后,你得到一個(gè) .wasm
文件。
機(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” 程序。
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)存的疊加投影,內(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
變量必須保留在棧中(但在本例中不是這樣)。
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ù)。
目前,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
:
Firefox setting
注意: 這樣做會(huì)使你容易受到 CVE-2019-11730 安全問(wèn)題的影響。
現(xiàn)在,在 Firefox 中打開(kāi) helloworld.html
,按下 Ctrl+K
打開(kāi)開(kāi)發(fā)者控制臺(tái)。
Debugger output
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“怎么在WebAssembly中寫(xiě) “Hello World””這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(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)容。