Design: 我们什么时候需要胶水代码?

创建于 2018-04-09  ·  4评论  ·  资料来源: WebAssembly/design

我遇到了一些情况。

一个我们需要一些胶水代码:

int addThree(uint8_t *buf, int len) {
  uint8_t *item;
  uint8_t *end = buf + len;

  for (item = buf; item<end; item++) {
    *item += 3;
  }

  return 0;
}

但是,简单来说,我们只需要使用 .wasm 文件

int adder (int a, int b) {
    return a + b;
}

那么,胶水代码有什么作用呢? 我找不到一些文档。

最有用的评论

上面注释中描述的粘合代码是 Emscripten 生成的 JavaScript 加载器。 它完全按照注释说的做:在 JS 和 C++ 数据表示(例如字符串)之间以及不同对象表示之间(即为 C++ 对象创建 JS 代理对象)之间进行转换。 它还创建所需的类型化数组。

正如您所注意到的,对于简单的情况,例如您用作示例的两个函数,您可以省去 Emscripten 加载程序。 它们都不需要任何复杂的粘合代码:每个都只需要一个 JS 文件来加载 Wasm 文件(在第二个示例中,addThree 的 wasm 文件也需要创建 Uint8Array)。

最后,内存分配由 Wasm 代码处理,它应该包括一份来自 musl 的 malloc 副本(尽管 Emscripten 实际上仍然包括它的 malloc,而不是使用 musl 的)。 只需在完成 C/C++ 代码后释放内存,即可以标准方式避免内存泄漏,Wasm 在这里没有什么特别要求。

最终,您只需要实际使用的胶水代码,这取决于您的代码所做的跨边界调用(从 JS 到 C++,从 C++ 到 JS)。

这个问题可以关闭,这是一个关于 Emscripten 的问题,而不是 WebAssembly 设计本身的错误。

所有4条评论

什么胶水代码? 您似乎从一些 Wasm 教程中复制了两个函数( addThree()adder() )? 它们似乎只是示例函数,实际上并没有做太多事情,只是用来演示一个简单的 Wasm 教程。 这两个函数都没有复杂的签名,应该可以在没有任何胶水代码的情况下调用。

但是,这不是我的重点。 从一些文档中,它解释如下:

从长远来看,带有类型对象和 GC 的 wasm 可能会有所帮助。 这是这里的意思吗?
否则,我不确定如何在短期或中期删除任何胶水代码。 围绕 C/C++ 事物形成一个外壳,使它们看起来像 JS 事物,这需要大量的工作。 例如,粘合代码必须包含将 C 字符串转换为 JS 字符串的方法,反之亦然。 在 C++ 级别,支持在 JS 中扩展 C++ 类并在 JS 中实现虚拟方法需要相当多的技巧。 一般来说,从 wasm 到 JS 访问 Web API 需要大量的胶水。

和别的:

Emscripten 需要大量的 JavaScript “胶水”代码来处理内存分配、内存泄漏和许多其他问题,这些问题已经包含在提供的模板中。 使用它比必须自己写出来更容易

当我遇到一些简单的 C/C++ 代码时,我可以通过编译它轻松地使用 wasm,而export.xxxFn()

int adder (int a, int b) {
    return a + b;
}

当我使用使用 Buffer 的代码时,我更喜欢使用胶水代码。

# C/C++
int addThree(uint8_t *buf, int len) {
  uint8_t *item;
  uint8_t *end = buf + len;

  for (item = buf; item<end; item++) {
    *item += 3;
  }

  return 0;
}

# deal with buffer in JS
...
let dataHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, nDataBytes);
dataHeap.set(new Uint8Array(buffer_pcm.buffer));
...

所以,我可以得出结论,当我将 Buffer 转移到 WASM 时,我需要粘合代码来处理内存分配、内存泄漏和许多其他问题吗?

上面注释中描述的粘合代码是 Emscripten 生成的 JavaScript 加载器。 它完全按照注释说的做:在 JS 和 C++ 数据表示(例如字符串)之间以及不同对象表示之间(即为 C++ 对象创建 JS 代理对象)之间进行转换。 它还创建所需的类型化数组。

正如您所注意到的,对于简单的情况,例如您用作示例的两个函数,您可以省去 Emscripten 加载程序。 它们都不需要任何复杂的粘合代码:每个都只需要一个 JS 文件来加载 Wasm 文件(在第二个示例中,addThree 的 wasm 文件也需要创建 Uint8Array)。

最后,内存分配由 Wasm 代码处理,它应该包括一份来自 musl 的 malloc 副本(尽管 Emscripten 实际上仍然包括它的 malloc,而不是使用 musl 的)。 只需在完成 C/C++ 代码后释放内存,即可以标准方式避免内存泄漏,Wasm 在这里没有什么特别要求。

最终,您只需要实际使用的胶水代码,这取决于您的代码所做的跨边界调用(从 JS 到 C++,从 C++ 到 JS)。

这个问题可以关闭,这是一个关于 Emscripten 的问题,而不是 WebAssembly 设计本身的错误。

非常感谢

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

jfbastien picture jfbastien  ·  6评论

konsoletyper picture konsoletyper  ·  6评论

Artur-A picture Artur-A  ·  3评论

beriberikix picture beriberikix  ·  7评论

frehberg picture frehberg  ·  6评论