什麼是 WebAssembly table
原文地址:[譯]WebAssembly 中的 Memory
轉載請註明出處
這是系列文章的第三篇:
- 使用 JavaScript 創建一個 WebAssembly 模塊的實例。
- WebAssembly 中的 Memory
- 什麼是 WebAssembly table?
WebAssembly中的內存與JavaScript中的內存有所不同。使用WebAssembly,您可以直接訪問原始位元組碼…這可能令人擔憂。但是,它的確比你想像中的要安全。
什麼是 memory 對象?
當 WebAssembly 模塊被實例化時,它需要一個 memory 對象。你可以創建一個新的WebAssembly.Memory並傳遞該對象。如果沒有創建 memory 對象,在模塊實例化的時候將會自動創建,並且傳遞給實例。
JS引擎創建一個ArrayBuffer(我在另一篇文章中解釋)來做這件事情。ArrayBuffer 是 JS 引用的 JavaScript 對象。JS 為你分配內存。你告訴它需要多少內存,它會創建一個對應大小的ArrayBuffer
數組的索引可以視為內存地址。如果你需要增加它的內存,你可以使用 grow 方法讓數組變大。
ArrayBuffer 做了兩件事情,一件是做 WebAssembly 的內存,另外一件是做 JavaScript 的對象。
- 它使 JS 和 WebAssembly 之間傳遞內容更方便。
- 使內存管理更安全。
JS 和 WebAssembly 之間傳值
因為 ArrayBuffer 是一個 JavaScript 對象,這意味著 JavaScript 也可以獲取到這個 memory 中的位元組。所以通過這種方式, WebAssembly 和 JavaScript 可以共享內存,並且相互傳值。
使用數組索引來訪問每個位元組,而不是使用內存地址。
比如,WebAssembly 想將一個字元串寫入內存。它需要將字元串轉換成位元組碼。
然後把這些位元組碼放進數組。
然後將字元串所在的內存位置的第一個位置,也就是數組的某個索引,傳遞給 JavaScript。JavaScript 可以根據索引從 ArrayBuffer 中拿到字元串
現在,很多人並不知道如何在 JavaScript 中使用位元組碼。你需要將位元組碼轉換為有用的內容,比如說字元串。
在一些瀏覽器中,你可以使用TextDecoder和TextEncoderAPI來處理。或者你可以在你的js文件里添加一些幫助函數。比如,Emscripten就可以幫你添加編碼和解碼的方法。
所以,WebAssembly memory 最好的地方就是它是一個 JS 對象。WebAssembly 和 JavaScript 可以直接使用 memory 互相傳值。
讓 memory 存取更安全
另外一個好處是,WebAssembly memory 只是一個 JavaScript 對象:安全。通過防止瀏覽器級內存泄漏並提供內存隔離,使事情變得更安全。
內存泄漏
正如我在內存管理的文章中提到的,當你管理自己的內存時,你可能會忘記清除它。這可能導致系統內存不足。
如果 WebAssembly 模塊實例直接訪問內存,並且如果在超出範圍之前忘記清除該內存,那麼瀏覽器可能會泄漏內存。
因為內存對象只是一個JavaScript對象,所以它本身就被垃圾回收器跟蹤(儘管它的內容不會垃圾回收)。
也就是說,WebAssembly 實例被移除以後,所有的內存數組將會被回收。
內存隔離
當人們聽到WebAssembly讓你直接訪問內存時,他們可能有點緊張。他們認為,一個惡意的 WebAssembly 模塊可能會進入並在內存中幹壞事,這是絕對不允許的。但事實並非如此。
ArrayBuffer 提供了邊界。WebAssembly 模塊可以直接管理的內存是受限制的。
它可以直接管理該數組內部的位元組,但它看不到任何超出此數組範圍的內容。
例如,內存中的任何其它 JS 對象,如 window 對象,WebAssembly無法訪問。這對安全性非常重要。
每當 WebAssembly 中有操作內存時,引擎會進行數組限制檢查,以確保該地址位於 WebAssembly 實例的內存中。
如果代碼嘗試訪問超出範圍的地址,引擎將拋出異常。這保護了其它的內存。
所以這就是 memory 相關的內容。在下一篇文章中,我們將看研究一些關於安全性的其它類型的 import 數據:table import。
About
Lin Clark
Lin 是Mozilla Developer Relations團隊的工程師。她使用 JavaScript、WebAssembly、Rust 和 Servo,也畫一些漫畫。
推薦閱讀:
※U4 內核 WebGL 支持發展方向
※WebAssembly 系列(三)編譯器如何生成彙編
TAG:WebAssembly |