P5.3: on_build(cb) build-callback registrar; callback takes BuildOptions
Per user design: on_build(build) is the build-callback registrar (a free fn), generalizing set_post_link_callback — the callback is (opt: BuildOptions) -> bool and the compiler invokes it post-codegen WITH the BuildOptions handle. - VM: callCompilerFn 'on_build' arm + legacy handleOnBuild, both set post_link_callback_fn + a new BuildConfig.post_link_takes_options flag. - comptime_vm: runEntry refactored to runEntryArgs(extra) (implicit ctx + explicit args); new public runBuildCallback(..., pass_options) passes the opaque BuildOptions handle (one word) after the ctx. The fat-config marshaling fear is moot — the handle is a single null-sentinel word. - core.invokeByFuncId/invokeByName take pass_options (was an unused args slice); main.zig passes comp.getPostLinkTakesOptions(). - build.sx: on_build decl (set_post_link_callback kept for now). Smoke test examples/1664-platform-on-build-callback (AOT): #run on_build(build) with build :: (opt: BuildOptions) -> bool; the callback is invoked with the handle arg (runEntryArgs param-count match) and runs the primitives. Benign .ir churn (37 snapshots: type table +1 for the on_build fn type + global renumber; behavior identical). 705/0 both gates.
This commit is contained in:
33
src/core.zig
33
src/core.zig
@@ -188,7 +188,7 @@ pub const Compilation = struct {
|
||||
/// if applicable) to invoke a named sx function. Used for the post-link
|
||||
/// bundling callback. Returns the function's return value, or null if the
|
||||
/// name doesn't resolve to a function in the lowered module.
|
||||
pub fn invokeByName(self: *Compilation, name: []const u8, args: []const ir.Value) !?ir.Value {
|
||||
pub fn invokeByName(self: *Compilation, name: []const u8, pass_options: bool) !?ir.Value {
|
||||
const mod = self.ir_module orelse return null;
|
||||
var found_id: ?ir.FuncId = null;
|
||||
for (mod.functions.items, 0..) |func, i| {
|
||||
@@ -199,14 +199,15 @@ pub const Compilation = struct {
|
||||
}
|
||||
}
|
||||
const fid = found_id orelse return null;
|
||||
return try self.invokeByFuncId(fid, args);
|
||||
return try self.invokeByFuncId(fid, pass_options);
|
||||
}
|
||||
|
||||
/// Re-enter the IR interpreter and call a previously-resolved function
|
||||
/// id. Companion to `invokeByName` — used when the FuncId was captured
|
||||
/// at `#run` time (e.g. by `set_post_link_callback`) and we want to
|
||||
/// invoke it later without name lookup.
|
||||
pub fn invokeByFuncId(self: *Compilation, id: ir.FuncId, args: []const ir.Value) !ir.Value {
|
||||
/// Re-enter the evaluator and call a previously-resolved function id. The
|
||||
/// post-link build callback, captured at `#run` time (by `on_build` /
|
||||
/// `set_post_link_callback`). `pass_options` passes the opaque `BuildOptions`
|
||||
/// handle as the callback's arg (the `on_build(cb)` form, `cb: (opt:
|
||||
/// BuildOptions) -> bool`); false for the legacy no-arg form.
|
||||
pub fn invokeByFuncId(self: *Compilation, id: ir.FuncId, pass_options: bool) !ir.Value {
|
||||
const mod = self.ir_module orelse return error.NoIRModule;
|
||||
// The build driver (post-link callback) runs on the comptime VM — NOT
|
||||
// the legacy interp. The driver allocates Lists, which the legacy interp
|
||||
@@ -215,13 +216,8 @@ pub const Compilation = struct {
|
||||
// callback can't safely re-run on a second evaluator (double execution),
|
||||
// so a VM bail is a hard build error. The bail reason is in
|
||||
// `comptime_vm.last_bail_reason` (surfaced by `main.printInterpBailDiag`).
|
||||
// Post-link callbacks are nullary today (the implicit `*Context` is
|
||||
// materialized by the VM's `runEntry`); a non-empty `args` would need a
|
||||
// VM entry that marshals them, which arrives with the `on_build(config)`
|
||||
// slot (Phase 5.3) — reject it loudly rather than silently drop.
|
||||
if (args.len != 0) return error.ComptimeVmArgsUnsupported;
|
||||
const build_config = if (self.ir_emitter) |*e| &e.build_config else null;
|
||||
return ir.comptime_vm.tryEval(self.allocator, mod, id, build_config, &self.import_sources) orelse
|
||||
return ir.comptime_vm.runBuildCallback(self.allocator, mod, id, build_config, &self.import_sources, pass_options) orelse
|
||||
error.ComptimeVmBail;
|
||||
}
|
||||
|
||||
@@ -249,13 +245,20 @@ pub const Compilation = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get the post-link callback function id (set via
|
||||
/// `BuildOptions.set_post_link_callback(fn)`), if any.
|
||||
/// Get the post-link callback function id (set via `on_build(fn)` or the
|
||||
/// legacy `set_post_link_callback(fn)`), if any.
|
||||
pub fn getPostLinkCallback(self: *Compilation) ?ir.FuncId {
|
||||
if (self.ir_emitter) |*e| return e.build_config.post_link_callback_fn;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Whether the post-link callback takes the `BuildOptions` handle arg (the
|
||||
/// `on_build(cb)` form). Drives the `pass_options` flag at invocation.
|
||||
pub fn getPostLinkTakesOptions(self: *Compilation) bool {
|
||||
if (self.ir_emitter) |*e| return e.build_config.post_link_takes_options;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Get the post-link module name (set via
|
||||
/// `BuildOptions.set_post_link_module("name")`), if any.
|
||||
pub fn getPostLinkModule(self: *Compilation) ?[]const u8 {
|
||||
|
||||
Reference in New Issue
Block a user