[譯]安全的WebAssembly內存操做

做者:Lin Clark
譯者:xlaoyu
英文原文:Memory in WebAssembly (and why it’s safer than you think)git

轉載請註明出處,保留原文連接以及做者信息github


這是 WebAssembly 使用系列介紹的第二篇文章:web

  1. 使用JavaScript建立WebAssembly模塊實例
  2. 安全的WebAssembly內存操做
  3. WebAssembly的導入類型 table 究竟是什麼?

Memory(內存,內存都以內存稱呼)在 WebAssembly 中的使用和在 JavaScript 中稍有不一樣。在 WebAssembly 裏,咱們能夠直接訪問原始字節,這可能會讓一些人感到擔心,但它實際上比你想象的更安全。數組

什麼是內存對象?

當一個WebAssembly模塊被實例化時,它須要一個內存對象。咱們能夠建立一個新 WebAssembly.Memory 對象並將其傳入。或者若是咱們沒傳,那麼引擎將建立一個內存對象並自動將其附加到該實例上。瀏覽器

全部 JS 引擎都會在內部建立一個ArrayBuffer。ArrayBuffer 是 JS 引用的 JavaScript 對象,JS 替咱們爲它分配內存。咱們告訴它須要多少內存,它會建立咱們須要大小的 ArrayBuffer 對象。安全

arraybuffer

數組的索引能夠看做是內存地址。若是之後咱們須要更多的內存空間,能夠執行一種叫作 增加 的操做來擴大數組。函數

使用 JavaScript 的對象 ArrayBuffer 來操控 WebAssembly 的內存,達成了兩個目的:編碼

  1. 使在 JS 和 WebAssembly 之間互相傳遞數據更簡單
  2. 有助於內存管理的安全性

在 JS 和 WebAssembly 之間傳遞數據

由於 ArrayBuffer 也只是一個 JavaScript 對象,這意味着 JavaScript 有足夠的能力能夠去操做內存裏的字節。基於這種方式,WebAssembly 和 JavaScript 能夠共享內存並來回傳遞值。code

它們使用數組下標去定位內存塊,而不是使用內存地址。cdn

例如,WebAssembly 能夠把一個字符串放進內存裏。首先把字符串編碼爲字節。。

encode

而後把字節放進數組中。

put-array

而後它會將第一個索引(整數)返回給 JavaScript,因此 JavaScript 能夠將字節取出來並使用它們。

return-index

目前爲止,大多數 JavaScript 引擎都沒法直接使用字節來工做,因此咱們須要在 JS 這邊使用某些方法把字節轉化爲有用的數據類型,好比字符串。

在某些瀏覽器中,咱們可使用 TextDecoderTextEncoder API。或者咱們能夠像 Emscripten 那樣在代碼中加入輔助函數,幫助咱們完成這件事情。

use-bytes

以上是使用 JS 對象操做 WebAssembly 內存的第一個優勢:能夠直接經過內存互相傳遞數據

讓內存訪問更安全

使用 JavaScript 對象處理 WebAssembly 內存的另一個好處就是:安全性。經過幫助防止瀏覽器級內存泄漏並提供內存隔離,它使事情更安全。

內存泄漏

當咱們本身手動管理內存時,隨時可能忘記清除它。這可能會致使系統內存不足最終內存溢出。

咱們想象一下,若是一個 WebAssembly 模塊實例能夠直接訪問內存,而且在該實例執行完成退出上下文時忘記釋放該內存,那麼將會致使內存泄露。可是如今因爲內存對象是一個 JavaScript 對象,它的存在將由垃圾回收器追蹤着(儘管並無控制內容)。這意味着當 WebAssembly 模塊實例離開執行上下文時,整個內存數組將會被回收掉。

gc

內存隔離

當人們得知 WebAssembly 模塊能夠直接訪問內存時,這可能會讓咱們有點緊張。咱們可能會覺得 WebAssembly 模塊能夠定位和訪問到它們本該不能訪問的內存,但事實並不是如此。

ArrayBuffer 對象邊界會提供一個限制,這是 WebAssembly 模塊能直接接觸到的內存邊界。

boundary

WebAssembly 能夠直接獲取該數組內部的字節,但它不能看到超出此數組邊界的任何內容。

例如,內存中的任何其餘JS對象(如全局window)都不能被 WebAssembly 訪問。這對安全性很是重要。

不管什麼時候在 WebAssembly 中進行讀取或寫操做時,引擎都會執行數組邊界檢查以確保地址位於 WebAssembly 實例的內存中。

若是代碼嘗試訪問超出界限的地址,則引擎將引起異常,這保護了其他的內存。


下篇文章,咱們一塊兒來看看什麼是 WebAssembly 的 table 對象。

相關文章
相關標籤/搜索