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
Reduce reliance on C++ types in the public API #121
Comments
We do have plans to add a C++-free interface to compile code. I agree it's important, it would allow using Luau compiler + VM across a C or C-like boundary. This could be done with an extra header like CompilerC.h that exports an extra C-friendly interface, still implemented in Compiler.cpp. PR welcome ;) I don't think it's realistic for us to do this for AST or Analysis. |
It's a bit weird that Luau uses
Nevermind - forgot Windows was stupid - and has a case-insensitive filesystem. Scratch that idea.
I'll look into it
It's not realistic for you to do it for anything, all things considered. Roblox as a company doesn't really have any C-only products to use it in :) |
We don't really have any pure C headers; in general in Roblox codebase ".h" is used as "C/C++ header" without differentiation. This is a pretty common style in C++ projects as well, although some projects indeed use |
It's a bit involved to define a C version of the compiler interface without pulling in tons of C++ stuff. For example, the error gives (and/or takes) a Is that something you'd be willing to accept, if I had to redefine some C++ classes as C structs? They would stay C++ classes in other parts of the codebase, but the C-only header file would have its own struct version. |
I think you only need to expose |
What about all the options structs and the bytecode encoder? I can expose functions to create/free a bytecode encoder and you'd just have to pass the pointer to compile - would that be okay? |
You can just skip the bytecode encoder. I forgot about the options - these are good to preserve. I think the headers with options are self-sufficient and don't rely on STL? |
CompileOptions are provided in the Compiler header itself, so I will have to redefine it, possibly as |
If you wanted to build an interface to the type checker in another language, it wouldn't be worth it to reflect the whole interface over. You probably just need a handful of things:
If you need more than that, you'll probably have to build it out in C++, but you should still be able to provide a narrow interface to that. |
I think the real action item here is an FFI-friendly interface for the compiler; this will let projects that use other languages or projects that don't use STL includes for policy reasons to still use compiler + VM. Everything else is probably best left outside of scope of this project, at least for now - you can always wrap Frontend or type introspection. Also worth noting that right now we plan to be ABI- and source-compatible within reason in the C-like API surface, but don't really have any sort of compat guarantees for C++ surface as we'd like to keep an ability to refactor at will. This is currently not documented, which we can fix after we add C-friendly compiler interface, and will result in a guarantee that loosely matches LLVM - LLVM has a C interface that is stable but only exposes a subset of LLVM functionality, and to build a fully featured toolchain you likely need to use the C++ interface. Similarly for Luau, the C interface is going to be sufficient for basic integration, but for something fully featured that includes type checking, autocomplete, et al, you really will need to work with the C++ interface, at least for now. We'll keep this issue open and will close it when a compiler interface arrives and the ABI/source compat gets documented in README.md |
@zeux If you're interested, I've already implemented a pure C interface to the compiler that doesn't raise exceptions, but manages to still communicate all the information from the exception(s) that would have been raised when there is an error. It does this is through a tagged union, which can represent a successful compilation, any amount of parse errors, or a compile error. It is quite complex, though, and more allocations than I'd like are required to shuffle blocks of data around. Perhaps Luau could adopt something like that? (That repository is licensed under GPLv3, but I still have full rights to the code and can offer it or a modified version of it to you under MIT.) |
- Improve error recovery during type checking - Initial (not fully complete) implementation for singleton types (RFC RFC: Singleton types #37) - Implement a C-friendly interface for compiler (luacode.h) - Remove C++ features from lua.h (removed default arguments from luau_load and lua_pushcfunction) - Fix lua_breakpoint behavior when enabled=false - Implement coroutine.close (RFC RFC: coroutine.close #88) Note, this introduces small breaking changes in lua.h: - luau_load env argument is now required, pass an extra 0 - lua_pushcfunction now must be called with 3 arguments; if you were calling it with 2 arguments, pass an extra NULL; if you were calling it with 4, use lua_pushcclosure. These changes are necessary to make sure lua.h can be used from pure C - the future release will make it possible by adding an option to luaconf.h to change function name mangling to be C-compatible. We don't anticipate breaking the FFI interface in the future, but this change was necessary to restore C compatibility. Closes #121 Fixes #213
The |
It's obviously up to you as to what you use; luacode.h should be sufficient for most use cases that involve pure code compilation, e.g. it's sufficient for Roblox. |
I understand how Luau evolved to contain so much C++, especially as Roblox uses C++ internally for the game engine and many other things.
Whatever is used for the implementation, C++ in the header files specifically raises lots of portability concerns. For example, most languages are simply unable to process C++ templates in any capacity, let alone classes.
I'm trying to create bindings to Luau so that I can use it from Rust, but bindgen famously cannot understand templates at all, and I don't imagine other languages have any solutions either. Furthermore, it's not even possible to use any templated functions or classes because templates require expansion before use.
This problem mostly attributes itself to the 500+ uses of STL types in the header files, specifically AST, Compiler and Analysis, which is pretty much 3/4ths of the project at this point.
Using any module other than VM (compiler especially, compiler is quite important) from another programming language is currently extremely difficult, manual, and error-prone with the current API surface. STL types are generally magical and cannot be understood by any language that is not C++, so it's usually best to keep them as implementation details, not exposed in the public API as they are now. Automated tools cannot digest them so all FFI must be done manually by a human which can introduce subtle memory bugs and undefined behavior just like that.
Luau is already in its situation with template types everywhere. Is it even possible to solve this now?
The text was updated successfully, but these errors were encountered: