這系列主要是我對WASM研究的筆記,可能內容比較簡略。總共包括:html
//async version WebAssembly.compile(bufferSource: ArrayBuffer): Promise<WebAssembly.Module> WebAssembly.instantiate(bufferSource: ArrayBuffer, importObj?: any): Promise<{module: WebAssembly.Module, instance: WebAssembly.Instance}> WebAssembly.instantiate(module: WebAssembly.Module, importObj?: any): Promise<WebAssembly.Instance> WebAssembly.compileStreaming(source: Promise<Responce>): Promise<WebAssembly.Module> // wasm 請求頭:Context-type: application/wasm //sync version new WebAssembly.Module(bufferSource: ArrayBuffer) new WebAssembly.Instance(module: WebAssembly.Module, importObj?: any) // helper WebAssembly.Module.customSections(module:WebAssembly.Module, sectionName: string): ArrayBuffer[] WebAssembly.Module.exports(module: WebAssembly.Module): { name: string, kind: "function|table|memory|global" }][] WebAssembly.Module.imports(module: WebAssembly.Module): { module: string, name: string, kind: "function|table|memory|global" }][] // validation and error WebAssembly.validate(bufferSource: ArrayBuffer):boolean interface CommonError { message: string filename: string lineNumber: number } new WebAssembly.CompileError(message: string, fileName: string, lineNumber: number) // 解碼,驗證階段 new WebAssembly.LinkError(message: string, fileName: string, lineNumber: number) // 實例化階段 new WebAssembly.RuntimeError(message: string, fileName: string, lineNumber: number) // 運行階段 複製代碼
fetch('./index.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, { env: { yyy: xxx } })).then(wasm => { const { module, instance } = wasm; }).catch(console.error); 複製代碼
const source = fetch('./index.wasm') WebAssembly.compileStreaming(source).then(module => WebAssembly.instantiate(module, { env: { xxx: yyy } }) ).then(instance => { //xxx }).catch(console.error); 複製代碼
const source = fetch('./index.wasm')
WebAssembly.compileStreaming(source).then(module =>
WebAssembly.instantiate(module, {
env: {
xxx: yyy
}
})
).then(instance => {
//xxx
}).catch(console.error);
複製代碼
最好的方式是經過 WebAssembly.compileStreaming
的方式來加載。能夠對wasm模塊提早進行編譯驗證。git
JavaScript類型化數組是一種相似數組的對象,並提供了一種用於訪問原始二進制數據的機制。 正如你可能已經知道,Array 存儲的對象能動態增多和減小,而且能夠存儲任何JavaScript值。JavaScript引擎會作一些內部優化,以便對數組的操做能夠很快。然而,隨着Web應用程序變得愈來愈強大,尤爲一些新增長的功能例如:音頻視頻編輯,訪問WebSockets的原始數據等,很明顯有些時候若是使用JavaScript代碼能夠快速方便地經過類型化數組來操做原始的二進制數據將會很是有幫助。 可是,不要把類型化數組與正常數組混淆,由於在類型數組上調用 Array.isArray()
會返回false。此外,並非全部可用於正常數組的方法都能被類型化數組所支持(如 push
和 pop
)。github
Custom Sections — WebAssembly 1.0web
custom section 是section id爲零的段,不惟一。目前只實現了 name sectionapi
wasm-ld 有關memory的參數:(WebAssembly lld port — lld 10 documentation)數組
--import-memory
Import memory from the environment.
--initial-memory=<value>
Initial size of the linear memory. Default: static data size.
--max-memory=<value>
Maximum size of the linear memory. Default: unlimited.
複製代碼
通常來講不須要限制,可是在某些安全場景下能夠在js或者wasm裏面設置。安全
編譯的時候啓用--import-memory
,而後在js中構造一個memory對象經過env傳給wasm模塊。bash
const memory = new WebAssembly.Memory({ initial: 10, maxium: 100, }); fetch('../a.wasm').then(buffer => WebAssembly.instantiate(buffer, {env: { memory }})).then((wasm) => { console.log(WebAssembly.imports(wasm.module)); }) 複製代碼
實際上不必定須要經過env傳遞,只是llvm編譯器如此指定的,能夠傳如任意對象,而後手動修改wasm模塊(github.com/mdn/webasse…markdown
memory單位是page
,pageSize爲64KB
, 初始內存不夠的時候能夠調用memory.grow(n)
來增大,但總共不能超過最大內存maxium, maxium設置以後不可更改(同stack)。app
A table is an array of opaque values of a particular element type. It allows programs to select such values indirectly through a dynamic index operand. Currently, the only available element type is an untyped function reference. Thereby, a program can call functions indirectly through a dynamic index into a table. For example, this allows emulating function pointers by way of table indices.
js下,WebAssembly.Table 表明着wasm模塊中的表結構實體。
const table = new WebAssembly.Table({ initial: 2, //初始時可儲存的表項的數量 element: "anyfunc", maxium: 10, //可選 }); table.length // 2 table.get(0) // null table.grow(n) table.set(index: number, value: elem) // 只能設置類型爲anyfunc的表項 複製代碼
(module
(import "js" "tbl" (table 2 anyfunc))
(func $f42 (result i32) i32.const 42)
(func $f83 (result i32) i32.const 83)
(elem (i32.const 0) $f42 $f83)
)
複製代碼
var tbl = new WebAssembly.Table({initial:2, element:"anyfunc"}); console.log(tbl.length); console.log(tbl.get(0)); console.log(tbl.get(1)); var importObject = { js: { tbl:tbl } }; WebAssembly.instantiateStreaming(fetch('table2.wasm'), importObject) .then(function(obj) { console.log(tbl.length); console.log(tbl.get(0)()); // 42 console.log(tbl.get(1)()); // 83 }); 複製代碼