On Monday, 25 November 2019 at 18:44:01 UTC, thedeemon wrote:
On Saturday, 23 November 2019 at 09:51:13 UTC, Sebastiaan Koppe wrote:
This is my proposal for porting D runtime to WebAssembly. I would like to ask you to review it. You can find it here: https://gist.github.com/skoppe/7617ceba6afd67b2e20c6be4f922725d

Please correct me where I'm wrong, but on the level of WebAssembly there are no registers, there is an operand stack outside the address space, there are local variables to the current function, again outside the accessible address space of program's linear memory, and there is the linear memory itself. So scanning the stack becomes a really hard (should I say impossible?) part. What some compilers do is they organize another stack manually in the linear memory and store the values that would otherwise be on the normal stack, there.

Yeah, that accurately describes the situation. I will update the wording in the document to use 'stack', 'shadow stack' (also sometimes called 'user stack') and the local variable. Thanks.

One solution that I employed in spasm's experimental gc is to only run it directly from javascript. This way there can't be anything hiding in the stack or in a local variable. Although that approach doesn't work for all use cases.

Which means in case of D you'll have to seriously change the codegen, to change how local variables are stored, and to use a kind of shadow stack for temporaries in expressions that may be pointers. Do you really have a plan about it?

Well, no, not fully. That is why I said 'unknown'. But there must be a solution somewhere.

LLVM already puts pointers to stack or local variables in the shadow stack. As well as for structs-by-val that don't fit the stack. We could adjust LDC to nudge LLVM to maintain live roots on the shadow stack as well.

Go's approach is to put everything on the shadow stack. (see: https://docs.google.com/document/d/131vjr4DH6JFnb-blm_uRdaC0_Nv3OUwjEY5qVCxCup4/preview#heading=h.mjo1bish3xni)

There is also the possibility of a code transformation. Binaryen has a spill-the-pointer pass that effectively gets you go's solution (but only for i32's) (see: https://github.com/WebAssembly/binaryen/blob/master/src/passes/pass.cpp#L310)

I am favoring the first option, but I don't know how hard that would be. Will update the document with this info.

Thank you for questioning this.

Reply via email to