title: WebAssembly中的內存(爲何它比你想象的更安全)javascript
date: 2018-3-22 23:58:00java
categories: 翻譯web
tags: WebAssembly數組
source: 原文地址瀏覽器
auther: Lin Clark安全
這是此係列的第二篇文章:函數
WebAssembly中的內存與JavaScript中的內存稍有不一樣。使用WebAssembly,您能夠直接訪問原始字節...而且會讓一些人感到擔心。但它實際上比你想象的更安全。工具
當一個WebAssembly模塊被實例化時,它須要一個內存對象。你能夠建立一個新的WebAssembly.Memory對象並將該對象傳入。若是不存在,則會建立一個內存對象並將其自動附加到該實例。編碼
全部JS引擎在內部都會建立一個ArrayBuffer(我在另外一篇文章中解釋過)。ArrayBuffer是一個對象,JS對其保持引用。JS爲你分配內存。你告訴它須要多少內存,它會建立一個給定大小的ArrayBuffer。翻譯
數組的索引能夠看做是內存地址。若是須要更多的內存,你能夠作一些叫作 growing(增加) 的事情來擴大數組。
將WebAssembly的內存做爲JavaScript中的一個對象 - 做爲ArrayBuffer處理 - 作到了兩件事:
由於這只是一個JavaScript對象,這意味着JavaScript也能夠挖掘出這些內存中的字節。於此,WebAssembly和JavaScript能夠經過共享內存並來回傳遞值。
他們不使用內存地址,而是使用數組索引來訪問每一個box(內存單元)。
例如,WebAssembly能夠在內存中放置一個字符串。它會將它編碼成字節......
...而後將這些字節放入數組中。
而後它會將第一個索引(整數)返回給JavaScript。因此JavaScript能夠將字節拉出來並使用它們。
如今,大多數JavaScript方法不知道如何直接使用字節。所以,你須要JavaScript端的一些東西,就你您在WebAssembly端作的那樣,它能夠將字節轉換爲更有用的值,好比字符串。
在某些瀏覽器中,你能夠使用TextDecoder和TextEncoder API。或者你能夠在你的.js文件中添加輔助函數。例如,像Emscripten這樣的工具能夠添加編碼和解碼輔助。
這就是使用JS對象做爲WebAssembly內存的第一個好處。WebAssembly和JavaScript能夠經過內存直接傳遞值。
正如我在關於內存管理的文章中提到的那樣,當你手動管理內存時,你可能會忘記清除它。這可能會致使系統內存不足。
若是WebAssembly模塊實例能夠直接訪問內存,而且在內存離開做用域以前忘記清除內存,則瀏覽器可能會發生內存泄露。
可是由於內存對象只是一個JavaScript對象,因此它自己被垃圾收集器跟蹤(即便它的內容不是)。
這意味着,當內存對象所附的WebAssembly實例離開做用域時,整個內存數組可能會被垃圾收集。
當人們聽到WebAssembly能讓你直接訪問內存時,它可能會讓一些人有點緊張。他們認爲一個惡意的WebAssembly模塊能夠進入內存而且在內存中進行挖掘,但它不該該這樣作。但事實並不是如此。
ArrayBuffer的數組範圍自然提供了一個邊界。這是WebAssembly模塊能夠直接觸摸內存的限制。
它能夠直接接觸該數組內部的字節,但它不能看到超出此數組邊界的任何內容。
例如,內存中的任何其餘JS對象(如window)都不能被WebAssembly訪問。這對安全性很是重要。
當在WebAssembly中加載或存儲時,引擎會執行數組邊界檢查(array bounds checks)以確保地址位於WebAssembly實例的內存中。
若是代碼嘗試訪問超出界限的地址,則引擎將拋出異常。這種行爲保護了其他的內存。
這就是內存導入。在下一篇文章中,咱們將看看另外一種導入更安全的導入方法...table import(導入表格)。