title: 什麼是 WebAssembly table imports
date: 2018-3-22 23:58:00
categories: 翻譯
tags: WebAssembly
source: 原文地址
auther: Lin Clark
什麼是 WebAssembly table imports
這是此係列的第三篇文章:
- Creating a WebAssembly module instance with JavaScript
- Memory in WebAssembly (and why it’s safer than you think)
- WebAssembly table imports… what are they?
在第一篇文章中,我介紹了WebAssembly模組例項可以具有的四種不同型別的匯入:
- values - 值
- function imports - 函式及其閉包
- memory - 記憶體物件
- table - 表
最後一個可能有點不熟悉。什麼是table imports,它能幹什麼?
有時在一個程式中,你希望能夠有一個指向函式的變數,比如回撥函式。然後你可以用它做一些事情,比如將它傳遞給另一個函式。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/cb4715a70f00544e414ee2e7dddfe6966d65fbd06f9ebcc2cf1d0e24c7d320a6.png)
在C中,這些被稱為函式指標。該函式駐留在記憶體中。指向函式的變數,即函式指標只是指向那個記憶體地址。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/7c3ffb39690b2c4648a870788e4a3f3b412d7e215c3a481b6166be76bb5697aa.png)
如果需要,稍後可以將變數指向另一個函式。這應該是一個熟悉的概念。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/a8f493dc60c93e6a1feb6f83a46a4bde9c05f39b731153553017e37a2995b897.png)
在網頁中,所有函式都只是JavaScript物件。而且因為它們是JavaScript物件,所以它們駐留在WebAssembly記憶體地址之外的記憶體中。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/a0d3512555c42e82b0c1a79ac2bc60fd9f839fb4721b6faa5131c0b9611252a1.png)
如果我們想要一個指向這些函式之一的變數,我們需要把它的地址寫入我們的記憶中。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/b6900db545398983b7896792b93d558005e252191f6cae4d17a72e8e9c6cd4b9.png)
但作為網頁安全的一部分,保持這些記憶體地址隱藏是必要的。你不會希望頁面上的程式碼能夠檢視或操縱該記憶體地址。如果頁面上存在惡意程式碼,它可以利用記憶體中的佈局位置資訊建立漏洞。
例如,它可以改變你已使用的一個記憶體地址,指向一個不同的記憶體位置。
然後,當您嘗試呼叫該函式時,實際載入的就是攻擊者給予您的記憶體地址中的任何內容。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/a7d51abcff8a0abe8e065250e303e6a7255e4c628de20f16f64d4a06ed01693a.png)
惡意程式碼可能以某種方式插入到記憶體中,比如嵌入在字串中。
tables使使用函式指標成為可能,但是以一種不易受到這類攻擊的方式。
table是一個陣列,它位於WebAssembly的記憶體之外。這些值具有對函式的引用。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/0314feffc0713e49a10ac0a45e541a95d7e0d0265968deaf87fcf0ae9bc5ab73.png)
在內部,這些引用包含記憶體地址,但由於它不在WebAssembly的記憶體中,因此WebAssembly無法看到這些地址。
不過,它可以訪問陣列索引。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/1fdb6389870623bb5d0e882365c1b3d007e5152735839332b08495d452dff78e.png)
如果WebAssembly模組想要呼叫其中一個函式,它會將索引傳遞給名為call_indirect
的操作,它會幫忙呼叫目標函式。
![[譯] 什麼是 WebAssembly table imports](https://i.iter01.com/images/f7d4b832533301b8c9202c52b109618819f6a349934f7adf2f6971133f884543.png)
現在table的用例非常有限。它們被新增到規範中以支援這些函式指標,因為 C/C++ 非常依賴這些函式指標。
正因為如此,目前你可以放入table中的唯一引用是對函式的引用。但是,隨著WebAssembly功能的擴充套件(例如,新增直接訪問DOM的功能),除了call_indirect
之外,你還可能會在table中儲存其他型別的引用以及能夠使用table中的其他操作。