科技女王范儿|WebAssembly 和 JS构建高性能应用程序,如何使用( 二 )


JavaScript的WebAssemblyAPI
为了充分利用WebAssembly的功能 , 我们必须将其与JavaScript代码集成在一起 。 这可以在JavaScriptWebAssemblyAPI的帮助下完成 。
模块编译和实例化
WebAssembly代码位于.wasm文件中 。 该文件应编译为针对底层机器的机器码 。 你可以使用WebAssembly.compile方法来编译WebAssembly模块 。 收到已编译的模块后 , 可以使用WebAssembly.instantiate方法实例化已编译的模块 。 另外 , 你也可以将获取.wasm文件获得的数组缓存传递到WebAssembly.instantiate方法中 。 这也可以 , 因为实例化方法有两个重载 。
letexports;fetch('sample.wasm').then(response=>response.arrayBuffer();).then(bytes=>WebAssembly.instantiate(bytes);).then(results=>exports=results.instance.exports;});上述方法的缺点之一是这些方法不能直接访问字节码 , 因此在编译/实例化wasm模块之前 , 需要采取额外的步骤将响应转换为ArrayBuffer 。 相比之下 , 我们可以使用WebAssembly.compileStreaming/WebAssembly.instantiateStreaming方法来实现上述功能 , 其优点是可以直接访问字节码 , 而无需将响应转换为ArrayBuffer 。
letexports;WebAssembly.instantiateStreaming(fetch('sample.wasm')).then(obj=>{exports=obj.instance.exports;})应注意 , WebAssembly.instantiate和WebAssembly.instantiateStreaming会返回实例以及已编译的模块 , 这些实例可用于快速启动模块的实例 。
letexports;letcompiledModule;WebAssembly.instantiateStreaming(fetch('sample.wasm')).then(obj=>{exports=obj.instance.exports;//accesscompiledmodulecompiledModule=obj.module;})导入对象
实例化WebAssembly模块实例时 , 可以选择传递一个导入对象 , 该对象将包含要导入到新创建的模块实例中的值 。 它们可以是4种类型 。
全局变量值函数memorytable导入对象可以视为提供给模块实例以帮助其完成任务的工具 。 如果未提供导入对象 , 则编译器将分配默认值 。
全局变量
WebAssembly允许你创建可从JavaScript和WebAssembly模块访问的全局变量实例 。 你可以导入/导出这些变量 , 并在一个或多个WebAssembly模块实例中使用它们 。
你可以使用WebAssembly.Global()构造器创建一个全局实例 。
constglobal=newWebAssembly.Global({value:'i64',mutable:true},20);全局构造器接收两个参数 。
一个对象 , 包含描述全局变量的数据类型和可变性的属性 。 允许的数据类型为i32、i64、f32或f64实际变量的初始值 。 此值应为参数1中提到的类型 。 例如 , 如果你声明类型为i32 , 则变量应为32位整数 。 同样 , 如果你声明类型为f64 , 则变量应为64位浮点数 。 constglobal=newWebAssembly.Global({value:'i64',mutable:true},20);letimportObject={js:{global}};WebAssembly.instantiateStreaming(fetch('global.wasm'),importObject)全局实例应传递到importObject上 , 以便在WebAssembly模块实例中访问它 。
Memory
在实例化时 , WebAssembly模块将需要分配一个memory对象 。 该memory对象应与importObject一起传递 。 如果没能这样做 , 则JIT编译器将使用默认值自动创建一个memory对象并将其附加到实例 。
附加到模块实例的memory对象只是一个ArrayBuffer 。 只需使用索引值 , 即可轻松访问memory 。 此外 , 由于它是简单的ArrayBuffer , 因此可以简单地在JavaScript和WebAssembly之间传递和共享值 。
Table
WebAssemblyTable是一个可调整大小的数组 , 位于WebAssembly的memory之外 。 该Table的值都是函数引用 。 尽管这听起来很像WebAssemblymemory , 但它们是不同的 , 主要区别在于Memory数组是原始字节 , 而Table数组是引用 。