參考類型支援
WebAssembly 最近獲得了一種稱為 externref
的新值類型支援。這個 WebAssembly 的功能在 WebAssembly 參考類型儲存庫中提出,希望能夠實現主機 (JS) 和 Wasm 模組之間更有效率的溝通。此功能消除了 wasm-bindgen
生成的大部分 JS 膠水程式碼的需求,因為它可以原生呼叫具有 JS 值的 API。
例如,這個 Rust 函數
#![allow(unused)] fn main() { #[wasm_bindgen] pub fn takes_js_value(a: &JsValue) { // ... } }
產生此 JS 膠水程式碼,不支援參考類型
const heap = new Array(32).fill(undefined);
heap.push(undefined, null, true, false);
let stack_pointer = 32;
function addBorrowedObject(obj) {
if (stack_pointer == 1) throw new Error('out of js stack');
heap[--stack_pointer] = obj;
return stack_pointer;
}
export function takes_js_value(a) {
try {
wasm.takes_js_value(addBorrowedObject(a));
} finally {
heap[stack_pointer++] = undefined;
}
}
我們可以在這裡看到 JS 如何在底層管理傳遞給 Wasm 二進制檔的 JS 值表格,因此 Wasm 實際上僅適用於索引。但是,如果我們使用 -Ctarget-feature=+reference-types
(自 Rust v1.82 以來預設)編譯,則產生的 JS 程式碼如下所示
export function takes_js_value(a) {
wasm.takes_js_value(a);
}
就是這樣!WebAssembly 二進制檔直接獲取 JS 值並在內部進行管理。
目前,此功能在 Firefox 79+ 和 Chrome 中受支援。其他瀏覽器也可能很快就會支援!在 Node.js 中,此功能位於 --experimental-wasm-anyref
標誌之後,儘管截至 14.6.0,其支援目前與上游規範不一致。