4 ms·
"This isn't a theoretical question at all -- Rust actually has a different calling convention from C" Technically correct, but not at the register/stack manage
by eddyb 11y ago
"This isn't a theoretical question at all -- Rust actually has a different calling convention from C"
Technically correct, but not at the register/stack management level: LLVM still controls all of that, Rust only chooses the order of the arguments and whether they are passed "directly" (in registers or on the stack, when registers are exhausted) or "indirectly" (pointer to the value, whether it's on the stack or somewhere else).
So the following statement, "which means it sets up its stack differently" is incorrect: even if Rust wanted to, it couldn't do so with the LLVM backend.
- masklinn 11y agoI believe Go, however, uses its own stack rather than the C stack. I think Rust used to do the same thing and use segmented stacks (rather than the C stack) until late 2013 or early 2014, point at which the language's base was drastically lowered (in the abstraction stack) away from builtin GC, green threads and the like.
- eddyb 11y agoAt no point while using LLVM, could Rust have used a different calling convention. It was managing its stack, but it does that even today: when creating a thread, it allocates a 8MB stack. Within that stack, however, function calls work as they do in C, and they've been like that effectively forever (although the Ocaml bootstrap compiler might have had a non-LLVM x86 backend, not sure about that).
- yoklov 11y agoIt couldn't? I'm by no means an expert on this, as my only experience with LLVM was for a undergraduate research project back when I was still in college, but I could swear that it allows custom calling conventions (would verify if I weren't on my phone). Assuming I'm not mistaken about their existence, is there a reason Rust couldn't use one?
- eddyb 11y agoIt has a predefined set of calling conventions (sadly, this doesn't list x86 and other architecture-specific ones): http://llvm.org/docs/LangRef.html#calling-conventions http://llvm.org/docs/LangRef.html#calling-conventions GHC and HiPE appear to have gotten themselves LLVM calling conventions, I guess. But none of this can be customized further without modifying LLVM. Besides, none of these choices seem to affect anything other than the (ordered) set of registers available for arguments, and the sets of caller/callee-save registers (i.e. what you expect from x86 calling conventions). Once you get to the stack it's really all the same. What I meant was that Rust could have picked any of those choices, which would make it incompatible with C (it already is for some argument types because of the simplistic handling around them), but it couldn't have used its own special one, not without adding it to all LLVM targets it wants to support.
- gshrikant 11y agoIn turn, isn't LLVM's stack management and argument passing dictated by the hardware's ABI? ARM, for one, publishes its calling convention in AAPCS (ARM Architecture Procedure Call Standard) which establishes the calling convention on the C stack.
- derefr 11y agoARM and modern x64 have pretty rigorously-defined calling conventions, yeah. x86, on the other hand, has six or seven different ones, and it was up to you as a C programmer to choose which one to use for each given function, by sticking e.g. a __stdcall or a __fastcall in your typespec.
- atilaneves 11y agox64 on Linux has a different calling convention than x64 on Windows.
- lmm 11y agoIf the hardware manufacturer publishes an ABI most people will use it for the sake of convenience and interoperability. But it's not like the ARM police can stop you from using a different calling convention for your language if you want.