我使用clang -> llc -> s2wasm
和clang -> lld
正在从C到WebAssembly编译。因为没有提供C库,所以我写了自己的分配器。但是我不确定最好的方法是找到免费内存的开始。
LLD和S2WASM似乎都具有内存布局:| globals | stack | free memory |
。使用S2WASM的堆栈指针位于内存地址,使用lld在全局中(从C?(。
我发现的一种方法是使用此hack在WASM执行开始时读取StackPointer:
int stacktop()
{
int a;
return (int)(&a+1);
}
这将创建一个局部变量,该变量不存在于线性内存并接收其地址。要生成一个地址,编译器将其放在内存堆栈上。
我将返回的值用作堆的开始。是否有一种更优雅,更适合未来的方法可以找到自由记忆?
您需要获取lld创建的__heap_base
符号的地址:
$ cat wasm-heap.c
extern unsigned char __heap_base;
__attribute__ ((visibility("default")))
void * get_heap_base(void) {
return &__heap_base;
}
这将返回与导出到JavaScript的__heap_base
WASM变量相同的值:
$ cat wasm-heap.js
var imports = {memory: new WebAssembly.Memory({initial:2})};
const module = new WebAssembly.Module(read('wasm-heap.wasm', 'binary'));
const instance = new WebAssembly.Instance(module, { "env" : imports }).exports;
var u8_data = new Uint8Array(imports["memory"]["buffer"]);
print("Heap base in WASM: " + instance.get_heap_base());
print("Heap base exported to JS: " + instance.__heap_base);
$ js52 wasm-heap.js
Heap base in WASM: 66560
Heap base exported to JS: 66560
lld创建一个称为 __heap_base
的C符号,该符号指向堆的底部。它还将其导出为WASM全局,以便嵌入器可以知道堆从哪里开始。