P5.7 Step C1: evaluate #insert on the comptime VM (sole evaluator)
evalComptimeString (the #insert lowering-time site) was the last user of the legacy Interpreter.call. Route it through comptime_vm.tryEval instead: the VM is hardened to bail (never panic) on malformed lowering-time IR (0737's ret Ref.none), and regToValue dupes the result string into the lowering allocator so it outlives the VM arena. Drop the now-unused interp_mod / build_opts imports from comptime.zig. 500/500 unit + 706/0 corpus.
This commit is contained in:
@@ -6,9 +6,7 @@ const types = @import("../types.zig");
|
|||||||
const inst_mod = @import("../inst.zig");
|
const inst_mod = @import("../inst.zig");
|
||||||
const unescape = @import("../../unescape.zig");
|
const unescape = @import("../../unescape.zig");
|
||||||
const parser_mod = @import("../../parser.zig");
|
const parser_mod = @import("../../parser.zig");
|
||||||
const interp_mod = @import("../interp.zig");
|
|
||||||
const comptime_vm = @import("../comptime_vm.zig");
|
const comptime_vm = @import("../comptime_vm.zig");
|
||||||
const build_opts = @import("build_opts");
|
|
||||||
const program_index_mod = @import("../program_index.zig");
|
const program_index_mod = @import("../program_index.zig");
|
||||||
const resolver_mod = @import("../resolver.zig");
|
const resolver_mod = @import("../resolver.zig");
|
||||||
const ModuleConstInfo = program_index_mod.ModuleConstInfo;
|
const ModuleConstInfo = program_index_mod.ModuleConstInfo;
|
||||||
@@ -588,34 +586,24 @@ pub fn evalComptimeString(self: *Lowering, expr: *const Node) ?[:0]const u8 {
|
|||||||
return self.alloc.dupeZ(u8, str) catch null;
|
return self.alloc.dupeZ(u8, str) catch null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 2: Evaluate via IR interpreter, reusing the parent module.
|
// Case 2: evaluate on the comptime VM (the SOLE evaluator — P5.7), reusing
|
||||||
// The parent's `scanDecls` pass has already registered every
|
// the parent module. The parent's `scanDecls` pass has already registered
|
||||||
// type / protocol / impl / thunk the comptime call may need
|
// every type / protocol / impl / thunk the comptime call may need
|
||||||
// (Allocator, CAllocator, Context, the per-impl thunks). A
|
// (Allocator, CAllocator, Context, the per-impl thunks); a fresh empty
|
||||||
// fresh empty module would only lazy-lower function ASTs and
|
// module would miss those and break `context.allocator.X`.
|
||||||
// would miss the type/protocol registrations, which would break
|
//
|
||||||
// `context.allocator.X` — the protocol dispatch chain needs
|
// Lowering-time IR can be malformed (e.g. a `ret Ref.none` left by an
|
||||||
// those types to resolve struct field layout and the alloc/
|
// unresolved name — see `0737`); the VM is hardened to BAIL (never panic) on
|
||||||
// dealloc thunks at the bottom of the dispatch.
|
// it, so `tryEval` yields null and we return null. The real user diagnostic
|
||||||
|
// (the visibility error, …) was already emitted while lowering the inserted
|
||||||
|
// expression. `regToValue` dupes the result string into `self.alloc`, so it
|
||||||
|
// outlives the VM's arena.
|
||||||
const ct_func_id = self.createComptimeFunction("__insert", expr, .string);
|
const ct_func_id = self.createComptimeFunction("__insert", expr, .string);
|
||||||
|
const result = comptime_vm.tryEval(self.alloc, self.module, ct_func_id, null, null) orelse return null;
|
||||||
// NOTE: the comptime VM is intentionally NOT wired at this LOWERING-time
|
const str = switch (result) {
|
||||||
// site. Unlike the emit-time const-init / `#run` folds (which run on fully
|
|
||||||
// lowered IR), lowering-time IR can be malformed (e.g. a `ret Ref.none` left by
|
|
||||||
// an unresolved name — see `0737`), and routing that through the VM is out of
|
|
||||||
// scope until the VM is fully hardened against arbitrary malformed IR. The
|
|
||||||
// emit-time sites already give the VM full corpus coverage.
|
|
||||||
var interp = interp_mod.Interpreter.init(self.module, self.alloc);
|
|
||||||
defer interp.deinit();
|
|
||||||
if (self.diagnostics) |d| if (d.import_sources) |sm| interp.setSourceMap(sm);
|
|
||||||
|
|
||||||
const result = interp.call(ct_func_id, &.{}) catch return null;
|
|
||||||
|
|
||||||
const str = result.asString(&interp) orelse switch (result) {
|
|
||||||
.string => |s| s,
|
.string => |s| s,
|
||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
return self.alloc.dupeZ(u8, str) catch null;
|
return self.alloc.dupeZ(u8, str) catch null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user