feat(C2): unit-first JIT symbol resolution — program-owned dylibs beat process images
runJITFromObject now takes priority dylibs (the #import c unit's linked objects first, then #library deps in declaration order) and attaches a per-path search generator for each AHEAD of the process-wide fallback, so a vendored symbol can never lose to a same-named export of an image the host process happens to carry (libz via LLVM, libsqlite3 via CoreServices). loadLibrary reports the name dlopen succeeded on; the c-import handle records its dylib path; temp link inputs are per-pid so concurrent runs can't clobber each other. Flips the C0.3 shadowing pin to from_unit: true.
This commit is contained in:
@@ -80,6 +80,9 @@ pub fn cSourceCacheKey(
|
||||
/// Handle returned from loadCObjectsForJIT — caller must call unload() after JIT.
|
||||
pub const CImportHandle = struct {
|
||||
dylib_handle: ?*anyopaque = null,
|
||||
/// Where the unit's linked dylib lives for THIS run; the JIT adds it
|
||||
/// as a priority symbol-search target ahead of the process images.
|
||||
dylib_path: ?[:0]const u8 = null,
|
||||
temp_paths: []const []const u8 = &.{},
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
@@ -415,10 +418,12 @@ pub fn loadCObjectsForJIT(
|
||||
|
||||
var temp_paths = std.ArrayList([]const u8).empty;
|
||||
|
||||
// Write each .o buffer to a temp file
|
||||
// Write each .o buffer to a temp file (per-pid names: concurrent
|
||||
// `sx run` processes must not clobber each other's link inputs)
|
||||
const pid = std.c.getpid();
|
||||
var obj_paths = std.ArrayList([]const u8).empty;
|
||||
for (obj_bufs, 0..) |buf, i| {
|
||||
const path = try std.fmt.allocPrint(allocator, "/tmp/sx_c_{d}.o", .{i});
|
||||
const path = try std.fmt.allocPrint(allocator, "/tmp/sx_c_{d}_{d}.o", .{ pid, i });
|
||||
const start = c.LLVMGetBufferStart(buf);
|
||||
const size = c.LLVMGetBufferSize(buf);
|
||||
const data = @as([*]const u8, @ptrCast(start))[0..size];
|
||||
@@ -432,8 +437,8 @@ pub fn loadCObjectsForJIT(
|
||||
}
|
||||
|
||||
// Link into a shared library
|
||||
const dylib_path = "/tmp/sx_c_import.dylib";
|
||||
try temp_paths.append(allocator, try allocator.dupe(u8, dylib_path));
|
||||
const dylib_path = try std.fmt.allocPrintSentinel(allocator, "/tmp/sx_c_import_{d}.dylib", .{pid}, 0);
|
||||
try temp_paths.append(allocator, dylib_path);
|
||||
|
||||
var argv = std.ArrayList([]const u8).empty;
|
||||
try argv.append(allocator, "cc");
|
||||
@@ -477,6 +482,7 @@ pub fn loadCObjectsForJIT(
|
||||
|
||||
return .{
|
||||
.dylib_handle = handle,
|
||||
.dylib_path = dylib_path,
|
||||
.temp_paths = try temp_paths.toOwnedSlice(allocator),
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user