#llvm #wrap #compile #c #api-bindings

llvm-wrap

基于 llvm-sys 的 Rust 对 LLVM C API 绑定的更安全的包装

5 个版本

使用旧的 Rust 2015

0.2.5 2018 年 3 月 21 日
0.2.4 2018 年 3 月 21 日
0.2.3 2018 年 3 月 16 日
0.2.2 2018 年 3 月 13 日
0.2.1 2018 年 3 月 11 日

#81 in #wrap

MIT 许可证

68KB
1.5K SLoC

基于 llvm-sys 的 Rust 对 LLVM C API 绑定的更安全的包装

安全性说明

尽管使用此库不需要 unsafe 块,但它确实忽略了 Rust 对内存管理的一些约束。主要是不变的引用仍然可以被修改,以便使某些程序更加简单。

为了简单起见,当离开作用域时,会自动处理 LLVMBuilderLLVMModule。值和类型始终在 LLVM 提供的默认全局上下文中创建。

如果需要,可以使用 inner 函数访问包装的值,或使用 into_inner 在不处理包含的值的情况下销毁包装器。大多数类型也可以解引用到它们的 C 等价类型。此包仍在开发中,许多功能尚未完全支持,因此如果您需要使用不受支持的 LLVM 函数,请使用此包。使用 into_cfrom_c 在直接处理 C API 时使字符串更容易处理。

设置

此包严重依赖于 llvm-sys 并需要相同的设置。在使用此包之前,请确保安装了 LLVM 5 版本,并将 LLVM_SYS_50_PREFIX=/path/to/llvm 添加到您的 PATH 环境变量中。

LLVM 文档 | LLVM 语言参考 | Rust 绑定

示例

// Create a module
let module = create_module("add");
// Create a builder
let builder = create_builder();

// Get an `i32 (i32, i32)` type
let ty = ty_i32().function(vec![ty_i32(); 2], false);
// Create the add function
let def = module.add_function("add", ty);
// Add an entry block
let entry = def.append_basic_block("entry");
// Move the builder to the end of the block
builder.position_at_end(entry);
// Add and name the two parameters
let result = builder.build_int_add(
    def.param(0).name("a"),
    def.param(1).name("b"),
);
// Return and name the result
builder.build_ret(result.name("tmp"));

// Dump the contents of the module
module.dump();

输出

; ModuleID = 'add'
source_filename = "add"

define i32 @add(i32 %a, i32 %b) {
entry:
  %tmp = add i32 %a, %b
  ret i32 %tmp
}

依赖项

~0.3–0.8MB
~17K SLoC