Skip to content
Tech News
← Back to articles

The Fil-C Optimized Calling Convention

read original more articles
Why This Matters

The Fil-C optimized calling convention enhances memory safety in C programs by detecting and preventing common errors such as incorrect function signatures, argument types, and misuse of calling conventions. It achieves this without sacrificing much performance, making it a significant advancement for both developers and the broader tech industry focused on secure and reliable software development.

Key Takeaways

The Fil-C Optimized Calling Convention

Fil-C achieves memory safety even for programs that behave adversarially. That includes casting function pointers to the wrong signature and then calling them, exporting a function with one signature in one module and then importing it with a different signature in another, or even exporting a symbol as a function in one module and importing it as data in another (and vice-versa). Passing too few arguments, arguments of the wrong type, misusing va_list (including escaping it), expecting too many values to be returned - these are all things that the Fil-C calling convention either catches with a panic or ascribes safe behavior to.

But in the common case - like when the programmer is behaving themselves - Fil-C generates reasonably efficient code for the call. For example, a call like this:

int x = 42; const char* y = "hello"; int z = foo(x, y);

in one module (say caller.c ) with foo defined in another module (say foo.c ):

int foo(int x, const char* y) { ... /* whatever */ }

will be compiled at the callsite exactly as if you had done the following call in Yolo-C with an optimized arguments-in-registers ABI:

foo(my_thread, x, y);

Where my_thread is a pointer to the current Fil-C thread, which Fil-C passes around as the first argument in all calls. So, my_thread , x , and y will be passed in registers. The implementation of foo will not check that x is an int and that y is a const char* (though if you use y , it will check that the pointer is in bounds of the capability and that the capability allows whatever kind of access you do). The return value will be passed in a register, too. In this regard, Fil-C is almost as efficient as Yolo-C!

And yet, if we changed foo to take extra arguments, we would get a panic. And if we changed the signature in any way (maybe x becomes a pointer and y becomes a double ), we would either get a panic or a well-defined bitwise cast of the value to the other type.

... continue reading