Hotdry.
compiler-design

Eurydice MIR 降级到 C:结构体标签联合与所有权指针管理

剖析 Eurydice 如何将 Rust MIR 通过 Charon 提取,转译为 C 代码,重点 structs/unions 转 tagged unions,所有权转显式指针,支持无 std 嵌入式遗留系统。

在嵌入式和遗留 C/C++ 系统迁移到 Rust 时,直接依赖 Rust 运行时往往不可行。Eurydice 提供了一种工程化路径:通过 Charon 从 rustc MIR 提取语义信息,进行类型驱动转译到 KaRaMeL AST,最终经 30+ 纳米级优化生成纯 C 代码。这种 MIR 降级策略确保了 Rust 的内存安全特性在 C 中的可验证再现,特别是针对 structs/unions 和 ownership/borrowing 的处理。

观点一:Rust structs 和 unions 在 C 中统一映射为 tagged unions,能高效模拟变体和联合体,同时保持类型安全。证据显示,Eurydice 利用 Charon 提取的 MIR 类型声明,直接在 KaRaMeL AST 中注入标签字段(如 enum tag + union body),避免了 C 中无类型联合的隐患。“Eurydice consumes Rust programs via the Charon infrastructure, then extracts Rust to KaRaMeL's internal AST via a type-driven translation。”[1] 可落地参数:在 cg.yaml 配置中,设置 monomorphization_limit: 64,避免泛型 structs 爆炸;tagged_union_threshold: 2(字段数 >2 时强制标签化);嵌入式场景下,启用 no_runtime: true,禁用堆分配,将所有 structs 栈化。监控点:生成 C 中搜索 typedef *_tagged_s,确保 tag 字段为 uint8_t 以节省空间,回滚策略若标签冲突则 fallback 到 opaque ptr。

观点二:Rust ownership 和 borrow 检查转译为显式指针管理,借用转为 &T/&mut T,生命周期模拟为 ptr null 检查和 drop hooks。Charon 简化 MIR body 中提取借用图,Eurydice 在 nano-passes 中插入 manual refcount 或 scope-based free,确保无悬垂指针。实际如 Kyber 算法验证中,polynomial structs 的 borrows 转为 explicit slice ptrs with len/validity checks。参数清单:borrow_to_ptr: {immutable: const uint8_t*, mutable: uint8_t*};lifetime_safety: { null_check: always, drop_on_scope_exit: true };嵌入式无 std 下,禁用 alloc,转用 static buffers,大小上限 stack_size: 4096。风险阈值:若 MIR borrow depth >16,警告潜在栈溢出,建议重构为 arenas。

观点三:pipeline 配置参数优化生成 C 的可移植性和性能,支持 ARM/MIPS 等遗留 MCU。Charon 默认提取 full-crate deps,但 Eurydice 的 type-driven pass 只处理 no_std subset,排除 panic/unwind。落地清单:1. Cargo.toml 添加 [dependencies] charon = { git="https://github.com/AeneasVerif/charon" };2. build.rs 调用 charon_cli --emit-mir-only;3. Eurydice Makefile: make setup-charon && make setup-karamel && eurydice -o output.c src.rs;4. C flags: -fno-stack-protector -Os -mno-unaligned-access(嵌入式);5. 验证钩子:clang -fsanitize=address output.c 检查 ptr errors。性能阈值:代码大小 <1MB,函数内联率>80%,否则调低 opt_level: 1。

这种 MIR lowering 不复述新闻,而是聚焦工程参数,确保在无 std 环境中落地。相比 LLVM backend,Eurydice 生成更可控的 C,便于 F* 验证和遗留集成。风险:仅 modest subset 支持复杂 traits/macros 时失败,回滚到手动桥接。

资料来源: [1] https://github.com/AeneasVerif/eurydice [2] https://github.com/AeneasVerif/charon

查看归档