【问题标题】:How is heap memory managed in WebAssembly?WebAssembly 中如何管理堆内存?
【发布时间】:2021-04-30 20:40:07
【问题描述】:

我正在开发一种针对 WebAssembly 的纯函数式编程语言的工具链。我对类型理论有点熟悉,因此,该语言的类型检查器已经准备就绪。我现在面临的问题是将这种高级语言翻译成较低级别的 WebAssembly。

在检查类型之后,编译器能够获取 AST 并将其转换为相当标准的超级组合子、lambda-lifted 形式。每个表达式都可以是:

  • 函数调用(顶级函数的名称 + 表示参数的表达式)
  • 引用(顶级函数或常量的名称);
  • 变量(参数名称或本地名称);
  • 整数(i32 数字文字);
  • 双(f64 数字文字);
  • 字节串(size + size UTF-8 字节序列);
  • Thunk(顶级函数的名称 + 捕获值的环境)。

函数调用、引用、变量、整数、双精度和字节串是不言自明的。 Thunks 是从部分应用的函数或从 lambda 提升的闭包中获得的。编译器知道 thunk 何时何地饱和,并能够自动插入 force 指令。

指针和数字字面量会很高兴地存在于堆栈中,它们体积小且复制成本低。但是复制字节串,取决于它们有多大,可能会很昂贵,而且还有溢出的可能性。在堆栈内存上操作字节串也需要副本。操作递归数据结构的函数可能需要在每一步都复制整个 thunk。

这意味着一些堆分配将非常有用(几乎是必不可少的),但是没有像malloc/free 这样的工具手动管理堆内存是灾难的根源。 this 之类的线程和 this 之类的帖子提到了我认为仅适用于 C 的 WebAssembly 分配器,我不知道如何将其中一个带入我的语言的运行时。还有 this 存储库,但我不知道如何将这个用 Rust 编写的分配器转换为通用 WebAssembly 模块并使用导出的函数。

如何开始将分配器集成到生成的 WebAssembly 字节码的运行时中,该字节码来自我的语言的编译器?

【问题讨论】:

    标签: compiler-construction webassembly


    【解决方案1】:

    从堆和内存管理的角度来看,WebAssembly 程序与您在其他计算机上运行的 C 程序非常相似。事实上,这就是重点。

    所以你不使用 类似 malloc()/free() 的东西,你使用 malloc 并释放自己——编译成 wasm 字节码,而不是 x64 或 arm 机器码。

    如果说 wasm 模块的 RAM 模型中有什么特别之处,那就是 wasm 和托管它的 Javascript 代码之间的消息传递协议。

    【讨论】:

    • 我应该在我的开篇文章开头说明我对任何 C 及更低级别的东西都没有什么经验。我主要还在学习如何创建编译器。你有什么资源可以告诉我将独立的分配器库编译成我可以试验的 WebAssembly 模块吗?
    • 恕我直言,我建议您去看看 Brian Kernighan 和 Dennis Ritchie 的 C 书。做那本书中的一两个小问题集。这与环境非常相似,一个相当原始的环境,你会在 Wasm 中看到。读这个。 stackoverflow.com/questions/57032577/…emscripten
    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 2021-04-28
    • 2012-03-07
    • 2020-10-10
    • 2015-09-28
    • 1970-01-01
    • 2011-01-05
    • 2011-01-16
    相关资源
    最近更新 更多