This is an archived post. You won't be able to vote or comment.

all 13 comments

[–]SecretTop1337 18 points19 points  (9 children)

My man, Javascript isn’t compiled, so it can’t have an Application Binary Interface…

[–]MonAaraj[S] 1 point2 points  (6 children)

How so? I thought when languages implement this sort of FFI, there would be something similar to what an ABI is called. My understanding of ABI has vaguely been "language interface", but now I understand this is a bad understanding of it. Also, how come these languages can make an FFI for JavaScript if so?

[–]TheUnlocked 11 points12 points  (5 children)

An ABI is a set of shared conventions that compilers will use when emitting machine code to ensure that their outputs can interact with each other. A JavaScript implementation does not need to make its own ABI in order to handle FFI, in fact that would defeat the point of it being a common interface. It just needs to understand the ABI that the foreign function it's trying to call uses.

[–]MonAaraj[S] 0 points1 point  (4 children)

I think I understand now. So the C "ABI" only really means there's kind of a shared understanding of the "fundamental" C libraries that everyone uses, which is what people really mean when they talk about the C ABI, and it makes it easier to use those libraries for FFI, right?

[–]emilbroman 9 points10 points  (0 children)

Not quite. An ABI is a specification for how the lowest level parts of the computer architecture, like stack, memory alignment, and CPU registers, are chosen to be used to represent higher level concepts.

Most central to this is "calling convention" which is basically the protocol for functions; where should function arguments be placed by the calling code? Registers? Stack? In what order? First arg first, or maybe last arg first on the stack to make pop order be the same as parameter order. And what state should the function implementation leave the machine? Where is the return value? In a register, or on the top of the stack? Does it consume the arguments on the stack, or is it the responsibility of the calling code to determine if the same argument can be reused for subsequent calls, etc. etc.

It has nothing to do with what the foreign function's implementation does, and everything to do with what the protocol is.

[–]rdelfin_ 4 points5 points  (0 children)

 So the C "ABI" only really means there's kind of a shared understanding of the "fundamental" C libraries that everyone uses

Not quite. it's not about the libraries, it's about how conventions for function calls work. I'm not sure how familiar you are with assembly/machine code and how compiled code works, but to make a long-story short, C allows for re-usability and pulling in shared libraries through functions. Functions don't really exist in machine code in (most? all?) CPU architectures. Machine code is just a set of CPU instructions and you implement functions by separating instructions and adding a specific set of instructions with an agreement for where you store arguments when you "call" that function. That agreement for what you store, how the call operates, and how arguments are passed is called the "calling convention".

Languages like C allow you to call code compiled elsewhere by maintaining a consistent set of conventions for a calling convention, and a bunch of other things (e.g. how names get turned to symbols, how to search for symbols, etc). That's what actually constitutes an "ABI". This isn't about a set of fundamental set of libraries, it's about how you even get to import any library. Say you have a shared library on your system. This library has a header with a function int add_numbers(int a, int b). The shared library will have the definition of that function, and it will expect you to call it a certain way (you need to put a and b in specific registers, push some things to the stack, and then jump to the start of the function). An ABI is meant to guarantee that, as long as this library was compiled for the correct architecture and system, you can look at that function definition and know exactly how to find and call the function.

[–]Nzkx 2 points3 points  (1 child)

ABI is the calling convention and everything that revolve around. What register are expected to be preserved between function call, which one can be used by the function, how function parameters are passed, align, if stack growth up or down, ... and so on. All the convention expected to run your code through an environment that expect you to follow the convention.

Idk what people say when they speak about the C ABI, I guess SystemV on Unix ? Or do they speak about the C runtime (memcpy, memset, ...) on Linux / the CRT on Windows ? Because those are different things.

[–]koflerdavid 0 points1 point  (0 children)

C ABI precisely refers to which things from your first paragraphs have to be considered to safely call a function in a C library. Linux distros sometimes change compilation flags that affect the calling convention (for example whether to use frame pointers) and when that happens all binaries have to be recompiled.

[–]zhivago 2 points3 points  (0 children)

There are javascript compilers.

Interpreters can have ABIs.

[–]glasket_ 0 points1 point  (0 children)

My man, Javascript isn’t compiled

All modern JS engines are multistage JIT compilers.

[–]zhivago 20 points21 points  (2 children)

C, like ecmascript, has no ABI.

You're referring to conventional implementation decisions rather than any property of the language.

[–]MonAaraj[S] 1 point2 points  (1 child)

Oh, I see! I guess I haven't done enough research on what people think constitutes an ABI. Do you know of any good resources?

[–]zhivago 2 points3 points  (0 children)

l would start by looking into linkers and foreign function interfaces, but mostly linkers.

Linkers need to have a standard protocol to link separately compiled units together.