扩展运行机制

扩展运行机制

扩展运行机制

功能

扩展机制把“脚本能看到的 API”和“扩展内部如何执行”分开。脚本只通过 bindings.json 里声明的入口、对象和方法调用扩展;BT 宿主负责加载 .bts 包、校验描述文件、建立注册表,并把调用分发给对应 Runner。

语法

扩展入口调用语法和普通函数一致:

calc 来自 bindings.json 的公开入口声明,addvalue 来自对象方法声明。

参数

扩展调用的参数由 bindings 决定。宿主会按 bindings 的参数数量、类型和 role 处理脚本传入的值,再把调用交给对应 Runner。

返回值

扩展调用可以返回原始值,也可以返回扩展对象句柄。对象句柄只表示“某个扩展模块中的某个对象”,真实状态由扩展后端保存。

加载流程

项目启动时,BT 会按以下流程处理扩展:

1. 查找项目根目录下的 extensions/

2. 按文件名顺序读取目录中的 .bts 文件。

3. 校验 .bts 后缀、zip 条目路径、条目数量、单文件大小和总解压大小。

4. 读取并校验 manifest.json

5. 读取并校验 bindings.json

6. 根据 manifest.kind 初始化纯 BT Runner 或 WASM Runner。

7. 建立扩展注册表,检查公开入口名是否冲突。

8. 把公开入口注入到当前 VM 的用户全局环境。

加载失败时,项目启动会失败并输出中文错误;BT 不会加载半成功的扩展包。

调用流程

脚本调用扩展入口时:

宿主会按入口名 calc 找到 bindings 中的函数声明,检查参数数量和类型,再把调用交给扩展所属 Runner。返回值如果是普通值,就直接回到脚本;如果是扩展对象,脚本拿到的是一个受宿主管理的对象句柄。

脚本调用对象方法时,宿主会先根据对象句柄找到扩展模块和对象类型,再查找方法名。WASM 方法调用时,接收者对象句柄会作为第一个参数传给 WASM;纯 BT 方法调用时,宿主会在内部 VM 中把方法调用到对应对象上。

kind 和 abi

kind 是后端类型,决定入口文件由谁执行。abi 是调用协议版本,决定宿主和后端如何交换参数、返回值和对象句柄。

kindabiRunner
btbts-bt-1纯 BT Runner,复用 BT Parser、Compiler 和 VM。
wasmbts-wasi-1WASM Runner,使用 WASI P1 和 BtValueBinary。

这两个字段不能随意组合。kind=bt 必须使用 bts-bt-1kind=wasm 必须使用 bts-wasi-1

代码示例

同一个 bindings.json 风格可以对应不同后端。脚本侧调用保持一致:

差别只在扩展包内部:纯 BT 扩展由 src/lib.bt 实现;WASM 扩展由 module.wasm 实现。

注意事项

  • 公开入口会成为全局常量,脚本不能重新赋值。
  • env('calc') 可以读取扩展入口,has_env('calc') 返回 true
  • envs('calc')has_envs('calc') 只表示系统函数和系统常量,不会把扩展入口当作系统能力。
  • 扩展入口名不能和 BT 系统环境名称冲突,也不能和其他扩展入口重复。
  • 扩展对象不应跨越不支持对象句柄的边界,例如 task() 快照。