ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何为ErlangRT扩展新BIF:4步实现原生函数的完整开发指南

如何为ErlangRT扩展新BIF:4步实现原生函数的完整开发指南 如何为ErlangRT扩展新BIF4步实现原生函数的完整开发指南【免费下载链接】ErlangRTErlang Replacement Therapy. Another attempt to make Erlang runtime (BEAM emulator) in Rust. Good news: I know what to do. Bad news: I have no clue how to Rust项目地址: https://gitcode.com/gh_mirrors/er/ErlangRTErlangRT 是一个用 Rust 编写的 Erlang 运行时BEAM 模拟器项目目标是用 Rust 重新实现 BEAM 虚拟机。如果你想为它扩展一个新的 BIF内置函数Built-In Function也就是用 Rust 原生代码实现 Erlang 侧可直接调用的函数本文将以 4 个步骤带你完成从定义、实现、注册到生成查找表的全过程。先了解 ErlangRT 的 BIF 机制在 ErlangRT 中BIF 被称为Native Function原生函数。它的统一函数签名定义在 lib-erlangrt/src/native_fun/mod.rs 中pub type NativeFn fn(vm: mut VM, cur_proc: mut Process, args: [Term]) - RtResultTerm;可以看到每个 BIF 都是纯函数接收一个虚拟机实例、当前进程和参数列表返回一个 Erlang 项Term。整体调用链是这样的BEAM 指令call触发时虚拟机会先查原生函数注册表注册表NativeFunRegistry位于lib-erlangrt/src/native_fun/registry.rs维护了一棵模块 → 函数表的树启动时预加载了erlang、erts_internal、lists三个原生模块命中后直接调用 Rust 函数指针不再走字节码执行若未命中再回落到已加载的 BEAM 模块。每个模块的函数表由NativeModule管理lib-erlangrt/src/native_fun/module.rs函数条目则使用NativeFnEntry结构lib-erlangrt/src/native_fun/fn_entry.rs记录函数名 元数的组合。准备工作获取源码并构建 克隆仓库并安装 Rust 工具链后即可构建git clone https://gitcode.com/gh_mirrors/er/ErlangRT cd ErlangRT make构建依赖 OTP 22 源码项目通过 Git 子模块管理Makefile 会自动处理。开发过程中常用的命令make build调试构建、make build-rel发布构建、make test运行测试、make doc生成文档。第1步用宏定义 BIF 入口ErlangRT 提供define_nativefun!宏定义在lib-erlangrt/src/native_fun/macros.rs它会帮你生成结构体、入口函数、参数提取和元数校验避免手写大量样板代码。以参考lists:member/2的实现lib-erlangrt/src/native_fun/lists/misc.rs为例新 BIF 的入口长这样define_nativefun!(_vm, _proc, args, name: lists:member/2, struct_name: NfListsMember2, arity: 2, invoke: { member_2(sample, list) }, args: term(sample), list(list), );各部分含义name模块:函数/元数用于调试断言struct_name生成的入口结构体名称invoke真正执行的逻辑调用args按位置声明参数类型term(x)表示任意项usize(x)表示要求正整数否则返回 badarg。 小技巧把实际逻辑放进一个#[inline]的独立函数如member_2入口宏只做参数解包代码更清晰。第2步实现 Rust 逻辑函数本体遵循入参校验 → 堆操作 → 返回 Term的模式。lists:member/2的实现展示了典型写法#[inline] fn member_2(sample: Term, list: Term) - RtResultTerm { if list Term::nil() { return Ok(Term::make_bool(false)); } let result cons::any(list, |elem| /* 比较逻辑 */); Ok(Term::make_bool(result)) }几个实用要点返回错误参数不合法时返回Err如 badarg而不是 panicErlang 侧会以异常形式收到构造复杂项使用term_builder模块如ListBuilder、TupleBuilderlib-erlangrt/src/term/term_builder/操作进程堆通过proc.get_heap_mut()获取堆例如lists:reverse/2就用ListBuilder向前拼接元素。第3步注册到原生模块写好后需要把函数挂到对应模块的函数表上。以lists模块为例lib-erlangrt/src/native_fun/lists/mod.rs模块的new()方法会通过init_with批量插入NativeFnEntry条目每个条目由NativeFnEntry::with_str(函数名, 元数, 函数指针)构造。如果你要新增一个全新模块而非往erlang/lists等现有模块加函数需要在lib-erlangrt/src/native_fun/下新建模块目录仿照lists/组织mod.rs在lib-erlangrt/src/native_fun/mod.rs中声明该模块在lib-erlangrt/src/native_fun/registry.rs的register_preloaded_modules中用atom::from_str取出模块名并insert进注册表使虚拟机启动时自动预加载。第4步重新生成 BIF 查找表ErlangRT 的代码生成体系位于lib-erlangrt/codegen/目录。BIF 全局查找表BIF_TABLE由脚本lib-erlangrt/codegen/create_gen_native_fun.py生成输出到lib-erlangrt/src/native_fun/gen_native_fun.rs。重新生成只需执行见lib-erlangrt/codegen/Makefilecd lib-erlangrt/codegen make genbif该目标会运行./create_gen_native_fun.py ../src/native_fun/gen_native_fun.rs。生成脚本读取 OTP 配置默认 OTP22把 BIF 的模块名、函数名自动转换为原子常量名和元数组装成BifTabItem数组。最后运行make build确认编译通过再用make test跑一遍测试确保新 BIF 没有破坏现有功能。相关文件速查内容路径NativeFn 类型定义lib-erlangrt/src/native_fun/mod.rsdefine_nativefun!宏lib-erlangrt/src/native_fun/macros.rs原生函数注册表lib-erlangrt/src/native_fun/registry.rs函数表结构lib-erlangrt/src/native_fun/module.rs、lib-erlangrt/src/native_fun/fn_entry.rs参考实现lists 模块lib-erlangrt/src/native_fun/lists/misc.rsBIF 表生成脚本lib-erlangrt/codegen/create_gen_native_fun.py生成的查找表lib-erlangrt/src/native_fun/gen_native_fun.rs项目说明文档README.rst小结为 ErlangRT 扩展 BIF 的核心路径是用define_nativefun!宏定义入口 → 用 Term 与 term_builder 实现 Rust 逻辑 → 注册进 NativeModule 与注册表 → 用make genbif重新生成 BIF_TABLE。项目目前 BIF 完成度还不高README 中标注 15%这意味着新增原生函数空间很大也是参与贡献 ErlangRT 的最佳切入点之一。【免费下载链接】ErlangRTErlang Replacement Therapy. Another attempt to make Erlang runtime (BEAM emulator) in Rust. Good news: I know what to do. Bad news: I have no clue how to Rust项目地址: https://gitcode.com/gh_mirrors/er/ErlangRT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表