Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack pointer in WebAssembly? #338

Closed
jcbeyler opened this issue Sep 10, 2015 · 4 comments
Closed

Stack pointer in WebAssembly? #338

jcbeyler opened this issue Sep 10, 2015 · 4 comments

Comments

@jcbeyler
Copy link

While reading the spec and looking at what is there, I was wondering about this but was not sure if this has been answered or not. If it has, I apologize!

I was wondering if the concept of stack pointer exists or will exist in Wasm? The question becomes relevant when you try to take a C-like code and port it to Wasm, If you do something like:

int a;
foo(&a);

It seems to me that you need to figure out a way to get the address of a in Wasm to port this code correctly.

I think, in the end, the question of the stack pointer comes to a bigger question of what are the limits (if any) of the C-language that we do not want to see reflected in Wasm and then, if there are any, how do we alleviate that?

Now it is possible that the way Wasm wants us to do this is to allocate this in memory directly and reference there but that might make C -> Wasm a bit tricky in certain cases.

@PeterJensen
Copy link

I guess this comes down to how the LLVM 'alloca' instruction is envisoned implemented when compiling LLVM bitcode into wasm code. Is the current thinking that a stack mechanism is implemented 'by-hand' like the way asm.js code does it with use of a global STACKTOP variable that's an index into the memory space. The STACKTOP variable could conveniently be represented as a wasm global, right?

For this C function:

void foo() {
    int x;
    bar(&x);
}

The asm.js code looks like this:

function _foo() {
 var $x = 0, label = 0, sp = 0;
 sp = STACKTOP;
 STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();
 $x = sp;
 _bar($x);
 STACKTOP = sp;return;
}

@sunfishcode
Copy link
Member

That's correct; the current thinking is that there will be an asm.js-style STACKTOP (though the details of that are still being discussed, e.g. here), and it will be a pointer into the "aliased stack", which is a region of linear memory. LLVM alloca instructions that aren't optimized away will be translated into linear memory regions addressed by some offset from the value of STACKTOP.

@lukewagner
Copy link
Member

You're right that, if a C variable is address-taken, it has to go in linear memory; wasm can't point into the native stack (and, in general, wasm has a trusted stack).

In the MVP, there are no threads, so a global or just constant memory address can be used (both should compile to a single load/store from constant address). When we have threads, STACKTOP will need to go in a TLS variable. An engine is expected to maintain some TLS register (or segment on x86 :) and be able to put wasm TLS variables into the array pointed to by the TLS register. We have discussed the possibility that, on register-plenty archs, a wasm engine could keep the STACKTOP TLS variable pinned to a physical register. This depends on measurements to see if this is actually a win vs. losing a register and would be an implementation detail anyway.

@jfbastien
Copy link
Member

To add a bit to what was said above (and with which I agree): wasm will have a "shadow" stack where all non-developer visible state is spilled. This includes code addresses for return as well as register spills and impl-specific calling convention gunk which isn't encoded in the .wasm format. It gets a bit tricky because this is very fluid depending on how compilers such as LLVM lowered C/C++ code to .wasm.

To address your issue: C's defined behavior should "just work", C's undefined behavior will often work, and users should always stay secure regardless of the tricks developers try to pull on the VM.

I'm assuming this answers the question and will therefore close it. Feel free to reopen if that's not the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants