Fluxon 默认以解释器运行,但也支持将脚本编译为 Java 8 字节码并直接执行。编译模式的入口是Documentation Index
Fetch the complete documentation index at: https://fluxon.tabooproject.org/llms.txt
Use this file to discover all available pages before exploring further.
Fluxon.compile(...),产物为一组
.class 字节码:
- 主脚本类:继承
RuntimeScriptBase,实现脚本主体逻辑。 - 内部类:用于
def/lambda 等脚本定义(同样由字节码生成器输出)。
target::method)、索引访问(obj[index])等依然交由运行时的
Intrinsics/Environment/注册表处理,因此语义应与解释器保持一致。
快速上手
CompileResult#dump(File) 输出 .class 文件,或用 CompileResult#defineClass(FluxonClassLoader)
手动控制类加载过程。
RuntimeScriptBase 的角色
- 每个编译后的脚本都会生成一个继承
RuntimeScriptBase的类。 - 生成类会覆写
eval(Environment),直接在字节码中实现脚本逻辑。 - 运行时错误会通过
RuntimeScriptBase#attachRuntimeError(...)补充源码摘录,便于定位行列。 - 生成类会实现
clone(),用于复制脚本实例(避免共享可变状态)。
索引访问器
IndexAccessor抽象了target[index]的读写行为,既可服务解释器,也可让编译器在遇到[]语法时绑定到正确的宿主类型。IndexAccessorRegistry利用 Java SPI 自动加载第三方实现,并允许在运行时调用registerAccessor提高优先级。- 索引访问由
Intrinsics统一派发到底层注册表,因此解释与编译模式共享同一套行为与错误类型(如IndexAccessError)。
导出桥
ExportRegistry扫描@Export方法并注册为扩展函数;底层通过ClassBridge(字节码生成)避免反射调用。- 编译后的脚本在调用处仍会走相同的派发链路:
Intrinsics.callFunction(...)Environment#getExtensionFunction(...)Function#call(...)
- 因此只要注册表一致,行为就应与解释器一致。
何时选用编译模式
- 脚本会被频繁执行,且你希望减少解释器开销。
- 你需要把脚本”打包”为库(配合
LibraryLoader等机制)。 - 你希望拿到可审计的
.class产物用于诊断(配合CompileResult#dump)。
调优建议
- 生成调试:在编译产物中打印
getClass().getName(),确认字节码是否加载到预期的 ClassLoader。 - 索引冲突:如遇
IndexAccessor顺序问题,记得调用registerAccessor将自定义实现插入列表开头。 - 导出同步:任何新的
@Export类都必须在运行时通过ExportRegistry#registerClass注册,并在需要时重建Environment, 确保缓存与派发表可见。