compiler-API: welded structs by reflection + memory-order validation
Replace the explored byte-layout-override engine (offset-ordered LLVM structs /
weld plans / byte-blobs — all unnecessary) with a much simpler design: a welded
`struct abi(.zig) extern compiler { … }` is a bodied header declaring its fields
in the bound compiler type's MEMORY order. The compiler reflects the real Zig
type (field names via @typeInfo, offsets via @offsetOf, size via @sizeOf —
nothing hand-maintained) and validates the header matches, with loud diagnostics.
On pass it is an ordinary struct whose natural layout already equals the Zig
layout — no reorder, no padding, no index/remap tables, no special LLVM path — so
@ptrCast'ing it to the compiler's own type and dereferencing is byte-identical.
When types.zig shifts, the header stops matching and the developer gets a specific
message to fix it.
- compiler_lib.zig: weldStruct reflects field names and bakes bound_types fields
in ascending-offset (memory) order; deleted computeWeldPlan/WeldPlan/WeldElement.
- nominal.zig validateWeldedStruct: precise diagnostics — field-not-found,
wrong-field-order (+ expected memory order), type-layout (size) mismatch,
total-size mismatch.
- Examples: 0627 (StructInfo in memory order, byte-identical, usable),
1186 (source-order StructInfo -> wrong-field-order diagnostic); 1183 refreshed.
- Design doc + checkpoint updated.
This commit is contained in:
30
examples/0627-comptime-weld-struct-reflected-layout.sx
Normal file
30
examples/0627-comptime-weld-struct-reflected-layout.sx
Normal file
@@ -0,0 +1,30 @@
|
||||
// Comptime compiler API — a welded struct mirrors the compiler's real Zig type
|
||||
// byte-for-byte by declaring its fields in the compiler type's MEMORY order.
|
||||
//
|
||||
// `StructInfo` is the real `types.TypeInfo.StructInfo`, which Zig reorders from
|
||||
// source order to (fields, name, nominal_id, is_protocol). The sx header declares
|
||||
// the fields in that memory order; the compiler reflects the bound Zig type
|
||||
// (@offsetOf/@sizeOf) and validates the header matches — so the struct is laid
|
||||
// out identically and a pointer to it can be cast to the compiler's own type and
|
||||
// dereferenced. Nothing is maintained by hand: a types.zig change re-reflects.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
compiler :: #library "compiler";
|
||||
|
||||
Field :: struct abi(.zig) extern compiler { name: u32; ty: u32; }
|
||||
|
||||
StructInfo :: struct abi(.zig) extern compiler {
|
||||
fields: []Field;
|
||||
name: u32;
|
||||
nominal_id: u32;
|
||||
is_protocol: bool;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
si : StructInfo = ---;
|
||||
si.name = 42;
|
||||
si.nominal_id = 7;
|
||||
si.is_protocol = true;
|
||||
print("name={} nominal={} proto={}\n", si.name, si.nominal_id, si.is_protocol);
|
||||
}
|
||||
20
examples/1186-diagnostics-weld-struct-wrong-order.sx
Normal file
20
examples/1186-diagnostics-weld-struct-wrong-order.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
// Diagnostic: a welded struct whose fields are NOT in the compiler type's memory
|
||||
// order is a loud build error — the sx header must mirror the real Zig layout so
|
||||
// the two are byte-identical. The message names the offending position and shows
|
||||
// the expected memory order. (Declaring StructInfo in source order trips this:
|
||||
// Zig reorders it to fields-first.)
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
compiler :: #library "compiler";
|
||||
|
||||
Field :: struct abi(.zig) extern compiler { name: u32; ty: u32; }
|
||||
|
||||
StructInfo :: struct abi(.zig) extern compiler {
|
||||
name: u32;
|
||||
fields: []Field;
|
||||
is_protocol: bool;
|
||||
nominal_id: u32;
|
||||
}
|
||||
|
||||
main :: () { print("unreached\n"); }
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
name=42 nominal=7 proto=true
|
||||
@@ -1,4 +1,4 @@
|
||||
error: welded type 'Field' has 2 field(s) in the compiler library but the declaration has 1
|
||||
error: welded type 'Field': the compiler type has 2 field(s) but the declaration has 1 — declare them in memory order: name, ty
|
||||
--> examples/1183-diagnostics-weld-struct-field-count.sx:12:51
|
||||
|
|
||||
12 | Field :: struct abi(.zig) extern compiler { name: u32; }
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: welded type 'StructInfo': wrong field order at position 0 — found 'name', the compiler type has 'fields' here (memory order: fields, name, nominal_id, is_protocol)
|
||||
--> examples/1186-diagnostics-weld-struct-wrong-order.sx:14:11
|
||||
|
|
||||
14 | name: u32;
|
||||
| ^^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user