.. | ||
src | ||
tests | ||
Cargo.toml | ||
README.md | ||
regenerate.sh |
Bitcode for Builtins
Roc's builtins are implemented in the compiler using LLVM only. When their implementations are simple enough (e.g. addition), they can be implemented directly in Inkwell.
When their implementations are complex enough, it's nicer to implement them in a higher-level language like Rust, compile the result to LLVM bitcode, and import that bitcode into the compiler.
Here is the process for doing that.
Building the bitcode
The source we'll use to generate the bitcode is in src/lib.rs
in this directory.
To generate the bitcode, cd
into compiler/builtins/bitcode/
and run:
$ ./regenerate.sh
If you want to take a look at the human-readable LLVM IR rather than the bitcode, run this instead and look for a
.ll
file instead of a.bc
file:$ cargo rustc --release --lib -- --emit=llvm-ir
Then look in the root
roc
source directory undertarget/release/deps/
for a file with a name likeroc_builtins_bitcode-8da0901c58a73ebf.bc
- except probably with a different hash before the.bc
. If there's more than one*.bc
file in that directory, delete the wholedeps/
directory and re-run thecargo rustc
command above to regenerate it.
Note: In order to be able to address the bitcode functions by name, they need to be defined with the #[no_mangle]
attribute.
The bitcode is a bunch of bytes that aren't particularly human-readable. Since Roc is designed to be distributed as a single binary, these bytes need to be included in the raw source somewhere.
The llvm/src/build.rs
file statically imports these raw bytes
using the include_bytes!
macro.
The current .bc
file is located at:
compiler/gen/src/llvm/builtins.bc
The script will automatically replace this .bc
file with the new one.
Once that's done, git status
should show that the builtins.bc
file
has been changed. Commit that change and you're done!
Calling bitcode functions
Use the call_bitcode_fn
function defined in llvm/src/build.rs
to call bitcode funcitons.