refactor(ir): move declaration maps into ProgramIndex (A1.1b)
Architecture phase A1.1b — mechanical storage relocation. Move the 9
declaration-fact maps out of the Lowering state bag into ProgramIndex:
high-fanout: fn_ast_map, foreign_class_map, global_names, type_alias_map
medium-fanout: struct_template_map, protocol_decl_map, protocol_ast_map,
module_const_map, ufcs_alias_map
168 self.<map> sites in lower.zig repointed to self.program_index.<map>;
external readers repointed too (core.zig foreign_class_map iteration;
lower.test.zig fn_ast_map / foreign_class_map). No duplicate storage, no
fallback path; zig build enforces no missed reference.
The four maps whose value types were Lowering-private pull those types into
program_index.zig as pub (GlobalInfo, StructTemplate + TemplateParam,
ProtocolDeclInfo + ProtocolMethodInfo, ModuleConstInfo); lower.zig aliases
them at file scope so call sites are unchanged.
Behavior is preserved exactly:
- per-map allocator unchanged — import_flags/fn_ast_map/global_names use the
lowering allocator (ProgramIndex.init), the other 7 keep their page_allocator
inline defaults;
- ProgramIndex.deinit frees only the 10 owned maps, never the borrowed
module_scopes / import_graph;
- TypeTable.aliases still borrows &self.program_index.type_alias_map, loaned at
lowerRoot with the same late-binding lifetime.
Extends program_index.test.zig with declaration-map round-trips (fn AST, type
alias, global, module const, foreign class, protocol decl/AST, struct template,
ufcs alias).
Registration logic (registerStructDecl / registerProtocolDecl /
registerForeignClassDecl, ...) stays in Lowering, writing through the index.
Gate green: zig build, zig build test, bash tests/run_examples.sh
(350 passed, 0 failed). lower.zig 19433 -> 19393 lines.
This commit is contained in:
@@ -1,36 +1,111 @@
|
||||
const std = @import("std");
|
||||
const ast = @import("../ast.zig");
|
||||
const types = @import("types.zig");
|
||||
const inst = @import("inst.zig");
|
||||
|
||||
/// Single storage owner for declaration-name facts: declarations, imports,
|
||||
/// visibility, names, aliases, templates, protocols, foreign classes, and
|
||||
/// module constants. The architecture stream (`current/PLAN-ARCH.md`, phase
|
||||
/// A1) extracts these out of the `Lowering` state bag incrementally; this is
|
||||
/// the A1.1a slice — the low-fanout import/visibility facts. `Lowering` embeds
|
||||
/// one `ProgramIndex` by value and reaches every moved fact through it; later
|
||||
/// phases hand collaborator modules a `*ProgramIndex` instead of `*Lowering`.
|
||||
const Node = ast.Node;
|
||||
const TypeId = types.TypeId;
|
||||
|
||||
/// Owned copy of a generic struct template (AST pointers are copied/interned to survive imports)
|
||||
pub const StructTemplate = struct {
|
||||
name: []const u8,
|
||||
type_params: []const TemplateParam,
|
||||
field_names: []const []const u8,
|
||||
field_type_nodes: []const *const Node, // raw AST pointers — must be copied from heap nodes
|
||||
};
|
||||
pub const TemplateParam = struct {
|
||||
name: []const u8,
|
||||
is_type_param: bool, // true for $T: Type, false for $N: u32
|
||||
is_variadic: bool = false, // `..$Ts: []Type` — binds remaining type args as a pack
|
||||
};
|
||||
|
||||
pub const ProtocolMethodInfo = struct {
|
||||
name: []const u8,
|
||||
param_types: []const TypeId, // excluding self
|
||||
ret_type: TypeId,
|
||||
// True when the AST return type was `Self` (encoded here as *void).
|
||||
// Lets the dispatcher distinguish Self-disguised-as-*void (auto-unbox
|
||||
// on the caller side) from a literal `-> *void` (return as-is).
|
||||
ret_is_self: bool = false,
|
||||
};
|
||||
|
||||
pub const ProtocolDeclInfo = struct {
|
||||
name: []const u8,
|
||||
is_inline: bool,
|
||||
methods: []const ProtocolMethodInfo,
|
||||
};
|
||||
|
||||
pub const ModuleConstInfo = struct {
|
||||
value: *const Node,
|
||||
ty: TypeId,
|
||||
};
|
||||
|
||||
pub const GlobalInfo = struct { id: inst.GlobalId, ty: TypeId };
|
||||
|
||||
/// Single lowering access point for declaration-name / import / visibility
|
||||
/// facts. The architecture stream (`current/PLAN-ARCH.md`, phase A1) extracts
|
||||
/// these out of the `Lowering` state bag incrementally. `Lowering` embeds one
|
||||
/// `ProgramIndex` by value and reaches every moved fact through
|
||||
/// `self.program_index.<field>`; later phases hand collaborator modules a
|
||||
/// `*ProgramIndex` instead of `*Lowering`.
|
||||
///
|
||||
/// `import_flags` is owned here. `module_scopes` / `import_graph` are borrowed
|
||||
/// views into maps owned by the compilation driver (`core.zig`); this index
|
||||
/// only reads through them.
|
||||
/// OWNS the declaration maps below. BORROWS `module_scopes` / `import_graph`
|
||||
/// (pointers into maps owned by the compilation driver, `core.zig`) — those
|
||||
/// are read-only views and are never freed here.
|
||||
///
|
||||
/// Per-map allocators are preserved exactly as they were on `Lowering`:
|
||||
/// `import_flags` / `fn_ast_map` / `global_names` use the lowering allocator
|
||||
/// (set in `init`); the rest default to `page_allocator`. Written only by the
|
||||
/// declaration scan / registration code in `Lowering`; read everywhere else.
|
||||
pub const ProgramIndex = struct {
|
||||
// ── Import / visibility ──
|
||||
/// Declaration name → is the function imported (declared `extern`)?
|
||||
/// Populated by the declaration scan / registration code in `Lowering`.
|
||||
import_flags: std.StringHashMap(bool),
|
||||
|
||||
/// Per-module visible names, keyed by source file (from import
|
||||
/// resolution). Borrowed — the backing map lives in the compilation
|
||||
/// driver, so this index does not free it.
|
||||
/// Per-module visible names, keyed by source file. Borrowed view.
|
||||
module_scopes: ?*std.StringHashMap(std.StringHashMap(void)) = null,
|
||||
|
||||
/// Module path → set of directly imported paths; drives the
|
||||
/// `param_impl_map` cross-module visibility filter. Borrowed — owned by
|
||||
/// the compilation driver.
|
||||
/// Module path → set of directly imported paths (param_impl visibility
|
||||
/// filter). Borrowed view.
|
||||
import_graph: ?*std.StringHashMap(std.StringHashMap(void)) = null,
|
||||
|
||||
// ── Declaration maps ──
|
||||
/// Function name → AST decl.
|
||||
fn_ast_map: std.StringHashMap(*const ast.FnDecl),
|
||||
/// sx alias → ForeignClassDecl (jni_class / objc_class / swift_class / ... — registered in scan pass).
|
||||
foreign_class_map: std.StringHashMap(*const ast.ForeignClassDecl) = std.StringHashMap(*const ast.ForeignClassDecl).init(std.heap.page_allocator),
|
||||
/// `#run` global name → GlobalId.
|
||||
global_names: std.StringHashMap(GlobalInfo),
|
||||
/// Type alias name → target TypeId. Loaned to `TypeTable.aliases`.
|
||||
type_alias_map: std.StringHashMap(TypeId) = std.StringHashMap(TypeId).init(std.heap.page_allocator),
|
||||
/// Generic struct name → template.
|
||||
struct_template_map: std.StringHashMap(StructTemplate) = std.StringHashMap(StructTemplate).init(std.heap.page_allocator),
|
||||
/// Protocol name → protocol info.
|
||||
protocol_decl_map: std.StringHashMap(ProtocolDeclInfo) = std.StringHashMap(ProtocolDeclInfo).init(std.heap.page_allocator),
|
||||
/// Protocol name → AST node.
|
||||
protocol_ast_map: std.StringHashMap(*const ast.ProtocolDecl) = std.StringHashMap(*const ast.ProtocolDecl).init(std.heap.page_allocator),
|
||||
/// Module-level value constants (e.g. AF_INET :s32: 2).
|
||||
module_const_map: std.StringHashMap(ModuleConstInfo) = std.StringHashMap(ModuleConstInfo).init(std.heap.page_allocator),
|
||||
/// UFCS alias name → target function name.
|
||||
ufcs_alias_map: std.StringHashMap([]const u8) = std.StringHashMap([]const u8).init(std.heap.page_allocator),
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator) ProgramIndex {
|
||||
return .{ .import_flags = std.StringHashMap(bool).init(alloc) };
|
||||
return .{
|
||||
.import_flags = std.StringHashMap(bool).init(alloc),
|
||||
.fn_ast_map = std.StringHashMap(*const ast.FnDecl).init(alloc),
|
||||
.global_names = std.StringHashMap(GlobalInfo).init(alloc),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *ProgramIndex) void {
|
||||
// Owned maps only — module_scopes / import_graph are borrowed.
|
||||
self.import_flags.deinit();
|
||||
self.fn_ast_map.deinit();
|
||||
self.foreign_class_map.deinit();
|
||||
self.global_names.deinit();
|
||||
self.type_alias_map.deinit();
|
||||
self.struct_template_map.deinit();
|
||||
self.protocol_decl_map.deinit();
|
||||
self.protocol_ast_map.deinit();
|
||||
self.module_const_map.deinit();
|
||||
self.ufcs_alias_map.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user