Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is heap memory managed in WebAssembly?

I am developing the toolchain of a pure, functional programming language that aims on targeting WebAssembly. I am somewhat familiar with type theory, and thus, the type checker for this language is ready. The problem that I'm facing right now is translating this high level language to the lower level of WebAssembly.

After checking types, the compiler is able to take the AST and transform it into a fairly standard supercombinator, lambda-lifted form. Every expression will be either a:

  • Function call (name of a top-level function + expressions standing for arguments)
  • Reference (name of a top-level function or constant);
  • Variable (name of an argument or local);
  • Integer (i32 numeric literal);
  • Double (f64 numeric literal);
  • Bytestring (size + sequence of size UTF-8 bytes);
  • Thunk (name of a top-level function + an environment of captured values).

Function calls, references, variables, integers, doubles and bytestrings are self-explanatory. Thunks are obtained from partially applied functions or from lambda-lifted closures. The compiler knows when and where thunks become saturated and is capable of automatically inserting force instructions.

Pointers and numeric literals will happily live on the stack, they are small and cheap to copy around. But copying bytestrings, depending on how big they are, can be costly and there's also the chance of an overflow. Manipulating bytestrings on stack memory would also require copies. Functions manipulating recursive data structures may require a copy of the entire thunk at each step.

This means that some heap allocation would be immensely helpful (nigh indispensable), but managing heap memory manually without some tool like malloc/free is a recipe for disaster. Threads like this and posts like this mention allocators for WebAssembly that I thought were only available to C, and I have no idea how it would be possible for me to bring one of them to the runtime of my language. There's also this repository, but I don't know how I would be able to turn this allocator written in Rust into a generic WebAssembly module and use the exported functions.

How would I start integrating an allocator into the runtime of the generated WebAssembly bytecode that comes from the compiler of my language?

like image 723
Valmir Junior Avatar asked Oct 17 '25 21:10

Valmir Junior


1 Answers

WebAssembly programs are, from the perspective of heap and memory management, very much like the C programs you run on other computers. In fact, that's the point.

So you don't use something like malloc()/free(), you use malloc and free themselves- compiled to wasm bytecode, rather than x64 or arm machine code.

If there's anything at all exotic in the RAM model of wasm modules, it's in the message-passing protocols between wasm and the Javascript code hosting it.

like image 73
O. Jones Avatar answered Oct 19 '25 14:10

O. Jones