From b838f6383ff38a07ab682a4839e5e3e4835febeb Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 15 Jun 2026 08:39:59 +0300 Subject: [PATCH] =?UTF-8?q?refactor(ffi-linkage):=20Phase=209.1a=20?= =?UTF-8?q?=E2=80=94=20rename=20collision-free=20linkage=20identifiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical src/ rename of the linkage-family identifiers whose extern_* target is collision-free: callForeign→callExtern, marshalForeignArg→marshalExternArg, dedupeForeignSymbol→dedupeExternSymbol, foreign_name_map→extern_name_map, is_foreign_c_api→is_extern_c_api. Snapshot-neutral (internal only); suite green (646 corpus / 444 unit, 0 failed). Deferred (need per-site analysis — target name already exists): is_foreign↔is_extern (38 existing), foreign_lib/foreign_name↔extern_lib/extern_name (15/16 existing), foreign_expr (still built by c_import.zig auto-synthesis). Runtime-class family (ForeignClassDecl etc. → Runtime*, Decision 5) is Phase 9.2. --- src/backend/llvm/abi.zig | 6 +++--- src/ir/emit_llvm.zig | 4 ++-- src/ir/interp.zig | 8 ++++---- src/ir/lower.zig | 8 ++++---- src/ir/lower/call.zig | 4 ++-- src/ir/lower/closure.zig | 4 ++-- src/ir/lower/decl.zig | 14 +++++++------- src/ir/lower/protocol.zig | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/backend/llvm/abi.zig b/src/backend/llvm/abi.zig index 8e8c6f7..71dc09e 100644 --- a/src/backend/llvm/abi.zig +++ b/src/backend/llvm/abi.zig @@ -26,7 +26,7 @@ pub const AbiLowering = struct { } /// Same as `abiCoerceParamType` but with an explicit - /// `is_foreign_c_api` knob. When true, sx `string` / `[]T` slices + /// `is_extern_c_api` knob. When true, sx `string` / `[]T` slices /// collapse to `ptr` — the libc convention where the user writes /// `string` to mean `char *` and the length is dropped. When /// false (sx-internal `callconv(.c)` like block trampolines), the @@ -37,8 +37,8 @@ pub const AbiLowering = struct { /// `(*Block, string) -> void callconv(.c)` fn-pointer mismatched /// the caller's `{ptr, i64}` value against the trampoline's /// collapsed `ptr` param. - pub fn abiCoerceParamTypeEx(self: AbiLowering, ir_ty: TypeId, llvm_ty: c.LLVMTypeRef, is_foreign_c_api: bool) c.LLVMTypeRef { - if (is_foreign_c_api) { + pub fn abiCoerceParamTypeEx(self: AbiLowering, ir_ty: TypeId, llvm_ty: c.LLVMTypeRef, is_extern_c_api: bool) c.LLVMTypeRef { + if (is_extern_c_api) { if (ir_ty == .string) return self.e.cached_ptr; if (!ir_ty.isBuiltin()) { const info = self.e.ir_mod.types.get(ir_ty); diff --git a/src/ir/emit_llvm.zig b/src/ir/emit_llvm.zig index 7cff02d..5acf8c6 100644 --- a/src/ir/emit_llvm.zig +++ b/src/ir/emit_llvm.zig @@ -2528,8 +2528,8 @@ pub const LLVMEmitter = struct { return self.abiLowering().abiCoerceParamType(ir_ty, llvm_ty); } - fn abiCoerceParamTypeEx(self: *LLVMEmitter, ir_ty: TypeId, llvm_ty: c.LLVMTypeRef, is_foreign_c_api: bool) c.LLVMTypeRef { - return self.abiLowering().abiCoerceParamTypeEx(ir_ty, llvm_ty, is_foreign_c_api); + fn abiCoerceParamTypeEx(self: *LLVMEmitter, ir_ty: TypeId, llvm_ty: c.LLVMTypeRef, is_extern_c_api: bool) c.LLVMTypeRef { + return self.abiLowering().abiCoerceParamTypeEx(ir_ty, llvm_ty, is_extern_c_api); } pub fn needsByval(self: *LLVMEmitter, ir_ty: TypeId, raw_llvm_ty: c.LLVMTypeRef) bool { diff --git a/src/ir/interp.zig b/src/ir/interp.zig index bf060a7..6aea99a 100644 --- a/src/ir/interp.zig +++ b/src/ir/interp.zig @@ -405,7 +405,7 @@ pub const Interpreter = struct { /// underlying address. The returned `usize` is only valid for the /// duration of this call — caller-allocated buffers are tracked in /// `tmp` so they get freed once the call returns. - fn marshalForeignArg(self: *Interpreter, v: Value, tmp: *std.ArrayList([]u8)) !usize { + fn marshalExternArg(self: *Interpreter, v: Value, tmp: *std.ArrayList([]u8)) !usize { return switch (v) { .int => |i| @bitCast(i), .boolean => |b| @intFromBool(b), @@ -488,7 +488,7 @@ pub const Interpreter = struct { } } - fn callForeign(self: *Interpreter, func: *const inst_mod.Function, args: []const Value) InterpError!Value { + fn callExtern(self: *Interpreter, func: *const inst_mod.Function, args: []const Value) InterpError!Value { const name = self.module.types.getString(func.name); // A foreign call may not return (e.g. `process.exit` → `_exit`), which @@ -513,7 +513,7 @@ pub const Interpreter = struct { tmp.deinit(self.alloc); } for (args, 0..) |a, i| { - packed_args[i] = self.marshalForeignArg(a, &tmp) catch return error.TypeError; + packed_args[i] = self.marshalExternArg(a, &tmp) catch return error.TypeError; } const argv = packed_args[0..args.len]; @@ -569,7 +569,7 @@ pub const Interpreter = struct { // Dispatch to host libc via dlsym. Lets `#run` (and the // post-link bundler) call ordinary foreign symbols like // `puts`, `getenv`, `posix_spawn`, etc. - return self.callForeign(func, args); + return self.callExtern(func, args); } // Track the sx call chain for `trace.print_interpreter_frames()`. diff --git a/src/ir/lower.zig b/src/ir/lower.zig index c07db13..3c47556 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -364,7 +364,7 @@ pub const Lowering = struct { /// Null / absent for the comptime `..$args` pack (no constraint). pack_constraint: ?std.StringHashMap([]const u8) = null, struct_const_map: std.StringHashMap(StructConstInfo), // "Struct.CONST" → value info - foreign_name_map: std.StringHashMap([]const u8), // sx name → C name for #foreign renames + extern_name_map: std.StringHashMap([]const u8), // sx name → C name for #foreign renames target_config: ?@import("../target.zig").TargetConfig = null, // compilation target (for inline if) comptime_constants: std.StringHashMap(ComptimeValue), // compile-time known constants (e.g. OS, ARCH) diagnostics: ?*errors.DiagnosticList = null, // error reporting with source locations @@ -524,7 +524,7 @@ pub const Lowering = struct { .param_impl_map = std.StringHashMap(std.ArrayList(ParamImplEntry)).init(module.alloc), .param_impl_pack_map = std.StringHashMap(std.ArrayList(PackParamImplEntry)).init(module.alloc), .struct_const_map = std.StringHashMap(StructConstInfo).init(module.alloc), - .foreign_name_map = std.StringHashMap([]const u8).init(module.alloc), + .extern_name_map = std.StringHashMap([]const u8).init(module.alloc), .comptime_constants = std.StringHashMap(ComptimeValue).init(module.alloc), .xx_reentrancy = std.AutoHashMap(u64, void).init(module.alloc), .inferred_error_sets = std.StringHashMap([]const u32).init(module.alloc), @@ -1820,7 +1820,7 @@ pub const Lowering = struct { pub const lowerCall = lower_call.lowerCall; pub const diagnoseMissingContext = lower_call.diagnoseMissingContext; pub const allocViaContext = lower_call.allocViaContext; - pub const callForeign = lower_call.callForeign; + pub const callExtern = lower_call.callExtern; pub const prependCtxIfNeeded = lower_call.prependCtxIfNeeded; pub const resolveFuncByName = lower_call.resolveFuncByName; pub const resolveBuiltin = lower_call.resolveBuiltin; @@ -1920,7 +1920,7 @@ pub const Lowering = struct { pub const findTaggedVariant = lower_expr.findTaggedVariant; pub const emitBadVariant = lower_expr.emitBadVariant; pub const emitBadEnumVariant = lower_expr.emitBadEnumVariant; - pub const dedupeForeignSymbol = lower_decl.dedupeForeignSymbol; + pub const dedupeExternSymbol = lower_decl.dedupeExternSymbol; pub const resolveVariantValue = lower_expr.resolveVariantValue; pub const resolveVariantIndex = lower_expr.resolveVariantIndex; pub const lowerArrayLiteral = lower_expr.lowerArrayLiteral; diff --git a/src/ir/lower/call.zig b/src/ir/lower/call.zig index cc88ab7..ed2135b 100644 --- a/src/ir/lower/call.zig +++ b/src/ir/lower/call.zig @@ -1255,7 +1255,7 @@ pub fn allocViaContext(self: *Lowering, size_ref: Ref, void_ptr_ty: TypeId) Ref /// Used for the compiler-internal byte-copy in the protocol-erasure /// heap path and the closure env-copy path, both of which need /// libc `memcpy` after the `#builtin` form was dropped. -pub fn callForeign(self: *Lowering, name: []const u8, args: []const Ref, ret_ty: TypeId) Ref { +pub fn callExtern(self: *Lowering, name: []const u8, args: []const Ref, ret_ty: TypeId) Ref { const fid = self.resolveFuncByName(name) orelse @panic("foreign symbol missing — std.sx not imported?"); return self.builder.call(fid, args, ret_ty); } @@ -1286,7 +1286,7 @@ fn protocolHasMethod(proto_info: anytype, name: []const u8) bool { pub fn resolveFuncByName(self: *Lowering, name: []const u8) ?FuncId { // Check foreign name map first (e.g., "c_abs" → "abs") - const effective_name = self.foreign_name_map.get(name) orelse name; + const effective_name = self.extern_name_map.get(name) orelse name; const name_id = self.module.types.internString(effective_name); for (self.module.functions.items, 0..) |func, i| { if (func.name == name_id) return FuncId.fromIndex(@intCast(i)); diff --git a/src/ir/lower/closure.zig b/src/ir/lower/closure.zig index 54ea15e..e186948 100644 --- a/src/ir/lower/closure.zig +++ b/src/ir/lower/closure.zig @@ -216,7 +216,7 @@ pub fn lowerLambda(self: *Lowering, lam: *const ast.Lambda) Ref { const env_byte_size_inner = self.computeEnvSize(capture_list); const env_size_val = self.builder.constInt(@intCast(env_byte_size_inner), .i64); // memcpy(local_alloca, env_param, size) - _ = self.callForeign("memcpy", &.{ env_local, env_param_ref, env_size_val }, self.module.types.ptrTo(.void)); + _ = self.callExtern("memcpy", &.{ env_local, env_param_ref, env_size_val }, self.module.types.ptrTo(.void)); for (capture_list, 0..) |cap, i| { // GEP into env struct to get field pointer @@ -359,7 +359,7 @@ pub fn lowerLambda(self: *Lowering, lam: *const ast.Lambda) Ref { const ptr_void = self.module.types.ptrTo(.void); const env_heap = self.allocViaContext(env_size, ptr_void); // memcpy(heap, stack_alloca, size) - _ = self.callForeign("memcpy", &.{ env_heap, env_local, env_size }, ptr_void); + _ = self.callExtern("memcpy", &.{ env_heap, env_local, env_size }, ptr_void); return self.builder.closureCreate(func_id, env_heap, closure_ty); } else { diff --git a/src/ir/lower/decl.zig b/src/ir/lower/decl.zig index 109dcc2..1527988 100644 --- a/src/ir/lower/decl.zig +++ b/src/ir/lower/decl.zig @@ -2035,7 +2035,7 @@ fn returnGenericLeaf(node: *const Node) ?[]const u8 { /// the later declaration (a `-> string` view of a symbol registered `-> *u8` /// reads the wrong shape; issue 0128). True = handled (shared or diagnosed), /// caller must not declare again. -pub fn dedupeForeignSymbol(self: *Lowering, fd: *const ast.FnDecl, sym_name: StringId, params: []const Function.Param, ret_ty: TypeId) bool { +pub fn dedupeExternSymbol(self: *Lowering, fd: *const ast.FnDecl, sym_name: StringId, params: []const Function.Param, ret_ty: TypeId) bool { for (self.module.functions.items, 0..) |*func, i| { if (func.name != sym_name or !func.is_extern) continue; var same = func.ret == ret_ty and func.params.len == params.len; @@ -2142,8 +2142,8 @@ pub fn declareFunction(self: *Lowering, fd: *const ast.FnDecl, name: []const u8) null; if (rename_c_name) |c_name| { const c_name_id = self.module.types.internString(c_name); - if (self.dedupeForeignSymbol(fd, c_name_id, params.items, ret_ty)) { - self.foreign_name_map.put(name, c_name) catch {}; + if (self.dedupeExternSymbol(fd, c_name_id, params.items, ret_ty)) { + self.extern_name_map.put(name, c_name) catch {}; return; } const fid = self.builder.declareExtern(c_name_id, params.items, ret_ty); @@ -2152,13 +2152,13 @@ pub fn declareFunction(self: *Lowering, fd: *const ast.FnDecl, name: []const u8) func.source_file = self.current_source_file; func.is_variadic = is_variadic; func.has_implicit_ctx = wants_ctx; - self.foreign_name_map.put(name, c_name) catch {}; + self.extern_name_map.put(name, c_name) catch {}; self.fn_decl_fids.put(fd, fid) catch {}; return; } const name_id = self.module.types.internString(name); - if ((is_foreign or is_extern_decl) and self.dedupeForeignSymbol(fd, name_id, params.items, ret_ty)) return; + if ((is_foreign or is_extern_decl) and self.dedupeExternSymbol(fd, name_id, params.items, ret_ty)) return; const fid = self.builder.declareExtern(name_id, params.items, ret_ty); const func = self.module.getFunctionMut(fid); func.call_conv = cc; @@ -2355,10 +2355,10 @@ pub fn lazyLowerFunction(self: *Lowering, name: []const u8) void { // its OWN FuncId by `lowerRetainedSameNameAuthors`. // A renamed `export … "csym"` fn was declared under its C symbol name // (declareFunction's rename path), so search for the stub under that name - // and promote the body into it. `foreign_name_map` only carries an entry + // and promote the body into it. `extern_name_map` only carries an entry // when a rename was registered; a bare export / normal define keeps its sx // name (Phase 2.2). - const search_name = self.foreign_name_map.get(name) orelse name; + const search_name = self.extern_name_map.get(name) orelse name; const name_id = self.module.types.internString(search_name); var func_id: ?FuncId = null; for (self.module.functions.items, 0..) |func, i| { diff --git a/src/ir/lower/protocol.zig b/src/ir/lower/protocol.zig index 759e596..4dd6c2f 100644 --- a/src/ir/lower/protocol.zig +++ b/src/ir/lower/protocol.zig @@ -443,7 +443,7 @@ pub fn buildProtocolValue(self: *Lowering, concrete_ptr: Ref, proto_name: []cons const concrete_size = self.module.types.typeSizeBytes(concrete_ty); const size_ref = self.builder.constInt(@intCast(concrete_size), .i64); const heap_ptr = self.allocViaContext(size_ref, void_ptr_ty); - _ = self.callForeign("memcpy", &.{ heap_ptr, concrete_ptr, size_ref }, void_ptr_ty); + _ = self.callExtern("memcpy", &.{ heap_ptr, concrete_ptr, size_ref }, void_ptr_ty); ctx_ptr = heap_ptr; }