emscripten 生成的 invoke_* 函数的用途

Purpose of invoke_* functions generated by emscripten

编译为 WebAssembly 时,emscripten 会生成类似 invoke_vii 的函数。他们的目的是什么?

详情:

使用 emcc -s WASM=1 -g 从 C 编译的 WebAssembly 模块期望主机环境提供各种功能。

...
(import "env" "abortOnCannotGrowMemory" (func $import (result i32)))
(import "env" "invoke_vii" (func $import (param i32 i32 i32)))
(import "env" "___syscall221" (func $import (param i32 i32) (result i32)))
...

我正在研究用 C 编写的 WebAssembly 解释器。所以我必须处理提供这些功能,但我对 invoke_viiinvoke_iiii 等功能感到震惊。

后缀显然与调用签名有关。例如,vii 表示 return void 并取一些 int。名称 invoke 表明该函数应该调用某些东西。

除了在 emscripten 生成的 Java 脚本代码中的实现外,我找不到关于这些函数的任何信息:

function invoke_ii(index,a1) {
  # removed error checking for brevity
  return Module["dynCall_ii"](index,a1);
}

dynCall_ii 存在于 WebAssembly 模块中。

似乎所有 invoke_* 函数所做的就是指示解释器 运行 相应的 dynCall_* 函数。这种间接的目的是什么?为什么 WebAssembly 代码不直接调用 dynCall_

这些用于处理 setjmp/longjmp 以及 C++ 异常。在这些机制中 JavaScript 需要能够回调 WebAssembly 并调用 WebAssembly 间接函数中的函数 table.

如果您没有例外地构建并且使用 -s SUPPORT_LONGJMP=0(不是默认值),您根本不应该看到任何这些函数。