comptime VM arc: abi(.compiler) ABI, out as sx fn, VM-native diagnostics, BuildConfig threaded
Lands the full VM/compiler-API arc on branch reify (701/0 both gates): - abi(.compiler) ABI replaces abi(.zig) extern compiler + the fake #library "compiler"; bodiless decl = compiler-API surface, bodied = user compiler-domain fn (lowered for VM eval, emit-skipped). - out is a plain sx fn (libc write) — the out builtin deleted; the VM handles it via host-FFI. trace_resolve + interp_print_frames ported. - 4B VM-native diagnostics: 1179/1180 render proper comptime type construction failed: under strict. - S5a: build_options/set_post_link_callback on abi(.compiler) with BuildConfig threaded into the VM (green intermediate). - 0522 fixed (describe(args: []Type)); regression 0638. Strict deletion-gate down to 4 compiler_call bails (1609/1614/1615/1616) + 1654 (legitimate unresolvable-symbol diagnostic).
This commit is contained in:
@@ -1119,13 +1119,23 @@ pub const Ops = struct {
|
||||
// wrapper, `is_comptime`) is fine — that body is interp-evaluated and its
|
||||
// LLVM emission is dead, so skip the gate there.
|
||||
const enclosing = &self.e.ir_mod.functions.items[self.e.current_func_idx];
|
||||
if (callee_func.compiler_welded and !enclosing.is_comptime) {
|
||||
if ((callee_func.compiler_welded or callee_func.is_compiler_domain) and !enclosing.is_comptime) {
|
||||
const fname = self.e.ir_mod.types.getString(callee_func.name);
|
||||
std.debug.print("error: '{s}' is a comptime-only compiler-library function — it cannot be called at runtime (use it inside #run or a comptime '::')\n", .{fname});
|
||||
std.debug.print("error: '{s}' is a comptime-only compiler-domain function — it cannot be called at runtime (use it inside #run or a comptime '::')\n", .{fname});
|
||||
self.e.comptime_failed = true;
|
||||
self.e.mapRef(c.LLVMGetUndef(self.e.toLLVMType(instruction.ty)));
|
||||
return;
|
||||
}
|
||||
// A comptime-only callee (compiler-API or compiler-domain) reached here from
|
||||
// a COMPTIME (dead) body — the enclosing `#run`/`::` wrapper whose LLVM is
|
||||
// never executed. Such a function has no runtime symbol, so emit `undef`
|
||||
// instead of a real `call` (which would leave an undefined reference for the
|
||||
// AOT linker). The comptime VALUE is produced by the interp/VM, not this dead
|
||||
// body. Mirrors the old `compiler_call` → undef.
|
||||
if (callee_func.compiler_welded or callee_func.is_compiler_domain) {
|
||||
self.e.mapRef(c.LLVMGetUndef(self.e.toLLVMType(instruction.ty)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (callee_func.is_comptime and call_op.args.len == 0) {
|
||||
var interp_inst = Interpreter.init(self.e.ir_mod, self.e.alloc);
|
||||
@@ -1377,25 +1387,6 @@ pub const Ops = struct {
|
||||
self.e.mapRef(c.LLVMBuildCall2(self.e.builder, self.e.getMathF64Type(), f, &args, 1, @tagName(bi.builtin)));
|
||||
}
|
||||
},
|
||||
.out => {
|
||||
// out(str): extract ptr and len from string fat pointer, call write(1, ptr, len)
|
||||
const str_val = self.e.resolveRef(bi.args[0]);
|
||||
const raw_ptr = c.LLVMBuildExtractValue(self.e.builder, str_val, 0, "str.ptr");
|
||||
const str_len = c.LLVMBuildExtractValue(self.e.builder, str_val, 1, "str.len");
|
||||
// On wasm32, count param is i32 (size_t)
|
||||
const count = if (self.e.target_config.isWasm32())
|
||||
c.LLVMBuildTrunc(self.e.builder, str_len, self.e.cached_i32, "len.tr")
|
||||
else
|
||||
str_len;
|
||||
const write_fn = self.e.getOrDeclareWrite();
|
||||
var write_args = [_]c.LLVMValueRef{
|
||||
c.LLVMConstInt(self.e.cached_i32, 1, 0), // fd = stdout
|
||||
raw_ptr,
|
||||
count,
|
||||
};
|
||||
_ = c.LLVMBuildCall2(self.e.builder, self.e.getWriteType(), write_fn, &write_args, 3, "");
|
||||
self.e.advanceRefCounter();
|
||||
},
|
||||
.type_name => {
|
||||
// Dynamic `type_name(t)` at runtime: resolve the TypeId
|
||||
// the arg denotes (reading an `Any`'s runtime type-tag,
|
||||
|
||||
Reference in New Issue
Block a user