Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果缓冲区大小大于4KB,则主线程上不允许WebAssembly.Compile_Javascript_Webassembly - Fatal编程技术网

Javascript 如果缓冲区大小大于4KB,则主线程上不允许WebAssembly.Compile

Javascript 如果缓冲区大小大于4KB,则主线程上不允许WebAssembly.Compile,javascript,webassembly,Javascript,Webassembly,我正在尝试一个简单的hello world WebAssembly示例,但我无法理解在Chrome 59中看到的一个错误: RangeError:如果缓冲区大小大于4KB,则主线程上不允许WebAssembly.Compile。使用WebAssembly.compile,或在工作线程上编译 我已经按照中的步骤进行了操作,我可以毫无错误地构建所有内容。我正在使用createreact应用程序 如果我使用计数器模块的本地构建,我会得到我在开头提到的错误。如果我尝试使用一个预构建的版本(例如,一个),

我正在尝试一个简单的hello world WebAssembly示例,但我无法理解在Chrome 59中看到的一个错误:

RangeError:如果缓冲区大小大于4KB,则主线程上不允许WebAssembly.Compile。使用WebAssembly.compile,或在工作线程上编译

我已经按照中的步骤进行了操作,我可以毫无错误地构建所有内容。我正在使用
createreact应用程序

如果我使用计数器模块的本地构建,我会得到我在开头提到的错误。如果我尝试使用一个预构建的版本(例如,一个),它工作得很好

当我构建模块时,我使用的命令与教程中指定的相同。具有工作模块的项目在其自述文件中列出了相同的命令:

emcc counter.c -O1 -o counter.wasm -s WASM=1 -s SIDE_MODULE=1

知道是什么导致了错误吗?

一些浏览器限制了可以同步编译的模块的大小,因为这会阻塞主线程。正如错误消息所说,他们希望您使用
WebAssembly.compile
,它返回一个。我建议您进一步使用
WebAssembly.instantiate
,它可以异步编译和实例化,在某些情况下,还可以生成性能更高的代码。看,签名是:

Promise<WebAssemblyInstantiatedSource>
  instantiate(BufferSource bytes [, importObject])
承诺
实例化(缓冲源字节[,importObject])
字节
与您传递到上面的
模块
的缓冲区相同,
导入对象
与您传递到
实例
的缓冲区相同


另一个选项是将
.wasm
文件变小。这是非常脆弱的,因为主线程大小限制是任意的,并且您无法真正控制生成代码的大小。您可以尝试使用
-O2
-Os
进行编译,并且可以运行的优化器来尝试减小大小。您还可以将代码拆分为多个较小的模块,分别编译每个模块,然后将它们动态链接在一起(共享导入/导出,并对所有模块使用相同的内存)

但是,这并不是你应该依赖的东西,你仍然在阻塞主线程



另一个选择是将所有代码移动到一个新的位置。您可以根据需要对它们进行任意阻塞,无需使用
Promise
s.

通过缓冲区创建URL对象,然后使用InstanceStreaming async方法加载wasm

const blob = new Blob([buffer], { type: "application/wasm" });
const url = URL.createObjectURL(blob);
wasm = await instantiateStreaming(fetch(url), {});

谢谢你的回复!这是有道理的-问题似乎来自
wasm-loader
,因为它是进行模块加载的那个。我在那里提交了一个问题:你能提供更多细节吗,同步模块编译什么时候会产生更慢的代码?@Vitaly主要区别在于编译器是否知道分配的内存:如果可以进行~4GiB虚拟保留,并且安装了信号处理程序,则不需要显式边界检查。编译时不一定知道,但在实例化时肯定知道。@JFBastien我仍然不明白这与同步/异步编译有什么关系。在我的noob看来,异步编译的唯一区别是将代码移动到单独的线程,而不是冻结主线程。可能您可以链接到一些文章,其中有一些详细信息,为什么sync WA init会产生不太理想的代码?这不是sync与async的区别,而是使用已知的
importObject
进行编译,它仅在实例化时提供。如果实现实际上在编译时编译,而不是延迟到第一个实例,并且具有不同的内存类型,那么它可能会被迫在实例化时重新编译。内存类型(~4GiB分配,安装了信号处理程序)允许更快的代码,没有它,您必须生成显式边界检查。作为参考,请参阅。
const blob = new Blob([buffer], { type: "application/wasm" });
const url = URL.createObjectURL(blob);
wasm = await instantiateStreaming(fetch(url), {});