| author | |
| committer | |
| log | 525f341f33af9b8aad53931fd5511f00a82cb090 |
| tree | cec3280498c1122858580946ac5e31f8feb807ce |
| parent | 8f20e81b8816aadd8ceb1b04bd3727cc1d124464 |
56 files changed, 11266 insertions(+), 9961 deletions(-)
CMakeLists.txt+1| ... | @@ -525,6 +525,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -525,6 +525,7 @@ set(ZIG_STAGE2_SOURCES |
| 525 | src/Type.zig | 525 | src/Type.zig |
| 526 | src/Value.zig | 526 | src/Value.zig |
| 527 | src/Zcu.zig | 527 | src/Zcu.zig |
| 528 | src/Zcu/PerThread.zig | ||
| 528 | src/arch/aarch64/CodeGen.zig | 529 | src/arch/aarch64/CodeGen.zig |
| 529 | src/arch/aarch64/Emit.zig | 530 | src/arch/aarch64/Emit.zig |
| 530 | src/arch/aarch64/Mir.zig | 531 | src/arch/aarch64/Mir.zig |
lib/std/Thread/Pool.zig+86-10| ... | @@ -9,17 +9,19 @@ run_queue: RunQueue = .{}, | ... | @@ -9,17 +9,19 @@ run_queue: RunQueue = .{}, |
| 9 | is_running: bool = true, | 9 | is_running: bool = true, |
| 10 | allocator: std.mem.Allocator, | 10 | allocator: std.mem.Allocator, |
| 11 | threads: []std.Thread, | 11 | threads: []std.Thread, |
| 12 | ids: std.AutoArrayHashMapUnmanaged(std.Thread.Id, void), | ||
| 12 | 13 | ||
| 13 | const RunQueue = std.SinglyLinkedList(Runnable); | 14 | const RunQueue = std.SinglyLinkedList(Runnable); |
| 14 | const Runnable = struct { | 15 | const Runnable = struct { |
| 15 | runFn: RunProto, | 16 | runFn: RunProto, |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | const RunProto = *const fn (*Runnable) void; | 19 | const RunProto = *const fn (*Runnable, id: ?usize) void; |
| 19 | 20 | ||
| 20 | pub const Options = struct { | 21 | pub const Options = struct { |
| 21 | allocator: std.mem.Allocator, | 22 | allocator: std.mem.Allocator, |
| 22 | n_jobs: ?u32 = null, | 23 | n_jobs: ?u32 = null, |
| 24 | track_ids: bool = false, | ||
| 23 | }; | 25 | }; |
| 24 | 26 | ||
| 25 | pub fn init(pool: *Pool, options: Options) !void { | 27 | pub fn init(pool: *Pool, options: Options) !void { |
| ... | @@ -28,6 +30,7 @@ pub fn init(pool: *Pool, options: Options) !void { | ... | @@ -28,6 +30,7 @@ pub fn init(pool: *Pool, options: Options) !void { |
| 28 | pool.* = .{ | 30 | pool.* = .{ |
| 29 | .allocator = allocator, | 31 | .allocator = allocator, |
| 30 | .threads = &[_]std.Thread{}, | 32 | .threads = &[_]std.Thread{}, |
| 33 | .ids = .{}, | ||
| 31 | }; | 34 | }; |
| 32 | 35 | ||
| 33 | if (builtin.single_threaded) { | 36 | if (builtin.single_threaded) { |
| ... | @@ -35,6 +38,10 @@ pub fn init(pool: *Pool, options: Options) !void { | ... | @@ -35,6 +38,10 @@ pub fn init(pool: *Pool, options: Options) !void { |
| 35 | } | 38 | } |
| 36 | 39 | ||
| 37 | const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1); | 40 | const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1); |
| 41 | if (options.track_ids) { | ||
| 42 | try pool.ids.ensureTotalCapacity(allocator, 1 + thread_count); | ||
| 43 | pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {}); | ||
| 44 | } | ||
| 38 | 45 | ||
| 39 | // kill and join any threads we spawned and free memory on error. | 46 | // kill and join any threads we spawned and free memory on error. |
| 40 | pool.threads = try allocator.alloc(std.Thread, thread_count); | 47 | pool.threads = try allocator.alloc(std.Thread, thread_count); |
| ... | @@ -49,6 +56,7 @@ pub fn init(pool: *Pool, options: Options) !void { | ... | @@ -49,6 +56,7 @@ pub fn init(pool: *Pool, options: Options) !void { |
| 49 | 56 | ||
| 50 | pub fn deinit(pool: *Pool) void { | 57 | pub fn deinit(pool: *Pool) void { |
| 51 | pool.join(pool.threads.len); // kill and join all threads. | 58 | pool.join(pool.threads.len); // kill and join all threads. |
| 59 | pool.ids.deinit(pool.allocator); | ||
| 52 | pool.* = undefined; | 60 | pool.* = undefined; |
| 53 | } | 61 | } |
| 54 | 62 | ||
| ... | @@ -96,7 +104,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args | ... | @@ -96,7 +104,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args |
| 96 | run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } }, | 104 | run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } }, |
| 97 | wait_group: *WaitGroup, | 105 | wait_group: *WaitGroup, |
| 98 | 106 | ||
| 99 | fn runFn(runnable: *Runnable) void { | 107 | fn runFn(runnable: *Runnable, _: ?usize) void { |
| 100 | const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable); | 108 | const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable); |
| 101 | const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node)); | 109 | const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node)); |
| 102 | @call(.auto, func, closure.arguments); | 110 | @call(.auto, func, closure.arguments); |
| ... | @@ -134,6 +142,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args | ... | @@ -134,6 +142,70 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args |
| 134 | pool.cond.signal(); | 142 | pool.cond.signal(); |
| 135 | } | 143 | } |
| 136 | 144 | ||
| 145 | /// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and | ||
| 146 | /// `WaitGroup.finish` after it returns. | ||
| 147 | /// | ||
| 148 | /// The first argument passed to `func` is a dense `usize` thread id, the rest | ||
| 149 | /// of the arguments are passed from `args`. Requires the pool to have been | ||
| 150 | /// initialized with `.track_ids = true`. | ||
| 151 | /// | ||
| 152 | /// In the case that queuing the function call fails to allocate memory, or the | ||
| 153 | /// target is single-threaded, the function is called directly. | ||
| 154 | pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args: anytype) void { | ||
| 155 | wait_group.start(); | ||
| 156 | |||
| 157 | if (builtin.single_threaded) { | ||
| 158 | @call(.auto, func, .{0} ++ args); | ||
| 159 | wait_group.finish(); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | const Args = @TypeOf(args); | ||
| 164 | const Closure = struct { | ||
| 165 | arguments: Args, | ||
| 166 | pool: *Pool, | ||
| 167 | run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } }, | ||
| 168 | wait_group: *WaitGroup, | ||
| 169 | |||
| 170 | fn runFn(runnable: *Runnable, id: ?usize) void { | ||
| 171 | const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable); | ||
| 172 | const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node)); | ||
| 173 | @call(.auto, func, .{id.?} ++ closure.arguments); | ||
| 174 | closure.wait_group.finish(); | ||
| 175 | |||
| 176 | // The thread pool's allocator is protected by the mutex. | ||
| 177 | const mutex = &closure.pool.mutex; | ||
| 178 | mutex.lock(); | ||
| 179 | defer mutex.unlock(); | ||
| 180 | |||
| 181 | closure.pool.allocator.destroy(closure); | ||
| 182 | } | ||
| 183 | }; | ||
| 184 | |||
| 185 | { | ||
| 186 | pool.mutex.lock(); | ||
| 187 | |||
| 188 | const closure = pool.allocator.create(Closure) catch { | ||
| 189 | const id = pool.ids.getIndex(std.Thread.getCurrentId()); | ||
| 190 | pool.mutex.unlock(); | ||
| 191 | @call(.auto, func, .{id.?} ++ args); | ||
| 192 | wait_group.finish(); | ||
| 193 | return; | ||
| 194 | }; | ||
| 195 | closure.* = .{ | ||
| 196 | .arguments = args, | ||
| 197 | .pool = pool, | ||
| 198 | .wait_group = wait_group, | ||
| 199 | }; | ||
| 200 | |||
| 201 | pool.run_queue.prepend(&closure.run_node); | ||
| 202 | pool.mutex.unlock(); | ||
| 203 | } | ||
| 204 | |||
| 205 | // Notify waiting threads outside the lock to try and keep the critical section small. | ||
| 206 | pool.cond.signal(); | ||
| 207 | } | ||
| 208 | |||
| 137 | pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void { | 209 | pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) !void { |
| 138 | if (builtin.single_threaded) { | 210 | if (builtin.single_threaded) { |
| 139 | @call(.auto, func, args); | 211 | @call(.auto, func, args); |
| ... | @@ -181,14 +253,16 @@ fn worker(pool: *Pool) void { | ... | @@ -181,14 +253,16 @@ fn worker(pool: *Pool) void { |
| 181 | pool.mutex.lock(); | 253 | pool.mutex.lock(); |
| 182 | defer pool.mutex.unlock(); | 254 | defer pool.mutex.unlock(); |
| 183 | 255 | ||
| 256 | const id = if (pool.ids.count() > 0) pool.ids.count() else null; | ||
| 257 | if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {}); | ||
| 258 | |||
| 184 | while (true) { | 259 | while (true) { |
| 185 | while (pool.run_queue.popFirst()) |run_node| { | 260 | while (pool.run_queue.popFirst()) |run_node| { |
| 186 | // Temporarily unlock the mutex in order to execute the run_node | 261 | // Temporarily unlock the mutex in order to execute the run_node |
| 187 | pool.mutex.unlock(); | 262 | pool.mutex.unlock(); |
| 188 | defer pool.mutex.lock(); | 263 | defer pool.mutex.lock(); |
| 189 | 264 | ||
| 190 | const runFn = run_node.data.runFn; | 265 | run_node.data.runFn(&run_node.data, id); |
| 191 | runFn(&run_node.data); | ||
| 192 | } | 266 | } |
| 193 | 267 | ||
| 194 | // Stop executing instead of waiting if the thread pool is no longer running. | 268 | // Stop executing instead of waiting if the thread pool is no longer running. |
| ... | @@ -201,16 +275,18 @@ fn worker(pool: *Pool) void { | ... | @@ -201,16 +275,18 @@ fn worker(pool: *Pool) void { |
| 201 | } | 275 | } |
| 202 | 276 | ||
| 203 | pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void { | 277 | pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void { |
| 278 | var id: ?usize = null; | ||
| 279 | |||
| 204 | while (!wait_group.isDone()) { | 280 | while (!wait_group.isDone()) { |
| 205 | if (blk: { | 281 | pool.mutex.lock(); |
| 206 | pool.mutex.lock(); | 282 | if (pool.run_queue.popFirst()) |run_node| { |
| 207 | defer pool.mutex.unlock(); | 283 | id = id orelse pool.ids.getIndex(std.Thread.getCurrentId()); |
| 208 | break :blk pool.run_queue.popFirst(); | 284 | pool.mutex.unlock(); |
| 209 | }) |run_node| { | 285 | run_node.data.runFn(&run_node.data, id); |
| 210 | run_node.data.runFn(&run_node.data); | ||
| 211 | continue; | 286 | continue; |
| 212 | } | 287 | } |
| 213 | 288 | ||
| 289 | pool.mutex.unlock(); | ||
| 214 | wait_group.wait(); | 290 | wait_group.wait(); |
| 215 | return; | 291 | return; |
| 216 | } | 292 | } |
src/Air.zig+2-2| ... | @@ -1563,12 +1563,12 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref { | ... | @@ -1563,12 +1563,12 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref { |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | /// Returns `null` if runtime-known. | 1565 | /// Returns `null` if runtime-known. |
| 1566 | pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value { | 1566 | pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value { |
| 1567 | if (inst.toInterned()) |ip_index| { | 1567 | if (inst.toInterned()) |ip_index| { |
| 1568 | return Value.fromInterned(ip_index); | 1568 | return Value.fromInterned(ip_index); |
| 1569 | } | 1569 | } |
| 1570 | const index = inst.toIndex().?; | 1570 | const index = inst.toIndex().?; |
| 1571 | return air.typeOfIndex(index, &mod.intern_pool).onePossibleValue(mod); | 1571 | return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt); |
| 1572 | } | 1572 | } |
| 1573 | 1573 | ||
| 1574 | pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 { | 1574 | pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 { |
src/Compilation.zig+31-29| ... | @@ -2146,6 +2146,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2146,6 +2146,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2146 | try comp.performAllTheWork(main_progress_node); | 2146 | try comp.performAllTheWork(main_progress_node); |
| 2147 | 2147 | ||
| 2148 | if (comp.module) |zcu| { | 2148 | if (comp.module) |zcu| { |
| 2149 | const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main }; | ||
| 2150 | |||
| 2149 | if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { | 2151 | if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { |
| 2150 | std.debug.print("intern pool stats for '{s}':\n", .{ | 2152 | std.debug.print("intern pool stats for '{s}':\n", .{ |
| 2151 | comp.root_name, | 2153 | comp.root_name, |
| ... | @@ -2165,10 +2167,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2165,10 +2167,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2165 | // The `test_functions` decl has been intentionally postponed until now, | 2167 | // The `test_functions` decl has been intentionally postponed until now, |
| 2166 | // at which point we must populate it with the list of test functions that | 2168 | // at which point we must populate it with the list of test functions that |
| 2167 | // have been discovered and not filtered out. | 2169 | // have been discovered and not filtered out. |
| 2168 | try zcu.populateTestFunctions(main_progress_node); | 2170 | try pt.populateTestFunctions(main_progress_node); |
| 2169 | } | 2171 | } |
| 2170 | 2172 | ||
| 2171 | try zcu.processExports(); | 2173 | try pt.processExports(); |
| 2172 | } | 2174 | } |
| 2173 | 2175 | ||
| 2174 | if (comp.totalErrorCount() != 0) { | 2176 | if (comp.totalErrorCount() != 0) { |
| ... | @@ -2247,7 +2249,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2247,7 +2249,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2247 | } | 2249 | } |
| 2248 | } | 2250 | } |
| 2249 | 2251 | ||
| 2250 | try flush(comp, arena, main_progress_node); | 2252 | try flush(comp, arena, .main, main_progress_node); |
| 2251 | if (comp.totalErrorCount() != 0) return; | 2253 | if (comp.totalErrorCount() != 0) return; |
| 2252 | 2254 | ||
| 2253 | // Failure here only means an unnecessary cache miss. | 2255 | // Failure here only means an unnecessary cache miss. |
| ... | @@ -2264,16 +2266,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2264,16 +2266,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2264 | whole.lock = man.toOwnedLock(); | 2266 | whole.lock = man.toOwnedLock(); |
| 2265 | }, | 2267 | }, |
| 2266 | .incremental => { | 2268 | .incremental => { |
| 2267 | try flush(comp, arena, main_progress_node); | 2269 | try flush(comp, arena, .main, main_progress_node); |
| 2268 | if (comp.totalErrorCount() != 0) return; | 2270 | if (comp.totalErrorCount() != 0) return; |
| 2269 | }, | 2271 | }, |
| 2270 | } | 2272 | } |
| 2271 | } | 2273 | } |
| 2272 | 2274 | ||
| 2273 | fn flush(comp: *Compilation, arena: Allocator, prog_node: std.Progress.Node) !void { | 2275 | fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 2274 | if (comp.bin_file) |lf| { | 2276 | if (comp.bin_file) |lf| { |
| 2275 | // This is needed before reading the error flags. | 2277 | // This is needed before reading the error flags. |
| 2276 | lf.flush(arena, prog_node) catch |err| switch (err) { | 2278 | lf.flush(arena, tid, prog_node) catch |err| switch (err) { |
| 2277 | error.FlushFailure => {}, // error reported through link_error_flags | 2279 | error.FlushFailure => {}, // error reported through link_error_flags |
| 2278 | error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr | 2280 | error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr |
| 2279 | else => |e| return e, | 2281 | else => |e| return e, |
| ... | @@ -3419,7 +3421,7 @@ pub fn performAllTheWork( | ... | @@ -3419,7 +3421,7 @@ pub fn performAllTheWork( |
| 3419 | 3421 | ||
| 3420 | while (true) { | 3422 | while (true) { |
| 3421 | if (comp.work_queue.readItem()) |work_item| { | 3423 | if (comp.work_queue.readItem()) |work_item| { |
| 3422 | try processOneJob(comp, work_item, main_progress_node); | 3424 | try processOneJob(0, comp, work_item, main_progress_node); |
| 3423 | continue; | 3425 | continue; |
| 3424 | } | 3426 | } |
| 3425 | if (comp.module) |zcu| { | 3427 | if (comp.module) |zcu| { |
| ... | @@ -3447,11 +3449,11 @@ pub fn performAllTheWork( | ... | @@ -3447,11 +3449,11 @@ pub fn performAllTheWork( |
| 3447 | } | 3449 | } |
| 3448 | } | 3450 | } |
| 3449 | 3451 | ||
| 3450 | fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void { | 3452 | fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void { |
| 3451 | switch (job) { | 3453 | switch (job) { |
| 3452 | .codegen_decl => |decl_index| { | 3454 | .codegen_decl => |decl_index| { |
| 3453 | const zcu = comp.module.?; | 3455 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3454 | const decl = zcu.declPtr(decl_index); | 3456 | const decl = pt.zcu.declPtr(decl_index); |
| 3455 | 3457 | ||
| 3456 | switch (decl.analysis) { | 3458 | switch (decl.analysis) { |
| 3457 | .unreferenced => unreachable, | 3459 | .unreferenced => unreachable, |
| ... | @@ -3469,7 +3471,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3469,7 +3471,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3469 | 3471 | ||
| 3470 | assert(decl.has_tv); | 3472 | assert(decl.has_tv); |
| 3471 | 3473 | ||
| 3472 | try zcu.linkerUpdateDecl(decl_index); | 3474 | try pt.linkerUpdateDecl(decl_index); |
| 3473 | return; | 3475 | return; |
| 3474 | }, | 3476 | }, |
| 3475 | } | 3477 | } |
| ... | @@ -3478,16 +3480,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3478,16 +3480,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3478 | const named_frame = tracy.namedFrame("codegen_func"); | 3480 | const named_frame = tracy.namedFrame("codegen_func"); |
| 3479 | defer named_frame.end(); | 3481 | defer named_frame.end(); |
| 3480 | 3482 | ||
| 3481 | const zcu = comp.module.?; | 3483 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3482 | // This call takes ownership of `func.air`. | 3484 | // This call takes ownership of `func.air`. |
| 3483 | try zcu.linkerUpdateFunc(func.func, func.air); | 3485 | try pt.linkerUpdateFunc(func.func, func.air); |
| 3484 | }, | 3486 | }, |
| 3485 | .analyze_func => |func| { | 3487 | .analyze_func => |func| { |
| 3486 | const named_frame = tracy.namedFrame("analyze_func"); | 3488 | const named_frame = tracy.namedFrame("analyze_func"); |
| 3487 | defer named_frame.end(); | 3489 | defer named_frame.end(); |
| 3488 | 3490 | ||
| 3489 | const zcu = comp.module.?; | 3491 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3490 | zcu.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { | 3492 | pt.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { |
| 3491 | error.OutOfMemory => return error.OutOfMemory, | 3493 | error.OutOfMemory => return error.OutOfMemory, |
| 3492 | error.AnalysisFail => return, | 3494 | error.AnalysisFail => return, |
| 3493 | }; | 3495 | }; |
| ... | @@ -3496,8 +3498,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3496,8 +3498,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3496 | if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++ | 3498 | if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++ |
| 3497 | "not decl analysis, which is too early to know about @export calls"); | 3499 | "not decl analysis, which is too early to know about @export calls"); |
| 3498 | 3500 | ||
| 3499 | const zcu = comp.module.?; | 3501 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3500 | const decl = zcu.declPtr(decl_index); | 3502 | const decl = pt.zcu.declPtr(decl_index); |
| 3501 | 3503 | ||
| 3502 | switch (decl.analysis) { | 3504 | switch (decl.analysis) { |
| 3503 | .unreferenced => unreachable, | 3505 | .unreferenced => unreachable, |
| ... | @@ -3515,7 +3517,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3515,7 +3517,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3515 | defer named_frame.end(); | 3517 | defer named_frame.end(); |
| 3516 | 3518 | ||
| 3517 | const gpa = comp.gpa; | 3519 | const gpa = comp.gpa; |
| 3518 | const emit_h = zcu.emit_h.?; | 3520 | const emit_h = pt.zcu.emit_h.?; |
| 3519 | _ = try emit_h.decl_table.getOrPut(gpa, decl_index); | 3521 | _ = try emit_h.decl_table.getOrPut(gpa, decl_index); |
| 3520 | const decl_emit_h = emit_h.declPtr(decl_index); | 3522 | const decl_emit_h = emit_h.declPtr(decl_index); |
| 3521 | const fwd_decl = &decl_emit_h.fwd_decl; | 3523 | const fwd_decl = &decl_emit_h.fwd_decl; |
| ... | @@ -3523,11 +3525,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3523,11 +3525,11 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3523 | var ctypes_arena = std.heap.ArenaAllocator.init(gpa); | 3525 | var ctypes_arena = std.heap.ArenaAllocator.init(gpa); |
| 3524 | defer ctypes_arena.deinit(); | 3526 | defer ctypes_arena.deinit(); |
| 3525 | 3527 | ||
| 3526 | const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); | 3528 | const file_scope = pt.zcu.namespacePtr(decl.src_namespace).fileScope(pt.zcu); |
| 3527 | 3529 | ||
| 3528 | var dg: c_codegen.DeclGen = .{ | 3530 | var dg: c_codegen.DeclGen = .{ |
| 3529 | .gpa = gpa, | 3531 | .gpa = gpa, |
| 3530 | .zcu = zcu, | 3532 | .pt = pt, |
| 3531 | .mod = file_scope.mod, | 3533 | .mod = file_scope.mod, |
| 3532 | .error_msg = null, | 3534 | .error_msg = null, |
| 3533 | .pass = .{ .decl = decl_index }, | 3535 | .pass = .{ .decl = decl_index }, |
| ... | @@ -3557,25 +3559,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3557,25 +3559,25 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3557 | } | 3559 | } |
| 3558 | }, | 3560 | }, |
| 3559 | .analyze_decl => |decl_index| { | 3561 | .analyze_decl => |decl_index| { |
| 3560 | const zcu = comp.module.?; | 3562 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3561 | zcu.ensureDeclAnalyzed(decl_index) catch |err| switch (err) { | 3563 | pt.ensureDeclAnalyzed(decl_index) catch |err| switch (err) { |
| 3562 | error.OutOfMemory => return error.OutOfMemory, | 3564 | error.OutOfMemory => return error.OutOfMemory, |
| 3563 | error.AnalysisFail => return, | 3565 | error.AnalysisFail => return, |
| 3564 | }; | 3566 | }; |
| 3565 | const decl = zcu.declPtr(decl_index); | 3567 | const decl = pt.zcu.declPtr(decl_index); |
| 3566 | if (decl.kind == .@"test" and comp.config.is_test) { | 3568 | if (decl.kind == .@"test" and comp.config.is_test) { |
| 3567 | // Tests are always emitted in test binaries. The decl_refs are created by | 3569 | // Tests are always emitted in test binaries. The decl_refs are created by |
| 3568 | // Zcu.populateTestFunctions, but this will not queue body analysis, so do | 3570 | // Zcu.populateTestFunctions, but this will not queue body analysis, so do |
| 3569 | // that now. | 3571 | // that now. |
| 3570 | try zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern()); | 3572 | try pt.zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern()); |
| 3571 | } | 3573 | } |
| 3572 | }, | 3574 | }, |
| 3573 | .resolve_type_fully => |ty| { | 3575 | .resolve_type_fully => |ty| { |
| 3574 | const named_frame = tracy.namedFrame("resolve_type_fully"); | 3576 | const named_frame = tracy.namedFrame("resolve_type_fully"); |
| 3575 | defer named_frame.end(); | 3577 | defer named_frame.end(); |
| 3576 | 3578 | ||
| 3577 | const zcu = comp.module.?; | 3579 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3578 | Type.fromInterned(ty).resolveFully(zcu) catch |err| switch (err) { | 3580 | Type.fromInterned(ty).resolveFully(pt) catch |err| switch (err) { |
| 3579 | error.OutOfMemory => return error.OutOfMemory, | 3581 | error.OutOfMemory => return error.OutOfMemory, |
| 3580 | error.AnalysisFail => return, | 3582 | error.AnalysisFail => return, |
| 3581 | }; | 3583 | }; |
| ... | @@ -3603,12 +3605,12 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo | ... | @@ -3603,12 +3605,12 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo |
| 3603 | try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | 3605 | try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); |
| 3604 | }; | 3606 | }; |
| 3605 | }, | 3607 | }, |
| 3606 | .analyze_mod => |pkg| { | 3608 | .analyze_mod => |mod| { |
| 3607 | const named_frame = tracy.namedFrame("analyze_mod"); | 3609 | const named_frame = tracy.namedFrame("analyze_mod"); |
| 3608 | defer named_frame.end(); | 3610 | defer named_frame.end(); |
| 3609 | 3611 | ||
| 3610 | const zcu = comp.module.?; | 3612 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) }; |
| 3611 | zcu.semaPkg(pkg) catch |err| switch (err) { | 3613 | pt.semaPkg(mod) catch |err| switch (err) { |
| 3612 | error.OutOfMemory => return error.OutOfMemory, | 3614 | error.OutOfMemory => return error.OutOfMemory, |
| 3613 | error.AnalysisFail => return, | 3615 | error.AnalysisFail => return, |
| 3614 | }; | 3616 | }; |
src/InternPool.zig+156-86| ... | @@ -4548,17 +4548,14 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void { | ... | @@ -4548,17 +4548,14 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void { |
| 4548 | 4548 | ||
| 4549 | // This inserts all the statically-known values into the intern pool in the | 4549 | // This inserts all the statically-known values into the intern pool in the |
| 4550 | // order expected. | 4550 | // order expected. |
| 4551 | for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| { | 4551 | for (&static_keys, 0..) |key, key_index| switch (@as(Index, @enumFromInt(key_index))) { |
| 4552 | _ = ip.get(gpa, key) catch unreachable; | 4552 | .empty_struct_type => assert(try ip.getAnonStructType(gpa, .main, .{ |
| 4553 | } | 4553 | .types = &.{}, |
| 4554 | _ = ip.getAnonStructType(gpa, .{ | 4554 | .names = &.{}, |
| 4555 | .types = &.{}, | 4555 | .values = &.{}, |
| 4556 | .names = &.{}, | 4556 | }) == .empty_struct_type), |
| 4557 | .values = &.{}, | 4557 | else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index), |
| 4558 | }) catch unreachable; | 4558 | }; |
| 4559 | for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| { | ||
| 4560 | _ = ip.get(gpa, key) catch unreachable; | ||
| 4561 | } | ||
| 4562 | 4559 | ||
| 4563 | if (std.debug.runtime_safety) { | 4560 | if (std.debug.runtime_safety) { |
| 4564 | // Sanity check. | 4561 | // Sanity check. |
| ... | @@ -5242,7 +5239,7 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key | ... | @@ -5242,7 +5239,7 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key |
| 5242 | } }; | 5239 | } }; |
| 5243 | } | 5240 | } |
| 5244 | 5241 | ||
| 5245 | pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | 5242 | pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index { |
| 5246 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 5243 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 5247 | const gop = try ip.map.getOrPutAdapted(gpa, key, adapter); | 5244 | const gop = try ip.map.getOrPutAdapted(gpa, key, adapter); |
| 5248 | if (gop.found_existing) return @enumFromInt(gop.index); | 5245 | if (gop.found_existing) return @enumFromInt(gop.index); |
| ... | @@ -5266,8 +5263,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -5266,8 +5263,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 5266 | _ = ip.map.pop(); | 5263 | _ = ip.map.pop(); |
| 5267 | var new_key = key; | 5264 | var new_key = key; |
| 5268 | new_key.ptr_type.flags.size = .Many; | 5265 | new_key.ptr_type.flags.size = .Many; |
| 5269 | const ptr_type_index = try ip.get(gpa, new_key); | 5266 | const ptr_type_index = try ip.get(gpa, tid, new_key); |
| 5270 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); | 5267 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); |
| 5268 | |||
| 5271 | try ip.items.ensureUnusedCapacity(gpa, 1); | 5269 | try ip.items.ensureUnusedCapacity(gpa, 1); |
| 5272 | ip.items.appendAssumeCapacity(.{ | 5270 | ip.items.appendAssumeCapacity(.{ |
| 5273 | .tag = .type_slice, | 5271 | .tag = .type_slice, |
| ... | @@ -5519,7 +5517,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -5519,7 +5517,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 5519 | else => unreachable, | 5517 | else => unreachable, |
| 5520 | } | 5518 | } |
| 5521 | _ = ip.map.pop(); | 5519 | _ = ip.map.pop(); |
| 5522 | const index_index = try ip.get(gpa, .{ .int = .{ | 5520 | const index_index = try ip.get(gpa, tid, .{ .int = .{ |
| 5523 | .ty = .usize_type, | 5521 | .ty = .usize_type, |
| 5524 | .storage = .{ .u64 = base_index.index }, | 5522 | .storage = .{ .u64 = base_index.index }, |
| 5525 | } }); | 5523 | } }); |
| ... | @@ -5932,7 +5930,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -5932,7 +5930,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 5932 | const elem = switch (aggregate.storage) { | 5930 | const elem = switch (aggregate.storage) { |
| 5933 | .bytes => |bytes| elem: { | 5931 | .bytes => |bytes| elem: { |
| 5934 | _ = ip.map.pop(); | 5932 | _ = ip.map.pop(); |
| 5935 | const elem = try ip.get(gpa, .{ .int = .{ | 5933 | const elem = try ip.get(gpa, tid, .{ .int = .{ |
| 5936 | .ty = .u8_type, | 5934 | .ty = .u8_type, |
| 5937 | .storage = .{ .u64 = bytes.at(0, ip) }, | 5935 | .storage = .{ .u64 = bytes.at(0, ip) }, |
| 5938 | } }); | 5936 | } }); |
| ... | @@ -6074,7 +6072,12 @@ pub const UnionTypeInit = struct { | ... | @@ -6074,7 +6072,12 @@ pub const UnionTypeInit = struct { |
| 6074 | }, | 6072 | }, |
| 6075 | }; | 6073 | }; |
| 6076 | 6074 | ||
| 6077 | pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocator.Error!WipNamespaceType.Result { | 6075 | pub fn getUnionType( |
| 6076 | ip: *InternPool, | ||
| 6077 | gpa: Allocator, | ||
| 6078 | _: Zcu.PerThread.Id, | ||
| 6079 | ini: UnionTypeInit, | ||
| 6080 | ) Allocator.Error!WipNamespaceType.Result { | ||
| 6078 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 6081 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 6079 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .union_type = switch (ini.key) { | 6082 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .union_type = switch (ini.key) { |
| 6080 | .declared => |d| .{ .declared = .{ | 6083 | .declared => |d| .{ .declared = .{ |
| ... | @@ -6221,6 +6224,7 @@ pub const StructTypeInit = struct { | ... | @@ -6221,6 +6224,7 @@ pub const StructTypeInit = struct { |
| 6221 | pub fn getStructType( | 6224 | pub fn getStructType( |
| 6222 | ip: *InternPool, | 6225 | ip: *InternPool, |
| 6223 | gpa: Allocator, | 6226 | gpa: Allocator, |
| 6227 | _: Zcu.PerThread.Id, | ||
| 6224 | ini: StructTypeInit, | 6228 | ini: StructTypeInit, |
| 6225 | ) Allocator.Error!WipNamespaceType.Result { | 6229 | ) Allocator.Error!WipNamespaceType.Result { |
| 6226 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 6230 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| ... | @@ -6396,7 +6400,12 @@ pub const AnonStructTypeInit = struct { | ... | @@ -6396,7 +6400,12 @@ pub const AnonStructTypeInit = struct { |
| 6396 | values: []const Index, | 6400 | values: []const Index, |
| 6397 | }; | 6401 | }; |
| 6398 | 6402 | ||
| 6399 | pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index { | 6403 | pub fn getAnonStructType( |
| 6404 | ip: *InternPool, | ||
| 6405 | gpa: Allocator, | ||
| 6406 | _: Zcu.PerThread.Id, | ||
| 6407 | ini: AnonStructTypeInit, | ||
| 6408 | ) Allocator.Error!Index { | ||
| 6400 | assert(ini.types.len == ini.values.len); | 6409 | assert(ini.types.len == ini.values.len); |
| 6401 | for (ini.types) |elem| assert(elem != .none); | 6410 | for (ini.types) |elem| assert(elem != .none); |
| 6402 | 6411 | ||
| ... | @@ -6450,7 +6459,12 @@ pub const GetFuncTypeKey = struct { | ... | @@ -6450,7 +6459,12 @@ pub const GetFuncTypeKey = struct { |
| 6450 | addrspace_is_generic: bool = false, | 6459 | addrspace_is_generic: bool = false, |
| 6451 | }; | 6460 | }; |
| 6452 | 6461 | ||
| 6453 | pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index { | 6462 | pub fn getFuncType( |
| 6463 | ip: *InternPool, | ||
| 6464 | gpa: Allocator, | ||
| 6465 | _: Zcu.PerThread.Id, | ||
| 6466 | key: GetFuncTypeKey, | ||
| 6467 | ) Allocator.Error!Index { | ||
| 6454 | // Validate input parameters. | 6468 | // Validate input parameters. |
| 6455 | assert(key.return_type != .none); | 6469 | assert(key.return_type != .none); |
| 6456 | for (key.param_types) |param_type| assert(param_type != .none); | 6470 | for (key.param_types) |param_type| assert(param_type != .none); |
| ... | @@ -6503,7 +6517,12 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat | ... | @@ -6503,7 +6517,12 @@ pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocat |
| 6503 | return @enumFromInt(ip.items.len - 1); | 6517 | return @enumFromInt(ip.items.len - 1); |
| 6504 | } | 6518 | } |
| 6505 | 6519 | ||
| 6506 | pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Allocator.Error!Index { | 6520 | pub fn getExternFunc( |
| 6521 | ip: *InternPool, | ||
| 6522 | gpa: Allocator, | ||
| 6523 | _: Zcu.PerThread.Id, | ||
| 6524 | key: Key.ExternFunc, | ||
| 6525 | ) Allocator.Error!Index { | ||
| 6507 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 6526 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 6508 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter); | 6527 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .extern_func = key }, adapter); |
| 6509 | if (gop.found_existing) return @enumFromInt(gop.index); | 6528 | if (gop.found_existing) return @enumFromInt(gop.index); |
| ... | @@ -6531,7 +6550,12 @@ pub const GetFuncDeclKey = struct { | ... | @@ -6531,7 +6550,12 @@ pub const GetFuncDeclKey = struct { |
| 6531 | is_noinline: bool, | 6550 | is_noinline: bool, |
| 6532 | }; | 6551 | }; |
| 6533 | 6552 | ||
| 6534 | pub fn getFuncDecl(ip: *InternPool, gpa: Allocator, key: GetFuncDeclKey) Allocator.Error!Index { | 6553 | pub fn getFuncDecl( |
| 6554 | ip: *InternPool, | ||
| 6555 | gpa: Allocator, | ||
| 6556 | _: Zcu.PerThread.Id, | ||
| 6557 | key: GetFuncDeclKey, | ||
| 6558 | ) Allocator.Error!Index { | ||
| 6535 | // The strategy here is to add the function type unconditionally, then to | 6559 | // The strategy here is to add the function type unconditionally, then to |
| 6536 | // ask if it already exists, and if so, revert the lengths of the mutated | 6560 | // ask if it already exists, and if so, revert the lengths of the mutated |
| 6537 | // arrays. This is similar to what `getOrPutTrailingString` does. | 6561 | // arrays. This is similar to what `getOrPutTrailingString` does. |
| ... | @@ -6598,7 +6622,12 @@ pub const GetFuncDeclIesKey = struct { | ... | @@ -6598,7 +6622,12 @@ pub const GetFuncDeclIesKey = struct { |
| 6598 | rbrace_column: u32, | 6622 | rbrace_column: u32, |
| 6599 | }; | 6623 | }; |
| 6600 | 6624 | ||
| 6601 | pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) Allocator.Error!Index { | 6625 | pub fn getFuncDeclIes( |
| 6626 | ip: *InternPool, | ||
| 6627 | gpa: Allocator, | ||
| 6628 | _: Zcu.PerThread.Id, | ||
| 6629 | key: GetFuncDeclIesKey, | ||
| 6630 | ) Allocator.Error!Index { | ||
| 6602 | // Validate input parameters. | 6631 | // Validate input parameters. |
| 6603 | assert(key.bare_return_type != .none); | 6632 | assert(key.bare_return_type != .none); |
| 6604 | for (key.param_types) |param_type| assert(param_type != .none); | 6633 | for (key.param_types) |param_type| assert(param_type != .none); |
| ... | @@ -6707,6 +6736,7 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A | ... | @@ -6707,6 +6736,7 @@ pub fn getFuncDeclIes(ip: *InternPool, gpa: Allocator, key: GetFuncDeclIesKey) A |
| 6707 | pub fn getErrorSetType( | 6736 | pub fn getErrorSetType( |
| 6708 | ip: *InternPool, | 6737 | ip: *InternPool, |
| 6709 | gpa: Allocator, | 6738 | gpa: Allocator, |
| 6739 | _: Zcu.PerThread.Id, | ||
| 6710 | names: []const NullTerminatedString, | 6740 | names: []const NullTerminatedString, |
| 6711 | ) Allocator.Error!Index { | 6741 | ) Allocator.Error!Index { |
| 6712 | assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan)); | 6742 | assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan)); |
| ... | @@ -6770,11 +6800,16 @@ pub const GetFuncInstanceKey = struct { | ... | @@ -6770,11 +6800,16 @@ pub const GetFuncInstanceKey = struct { |
| 6770 | inferred_error_set: bool, | 6800 | inferred_error_set: bool, |
| 6771 | }; | 6801 | }; |
| 6772 | 6802 | ||
| 6773 | pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) Allocator.Error!Index { | 6803 | pub fn getFuncInstance( |
| 6804 | ip: *InternPool, | ||
| 6805 | gpa: Allocator, | ||
| 6806 | tid: Zcu.PerThread.Id, | ||
| 6807 | arg: GetFuncInstanceKey, | ||
| 6808 | ) Allocator.Error!Index { | ||
| 6774 | if (arg.inferred_error_set) | 6809 | if (arg.inferred_error_set) |
| 6775 | return getFuncInstanceIes(ip, gpa, arg); | 6810 | return getFuncInstanceIes(ip, gpa, tid, arg); |
| 6776 | 6811 | ||
| 6777 | const func_ty = try ip.getFuncType(gpa, .{ | 6812 | const func_ty = try ip.getFuncType(gpa, tid, .{ |
| 6778 | .param_types = arg.param_types, | 6813 | .param_types = arg.param_types, |
| 6779 | .return_type = arg.bare_return_type, | 6814 | .return_type = arg.bare_return_type, |
| 6780 | .noalias_bits = arg.noalias_bits, | 6815 | .noalias_bits = arg.noalias_bits, |
| ... | @@ -6844,6 +6879,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) | ... | @@ -6844,6 +6879,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) |
| 6844 | pub fn getFuncInstanceIes( | 6879 | pub fn getFuncInstanceIes( |
| 6845 | ip: *InternPool, | 6880 | ip: *InternPool, |
| 6846 | gpa: Allocator, | 6881 | gpa: Allocator, |
| 6882 | _: Zcu.PerThread.Id, | ||
| 6847 | arg: GetFuncInstanceKey, | 6883 | arg: GetFuncInstanceKey, |
| 6848 | ) Allocator.Error!Index { | 6884 | ) Allocator.Error!Index { |
| 6849 | // Validate input parameters. | 6885 | // Validate input parameters. |
| ... | @@ -6955,7 +6991,6 @@ pub fn getFuncInstanceIes( | ... | @@ -6955,7 +6991,6 @@ pub fn getFuncInstanceIes( |
| 6955 | assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{ | 6991 | assert(!ip.map.getOrPutAssumeCapacityAdapted(Key{ |
| 6956 | .func_type = extraFuncType(ip, func_type_extra_index), | 6992 | .func_type = extraFuncType(ip, func_type_extra_index), |
| 6957 | }, adapter).found_existing); | 6993 | }, adapter).found_existing); |
| 6958 | |||
| 6959 | return finishFuncInstance( | 6994 | return finishFuncInstance( |
| 6960 | ip, | 6995 | ip, |
| 6961 | gpa, | 6996 | gpa, |
| ... | @@ -7096,6 +7131,7 @@ pub const WipEnumType = struct { | ... | @@ -7096,6 +7131,7 @@ pub const WipEnumType = struct { |
| 7096 | pub fn getEnumType( | 7131 | pub fn getEnumType( |
| 7097 | ip: *InternPool, | 7132 | ip: *InternPool, |
| 7098 | gpa: Allocator, | 7133 | gpa: Allocator, |
| 7134 | _: Zcu.PerThread.Id, | ||
| 7099 | ini: EnumTypeInit, | 7135 | ini: EnumTypeInit, |
| 7100 | ) Allocator.Error!WipEnumType.Result { | 7136 | ) Allocator.Error!WipEnumType.Result { |
| 7101 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 7137 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| ... | @@ -7172,7 +7208,7 @@ pub fn getEnumType( | ... | @@ -7172,7 +7208,7 @@ pub fn getEnumType( |
| 7172 | break :m values_map.toOptional(); | 7208 | break :m values_map.toOptional(); |
| 7173 | }; | 7209 | }; |
| 7174 | errdefer if (ini.has_values) { | 7210 | errdefer if (ini.has_values) { |
| 7175 | _ = ip.map.pop(); | 7211 | _ = ip.maps.pop(); |
| 7176 | }; | 7212 | }; |
| 7177 | 7213 | ||
| 7178 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len + | 7214 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len + |
| ... | @@ -7245,7 +7281,12 @@ const GeneratedTagEnumTypeInit = struct { | ... | @@ -7245,7 +7281,12 @@ const GeneratedTagEnumTypeInit = struct { |
| 7245 | /// Creates an enum type which was automatically-generated as the tag type of a | 7281 | /// Creates an enum type which was automatically-generated as the tag type of a |
| 7246 | /// `union` with no explicit tag type. Since this is only called once per union | 7282 | /// `union` with no explicit tag type. Since this is only called once per union |
| 7247 | /// type, it asserts that no matching type yet exists. | 7283 | /// type, it asserts that no matching type yet exists. |
| 7248 | pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTagEnumTypeInit) Allocator.Error!Index { | 7284 | pub fn getGeneratedTagEnumType( |
| 7285 | ip: *InternPool, | ||
| 7286 | gpa: Allocator, | ||
| 7287 | _: Zcu.PerThread.Id, | ||
| 7288 | ini: GeneratedTagEnumTypeInit, | ||
| 7289 | ) Allocator.Error!Index { | ||
| 7249 | assert(ip.isUnion(ini.owner_union_ty)); | 7290 | assert(ip.isUnion(ini.owner_union_ty)); |
| 7250 | assert(ip.isIntegerType(ini.tag_ty)); | 7291 | assert(ip.isIntegerType(ini.tag_ty)); |
| 7251 | for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty); | 7292 | for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty); |
| ... | @@ -7342,7 +7383,12 @@ pub const OpaqueTypeInit = struct { | ... | @@ -7342,7 +7383,12 @@ pub const OpaqueTypeInit = struct { |
| 7342 | }, | 7383 | }, |
| 7343 | }; | 7384 | }; |
| 7344 | 7385 | ||
| 7345 | pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Allocator.Error!WipNamespaceType.Result { | 7386 | pub fn getOpaqueType( |
| 7387 | ip: *InternPool, | ||
| 7388 | gpa: Allocator, | ||
| 7389 | _: Zcu.PerThread.Id, | ||
| 7390 | ini: OpaqueTypeInit, | ||
| 7391 | ) Allocator.Error!WipNamespaceType.Result { | ||
| 7346 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | 7392 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 7347 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) { | 7393 | const gop = try ip.map.getOrPutAdapted(gpa, Key{ .opaque_type = switch (ini.key) { |
| 7348 | .declared => |d| .{ .declared = .{ | 7394 | .declared => |d| .{ .declared = .{ |
| ... | @@ -7680,23 +7726,23 @@ test "basic usage" { | ... | @@ -7680,23 +7726,23 @@ test "basic usage" { |
| 7680 | var ip: InternPool = .{}; | 7726 | var ip: InternPool = .{}; |
| 7681 | defer ip.deinit(gpa); | 7727 | defer ip.deinit(gpa); |
| 7682 | 7728 | ||
| 7683 | const i32_type = try ip.get(gpa, .{ .int_type = .{ | 7729 | const i32_type = try ip.get(gpa, .main, .{ .int_type = .{ |
| 7684 | .signedness = .signed, | 7730 | .signedness = .signed, |
| 7685 | .bits = 32, | 7731 | .bits = 32, |
| 7686 | } }); | 7732 | } }); |
| 7687 | const array_i32 = try ip.get(gpa, .{ .array_type = .{ | 7733 | const array_i32 = try ip.get(gpa, .main, .{ .array_type = .{ |
| 7688 | .len = 10, | 7734 | .len = 10, |
| 7689 | .child = i32_type, | 7735 | .child = i32_type, |
| 7690 | .sentinel = .none, | 7736 | .sentinel = .none, |
| 7691 | } }); | 7737 | } }); |
| 7692 | 7738 | ||
| 7693 | const another_i32_type = try ip.get(gpa, .{ .int_type = .{ | 7739 | const another_i32_type = try ip.get(gpa, .main, .{ .int_type = .{ |
| 7694 | .signedness = .signed, | 7740 | .signedness = .signed, |
| 7695 | .bits = 32, | 7741 | .bits = 32, |
| 7696 | } }); | 7742 | } }); |
| 7697 | try std.testing.expect(another_i32_type == i32_type); | 7743 | try std.testing.expect(another_i32_type == i32_type); |
| 7698 | 7744 | ||
| 7699 | const another_array_i32 = try ip.get(gpa, .{ .array_type = .{ | 7745 | const another_array_i32 = try ip.get(gpa, .main, .{ .array_type = .{ |
| 7700 | .len = 10, | 7746 | .len = 10, |
| 7701 | .child = i32_type, | 7747 | .child = i32_type, |
| 7702 | .sentinel = .none, | 7748 | .sentinel = .none, |
| ... | @@ -7766,48 +7812,54 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index { | ... | @@ -7766,48 +7812,54 @@ pub fn sliceLen(ip: *const InternPool, i: Index) Index { |
| 7766 | /// * payload => error union | 7812 | /// * payload => error union |
| 7767 | /// * fn <=> fn | 7813 | /// * fn <=> fn |
| 7768 | /// * aggregate <=> aggregate (where children can also be coerced) | 7814 | /// * aggregate <=> aggregate (where children can also be coerced) |
| 7769 | pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { | 7815 | pub fn getCoerced( |
| 7816 | ip: *InternPool, | ||
| 7817 | gpa: Allocator, | ||
| 7818 | tid: Zcu.PerThread.Id, | ||
| 7819 | val: Index, | ||
| 7820 | new_ty: Index, | ||
| 7821 | ) Allocator.Error!Index { | ||
| 7770 | const old_ty = ip.typeOf(val); | 7822 | const old_ty = ip.typeOf(val); |
| 7771 | if (old_ty == new_ty) return val; | 7823 | if (old_ty == new_ty) return val; |
| 7772 | 7824 | ||
| 7773 | const tags = ip.items.items(.tag); | 7825 | const tags = ip.items.items(.tag); |
| 7774 | 7826 | ||
| 7775 | switch (val) { | 7827 | switch (val) { |
| 7776 | .undef => return ip.get(gpa, .{ .undef = new_ty }), | 7828 | .undef => return ip.get(gpa, tid, .{ .undef = new_ty }), |
| 7777 | .null_value => { | 7829 | .null_value => { |
| 7778 | if (ip.isOptionalType(new_ty)) return ip.get(gpa, .{ .opt = .{ | 7830 | if (ip.isOptionalType(new_ty)) return ip.get(gpa, tid, .{ .opt = .{ |
| 7779 | .ty = new_ty, | 7831 | .ty = new_ty, |
| 7780 | .val = .none, | 7832 | .val = .none, |
| 7781 | } }); | 7833 | } }); |
| 7782 | 7834 | ||
| 7783 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { | 7835 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { |
| 7784 | .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{ | 7836 | .One, .Many, .C => return ip.get(gpa, tid, .{ .ptr = .{ |
| 7785 | .ty = new_ty, | 7837 | .ty = new_ty, |
| 7786 | .base_addr = .int, | 7838 | .base_addr = .int, |
| 7787 | .byte_offset = 0, | 7839 | .byte_offset = 0, |
| 7788 | } }), | 7840 | } }), |
| 7789 | .Slice => return ip.get(gpa, .{ .slice = .{ | 7841 | .Slice => return ip.get(gpa, tid, .{ .slice = .{ |
| 7790 | .ty = new_ty, | 7842 | .ty = new_ty, |
| 7791 | .ptr = try ip.get(gpa, .{ .ptr = .{ | 7843 | .ptr = try ip.get(gpa, tid, .{ .ptr = .{ |
| 7792 | .ty = ip.slicePtrType(new_ty), | 7844 | .ty = ip.slicePtrType(new_ty), |
| 7793 | .base_addr = .int, | 7845 | .base_addr = .int, |
| 7794 | .byte_offset = 0, | 7846 | .byte_offset = 0, |
| 7795 | } }), | 7847 | } }), |
| 7796 | .len = try ip.get(gpa, .{ .undef = .usize_type }), | 7848 | .len = try ip.get(gpa, tid, .{ .undef = .usize_type }), |
| 7797 | } }), | 7849 | } }), |
| 7798 | }; | 7850 | }; |
| 7799 | }, | 7851 | }, |
| 7800 | else => switch (tags[@intFromEnum(val)]) { | 7852 | else => switch (tags[@intFromEnum(val)]) { |
| 7801 | .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty), | 7853 | .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty), |
| 7802 | .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty), | 7854 | .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty), |
| 7803 | .func_coerced => { | 7855 | .func_coerced => { |
| 7804 | const extra_index = ip.items.items(.data)[@intFromEnum(val)]; | 7856 | const extra_index = ip.items.items(.data)[@intFromEnum(val)]; |
| 7805 | const func: Index = @enumFromInt( | 7857 | const func: Index = @enumFromInt( |
| 7806 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?], | 7858 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?], |
| 7807 | ); | 7859 | ); |
| 7808 | switch (tags[@intFromEnum(func)]) { | 7860 | switch (tags[@intFromEnum(func)]) { |
| 7809 | .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty), | 7861 | .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty), |
| 7810 | .func_instance => return getCoercedFuncInstance(ip, gpa, val, new_ty), | 7862 | .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty), |
| 7811 | else => unreachable, | 7863 | else => unreachable, |
| 7812 | } | 7864 | } |
| 7813 | }, | 7865 | }, |
| ... | @@ -7816,9 +7868,9 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7816,9 +7868,9 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7816 | } | 7868 | } |
| 7817 | 7869 | ||
| 7818 | switch (ip.indexToKey(val)) { | 7870 | switch (ip.indexToKey(val)) { |
| 7819 | .undef => return ip.get(gpa, .{ .undef = new_ty }), | 7871 | .undef => return ip.get(gpa, tid, .{ .undef = new_ty }), |
| 7820 | .extern_func => |extern_func| if (ip.isFunctionType(new_ty)) | 7872 | .extern_func => |extern_func| if (ip.isFunctionType(new_ty)) |
| 7821 | return ip.get(gpa, .{ .extern_func = .{ | 7873 | return ip.get(gpa, tid, .{ .extern_func = .{ |
| 7822 | .ty = new_ty, | 7874 | .ty = new_ty, |
| 7823 | .decl = extern_func.decl, | 7875 | .decl = extern_func.decl, |
| 7824 | .lib_name = extern_func.lib_name, | 7876 | .lib_name = extern_func.lib_name, |
| ... | @@ -7827,12 +7879,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7827,12 +7879,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7827 | .func => unreachable, | 7879 | .func => unreachable, |
| 7828 | 7880 | ||
| 7829 | .int => |int| switch (ip.indexToKey(new_ty)) { | 7881 | .int => |int| switch (ip.indexToKey(new_ty)) { |
| 7830 | .enum_type => return ip.get(gpa, .{ .enum_tag = .{ | 7882 | .enum_type => return ip.get(gpa, tid, .{ .enum_tag = .{ |
| 7831 | .ty = new_ty, | 7883 | .ty = new_ty, |
| 7832 | .int = try ip.getCoerced(gpa, val, ip.loadEnumType(new_ty).tag_ty), | 7884 | .int = try ip.getCoerced(gpa, tid, val, ip.loadEnumType(new_ty).tag_ty), |
| 7833 | } }), | 7885 | } }), |
| 7834 | .ptr_type => switch (int.storage) { | 7886 | .ptr_type => switch (int.storage) { |
| 7835 | inline .u64, .i64 => |int_val| return ip.get(gpa, .{ .ptr = .{ | 7887 | inline .u64, .i64 => |int_val| return ip.get(gpa, tid, .{ .ptr = .{ |
| 7836 | .ty = new_ty, | 7888 | .ty = new_ty, |
| 7837 | .base_addr = .int, | 7889 | .base_addr = .int, |
| 7838 | .byte_offset = @intCast(int_val), | 7890 | .byte_offset = @intCast(int_val), |
| ... | @@ -7841,7 +7893,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7841,7 +7893,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7841 | .lazy_align, .lazy_size => {}, | 7893 | .lazy_align, .lazy_size => {}, |
| 7842 | }, | 7894 | }, |
| 7843 | else => if (ip.isIntegerType(new_ty)) | 7895 | else => if (ip.isIntegerType(new_ty)) |
| 7844 | return getCoercedInts(ip, gpa, int, new_ty), | 7896 | return ip.getCoercedInts(gpa, tid, int, new_ty), |
| 7845 | }, | 7897 | }, |
| 7846 | .float => |float| switch (ip.indexToKey(new_ty)) { | 7898 | .float => |float| switch (ip.indexToKey(new_ty)) { |
| 7847 | .simple_type => |simple| switch (simple) { | 7899 | .simple_type => |simple| switch (simple) { |
| ... | @@ -7852,7 +7904,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7852,7 +7904,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7852 | .f128, | 7904 | .f128, |
| 7853 | .c_longdouble, | 7905 | .c_longdouble, |
| 7854 | .comptime_float, | 7906 | .comptime_float, |
| 7855 | => return ip.get(gpa, .{ .float = .{ | 7907 | => return ip.get(gpa, tid, .{ .float = .{ |
| 7856 | .ty = new_ty, | 7908 | .ty = new_ty, |
| 7857 | .storage = float.storage, | 7909 | .storage = float.storage, |
| 7858 | } }), | 7910 | } }), |
| ... | @@ -7861,17 +7913,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7861,17 +7913,17 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7861 | else => {}, | 7913 | else => {}, |
| 7862 | }, | 7914 | }, |
| 7863 | .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty)) | 7915 | .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty)) |
| 7864 | return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty), | 7916 | return ip.getCoercedInts(gpa, tid, ip.indexToKey(enum_tag.int).int, new_ty), |
| 7865 | .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) { | 7917 | .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) { |
| 7866 | .enum_type => { | 7918 | .enum_type => { |
| 7867 | const enum_type = ip.loadEnumType(new_ty); | 7919 | const enum_type = ip.loadEnumType(new_ty); |
| 7868 | const index = enum_type.nameIndex(ip, enum_literal).?; | 7920 | const index = enum_type.nameIndex(ip, enum_literal).?; |
| 7869 | return ip.get(gpa, .{ .enum_tag = .{ | 7921 | return ip.get(gpa, tid, .{ .enum_tag = .{ |
| 7870 | .ty = new_ty, | 7922 | .ty = new_ty, |
| 7871 | .int = if (enum_type.values.len != 0) | 7923 | .int = if (enum_type.values.len != 0) |
| 7872 | enum_type.values.get(ip)[index] | 7924 | enum_type.values.get(ip)[index] |
| 7873 | else | 7925 | else |
| 7874 | try ip.get(gpa, .{ .int = .{ | 7926 | try ip.get(gpa, tid, .{ .int = .{ |
| 7875 | .ty = enum_type.tag_ty, | 7927 | .ty = enum_type.tag_ty, |
| 7876 | .storage = .{ .u64 = index }, | 7928 | .storage = .{ .u64 = index }, |
| 7877 | } }), | 7929 | } }), |
| ... | @@ -7880,22 +7932,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7880,22 +7932,22 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7880 | else => {}, | 7932 | else => {}, |
| 7881 | }, | 7933 | }, |
| 7882 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice) | 7934 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice) |
| 7883 | return ip.get(gpa, .{ .slice = .{ | 7935 | return ip.get(gpa, tid, .{ .slice = .{ |
| 7884 | .ty = new_ty, | 7936 | .ty = new_ty, |
| 7885 | .ptr = try ip.getCoerced(gpa, slice.ptr, ip.slicePtrType(new_ty)), | 7937 | .ptr = try ip.getCoerced(gpa, tid, slice.ptr, ip.slicePtrType(new_ty)), |
| 7886 | .len = slice.len, | 7938 | .len = slice.len, |
| 7887 | } }) | 7939 | } }) |
| 7888 | else if (ip.isIntegerType(new_ty)) | 7940 | else if (ip.isIntegerType(new_ty)) |
| 7889 | return ip.getCoerced(gpa, slice.ptr, new_ty), | 7941 | return ip.getCoerced(gpa, tid, slice.ptr, new_ty), |
| 7890 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice) | 7942 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice) |
| 7891 | return ip.get(gpa, .{ .ptr = .{ | 7943 | return ip.get(gpa, tid, .{ .ptr = .{ |
| 7892 | .ty = new_ty, | 7944 | .ty = new_ty, |
| 7893 | .base_addr = ptr.base_addr, | 7945 | .base_addr = ptr.base_addr, |
| 7894 | .byte_offset = ptr.byte_offset, | 7946 | .byte_offset = ptr.byte_offset, |
| 7895 | } }) | 7947 | } }) |
| 7896 | else if (ip.isIntegerType(new_ty)) | 7948 | else if (ip.isIntegerType(new_ty)) |
| 7897 | switch (ptr.base_addr) { | 7949 | switch (ptr.base_addr) { |
| 7898 | .int => return ip.get(gpa, .{ .int = .{ | 7950 | .int => return ip.get(gpa, tid, .{ .int = .{ |
| 7899 | .ty = .usize_type, | 7951 | .ty = .usize_type, |
| 7900 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, | 7952 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, |
| 7901 | } }), | 7953 | } }), |
| ... | @@ -7904,44 +7956,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7904,44 +7956,44 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7904 | .opt => |opt| switch (ip.indexToKey(new_ty)) { | 7956 | .opt => |opt| switch (ip.indexToKey(new_ty)) { |
| 7905 | .ptr_type => |ptr_type| return switch (opt.val) { | 7957 | .ptr_type => |ptr_type| return switch (opt.val) { |
| 7906 | .none => switch (ptr_type.flags.size) { | 7958 | .none => switch (ptr_type.flags.size) { |
| 7907 | .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{ | 7959 | .One, .Many, .C => try ip.get(gpa, tid, .{ .ptr = .{ |
| 7908 | .ty = new_ty, | 7960 | .ty = new_ty, |
| 7909 | .base_addr = .int, | 7961 | .base_addr = .int, |
| 7910 | .byte_offset = 0, | 7962 | .byte_offset = 0, |
| 7911 | } }), | 7963 | } }), |
| 7912 | .Slice => try ip.get(gpa, .{ .slice = .{ | 7964 | .Slice => try ip.get(gpa, tid, .{ .slice = .{ |
| 7913 | .ty = new_ty, | 7965 | .ty = new_ty, |
| 7914 | .ptr = try ip.get(gpa, .{ .ptr = .{ | 7966 | .ptr = try ip.get(gpa, tid, .{ .ptr = .{ |
| 7915 | .ty = ip.slicePtrType(new_ty), | 7967 | .ty = ip.slicePtrType(new_ty), |
| 7916 | .base_addr = .int, | 7968 | .base_addr = .int, |
| 7917 | .byte_offset = 0, | 7969 | .byte_offset = 0, |
| 7918 | } }), | 7970 | } }), |
| 7919 | .len = try ip.get(gpa, .{ .undef = .usize_type }), | 7971 | .len = try ip.get(gpa, tid, .{ .undef = .usize_type }), |
| 7920 | } }), | 7972 | } }), |
| 7921 | }, | 7973 | }, |
| 7922 | else => |payload| try ip.getCoerced(gpa, payload, new_ty), | 7974 | else => |payload| try ip.getCoerced(gpa, tid, payload, new_ty), |
| 7923 | }, | 7975 | }, |
| 7924 | .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{ | 7976 | .opt_type => |child_type| return try ip.get(gpa, tid, .{ .opt = .{ |
| 7925 | .ty = new_ty, | 7977 | .ty = new_ty, |
| 7926 | .val = switch (opt.val) { | 7978 | .val = switch (opt.val) { |
| 7927 | .none => .none, | 7979 | .none => .none, |
| 7928 | else => try ip.getCoerced(gpa, opt.val, child_type), | 7980 | else => try ip.getCoerced(gpa, tid, opt.val, child_type), |
| 7929 | }, | 7981 | }, |
| 7930 | } }), | 7982 | } }), |
| 7931 | else => {}, | 7983 | else => {}, |
| 7932 | }, | 7984 | }, |
| 7933 | .err => |err| if (ip.isErrorSetType(new_ty)) | 7985 | .err => |err| if (ip.isErrorSetType(new_ty)) |
| 7934 | return ip.get(gpa, .{ .err = .{ | 7986 | return ip.get(gpa, tid, .{ .err = .{ |
| 7935 | .ty = new_ty, | 7987 | .ty = new_ty, |
| 7936 | .name = err.name, | 7988 | .name = err.name, |
| 7937 | } }) | 7989 | } }) |
| 7938 | else if (ip.isErrorUnionType(new_ty)) | 7990 | else if (ip.isErrorUnionType(new_ty)) |
| 7939 | return ip.get(gpa, .{ .error_union = .{ | 7991 | return ip.get(gpa, tid, .{ .error_union = .{ |
| 7940 | .ty = new_ty, | 7992 | .ty = new_ty, |
| 7941 | .val = .{ .err_name = err.name }, | 7993 | .val = .{ .err_name = err.name }, |
| 7942 | } }), | 7994 | } }), |
| 7943 | .error_union => |error_union| if (ip.isErrorUnionType(new_ty)) | 7995 | .error_union => |error_union| if (ip.isErrorUnionType(new_ty)) |
| 7944 | return ip.get(gpa, .{ .error_union = .{ | 7996 | return ip.get(gpa, tid, .{ .error_union = .{ |
| 7945 | .ty = new_ty, | 7997 | .ty = new_ty, |
| 7946 | .val = error_union.val, | 7998 | .val = error_union.val, |
| 7947 | } }), | 7999 | } }), |
| ... | @@ -7960,20 +8012,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7960,20 +8012,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7960 | }; | 8012 | }; |
| 7961 | if (old_ty_child != new_ty_child) break :direct; | 8013 | if (old_ty_child != new_ty_child) break :direct; |
| 7962 | switch (aggregate.storage) { | 8014 | switch (aggregate.storage) { |
| 7963 | .bytes => |bytes| return ip.get(gpa, .{ .aggregate = .{ | 8015 | .bytes => |bytes| return ip.get(gpa, tid, .{ .aggregate = .{ |
| 7964 | .ty = new_ty, | 8016 | .ty = new_ty, |
| 7965 | .storage = .{ .bytes = bytes }, | 8017 | .storage = .{ .bytes = bytes }, |
| 7966 | } }), | 8018 | } }), |
| 7967 | .elems => |elems| { | 8019 | .elems => |elems| { |
| 7968 | const elems_copy = try gpa.dupe(Index, elems[0..new_len]); | 8020 | const elems_copy = try gpa.dupe(Index, elems[0..new_len]); |
| 7969 | defer gpa.free(elems_copy); | 8021 | defer gpa.free(elems_copy); |
| 7970 | return ip.get(gpa, .{ .aggregate = .{ | 8022 | return ip.get(gpa, tid, .{ .aggregate = .{ |
| 7971 | .ty = new_ty, | 8023 | .ty = new_ty, |
| 7972 | .storage = .{ .elems = elems_copy }, | 8024 | .storage = .{ .elems = elems_copy }, |
| 7973 | } }); | 8025 | } }); |
| 7974 | }, | 8026 | }, |
| 7975 | .repeated_elem => |elem| { | 8027 | .repeated_elem => |elem| { |
| 7976 | return ip.get(gpa, .{ .aggregate = .{ | 8028 | return ip.get(gpa, tid, .{ .aggregate = .{ |
| 7977 | .ty = new_ty, | 8029 | .ty = new_ty, |
| 7978 | .storage = .{ .repeated_elem = elem }, | 8030 | .storage = .{ .repeated_elem = elem }, |
| 7979 | } }); | 8031 | } }); |
| ... | @@ -7991,7 +8043,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -7991,7 +8043,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 7991 | // We have to intern each value here, so unfortunately we can't easily avoid | 8043 | // We have to intern each value here, so unfortunately we can't easily avoid |
| 7992 | // the repeated indexToKey calls. | 8044 | // the repeated indexToKey calls. |
| 7993 | for (agg_elems, 0..) |*elem, index| { | 8045 | for (agg_elems, 0..) |*elem, index| { |
| 7994 | elem.* = try ip.get(gpa, .{ .int = .{ | 8046 | elem.* = try ip.get(gpa, tid, .{ .int = .{ |
| 7995 | .ty = .u8_type, | 8047 | .ty = .u8_type, |
| 7996 | .storage = .{ .u64 = bytes.at(index, ip) }, | 8048 | .storage = .{ .u64 = bytes.at(index, ip) }, |
| 7997 | } }); | 8049 | } }); |
| ... | @@ -8008,27 +8060,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -8008,27 +8060,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 8008 | .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i], | 8060 | .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i], |
| 8009 | else => unreachable, | 8061 | else => unreachable, |
| 8010 | }; | 8062 | }; |
| 8011 | elem.* = try ip.getCoerced(gpa, elem.*, new_elem_ty); | 8063 | elem.* = try ip.getCoerced(gpa, tid, elem.*, new_elem_ty); |
| 8012 | } | 8064 | } |
| 8013 | return ip.get(gpa, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } }); | 8065 | return ip.get(gpa, tid, .{ .aggregate = .{ .ty = new_ty, .storage = .{ .elems = agg_elems } } }); |
| 8014 | }, | 8066 | }, |
| 8015 | else => {}, | 8067 | else => {}, |
| 8016 | } | 8068 | } |
| 8017 | 8069 | ||
| 8018 | switch (ip.indexToKey(new_ty)) { | 8070 | switch (ip.indexToKey(new_ty)) { |
| 8019 | .opt_type => |child_type| switch (val) { | 8071 | .opt_type => |child_type| switch (val) { |
| 8020 | .null_value => return ip.get(gpa, .{ .opt = .{ | 8072 | .null_value => return ip.get(gpa, tid, .{ .opt = .{ |
| 8021 | .ty = new_ty, | 8073 | .ty = new_ty, |
| 8022 | .val = .none, | 8074 | .val = .none, |
| 8023 | } }), | 8075 | } }), |
| 8024 | else => return ip.get(gpa, .{ .opt = .{ | 8076 | else => return ip.get(gpa, tid, .{ .opt = .{ |
| 8025 | .ty = new_ty, | 8077 | .ty = new_ty, |
| 8026 | .val = try ip.getCoerced(gpa, val, child_type), | 8078 | .val = try ip.getCoerced(gpa, tid, val, child_type), |
| 8027 | } }), | 8079 | } }), |
| 8028 | }, | 8080 | }, |
| 8029 | .error_union_type => |error_union_type| return ip.get(gpa, .{ .error_union = .{ | 8081 | .error_union_type => |error_union_type| return ip.get(gpa, tid, .{ .error_union = .{ |
| 8030 | .ty = new_ty, | 8082 | .ty = new_ty, |
| 8031 | .val = .{ .payload = try ip.getCoerced(gpa, val, error_union_type.payload_type) }, | 8083 | .val = .{ .payload = try ip.getCoerced(gpa, tid, val, error_union_type.payload_type) }, |
| 8032 | } }), | 8084 | } }), |
| 8033 | else => {}, | 8085 | else => {}, |
| 8034 | } | 8086 | } |
| ... | @@ -8042,27 +8094,45 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -8042,27 +8094,45 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 8042 | unreachable; | 8094 | unreachable; |
| 8043 | } | 8095 | } |
| 8044 | 8096 | ||
| 8045 | fn getCoercedFuncDecl(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { | 8097 | fn getCoercedFuncDecl( |
| 8098 | ip: *InternPool, | ||
| 8099 | gpa: Allocator, | ||
| 8100 | tid: Zcu.PerThread.Id, | ||
| 8101 | val: Index, | ||
| 8102 | new_ty: Index, | ||
| 8103 | ) Allocator.Error!Index { | ||
| 8046 | const datas = ip.items.items(.data); | 8104 | const datas = ip.items.items(.data); |
| 8047 | const extra_index = datas[@intFromEnum(val)]; | 8105 | const extra_index = datas[@intFromEnum(val)]; |
| 8048 | const prev_ty: Index = @enumFromInt( | 8106 | const prev_ty: Index = @enumFromInt( |
| 8049 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?], | 8107 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?], |
| 8050 | ); | 8108 | ); |
| 8051 | if (new_ty == prev_ty) return val; | 8109 | if (new_ty == prev_ty) return val; |
| 8052 | return getCoercedFunc(ip, gpa, val, new_ty); | 8110 | return getCoercedFunc(ip, gpa, tid, val, new_ty); |
| 8053 | } | 8111 | } |
| 8054 | 8112 | ||
| 8055 | fn getCoercedFuncInstance(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { | 8113 | fn getCoercedFuncInstance( |
| 8114 | ip: *InternPool, | ||
| 8115 | gpa: Allocator, | ||
| 8116 | tid: Zcu.PerThread.Id, | ||
| 8117 | val: Index, | ||
| 8118 | new_ty: Index, | ||
| 8119 | ) Allocator.Error!Index { | ||
| 8056 | const datas = ip.items.items(.data); | 8120 | const datas = ip.items.items(.data); |
| 8057 | const extra_index = datas[@intFromEnum(val)]; | 8121 | const extra_index = datas[@intFromEnum(val)]; |
| 8058 | const prev_ty: Index = @enumFromInt( | 8122 | const prev_ty: Index = @enumFromInt( |
| 8059 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?], | 8123 | ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?], |
| 8060 | ); | 8124 | ); |
| 8061 | if (new_ty == prev_ty) return val; | 8125 | if (new_ty == prev_ty) return val; |
| 8062 | return getCoercedFunc(ip, gpa, val, new_ty); | 8126 | return getCoercedFunc(ip, gpa, tid, val, new_ty); |
| 8063 | } | 8127 | } |
| 8064 | 8128 | ||
| 8065 | fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Allocator.Error!Index { | 8129 | fn getCoercedFunc( |
| 8130 | ip: *InternPool, | ||
| 8131 | gpa: Allocator, | ||
| 8132 | _: Zcu.PerThread.Id, | ||
| 8133 | func: Index, | ||
| 8134 | ty: Index, | ||
| 8135 | ) Allocator.Error!Index { | ||
| 8066 | const prev_extra_len = ip.extra.items.len; | 8136 | const prev_extra_len = ip.extra.items.len; |
| 8067 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len); | 8137 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len); |
| 8068 | try ip.items.ensureUnusedCapacity(gpa, 1); | 8138 | try ip.items.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -8092,7 +8162,7 @@ fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Alloc | ... | @@ -8092,7 +8162,7 @@ fn getCoercedFunc(ip: *InternPool, gpa: Allocator, func: Index, ty: Index) Alloc |
| 8092 | 8162 | ||
| 8093 | /// Asserts `val` has an integer type. | 8163 | /// Asserts `val` has an integer type. |
| 8094 | /// Assumes `new_ty` is an integer type. | 8164 | /// Assumes `new_ty` is an integer type. |
| 8095 | pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Index) Allocator.Error!Index { | 8165 | pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, int: Key.Int, new_ty: Index) Allocator.Error!Index { |
| 8096 | // The key cannot be passed directly to `get`, otherwise in the case of | 8166 | // The key cannot be passed directly to `get`, otherwise in the case of |
| 8097 | // big_int storage, the limbs would be invalidated before they are read. | 8167 | // big_int storage, the limbs would be invalidated before they are read. |
| 8098 | // Here we pre-reserve the limbs to ensure that the logic in `addInt` will | 8168 | // Here we pre-reserve the limbs to ensure that the logic in `addInt` will |
| ... | @@ -8111,7 +8181,7 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind | ... | @@ -8111,7 +8181,7 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, int: Key.Int, new_ty: Ind |
| 8111 | } }; | 8181 | } }; |
| 8112 | }, | 8182 | }, |
| 8113 | }; | 8183 | }; |
| 8114 | return ip.get(gpa, .{ .int = .{ | 8184 | return ip.get(gpa, tid, .{ .int = .{ |
| 8115 | .ty = new_ty, | 8185 | .ty = new_ty, |
| 8116 | .storage = new_storage, | 8186 | .storage = new_storage, |
| 8117 | } }); | 8187 | } }); |
src/RangeSet.zig+15-17| ... | @@ -6,13 +6,11 @@ const InternPool = @import("InternPool.zig"); | ... | @@ -6,13 +6,11 @@ const InternPool = @import("InternPool.zig"); |
| 6 | const Type = @import("Type.zig"); | 6 | const Type = @import("Type.zig"); |
| 7 | const Value = @import("Value.zig"); | 7 | const Value = @import("Value.zig"); |
| 8 | const Zcu = @import("Zcu.zig"); | 8 | const Zcu = @import("Zcu.zig"); |
| 9 | /// Deprecated. | ||
| 10 | const Module = Zcu; | ||
| 11 | const RangeSet = @This(); | 9 | const RangeSet = @This(); |
| 12 | const LazySrcLoc = Zcu.LazySrcLoc; | 10 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 13 | 11 | ||
| 12 | pt: Zcu.PerThread, | ||
| 14 | ranges: std.ArrayList(Range), | 13 | ranges: std.ArrayList(Range), |
| 15 | module: *Module, | ||
| 16 | 14 | ||
| 17 | pub const Range = struct { | 15 | pub const Range = struct { |
| 18 | first: InternPool.Index, | 16 | first: InternPool.Index, |
| ... | @@ -20,10 +18,10 @@ pub const Range = struct { | ... | @@ -20,10 +18,10 @@ pub const Range = struct { |
| 20 | src: LazySrcLoc, | 18 | src: LazySrcLoc, |
| 21 | }; | 19 | }; |
| 22 | 20 | ||
| 23 | pub fn init(allocator: std.mem.Allocator, module: *Module) RangeSet { | 21 | pub fn init(allocator: std.mem.Allocator, pt: Zcu.PerThread) RangeSet { |
| 24 | return .{ | 22 | return .{ |
| 23 | .pt = pt, | ||
| 25 | .ranges = std.ArrayList(Range).init(allocator), | 24 | .ranges = std.ArrayList(Range).init(allocator), |
| 26 | .module = module, | ||
| 27 | }; | 25 | }; |
| 28 | } | 26 | } |
| 29 | 27 | ||
| ... | @@ -37,8 +35,8 @@ pub fn add( | ... | @@ -37,8 +35,8 @@ pub fn add( |
| 37 | last: InternPool.Index, | 35 | last: InternPool.Index, |
| 38 | src: LazySrcLoc, | 36 | src: LazySrcLoc, |
| 39 | ) !?LazySrcLoc { | 37 | ) !?LazySrcLoc { |
| 40 | const mod = self.module; | 38 | const pt = self.pt; |
| 41 | const ip = &mod.intern_pool; | 39 | const ip = &pt.zcu.intern_pool; |
| 42 | 40 | ||
| 43 | const ty = ip.typeOf(first); | 41 | const ty = ip.typeOf(first); |
| 44 | assert(ty == ip.typeOf(last)); | 42 | assert(ty == ip.typeOf(last)); |
| ... | @@ -47,8 +45,8 @@ pub fn add( | ... | @@ -47,8 +45,8 @@ pub fn add( |
| 47 | assert(ty == ip.typeOf(range.first)); | 45 | assert(ty == ip.typeOf(range.first)); |
| 48 | assert(ty == ip.typeOf(range.last)); | 46 | assert(ty == ip.typeOf(range.last)); |
| 49 | 47 | ||
| 50 | if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), mod) and | 48 | if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), pt) and |
| 51 | Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), mod)) | 49 | Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), pt)) |
| 52 | { | 50 | { |
| 53 | return range.src; // They overlap. | 51 | return range.src; // They overlap. |
| 54 | } | 52 | } |
| ... | @@ -63,20 +61,20 @@ pub fn add( | ... | @@ -63,20 +61,20 @@ pub fn add( |
| 63 | } | 61 | } |
| 64 | 62 | ||
| 65 | /// Assumes a and b do not overlap | 63 | /// Assumes a and b do not overlap |
| 66 | fn lessThan(mod: *Module, a: Range, b: Range) bool { | 64 | fn lessThan(pt: Zcu.PerThread, a: Range, b: Range) bool { |
| 67 | const ty = Type.fromInterned(mod.intern_pool.typeOf(a.first)); | 65 | const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(a.first)); |
| 68 | return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, mod); | 66 | return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, pt); |
| 69 | } | 67 | } |
| 70 | 68 | ||
| 71 | pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !bool { | 69 | pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !bool { |
| 72 | const mod = self.module; | 70 | const pt = self.pt; |
| 73 | const ip = &mod.intern_pool; | 71 | const ip = &pt.zcu.intern_pool; |
| 74 | assert(ip.typeOf(first) == ip.typeOf(last)); | 72 | assert(ip.typeOf(first) == ip.typeOf(last)); |
| 75 | 73 | ||
| 76 | if (self.ranges.items.len == 0) | 74 | if (self.ranges.items.len == 0) |
| 77 | return false; | 75 | return false; |
| 78 | 76 | ||
| 79 | std.mem.sort(Range, self.ranges.items, mod, lessThan); | 77 | std.mem.sort(Range, self.ranges.items, pt, lessThan); |
| 80 | 78 | ||
| 81 | if (self.ranges.items[0].first != first or | 79 | if (self.ranges.items[0].first != first or |
| 82 | self.ranges.items[self.ranges.items.len - 1].last != last) | 80 | self.ranges.items[self.ranges.items.len - 1].last != last) |
| ... | @@ -95,10 +93,10 @@ pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) ! | ... | @@ -95,10 +93,10 @@ pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) ! |
| 95 | const prev = self.ranges.items[i]; | 93 | const prev = self.ranges.items[i]; |
| 96 | 94 | ||
| 97 | // prev.last + 1 == cur.first | 95 | // prev.last + 1 == cur.first |
| 98 | try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, mod)); | 96 | try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, pt)); |
| 99 | try counter.addScalar(&counter, 1); | 97 | try counter.addScalar(&counter, 1); |
| 100 | 98 | ||
| 101 | const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, mod); | 99 | const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, pt); |
| 102 | if (!cur_start_int.eql(counter.toConst())) { | 100 | if (!cur_start_int.eql(counter.toConst())) { |
| 103 | return false; | 101 | return false; |
| 104 | } | 102 | } |
src/Sema.zig+2671-2297| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | //! Does type checking, comptime control flow, and safety-check generation. | 5 | //! Does type checking, comptime control flow, and safety-check generation. |
| 6 | //! This is the the heart of the Zig compiler. | 6 | //! This is the the heart of the Zig compiler. |
| 7 | 7 | ||
| 8 | mod: *Module, | 8 | pt: Zcu.PerThread, |
| 9 | /// Alias to `mod.gpa`. | 9 | /// Alias to `mod.gpa`. |
| 10 | gpa: Allocator, | 10 | gpa: Allocator, |
| 11 | /// Points to the temporary arena allocator of the Sema. | 11 | /// Points to the temporary arena allocator of the Sema. |
| ... | @@ -146,7 +146,7 @@ const ComptimeAlloc = struct { | ... | @@ -146,7 +146,7 @@ const ComptimeAlloc = struct { |
| 146 | fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex { | 146 | fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex { |
| 147 | const idx = sema.comptime_allocs.items.len; | 147 | const idx = sema.comptime_allocs.items.len; |
| 148 | try sema.comptime_allocs.append(sema.gpa, .{ | 148 | try sema.comptime_allocs.append(sema.gpa, .{ |
| 149 | .val = .{ .interned = try sema.mod.intern(.{ .undef = ty.toIntern() }) }, | 149 | .val = .{ .interned = try sema.pt.intern(.{ .undef = ty.toIntern() }) }, |
| 150 | .is_const = false, | 150 | .is_const = false, |
| 151 | .alignment = alignment, | 151 | .alignment = alignment, |
| 152 | .runtime_index = block.runtime_index, | 152 | .runtime_index = block.runtime_index, |
| ... | @@ -433,7 +433,7 @@ pub const Block = struct { | ... | @@ -433,7 +433,7 @@ pub const Block = struct { |
| 433 | 433 | ||
| 434 | fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void { | 434 | fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void { |
| 435 | const parent = msg orelse return; | 435 | const parent = msg orelse return; |
| 436 | const mod = sema.mod; | 436 | const pt = sema.pt; |
| 437 | const prefix = "expression is evaluated at comptime because "; | 437 | const prefix = "expression is evaluated at comptime because "; |
| 438 | switch (cr) { | 438 | switch (cr) { |
| 439 | .c_import => |ci| { | 439 | .c_import => |ci| { |
| ... | @@ -451,7 +451,7 @@ pub const Block = struct { | ... | @@ -451,7 +451,7 @@ pub const Block = struct { |
| 451 | ret_ty_src, | 451 | ret_ty_src, |
| 452 | parent, | 452 | parent, |
| 453 | prefix ++ "the function returns a comptime-only type '{}'", | 453 | prefix ++ "the function returns a comptime-only type '{}'", |
| 454 | .{rt.return_ty.fmt(mod)}, | 454 | .{rt.return_ty.fmt(pt)}, |
| 455 | ); | 455 | ); |
| 456 | try sema.explainWhyTypeIsComptime(parent, ret_ty_src, rt.return_ty); | 456 | try sema.explainWhyTypeIsComptime(parent, ret_ty_src, rt.return_ty); |
| 457 | }, | 457 | }, |
| ... | @@ -538,7 +538,7 @@ pub const Block = struct { | ... | @@ -538,7 +538,7 @@ pub const Block = struct { |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | pub fn wantSafety(block: *const Block) bool { | 540 | pub fn wantSafety(block: *const Block) bool { |
| 541 | return block.want_safety orelse switch (block.sema.mod.optimizeMode()) { | 541 | return block.want_safety orelse switch (block.sema.pt.zcu.optimizeMode()) { |
| 542 | .Debug => true, | 542 | .Debug => true, |
| 543 | .ReleaseSafe => true, | 543 | .ReleaseSafe => true, |
| 544 | .ReleaseFast => false, | 544 | .ReleaseFast => false, |
| ... | @@ -737,11 +737,12 @@ pub const Block = struct { | ... | @@ -737,11 +737,12 @@ pub const Block = struct { |
| 737 | 737 | ||
| 738 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref { | 738 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref { |
| 739 | const sema = block.sema; | 739 | const sema = block.sema; |
| 740 | const mod = sema.mod; | 740 | const pt = sema.pt; |
| 741 | const mod = pt.zcu; | ||
| 741 | return block.addInst(.{ | 742 | return block.addInst(.{ |
| 742 | .tag = if (block.float_mode == .optimized) .cmp_vector_optimized else .cmp_vector, | 743 | .tag = if (block.float_mode == .optimized) .cmp_vector_optimized else .cmp_vector, |
| 743 | .data = .{ .ty_pl = .{ | 744 | .data = .{ .ty_pl = .{ |
| 744 | .ty = Air.internedToRef((try mod.vectorType(.{ | 745 | .ty = Air.internedToRef((try pt.vectorType(.{ |
| 745 | .len = sema.typeOf(lhs).vectorLen(mod), | 746 | .len = sema.typeOf(lhs).vectorLen(mod), |
| 746 | .child = .bool_type, | 747 | .child = .bool_type, |
| 747 | })).toIntern()), | 748 | })).toIntern()), |
| ... | @@ -829,14 +830,14 @@ pub const Block = struct { | ... | @@ -829,14 +830,14 @@ pub const Block = struct { |
| 829 | } | 830 | } |
| 830 | 831 | ||
| 831 | pub fn ownerModule(block: Block) *Package.Module { | 832 | pub fn ownerModule(block: Block) *Package.Module { |
| 832 | const zcu = block.sema.mod; | 833 | const zcu = block.sema.pt.zcu; |
| 833 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod; | 834 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod; |
| 834 | } | 835 | } |
| 835 | 836 | ||
| 836 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { | 837 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { |
| 837 | const sema = block.sema; | 838 | const sema = block.sema; |
| 838 | const gpa = sema.gpa; | 839 | const gpa = sema.gpa; |
| 839 | const zcu = sema.mod; | 840 | const zcu = sema.pt.zcu; |
| 840 | const ip = &zcu.intern_pool; | 841 | const ip = &zcu.intern_pool; |
| 841 | const file_index = block.getFileScopeIndex(zcu); | 842 | const file_index = block.getFileScopeIndex(zcu); |
| 842 | return ip.trackZir(gpa, file_index, inst); | 843 | return ip.trackZir(gpa, file_index, inst); |
| ... | @@ -992,7 +993,8 @@ fn analyzeBodyInner( | ... | @@ -992,7 +993,8 @@ fn analyzeBodyInner( |
| 992 | 993 | ||
| 993 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); | 994 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); |
| 994 | 995 | ||
| 995 | const zcu = sema.mod; | 996 | const pt = sema.pt; |
| 997 | const zcu = pt.zcu; | ||
| 996 | const map = &sema.inst_map; | 998 | const map = &sema.inst_map; |
| 997 | const tags = sema.code.instructions.items(.tag); | 999 | const tags = sema.code.instructions.items(.tag); |
| 998 | const datas = sema.code.instructions.items(.data); | 1000 | const datas = sema.code.instructions.items(.data); |
| ... | @@ -1777,7 +1779,7 @@ fn analyzeBodyInner( | ... | @@ -1777,7 +1779,7 @@ fn analyzeBodyInner( |
| 1777 | const err_union_ty = sema.typeOf(err_union); | 1779 | const err_union_ty = sema.typeOf(err_union); |
| 1778 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { | 1780 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { |
| 1779 | return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ | 1781 | return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ |
| 1780 | err_union_ty.fmt(zcu), | 1782 | err_union_ty.fmt(pt), |
| 1781 | }); | 1783 | }); |
| 1782 | } | 1784 | } |
| 1783 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); | 1785 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| ... | @@ -1910,10 +1912,11 @@ pub fn toConstString( | ... | @@ -1910,10 +1912,11 @@ pub fn toConstString( |
| 1910 | air_inst: Air.Inst.Ref, | 1912 | air_inst: Air.Inst.Ref, |
| 1911 | reason: NeededComptimeReason, | 1913 | reason: NeededComptimeReason, |
| 1912 | ) ![]u8 { | 1914 | ) ![]u8 { |
| 1915 | const pt = sema.pt; | ||
| 1913 | const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src); | 1916 | const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src); |
| 1914 | const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 1917 | const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| 1915 | const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason); | 1918 | const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason); |
| 1916 | return arr_val.toAllocatedBytes(arr_val.typeOf(sema.mod), sema.arena, sema.mod); | 1919 | return arr_val.toAllocatedBytes(arr_val.typeOf(pt.zcu), sema.arena, pt); |
| 1917 | } | 1920 | } |
| 1918 | 1921 | ||
| 1919 | pub fn resolveConstStringIntern( | 1922 | pub fn resolveConstStringIntern( |
| ... | @@ -1945,7 +1948,8 @@ fn resolveDestType( | ... | @@ -1945,7 +1948,8 @@ fn resolveDestType( |
| 1945 | strat: enum { remove_eu_opt, remove_eu, remove_opt }, | 1948 | strat: enum { remove_eu_opt, remove_eu, remove_opt }, |
| 1946 | builtin_name: []const u8, | 1949 | builtin_name: []const u8, |
| 1947 | ) !Type { | 1950 | ) !Type { |
| 1948 | const mod = sema.mod; | 1951 | const pt = sema.pt; |
| 1952 | const mod = pt.zcu; | ||
| 1949 | const remove_eu = switch (strat) { | 1953 | const remove_eu = switch (strat) { |
| 1950 | .remove_eu_opt, .remove_eu => true, | 1954 | .remove_eu_opt, .remove_eu => true, |
| 1951 | .remove_opt => false, | 1955 | .remove_opt => false, |
| ... | @@ -2062,7 +2066,8 @@ fn analyzeAsType( | ... | @@ -2062,7 +2066,8 @@ fn analyzeAsType( |
| 2062 | } | 2066 | } |
| 2063 | 2067 | ||
| 2064 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { | 2068 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { |
| 2065 | const mod = sema.mod; | 2069 | const pt = sema.pt; |
| 2070 | const mod = pt.zcu; | ||
| 2066 | const comp = mod.comp; | 2071 | const comp = mod.comp; |
| 2067 | const gpa = sema.gpa; | 2072 | const gpa = sema.gpa; |
| 2068 | const ip = &mod.intern_pool; | 2073 | const ip = &mod.intern_pool; |
| ... | @@ -2076,16 +2081,16 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) | ... | @@ -2076,16 +2081,16 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 2076 | 2081 | ||
| 2077 | // var addrs: [err_return_trace_addr_count]usize = undefined; | 2082 | // var addrs: [err_return_trace_addr_count]usize = undefined; |
| 2078 | const err_return_trace_addr_count = 32; | 2083 | const err_return_trace_addr_count = 32; |
| 2079 | const addr_arr_ty = try mod.arrayType(.{ | 2084 | const addr_arr_ty = try pt.arrayType(.{ |
| 2080 | .len = err_return_trace_addr_count, | 2085 | .len = err_return_trace_addr_count, |
| 2081 | .child = .usize_type, | 2086 | .child = .usize_type, |
| 2082 | }); | 2087 | }); |
| 2083 | const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty)); | 2088 | const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty)); |
| 2084 | 2089 | ||
| 2085 | // var st: StackTrace = undefined; | 2090 | // var st: StackTrace = undefined; |
| 2086 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 2091 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 2087 | try stack_trace_ty.resolveFields(mod); | 2092 | try stack_trace_ty.resolveFields(pt); |
| 2088 | const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty)); | 2093 | const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty)); |
| 2089 | 2094 | ||
| 2090 | // st.instruction_addresses = &addrs; | 2095 | // st.instruction_addresses = &addrs; |
| 2091 | const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses", .no_embedded_nulls); | 2096 | const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses", .no_embedded_nulls); |
| ... | @@ -2109,7 +2114,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) | ... | @@ -2109,7 +2114,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 2109 | fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { | 2114 | fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2110 | const val = (try sema.resolveValueAllowVariables(inst)) orelse return null; | 2115 | const val = (try sema.resolveValueAllowVariables(inst)) orelse return null; |
| 2111 | if (val.isGenericPoison()) return error.GenericPoison; | 2116 | if (val.isGenericPoison()) return error.GenericPoison; |
| 2112 | if (sema.mod.intern_pool.isVariable(val.toIntern())) return null; | 2117 | if (sema.pt.zcu.intern_pool.isVariable(val.toIntern())) return null; |
| 2113 | return val; | 2118 | return val; |
| 2114 | } | 2119 | } |
| 2115 | 2120 | ||
| ... | @@ -2133,7 +2138,8 @@ fn resolveDefinedValue( | ... | @@ -2133,7 +2138,8 @@ fn resolveDefinedValue( |
| 2133 | src: LazySrcLoc, | 2138 | src: LazySrcLoc, |
| 2134 | air_ref: Air.Inst.Ref, | 2139 | air_ref: Air.Inst.Ref, |
| 2135 | ) CompileError!?Value { | 2140 | ) CompileError!?Value { |
| 2136 | const mod = sema.mod; | 2141 | const pt = sema.pt; |
| 2142 | const mod = pt.zcu; | ||
| 2137 | const val = try sema.resolveValue(air_ref) orelse return null; | 2143 | const val = try sema.resolveValue(air_ref) orelse return null; |
| 2138 | if (val.isUndef(mod)) { | 2144 | if (val.isUndef(mod)) { |
| 2139 | return sema.failWithUseOfUndef(block, src); | 2145 | return sema.failWithUseOfUndef(block, src); |
| ... | @@ -2150,7 +2156,7 @@ fn resolveConstDefinedValue( | ... | @@ -2150,7 +2156,7 @@ fn resolveConstDefinedValue( |
| 2150 | reason: NeededComptimeReason, | 2156 | reason: NeededComptimeReason, |
| 2151 | ) CompileError!Value { | 2157 | ) CompileError!Value { |
| 2152 | const val = try sema.resolveConstValue(block, src, air_ref, reason); | 2158 | const val = try sema.resolveConstValue(block, src, air_ref, reason); |
| 2153 | if (val.isUndef(sema.mod)) return sema.failWithUseOfUndef(block, src); | 2159 | if (val.isUndef(sema.pt.zcu)) return sema.failWithUseOfUndef(block, src); |
| 2154 | return val; | 2160 | return val; |
| 2155 | } | 2161 | } |
| 2156 | 2162 | ||
| ... | @@ -2164,7 +2170,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value | ... | @@ -2164,7 +2170,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value |
| 2164 | /// Lazy values are recursively resolved. | 2170 | /// Lazy values are recursively resolved. |
| 2165 | fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { | 2171 | fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2166 | const val = (try sema.resolveValue(inst)) orelse return null; | 2172 | const val = (try sema.resolveValue(inst)) orelse return null; |
| 2167 | if (sema.mod.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) { | 2173 | if (sema.pt.zcu.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) { |
| 2168 | .decl, .anon_decl, .comptime_alloc, .comptime_field => return null, | 2174 | .decl, .anon_decl, .comptime_alloc, .comptime_field => return null, |
| 2169 | .int => {}, | 2175 | .int => {}, |
| 2170 | .eu_payload, .opt_payload, .arr_elem, .field => unreachable, | 2176 | .eu_payload, .opt_payload, .arr_elem, .field => unreachable, |
| ... | @@ -2174,6 +2180,7 @@ fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { | ... | @@ -2174,6 +2180,7 @@ fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2174 | 2180 | ||
| 2175 | /// Returns all InternPool keys representing values, including `variable`, `undef`, and `generic_poison`. | 2181 | /// Returns all InternPool keys representing values, including `variable`, `undef`, and `generic_poison`. |
| 2176 | fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { | 2182 | fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { |
| 2183 | const pt = sema.pt; | ||
| 2177 | assert(inst != .none); | 2184 | assert(inst != .none); |
| 2178 | // First section of indexes correspond to a set number of constant values. | 2185 | // First section of indexes correspond to a set number of constant values. |
| 2179 | if (@intFromEnum(inst) < InternPool.static_len) { | 2186 | if (@intFromEnum(inst) < InternPool.static_len) { |
| ... | @@ -2184,7 +2191,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val | ... | @@ -2184,7 +2191,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val |
| 2184 | if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| { | 2191 | if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| { |
| 2185 | if (inst.toInterned()) |ip_index| { | 2192 | if (inst.toInterned()) |ip_index| { |
| 2186 | const val = Value.fromInterned(ip_index); | 2193 | const val = Value.fromInterned(ip_index); |
| 2187 | if (val.getVariable(sema.mod) != null) return val; | 2194 | if (val.getVariable(pt.zcu) != null) return val; |
| 2188 | } | 2195 | } |
| 2189 | return opv; | 2196 | return opv; |
| 2190 | } | 2197 | } |
| ... | @@ -2196,7 +2203,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val | ... | @@ -2196,7 +2203,7 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val |
| 2196 | } | 2203 | } |
| 2197 | }; | 2204 | }; |
| 2198 | const val = Value.fromInterned(ip_index); | 2205 | const val = Value.fromInterned(ip_index); |
| 2199 | if (val.isPtrToThreadLocal(sema.mod)) return null; | 2206 | if (val.isPtrToThreadLocal(pt.zcu)) return null; |
| 2200 | return val; | 2207 | return val; |
| 2201 | } | 2208 | } |
| 2202 | 2209 | ||
| ... | @@ -2225,7 +2232,7 @@ pub fn resolveFinalDeclValue( | ... | @@ -2225,7 +2232,7 @@ pub fn resolveFinalDeclValue( |
| 2225 | }); | 2232 | }); |
| 2226 | }; | 2233 | }; |
| 2227 | if (val.isGenericPoison()) return error.GenericPoison; | 2234 | if (val.isGenericPoison()) return error.GenericPoison; |
| 2228 | if (val.canMutateComptimeVarState(sema.mod)) { | 2235 | if (val.canMutateComptimeVarState(sema.pt.zcu)) { |
| 2229 | return sema.fail(block, src, "global variable contains reference to comptime var", .{}); | 2236 | return sema.fail(block, src, "global variable contains reference to comptime var", .{}); |
| 2230 | } | 2237 | } |
| 2231 | return val; | 2238 | return val; |
| ... | @@ -2254,19 +2261,20 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro | ... | @@ -2254,19 +2261,20 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro |
| 2254 | } | 2261 | } |
| 2255 | 2262 | ||
| 2256 | fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { | 2263 | fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { |
| 2264 | const pt = sema.pt; | ||
| 2257 | return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ | 2265 | return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ |
| 2258 | lhs_ty.fmt(sema.mod), rhs_ty.fmt(sema.mod), | 2266 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 2259 | }); | 2267 | }); |
| 2260 | } | 2268 | } |
| 2261 | 2269 | ||
| 2262 | fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError { | 2270 | fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError { |
| 2263 | const mod = sema.mod; | 2271 | const pt = sema.pt; |
| 2264 | const msg = msg: { | 2272 | const msg = msg: { |
| 2265 | const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{ | 2273 | const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{ |
| 2266 | non_optional_ty.fmt(mod), | 2274 | non_optional_ty.fmt(pt), |
| 2267 | }); | 2275 | }); |
| 2268 | errdefer msg.destroy(sema.gpa); | 2276 | errdefer msg.destroy(sema.gpa); |
| 2269 | if (non_optional_ty.zigTypeTag(mod) == .ErrorUnion) { | 2277 | if (non_optional_ty.zigTypeTag(pt.zcu) == .ErrorUnion) { |
| 2270 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); | 2278 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 2271 | } | 2279 | } |
| 2272 | try addDeclaredHereNote(sema, msg, non_optional_ty); | 2280 | try addDeclaredHereNote(sema, msg, non_optional_ty); |
| ... | @@ -2276,14 +2284,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non | ... | @@ -2276,14 +2284,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non |
| 2276 | } | 2284 | } |
| 2277 | 2285 | ||
| 2278 | fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { | 2286 | fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { |
| 2279 | const mod = sema.mod; | 2287 | const pt = sema.pt; |
| 2280 | const msg = msg: { | 2288 | const msg = msg: { |
| 2281 | const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{ | 2289 | const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{ |
| 2282 | ty.fmt(mod), | 2290 | ty.fmt(pt), |
| 2283 | }); | 2291 | }); |
| 2284 | errdefer msg.destroy(sema.gpa); | 2292 | errdefer msg.destroy(sema.gpa); |
| 2285 | if (ty.isSlice(mod)) { | 2293 | if (ty.isSlice(pt.zcu)) { |
| 2286 | try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)}); | 2294 | try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(pt.zcu).fmt(pt)}); |
| 2287 | } | 2295 | } |
| 2288 | break :msg msg; | 2296 | break :msg msg; |
| 2289 | }; | 2297 | }; |
| ... | @@ -2291,8 +2299,9 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty | ... | @@ -2291,8 +2299,9 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty |
| 2291 | } | 2299 | } |
| 2292 | 2300 | ||
| 2293 | fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { | 2301 | fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { |
| 2302 | const pt = sema.pt; | ||
| 2294 | return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ | 2303 | return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ |
| 2295 | ty.fmt(sema.mod), | 2304 | ty.fmt(pt), |
| 2296 | }); | 2305 | }); |
| 2297 | } | 2306 | } |
| 2298 | 2307 | ||
| ... | @@ -2303,17 +2312,19 @@ fn failWithErrorSetCodeMissing( | ... | @@ -2303,17 +2312,19 @@ fn failWithErrorSetCodeMissing( |
| 2303 | dest_err_set_ty: Type, | 2312 | dest_err_set_ty: Type, |
| 2304 | src_err_set_ty: Type, | 2313 | src_err_set_ty: Type, |
| 2305 | ) CompileError { | 2314 | ) CompileError { |
| 2315 | const pt = sema.pt; | ||
| 2306 | return sema.fail(block, src, "expected type '{}', found type '{}'", .{ | 2316 | return sema.fail(block, src, "expected type '{}', found type '{}'", .{ |
| 2307 | dest_err_set_ty.fmt(sema.mod), src_err_set_ty.fmt(sema.mod), | 2317 | dest_err_set_ty.fmt(pt), src_err_set_ty.fmt(pt), |
| 2308 | }); | 2318 | }); |
| 2309 | } | 2319 | } |
| 2310 | 2320 | ||
| 2311 | fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError { | 2321 | fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError { |
| 2312 | const zcu = sema.mod; | 2322 | const pt = sema.pt; |
| 2323 | const zcu = pt.zcu; | ||
| 2313 | if (int_ty.zigTypeTag(zcu) == .Vector) { | 2324 | if (int_ty.zigTypeTag(zcu) == .Vector) { |
| 2314 | const msg = msg: { | 2325 | const msg = msg: { |
| 2315 | const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{ | 2326 | const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{ |
| 2316 | int_ty.fmt(zcu), val.fmtValue(zcu, sema), | 2327 | int_ty.fmt(pt), val.fmtValue(pt, sema), |
| 2317 | }); | 2328 | }); |
| 2318 | errdefer msg.destroy(sema.gpa); | 2329 | errdefer msg.destroy(sema.gpa); |
| 2319 | try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index}); | 2330 | try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index}); |
| ... | @@ -2322,12 +2333,13 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: | ... | @@ -2322,12 +2333,13 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: |
| 2322 | return sema.failWithOwnedErrorMsg(block, msg); | 2333 | return sema.failWithOwnedErrorMsg(block, msg); |
| 2323 | } | 2334 | } |
| 2324 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ | 2335 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ |
| 2325 | int_ty.fmt(zcu), val.fmtValue(zcu, sema), | 2336 | int_ty.fmt(pt), val.fmtValue(pt, sema), |
| 2326 | }); | 2337 | }); |
| 2327 | } | 2338 | } |
| 2328 | 2339 | ||
| 2329 | fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError { | 2340 | fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError { |
| 2330 | const mod = sema.mod; | 2341 | const pt = sema.pt; |
| 2342 | const mod = pt.zcu; | ||
| 2331 | const msg = msg: { | 2343 | const msg = msg: { |
| 2332 | const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{}); | 2344 | const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{}); |
| 2333 | errdefer msg.destroy(sema.gpa); | 2345 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -2358,14 +2370,15 @@ fn failWithInvalidFieldAccess( | ... | @@ -2358,14 +2370,15 @@ fn failWithInvalidFieldAccess( |
| 2358 | object_ty: Type, | 2370 | object_ty: Type, |
| 2359 | field_name: InternPool.NullTerminatedString, | 2371 | field_name: InternPool.NullTerminatedString, |
| 2360 | ) CompileError { | 2372 | ) CompileError { |
| 2361 | const mod = sema.mod; | 2373 | const pt = sema.pt; |
| 2374 | const mod = pt.zcu; | ||
| 2362 | const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty; | 2375 | const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty; |
| 2363 | 2376 | ||
| 2364 | if (inner_ty.zigTypeTag(mod) == .Optional) opt: { | 2377 | if (inner_ty.zigTypeTag(mod) == .Optional) opt: { |
| 2365 | const child_ty = inner_ty.optionalChild(mod); | 2378 | const child_ty = inner_ty.optionalChild(mod); |
| 2366 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt; | 2379 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt; |
| 2367 | const msg = msg: { | 2380 | const msg = msg: { |
| 2368 | const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); | 2381 | const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2369 | errdefer msg.destroy(sema.gpa); | 2382 | errdefer msg.destroy(sema.gpa); |
| 2370 | try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{}); | 2383 | try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{}); |
| 2371 | break :msg msg; | 2384 | break :msg msg; |
| ... | @@ -2375,14 +2388,14 @@ fn failWithInvalidFieldAccess( | ... | @@ -2375,14 +2388,14 @@ fn failWithInvalidFieldAccess( |
| 2375 | const child_ty = inner_ty.errorUnionPayload(mod); | 2388 | const child_ty = inner_ty.errorUnionPayload(mod); |
| 2376 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err; | 2389 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err; |
| 2377 | const msg = msg: { | 2390 | const msg = msg: { |
| 2378 | const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); | 2391 | const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2379 | errdefer msg.destroy(sema.gpa); | 2392 | errdefer msg.destroy(sema.gpa); |
| 2380 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); | 2393 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 2381 | break :msg msg; | 2394 | break :msg msg; |
| 2382 | }; | 2395 | }; |
| 2383 | return sema.failWithOwnedErrorMsg(block, msg); | 2396 | return sema.failWithOwnedErrorMsg(block, msg); |
| 2384 | } | 2397 | } |
| 2385 | return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); | 2398 | return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2386 | } | 2399 | } |
| 2387 | 2400 | ||
| 2388 | fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool { | 2401 | fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool { |
| ... | @@ -2408,7 +2421,8 @@ fn failWithComptimeErrorRetTrace( | ... | @@ -2408,7 +2421,8 @@ fn failWithComptimeErrorRetTrace( |
| 2408 | src: LazySrcLoc, | 2421 | src: LazySrcLoc, |
| 2409 | name: InternPool.NullTerminatedString, | 2422 | name: InternPool.NullTerminatedString, |
| 2410 | ) CompileError { | 2423 | ) CompileError { |
| 2411 | const mod = sema.mod; | 2424 | const pt = sema.pt; |
| 2425 | const mod = pt.zcu; | ||
| 2412 | const msg = msg: { | 2426 | const msg = msg: { |
| 2413 | const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)}); | 2427 | const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)}); |
| 2414 | errdefer msg.destroy(sema.gpa); | 2428 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -2430,7 +2444,7 @@ pub fn errNote( | ... | @@ -2430,7 +2444,7 @@ pub fn errNote( |
| 2430 | comptime format: []const u8, | 2444 | comptime format: []const u8, |
| 2431 | args: anytype, | 2445 | args: anytype, |
| 2432 | ) error{OutOfMemory}!void { | 2446 | ) error{OutOfMemory}!void { |
| 2433 | return sema.mod.errNote(src, parent, format, args); | 2447 | return sema.pt.zcu.errNote(src, parent, format, args); |
| 2434 | } | 2448 | } |
| 2435 | 2449 | ||
| 2436 | fn addFieldErrNote( | 2450 | fn addFieldErrNote( |
| ... | @@ -2442,8 +2456,7 @@ fn addFieldErrNote( | ... | @@ -2442,8 +2456,7 @@ fn addFieldErrNote( |
| 2442 | args: anytype, | 2456 | args: anytype, |
| 2443 | ) !void { | 2457 | ) !void { |
| 2444 | @setCold(true); | 2458 | @setCold(true); |
| 2445 | const zcu = sema.mod; | 2459 | const type_src = container_ty.srcLocOrNull(sema.pt.zcu) orelse return; |
| 2446 | const type_src = container_ty.srcLocOrNull(zcu) orelse return; | ||
| 2447 | const field_src: LazySrcLoc = .{ | 2460 | const field_src: LazySrcLoc = .{ |
| 2448 | .base_node_inst = type_src.base_node_inst, | 2461 | .base_node_inst = type_src.base_node_inst, |
| 2449 | .offset = .{ .container_field_name = @intCast(field_index) }, | 2462 | .offset = .{ .container_field_name = @intCast(field_index) }, |
| ... | @@ -2480,7 +2493,7 @@ pub fn fail( | ... | @@ -2480,7 +2493,7 @@ pub fn fail( |
| 2480 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) error{ AnalysisFail, OutOfMemory } { | 2493 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) error{ AnalysisFail, OutOfMemory } { |
| 2481 | @setCold(true); | 2494 | @setCold(true); |
| 2482 | const gpa = sema.gpa; | 2495 | const gpa = sema.gpa; |
| 2483 | const mod = sema.mod; | 2496 | const mod = sema.pt.zcu; |
| 2484 | const ip = &mod.intern_pool; | 2497 | const ip = &mod.intern_pool; |
| 2485 | 2498 | ||
| 2486 | if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) { | 2499 | if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) { |
| ... | @@ -2545,8 +2558,7 @@ fn reparentOwnedErrorMsg( | ... | @@ -2545,8 +2558,7 @@ fn reparentOwnedErrorMsg( |
| 2545 | comptime format: []const u8, | 2558 | comptime format: []const u8, |
| 2546 | args: anytype, | 2559 | args: anytype, |
| 2547 | ) !void { | 2560 | ) !void { |
| 2548 | const mod = sema.mod; | 2561 | const msg_str = try std.fmt.allocPrint(sema.gpa, format, args); |
| 2549 | const msg_str = try std.fmt.allocPrint(mod.gpa, format, args); | ||
| 2550 | 2562 | ||
| 2551 | const orig_notes = msg.notes.len; | 2563 | const orig_notes = msg.notes.len; |
| 2552 | msg.notes = try sema.gpa.realloc(msg.notes, orig_notes + 1); | 2564 | msg.notes = try sema.gpa.realloc(msg.notes, orig_notes + 1); |
| ... | @@ -2630,16 +2642,16 @@ fn analyzeAsInt( | ... | @@ -2630,16 +2642,16 @@ fn analyzeAsInt( |
| 2630 | dest_ty: Type, | 2642 | dest_ty: Type, |
| 2631 | reason: NeededComptimeReason, | 2643 | reason: NeededComptimeReason, |
| 2632 | ) !u64 { | 2644 | ) !u64 { |
| 2633 | const mod = sema.mod; | ||
| 2634 | const coerced = try sema.coerce(block, dest_ty, air_ref, src); | 2645 | const coerced = try sema.coerce(block, dest_ty, air_ref, src); |
| 2635 | const val = try sema.resolveConstDefinedValue(block, src, coerced, reason); | 2646 | const val = try sema.resolveConstDefinedValue(block, src, coerced, reason); |
| 2636 | return (try val.getUnsignedIntAdvanced(mod, .sema)).?; | 2647 | return (try val.getUnsignedIntAdvanced(sema.pt, .sema)).?; |
| 2637 | } | 2648 | } |
| 2638 | 2649 | ||
| 2639 | /// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`, | 2650 | /// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`, |
| 2640 | /// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`. | 2651 | /// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`. |
| 2641 | fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue { | 2652 | fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue { |
| 2642 | const zcu = sema.mod; | 2653 | const pt = sema.pt; |
| 2654 | const zcu = pt.zcu; | ||
| 2643 | const ip = &zcu.intern_pool; | 2655 | const ip = &zcu.intern_pool; |
| 2644 | const parent_captures: InternPool.CaptureValue.Slice = zcu.namespacePtr(block.namespace).getType(zcu).getCaptures(zcu); | 2656 | const parent_captures: InternPool.CaptureValue.Slice = zcu.namespacePtr(block.namespace).getType(zcu).getCaptures(zcu); |
| 2645 | 2657 | ||
| ... | @@ -2706,7 +2718,7 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { | ... | @@ -2706,7 +2718,7 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { |
| 2706 | if (sema.builtin_type_target_index == .none) return wip_ty; | 2718 | if (sema.builtin_type_target_index == .none) return wip_ty; |
| 2707 | var new = wip_ty; | 2719 | var new = wip_ty; |
| 2708 | new.index = sema.builtin_type_target_index; | 2720 | new.index = sema.builtin_type_target_index; |
| 2709 | sema.mod.intern_pool.resolveBuiltinType(new.index, wip_ty.index); | 2721 | sema.pt.zcu.intern_pool.resolveBuiltinType(new.index, wip_ty.index); |
| 2710 | return new; | 2722 | return new; |
| 2711 | } | 2723 | } |
| 2712 | 2724 | ||
| ... | @@ -2714,7 +2726,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { | ... | @@ -2714,7 +2726,8 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) { |
| 2714 | /// considered outdated on this update. If so, remove it from the pool | 2726 | /// considered outdated on this update. If so, remove it from the pool |
| 2715 | /// and return `true`. | 2727 | /// and return `true`. |
| 2716 | fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { | 2728 | fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { |
| 2717 | const zcu = sema.mod; | 2729 | const pt = sema.pt; |
| 2730 | const zcu = pt.zcu; | ||
| 2718 | 2731 | ||
| 2719 | if (!zcu.comp.debug_incremental) return false; | 2732 | if (!zcu.comp.debug_incremental) return false; |
| 2720 | 2733 | ||
| ... | @@ -2737,7 +2750,8 @@ fn zirStructDecl( | ... | @@ -2737,7 +2750,8 @@ fn zirStructDecl( |
| 2737 | extended: Zir.Inst.Extended.InstData, | 2750 | extended: Zir.Inst.Extended.InstData, |
| 2738 | inst: Zir.Inst.Index, | 2751 | inst: Zir.Inst.Index, |
| 2739 | ) CompileError!Air.Inst.Ref { | 2752 | ) CompileError!Air.Inst.Ref { |
| 2740 | const mod = sema.mod; | 2753 | const pt = sema.pt; |
| 2754 | const mod = pt.zcu; | ||
| 2741 | const gpa = sema.gpa; | 2755 | const gpa = sema.gpa; |
| 2742 | const ip = &mod.intern_pool; | 2756 | const ip = &mod.intern_pool; |
| 2743 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | 2757 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| ... | @@ -2796,10 +2810,10 @@ fn zirStructDecl( | ... | @@ -2796,10 +2810,10 @@ fn zirStructDecl( |
| 2796 | .captures = captures, | 2810 | .captures = captures, |
| 2797 | } }, | 2811 | } }, |
| 2798 | }; | 2812 | }; |
| 2799 | const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, struct_init)) { | 2813 | const wip_ty = sema.wrapWipTy(switch (try ip.getStructType(gpa, pt.tid, struct_init)) { |
| 2800 | .existing => |ty| wip: { | 2814 | .existing => |ty| wip: { |
| 2801 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); | 2815 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); |
| 2802 | break :wip (try ip.getStructType(gpa, struct_init)).wip; | 2816 | break :wip (try ip.getStructType(gpa, pt.tid, struct_init)).wip; |
| 2803 | }, | 2817 | }, |
| 2804 | .wip => |wip| wip, | 2818 | .wip => |wip| wip, |
| 2805 | }); | 2819 | }); |
| ... | @@ -2815,7 +2829,7 @@ fn zirStructDecl( | ... | @@ -2815,7 +2829,7 @@ fn zirStructDecl( |
| 2815 | mod.declPtr(new_decl_index).owns_tv = true; | 2829 | mod.declPtr(new_decl_index).owns_tv = true; |
| 2816 | errdefer mod.abortAnonDecl(new_decl_index); | 2830 | errdefer mod.abortAnonDecl(new_decl_index); |
| 2817 | 2831 | ||
| 2818 | if (sema.mod.comp.debug_incremental) { | 2832 | if (pt.zcu.comp.debug_incremental) { |
| 2819 | try ip.addDependency( | 2833 | try ip.addDependency( |
| 2820 | sema.gpa, | 2834 | sema.gpa, |
| 2821 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 2835 | AnalUnit.wrap(.{ .decl = new_decl_index }), |
| ... | @@ -2836,7 +2850,7 @@ fn zirStructDecl( | ... | @@ -2836,7 +2850,7 @@ fn zirStructDecl( |
| 2836 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | 2850 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); |
| 2837 | } | 2851 | } |
| 2838 | 2852 | ||
| 2839 | try mod.finalizeAnonDecl(new_decl_index); | 2853 | try pt.finalizeAnonDecl(new_decl_index); |
| 2840 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | 2854 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); |
| 2841 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 2855 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); |
| 2842 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 2856 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); |
| ... | @@ -2850,7 +2864,8 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2850,7 +2864,8 @@ fn createAnonymousDeclTypeNamed( |
| 2850 | anon_prefix: []const u8, | 2864 | anon_prefix: []const u8, |
| 2851 | inst: ?Zir.Inst.Index, | 2865 | inst: ?Zir.Inst.Index, |
| 2852 | ) !InternPool.DeclIndex { | 2866 | ) !InternPool.DeclIndex { |
| 2853 | const zcu = sema.mod; | 2867 | const pt = sema.pt; |
| 2868 | const zcu = pt.zcu; | ||
| 2854 | const ip = &zcu.intern_pool; | 2869 | const ip = &zcu.intern_pool; |
| 2855 | const gpa = sema.gpa; | 2870 | const gpa = sema.gpa; |
| 2856 | const namespace = block.namespace; | 2871 | const namespace = block.namespace; |
| ... | @@ -2892,7 +2907,7 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2892,7 +2907,7 @@ fn createAnonymousDeclTypeNamed( |
| 2892 | // some tooling may not support very long symbol names. | 2907 | // some tooling may not support very long symbol names. |
| 2893 | try writer.print("{}", .{Value.fmtValueFull(.{ | 2908 | try writer.print("{}", .{Value.fmtValueFull(.{ |
| 2894 | .val = arg_val, | 2909 | .val = arg_val, |
| 2895 | .mod = zcu, | 2910 | .pt = pt, |
| 2896 | .opt_sema = sema, | 2911 | .opt_sema = sema, |
| 2897 | .depth = 1, | 2912 | .depth = 1, |
| 2898 | })}); | 2913 | })}); |
| ... | @@ -2953,7 +2968,8 @@ fn zirEnumDecl( | ... | @@ -2953,7 +2968,8 @@ fn zirEnumDecl( |
| 2953 | const tracy = trace(@src()); | 2968 | const tracy = trace(@src()); |
| 2954 | defer tracy.end(); | 2969 | defer tracy.end(); |
| 2955 | 2970 | ||
| 2956 | const mod = sema.mod; | 2971 | const pt = sema.pt; |
| 2972 | const mod = pt.zcu; | ||
| 2957 | const gpa = sema.gpa; | 2973 | const gpa = sema.gpa; |
| 2958 | const ip = &mod.intern_pool; | 2974 | const ip = &mod.intern_pool; |
| 2959 | const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small); | 2975 | const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small); |
| ... | @@ -3026,10 +3042,10 @@ fn zirEnumDecl( | ... | @@ -3026,10 +3042,10 @@ fn zirEnumDecl( |
| 3026 | .captures = captures, | 3042 | .captures = captures, |
| 3027 | } }, | 3043 | } }, |
| 3028 | }; | 3044 | }; |
| 3029 | const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, enum_init)) { | 3045 | const wip_ty = sema.wrapWipTy(switch (try ip.getEnumType(gpa, pt.tid, enum_init)) { |
| 3030 | .existing => |ty| wip: { | 3046 | .existing => |ty| wip: { |
| 3031 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); | 3047 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); |
| 3032 | break :wip (try ip.getEnumType(gpa, enum_init)).wip; | 3048 | break :wip (try ip.getEnumType(gpa, pt.tid, enum_init)).wip; |
| 3033 | }, | 3049 | }, |
| 3034 | .wip => |wip| wip, | 3050 | .wip => |wip| wip, |
| 3035 | }); | 3051 | }); |
| ... | @@ -3051,7 +3067,7 @@ fn zirEnumDecl( | ... | @@ -3051,7 +3067,7 @@ fn zirEnumDecl( |
| 3051 | new_decl.owns_tv = true; | 3067 | new_decl.owns_tv = true; |
| 3052 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); | 3068 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); |
| 3053 | 3069 | ||
| 3054 | if (sema.mod.comp.debug_incremental) { | 3070 | if (pt.zcu.comp.debug_incremental) { |
| 3055 | try mod.intern_pool.addDependency( | 3071 | try mod.intern_pool.addDependency( |
| 3056 | gpa, | 3072 | gpa, |
| 3057 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 3073 | AnalUnit.wrap(.{ .decl = new_decl_index }), |
| ... | @@ -3118,21 +3134,21 @@ fn zirEnumDecl( | ... | @@ -3118,21 +3134,21 @@ fn zirEnumDecl( |
| 3118 | if (tag_type_ref != .none) { | 3134 | if (tag_type_ref != .none) { |
| 3119 | const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref); | 3135 | const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref); |
| 3120 | if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) { | 3136 | if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) { |
| 3121 | return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); | 3137 | return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)}); |
| 3122 | } | 3138 | } |
| 3123 | break :ty ty; | 3139 | break :ty ty; |
| 3124 | } else if (fields_len == 0) { | 3140 | } else if (fields_len == 0) { |
| 3125 | break :ty try mod.intType(.unsigned, 0); | 3141 | break :ty try pt.intType(.unsigned, 0); |
| 3126 | } else { | 3142 | } else { |
| 3127 | const bits = std.math.log2_int_ceil(usize, fields_len); | 3143 | const bits = std.math.log2_int_ceil(usize, fields_len); |
| 3128 | break :ty try mod.intType(.unsigned, bits); | 3144 | break :ty try pt.intType(.unsigned, bits); |
| 3129 | } | 3145 | } |
| 3130 | }; | 3146 | }; |
| 3131 | 3147 | ||
| 3132 | wip_ty.setTagTy(ip, int_tag_ty.toIntern()); | 3148 | wip_ty.setTagTy(ip, int_tag_ty.toIntern()); |
| 3133 | 3149 | ||
| 3134 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { | 3150 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { |
| 3135 | if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(mod)) { | 3151 | if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(pt)) { |
| 3136 | return sema.fail(block, src, "non-exhaustive enum specifies every value", .{}); | 3152 | return sema.fail(block, src, "non-exhaustive enum specifies every value", .{}); |
| 3137 | } | 3153 | } |
| 3138 | } | 3154 | } |
| ... | @@ -3171,7 +3187,7 @@ fn zirEnumDecl( | ... | @@ -3171,7 +3187,7 @@ fn zirEnumDecl( |
| 3171 | .needed_comptime_reason = "enum tag value must be comptime-known", | 3187 | .needed_comptime_reason = "enum tag value must be comptime-known", |
| 3172 | }); | 3188 | }); |
| 3173 | if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true; | 3189 | if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true; |
| 3174 | last_tag_val = try mod.getCoerced(last_tag_val.?, int_tag_ty); | 3190 | last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty); |
| 3175 | if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| { | 3191 | if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| { |
| 3176 | assert(conflict.kind == .value); // AstGen validated names are unique | 3192 | assert(conflict.kind == .value); // AstGen validated names are unique |
| 3177 | const other_field_src: LazySrcLoc = .{ | 3193 | const other_field_src: LazySrcLoc = .{ |
| ... | @@ -3179,7 +3195,7 @@ fn zirEnumDecl( | ... | @@ -3179,7 +3195,7 @@ fn zirEnumDecl( |
| 3179 | .offset = .{ .container_field_value = conflict.prev_field_idx }, | 3195 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 3180 | }; | 3196 | }; |
| 3181 | const msg = msg: { | 3197 | const msg = msg: { |
| 3182 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)}); | 3198 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)}); |
| 3183 | errdefer msg.destroy(gpa); | 3199 | errdefer msg.destroy(gpa); |
| 3184 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); | 3200 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 3185 | break :msg msg; | 3201 | break :msg msg; |
| ... | @@ -3190,9 +3206,9 @@ fn zirEnumDecl( | ... | @@ -3190,9 +3206,9 @@ fn zirEnumDecl( |
| 3190 | } else if (any_values) overflow: { | 3206 | } else if (any_values) overflow: { |
| 3191 | var overflow: ?usize = null; | 3207 | var overflow: ?usize = null; |
| 3192 | last_tag_val = if (last_tag_val) |val| | 3208 | last_tag_val = if (last_tag_val) |val| |
| 3193 | try sema.intAdd(val, try mod.intValue(int_tag_ty, 1), int_tag_ty, &overflow) | 3209 | try sema.intAdd(val, try pt.intValue(int_tag_ty, 1), int_tag_ty, &overflow) |
| 3194 | else | 3210 | else |
| 3195 | try mod.intValue(int_tag_ty, 0); | 3211 | try pt.intValue(int_tag_ty, 0); |
| 3196 | if (overflow != null) break :overflow true; | 3212 | if (overflow != null) break :overflow true; |
| 3197 | if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| { | 3213 | if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| { |
| 3198 | assert(conflict.kind == .value); // AstGen validated names are unique | 3214 | assert(conflict.kind == .value); // AstGen validated names are unique |
| ... | @@ -3201,7 +3217,7 @@ fn zirEnumDecl( | ... | @@ -3201,7 +3217,7 @@ fn zirEnumDecl( |
| 3201 | .offset = .{ .container_field_value = conflict.prev_field_idx }, | 3217 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 3202 | }; | 3218 | }; |
| 3203 | const msg = msg: { | 3219 | const msg = msg: { |
| 3204 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)}); | 3220 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(pt, sema)}); |
| 3205 | errdefer msg.destroy(gpa); | 3221 | errdefer msg.destroy(gpa); |
| 3206 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); | 3222 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 3207 | break :msg msg; | 3223 | break :msg msg; |
| ... | @@ -3211,21 +3227,21 @@ fn zirEnumDecl( | ... | @@ -3211,21 +3227,21 @@ fn zirEnumDecl( |
| 3211 | break :overflow false; | 3227 | break :overflow false; |
| 3212 | } else overflow: { | 3228 | } else overflow: { |
| 3213 | assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null); | 3229 | assert(wip_ty.nextField(&mod.intern_pool, field_name, .none) == null); |
| 3214 | last_tag_val = try mod.intValue(Type.comptime_int, field_i); | 3230 | last_tag_val = try pt.intValue(Type.comptime_int, field_i); |
| 3215 | if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true; | 3231 | if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true; |
| 3216 | last_tag_val = try mod.getCoerced(last_tag_val.?, int_tag_ty); | 3232 | last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty); |
| 3217 | break :overflow false; | 3233 | break :overflow false; |
| 3218 | }; | 3234 | }; |
| 3219 | 3235 | ||
| 3220 | if (tag_overflow) { | 3236 | if (tag_overflow) { |
| 3221 | const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{ | 3237 | const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{ |
| 3222 | last_tag_val.?.fmtValue(mod, sema), int_tag_ty.fmt(mod), | 3238 | last_tag_val.?.fmtValue(pt, sema), int_tag_ty.fmt(pt), |
| 3223 | }); | 3239 | }); |
| 3224 | return sema.failWithOwnedErrorMsg(block, msg); | 3240 | return sema.failWithOwnedErrorMsg(block, msg); |
| 3225 | } | 3241 | } |
| 3226 | } | 3242 | } |
| 3227 | 3243 | ||
| 3228 | try mod.finalizeAnonDecl(new_decl_index); | 3244 | try pt.finalizeAnonDecl(new_decl_index); |
| 3229 | return Air.internedToRef(wip_ty.index); | 3245 | return Air.internedToRef(wip_ty.index); |
| 3230 | } | 3246 | } |
| 3231 | 3247 | ||
| ... | @@ -3238,7 +3254,8 @@ fn zirUnionDecl( | ... | @@ -3238,7 +3254,8 @@ fn zirUnionDecl( |
| 3238 | const tracy = trace(@src()); | 3254 | const tracy = trace(@src()); |
| 3239 | defer tracy.end(); | 3255 | defer tracy.end(); |
| 3240 | 3256 | ||
| 3241 | const mod = sema.mod; | 3257 | const pt = sema.pt; |
| 3258 | const mod = pt.zcu; | ||
| 3242 | const gpa = sema.gpa; | 3259 | const gpa = sema.gpa; |
| 3243 | const ip = &mod.intern_pool; | 3260 | const ip = &mod.intern_pool; |
| 3244 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); | 3261 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); |
| ... | @@ -3298,10 +3315,10 @@ fn zirUnionDecl( | ... | @@ -3298,10 +3315,10 @@ fn zirUnionDecl( |
| 3298 | .captures = captures, | 3315 | .captures = captures, |
| 3299 | } }, | 3316 | } }, |
| 3300 | }; | 3317 | }; |
| 3301 | const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, union_init)) { | 3318 | const wip_ty = sema.wrapWipTy(switch (try ip.getUnionType(gpa, pt.tid, union_init)) { |
| 3302 | .existing => |ty| wip: { | 3319 | .existing => |ty| wip: { |
| 3303 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); | 3320 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); |
| 3304 | break :wip (try ip.getUnionType(gpa, union_init)).wip; | 3321 | break :wip (try ip.getUnionType(gpa, pt.tid, union_init)).wip; |
| 3305 | }, | 3322 | }, |
| 3306 | .wip => |wip| wip, | 3323 | .wip => |wip| wip, |
| 3307 | }); | 3324 | }); |
| ... | @@ -3317,7 +3334,7 @@ fn zirUnionDecl( | ... | @@ -3317,7 +3334,7 @@ fn zirUnionDecl( |
| 3317 | mod.declPtr(new_decl_index).owns_tv = true; | 3334 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3318 | errdefer mod.abortAnonDecl(new_decl_index); | 3335 | errdefer mod.abortAnonDecl(new_decl_index); |
| 3319 | 3336 | ||
| 3320 | if (sema.mod.comp.debug_incremental) { | 3337 | if (pt.zcu.comp.debug_incremental) { |
| 3321 | try mod.intern_pool.addDependency( | 3338 | try mod.intern_pool.addDependency( |
| 3322 | gpa, | 3339 | gpa, |
| 3323 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 3340 | AnalUnit.wrap(.{ .decl = new_decl_index }), |
| ... | @@ -3338,7 +3355,7 @@ fn zirUnionDecl( | ... | @@ -3338,7 +3355,7 @@ fn zirUnionDecl( |
| 3338 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | 3355 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); |
| 3339 | } | 3356 | } |
| 3340 | 3357 | ||
| 3341 | try mod.finalizeAnonDecl(new_decl_index); | 3358 | try pt.finalizeAnonDecl(new_decl_index); |
| 3342 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | 3359 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); |
| 3343 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 3360 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); |
| 3344 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 3361 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); |
| ... | @@ -3353,7 +3370,8 @@ fn zirOpaqueDecl( | ... | @@ -3353,7 +3370,8 @@ fn zirOpaqueDecl( |
| 3353 | const tracy = trace(@src()); | 3370 | const tracy = trace(@src()); |
| 3354 | defer tracy.end(); | 3371 | defer tracy.end(); |
| 3355 | 3372 | ||
| 3356 | const mod = sema.mod; | 3373 | const pt = sema.pt; |
| 3374 | const mod = pt.zcu; | ||
| 3357 | const gpa = sema.gpa; | 3375 | const gpa = sema.gpa; |
| 3358 | const ip = &mod.intern_pool; | 3376 | const ip = &mod.intern_pool; |
| 3359 | 3377 | ||
| ... | @@ -3387,10 +3405,10 @@ fn zirOpaqueDecl( | ... | @@ -3387,10 +3405,10 @@ fn zirOpaqueDecl( |
| 3387 | } }, | 3405 | } }, |
| 3388 | }; | 3406 | }; |
| 3389 | // No `wrapWipTy` needed as no std.builtin types are opaque. | 3407 | // No `wrapWipTy` needed as no std.builtin types are opaque. |
| 3390 | const wip_ty = switch (try ip.getOpaqueType(gpa, opaque_init)) { | 3408 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { |
| 3391 | .existing => |ty| wip: { | 3409 | .existing => |ty| wip: { |
| 3392 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); | 3410 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); |
| 3393 | break :wip (try ip.getOpaqueType(gpa, opaque_init)).wip; | 3411 | break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip; |
| 3394 | }, | 3412 | }, |
| 3395 | .wip => |wip| wip, | 3413 | .wip => |wip| wip, |
| 3396 | }; | 3414 | }; |
| ... | @@ -3406,7 +3424,7 @@ fn zirOpaqueDecl( | ... | @@ -3406,7 +3424,7 @@ fn zirOpaqueDecl( |
| 3406 | mod.declPtr(new_decl_index).owns_tv = true; | 3424 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3407 | errdefer mod.abortAnonDecl(new_decl_index); | 3425 | errdefer mod.abortAnonDecl(new_decl_index); |
| 3408 | 3426 | ||
| 3409 | if (sema.mod.comp.debug_incremental) { | 3427 | if (pt.zcu.comp.debug_incremental) { |
| 3410 | try ip.addDependency( | 3428 | try ip.addDependency( |
| 3411 | gpa, | 3429 | gpa, |
| 3412 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 3430 | AnalUnit.wrap(.{ .decl = new_decl_index }), |
| ... | @@ -3426,7 +3444,7 @@ fn zirOpaqueDecl( | ... | @@ -3426,7 +3444,7 @@ fn zirOpaqueDecl( |
| 3426 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | 3444 | try mod.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); |
| 3427 | } | 3445 | } |
| 3428 | 3446 | ||
| 3429 | try mod.finalizeAnonDecl(new_decl_index); | 3447 | try pt.finalizeAnonDecl(new_decl_index); |
| 3430 | 3448 | ||
| 3431 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 3449 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); |
| 3432 | } | 3450 | } |
| ... | @@ -3438,7 +3456,8 @@ fn zirErrorSetDecl( | ... | @@ -3438,7 +3456,8 @@ fn zirErrorSetDecl( |
| 3438 | const tracy = trace(@src()); | 3456 | const tracy = trace(@src()); |
| 3439 | defer tracy.end(); | 3457 | defer tracy.end(); |
| 3440 | 3458 | ||
| 3441 | const mod = sema.mod; | 3459 | const pt = sema.pt; |
| 3460 | const mod = pt.zcu; | ||
| 3442 | const gpa = sema.gpa; | 3461 | const gpa = sema.gpa; |
| 3443 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 3462 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 3444 | const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); | 3463 | const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); |
| ... | @@ -3457,20 +3476,22 @@ fn zirErrorSetDecl( | ... | @@ -3457,20 +3476,22 @@ fn zirErrorSetDecl( |
| 3457 | assert(!result.found_existing); // verified in AstGen | 3476 | assert(!result.found_existing); // verified in AstGen |
| 3458 | } | 3477 | } |
| 3459 | 3478 | ||
| 3460 | return Air.internedToRef((try mod.errorSetFromUnsortedNames(names.keys())).toIntern()); | 3479 | return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern()); |
| 3461 | } | 3480 | } |
| 3462 | 3481 | ||
| 3463 | fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | 3482 | fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 3464 | const tracy = trace(@src()); | 3483 | const tracy = trace(@src()); |
| 3465 | defer tracy.end(); | 3484 | defer tracy.end(); |
| 3466 | 3485 | ||
| 3486 | const pt = sema.pt; | ||
| 3487 | |||
| 3467 | if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) { | 3488 | if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) { |
| 3468 | try sema.fn_ret_ty.resolveFields(sema.mod); | 3489 | try sema.fn_ret_ty.resolveFields(pt); |
| 3469 | return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none); | 3490 | return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none); |
| 3470 | } | 3491 | } |
| 3471 | 3492 | ||
| 3472 | const target = sema.mod.getTarget(); | 3493 | const target = pt.zcu.getTarget(); |
| 3473 | const ptr_type = try sema.mod.ptrTypeSema(.{ | 3494 | const ptr_type = try pt.ptrTypeSema(.{ |
| 3474 | .child = sema.fn_ret_ty.toIntern(), | 3495 | .child = sema.fn_ret_ty.toIntern(), |
| 3475 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 3496 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 3476 | }); | 3497 | }); |
| ... | @@ -3511,7 +3532,8 @@ fn ensureResultUsed( | ... | @@ -3511,7 +3532,8 @@ fn ensureResultUsed( |
| 3511 | ty: Type, | 3532 | ty: Type, |
| 3512 | src: LazySrcLoc, | 3533 | src: LazySrcLoc, |
| 3513 | ) CompileError!void { | 3534 | ) CompileError!void { |
| 3514 | const mod = sema.mod; | 3535 | const pt = sema.pt; |
| 3536 | const mod = pt.zcu; | ||
| 3515 | switch (ty.zigTypeTag(mod)) { | 3537 | switch (ty.zigTypeTag(mod)) { |
| 3516 | .Void, .NoReturn => return, | 3538 | .Void, .NoReturn => return, |
| 3517 | .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}), | 3539 | .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}), |
| ... | @@ -3526,7 +3548,7 @@ fn ensureResultUsed( | ... | @@ -3526,7 +3548,7 @@ fn ensureResultUsed( |
| 3526 | }, | 3548 | }, |
| 3527 | else => { | 3549 | else => { |
| 3528 | const msg = msg: { | 3550 | const msg = msg: { |
| 3529 | const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(sema.mod)}); | 3551 | const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(pt)}); |
| 3530 | errdefer msg.destroy(sema.gpa); | 3552 | errdefer msg.destroy(sema.gpa); |
| 3531 | try sema.errNote(src, msg, "all non-void values must be used", .{}); | 3553 | try sema.errNote(src, msg, "all non-void values must be used", .{}); |
| 3532 | try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{}); | 3554 | try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{}); |
| ... | @@ -3541,7 +3563,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3541,7 +3563,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3541 | const tracy = trace(@src()); | 3563 | const tracy = trace(@src()); |
| 3542 | defer tracy.end(); | 3564 | defer tracy.end(); |
| 3543 | 3565 | ||
| 3544 | const mod = sema.mod; | 3566 | const pt = sema.pt; |
| 3567 | const mod = pt.zcu; | ||
| 3545 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 3568 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3546 | const operand = try sema.resolveInst(inst_data.operand); | 3569 | const operand = try sema.resolveInst(inst_data.operand); |
| 3547 | const src = block.nodeOffset(inst_data.src_node); | 3570 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -3565,7 +3588,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index | ... | @@ -3565,7 +3588,8 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index |
| 3565 | const tracy = trace(@src()); | 3588 | const tracy = trace(@src()); |
| 3566 | defer tracy.end(); | 3589 | defer tracy.end(); |
| 3567 | 3590 | ||
| 3568 | const mod = sema.mod; | 3591 | const pt = sema.pt; |
| 3592 | const mod = pt.zcu; | ||
| 3569 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 3593 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3570 | const src = block.nodeOffset(inst_data.src_node); | 3594 | const src = block.nodeOffset(inst_data.src_node); |
| 3571 | const operand = try sema.resolveInst(inst_data.operand); | 3595 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -3604,7 +3628,8 @@ fn indexablePtrLen( | ... | @@ -3604,7 +3628,8 @@ fn indexablePtrLen( |
| 3604 | src: LazySrcLoc, | 3628 | src: LazySrcLoc, |
| 3605 | object: Air.Inst.Ref, | 3629 | object: Air.Inst.Ref, |
| 3606 | ) CompileError!Air.Inst.Ref { | 3630 | ) CompileError!Air.Inst.Ref { |
| 3607 | const mod = sema.mod; | 3631 | const pt = sema.pt; |
| 3632 | const mod = pt.zcu; | ||
| 3608 | const object_ty = sema.typeOf(object); | 3633 | const object_ty = sema.typeOf(object); |
| 3609 | const is_pointer_to = object_ty.isSinglePointer(mod); | 3634 | const is_pointer_to = object_ty.isSinglePointer(mod); |
| 3610 | const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty; | 3635 | const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty; |
| ... | @@ -3619,7 +3644,8 @@ fn indexablePtrLenOrNone( | ... | @@ -3619,7 +3644,8 @@ fn indexablePtrLenOrNone( |
| 3619 | src: LazySrcLoc, | 3644 | src: LazySrcLoc, |
| 3620 | operand: Air.Inst.Ref, | 3645 | operand: Air.Inst.Ref, |
| 3621 | ) CompileError!Air.Inst.Ref { | 3646 | ) CompileError!Air.Inst.Ref { |
| 3622 | const mod = sema.mod; | 3647 | const pt = sema.pt; |
| 3648 | const mod = pt.zcu; | ||
| 3623 | const operand_ty = sema.typeOf(operand); | 3649 | const operand_ty = sema.typeOf(operand); |
| 3624 | try checkMemOperand(sema, block, src, operand_ty); | 3650 | try checkMemOperand(sema, block, src, operand_ty); |
| 3625 | if (operand_ty.ptrSize(mod) == .Many) return .none; | 3651 | if (operand_ty.ptrSize(mod) == .Many) return .none; |
| ... | @@ -3632,6 +3658,7 @@ fn zirAllocExtended( | ... | @@ -3632,6 +3658,7 @@ fn zirAllocExtended( |
| 3632 | block: *Block, | 3658 | block: *Block, |
| 3633 | extended: Zir.Inst.Extended.InstData, | 3659 | extended: Zir.Inst.Extended.InstData, |
| 3634 | ) CompileError!Air.Inst.Ref { | 3660 | ) CompileError!Air.Inst.Ref { |
| 3661 | const pt = sema.pt; | ||
| 3635 | const gpa = sema.gpa; | 3662 | const gpa = sema.gpa; |
| 3636 | const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand); | 3663 | const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand); |
| 3637 | const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node }); | 3664 | const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node }); |
| ... | @@ -3673,9 +3700,9 @@ fn zirAllocExtended( | ... | @@ -3673,9 +3700,9 @@ fn zirAllocExtended( |
| 3673 | if (!small.is_const) { | 3700 | if (!small.is_const) { |
| 3674 | try sema.validateVarType(block, ty_src, var_ty, false); | 3701 | try sema.validateVarType(block, ty_src, var_ty, false); |
| 3675 | } | 3702 | } |
| 3676 | const target = sema.mod.getTarget(); | 3703 | const target = pt.zcu.getTarget(); |
| 3677 | try var_ty.resolveLayout(sema.mod); | 3704 | try var_ty.resolveLayout(pt); |
| 3678 | const ptr_type = try sema.mod.ptrTypeSema(.{ | 3705 | const ptr_type = try sema.pt.ptrTypeSema(.{ |
| 3679 | .child = var_ty.toIntern(), | 3706 | .child = var_ty.toIntern(), |
| 3680 | .flags = .{ | 3707 | .flags = .{ |
| 3681 | .alignment = alignment, | 3708 | .alignment = alignment, |
| ... | @@ -3717,7 +3744,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -3717,7 +3744,8 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 3717 | } | 3744 | } |
| 3718 | 3745 | ||
| 3719 | fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 3746 | fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 3720 | const mod = sema.mod; | 3747 | const pt = sema.pt; |
| 3748 | const mod = pt.zcu; | ||
| 3721 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 3749 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3722 | const alloc = try sema.resolveInst(inst_data.operand); | 3750 | const alloc = try sema.resolveInst(inst_data.operand); |
| 3723 | const alloc_ty = sema.typeOf(alloc); | 3751 | const alloc_ty = sema.typeOf(alloc); |
| ... | @@ -3749,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3749,7 +3777,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3749 | assert(ptr.byte_offset == 0); | 3777 | assert(ptr.byte_offset == 0); |
| 3750 | const alloc_index = ptr.base_addr.comptime_alloc; | 3778 | const alloc_index = ptr.base_addr.comptime_alloc; |
| 3751 | const ct_alloc = sema.getComptimeAlloc(alloc_index); | 3779 | const ct_alloc = sema.getComptimeAlloc(alloc_index); |
| 3752 | const interned = try ct_alloc.val.intern(mod, sema.arena); | 3780 | const interned = try ct_alloc.val.intern(pt, sema.arena); |
| 3753 | if (interned.canMutateComptimeVarState(mod)) { | 3781 | if (interned.canMutateComptimeVarState(mod)) { |
| 3754 | // Preserve the comptime alloc, just make the pointer const. | 3782 | // Preserve the comptime alloc, just make the pointer const. |
| 3755 | ct_alloc.val = .{ .interned = interned.toIntern() }; | 3783 | ct_alloc.val = .{ .interned = interned.toIntern() }; |
| ... | @@ -3757,7 +3785,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3757,7 +3785,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3757 | return sema.makePtrConst(block, alloc); | 3785 | return sema.makePtrConst(block, alloc); |
| 3758 | } else { | 3786 | } else { |
| 3759 | // Promote the constant to an anon decl. | 3787 | // Promote the constant to an anon decl. |
| 3760 | const new_mut_ptr = Air.internedToRef(try mod.intern(.{ .ptr = .{ | 3788 | const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{ |
| 3761 | .ty = alloc_ty.toIntern(), | 3789 | .ty = alloc_ty.toIntern(), |
| 3762 | .base_addr = .{ .anon_decl = .{ | 3790 | .base_addr = .{ .anon_decl = .{ |
| 3763 | .val = interned.toIntern(), | 3791 | .val = interned.toIntern(), |
| ... | @@ -3778,7 +3806,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3778,7 +3806,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3778 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. | 3806 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. |
| 3779 | // TODO: source location of runtime control flow | 3807 | // TODO: source location of runtime control flow |
| 3780 | const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 3808 | const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); |
| 3781 | return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(mod)}); | 3809 | return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)}); |
| 3782 | } | 3810 | } |
| 3783 | 3811 | ||
| 3784 | // This is a runtime value. | 3812 | // This is a runtime value. |
| ... | @@ -3788,7 +3816,8 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3788,7 +3816,8 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3788 | /// If `alloc` is an inferred allocation, `resolved_inferred_ty` is taken to be its resolved | 3816 | /// If `alloc` is an inferred allocation, `resolved_inferred_ty` is taken to be its resolved |
| 3789 | /// type. Otherwise, it may be `null`, and the type will be inferred from `alloc`. | 3817 | /// type. Otherwise, it may be `null`, and the type will be inferred from `alloc`. |
| 3790 | fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, resolved_alloc_ty: ?Type) CompileError!?InternPool.Index { | 3818 | fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, resolved_alloc_ty: ?Type) CompileError!?InternPool.Index { |
| 3791 | const zcu = sema.mod; | 3819 | const pt = sema.pt; |
| 3820 | const zcu = pt.zcu; | ||
| 3792 | 3821 | ||
| 3793 | const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc); | 3822 | const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc); |
| 3794 | const ptr_info = alloc_ty.ptrInfo(zcu); | 3823 | const ptr_info = alloc_ty.ptrInfo(zcu); |
| ... | @@ -3831,7 +3860,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -3831,7 +3860,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 3831 | 3860 | ||
| 3832 | const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment); | 3861 | const ct_alloc = try sema.newComptimeAlloc(block, elem_ty, ptr_info.flags.alignment); |
| 3833 | 3862 | ||
| 3834 | const alloc_ptr = try zcu.intern(.{ .ptr = .{ | 3863 | const alloc_ptr = try pt.intern(.{ .ptr = .{ |
| 3835 | .ty = alloc_ty.toIntern(), | 3864 | .ty = alloc_ty.toIntern(), |
| 3836 | .base_addr = .{ .comptime_alloc = ct_alloc }, | 3865 | .base_addr = .{ .comptime_alloc = ct_alloc }, |
| 3837 | .byte_offset = 0, | 3866 | .byte_offset = 0, |
| ... | @@ -3909,7 +3938,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -3909,7 +3938,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 3909 | const idx_val = (try sema.resolveValue(data.rhs)).?; | 3938 | const idx_val = (try sema.resolveValue(data.rhs)).?; |
| 3910 | break :blk .{ | 3939 | break :blk .{ |
| 3911 | data.lhs, | 3940 | data.lhs, |
| 3912 | .{ .elem = try idx_val.toUnsignedIntSema(zcu) }, | 3941 | .{ .elem = try idx_val.toUnsignedIntSema(pt) }, |
| 3913 | }; | 3942 | }; |
| 3914 | }, | 3943 | }, |
| 3915 | .bitcast => .{ | 3944 | .bitcast => .{ |
| ... | @@ -3935,32 +3964,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -3935,32 +3964,32 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 3935 | }; | 3964 | }; |
| 3936 | const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern(); | 3965 | const new_ptr_ty = tmp_air.typeOfIndex(air_ptr, &zcu.intern_pool).toIntern(); |
| 3937 | const new_ptr = switch (method) { | 3966 | const new_ptr = switch (method) { |
| 3938 | .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, decl_parent_ptr, new_ptr_ty), | 3967 | .same_addr => try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, decl_parent_ptr, new_ptr_ty), |
| 3939 | .opt_payload => ptr: { | 3968 | .opt_payload => ptr: { |
| 3940 | // Set the optional to non-null at comptime. | 3969 | // Set the optional to non-null at comptime. |
| 3941 | // If the payload is OPV, we must use that value instead of undef. | 3970 | // If the payload is OPV, we must use that value instead of undef. |
| 3942 | const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); | 3971 | const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); |
| 3943 | const payload_ty = opt_ty.optionalChild(zcu); | 3972 | const payload_ty = opt_ty.optionalChild(zcu); |
| 3944 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty); | 3973 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); |
| 3945 | const opt_val = try zcu.intern(.{ .opt = .{ | 3974 | const opt_val = try pt.intern(.{ .opt = .{ |
| 3946 | .ty = opt_ty.toIntern(), | 3975 | .ty = opt_ty.toIntern(), |
| 3947 | .val = payload_val.toIntern(), | 3976 | .val = payload_val.toIntern(), |
| 3948 | } }); | 3977 | } }); |
| 3949 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty); | 3978 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty); |
| 3950 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(zcu)).toIntern(); | 3979 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(pt)).toIntern(); |
| 3951 | }, | 3980 | }, |
| 3952 | .eu_payload => ptr: { | 3981 | .eu_payload => ptr: { |
| 3953 | // Set the error union to non-error at comptime. | 3982 | // Set the error union to non-error at comptime. |
| 3954 | // If the payload is OPV, we must use that value instead of undef. | 3983 | // If the payload is OPV, we must use that value instead of undef. |
| 3955 | const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); | 3984 | const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); |
| 3956 | const payload_ty = eu_ty.errorUnionPayload(zcu); | 3985 | const payload_ty = eu_ty.errorUnionPayload(zcu); |
| 3957 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty); | 3986 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); |
| 3958 | const eu_val = try zcu.intern(.{ .error_union = .{ | 3987 | const eu_val = try pt.intern(.{ .error_union = .{ |
| 3959 | .ty = eu_ty.toIntern(), | 3988 | .ty = eu_ty.toIntern(), |
| 3960 | .val = .{ .payload = payload_val.toIntern() }, | 3989 | .val = .{ .payload = payload_val.toIntern() }, |
| 3961 | } }); | 3990 | } }); |
| 3962 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty); | 3991 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty); |
| 3963 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(zcu)).toIntern(); | 3992 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(pt)).toIntern(); |
| 3964 | }, | 3993 | }, |
| 3965 | .field => |idx| ptr: { | 3994 | .field => |idx| ptr: { |
| 3966 | const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); | 3995 | const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu); |
| ... | @@ -3969,14 +3998,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, | ... | @@ -3969,14 +3998,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref, |
| 3969 | // If the payload is OPV, there will not be a payload store, so we store that value. | 3998 | // If the payload is OPV, there will not be a payload store, so we store that value. |
| 3970 | // Otherwise, there will be a payload store to process later, so undef will suffice. | 3999 | // Otherwise, there will be a payload store to process later, so undef will suffice. |
| 3971 | const payload_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]); | 4000 | const payload_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]); |
| 3972 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty); | 4001 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); |
| 3973 | const tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx); | 4002 | const tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx); |
| 3974 | const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val); | 4003 | const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val); |
| 3975 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty); | 4004 | try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty); |
| 3976 | } | 4005 | } |
| 3977 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, zcu)).toIntern(); | 4006 | break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern(); |
| 3978 | }, | 4007 | }, |
| 3979 | .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, zcu)).toIntern(), | 4008 | .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, pt)).toIntern(), |
| 3980 | }; | 4009 | }; |
| 3981 | try ptr_mapping.put(air_ptr, new_ptr); | 4010 | try ptr_mapping.put(air_ptr, new_ptr); |
| 3982 | } | 4011 | } |
| ... | @@ -4020,7 +4049,8 @@ fn finishResolveComptimeKnownAllocPtr( | ... | @@ -4020,7 +4049,8 @@ fn finishResolveComptimeKnownAllocPtr( |
| 4020 | alloc_inst: Air.Inst.Index, | 4049 | alloc_inst: Air.Inst.Index, |
| 4021 | comptime_info: MaybeComptimeAlloc, | 4050 | comptime_info: MaybeComptimeAlloc, |
| 4022 | ) CompileError!?InternPool.Index { | 4051 | ) CompileError!?InternPool.Index { |
| 4023 | const zcu = sema.mod; | 4052 | const pt = sema.pt; |
| 4053 | const zcu = pt.zcu; | ||
| 4024 | 4054 | ||
| 4025 | // We're almost done - we have the resolved comptime value. We just need to | 4055 | // We're almost done - we have the resolved comptime value. We just need to |
| 4026 | // eliminate the now-dead runtime instructions. | 4056 | // eliminate the now-dead runtime instructions. |
| ... | @@ -4041,19 +4071,19 @@ fn finishResolveComptimeKnownAllocPtr( | ... | @@ -4041,19 +4071,19 @@ fn finishResolveComptimeKnownAllocPtr( |
| 4041 | 4071 | ||
| 4042 | if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) { | 4072 | if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) { |
| 4043 | const alloc_index = existing_comptime_alloc orelse a: { | 4073 | const alloc_index = existing_comptime_alloc orelse a: { |
| 4044 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu)); | 4074 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(pt)); |
| 4045 | const alloc = sema.getComptimeAlloc(idx); | 4075 | const alloc = sema.getComptimeAlloc(idx); |
| 4046 | alloc.val = .{ .interned = result_val }; | 4076 | alloc.val = .{ .interned = result_val }; |
| 4047 | break :a idx; | 4077 | break :a idx; |
| 4048 | }; | 4078 | }; |
| 4049 | sema.getComptimeAlloc(alloc_index).is_const = true; | 4079 | sema.getComptimeAlloc(alloc_index).is_const = true; |
| 4050 | return try zcu.intern(.{ .ptr = .{ | 4080 | return try pt.intern(.{ .ptr = .{ |
| 4051 | .ty = alloc_ty.toIntern(), | 4081 | .ty = alloc_ty.toIntern(), |
| 4052 | .base_addr = .{ .comptime_alloc = alloc_index }, | 4082 | .base_addr = .{ .comptime_alloc = alloc_index }, |
| 4053 | .byte_offset = 0, | 4083 | .byte_offset = 0, |
| 4054 | } }); | 4084 | } }); |
| 4055 | } else { | 4085 | } else { |
| 4056 | return try zcu.intern(.{ .ptr = .{ | 4086 | return try pt.intern(.{ .ptr = .{ |
| 4057 | .ty = alloc_ty.toIntern(), | 4087 | .ty = alloc_ty.toIntern(), |
| 4058 | .base_addr = .{ .anon_decl = .{ | 4088 | .base_addr = .{ .anon_decl = .{ |
| 4059 | .orig_ty = alloc_ty.toIntern(), | 4089 | .orig_ty = alloc_ty.toIntern(), |
| ... | @@ -4065,9 +4095,9 @@ fn finishResolveComptimeKnownAllocPtr( | ... | @@ -4065,9 +4095,9 @@ fn finishResolveComptimeKnownAllocPtr( |
| 4065 | } | 4095 | } |
| 4066 | 4096 | ||
| 4067 | fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type { | 4097 | fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type { |
| 4068 | var ptr_info = ptr_ty.ptrInfo(sema.mod); | 4098 | var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu); |
| 4069 | ptr_info.flags.is_const = true; | 4099 | ptr_info.flags.is_const = true; |
| 4070 | return sema.mod.ptrTypeSema(ptr_info); | 4100 | return sema.pt.ptrTypeSema(ptr_info); |
| 4071 | } | 4101 | } |
| 4072 | 4102 | ||
| 4073 | fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref { | 4103 | fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| ... | @@ -4076,7 +4106,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai | ... | @@ -4076,7 +4106,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai |
| 4076 | 4106 | ||
| 4077 | // Detect if a comptime value simply needs to have its type changed. | 4107 | // Detect if a comptime value simply needs to have its type changed. |
| 4078 | if (try sema.resolveValue(alloc)) |val| { | 4108 | if (try sema.resolveValue(alloc)) |val| { |
| 4079 | return Air.internedToRef((try sema.mod.getCoerced(val, const_ptr_ty)).toIntern()); | 4109 | return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern()); |
| 4080 | } | 4110 | } |
| 4081 | 4111 | ||
| 4082 | return block.addBitCast(const_ptr_ty, alloc); | 4112 | return block.addBitCast(const_ptr_ty, alloc); |
| ... | @@ -4103,14 +4133,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -4103,14 +4133,16 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 4103 | const tracy = trace(@src()); | 4133 | const tracy = trace(@src()); |
| 4104 | defer tracy.end(); | 4134 | defer tracy.end(); |
| 4105 | 4135 | ||
| 4136 | const pt = sema.pt; | ||
| 4137 | |||
| 4106 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 4138 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4107 | const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node }); | 4139 | const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node }); |
| 4108 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); | 4140 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 4109 | if (block.is_comptime) { | 4141 | if (block.is_comptime) { |
| 4110 | return sema.analyzeComptimeAlloc(block, var_ty, .none); | 4142 | return sema.analyzeComptimeAlloc(block, var_ty, .none); |
| 4111 | } | 4143 | } |
| 4112 | const target = sema.mod.getTarget(); | 4144 | const target = pt.zcu.getTarget(); |
| 4113 | const ptr_type = try sema.mod.ptrTypeSema(.{ | 4145 | const ptr_type = try pt.ptrTypeSema(.{ |
| 4114 | .child = var_ty.toIntern(), | 4146 | .child = var_ty.toIntern(), |
| 4115 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 4147 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 4116 | }); | 4148 | }); |
| ... | @@ -4125,6 +4157,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -4125,6 +4157,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 4125 | const tracy = trace(@src()); | 4157 | const tracy = trace(@src()); |
| 4126 | defer tracy.end(); | 4158 | defer tracy.end(); |
| 4127 | 4159 | ||
| 4160 | const pt = sema.pt; | ||
| 4161 | |||
| 4128 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 4162 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4129 | const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node }); | 4163 | const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node }); |
| 4130 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); | 4164 | const var_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| ... | @@ -4132,8 +4166,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -4132,8 +4166,8 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 4132 | return sema.analyzeComptimeAlloc(block, var_ty, .none); | 4166 | return sema.analyzeComptimeAlloc(block, var_ty, .none); |
| 4133 | } | 4167 | } |
| 4134 | try sema.validateVarType(block, ty_src, var_ty, false); | 4168 | try sema.validateVarType(block, ty_src, var_ty, false); |
| 4135 | const target = sema.mod.getTarget(); | 4169 | const target = pt.zcu.getTarget(); |
| 4136 | const ptr_type = try sema.mod.ptrTypeSema(.{ | 4170 | const ptr_type = try pt.ptrTypeSema(.{ |
| 4137 | .child = var_ty.toIntern(), | 4171 | .child = var_ty.toIntern(), |
| 4138 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 4172 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 4139 | }); | 4173 | }); |
| ... | @@ -4181,7 +4215,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4181,7 +4215,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4181 | const tracy = trace(@src()); | 4215 | const tracy = trace(@src()); |
| 4182 | defer tracy.end(); | 4216 | defer tracy.end(); |
| 4183 | 4217 | ||
| 4184 | const mod = sema.mod; | 4218 | const pt = sema.pt; |
| 4219 | const mod = pt.zcu; | ||
| 4185 | const gpa = sema.gpa; | 4220 | const gpa = sema.gpa; |
| 4186 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 4221 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4187 | const src = block.nodeOffset(inst_data.src_node); | 4222 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -4206,7 +4241,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4206,7 +4241,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4206 | .anon_decl => |a| a.val, | 4241 | .anon_decl => |a| a.val, |
| 4207 | .comptime_alloc => |i| val: { | 4242 | .comptime_alloc => |i| val: { |
| 4208 | const alloc = sema.getComptimeAlloc(i); | 4243 | const alloc = sema.getComptimeAlloc(i); |
| 4209 | break :val (try alloc.val.intern(mod, sema.arena)).toIntern(); | 4244 | break :val (try alloc.val.intern(pt, sema.arena)).toIntern(); |
| 4210 | }, | 4245 | }, |
| 4211 | else => unreachable, | 4246 | else => unreachable, |
| 4212 | }; | 4247 | }; |
| ... | @@ -4232,7 +4267,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4232,7 +4267,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4232 | } | 4267 | } |
| 4233 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none); | 4268 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none); |
| 4234 | 4269 | ||
| 4235 | const final_ptr_ty = try mod.ptrTypeSema(.{ | 4270 | const final_ptr_ty = try pt.ptrTypeSema(.{ |
| 4236 | .child = final_elem_ty.toIntern(), | 4271 | .child = final_elem_ty.toIntern(), |
| 4237 | .flags = .{ | 4272 | .flags = .{ |
| 4238 | .alignment = ia1.alignment, | 4273 | .alignment = ia1.alignment, |
| ... | @@ -4244,7 +4279,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4244,7 +4279,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4244 | try sema.validateVarType(block, ty_src, final_elem_ty, false); | 4279 | try sema.validateVarType(block, ty_src, final_elem_ty, false); |
| 4245 | } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| { | 4280 | } else if (try sema.resolveComptimeKnownAllocPtr(block, ptr, final_ptr_ty)) |ptr_val| { |
| 4246 | const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty); | 4281 | const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty); |
| 4247 | const new_const_ptr = try mod.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty); | 4282 | const new_const_ptr = try pt.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty); |
| 4248 | 4283 | ||
| 4249 | // Remap the ZIR operand to the resolved pointer value | 4284 | // Remap the ZIR operand to the resolved pointer value |
| 4250 | sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern())); | 4285 | sema.inst_map.putAssumeCapacity(inst_data.operand.toIndex().?, Air.internedToRef(new_const_ptr.toIntern())); |
| ... | @@ -4252,7 +4287,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4252,7 +4287,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4252 | // Unless the block is comptime, `alloc_inferred` always produces | 4287 | // Unless the block is comptime, `alloc_inferred` always produces |
| 4253 | // a runtime constant. The final inferred type needs to be | 4288 | // a runtime constant. The final inferred type needs to be |
| 4254 | // fully resolved so it can be lowered in codegen. | 4289 | // fully resolved so it can be lowered in codegen. |
| 4255 | try final_elem_ty.resolveFully(mod); | 4290 | try final_elem_ty.resolveFully(pt); |
| 4256 | 4291 | ||
| 4257 | return; | 4292 | return; |
| 4258 | } | 4293 | } |
| ... | @@ -4261,7 +4296,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4261,7 +4296,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4261 | // The alloc wasn't comptime-known per the above logic, so the | 4296 | // The alloc wasn't comptime-known per the above logic, so the |
| 4262 | // type cannot be comptime-only. | 4297 | // type cannot be comptime-only. |
| 4263 | // TODO: source location of runtime control flow | 4298 | // TODO: source location of runtime control flow |
| 4264 | return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(mod)}); | 4299 | return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(pt)}); |
| 4265 | } | 4300 | } |
| 4266 | 4301 | ||
| 4267 | // Change it to a normal alloc. | 4302 | // Change it to a normal alloc. |
| ... | @@ -4318,7 +4353,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4318,7 +4353,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4318 | } | 4353 | } |
| 4319 | 4354 | ||
| 4320 | fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 4355 | fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 4321 | const mod = sema.mod; | 4356 | const pt = sema.pt; |
| 4357 | const mod = pt.zcu; | ||
| 4322 | const gpa = sema.gpa; | 4358 | const gpa = sema.gpa; |
| 4323 | const ip = &mod.intern_pool; | 4359 | const ip = &mod.intern_pool; |
| 4324 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 4360 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | @@ -4355,7 +4391,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4355,7 +4391,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4355 | if (!object_ty.isIndexable(mod)) { | 4391 | if (!object_ty.isIndexable(mod)) { |
| 4356 | // Instead of using checkIndexable we customize this error. | 4392 | // Instead of using checkIndexable we customize this error. |
| 4357 | const msg = msg: { | 4393 | const msg = msg: { |
| 4358 | const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)}); | 4394 | const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(pt)}); |
| 4359 | errdefer msg.destroy(sema.gpa); | 4395 | errdefer msg.destroy(sema.gpa); |
| 4360 | try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); | 4396 | try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); |
| 4361 | 4397 | ||
| ... | @@ -4387,10 +4423,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4387,10 +4423,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4387 | .input_index = len_idx, | 4423 | .input_index = len_idx, |
| 4388 | } }); | 4424 | } }); |
| 4389 | try sema.errNote(a_src, msg, "length {} here", .{ | 4425 | try sema.errNote(a_src, msg, "length {} here", .{ |
| 4390 | v.fmtValue(sema.mod, sema), | 4426 | v.fmtValue(pt, sema), |
| 4391 | }); | 4427 | }); |
| 4392 | try sema.errNote(arg_src, msg, "length {} here", .{ | 4428 | try sema.errNote(arg_src, msg, "length {} here", .{ |
| 4393 | arg_val.fmtValue(sema.mod, sema), | 4429 | arg_val.fmtValue(pt, sema), |
| 4394 | }); | 4430 | }); |
| 4395 | break :msg msg; | 4431 | break :msg msg; |
| 4396 | }; | 4432 | }; |
| ... | @@ -4427,7 +4463,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4427,7 +4463,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4427 | .input_index = i, | 4463 | .input_index = i, |
| 4428 | } }); | 4464 | } }); |
| 4429 | try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{ | 4465 | try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{ |
| 4430 | object_ty.fmt(sema.mod), | 4466 | object_ty.fmt(pt), |
| 4431 | }); | 4467 | }); |
| 4432 | } | 4468 | } |
| 4433 | break :msg msg; | 4469 | break :msg msg; |
| ... | @@ -4453,7 +4489,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4453,7 +4489,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4453 | /// Given a `*E!?T`, returns a (valid) `*T`. | 4489 | /// Given a `*E!?T`, returns a (valid) `*T`. |
| 4454 | /// May invalidate already-stored payload data. | 4490 | /// May invalidate already-stored payload data. |
| 4455 | fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref { | 4491 | fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref { |
| 4456 | const mod = sema.mod; | 4492 | const pt = sema.pt; |
| 4493 | const mod = pt.zcu; | ||
| 4457 | var base_ptr = ptr; | 4494 | var base_ptr = ptr; |
| 4458 | while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) { | 4495 | while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) { |
| 4459 | .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true), | 4496 | .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true), |
| ... | @@ -4471,7 +4508,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile | ... | @@ -4471,7 +4508,8 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile |
| 4471 | } | 4508 | } |
| 4472 | 4509 | ||
| 4473 | fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 4510 | fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 4474 | const mod = sema.mod; | 4511 | const pt = sema.pt; |
| 4512 | const mod = pt.zcu; | ||
| 4475 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 4513 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4476 | const src = block.nodeOffset(pl_node.src_node); | 4514 | const src = block.nodeOffset(pl_node.src_node); |
| 4477 | const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data; | 4515 | const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data; |
| ... | @@ -4503,10 +4541,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -4503,10 +4541,10 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4503 | switch (val_ty.zigTypeTag(mod)) { | 4541 | switch (val_ty.zigTypeTag(mod)) { |
| 4504 | .Array, .Vector => {}, | 4542 | .Array, .Vector => {}, |
| 4505 | else => if (!val_ty.isTuple(mod)) { | 4543 | else => if (!val_ty.isTuple(mod)) { |
| 4506 | return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(mod), val_ty.fmt(mod) }); | 4544 | return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) }); |
| 4507 | }, | 4545 | }, |
| 4508 | } | 4546 | } |
| 4509 | const want_ty = try mod.arrayType(.{ | 4547 | const want_ty = try pt.arrayType(.{ |
| 4510 | .len = val_ty.arrayLen(mod), | 4548 | .len = val_ty.arrayLen(mod), |
| 4511 | .child = elem_ty.toIntern(), | 4549 | .child = elem_ty.toIntern(), |
| 4512 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | 4550 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| ... | @@ -4522,7 +4560,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -4522,7 +4560,8 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4522 | } | 4560 | } |
| 4523 | 4561 | ||
| 4524 | fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 4562 | fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 4525 | const mod = sema.mod; | 4563 | const pt = sema.pt; |
| 4564 | const mod = pt.zcu; | ||
| 4526 | const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; | 4565 | const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; |
| 4527 | const src = block.tokenOffset(un_tok.src_tok); | 4566 | const src = block.tokenOffset(un_tok.src_tok); |
| 4528 | // In case of GenericPoison, we don't actually have a type, so this will be | 4567 | // In case of GenericPoison, we don't actually have a type, so this will be |
| ... | @@ -4538,7 +4577,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -4538,7 +4577,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4538 | if (ty_operand.isGenericPoison()) return; | 4577 | if (ty_operand.isGenericPoison()) return; |
| 4539 | if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) { | 4578 | if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) { |
| 4540 | return sema.failWithOwnedErrorMsg(block, msg: { | 4579 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 4541 | const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(mod)}); | 4580 | const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(pt)}); |
| 4542 | errdefer msg.destroy(sema.gpa); | 4581 | errdefer msg.destroy(sema.gpa); |
| 4543 | try sema.errNote(src, msg, "address-of operator always returns a pointer", .{}); | 4582 | try sema.errNote(src, msg, "address-of operator always returns a pointer", .{}); |
| 4544 | break :msg msg; | 4583 | break :msg msg; |
| ... | @@ -4551,7 +4590,8 @@ fn zirValidateArrayInitRefTy( | ... | @@ -4551,7 +4590,8 @@ fn zirValidateArrayInitRefTy( |
| 4551 | block: *Block, | 4590 | block: *Block, |
| 4552 | inst: Zir.Inst.Index, | 4591 | inst: Zir.Inst.Index, |
| 4553 | ) CompileError!Air.Inst.Ref { | 4592 | ) CompileError!Air.Inst.Ref { |
| 4554 | const mod = sema.mod; | 4593 | const pt = sema.pt; |
| 4594 | const mod = pt.zcu; | ||
| 4555 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 4595 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4556 | const src = block.nodeOffset(pl_node.src_node); | 4596 | const src = block.nodeOffset(pl_node.src_node); |
| 4557 | const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data; | 4597 | const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data; |
| ... | @@ -4565,7 +4605,7 @@ fn zirValidateArrayInitRefTy( | ... | @@ -4565,7 +4605,7 @@ fn zirValidateArrayInitRefTy( |
| 4565 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 4605 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 4566 | .Slice, .Many => { | 4606 | .Slice, .Many => { |
| 4567 | // Use array of correct length | 4607 | // Use array of correct length |
| 4568 | const arr_ty = try mod.arrayType(.{ | 4608 | const arr_ty = try pt.arrayType(.{ |
| 4569 | .len = extra.elem_count, | 4609 | .len = extra.elem_count, |
| 4570 | .child = ptr_ty.childType(mod).toIntern(), | 4610 | .child = ptr_ty.childType(mod).toIntern(), |
| 4571 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | 4611 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| ... | @@ -4593,7 +4633,8 @@ fn zirValidateArrayInitTy( | ... | @@ -4593,7 +4633,8 @@ fn zirValidateArrayInitTy( |
| 4593 | inst: Zir.Inst.Index, | 4633 | inst: Zir.Inst.Index, |
| 4594 | is_result_ty: bool, | 4634 | is_result_ty: bool, |
| 4595 | ) CompileError!void { | 4635 | ) CompileError!void { |
| 4596 | const mod = sema.mod; | 4636 | const pt = sema.pt; |
| 4637 | const mod = pt.zcu; | ||
| 4597 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 4638 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4598 | const src = block.nodeOffset(inst_data.src_node); | 4639 | const src = block.nodeOffset(inst_data.src_node); |
| 4599 | const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node }); | 4640 | const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node }); |
| ... | @@ -4615,7 +4656,8 @@ fn validateArrayInitTy( | ... | @@ -4615,7 +4656,8 @@ fn validateArrayInitTy( |
| 4615 | init_count: u32, | 4656 | init_count: u32, |
| 4616 | ty: Type, | 4657 | ty: Type, |
| 4617 | ) CompileError!void { | 4658 | ) CompileError!void { |
| 4618 | const mod = sema.mod; | 4659 | const pt = sema.pt; |
| 4660 | const mod = pt.zcu; | ||
| 4619 | switch (ty.zigTypeTag(mod)) { | 4661 | switch (ty.zigTypeTag(mod)) { |
| 4620 | .Array => { | 4662 | .Array => { |
| 4621 | const array_len = ty.arrayLen(mod); | 4663 | const array_len = ty.arrayLen(mod); |
| ... | @@ -4636,7 +4678,7 @@ fn validateArrayInitTy( | ... | @@ -4636,7 +4678,7 @@ fn validateArrayInitTy( |
| 4636 | return; | 4678 | return; |
| 4637 | }, | 4679 | }, |
| 4638 | .Struct => if (ty.isTuple(mod)) { | 4680 | .Struct => if (ty.isTuple(mod)) { |
| 4639 | try ty.resolveFields(mod); | 4681 | try ty.resolveFields(pt); |
| 4640 | const array_len = ty.arrayLen(mod); | 4682 | const array_len = ty.arrayLen(mod); |
| 4641 | if (init_count > array_len) { | 4683 | if (init_count > array_len) { |
| 4642 | return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{ | 4684 | return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{ |
| ... | @@ -4656,7 +4698,8 @@ fn zirValidateStructInitTy( | ... | @@ -4656,7 +4698,8 @@ fn zirValidateStructInitTy( |
| 4656 | inst: Zir.Inst.Index, | 4698 | inst: Zir.Inst.Index, |
| 4657 | is_result_ty: bool, | 4699 | is_result_ty: bool, |
| 4658 | ) CompileError!void { | 4700 | ) CompileError!void { |
| 4659 | const mod = sema.mod; | 4701 | const pt = sema.pt; |
| 4702 | const mod = pt.zcu; | ||
| 4660 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 4703 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4661 | const src = block.nodeOffset(inst_data.src_node); | 4704 | const src = block.nodeOffset(inst_data.src_node); |
| 4662 | const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { | 4705 | const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { |
| ... | @@ -4681,7 +4724,8 @@ fn zirValidatePtrStructInit( | ... | @@ -4681,7 +4724,8 @@ fn zirValidatePtrStructInit( |
| 4681 | const tracy = trace(@src()); | 4724 | const tracy = trace(@src()); |
| 4682 | defer tracy.end(); | 4725 | defer tracy.end(); |
| 4683 | 4726 | ||
| 4684 | const mod = sema.mod; | 4727 | const pt = sema.pt; |
| 4728 | const mod = pt.zcu; | ||
| 4685 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 4729 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4686 | const init_src = block.nodeOffset(validate_inst.src_node); | 4730 | const init_src = block.nodeOffset(validate_inst.src_node); |
| 4687 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); | 4731 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); |
| ... | @@ -4716,7 +4760,8 @@ fn validateUnionInit( | ... | @@ -4716,7 +4760,8 @@ fn validateUnionInit( |
| 4716 | instrs: []const Zir.Inst.Index, | 4760 | instrs: []const Zir.Inst.Index, |
| 4717 | union_ptr: Air.Inst.Ref, | 4761 | union_ptr: Air.Inst.Ref, |
| 4718 | ) CompileError!void { | 4762 | ) CompileError!void { |
| 4719 | const mod = sema.mod; | 4763 | const pt = sema.pt; |
| 4764 | const mod = pt.zcu; | ||
| 4720 | const gpa = sema.gpa; | 4765 | const gpa = sema.gpa; |
| 4721 | 4766 | ||
| 4722 | if (instrs.len != 1) { | 4767 | if (instrs.len != 1) { |
| ... | @@ -4814,7 +4859,7 @@ fn validateUnionInit( | ... | @@ -4814,7 +4859,7 @@ fn validateUnionInit( |
| 4814 | } | 4859 | } |
| 4815 | 4860 | ||
| 4816 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | 4861 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); |
| 4817 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); | 4862 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 4818 | const field_type = union_ty.unionFieldType(tag_val, mod).?; | 4863 | const field_type = union_ty.unionFieldType(tag_val, mod).?; |
| 4819 | 4864 | ||
| 4820 | if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| { | 4865 | if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| { |
| ... | @@ -4848,7 +4893,7 @@ fn validateUnionInit( | ... | @@ -4848,7 +4893,7 @@ fn validateUnionInit( |
| 4848 | } | 4893 | } |
| 4849 | block.instructions.shrinkRetainingCapacity(block_index); | 4894 | block.instructions.shrinkRetainingCapacity(block_index); |
| 4850 | 4895 | ||
| 4851 | const union_val = try mod.intern(.{ .un = .{ | 4896 | const union_val = try pt.intern(.{ .un = .{ |
| 4852 | .ty = union_ty.toIntern(), | 4897 | .ty = union_ty.toIntern(), |
| 4853 | .tag = tag_val.toIntern(), | 4898 | .tag = tag_val.toIntern(), |
| 4854 | .val = val.toIntern(), | 4899 | .val = val.toIntern(), |
| ... | @@ -4875,7 +4920,8 @@ fn validateStructInit( | ... | @@ -4875,7 +4920,8 @@ fn validateStructInit( |
| 4875 | init_src: LazySrcLoc, | 4920 | init_src: LazySrcLoc, |
| 4876 | instrs: []const Zir.Inst.Index, | 4921 | instrs: []const Zir.Inst.Index, |
| 4877 | ) CompileError!void { | 4922 | ) CompileError!void { |
| 4878 | const mod = sema.mod; | 4923 | const pt = sema.pt; |
| 4924 | const mod = pt.zcu; | ||
| 4879 | const gpa = sema.gpa; | 4925 | const gpa = sema.gpa; |
| 4880 | const ip = &mod.intern_pool; | 4926 | const ip = &mod.intern_pool; |
| 4881 | 4927 | ||
| ... | @@ -4914,7 +4960,7 @@ fn validateStructInit( | ... | @@ -4914,7 +4960,7 @@ fn validateStructInit( |
| 4914 | if (block.is_comptime and | 4960 | if (block.is_comptime and |
| 4915 | (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null) | 4961 | (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null) |
| 4916 | { | 4962 | { |
| 4917 | try struct_ty.resolveLayout(mod); | 4963 | try struct_ty.resolveLayout(pt); |
| 4918 | // In this case the only thing we need to do is evaluate the implicit | 4964 | // In this case the only thing we need to do is evaluate the implicit |
| 4919 | // store instructions for default field values, and report any missing fields. | 4965 | // store instructions for default field values, and report any missing fields. |
| 4920 | // Avoid the cost of the extra machinery for detecting a comptime struct init value. | 4966 | // Avoid the cost of the extra machinery for detecting a comptime struct init value. |
| ... | @@ -4922,7 +4968,7 @@ fn validateStructInit( | ... | @@ -4922,7 +4968,7 @@ fn validateStructInit( |
| 4922 | const i: u32 = @intCast(i_usize); | 4968 | const i: u32 = @intCast(i_usize); |
| 4923 | if (field_ptr != .none) continue; | 4969 | if (field_ptr != .none) continue; |
| 4924 | 4970 | ||
| 4925 | try struct_ty.resolveStructFieldInits(mod); | 4971 | try struct_ty.resolveStructFieldInits(pt); |
| 4926 | const default_val = struct_ty.structFieldDefaultValue(i, mod); | 4972 | const default_val = struct_ty.structFieldDefaultValue(i, mod); |
| 4927 | if (default_val.toIntern() == .unreachable_value) { | 4973 | if (default_val.toIntern() == .unreachable_value) { |
| 4928 | const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse { | 4974 | const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse { |
| ... | @@ -4971,7 +5017,7 @@ fn validateStructInit( | ... | @@ -4971,7 +5017,7 @@ fn validateStructInit( |
| 4971 | const air_tags = sema.air_instructions.items(.tag); | 5017 | const air_tags = sema.air_instructions.items(.tag); |
| 4972 | const air_datas = sema.air_instructions.items(.data); | 5018 | const air_datas = sema.air_instructions.items(.data); |
| 4973 | 5019 | ||
| 4974 | try struct_ty.resolveStructFieldInits(mod); | 5020 | try struct_ty.resolveStructFieldInits(pt); |
| 4975 | 5021 | ||
| 4976 | // We collect the comptime field values in case the struct initialization | 5022 | // We collect the comptime field values in case the struct initialization |
| 4977 | // ends up being comptime-known. | 5023 | // ends up being comptime-known. |
| ... | @@ -5094,7 +5140,7 @@ fn validateStructInit( | ... | @@ -5094,7 +5140,7 @@ fn validateStructInit( |
| 5094 | for (block.instructions.items[first_block_index..]) |cur_inst| { | 5140 | for (block.instructions.items[first_block_index..]) |cur_inst| { |
| 5095 | while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) { | 5141 | while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) { |
| 5096 | const field_ty = struct_ty.structFieldType(field_indices[init_index], mod); | 5142 | const field_ty = struct_ty.structFieldType(field_indices[init_index], mod); |
| 5097 | if (try field_ty.onePossibleValue(mod)) |_| continue; | 5143 | if (try field_ty.onePossibleValue(pt)) |_| continue; |
| 5098 | field_ptr_ref = sema.inst_map.get(instrs[init_index]).?; | 5144 | field_ptr_ref = sema.inst_map.get(instrs[init_index]).?; |
| 5099 | } | 5145 | } |
| 5100 | switch (air_tags[@intFromEnum(cur_inst)]) { | 5146 | switch (air_tags[@intFromEnum(cur_inst)]) { |
| ... | @@ -5122,7 +5168,7 @@ fn validateStructInit( | ... | @@ -5122,7 +5168,7 @@ fn validateStructInit( |
| 5122 | } | 5168 | } |
| 5123 | block.instructions.shrinkRetainingCapacity(block_index); | 5169 | block.instructions.shrinkRetainingCapacity(block_index); |
| 5124 | 5170 | ||
| 5125 | const struct_val = try mod.intern(.{ .aggregate = .{ | 5171 | const struct_val = try pt.intern(.{ .aggregate = .{ |
| 5126 | .ty = struct_ty.toIntern(), | 5172 | .ty = struct_ty.toIntern(), |
| 5127 | .storage = .{ .elems = field_values }, | 5173 | .storage = .{ .elems = field_values }, |
| 5128 | } }); | 5174 | } }); |
| ... | @@ -5130,7 +5176,7 @@ fn validateStructInit( | ... | @@ -5130,7 +5176,7 @@ fn validateStructInit( |
| 5130 | try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store); | 5176 | try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store); |
| 5131 | return; | 5177 | return; |
| 5132 | } | 5178 | } |
| 5133 | try struct_ty.resolveLayout(mod); | 5179 | try struct_ty.resolveLayout(pt); |
| 5134 | 5180 | ||
| 5135 | // Our task is to insert `store` instructions for all the default field values. | 5181 | // Our task is to insert `store` instructions for all the default field values. |
| 5136 | for (found_fields, 0..) |field_ptr, i| { | 5182 | for (found_fields, 0..) |field_ptr, i| { |
| ... | @@ -5152,7 +5198,8 @@ fn zirValidatePtrArrayInit( | ... | @@ -5152,7 +5198,8 @@ fn zirValidatePtrArrayInit( |
| 5152 | block: *Block, | 5198 | block: *Block, |
| 5153 | inst: Zir.Inst.Index, | 5199 | inst: Zir.Inst.Index, |
| 5154 | ) CompileError!void { | 5200 | ) CompileError!void { |
| 5155 | const mod = sema.mod; | 5201 | const pt = sema.pt; |
| 5202 | const mod = pt.zcu; | ||
| 5156 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5203 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5157 | const init_src = block.nodeOffset(validate_inst.src_node); | 5204 | const init_src = block.nodeOffset(validate_inst.src_node); |
| 5158 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); | 5205 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); |
| ... | @@ -5175,7 +5222,7 @@ fn zirValidatePtrArrayInit( | ... | @@ -5175,7 +5222,7 @@ fn zirValidatePtrArrayInit( |
| 5175 | var root_msg: ?*Module.ErrorMsg = null; | 5222 | var root_msg: ?*Module.ErrorMsg = null; |
| 5176 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); | 5223 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 5177 | 5224 | ||
| 5178 | try array_ty.resolveStructFieldInits(mod); | 5225 | try array_ty.resolveStructFieldInits(pt); |
| 5179 | var i = instrs.len; | 5226 | var i = instrs.len; |
| 5180 | while (i < array_len) : (i += 1) { | 5227 | while (i < array_len) : (i += 1) { |
| 5181 | const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern(); | 5228 | const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern(); |
| ... | @@ -5218,7 +5265,7 @@ fn zirValidatePtrArrayInit( | ... | @@ -5218,7 +5265,7 @@ fn zirValidatePtrArrayInit( |
| 5218 | // sentinel-terminated array, the sentinel will not have been populated by | 5265 | // sentinel-terminated array, the sentinel will not have been populated by |
| 5219 | // any ZIR instructions at comptime; we need to do that here. | 5266 | // any ZIR instructions at comptime; we need to do that here. |
| 5220 | if (array_ty.sentinel(mod)) |sentinel_val| { | 5267 | if (array_ty.sentinel(mod)) |sentinel_val| { |
| 5221 | const array_len_ref = try mod.intRef(Type.usize, array_len); | 5268 | const array_len_ref = try pt.intRef(Type.usize, array_len); |
| 5222 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); | 5269 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); |
| 5223 | const sentinel = Air.internedToRef(sentinel_val.toIntern()); | 5270 | const sentinel = Air.internedToRef(sentinel_val.toIntern()); |
| 5224 | try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); | 5271 | try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); |
| ... | @@ -5244,8 +5291,8 @@ fn zirValidatePtrArrayInit( | ... | @@ -5244,8 +5291,8 @@ fn zirValidatePtrArrayInit( |
| 5244 | 5291 | ||
| 5245 | if (array_ty.isTuple(mod)) { | 5292 | if (array_ty.isTuple(mod)) { |
| 5246 | if (array_ty.structFieldIsComptime(i, mod)) | 5293 | if (array_ty.structFieldIsComptime(i, mod)) |
| 5247 | try array_ty.resolveStructFieldInits(mod); | 5294 | try array_ty.resolveStructFieldInits(pt); |
| 5248 | if (try array_ty.structFieldValueComptime(mod, i)) |opv| { | 5295 | if (try array_ty.structFieldValueComptime(pt, i)) |opv| { |
| 5249 | element_vals[i] = opv.toIntern(); | 5296 | element_vals[i] = opv.toIntern(); |
| 5250 | continue; | 5297 | continue; |
| 5251 | } | 5298 | } |
| ... | @@ -5347,7 +5394,7 @@ fn zirValidatePtrArrayInit( | ... | @@ -5347,7 +5394,7 @@ fn zirValidatePtrArrayInit( |
| 5347 | } | 5394 | } |
| 5348 | block.instructions.shrinkRetainingCapacity(block_index); | 5395 | block.instructions.shrinkRetainingCapacity(block_index); |
| 5349 | 5396 | ||
| 5350 | const array_val = try mod.intern(.{ .aggregate = .{ | 5397 | const array_val = try pt.intern(.{ .aggregate = .{ |
| 5351 | .ty = array_ty.toIntern(), | 5398 | .ty = array_ty.toIntern(), |
| 5352 | .storage = .{ .elems = element_vals }, | 5399 | .storage = .{ .elems = element_vals }, |
| 5353 | } }); | 5400 | } }); |
| ... | @@ -5357,18 +5404,19 @@ fn zirValidatePtrArrayInit( | ... | @@ -5357,18 +5404,19 @@ fn zirValidatePtrArrayInit( |
| 5357 | } | 5404 | } |
| 5358 | 5405 | ||
| 5359 | fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 5406 | fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5360 | const mod = sema.mod; | 5407 | const pt = sema.pt; |
| 5408 | const mod = pt.zcu; | ||
| 5361 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 5409 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 5362 | const src = block.nodeOffset(inst_data.src_node); | 5410 | const src = block.nodeOffset(inst_data.src_node); |
| 5363 | const operand = try sema.resolveInst(inst_data.operand); | 5411 | const operand = try sema.resolveInst(inst_data.operand); |
| 5364 | const operand_ty = sema.typeOf(operand); | 5412 | const operand_ty = sema.typeOf(operand); |
| 5365 | 5413 | ||
| 5366 | if (operand_ty.zigTypeTag(mod) != .Pointer) { | 5414 | if (operand_ty.zigTypeTag(mod) != .Pointer) { |
| 5367 | return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(mod)}); | 5415 | return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(pt)}); |
| 5368 | } else switch (operand_ty.ptrSize(mod)) { | 5416 | } else switch (operand_ty.ptrSize(mod)) { |
| 5369 | .One, .C => {}, | 5417 | .One, .C => {}, |
| 5370 | .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(mod)}), | 5418 | .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(pt)}), |
| 5371 | .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(mod)}), | 5419 | .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(pt)}), |
| 5372 | } | 5420 | } |
| 5373 | 5421 | ||
| 5374 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) { | 5422 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) { |
| ... | @@ -5386,7 +5434,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -5386,7 +5434,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5386 | const msg = try sema.errMsg( | 5434 | const msg = try sema.errMsg( |
| 5387 | src, | 5435 | src, |
| 5388 | "values of type '{}' must be comptime-known, but operand value is runtime-known", | 5436 | "values of type '{}' must be comptime-known, but operand value is runtime-known", |
| 5389 | .{elem_ty.fmt(mod)}, | 5437 | .{elem_ty.fmt(pt)}, |
| 5390 | ); | 5438 | ); |
| 5391 | errdefer msg.destroy(sema.gpa); | 5439 | errdefer msg.destroy(sema.gpa); |
| 5392 | 5440 | ||
| ... | @@ -5398,7 +5446,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -5398,7 +5446,8 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5398 | } | 5446 | } |
| 5399 | 5447 | ||
| 5400 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 5448 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5401 | const mod = sema.mod; | 5449 | const pt = sema.pt; |
| 5450 | const mod = pt.zcu; | ||
| 5402 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5451 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5403 | const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data; | 5452 | const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data; |
| 5404 | const src = block.nodeOffset(inst_data.src_node); | 5453 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -5414,7 +5463,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -5414,7 +5463,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5414 | 5463 | ||
| 5415 | if (!can_destructure) { | 5464 | if (!can_destructure) { |
| 5416 | return sema.failWithOwnedErrorMsg(block, msg: { | 5465 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5417 | const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(mod)}); | 5466 | const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)}); |
| 5418 | errdefer msg.destroy(sema.gpa); | 5467 | errdefer msg.destroy(sema.gpa); |
| 5419 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); | 5468 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); |
| 5420 | break :msg msg; | 5469 | break :msg msg; |
| ... | @@ -5441,7 +5490,8 @@ fn failWithBadMemberAccess( | ... | @@ -5441,7 +5490,8 @@ fn failWithBadMemberAccess( |
| 5441 | field_src: LazySrcLoc, | 5490 | field_src: LazySrcLoc, |
| 5442 | field_name: InternPool.NullTerminatedString, | 5491 | field_name: InternPool.NullTerminatedString, |
| 5443 | ) CompileError { | 5492 | ) CompileError { |
| 5444 | const mod = sema.mod; | 5493 | const pt = sema.pt; |
| 5494 | const mod = pt.zcu; | ||
| 5445 | const kw_name = switch (agg_ty.zigTypeTag(mod)) { | 5495 | const kw_name = switch (agg_ty.zigTypeTag(mod)) { |
| 5446 | .Union => "union", | 5496 | .Union => "union", |
| 5447 | .Struct => "struct", | 5497 | .Struct => "struct", |
| ... | @@ -5451,12 +5501,12 @@ fn failWithBadMemberAccess( | ... | @@ -5451,12 +5501,12 @@ fn failWithBadMemberAccess( |
| 5451 | }; | 5501 | }; |
| 5452 | if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { | 5502 | if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { |
| 5453 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ | 5503 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ |
| 5454 | agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), | 5504 | agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool), |
| 5455 | }); | 5505 | }); |
| 5456 | }; | 5506 | }; |
| 5457 | 5507 | ||
| 5458 | return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{ | 5508 | return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{ |
| 5459 | kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), | 5509 | kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool), |
| 5460 | }); | 5510 | }); |
| 5461 | } | 5511 | } |
| 5462 | 5512 | ||
| ... | @@ -5468,8 +5518,8 @@ fn failWithBadStructFieldAccess( | ... | @@ -5468,8 +5518,8 @@ fn failWithBadStructFieldAccess( |
| 5468 | field_src: LazySrcLoc, | 5518 | field_src: LazySrcLoc, |
| 5469 | field_name: InternPool.NullTerminatedString, | 5519 | field_name: InternPool.NullTerminatedString, |
| 5470 | ) CompileError { | 5520 | ) CompileError { |
| 5471 | const zcu = sema.mod; | 5521 | const zcu = sema.pt.zcu; |
| 5472 | const gpa = sema.gpa; | 5522 | const ip = &zcu.intern_pool; |
| 5473 | const decl = zcu.declPtr(struct_type.decl.unwrap().?); | 5523 | const decl = zcu.declPtr(struct_type.decl.unwrap().?); |
| 5474 | const fqn = try decl.fullyQualifiedName(zcu); | 5524 | const fqn = try decl.fullyQualifiedName(zcu); |
| 5475 | 5525 | ||
| ... | @@ -5477,9 +5527,9 @@ fn failWithBadStructFieldAccess( | ... | @@ -5477,9 +5527,9 @@ fn failWithBadStructFieldAccess( |
| 5477 | const msg = try sema.errMsg( | 5527 | const msg = try sema.errMsg( |
| 5478 | field_src, | 5528 | field_src, |
| 5479 | "no field named '{}' in struct '{}'", | 5529 | "no field named '{}' in struct '{}'", |
| 5480 | .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) }, | 5530 | .{ field_name.fmt(ip), fqn.fmt(ip) }, |
| 5481 | ); | 5531 | ); |
| 5482 | errdefer msg.destroy(gpa); | 5532 | errdefer msg.destroy(sema.gpa); |
| 5483 | try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{}); | 5533 | try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{}); |
| 5484 | break :msg msg; | 5534 | break :msg msg; |
| 5485 | }; | 5535 | }; |
| ... | @@ -5494,7 +5544,8 @@ fn failWithBadUnionFieldAccess( | ... | @@ -5494,7 +5544,8 @@ fn failWithBadUnionFieldAccess( |
| 5494 | field_src: LazySrcLoc, | 5544 | field_src: LazySrcLoc, |
| 5495 | field_name: InternPool.NullTerminatedString, | 5545 | field_name: InternPool.NullTerminatedString, |
| 5496 | ) CompileError { | 5546 | ) CompileError { |
| 5497 | const zcu = sema.mod; | 5547 | const zcu = sema.pt.zcu; |
| 5548 | const ip = &zcu.intern_pool; | ||
| 5498 | const gpa = sema.gpa; | 5549 | const gpa = sema.gpa; |
| 5499 | 5550 | ||
| 5500 | const decl = zcu.declPtr(union_obj.decl); | 5551 | const decl = zcu.declPtr(union_obj.decl); |
| ... | @@ -5504,7 +5555,7 @@ fn failWithBadUnionFieldAccess( | ... | @@ -5504,7 +5555,7 @@ fn failWithBadUnionFieldAccess( |
| 5504 | const msg = try sema.errMsg( | 5555 | const msg = try sema.errMsg( |
| 5505 | field_src, | 5556 | field_src, |
| 5506 | "no field named '{}' in union '{}'", | 5557 | "no field named '{}' in union '{}'", |
| 5507 | .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) }, | 5558 | .{ field_name.fmt(ip), fqn.fmt(ip) }, |
| 5508 | ); | 5559 | ); |
| 5509 | errdefer msg.destroy(gpa); | 5560 | errdefer msg.destroy(gpa); |
| 5510 | try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{}); | 5561 | try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{}); |
| ... | @@ -5514,9 +5565,9 @@ fn failWithBadUnionFieldAccess( | ... | @@ -5514,9 +5565,9 @@ fn failWithBadUnionFieldAccess( |
| 5514 | } | 5565 | } |
| 5515 | 5566 | ||
| 5516 | fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void { | 5567 | fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void { |
| 5517 | const mod = sema.mod; | 5568 | const zcu = sema.pt.zcu; |
| 5518 | const src_loc = decl_ty.srcLocOrNull(mod) orelse return; | 5569 | const src_loc = decl_ty.srcLocOrNull(zcu) orelse return; |
| 5519 | const category = switch (decl_ty.zigTypeTag(mod)) { | 5570 | const category = switch (decl_ty.zigTypeTag(zcu)) { |
| 5520 | .Union => "union", | 5571 | .Union => "union", |
| 5521 | .Struct => "struct", | 5572 | .Struct => "struct", |
| 5522 | .Enum => "enum", | 5573 | .Enum => "enum", |
| ... | @@ -5575,7 +5626,8 @@ fn storeToInferredAllocComptime( | ... | @@ -5575,7 +5626,8 @@ fn storeToInferredAllocComptime( |
| 5575 | operand: Air.Inst.Ref, | 5626 | operand: Air.Inst.Ref, |
| 5576 | iac: *Air.Inst.Data.InferredAllocComptime, | 5627 | iac: *Air.Inst.Data.InferredAllocComptime, |
| 5577 | ) CompileError!void { | 5628 | ) CompileError!void { |
| 5578 | const zcu = sema.mod; | 5629 | const pt = sema.pt; |
| 5630 | const zcu = pt.zcu; | ||
| 5579 | const operand_ty = sema.typeOf(operand); | 5631 | const operand_ty = sema.typeOf(operand); |
| 5580 | // There will be only one store_to_inferred_ptr because we are running at comptime. | 5632 | // There will be only one store_to_inferred_ptr because we are running at comptime. |
| 5581 | // The alloc will turn into a Decl or a ComptimeAlloc. | 5633 | // The alloc will turn into a Decl or a ComptimeAlloc. |
| ... | @@ -5584,7 +5636,7 @@ fn storeToInferredAllocComptime( | ... | @@ -5584,7 +5636,7 @@ fn storeToInferredAllocComptime( |
| 5584 | .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known", | 5636 | .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known", |
| 5585 | }); | 5637 | }); |
| 5586 | }; | 5638 | }; |
| 5587 | const alloc_ty = try zcu.ptrTypeSema(.{ | 5639 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 5588 | .child = operand_ty.toIntern(), | 5640 | .child = operand_ty.toIntern(), |
| 5589 | .flags = .{ | 5641 | .flags = .{ |
| 5590 | .alignment = iac.alignment, | 5642 | .alignment = iac.alignment, |
| ... | @@ -5592,7 +5644,7 @@ fn storeToInferredAllocComptime( | ... | @@ -5592,7 +5644,7 @@ fn storeToInferredAllocComptime( |
| 5592 | }, | 5644 | }, |
| 5593 | }); | 5645 | }); |
| 5594 | if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) { | 5646 | if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) { |
| 5595 | iac.ptr = try zcu.intern(.{ .ptr = .{ | 5647 | iac.ptr = try pt.intern(.{ .ptr = .{ |
| 5596 | .ty = alloc_ty.toIntern(), | 5648 | .ty = alloc_ty.toIntern(), |
| 5597 | .base_addr = .{ .anon_decl = .{ | 5649 | .base_addr = .{ .anon_decl = .{ |
| 5598 | .val = operand_val.toIntern(), | 5650 | .val = operand_val.toIntern(), |
| ... | @@ -5603,7 +5655,7 @@ fn storeToInferredAllocComptime( | ... | @@ -5603,7 +5655,7 @@ fn storeToInferredAllocComptime( |
| 5603 | } else { | 5655 | } else { |
| 5604 | const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment); | 5656 | const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment); |
| 5605 | sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() }; | 5657 | sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() }; |
| 5606 | iac.ptr = try zcu.intern(.{ .ptr = .{ | 5658 | iac.ptr = try pt.intern(.{ .ptr = .{ |
| 5607 | .ty = alloc_ty.toIntern(), | 5659 | .ty = alloc_ty.toIntern(), |
| 5608 | .base_addr = .{ .comptime_alloc = alloc_index }, | 5660 | .base_addr = .{ .comptime_alloc = alloc_index }, |
| 5609 | .byte_offset = 0, | 5661 | .byte_offset = 0, |
| ... | @@ -5624,7 +5676,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v | ... | @@ -5624,7 +5676,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v |
| 5624 | const tracy = trace(@src()); | 5676 | const tracy = trace(@src()); |
| 5625 | defer tracy.end(); | 5677 | defer tracy.end(); |
| 5626 | 5678 | ||
| 5627 | const mod = sema.mod; | 5679 | const pt = sema.pt; |
| 5680 | const mod = pt.zcu; | ||
| 5628 | const zir_tags = sema.code.instructions.items(.tag); | 5681 | const zir_tags = sema.code.instructions.items(.tag); |
| 5629 | const zir_datas = sema.code.instructions.items(.data); | 5682 | const zir_datas = sema.code.instructions.items(.data); |
| 5630 | const inst_data = zir_datas[@intFromEnum(inst)].pl_node; | 5683 | const inst_data = zir_datas[@intFromEnum(inst)].pl_node; |
| ... | @@ -5662,23 +5715,23 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v | ... | @@ -5662,23 +5715,23 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v |
| 5662 | fn zirStr(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5715 | fn zirStr(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5663 | const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code); | 5716 | const bytes = sema.code.instructions.items(.data)[@intFromEnum(inst)].str.get(sema.code); |
| 5664 | return sema.addStrLit( | 5717 | return sema.addStrLit( |
| 5665 | try sema.mod.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls), | 5718 | try sema.pt.zcu.intern_pool.getOrPutString(sema.gpa, bytes, .maybe_embedded_nulls), |
| 5666 | bytes.len, | 5719 | bytes.len, |
| 5667 | ); | 5720 | ); |
| 5668 | } | 5721 | } |
| 5669 | 5722 | ||
| 5670 | fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref { | 5723 | fn addNullTerminatedStrLit(sema: *Sema, string: InternPool.NullTerminatedString) CompileError!Air.Inst.Ref { |
| 5671 | return sema.addStrLit(string.toString(), string.length(&sema.mod.intern_pool)); | 5724 | return sema.addStrLit(string.toString(), string.length(&sema.pt.zcu.intern_pool)); |
| 5672 | } | 5725 | } |
| 5673 | 5726 | ||
| 5674 | fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref { | 5727 | fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.Inst.Ref { |
| 5675 | const mod = sema.mod; | 5728 | const pt = sema.pt; |
| 5676 | const array_ty = try mod.arrayType(.{ | 5729 | const array_ty = try pt.arrayType(.{ |
| 5677 | .len = len, | 5730 | .len = len, |
| 5678 | .sentinel = .zero_u8, | 5731 | .sentinel = .zero_u8, |
| 5679 | .child = .u8_type, | 5732 | .child = .u8_type, |
| 5680 | }); | 5733 | }); |
| 5681 | const val = try mod.intern(.{ .aggregate = .{ | 5734 | const val = try pt.intern(.{ .aggregate = .{ |
| 5682 | .ty = array_ty.toIntern(), | 5735 | .ty = array_ty.toIntern(), |
| 5683 | .storage = .{ .bytes = string }, | 5736 | .storage = .{ .bytes = string }, |
| 5684 | } }); | 5737 | } }); |
| ... | @@ -5690,16 +5743,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { | ... | @@ -5690,16 +5743,16 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { |
| 5690 | } | 5743 | } |
| 5691 | 5744 | ||
| 5692 | fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { | 5745 | fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { |
| 5693 | const mod = sema.mod; | 5746 | const pt = sema.pt; |
| 5694 | const ptr_ty = (try mod.ptrTypeSema(.{ | 5747 | const ptr_ty = (try pt.ptrTypeSema(.{ |
| 5695 | .child = mod.intern_pool.typeOf(val), | 5748 | .child = pt.zcu.intern_pool.typeOf(val), |
| 5696 | .flags = .{ | 5749 | .flags = .{ |
| 5697 | .alignment = .none, | 5750 | .alignment = .none, |
| 5698 | .is_const = true, | 5751 | .is_const = true, |
| 5699 | .address_space = .generic, | 5752 | .address_space = .generic, |
| 5700 | }, | 5753 | }, |
| 5701 | })).toIntern(); | 5754 | })).toIntern(); |
| 5702 | return mod.intern(.{ .ptr = .{ | 5755 | return pt.intern(.{ .ptr = .{ |
| 5703 | .ty = ptr_ty, | 5756 | .ty = ptr_ty, |
| 5704 | .base_addr = .{ .anon_decl = .{ | 5757 | .base_addr = .{ .anon_decl = .{ |
| 5705 | .val = val, | 5758 | .val = val, |
| ... | @@ -5715,7 +5768,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -5715,7 +5768,7 @@ fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 5715 | defer tracy.end(); | 5768 | defer tracy.end(); |
| 5716 | 5769 | ||
| 5717 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int; | 5770 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].int; |
| 5718 | return sema.mod.intRef(Type.comptime_int, int); | 5771 | return sema.pt.intRef(Type.comptime_int, int); |
| 5719 | } | 5772 | } |
| 5720 | 5773 | ||
| 5721 | fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5774 | fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5723,7 +5776,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -5723,7 +5776,6 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 5723 | const tracy = trace(@src()); | 5776 | const tracy = trace(@src()); |
| 5724 | defer tracy.end(); | 5777 | defer tracy.end(); |
| 5725 | 5778 | ||
| 5726 | const mod = sema.mod; | ||
| 5727 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str; | 5779 | const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str; |
| 5728 | const byte_count = int.len * @sizeOf(std.math.big.Limb); | 5780 | const byte_count = int.len * @sizeOf(std.math.big.Limb); |
| 5729 | const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count]; | 5781 | const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count]; |
| ... | @@ -5734,7 +5786,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -5734,7 +5786,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 5734 | const limbs = try sema.arena.alloc(std.math.big.Limb, int.len); | 5786 | const limbs = try sema.arena.alloc(std.math.big.Limb, int.len); |
| 5735 | @memcpy(mem.sliceAsBytes(limbs), limb_bytes); | 5787 | @memcpy(mem.sliceAsBytes(limbs), limb_bytes); |
| 5736 | 5788 | ||
| 5737 | return Air.internedToRef((try mod.intValue_big(Type.comptime_int, .{ | 5789 | return Air.internedToRef((try sema.pt.intValue_big(Type.comptime_int, .{ |
| 5738 | .limbs = limbs, | 5790 | .limbs = limbs, |
| 5739 | .positive = true, | 5791 | .positive = true, |
| 5740 | })).toIntern()); | 5792 | })).toIntern()); |
| ... | @@ -5743,7 +5795,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -5743,7 +5795,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 5743 | fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5795 | fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5744 | _ = block; | 5796 | _ = block; |
| 5745 | const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float; | 5797 | const number = sema.code.instructions.items(.data)[@intFromEnum(inst)].float; |
| 5746 | return Air.internedToRef((try sema.mod.floatValue( | 5798 | return Air.internedToRef((try sema.pt.floatValue( |
| 5747 | Type.comptime_float, | 5799 | Type.comptime_float, |
| 5748 | number, | 5800 | number, |
| 5749 | )).toIntern()); | 5801 | )).toIntern()); |
| ... | @@ -5754,7 +5806,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -5754,7 +5806,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 5754 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5806 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5755 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; | 5807 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; |
| 5756 | const number = extra.get(); | 5808 | const number = extra.get(); |
| 5757 | return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern()); | 5809 | return Air.internedToRef((try sema.pt.floatValue(Type.comptime_float, number)).toIntern()); |
| 5758 | } | 5810 | } |
| 5759 | 5811 | ||
| 5760 | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 5812 | fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -5775,10 +5827,11 @@ fn zirCompileLog( | ... | @@ -5775,10 +5827,11 @@ fn zirCompileLog( |
| 5775 | block: *Block, | 5827 | block: *Block, |
| 5776 | extended: Zir.Inst.Extended.InstData, | 5828 | extended: Zir.Inst.Extended.InstData, |
| 5777 | ) CompileError!Air.Inst.Ref { | 5829 | ) CompileError!Air.Inst.Ref { |
| 5778 | const mod = sema.mod; | 5830 | const pt = sema.pt; |
| 5831 | const mod = pt.zcu; | ||
| 5779 | 5832 | ||
| 5780 | var managed = mod.compile_log_text.toManaged(sema.gpa); | 5833 | var managed = mod.compile_log_text.toManaged(sema.gpa); |
| 5781 | defer sema.mod.compile_log_text = managed.moveToUnmanaged(); | 5834 | defer pt.zcu.compile_log_text = managed.moveToUnmanaged(); |
| 5782 | const writer = managed.writer(); | 5835 | const writer = managed.writer(); |
| 5783 | 5836 | ||
| 5784 | const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); | 5837 | const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); |
| ... | @@ -5792,10 +5845,10 @@ fn zirCompileLog( | ... | @@ -5792,10 +5845,10 @@ fn zirCompileLog( |
| 5792 | const arg_ty = sema.typeOf(arg); | 5845 | const arg_ty = sema.typeOf(arg); |
| 5793 | if (try sema.resolveValueResolveLazy(arg)) |val| { | 5846 | if (try sema.resolveValueResolveLazy(arg)) |val| { |
| 5794 | try writer.print("@as({}, {})", .{ | 5847 | try writer.print("@as({}, {})", .{ |
| 5795 | arg_ty.fmt(mod), val.fmtValue(mod, sema), | 5848 | arg_ty.fmt(pt), val.fmtValue(pt, sema), |
| 5796 | }); | 5849 | }); |
| 5797 | } else { | 5850 | } else { |
| 5798 | try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)}); | 5851 | try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)}); |
| 5799 | } | 5852 | } |
| 5800 | } | 5853 | } |
| 5801 | try writer.print("\n", .{}); | 5854 | try writer.print("\n", .{}); |
| ... | @@ -5835,7 +5888,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -5835,7 +5888,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5835 | const tracy = trace(@src()); | 5888 | const tracy = trace(@src()); |
| 5836 | defer tracy.end(); | 5889 | defer tracy.end(); |
| 5837 | 5890 | ||
| 5838 | const mod = sema.mod; | 5891 | const pt = sema.pt; |
| 5892 | const mod = pt.zcu; | ||
| 5839 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5893 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5840 | const src = parent_block.nodeOffset(inst_data.src_node); | 5894 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 5841 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 5895 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| ... | @@ -5906,7 +5960,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5906,7 +5960,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5906 | const tracy = trace(@src()); | 5960 | const tracy = trace(@src()); |
| 5907 | defer tracy.end(); | 5961 | defer tracy.end(); |
| 5908 | 5962 | ||
| 5909 | const zcu = sema.mod; | 5963 | const pt = sema.pt; |
| 5964 | const zcu = pt.zcu; | ||
| 5910 | const comp = zcu.comp; | 5965 | const comp = zcu.comp; |
| 5911 | const gpa = sema.gpa; | 5966 | const gpa = sema.gpa; |
| 5912 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 5967 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | @@ -6005,7 +6060,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6005,7 +6060,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 6005 | zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err| | 6060 | zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err| |
| 6006 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6061 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6007 | 6062 | ||
| 6008 | try zcu.ensureFileAnalyzed(result.file_index); | 6063 | try pt.ensureFileAnalyzed(result.file_index); |
| 6009 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; | 6064 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; |
| 6010 | return sema.analyzeDeclVal(parent_block, src, file_root_decl_index); | 6065 | return sema.analyzeDeclVal(parent_block, src, file_root_decl_index); |
| 6011 | } | 6066 | } |
| ... | @@ -6147,7 +6202,8 @@ fn resolveAnalyzedBlock( | ... | @@ -6147,7 +6202,8 @@ fn resolveAnalyzedBlock( |
| 6147 | defer tracy.end(); | 6202 | defer tracy.end(); |
| 6148 | 6203 | ||
| 6149 | const gpa = sema.gpa; | 6204 | const gpa = sema.gpa; |
| 6150 | const mod = sema.mod; | 6205 | const pt = sema.pt; |
| 6206 | const mod = pt.zcu; | ||
| 6151 | 6207 | ||
| 6152 | // Blocks must terminate with noreturn instruction. | 6208 | // Blocks must terminate with noreturn instruction. |
| 6153 | assert(child_block.instructions.items.len != 0); | 6209 | assert(child_block.instructions.items.len != 0); |
| ... | @@ -6258,7 +6314,7 @@ fn resolveAnalyzedBlock( | ... | @@ -6258,7 +6314,7 @@ fn resolveAnalyzedBlock( |
| 6258 | const type_src = src; // TODO: better source location | 6314 | const type_src = src; // TODO: better source location |
| 6259 | if (try sema.typeRequiresComptime(resolved_ty)) { | 6315 | if (try sema.typeRequiresComptime(resolved_ty)) { |
| 6260 | const msg = msg: { | 6316 | const msg = msg: { |
| 6261 | const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)}); | 6317 | const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(pt)}); |
| 6262 | errdefer msg.destroy(sema.gpa); | 6318 | errdefer msg.destroy(sema.gpa); |
| 6263 | 6319 | ||
| 6264 | const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?; | 6320 | const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?; |
| ... | @@ -6353,7 +6409,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -6353,7 +6409,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 6353 | const tracy = trace(@src()); | 6409 | const tracy = trace(@src()); |
| 6354 | defer tracy.end(); | 6410 | defer tracy.end(); |
| 6355 | 6411 | ||
| 6356 | const mod = sema.mod; | 6412 | const pt = sema.pt; |
| 6413 | const mod = pt.zcu; | ||
| 6357 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 6414 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6358 | const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; | 6415 | const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; |
| 6359 | const src = block.nodeOffset(inst_data.src_node); | 6416 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -6388,7 +6445,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6388,7 +6445,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6388 | const tracy = trace(@src()); | 6445 | const tracy = trace(@src()); |
| 6389 | defer tracy.end(); | 6446 | defer tracy.end(); |
| 6390 | 6447 | ||
| 6391 | const mod = sema.mod; | 6448 | const pt = sema.pt; |
| 6449 | const mod = pt.zcu; | ||
| 6392 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 6450 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6393 | const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data; | 6451 | const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data; |
| 6394 | const src = block.nodeOffset(inst_data.src_node); | 6452 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -6421,7 +6479,8 @@ pub fn analyzeExport( | ... | @@ -6421,7 +6479,8 @@ pub fn analyzeExport( |
| 6421 | exported_decl_index: InternPool.DeclIndex, | 6479 | exported_decl_index: InternPool.DeclIndex, |
| 6422 | ) !void { | 6480 | ) !void { |
| 6423 | const gpa = sema.gpa; | 6481 | const gpa = sema.gpa; |
| 6424 | const mod = sema.mod; | 6482 | const pt = sema.pt; |
| 6483 | const mod = pt.zcu; | ||
| 6425 | 6484 | ||
| 6426 | if (options.linkage == .internal) | 6485 | if (options.linkage == .internal) |
| 6427 | return; | 6486 | return; |
| ... | @@ -6433,7 +6492,7 @@ pub fn analyzeExport( | ... | @@ -6433,7 +6492,7 @@ pub fn analyzeExport( |
| 6433 | 6492 | ||
| 6434 | if (!try sema.validateExternType(export_ty, .other)) { | 6493 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6435 | const msg = msg: { | 6494 | const msg = msg: { |
| 6436 | const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(mod)}); | 6495 | const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)}); |
| 6437 | errdefer msg.destroy(gpa); | 6496 | errdefer msg.destroy(gpa); |
| 6438 | 6497 | ||
| 6439 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); | 6498 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); |
| ... | @@ -6460,7 +6519,8 @@ pub fn analyzeExport( | ... | @@ -6460,7 +6519,8 @@ pub fn analyzeExport( |
| 6460 | } | 6519 | } |
| 6461 | 6520 | ||
| 6462 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6521 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 6463 | const mod = sema.mod; | 6522 | const pt = sema.pt; |
| 6523 | const mod = pt.zcu; | ||
| 6464 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 6524 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 6465 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 6525 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 6466 | const src = block.nodeOffset(extra.node); | 6526 | const src = block.nodeOffset(extra.node); |
| ... | @@ -6502,7 +6562,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst | ... | @@ -6502,7 +6562,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 6502 | } | 6562 | } |
| 6503 | 6563 | ||
| 6504 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6564 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 6505 | const mod = sema.mod; | 6565 | const pt = sema.pt; |
| 6566 | const mod = pt.zcu; | ||
| 6506 | const ip = &mod.intern_pool; | 6567 | const ip = &mod.intern_pool; |
| 6507 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 6568 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 6508 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 6569 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| ... | @@ -6628,7 +6689,8 @@ fn addDbgVar( | ... | @@ -6628,7 +6689,8 @@ fn addDbgVar( |
| 6628 | ) CompileError!void { | 6689 | ) CompileError!void { |
| 6629 | if (block.is_comptime or block.ownerModule().strip) return; | 6690 | if (block.is_comptime or block.ownerModule().strip) return; |
| 6630 | 6691 | ||
| 6631 | const mod = sema.mod; | 6692 | const pt = sema.pt; |
| 6693 | const mod = pt.zcu; | ||
| 6632 | const operand_ty = sema.typeOf(operand); | 6694 | const operand_ty = sema.typeOf(operand); |
| 6633 | const val_ty = switch (air_tag) { | 6695 | const val_ty = switch (air_tag) { |
| 6634 | .dbg_var_ptr => operand_ty.childType(mod), | 6696 | .dbg_var_ptr => operand_ty.childType(mod), |
| ... | @@ -6669,7 +6731,8 @@ fn addDbgVar( | ... | @@ -6669,7 +6731,8 @@ fn addDbgVar( |
| 6669 | } | 6731 | } |
| 6670 | 6732 | ||
| 6671 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6733 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6672 | const mod = sema.mod; | 6734 | const pt = sema.pt; |
| 6735 | const mod = pt.zcu; | ||
| 6673 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 6736 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 6674 | const src = block.tokenOffset(inst_data.src_tok); | 6737 | const src = block.tokenOffset(inst_data.src_tok); |
| 6675 | const decl_name = try mod.intern_pool.getOrPutString( | 6738 | const decl_name = try mod.intern_pool.getOrPutString( |
| ... | @@ -6682,7 +6745,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -6682,7 +6745,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6682 | } | 6745 | } |
| 6683 | 6746 | ||
| 6684 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6747 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6685 | const mod = sema.mod; | 6748 | const pt = sema.pt; |
| 6749 | const mod = pt.zcu; | ||
| 6686 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 6750 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 6687 | const src = block.tokenOffset(inst_data.src_tok); | 6751 | const src = block.tokenOffset(inst_data.src_tok); |
| 6688 | const decl_name = try mod.intern_pool.getOrPutString( | 6752 | const decl_name = try mod.intern_pool.getOrPutString( |
| ... | @@ -6695,7 +6759,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -6695,7 +6759,8 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6695 | } | 6759 | } |
| 6696 | 6760 | ||
| 6697 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex { | 6761 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex { |
| 6698 | const mod = sema.mod; | 6762 | const pt = sema.pt; |
| 6763 | const mod = pt.zcu; | ||
| 6699 | var namespace = block.namespace; | 6764 | var namespace = block.namespace; |
| 6700 | while (true) { | 6765 | while (true) { |
| 6701 | if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| { | 6766 | if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| { |
| ... | @@ -6716,7 +6781,8 @@ fn lookupInNamespace( | ... | @@ -6716,7 +6781,8 @@ fn lookupInNamespace( |
| 6716 | ident_name: InternPool.NullTerminatedString, | 6781 | ident_name: InternPool.NullTerminatedString, |
| 6717 | observe_usingnamespace: bool, | 6782 | observe_usingnamespace: bool, |
| 6718 | ) CompileError!?InternPool.DeclIndex { | 6783 | ) CompileError!?InternPool.DeclIndex { |
| 6719 | const mod = sema.mod; | 6784 | const pt = sema.pt; |
| 6785 | const mod = pt.zcu; | ||
| 6720 | 6786 | ||
| 6721 | const namespace_index = opt_namespace_index.unwrap() orelse return null; | 6787 | const namespace_index = opt_namespace_index.unwrap() orelse return null; |
| 6722 | const namespace = mod.namespacePtr(namespace_index); | 6788 | const namespace = mod.namespacePtr(namespace_index); |
| ... | @@ -6811,7 +6877,8 @@ fn lookupInNamespace( | ... | @@ -6811,7 +6877,8 @@ fn lookupInNamespace( |
| 6811 | } | 6877 | } |
| 6812 | 6878 | ||
| 6813 | fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | 6879 | fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { |
| 6814 | const mod = sema.mod; | 6880 | const pt = sema.pt; |
| 6881 | const mod = pt.zcu; | ||
| 6815 | const func_val = (try sema.resolveValue(func_inst)) orelse return null; | 6882 | const func_val = (try sema.resolveValue(func_inst)) orelse return null; |
| 6816 | if (func_val.isUndef(mod)) return null; | 6883 | if (func_val.isUndef(mod)) return null; |
| 6817 | const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { | 6884 | const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { |
| ... | @@ -6827,18 +6894,19 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | ... | @@ -6827,18 +6894,19 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { |
| 6827 | } | 6894 | } |
| 6828 | 6895 | ||
| 6829 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { | 6896 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { |
| 6830 | const mod = sema.mod; | 6897 | const pt = sema.pt; |
| 6898 | const mod = pt.zcu; | ||
| 6831 | const gpa = sema.gpa; | 6899 | const gpa = sema.gpa; |
| 6832 | 6900 | ||
| 6833 | if (block.is_comptime or block.is_typeof) { | 6901 | if (block.is_comptime or block.is_typeof) { |
| 6834 | const index_val = try mod.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len); | 6902 | const index_val = try pt.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len); |
| 6835 | return Air.internedToRef(index_val.toIntern()); | 6903 | return Air.internedToRef(index_val.toIntern()); |
| 6836 | } | 6904 | } |
| 6837 | 6905 | ||
| 6838 | if (!block.ownerModule().error_tracing) return .none; | 6906 | if (!block.ownerModule().error_tracing) return .none; |
| 6839 | 6907 | ||
| 6840 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 6908 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 6841 | try stack_trace_ty.resolveFields(mod); | 6909 | try stack_trace_ty.resolveFields(pt); |
| 6842 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); | 6910 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); |
| 6843 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { | 6911 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { |
| 6844 | error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"), | 6912 | error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"), |
| ... | @@ -6864,7 +6932,8 @@ fn popErrorReturnTrace( | ... | @@ -6864,7 +6932,8 @@ fn popErrorReturnTrace( |
| 6864 | operand: Air.Inst.Ref, | 6932 | operand: Air.Inst.Ref, |
| 6865 | saved_error_trace_index: Air.Inst.Ref, | 6933 | saved_error_trace_index: Air.Inst.Ref, |
| 6866 | ) CompileError!void { | 6934 | ) CompileError!void { |
| 6867 | const mod = sema.mod; | 6935 | const pt = sema.pt; |
| 6936 | const mod = pt.zcu; | ||
| 6868 | const gpa = sema.gpa; | 6937 | const gpa = sema.gpa; |
| 6869 | var is_non_error: ?bool = null; | 6938 | var is_non_error: ?bool = null; |
| 6870 | var is_non_error_inst: Air.Inst.Ref = undefined; | 6939 | var is_non_error_inst: Air.Inst.Ref = undefined; |
| ... | @@ -6878,9 +6947,9 @@ fn popErrorReturnTrace( | ... | @@ -6878,9 +6947,9 @@ fn popErrorReturnTrace( |
| 6878 | // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or | 6947 | // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or |
| 6879 | // the result is comptime-known to be a non-error. Either way, pop unconditionally. | 6948 | // the result is comptime-known to be a non-error. Either way, pop unconditionally. |
| 6880 | 6949 | ||
| 6881 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 6950 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 6882 | try stack_trace_ty.resolveFields(mod); | 6951 | try stack_trace_ty.resolveFields(pt); |
| 6883 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); | 6952 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 6884 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); | 6953 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6885 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); | 6954 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); |
| 6886 | const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true); | 6955 | const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true); |
| ... | @@ -6904,9 +6973,9 @@ fn popErrorReturnTrace( | ... | @@ -6904,9 +6973,9 @@ fn popErrorReturnTrace( |
| 6904 | defer then_block.instructions.deinit(gpa); | 6973 | defer then_block.instructions.deinit(gpa); |
| 6905 | 6974 | ||
| 6906 | // If non-error, then pop the error return trace by restoring the index. | 6975 | // If non-error, then pop the error return trace by restoring the index. |
| 6907 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 6976 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 6908 | try stack_trace_ty.resolveFields(mod); | 6977 | try stack_trace_ty.resolveFields(pt); |
| 6909 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); | 6978 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 6910 | const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty); | 6979 | const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6911 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); | 6980 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls); |
| 6912 | const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true); | 6981 | const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true); |
| ... | @@ -6947,7 +7016,8 @@ fn zirCall( | ... | @@ -6947,7 +7016,8 @@ fn zirCall( |
| 6947 | const tracy = trace(@src()); | 7016 | const tracy = trace(@src()); |
| 6948 | defer tracy.end(); | 7017 | defer tracy.end(); |
| 6949 | 7018 | ||
| 6950 | const mod = sema.mod; | 7019 | const pt = sema.pt; |
| 7020 | const mod = pt.zcu; | ||
| 6951 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 7021 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6952 | const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node }); | 7022 | const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node }); |
| 6953 | const call_src = block.nodeOffset(inst_data.src_node); | 7023 | const call_src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -7031,8 +7101,8 @@ fn zirCall( | ... | @@ -7031,8 +7101,8 @@ fn zirCall( |
| 7031 | // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only | 7101 | // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only |
| 7032 | // need to clean-up our own trace if we were passed to a non-error-handling expression. | 7102 | // need to clean-up our own trace if we were passed to a non-error-handling expression. |
| 7033 | if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) { | 7103 | if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) { |
| 7034 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 7104 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 7035 | try stack_trace_ty.resolveFields(mod); | 7105 | try stack_trace_ty.resolveFields(pt); |
| 7036 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls); | 7106 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls); |
| 7037 | const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src); | 7107 | const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src); |
| 7038 | 7108 | ||
| ... | @@ -7065,7 +7135,8 @@ fn checkCallArgumentCount( | ... | @@ -7065,7 +7135,8 @@ fn checkCallArgumentCount( |
| 7065 | total_args: usize, | 7135 | total_args: usize, |
| 7066 | member_fn: bool, | 7136 | member_fn: bool, |
| 7067 | ) !Type { | 7137 | ) !Type { |
| 7068 | const mod = sema.mod; | 7138 | const pt = sema.pt; |
| 7139 | const mod = pt.zcu; | ||
| 7069 | const func_ty = func_ty: { | 7140 | const func_ty = func_ty: { |
| 7070 | switch (callee_ty.zigTypeTag(mod)) { | 7141 | switch (callee_ty.zigTypeTag(mod)) { |
| 7071 | .Fn => break :func_ty callee_ty, | 7142 | .Fn => break :func_ty callee_ty, |
| ... | @@ -7082,7 +7153,7 @@ fn checkCallArgumentCount( | ... | @@ -7082,7 +7153,7 @@ fn checkCallArgumentCount( |
| 7082 | { | 7153 | { |
| 7083 | const msg = msg: { | 7154 | const msg = msg: { |
| 7084 | const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{ | 7155 | const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{ |
| 7085 | callee_ty.fmt(mod), | 7156 | callee_ty.fmt(pt), |
| 7086 | }); | 7157 | }); |
| 7087 | errdefer msg.destroy(sema.gpa); | 7158 | errdefer msg.destroy(sema.gpa); |
| 7088 | try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{}); | 7159 | try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{}); |
| ... | @@ -7093,7 +7164,7 @@ fn checkCallArgumentCount( | ... | @@ -7093,7 +7164,7 @@ fn checkCallArgumentCount( |
| 7093 | }, | 7164 | }, |
| 7094 | else => {}, | 7165 | else => {}, |
| 7095 | } | 7166 | } |
| 7096 | return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(mod)}); | 7167 | return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(pt)}); |
| 7097 | }; | 7168 | }; |
| 7098 | 7169 | ||
| 7099 | const func_ty_info = mod.typeToFunc(func_ty).?; | 7170 | const func_ty_info = mod.typeToFunc(func_ty).?; |
| ... | @@ -7142,7 +7213,8 @@ fn callBuiltin( | ... | @@ -7142,7 +7213,8 @@ fn callBuiltin( |
| 7142 | args: []const Air.Inst.Ref, | 7213 | args: []const Air.Inst.Ref, |
| 7143 | operation: CallOperation, | 7214 | operation: CallOperation, |
| 7144 | ) !void { | 7215 | ) !void { |
| 7145 | const mod = sema.mod; | 7216 | const pt = sema.pt; |
| 7217 | const mod = pt.zcu; | ||
| 7146 | const callee_ty = sema.typeOf(builtin_fn); | 7218 | const callee_ty = sema.typeOf(builtin_fn); |
| 7147 | const func_ty = func_ty: { | 7219 | const func_ty = func_ty: { |
| 7148 | switch (callee_ty.zigTypeTag(mod)) { | 7220 | switch (callee_ty.zigTypeTag(mod)) { |
| ... | @@ -7155,7 +7227,7 @@ fn callBuiltin( | ... | @@ -7155,7 +7227,7 @@ fn callBuiltin( |
| 7155 | }, | 7227 | }, |
| 7156 | else => {}, | 7228 | else => {}, |
| 7157 | } | 7229 | } |
| 7158 | std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(mod)}); | 7230 | std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(pt)}); |
| 7159 | }; | 7231 | }; |
| 7160 | 7232 | ||
| 7161 | const func_ty_info = mod.typeToFunc(func_ty).?; | 7233 | const func_ty_info = mod.typeToFunc(func_ty).?; |
| ... | @@ -7261,7 +7333,8 @@ const CallArgsInfo = union(enum) { | ... | @@ -7261,7 +7333,8 @@ const CallArgsInfo = union(enum) { |
| 7261 | func_ty_info: InternPool.Key.FuncType, | 7333 | func_ty_info: InternPool.Key.FuncType, |
| 7262 | func_inst: Air.Inst.Ref, | 7334 | func_inst: Air.Inst.Ref, |
| 7263 | ) CompileError!Air.Inst.Ref { | 7335 | ) CompileError!Air.Inst.Ref { |
| 7264 | const mod = sema.mod; | 7336 | const pt = sema.pt; |
| 7337 | const mod = pt.zcu; | ||
| 7265 | const param_count = func_ty_info.param_types.len; | 7338 | const param_count = func_ty_info.param_types.len; |
| 7266 | const uncoerced_arg: Air.Inst.Ref = switch (cai) { | 7339 | const uncoerced_arg: Air.Inst.Ref = switch (cai) { |
| 7267 | inline .resolved, .call_builtin => |resolved| resolved.args[arg_index], | 7340 | inline .resolved, .call_builtin => |resolved| resolved.args[arg_index], |
| ... | @@ -7438,7 +7511,8 @@ fn analyzeCall( | ... | @@ -7438,7 +7511,8 @@ fn analyzeCall( |
| 7438 | call_dbg_node: ?Zir.Inst.Index, | 7511 | call_dbg_node: ?Zir.Inst.Index, |
| 7439 | operation: CallOperation, | 7512 | operation: CallOperation, |
| 7440 | ) CompileError!Air.Inst.Ref { | 7513 | ) CompileError!Air.Inst.Ref { |
| 7441 | const mod = sema.mod; | 7514 | const pt = sema.pt; |
| 7515 | const mod = pt.zcu; | ||
| 7442 | const ip = &mod.intern_pool; | 7516 | const ip = &mod.intern_pool; |
| 7443 | 7517 | ||
| 7444 | const callee_ty = sema.typeOf(func); | 7518 | const callee_ty = sema.typeOf(func); |
| ... | @@ -7741,10 +7815,10 @@ fn analyzeCall( | ... | @@ -7741,10 +7815,10 @@ fn analyzeCall( |
| 7741 | const ies = try sema.arena.create(InferredErrorSet); | 7815 | const ies = try sema.arena.create(InferredErrorSet); |
| 7742 | ies.* = .{ .func = .none }; | 7816 | ies.* = .{ .func = .none }; |
| 7743 | sema.fn_ret_ty_ies = ies; | 7817 | sema.fn_ret_ty_ies = ies; |
| 7744 | sema.fn_ret_ty = Type.fromInterned((try ip.get(gpa, .{ .error_union_type = .{ | 7818 | sema.fn_ret_ty = Type.fromInterned(try pt.intern(.{ .error_union_type = .{ |
| 7745 | .error_set_type = .adhoc_inferred_error_set_type, | 7819 | .error_set_type = .adhoc_inferred_error_set_type, |
| 7746 | .payload_type = sema.fn_ret_ty.toIntern(), | 7820 | .payload_type = sema.fn_ret_ty.toIntern(), |
| 7747 | } }))); | 7821 | } })); |
| 7748 | } | 7822 | } |
| 7749 | 7823 | ||
| 7750 | // This `res2` is here instead of directly breaking from `res` due to a stage1 | 7824 | // This `res2` is here instead of directly breaking from `res` due to a stage1 |
| ... | @@ -7816,7 +7890,7 @@ fn analyzeCall( | ... | @@ -7816,7 +7890,7 @@ fn analyzeCall( |
| 7816 | // TODO: check whether any external comptime memory was mutated by the | 7890 | // TODO: check whether any external comptime memory was mutated by the |
| 7817 | // comptime function call. If so, then do not memoize the call here. | 7891 | // comptime function call. If so, then do not memoize the call here. |
| 7818 | if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) { | 7892 | if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) { |
| 7819 | _ = try mod.intern(.{ .memoized_call = .{ | 7893 | _ = try pt.intern(.{ .memoized_call = .{ |
| 7820 | .func = module_fn_index, | 7894 | .func = module_fn_index, |
| 7821 | .arg_values = memoized_arg_values, | 7895 | .arg_values = memoized_arg_values, |
| 7822 | .result = result_transformed, | 7896 | .result = result_transformed, |
| ... | @@ -7921,7 +7995,8 @@ fn analyzeCall( | ... | @@ -7921,7 +7995,8 @@ fn analyzeCall( |
| 7921 | } | 7995 | } |
| 7922 | 7996 | ||
| 7923 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { | 7997 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { |
| 7924 | const mod = sema.mod; | 7998 | const pt = sema.pt; |
| 7999 | const mod = pt.zcu; | ||
| 7925 | const target = mod.getTarget(); | 8000 | const target = mod.getTarget(); |
| 7926 | const backend = mod.comp.getZigBackend(); | 8001 | const backend = mod.comp.getZigBackend(); |
| 7927 | if (!target_util.supportsTailCall(target, backend)) { | 8002 | if (!target_util.supportsTailCall(target, backend)) { |
| ... | @@ -7932,7 +8007,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ | ... | @@ -7932,7 +8007,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ |
| 7932 | const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index); | 8007 | const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index); |
| 7933 | if (!func_ty.eql(func_decl.typeOf(mod), mod)) { | 8008 | if (!func_ty.eql(func_decl.typeOf(mod), mod)) { |
| 7934 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ | 8009 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ |
| 7935 | func_ty.fmt(mod), func_decl.typeOf(mod).fmt(mod), | 8010 | func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt), |
| 7936 | }); | 8011 | }); |
| 7937 | } | 8012 | } |
| 7938 | _ = try block.addUnOp(.ret, result); | 8013 | _ = try block.addUnOp(.ret, result); |
| ... | @@ -7954,7 +8029,7 @@ fn analyzeInlineCallArg( | ... | @@ -7954,7 +8029,7 @@ fn analyzeInlineCallArg( |
| 7954 | func_ty_info: InternPool.Key.FuncType, | 8029 | func_ty_info: InternPool.Key.FuncType, |
| 7955 | func_inst: Air.Inst.Ref, | 8030 | func_inst: Air.Inst.Ref, |
| 7956 | ) !?Air.Inst.Ref { | 8031 | ) !?Air.Inst.Ref { |
| 7957 | const mod = ics.sema.mod; | 8032 | const mod = ics.sema.pt.zcu; |
| 7958 | const ip = &mod.intern_pool; | 8033 | const ip = &mod.intern_pool; |
| 7959 | const zir_tags = ics.callee().code.instructions.items(.tag); | 8034 | const zir_tags = ics.callee().code.instructions.items(.tag); |
| 7960 | switch (zir_tags[@intFromEnum(inst)]) { | 8035 | switch (zir_tags[@intFromEnum(inst)]) { |
| ... | @@ -8084,7 +8159,8 @@ fn instantiateGenericCall( | ... | @@ -8084,7 +8159,8 @@ fn instantiateGenericCall( |
| 8084 | call_tag: Air.Inst.Tag, | 8159 | call_tag: Air.Inst.Tag, |
| 8085 | call_dbg_node: ?Zir.Inst.Index, | 8160 | call_dbg_node: ?Zir.Inst.Index, |
| 8086 | ) CompileError!Air.Inst.Ref { | 8161 | ) CompileError!Air.Inst.Ref { |
| 8087 | const zcu = sema.mod; | 8162 | const pt = sema.pt; |
| 8163 | const zcu = pt.zcu; | ||
| 8088 | const gpa = sema.gpa; | 8164 | const gpa = sema.gpa; |
| 8089 | const ip = &zcu.intern_pool; | 8165 | const ip = &zcu.intern_pool; |
| 8090 | 8166 | ||
| ... | @@ -8127,7 +8203,7 @@ fn instantiateGenericCall( | ... | @@ -8127,7 +8203,7 @@ fn instantiateGenericCall( |
| 8127 | // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a | 8203 | // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a |
| 8128 | // new, monomorphized function, with the comptime parameters elided. | 8204 | // new, monomorphized function, with the comptime parameters elided. |
| 8129 | var child_sema: Sema = .{ | 8205 | var child_sema: Sema = .{ |
| 8130 | .mod = zcu, | 8206 | .pt = pt, |
| 8131 | .gpa = gpa, | 8207 | .gpa = gpa, |
| 8132 | .arena = sema.arena, | 8208 | .arena = sema.arena, |
| 8133 | .code = fn_zir, | 8209 | .code = fn_zir, |
| ... | @@ -8358,7 +8434,8 @@ fn instantiateGenericCall( | ... | @@ -8358,7 +8434,8 @@ fn instantiateGenericCall( |
| 8358 | } | 8434 | } |
| 8359 | 8435 | ||
| 8360 | fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { | 8436 | fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { |
| 8361 | const mod = sema.mod; | 8437 | const pt = sema.pt; |
| 8438 | const mod = pt.zcu; | ||
| 8362 | const ip = &mod.intern_pool; | 8439 | const ip = &mod.intern_pool; |
| 8363 | const tuple = switch (ip.indexToKey(ty.toIntern())) { | 8440 | const tuple = switch (ip.indexToKey(ty.toIntern())) { |
| 8364 | .anon_struct_type => |tuple| tuple, | 8441 | .anon_struct_type => |tuple| tuple, |
| ... | @@ -8373,9 +8450,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) | ... | @@ -8373,9 +8450,8 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 8373 | } | 8450 | } |
| 8374 | 8451 | ||
| 8375 | fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8452 | fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8376 | const mod = sema.mod; | ||
| 8377 | const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type; | 8453 | const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type; |
| 8378 | const ty = try mod.intType(int_type.signedness, int_type.bit_count); | 8454 | const ty = try sema.pt.intType(int_type.signedness, int_type.bit_count); |
| 8379 | return Air.internedToRef(ty.toIntern()); | 8455 | return Air.internedToRef(ty.toIntern()); |
| 8380 | } | 8456 | } |
| 8381 | 8457 | ||
| ... | @@ -8383,22 +8459,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -8383,22 +8459,24 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8383 | const tracy = trace(@src()); | 8459 | const tracy = trace(@src()); |
| 8384 | defer tracy.end(); | 8460 | defer tracy.end(); |
| 8385 | 8461 | ||
| 8386 | const mod = sema.mod; | 8462 | const pt = sema.pt; |
| 8463 | const mod = pt.zcu; | ||
| 8387 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 8464 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8388 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); | 8465 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 8389 | const child_type = try sema.resolveType(block, operand_src, inst_data.operand); | 8466 | const child_type = try sema.resolveType(block, operand_src, inst_data.operand); |
| 8390 | if (child_type.zigTypeTag(mod) == .Opaque) { | 8467 | if (child_type.zigTypeTag(mod) == .Opaque) { |
| 8391 | return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(mod)}); | 8468 | return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(pt)}); |
| 8392 | } else if (child_type.zigTypeTag(mod) == .Null) { | 8469 | } else if (child_type.zigTypeTag(mod) == .Null) { |
| 8393 | return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)}); | 8470 | return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(pt)}); |
| 8394 | } | 8471 | } |
| 8395 | const opt_type = try mod.optionalType(child_type.toIntern()); | 8472 | const opt_type = try pt.optionalType(child_type.toIntern()); |
| 8396 | 8473 | ||
| 8397 | return Air.internedToRef(opt_type.toIntern()); | 8474 | return Air.internedToRef(opt_type.toIntern()); |
| 8398 | } | 8475 | } |
| 8399 | 8476 | ||
| 8400 | fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8477 | fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8401 | const mod = sema.mod; | 8478 | const pt = sema.pt; |
| 8479 | const mod = pt.zcu; | ||
| 8402 | const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin; | 8480 | const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin; |
| 8403 | const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) { | 8481 | const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) { |
| 8404 | // Since this is a ZIR instruction that returns a type, encountering | 8482 | // Since this is a ZIR instruction that returns a type, encountering |
| ... | @@ -8409,7 +8487,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -8409,7 +8487,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8409 | else => |e| return e, | 8487 | else => |e| return e, |
| 8410 | }; | 8488 | }; |
| 8411 | const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod); | 8489 | const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod); |
| 8412 | try indexable_ty.resolveFields(mod); | 8490 | try indexable_ty.resolveFields(pt); |
| 8413 | assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction | 8491 | assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction |
| 8414 | if (indexable_ty.zigTypeTag(mod) == .Struct) { | 8492 | if (indexable_ty.zigTypeTag(mod) == .Struct) { |
| 8415 | const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod); | 8493 | const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod); |
| ... | @@ -8421,7 +8499,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -8421,7 +8499,8 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8421 | } | 8499 | } |
| 8422 | 8500 | ||
| 8423 | fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8501 | fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8424 | const mod = sema.mod; | 8502 | const pt = sema.pt; |
| 8503 | const mod = pt.zcu; | ||
| 8425 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 8504 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8426 | const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { | 8505 | const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { |
| 8427 | error.GenericPoison => return .generic_poison_type, | 8506 | error.GenericPoison => return .generic_poison_type, |
| ... | @@ -8439,7 +8518,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -8439,7 +8518,8 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8439 | } | 8518 | } |
| 8440 | 8519 | ||
| 8441 | fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8520 | fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8442 | const mod = sema.mod; | 8521 | const pt = sema.pt; |
| 8522 | const mod = pt.zcu; | ||
| 8443 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 8523 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8444 | const src = block.nodeOffset(un_node.src_node); | 8524 | const src = block.nodeOffset(un_node.src_node); |
| 8445 | const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) { | 8525 | const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) { |
| ... | @@ -8455,7 +8535,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -8455,7 +8535,8 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 8455 | } | 8535 | } |
| 8456 | 8536 | ||
| 8457 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8537 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8458 | const mod = sema.mod; | 8538 | const pt = sema.pt; |
| 8539 | const mod = pt.zcu; | ||
| 8459 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 8540 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8460 | const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { | 8541 | const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { |
| 8461 | // Since this is a ZIR instruction that returns a type, encountering | 8542 | // Since this is a ZIR instruction that returns a type, encountering |
| ... | @@ -8466,13 +8547,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -8466,13 +8547,12 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8466 | else => |e| return e, | 8547 | else => |e| return e, |
| 8467 | }; | 8548 | }; |
| 8468 | if (!vec_ty.isVector(mod)) { | 8549 | if (!vec_ty.isVector(mod)) { |
| 8469 | return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(mod)}); | 8550 | return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(pt)}); |
| 8470 | } | 8551 | } |
| 8471 | return Air.internedToRef(vec_ty.childType(mod).toIntern()); | 8552 | return Air.internedToRef(vec_ty.childType(mod).toIntern()); |
| 8472 | } | 8553 | } |
| 8473 | 8554 | ||
| 8474 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8555 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8475 | const mod = sema.mod; | ||
| 8476 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 8556 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8477 | const len_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 8557 | const len_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 8478 | const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 8558 | const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| ... | @@ -8482,7 +8562,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -8482,7 +8562,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 8482 | })); | 8562 | })); |
| 8483 | const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); | 8563 | const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); |
| 8484 | try sema.checkVectorElemType(block, elem_type_src, elem_type); | 8564 | try sema.checkVectorElemType(block, elem_type_src, elem_type); |
| 8485 | const vector_type = try mod.vectorType(.{ | 8565 | const vector_type = try sema.pt.vectorType(.{ |
| 8486 | .len = len, | 8566 | .len = len, |
| 8487 | .child = elem_type.toIntern(), | 8567 | .child = elem_type.toIntern(), |
| 8488 | }); | 8568 | }); |
| ... | @@ -8502,7 +8582,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -8502,7 +8582,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 8502 | }); | 8582 | }); |
| 8503 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); | 8583 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); |
| 8504 | try sema.validateArrayElemType(block, elem_type, elem_src); | 8584 | try sema.validateArrayElemType(block, elem_type, elem_src); |
| 8505 | const array_ty = try sema.mod.arrayType(.{ | 8585 | const array_ty = try sema.pt.arrayType(.{ |
| 8506 | .len = len, | 8586 | .len = len, |
| 8507 | .child = elem_type.toIntern(), | 8587 | .child = elem_type.toIntern(), |
| 8508 | }); | 8588 | }); |
| ... | @@ -8529,7 +8609,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -8529,7 +8609,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8529 | const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{ | 8609 | const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{ |
| 8530 | .needed_comptime_reason = "array sentinel value must be comptime-known", | 8610 | .needed_comptime_reason = "array sentinel value must be comptime-known", |
| 8531 | }); | 8611 | }); |
| 8532 | const array_ty = try sema.mod.arrayType(.{ | 8612 | const array_ty = try sema.pt.arrayType(.{ |
| 8533 | .len = len, | 8613 | .len = len, |
| 8534 | .sentinel = sentinel_val.toIntern(), | 8614 | .sentinel = sentinel_val.toIntern(), |
| 8535 | .child = elem_type.toIntern(), | 8615 | .child = elem_type.toIntern(), |
| ... | @@ -8539,9 +8619,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -8539,9 +8619,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8539 | } | 8619 | } |
| 8540 | 8620 | ||
| 8541 | fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void { | 8621 | fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void { |
| 8542 | const mod = sema.mod; | 8622 | const pt = sema.pt; |
| 8623 | const mod = pt.zcu; | ||
| 8543 | if (elem_type.zigTypeTag(mod) == .Opaque) { | 8624 | if (elem_type.zigTypeTag(mod) == .Opaque) { |
| 8544 | return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(mod)}); | 8625 | return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(pt)}); |
| 8545 | } else if (elem_type.zigTypeTag(mod) == .NoReturn) { | 8626 | } else if (elem_type.zigTypeTag(mod) == .NoReturn) { |
| 8546 | return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); | 8627 | return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); |
| 8547 | } | 8628 | } |
| ... | @@ -8567,7 +8648,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -8567,7 +8648,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8567 | const tracy = trace(@src()); | 8648 | const tracy = trace(@src()); |
| 8568 | defer tracy.end(); | 8649 | defer tracy.end(); |
| 8569 | 8650 | ||
| 8570 | const mod = sema.mod; | 8651 | const pt = sema.pt; |
| 8652 | const mod = pt.zcu; | ||
| 8571 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 8653 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8572 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8654 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8573 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 8655 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -8577,40 +8659,41 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -8577,40 +8659,41 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8577 | 8659 | ||
| 8578 | if (error_set.zigTypeTag(mod) != .ErrorSet) { | 8660 | if (error_set.zigTypeTag(mod) != .ErrorSet) { |
| 8579 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{ | 8661 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{ |
| 8580 | error_set.fmt(mod), | 8662 | error_set.fmt(pt), |
| 8581 | }); | 8663 | }); |
| 8582 | } | 8664 | } |
| 8583 | try sema.validateErrorUnionPayloadType(block, payload, rhs_src); | 8665 | try sema.validateErrorUnionPayloadType(block, payload, rhs_src); |
| 8584 | const err_union_ty = try mod.errorUnionType(error_set, payload); | 8666 | const err_union_ty = try pt.errorUnionType(error_set, payload); |
| 8585 | return Air.internedToRef(err_union_ty.toIntern()); | 8667 | return Air.internedToRef(err_union_ty.toIntern()); |
| 8586 | } | 8668 | } |
| 8587 | 8669 | ||
| 8588 | fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void { | 8670 | fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void { |
| 8589 | const mod = sema.mod; | 8671 | const pt = sema.pt; |
| 8672 | const mod = pt.zcu; | ||
| 8590 | if (payload_ty.zigTypeTag(mod) == .Opaque) { | 8673 | if (payload_ty.zigTypeTag(mod) == .Opaque) { |
| 8591 | return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{ | 8674 | return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{ |
| 8592 | payload_ty.fmt(mod), | 8675 | payload_ty.fmt(pt), |
| 8593 | }); | 8676 | }); |
| 8594 | } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) { | 8677 | } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) { |
| 8595 | return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{ | 8678 | return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{ |
| 8596 | payload_ty.fmt(mod), | 8679 | payload_ty.fmt(pt), |
| 8597 | }); | 8680 | }); |
| 8598 | } | 8681 | } |
| 8599 | } | 8682 | } |
| 8600 | 8683 | ||
| 8601 | fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8684 | fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8602 | _ = block; | 8685 | _ = block; |
| 8603 | const mod = sema.mod; | 8686 | const pt = sema.pt; |
| 8604 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 8687 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 8605 | const name = try mod.intern_pool.getOrPutString( | 8688 | const name = try pt.zcu.intern_pool.getOrPutString( |
| 8606 | sema.gpa, | 8689 | sema.gpa, |
| 8607 | inst_data.get(sema.code), | 8690 | inst_data.get(sema.code), |
| 8608 | .no_embedded_nulls, | 8691 | .no_embedded_nulls, |
| 8609 | ); | 8692 | ); |
| 8610 | _ = try mod.getErrorValue(name); | 8693 | _ = try pt.zcu.getErrorValue(name); |
| 8611 | // Create an error set type with only this error value, and return the value. | 8694 | // Create an error set type with only this error value, and return the value. |
| 8612 | const error_set_type = try mod.singleErrorSetType(name); | 8695 | const error_set_type = try pt.singleErrorSetType(name); |
| 8613 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 8696 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 8614 | .ty = error_set_type.toIntern(), | 8697 | .ty = error_set_type.toIntern(), |
| 8615 | .name = name, | 8698 | .name = name, |
| 8616 | } }))); | 8699 | } }))); |
| ... | @@ -8620,21 +8703,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -8620,21 +8703,22 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8620 | const tracy = trace(@src()); | 8703 | const tracy = trace(@src()); |
| 8621 | defer tracy.end(); | 8704 | defer tracy.end(); |
| 8622 | 8705 | ||
| 8623 | const mod = sema.mod; | 8706 | const pt = sema.pt; |
| 8707 | const mod = pt.zcu; | ||
| 8624 | const ip = &mod.intern_pool; | 8708 | const ip = &mod.intern_pool; |
| 8625 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 8709 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8626 | const src = block.nodeOffset(extra.node); | 8710 | const src = block.nodeOffset(extra.node); |
| 8627 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 8711 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 8628 | const uncasted_operand = try sema.resolveInst(extra.operand); | 8712 | const uncasted_operand = try sema.resolveInst(extra.operand); |
| 8629 | const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src); | 8713 | const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src); |
| 8630 | const err_int_ty = try mod.errorIntType(); | 8714 | const err_int_ty = try pt.errorIntType(); |
| 8631 | 8715 | ||
| 8632 | if (try sema.resolveValue(operand)) |val| { | 8716 | if (try sema.resolveValue(operand)) |val| { |
| 8633 | if (val.isUndef(mod)) { | 8717 | if (val.isUndef(mod)) { |
| 8634 | return mod.undefRef(err_int_ty); | 8718 | return pt.undefRef(err_int_ty); |
| 8635 | } | 8719 | } |
| 8636 | const err_name = ip.indexToKey(val.toIntern()).err.name; | 8720 | const err_name = ip.indexToKey(val.toIntern()).err.name; |
| 8637 | return Air.internedToRef((try mod.intValue( | 8721 | return Air.internedToRef((try pt.intValue( |
| 8638 | err_int_ty, | 8722 | err_int_ty, |
| 8639 | try mod.getErrorValue(err_name), | 8723 | try mod.getErrorValue(err_name), |
| 8640 | )).toIntern()); | 8724 | )).toIntern()); |
| ... | @@ -8646,10 +8730,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -8646,10 +8730,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8646 | else => |err_set_ty_index| { | 8730 | else => |err_set_ty_index| { |
| 8647 | const names = ip.indexToKey(err_set_ty_index).error_set_type.names; | 8731 | const names = ip.indexToKey(err_set_ty_index).error_set_type.names; |
| 8648 | switch (names.len) { | 8732 | switch (names.len) { |
| 8649 | 0 => return Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()), | 8733 | 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()), |
| 8650 | 1 => { | 8734 | 1 => { |
| 8651 | const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?); | 8735 | const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?); |
| 8652 | return mod.intRef(err_int_ty, int); | 8736 | return pt.intRef(err_int_ty, int); |
| 8653 | }, | 8737 | }, |
| 8654 | else => {}, | 8738 | else => {}, |
| 8655 | } | 8739 | } |
| ... | @@ -8664,19 +8748,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -8664,19 +8748,20 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8664 | const tracy = trace(@src()); | 8748 | const tracy = trace(@src()); |
| 8665 | defer tracy.end(); | 8749 | defer tracy.end(); |
| 8666 | 8750 | ||
| 8667 | const mod = sema.mod; | 8751 | const pt = sema.pt; |
| 8752 | const mod = pt.zcu; | ||
| 8668 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 8753 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8669 | const src = block.nodeOffset(extra.node); | 8754 | const src = block.nodeOffset(extra.node); |
| 8670 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 8755 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 8671 | const uncasted_operand = try sema.resolveInst(extra.operand); | 8756 | const uncasted_operand = try sema.resolveInst(extra.operand); |
| 8672 | const err_int_ty = try mod.errorIntType(); | 8757 | const err_int_ty = try pt.errorIntType(); |
| 8673 | const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src); | 8758 | const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src); |
| 8674 | 8759 | ||
| 8675 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| { | 8760 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| { |
| 8676 | const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(mod)); | 8761 | const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt)); |
| 8677 | if (int > mod.global_error_set.count() or int == 0) | 8762 | if (int > mod.global_error_set.count() or int == 0) |
| 8678 | return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int}); | 8763 | return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int}); |
| 8679 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 8764 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 8680 | .ty = .anyerror_type, | 8765 | .ty = .anyerror_type, |
| 8681 | .name = mod.global_error_set.keys()[int], | 8766 | .name = mod.global_error_set.keys()[int], |
| 8682 | } }))); | 8767 | } }))); |
| ... | @@ -8684,7 +8769,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -8684,7 +8769,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8684 | try sema.requireRuntimeBlock(block, src, operand_src); | 8769 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 8685 | if (block.wantSafety()) { | 8770 | if (block.wantSafety()) { |
| 8686 | const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand); | 8771 | const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand); |
| 8687 | const zero_val = Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()); | 8772 | const zero_val = Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()); |
| 8688 | const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val); | 8773 | const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val); |
| 8689 | const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero); | 8774 | const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero); |
| 8690 | try sema.addSafetyCheck(block, src, ok, .invalid_error_code); | 8775 | try sema.addSafetyCheck(block, src, ok, .invalid_error_code); |
| ... | @@ -8702,7 +8787,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -8702,7 +8787,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8702 | const tracy = trace(@src()); | 8787 | const tracy = trace(@src()); |
| 8703 | defer tracy.end(); | 8788 | defer tracy.end(); |
| 8704 | 8789 | ||
| 8705 | const mod = sema.mod; | 8790 | const pt = sema.pt; |
| 8791 | const mod = pt.zcu; | ||
| 8706 | const ip = &mod.intern_pool; | 8792 | const ip = &mod.intern_pool; |
| 8707 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 8793 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8708 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8794 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -8723,9 +8809,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -8723,9 +8809,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8723 | const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); | 8809 | const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); |
| 8724 | const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); | 8810 | const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); |
| 8725 | if (lhs_ty.zigTypeTag(mod) != .ErrorSet) | 8811 | if (lhs_ty.zigTypeTag(mod) != .ErrorSet) |
| 8726 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(mod)}); | 8812 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(pt)}); |
| 8727 | if (rhs_ty.zigTypeTag(mod) != .ErrorSet) | 8813 | if (rhs_ty.zigTypeTag(mod) != .ErrorSet) |
| 8728 | return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(mod)}); | 8814 | return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(pt)}); |
| 8729 | 8815 | ||
| 8730 | // Anything merged with anyerror is anyerror. | 8816 | // Anything merged with anyerror is anyerror. |
| 8731 | if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) { | 8817 | if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) { |
| ... | @@ -8758,16 +8844,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8758,16 +8844,18 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8758 | const tracy = trace(@src()); | 8844 | const tracy = trace(@src()); |
| 8759 | defer tracy.end(); | 8845 | defer tracy.end(); |
| 8760 | 8846 | ||
| 8761 | const mod = sema.mod; | 8847 | const pt = sema.pt; |
| 8848 | const mod = pt.zcu; | ||
| 8762 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 8849 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 8763 | const name = inst_data.get(sema.code); | 8850 | const name = inst_data.get(sema.code); |
| 8764 | return Air.internedToRef((try mod.intern(.{ | 8851 | return Air.internedToRef((try pt.intern(.{ |
| 8765 | .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls), | 8852 | .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, name, .no_embedded_nulls), |
| 8766 | }))); | 8853 | }))); |
| 8767 | } | 8854 | } |
| 8768 | 8855 | ||
| 8769 | fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8856 | fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8770 | const mod = sema.mod; | 8857 | const pt = sema.pt; |
| 8858 | const mod = pt.zcu; | ||
| 8771 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 8859 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8772 | const src = block.nodeOffset(inst_data.src_node); | 8860 | const src = block.nodeOffset(inst_data.src_node); |
| 8773 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 8861 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -8777,7 +8865,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8777,7 +8865,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8777 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) { | 8865 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) { |
| 8778 | .Enum => operand, | 8866 | .Enum => operand, |
| 8779 | .Union => blk: { | 8867 | .Union => blk: { |
| 8780 | try operand_ty.resolveFields(mod); | 8868 | try operand_ty.resolveFields(pt); |
| 8781 | const tag_ty = operand_ty.unionTagType(mod) orelse { | 8869 | const tag_ty = operand_ty.unionTagType(mod) orelse { |
| 8782 | return sema.fail( | 8870 | return sema.fail( |
| 8783 | block, | 8871 | block, |
| ... | @@ -8791,7 +8879,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8791,7 +8879,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8791 | }, | 8879 | }, |
| 8792 | else => { | 8880 | else => { |
| 8793 | return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{ | 8881 | return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{ |
| 8794 | operand_ty.fmt(mod), | 8882 | operand_ty.fmt(pt), |
| 8795 | }); | 8883 | }); |
| 8796 | }, | 8884 | }, |
| 8797 | }; | 8885 | }; |
| ... | @@ -8802,20 +8890,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8802,20 +8890,20 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8802 | // https://github.com/ziglang/zig/issues/15909 | 8890 | // https://github.com/ziglang/zig/issues/15909 |
| 8803 | if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) { | 8891 | if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) { |
| 8804 | return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{ | 8892 | return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{ |
| 8805 | enum_tag_ty.fmt(mod), | 8893 | enum_tag_ty.fmt(pt), |
| 8806 | }); | 8894 | }); |
| 8807 | } | 8895 | } |
| 8808 | 8896 | ||
| 8809 | if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| { | 8897 | if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| { |
| 8810 | return Air.internedToRef((try mod.getCoerced(opv, int_tag_ty)).toIntern()); | 8898 | return Air.internedToRef((try pt.getCoerced(opv, int_tag_ty)).toIntern()); |
| 8811 | } | 8899 | } |
| 8812 | 8900 | ||
| 8813 | if (try sema.resolveValue(enum_tag)) |enum_tag_val| { | 8901 | if (try sema.resolveValue(enum_tag)) |enum_tag_val| { |
| 8814 | if (enum_tag_val.isUndef(mod)) { | 8902 | if (enum_tag_val.isUndef(mod)) { |
| 8815 | return mod.undefRef(int_tag_ty); | 8903 | return pt.undefRef(int_tag_ty); |
| 8816 | } | 8904 | } |
| 8817 | 8905 | ||
| 8818 | const val = try enum_tag_val.intFromEnum(enum_tag_ty, mod); | 8906 | const val = try enum_tag_val.intFromEnum(enum_tag_ty, pt); |
| 8819 | return Air.internedToRef(val.toIntern()); | 8907 | return Air.internedToRef(val.toIntern()); |
| 8820 | } | 8908 | } |
| 8821 | 8909 | ||
| ... | @@ -8824,7 +8912,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8824,7 +8912,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8824 | } | 8912 | } |
| 8825 | 8913 | ||
| 8826 | fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8914 | fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8827 | const mod = sema.mod; | 8915 | const pt = sema.pt; |
| 8916 | const mod = pt.zcu; | ||
| 8828 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 8917 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8829 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8918 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8830 | const src = block.nodeOffset(inst_data.src_node); | 8919 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -8833,7 +8922,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8833,7 +8922,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8833 | const operand = try sema.resolveInst(extra.rhs); | 8922 | const operand = try sema.resolveInst(extra.rhs); |
| 8834 | 8923 | ||
| 8835 | if (dest_ty.zigTypeTag(mod) != .Enum) { | 8924 | if (dest_ty.zigTypeTag(mod) != .Enum) { |
| 8836 | return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(mod)}); | 8925 | return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(pt)}); |
| 8837 | } | 8926 | } |
| 8838 | _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); | 8927 | _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); |
| 8839 | 8928 | ||
| ... | @@ -8841,10 +8930,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8841,10 +8930,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8841 | if (dest_ty.isNonexhaustiveEnum(mod)) { | 8930 | if (dest_ty.isNonexhaustiveEnum(mod)) { |
| 8842 | const int_tag_ty = dest_ty.intTagType(mod); | 8931 | const int_tag_ty = dest_ty.intTagType(mod); |
| 8843 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { | 8932 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { |
| 8844 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); | 8933 | return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); |
| 8845 | } | 8934 | } |
| 8846 | return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ | 8935 | return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ |
| 8847 | int_val.fmtValue(mod, sema), dest_ty.fmt(mod), | 8936 | int_val.fmtValue(pt, sema), dest_ty.fmt(pt), |
| 8848 | }); | 8937 | }); |
| 8849 | } | 8938 | } |
| 8850 | if (int_val.isUndef(mod)) { | 8939 | if (int_val.isUndef(mod)) { |
| ... | @@ -8852,10 +8941,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8852,10 +8941,10 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8852 | } | 8941 | } |
| 8853 | if (!(try sema.enumHasInt(dest_ty, int_val))) { | 8942 | if (!(try sema.enumHasInt(dest_ty, int_val))) { |
| 8854 | return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ | 8943 | return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ |
| 8855 | dest_ty.fmt(mod), int_val.fmtValue(mod, sema), | 8944 | dest_ty.fmt(pt), int_val.fmtValue(pt, sema), |
| 8856 | }); | 8945 | }); |
| 8857 | } | 8946 | } |
| 8858 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); | 8947 | return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); |
| 8859 | } | 8948 | } |
| 8860 | 8949 | ||
| 8861 | if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) { | 8950 | if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) { |
| ... | @@ -8909,7 +8998,8 @@ fn analyzeOptionalPayloadPtr( | ... | @@ -8909,7 +8998,8 @@ fn analyzeOptionalPayloadPtr( |
| 8909 | safety_check: bool, | 8998 | safety_check: bool, |
| 8910 | initializing: bool, | 8999 | initializing: bool, |
| 8911 | ) CompileError!Air.Inst.Ref { | 9000 | ) CompileError!Air.Inst.Ref { |
| 8912 | const zcu = sema.mod; | 9001 | const pt = sema.pt; |
| 9002 | const zcu = pt.zcu; | ||
| 8913 | const optional_ptr_ty = sema.typeOf(optional_ptr); | 9003 | const optional_ptr_ty = sema.typeOf(optional_ptr); |
| 8914 | assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer); | 9004 | assert(optional_ptr_ty.zigTypeTag(zcu) == .Pointer); |
| 8915 | 9005 | ||
| ... | @@ -8919,7 +9009,7 @@ fn analyzeOptionalPayloadPtr( | ... | @@ -8919,7 +9009,7 @@ fn analyzeOptionalPayloadPtr( |
| 8919 | } | 9009 | } |
| 8920 | 9010 | ||
| 8921 | const child_type = opt_type.optionalChild(zcu); | 9011 | const child_type = opt_type.optionalChild(zcu); |
| 8922 | const child_pointer = try zcu.ptrTypeSema(.{ | 9012 | const child_pointer = try pt.ptrTypeSema(.{ |
| 8923 | .child = child_type.toIntern(), | 9013 | .child = child_type.toIntern(), |
| 8924 | .flags = .{ | 9014 | .flags = .{ |
| 8925 | .is_const = optional_ptr_ty.isConstPtr(zcu), | 9015 | .is_const = optional_ptr_ty.isConstPtr(zcu), |
| ... | @@ -8932,8 +9022,8 @@ fn analyzeOptionalPayloadPtr( | ... | @@ -8932,8 +9022,8 @@ fn analyzeOptionalPayloadPtr( |
| 8932 | if (sema.isComptimeMutablePtr(ptr_val)) { | 9022 | if (sema.isComptimeMutablePtr(ptr_val)) { |
| 8933 | // Set the optional to non-null at comptime. | 9023 | // Set the optional to non-null at comptime. |
| 8934 | // If the payload is OPV, we must use that value instead of undef. | 9024 | // If the payload is OPV, we must use that value instead of undef. |
| 8935 | const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try zcu.undefValue(child_type); | 9025 | const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try pt.undefValue(child_type); |
| 8936 | const opt_val = try zcu.intern(.{ .opt = .{ | 9026 | const opt_val = try pt.intern(.{ .opt = .{ |
| 8937 | .ty = opt_type.toIntern(), | 9027 | .ty = opt_type.toIntern(), |
| 8938 | .val = payload_val.toIntern(), | 9028 | .val = payload_val.toIntern(), |
| 8939 | } }); | 9029 | } }); |
| ... | @@ -8943,13 +9033,13 @@ fn analyzeOptionalPayloadPtr( | ... | @@ -8943,13 +9033,13 @@ fn analyzeOptionalPayloadPtr( |
| 8943 | const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr); | 9033 | const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr); |
| 8944 | try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr); | 9034 | try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr); |
| 8945 | } | 9035 | } |
| 8946 | return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern()); | 9036 | return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern()); |
| 8947 | } | 9037 | } |
| 8948 | if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| { | 9038 | if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| { |
| 8949 | if (val.isNull(zcu)) { | 9039 | if (val.isNull(zcu)) { |
| 8950 | return sema.fail(block, src, "unable to unwrap null", .{}); | 9040 | return sema.fail(block, src, "unable to unwrap null", .{}); |
| 8951 | } | 9041 | } |
| 8952 | return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern()); | 9042 | return Air.internedToRef((try ptr_val.ptrOptPayload(pt)).toIntern()); |
| 8953 | } | 9043 | } |
| 8954 | } | 9044 | } |
| 8955 | 9045 | ||
| ... | @@ -8978,7 +9068,8 @@ fn zirOptionalPayload( | ... | @@ -8978,7 +9068,8 @@ fn zirOptionalPayload( |
| 8978 | const tracy = trace(@src()); | 9068 | const tracy = trace(@src()); |
| 8979 | defer tracy.end(); | 9069 | defer tracy.end(); |
| 8980 | 9070 | ||
| 8981 | const mod = sema.mod; | 9071 | const pt = sema.pt; |
| 9072 | const mod = pt.zcu; | ||
| 8982 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 9073 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8983 | const src = block.nodeOffset(inst_data.src_node); | 9074 | const src = block.nodeOffset(inst_data.src_node); |
| 8984 | const operand = try sema.resolveInst(inst_data.operand); | 9075 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -8992,7 +9083,7 @@ fn zirOptionalPayload( | ... | @@ -8992,7 +9083,7 @@ fn zirOptionalPayload( |
| 8992 | // TODO https://github.com/ziglang/zig/issues/6597 | 9083 | // TODO https://github.com/ziglang/zig/issues/6597 |
| 8993 | if (true) break :t operand_ty; | 9084 | if (true) break :t operand_ty; |
| 8994 | const ptr_info = operand_ty.ptrInfo(mod); | 9085 | const ptr_info = operand_ty.ptrInfo(mod); |
| 8995 | break :t try mod.ptrTypeSema(.{ | 9086 | break :t try pt.ptrTypeSema(.{ |
| 8996 | .child = ptr_info.child, | 9087 | .child = ptr_info.child, |
| 8997 | .flags = .{ | 9088 | .flags = .{ |
| 8998 | .alignment = ptr_info.flags.alignment, | 9089 | .alignment = ptr_info.flags.alignment, |
| ... | @@ -9030,7 +9121,8 @@ fn zirErrUnionPayload( | ... | @@ -9030,7 +9121,8 @@ fn zirErrUnionPayload( |
| 9030 | const tracy = trace(@src()); | 9121 | const tracy = trace(@src()); |
| 9031 | defer tracy.end(); | 9122 | defer tracy.end(); |
| 9032 | 9123 | ||
| 9033 | const mod = sema.mod; | 9124 | const pt = sema.pt; |
| 9125 | const mod = pt.zcu; | ||
| 9034 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 9126 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 9035 | const src = block.nodeOffset(inst_data.src_node); | 9127 | const src = block.nodeOffset(inst_data.src_node); |
| 9036 | const operand = try sema.resolveInst(inst_data.operand); | 9128 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -9038,7 +9130,7 @@ fn zirErrUnionPayload( | ... | @@ -9038,7 +9130,7 @@ fn zirErrUnionPayload( |
| 9038 | const err_union_ty = sema.typeOf(operand); | 9130 | const err_union_ty = sema.typeOf(operand); |
| 9039 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | 9131 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { |
| 9040 | return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ | 9132 | return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ |
| 9041 | err_union_ty.fmt(mod), | 9133 | err_union_ty.fmt(pt), |
| 9042 | }); | 9134 | }); |
| 9043 | } | 9135 | } |
| 9044 | return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false); | 9136 | return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false); |
| ... | @@ -9053,7 +9145,8 @@ fn analyzeErrUnionPayload( | ... | @@ -9053,7 +9145,8 @@ fn analyzeErrUnionPayload( |
| 9053 | operand_src: LazySrcLoc, | 9145 | operand_src: LazySrcLoc, |
| 9054 | safety_check: bool, | 9146 | safety_check: bool, |
| 9055 | ) CompileError!Air.Inst.Ref { | 9147 | ) CompileError!Air.Inst.Ref { |
| 9056 | const mod = sema.mod; | 9148 | const pt = sema.pt; |
| 9149 | const mod = pt.zcu; | ||
| 9057 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 9150 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 9058 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { | 9151 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 9059 | if (val.getErrorName(mod).unwrap()) |name| { | 9152 | if (val.getErrorName(mod).unwrap()) |name| { |
| ... | @@ -9098,19 +9191,20 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -9098,19 +9191,20 @@ fn analyzeErrUnionPayloadPtr( |
| 9098 | safety_check: bool, | 9191 | safety_check: bool, |
| 9099 | initializing: bool, | 9192 | initializing: bool, |
| 9100 | ) CompileError!Air.Inst.Ref { | 9193 | ) CompileError!Air.Inst.Ref { |
| 9101 | const zcu = sema.mod; | 9194 | const pt = sema.pt; |
| 9195 | const zcu = pt.zcu; | ||
| 9102 | const operand_ty = sema.typeOf(operand); | 9196 | const operand_ty = sema.typeOf(operand); |
| 9103 | assert(operand_ty.zigTypeTag(zcu) == .Pointer); | 9197 | assert(operand_ty.zigTypeTag(zcu) == .Pointer); |
| 9104 | 9198 | ||
| 9105 | if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) { | 9199 | if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) { |
| 9106 | return sema.fail(block, src, "expected error union type, found '{}'", .{ | 9200 | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 9107 | operand_ty.childType(zcu).fmt(zcu), | 9201 | operand_ty.childType(zcu).fmt(pt), |
| 9108 | }); | 9202 | }); |
| 9109 | } | 9203 | } |
| 9110 | 9204 | ||
| 9111 | const err_union_ty = operand_ty.childType(zcu); | 9205 | const err_union_ty = operand_ty.childType(zcu); |
| 9112 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 9206 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 9113 | const operand_pointer_ty = try zcu.ptrTypeSema(.{ | 9207 | const operand_pointer_ty = try pt.ptrTypeSema(.{ |
| 9114 | .child = payload_ty.toIntern(), | 9208 | .child = payload_ty.toIntern(), |
| 9115 | .flags = .{ | 9209 | .flags = .{ |
| 9116 | .is_const = operand_ty.isConstPtr(zcu), | 9210 | .is_const = operand_ty.isConstPtr(zcu), |
| ... | @@ -9123,8 +9217,8 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -9123,8 +9217,8 @@ fn analyzeErrUnionPayloadPtr( |
| 9123 | if (sema.isComptimeMutablePtr(ptr_val)) { | 9217 | if (sema.isComptimeMutablePtr(ptr_val)) { |
| 9124 | // Set the error union to non-error at comptime. | 9218 | // Set the error union to non-error at comptime. |
| 9125 | // If the payload is OPV, we must use that value instead of undef. | 9219 | // If the payload is OPV, we must use that value instead of undef. |
| 9126 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty); | 9220 | const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty); |
| 9127 | const eu_val = try zcu.intern(.{ .error_union = .{ | 9221 | const eu_val = try pt.intern(.{ .error_union = .{ |
| 9128 | .ty = err_union_ty.toIntern(), | 9222 | .ty = err_union_ty.toIntern(), |
| 9129 | .val = .{ .payload = payload_val.toIntern() }, | 9223 | .val = .{ .payload = payload_val.toIntern() }, |
| 9130 | } }); | 9224 | } }); |
| ... | @@ -9135,13 +9229,13 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -9135,13 +9229,13 @@ fn analyzeErrUnionPayloadPtr( |
| 9135 | const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand); | 9229 | const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand); |
| 9136 | try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr); | 9230 | try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr); |
| 9137 | } | 9231 | } |
| 9138 | return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern()); | 9232 | return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern()); |
| 9139 | } | 9233 | } |
| 9140 | if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| { | 9234 | if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| { |
| 9141 | if (val.getErrorName(zcu).unwrap()) |name| { | 9235 | if (val.getErrorName(zcu).unwrap()) |name| { |
| 9142 | return sema.failWithComptimeErrorRetTrace(block, src, name); | 9236 | return sema.failWithComptimeErrorRetTrace(block, src, name); |
| 9143 | } | 9237 | } |
| 9144 | return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern()); | 9238 | return Air.internedToRef((try ptr_val.ptrEuPayload(pt)).toIntern()); |
| 9145 | } | 9239 | } |
| 9146 | } | 9240 | } |
| 9147 | 9241 | ||
| ... | @@ -9175,18 +9269,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -9175,18 +9269,19 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 9175 | } | 9269 | } |
| 9176 | 9270 | ||
| 9177 | fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { | 9271 | fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 9178 | const mod = sema.mod; | 9272 | const pt = sema.pt; |
| 9273 | const mod = pt.zcu; | ||
| 9179 | const operand_ty = sema.typeOf(operand); | 9274 | const operand_ty = sema.typeOf(operand); |
| 9180 | if (operand_ty.zigTypeTag(mod) != .ErrorUnion) { | 9275 | if (operand_ty.zigTypeTag(mod) != .ErrorUnion) { |
| 9181 | return sema.fail(block, src, "expected error union type, found '{}'", .{ | 9276 | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 9182 | operand_ty.fmt(mod), | 9277 | operand_ty.fmt(pt), |
| 9183 | }); | 9278 | }); |
| 9184 | } | 9279 | } |
| 9185 | 9280 | ||
| 9186 | const result_ty = operand_ty.errorUnionSet(mod); | 9281 | const result_ty = operand_ty.errorUnionSet(mod); |
| 9187 | 9282 | ||
| 9188 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 9283 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 9189 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 9284 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 9190 | .ty = result_ty.toIntern(), | 9285 | .ty = result_ty.toIntern(), |
| 9191 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | 9286 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, |
| 9192 | } }))); | 9287 | } }))); |
| ... | @@ -9208,13 +9303,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -9208,13 +9303,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 9208 | } | 9303 | } |
| 9209 | 9304 | ||
| 9210 | fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { | 9305 | fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 9211 | const mod = sema.mod; | 9306 | const pt = sema.pt; |
| 9307 | const mod = pt.zcu; | ||
| 9212 | const operand_ty = sema.typeOf(operand); | 9308 | const operand_ty = sema.typeOf(operand); |
| 9213 | assert(operand_ty.zigTypeTag(mod) == .Pointer); | 9309 | assert(operand_ty.zigTypeTag(mod) == .Pointer); |
| 9214 | 9310 | ||
| 9215 | if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { | 9311 | if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { |
| 9216 | return sema.fail(block, src, "expected error union type, found '{}'", .{ | 9312 | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 9217 | operand_ty.childType(mod).fmt(mod), | 9313 | operand_ty.childType(mod).fmt(pt), |
| 9218 | }); | 9314 | }); |
| 9219 | } | 9315 | } |
| 9220 | 9316 | ||
| ... | @@ -9223,7 +9319,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: | ... | @@ -9223,7 +9319,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: |
| 9223 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { | 9319 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 9224 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { | 9320 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { |
| 9225 | assert(val.getErrorName(mod) != .none); | 9321 | assert(val.getErrorName(mod) != .none); |
| 9226 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 9322 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 9227 | .ty = result_ty.toIntern(), | 9323 | .ty = result_ty.toIntern(), |
| 9228 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | 9324 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, |
| 9229 | } }))); | 9325 | } }))); |
| ... | @@ -9240,10 +9336,11 @@ fn zirFunc( | ... | @@ -9240,10 +9336,11 @@ fn zirFunc( |
| 9240 | inst: Zir.Inst.Index, | 9336 | inst: Zir.Inst.Index, |
| 9241 | inferred_error_set: bool, | 9337 | inferred_error_set: bool, |
| 9242 | ) CompileError!Air.Inst.Ref { | 9338 | ) CompileError!Air.Inst.Ref { |
| 9243 | const mod = sema.mod; | 9339 | const pt = sema.pt; |
| 9340 | const mod = pt.zcu; | ||
| 9244 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 9341 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 9245 | const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index); | 9342 | const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index); |
| 9246 | const target = sema.mod.getTarget(); | 9343 | const target = mod.getTarget(); |
| 9247 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node }); | 9344 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node }); |
| 9248 | 9345 | ||
| 9249 | var extra_index = extra.end; | 9346 | var extra_index = extra.end; |
| ... | @@ -9372,7 +9469,8 @@ fn handleExternLibName( | ... | @@ -9372,7 +9469,8 @@ fn handleExternLibName( |
| 9372 | lib_name: []const u8, | 9469 | lib_name: []const u8, |
| 9373 | ) CompileError!void { | 9470 | ) CompileError!void { |
| 9374 | blk: { | 9471 | blk: { |
| 9375 | const mod = sema.mod; | 9472 | const pt = sema.pt; |
| 9473 | const mod = pt.zcu; | ||
| 9376 | const comp = mod.comp; | 9474 | const comp = mod.comp; |
| 9377 | const target = mod.getTarget(); | 9475 | const target = mod.getTarget(); |
| 9378 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); | 9476 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); |
| ... | @@ -9485,7 +9583,8 @@ fn funcCommon( | ... | @@ -9485,7 +9583,8 @@ fn funcCommon( |
| 9485 | noalias_bits: u32, | 9583 | noalias_bits: u32, |
| 9486 | is_noinline: bool, | 9584 | is_noinline: bool, |
| 9487 | ) CompileError!Air.Inst.Ref { | 9585 | ) CompileError!Air.Inst.Ref { |
| 9488 | const mod = sema.mod; | 9586 | const pt = sema.pt; |
| 9587 | const mod = pt.zcu; | ||
| 9489 | const gpa = sema.gpa; | 9588 | const gpa = sema.gpa; |
| 9490 | const target = mod.getTarget(); | 9589 | const target = mod.getTarget(); |
| 9491 | const ip = &mod.intern_pool; | 9590 | const ip = &mod.intern_pool; |
| ... | @@ -9539,13 +9638,13 @@ fn funcCommon( | ... | @@ -9539,13 +9638,13 @@ fn funcCommon( |
| 9539 | if (!param_ty.isValidParamType(mod)) { | 9638 | if (!param_ty.isValidParamType(mod)) { |
| 9540 | const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else ""; | 9639 | const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else ""; |
| 9541 | return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{ | 9640 | return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{ |
| 9542 | opaque_str, param_ty.fmt(mod), | 9641 | opaque_str, param_ty.fmt(pt), |
| 9543 | }); | 9642 | }); |
| 9544 | } | 9643 | } |
| 9545 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { | 9644 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { |
| 9546 | const msg = msg: { | 9645 | const msg = msg: { |
| 9547 | const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ | 9646 | const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 9548 | param_ty.fmt(mod), @tagName(cc_resolved), | 9647 | param_ty.fmt(pt), @tagName(cc_resolved), |
| 9549 | }); | 9648 | }); |
| 9550 | errdefer msg.destroy(sema.gpa); | 9649 | errdefer msg.destroy(sema.gpa); |
| 9551 | 9650 | ||
| ... | @@ -9559,7 +9658,7 @@ fn funcCommon( | ... | @@ -9559,7 +9658,7 @@ fn funcCommon( |
| 9559 | if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) { | 9658 | if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) { |
| 9560 | const msg = msg: { | 9659 | const msg = msg: { |
| 9561 | const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{ | 9660 | const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{ |
| 9562 | param_ty.fmt(mod), | 9661 | param_ty.fmt(pt), |
| 9563 | }); | 9662 | }); |
| 9564 | errdefer msg.destroy(sema.gpa); | 9663 | errdefer msg.destroy(sema.gpa); |
| 9565 | 9664 | ||
| ... | @@ -9580,7 +9679,7 @@ fn funcCommon( | ... | @@ -9580,7 +9679,7 @@ fn funcCommon( |
| 9580 | const err_code_size = target.ptrBitWidth(); | 9679 | const err_code_size = target.ptrBitWidth(); |
| 9581 | switch (i) { | 9680 | switch (i) { |
| 9582 | 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), | 9681 | 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), |
| 9583 | 1 => if (param_ty.bitSize(mod) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), | 9682 | 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), |
| 9584 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), | 9683 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), |
| 9585 | } | 9684 | } |
| 9586 | } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}), | 9685 | } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}), |
| ... | @@ -9606,7 +9705,7 @@ fn funcCommon( | ... | @@ -9606,7 +9705,7 @@ fn funcCommon( |
| 9606 | if (inferred_error_set) { | 9705 | if (inferred_error_set) { |
| 9607 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); | 9706 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); |
| 9608 | } | 9707 | } |
| 9609 | const func_index = try ip.getFuncInstance(gpa, .{ | 9708 | const func_index = try ip.getFuncInstance(gpa, pt.tid, .{ |
| 9610 | .param_types = param_types, | 9709 | .param_types = param_types, |
| 9611 | .noalias_bits = noalias_bits, | 9710 | .noalias_bits = noalias_bits, |
| 9612 | .bare_return_type = bare_return_type.toIntern(), | 9711 | .bare_return_type = bare_return_type.toIntern(), |
| ... | @@ -9655,7 +9754,7 @@ fn funcCommon( | ... | @@ -9655,7 +9754,7 @@ fn funcCommon( |
| 9655 | assert(has_body); | 9754 | assert(has_body); |
| 9656 | if (!ret_poison) | 9755 | if (!ret_poison) |
| 9657 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); | 9756 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); |
| 9658 | const func_index = try ip.getFuncDeclIes(gpa, .{ | 9757 | const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{ |
| 9659 | .owner_decl = sema.owner_decl_index, | 9758 | .owner_decl = sema.owner_decl_index, |
| 9660 | 9759 | ||
| 9661 | .param_types = param_types, | 9760 | .param_types = param_types, |
| ... | @@ -9695,7 +9794,7 @@ fn funcCommon( | ... | @@ -9695,7 +9794,7 @@ fn funcCommon( |
| 9695 | ); | 9794 | ); |
| 9696 | } | 9795 | } |
| 9697 | 9796 | ||
| 9698 | const func_ty = try ip.getFuncType(gpa, .{ | 9797 | const func_ty = try ip.getFuncType(gpa, pt.tid, .{ |
| 9699 | .param_types = param_types, | 9798 | .param_types = param_types, |
| 9700 | .noalias_bits = noalias_bits, | 9799 | .noalias_bits = noalias_bits, |
| 9701 | .comptime_bits = comptime_bits, | 9800 | .comptime_bits = comptime_bits, |
| ... | @@ -9718,7 +9817,7 @@ fn funcCommon( | ... | @@ -9718,7 +9817,7 @@ fn funcCommon( |
| 9718 | if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{ | 9817 | if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{ |
| 9719 | .node_offset_lib_name = src_node_offset, | 9818 | .node_offset_lib_name = src_node_offset, |
| 9720 | }), lib_name); | 9819 | }), lib_name); |
| 9721 | const func_index = try ip.getExternFunc(gpa, .{ | 9820 | const func_index = try ip.getExternFunc(gpa, pt.tid, .{ |
| 9722 | .ty = func_ty, | 9821 | .ty = func_ty, |
| 9723 | .decl = sema.owner_decl_index, | 9822 | .decl = sema.owner_decl_index, |
| 9724 | .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls), | 9823 | .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name, .no_embedded_nulls), |
| ... | @@ -9743,7 +9842,7 @@ fn funcCommon( | ... | @@ -9743,7 +9842,7 @@ fn funcCommon( |
| 9743 | } | 9842 | } |
| 9744 | 9843 | ||
| 9745 | if (has_body) { | 9844 | if (has_body) { |
| 9746 | const func_index = try ip.getFuncDecl(gpa, .{ | 9845 | const func_index = try ip.getFuncDecl(gpa, pt.tid, .{ |
| 9747 | .owner_decl = sema.owner_decl_index, | 9846 | .owner_decl = sema.owner_decl_index, |
| 9748 | .ty = func_ty, | 9847 | .ty = func_ty, |
| 9749 | .cc = cc, | 9848 | .cc = cc, |
| ... | @@ -9809,7 +9908,8 @@ fn finishFunc( | ... | @@ -9809,7 +9908,8 @@ fn finishFunc( |
| 9809 | is_generic: bool, | 9908 | is_generic: bool, |
| 9810 | final_is_generic: bool, | 9909 | final_is_generic: bool, |
| 9811 | ) CompileError!Air.Inst.Ref { | 9910 | ) CompileError!Air.Inst.Ref { |
| 9812 | const mod = sema.mod; | 9911 | const pt = sema.pt; |
| 9912 | const mod = pt.zcu; | ||
| 9813 | const ip = &mod.intern_pool; | 9913 | const ip = &mod.intern_pool; |
| 9814 | const gpa = sema.gpa; | 9914 | const gpa = sema.gpa; |
| 9815 | const target = mod.getTarget(); | 9915 | const target = mod.getTarget(); |
| ... | @@ -9822,7 +9922,7 @@ fn finishFunc( | ... | @@ -9822,7 +9922,7 @@ fn finishFunc( |
| 9822 | if (!return_type.isValidReturnType(mod)) { | 9922 | if (!return_type.isValidReturnType(mod)) { |
| 9823 | const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else ""; | 9923 | const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else ""; |
| 9824 | return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{ | 9924 | return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 9825 | opaque_str, return_type.fmt(mod), | 9925 | opaque_str, return_type.fmt(pt), |
| 9826 | }); | 9926 | }); |
| 9827 | } | 9927 | } |
| 9828 | if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and | 9928 | if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and |
| ... | @@ -9830,7 +9930,7 @@ fn finishFunc( | ... | @@ -9830,7 +9930,7 @@ fn finishFunc( |
| 9830 | { | 9930 | { |
| 9831 | const msg = msg: { | 9931 | const msg = msg: { |
| 9832 | const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ | 9932 | const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ |
| 9833 | return_type.fmt(mod), @tagName(cc_resolved), | 9933 | return_type.fmt(pt), @tagName(cc_resolved), |
| 9834 | }); | 9934 | }); |
| 9835 | errdefer msg.destroy(gpa); | 9935 | errdefer msg.destroy(gpa); |
| 9836 | 9936 | ||
| ... | @@ -9852,7 +9952,7 @@ fn finishFunc( | ... | @@ -9852,7 +9952,7 @@ fn finishFunc( |
| 9852 | const msg = try sema.errMsg( | 9952 | const msg = try sema.errMsg( |
| 9853 | ret_ty_src, | 9953 | ret_ty_src, |
| 9854 | "function with comptime-only return type '{}' requires all parameters to be comptime", | 9954 | "function with comptime-only return type '{}' requires all parameters to be comptime", |
| 9855 | .{return_type.fmt(mod)}, | 9955 | .{return_type.fmt(pt)}, |
| 9856 | ); | 9956 | ); |
| 9857 | try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type); | 9957 | try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type); |
| 9858 | 9958 | ||
| ... | @@ -9938,8 +10038,8 @@ fn finishFunc( | ... | @@ -9938,8 +10038,8 @@ fn finishFunc( |
| 9938 | if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) { | 10038 | if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) { |
| 9939 | // Make sure that StackTrace's fields are resolved so that the backend can | 10039 | // Make sure that StackTrace's fields are resolved so that the backend can |
| 9940 | // lower this fn type. | 10040 | // lower this fn type. |
| 9941 | const unresolved_stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 10041 | const unresolved_stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 9942 | try unresolved_stack_trace_ty.resolveFields(mod); | 10042 | try unresolved_stack_trace_ty.resolveFields(pt); |
| 9943 | } | 10043 | } |
| 9944 | 10044 | ||
| 9945 | return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty); | 10045 | return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty); |
| ... | @@ -10068,7 +10168,8 @@ fn analyzeAs( | ... | @@ -10068,7 +10168,8 @@ fn analyzeAs( |
| 10068 | zir_operand: Zir.Inst.Ref, | 10168 | zir_operand: Zir.Inst.Ref, |
| 10069 | no_cast_to_comptime_int: bool, | 10169 | no_cast_to_comptime_int: bool, |
| 10070 | ) CompileError!Air.Inst.Ref { | 10170 | ) CompileError!Air.Inst.Ref { |
| 10071 | const mod = sema.mod; | 10171 | const pt = sema.pt; |
| 10172 | const mod = pt.zcu; | ||
| 10072 | const operand = try sema.resolveInst(zir_operand); | 10173 | const operand = try sema.resolveInst(zir_operand); |
| 10073 | const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) { | 10174 | const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) { |
| 10074 | error.GenericPoison => return operand, | 10175 | error.GenericPoison => return operand, |
| ... | @@ -10098,7 +10199,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10098,7 +10199,8 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10098 | const tracy = trace(@src()); | 10199 | const tracy = trace(@src()); |
| 10099 | defer tracy.end(); | 10200 | defer tracy.end(); |
| 10100 | 10201 | ||
| 10101 | const zcu = sema.mod; | 10202 | const pt = sema.pt; |
| 10203 | const zcu = pt.zcu; | ||
| 10102 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 10204 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 10103 | const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 10205 | const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 10104 | const operand = try sema.resolveInst(inst_data.operand); | 10206 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -10106,12 +10208,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10106,12 +10208,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10106 | const ptr_ty = operand_ty.scalarType(zcu); | 10208 | const ptr_ty = operand_ty.scalarType(zcu); |
| 10107 | const is_vector = operand_ty.zigTypeTag(zcu) == .Vector; | 10209 | const is_vector = operand_ty.zigTypeTag(zcu) == .Vector; |
| 10108 | if (!ptr_ty.isPtrAtRuntime(zcu)) { | 10210 | if (!ptr_ty.isPtrAtRuntime(zcu)) { |
| 10109 | return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(zcu)}); | 10211 | return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}); |
| 10110 | } | 10212 | } |
| 10111 | const pointee_ty = ptr_ty.childType(zcu); | 10213 | const pointee_ty = ptr_ty.childType(zcu); |
| 10112 | if (try sema.typeRequiresComptime(ptr_ty)) { | 10214 | if (try sema.typeRequiresComptime(ptr_ty)) { |
| 10113 | const msg = msg: { | 10215 | const msg = msg: { |
| 10114 | const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(zcu)}); | 10216 | const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(pt)}); |
| 10115 | errdefer msg.destroy(sema.gpa); | 10217 | errdefer msg.destroy(sema.gpa); |
| 10116 | try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty); | 10218 | try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty); |
| 10117 | break :msg msg; | 10219 | break :msg msg; |
| ... | @@ -10121,32 +10223,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10121,32 +10223,32 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10121 | if (try sema.resolveValueIntable(operand)) |operand_val| ct: { | 10223 | if (try sema.resolveValueIntable(operand)) |operand_val| ct: { |
| 10122 | if (!is_vector) { | 10224 | if (!is_vector) { |
| 10123 | if (operand_val.isUndef(zcu)) { | 10225 | if (operand_val.isUndef(zcu)) { |
| 10124 | return Air.internedToRef((try zcu.undefValue(Type.usize)).toIntern()); | 10226 | return Air.internedToRef((try pt.undefValue(Type.usize)).toIntern()); |
| 10125 | } | 10227 | } |
| 10126 | return Air.internedToRef((try zcu.intValue( | 10228 | return Air.internedToRef((try pt.intValue( |
| 10127 | Type.usize, | 10229 | Type.usize, |
| 10128 | (try operand_val.getUnsignedIntAdvanced(zcu, .sema)).?, | 10230 | (try operand_val.getUnsignedIntAdvanced(pt, .sema)).?, |
| 10129 | )).toIntern()); | 10231 | )).toIntern()); |
| 10130 | } | 10232 | } |
| 10131 | const len = operand_ty.vectorLen(zcu); | 10233 | const len = operand_ty.vectorLen(zcu); |
| 10132 | const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len }); | 10234 | const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len }); |
| 10133 | const new_elems = try sema.arena.alloc(InternPool.Index, len); | 10235 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 10134 | for (new_elems, 0..) |*new_elem, i| { | 10236 | for (new_elems, 0..) |*new_elem, i| { |
| 10135 | const ptr_val = try operand_val.elemValue(zcu, i); | 10237 | const ptr_val = try operand_val.elemValue(pt, i); |
| 10136 | if (ptr_val.isUndef(zcu)) { | 10238 | if (ptr_val.isUndef(zcu)) { |
| 10137 | new_elem.* = (try zcu.undefValue(Type.usize)).toIntern(); | 10239 | new_elem.* = (try pt.undefValue(Type.usize)).toIntern(); |
| 10138 | continue; | 10240 | continue; |
| 10139 | } | 10241 | } |
| 10140 | const addr = try ptr_val.getUnsignedIntAdvanced(zcu, .sema) orelse { | 10242 | const addr = try ptr_val.getUnsignedIntAdvanced(pt, .sema) orelse { |
| 10141 | // A vector element wasn't an integer pointer. This is a runtime operation. | 10243 | // A vector element wasn't an integer pointer. This is a runtime operation. |
| 10142 | break :ct; | 10244 | break :ct; |
| 10143 | }; | 10245 | }; |
| 10144 | new_elem.* = (try zcu.intValue( | 10246 | new_elem.* = (try pt.intValue( |
| 10145 | Type.usize, | 10247 | Type.usize, |
| 10146 | addr, | 10248 | addr, |
| 10147 | )).toIntern(); | 10249 | )).toIntern(); |
| 10148 | } | 10250 | } |
| 10149 | return Air.internedToRef(try zcu.intern(.{ .aggregate = .{ | 10251 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 10150 | .ty = dest_ty.toIntern(), | 10252 | .ty = dest_ty.toIntern(), |
| 10151 | .storage = .{ .elems = new_elems }, | 10253 | .storage = .{ .elems = new_elems }, |
| 10152 | } })); | 10254 | } })); |
| ... | @@ -10157,10 +10259,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10157,10 +10259,10 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10157 | return block.addUnOp(.int_from_ptr, operand); | 10259 | return block.addUnOp(.int_from_ptr, operand); |
| 10158 | } | 10260 | } |
| 10159 | const len = operand_ty.vectorLen(zcu); | 10261 | const len = operand_ty.vectorLen(zcu); |
| 10160 | const dest_ty = try zcu.vectorType(.{ .child = .usize_type, .len = len }); | 10262 | const dest_ty = try pt.vectorType(.{ .child = .usize_type, .len = len }); |
| 10161 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | 10263 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 10162 | for (new_elems, 0..) |*new_elem, i| { | 10264 | for (new_elems, 0..) |*new_elem, i| { |
| 10163 | const idx_ref = try zcu.intRef(Type.usize, i); | 10265 | const idx_ref = try pt.intRef(Type.usize, i); |
| 10164 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | 10266 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 10165 | new_elem.* = try block.addUnOp(.int_from_ptr, old_elem); | 10267 | new_elem.* = try block.addUnOp(.int_from_ptr, old_elem); |
| 10166 | } | 10268 | } |
| ... | @@ -10171,7 +10273,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -10171,7 +10273,8 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10171 | const tracy = trace(@src()); | 10273 | const tracy = trace(@src()); |
| 10172 | defer tracy.end(); | 10274 | defer tracy.end(); |
| 10173 | 10275 | ||
| 10174 | const mod = sema.mod; | 10276 | const pt = sema.pt; |
| 10277 | const mod = pt.zcu; | ||
| 10175 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10278 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10176 | const src = block.nodeOffset(inst_data.src_node); | 10279 | const src = block.nodeOffset(inst_data.src_node); |
| 10177 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); | 10280 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); |
| ... | @@ -10189,7 +10292,8 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -10189,7 +10292,8 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10189 | const tracy = trace(@src()); | 10292 | const tracy = trace(@src()); |
| 10190 | defer tracy.end(); | 10293 | defer tracy.end(); |
| 10191 | 10294 | ||
| 10192 | const mod = sema.mod; | 10295 | const pt = sema.pt; |
| 10296 | const mod = pt.zcu; | ||
| 10193 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10297 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10194 | const src = block.nodeOffset(inst_data.src_node); | 10298 | const src = block.nodeOffset(inst_data.src_node); |
| 10195 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); | 10299 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); |
| ... | @@ -10207,7 +10311,8 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi | ... | @@ -10207,7 +10311,8 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 10207 | const tracy = trace(@src()); | 10311 | const tracy = trace(@src()); |
| 10208 | defer tracy.end(); | 10312 | defer tracy.end(); |
| 10209 | 10313 | ||
| 10210 | const mod = sema.mod; | 10314 | const pt = sema.pt; |
| 10315 | const mod = pt.zcu; | ||
| 10211 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10316 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10212 | const src = block.nodeOffset(inst_data.src_node); | 10317 | const src = block.nodeOffset(inst_data.src_node); |
| 10213 | const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node }); | 10318 | const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node }); |
| ... | @@ -10284,7 +10389,8 @@ fn intCast( | ... | @@ -10284,7 +10389,8 @@ fn intCast( |
| 10284 | operand_src: LazySrcLoc, | 10389 | operand_src: LazySrcLoc, |
| 10285 | runtime_safety: bool, | 10390 | runtime_safety: bool, |
| 10286 | ) CompileError!Air.Inst.Ref { | 10391 | ) CompileError!Air.Inst.Ref { |
| 10287 | const mod = sema.mod; | 10392 | const pt = sema.pt; |
| 10393 | const mod = pt.zcu; | ||
| 10288 | const operand_ty = sema.typeOf(operand); | 10394 | const operand_ty = sema.typeOf(operand); |
| 10289 | const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src); | 10395 | const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src); |
| 10290 | const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src); | 10396 | const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src); |
| ... | @@ -10307,7 +10413,7 @@ fn intCast( | ... | @@ -10307,7 +10413,7 @@ fn intCast( |
| 10307 | 10413 | ||
| 10308 | if (wanted_bits == 0) { | 10414 | if (wanted_bits == 0) { |
| 10309 | const ok = if (is_vector) ok: { | 10415 | const ok = if (is_vector) ok: { |
| 10310 | const zeros = try sema.splat(operand_ty, try mod.intValue(operand_scalar_ty, 0)); | 10416 | const zeros = try sema.splat(operand_ty, try pt.intValue(operand_scalar_ty, 0)); |
| 10311 | const zero_inst = Air.internedToRef(zeros.toIntern()); | 10417 | const zero_inst = Air.internedToRef(zeros.toIntern()); |
| 10312 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq); | 10418 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq); |
| 10313 | const all_in_range = try block.addInst(.{ | 10419 | const all_in_range = try block.addInst(.{ |
| ... | @@ -10316,7 +10422,7 @@ fn intCast( | ... | @@ -10316,7 +10422,7 @@ fn intCast( |
| 10316 | }); | 10422 | }); |
| 10317 | break :ok all_in_range; | 10423 | break :ok all_in_range; |
| 10318 | } else ok: { | 10424 | } else ok: { |
| 10319 | const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern()); | 10425 | const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern()); |
| 10320 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); | 10426 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); |
| 10321 | break :ok is_in_range; | 10427 | break :ok is_in_range; |
| 10322 | }; | 10428 | }; |
| ... | @@ -10339,7 +10445,7 @@ fn intCast( | ... | @@ -10339,7 +10445,7 @@ fn intCast( |
| 10339 | // range shrinkage | 10445 | // range shrinkage |
| 10340 | // requirement: int value fits into target type | 10446 | // requirement: int value fits into target type |
| 10341 | if (wanted_value_bits < actual_value_bits) { | 10447 | if (wanted_value_bits < actual_value_bits) { |
| 10342 | const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_scalar_ty); | 10448 | const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(pt, operand_scalar_ty); |
| 10343 | const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar); | 10449 | const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar); |
| 10344 | const dest_max = Air.internedToRef(dest_max_val.toIntern()); | 10450 | const dest_max = Air.internedToRef(dest_max_val.toIntern()); |
| 10345 | 10451 | ||
| ... | @@ -10348,8 +10454,8 @@ fn intCast( | ... | @@ -10348,8 +10454,8 @@ fn intCast( |
| 10348 | 10454 | ||
| 10349 | // Reinterpret the sign-bit as part of the value. This will make | 10455 | // Reinterpret the sign-bit as part of the value. This will make |
| 10350 | // negative differences (`operand` > `dest_max`) appear too big. | 10456 | // negative differences (`operand` > `dest_max`) appear too big. |
| 10351 | const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits); | 10457 | const unsigned_scalar_operand_ty = try pt.intType(.unsigned, actual_bits); |
| 10352 | const unsigned_operand_ty = if (is_vector) try mod.vectorType(.{ | 10458 | const unsigned_operand_ty = if (is_vector) try pt.vectorType(.{ |
| 10353 | .len = dest_ty.vectorLen(mod), | 10459 | .len = dest_ty.vectorLen(mod), |
| 10354 | .child = unsigned_scalar_operand_ty.toIntern(), | 10460 | .child = unsigned_scalar_operand_ty.toIntern(), |
| 10355 | }) else unsigned_scalar_operand_ty; | 10461 | }) else unsigned_scalar_operand_ty; |
| ... | @@ -10358,14 +10464,14 @@ fn intCast( | ... | @@ -10358,14 +10464,14 @@ fn intCast( |
| 10358 | // If the destination type is signed, then we need to double its | 10464 | // If the destination type is signed, then we need to double its |
| 10359 | // range to account for negative values. | 10465 | // range to account for negative values. |
| 10360 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { | 10466 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 10361 | const one_scalar = try mod.intValue(unsigned_scalar_operand_ty, 1); | 10467 | const one_scalar = try pt.intValue(unsigned_scalar_operand_ty, 1); |
| 10362 | const one = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 10468 | const one = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 10363 | .ty = unsigned_operand_ty.toIntern(), | 10469 | .ty = unsigned_operand_ty.toIntern(), |
| 10364 | .storage = .{ .repeated_elem = one_scalar.toIntern() }, | 10470 | .storage = .{ .repeated_elem = one_scalar.toIntern() }, |
| 10365 | } }))) else one_scalar; | 10471 | } })) else one_scalar; |
| 10366 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod); | 10472 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, pt); |
| 10367 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined); | 10473 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined); |
| 10368 | } else try mod.getCoerced(dest_max_val, unsigned_operand_ty); | 10474 | } else try pt.getCoerced(dest_max_val, unsigned_operand_ty); |
| 10369 | const dest_range = Air.internedToRef(dest_range_val.toIntern()); | 10475 | const dest_range = Air.internedToRef(dest_range_val.toIntern()); |
| 10370 | 10476 | ||
| 10371 | const ok = if (is_vector) ok: { | 10477 | const ok = if (is_vector) ok: { |
| ... | @@ -10405,7 +10511,7 @@ fn intCast( | ... | @@ -10405,7 +10511,7 @@ fn intCast( |
| 10405 | // no shrinkage, yes sign loss | 10511 | // no shrinkage, yes sign loss |
| 10406 | // requirement: signed to unsigned >= 0 | 10512 | // requirement: signed to unsigned >= 0 |
| 10407 | const ok = if (is_vector) ok: { | 10513 | const ok = if (is_vector) ok: { |
| 10408 | const scalar_zero = try mod.intValue(operand_scalar_ty, 0); | 10514 | const scalar_zero = try pt.intValue(operand_scalar_ty, 0); |
| 10409 | const zero_val = try sema.splat(operand_ty, scalar_zero); | 10515 | const zero_val = try sema.splat(operand_ty, scalar_zero); |
| 10410 | const zero_inst = Air.internedToRef(zero_val.toIntern()); | 10516 | const zero_inst = Air.internedToRef(zero_val.toIntern()); |
| 10411 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); | 10517 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); |
| ... | @@ -10418,7 +10524,7 @@ fn intCast( | ... | @@ -10418,7 +10524,7 @@ fn intCast( |
| 10418 | }); | 10524 | }); |
| 10419 | break :ok all_in_range; | 10525 | break :ok all_in_range; |
| 10420 | } else ok: { | 10526 | } else ok: { |
| 10421 | const zero_inst = Air.internedToRef((try mod.intValue(operand_ty, 0)).toIntern()); | 10527 | const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern()); |
| 10422 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); | 10528 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); |
| 10423 | break :ok is_in_range; | 10529 | break :ok is_in_range; |
| 10424 | }; | 10530 | }; |
| ... | @@ -10432,7 +10538,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10432,7 +10538,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10432 | const tracy = trace(@src()); | 10538 | const tracy = trace(@src()); |
| 10433 | defer tracy.end(); | 10539 | defer tracy.end(); |
| 10434 | 10540 | ||
| 10435 | const mod = sema.mod; | 10541 | const pt = sema.pt; |
| 10542 | const mod = pt.zcu; | ||
| 10436 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10543 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10437 | const src = block.nodeOffset(inst_data.src_node); | 10544 | const src = block.nodeOffset(inst_data.src_node); |
| 10438 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 10545 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -10457,14 +10564,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10457,14 +10564,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10457 | .Type, | 10564 | .Type, |
| 10458 | .Undefined, | 10565 | .Undefined, |
| 10459 | .Void, | 10566 | .Void, |
| 10460 | => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}), | 10567 | => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}), |
| 10461 | 10568 | ||
| 10462 | .Enum => { | 10569 | .Enum => { |
| 10463 | const msg = msg: { | 10570 | const msg = msg: { |
| 10464 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}); | 10571 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}); |
| 10465 | errdefer msg.destroy(sema.gpa); | 10572 | errdefer msg.destroy(sema.gpa); |
| 10466 | switch (operand_ty.zigTypeTag(mod)) { | 10573 | switch (operand_ty.zigTypeTag(mod)) { |
| 10467 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(mod)}), | 10574 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10468 | else => {}, | 10575 | else => {}, |
| 10469 | } | 10576 | } |
| 10470 | 10577 | ||
| ... | @@ -10475,11 +10582,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10475,11 +10582,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10475 | 10582 | ||
| 10476 | .Pointer => { | 10583 | .Pointer => { |
| 10477 | const msg = msg: { | 10584 | const msg = msg: { |
| 10478 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}); | 10585 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}); |
| 10479 | errdefer msg.destroy(sema.gpa); | 10586 | errdefer msg.destroy(sema.gpa); |
| 10480 | switch (operand_ty.zigTypeTag(mod)) { | 10587 | switch (operand_ty.zigTypeTag(mod)) { |
| 10481 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(mod)}), | 10588 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10482 | .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(mod)}), | 10589 | .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10483 | else => {}, | 10590 | else => {}, |
| 10484 | } | 10591 | } |
| 10485 | 10592 | ||
| ... | @@ -10494,7 +10601,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10494,7 +10601,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10494 | else => unreachable, | 10601 | else => unreachable, |
| 10495 | }; | 10602 | }; |
| 10496 | return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{ | 10603 | return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{ |
| 10497 | dest_ty.fmt(mod), container, | 10604 | dest_ty.fmt(pt), container, |
| 10498 | }); | 10605 | }); |
| 10499 | }, | 10606 | }, |
| 10500 | 10607 | ||
| ... | @@ -10521,14 +10628,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10521,14 +10628,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10521 | .Type, | 10628 | .Type, |
| 10522 | .Undefined, | 10629 | .Undefined, |
| 10523 | .Void, | 10630 | .Void, |
| 10524 | => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}), | 10631 | => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}), |
| 10525 | 10632 | ||
| 10526 | .Enum => { | 10633 | .Enum => { |
| 10527 | const msg = msg: { | 10634 | const msg = msg: { |
| 10528 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}); | 10635 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}); |
| 10529 | errdefer msg.destroy(sema.gpa); | 10636 | errdefer msg.destroy(sema.gpa); |
| 10530 | switch (dest_ty.zigTypeTag(mod)) { | 10637 | switch (dest_ty.zigTypeTag(mod)) { |
| 10531 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(mod)}), | 10638 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10532 | else => {}, | 10639 | else => {}, |
| 10533 | } | 10640 | } |
| 10534 | 10641 | ||
| ... | @@ -10538,11 +10645,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10538,11 +10645,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10538 | }, | 10645 | }, |
| 10539 | .Pointer => { | 10646 | .Pointer => { |
| 10540 | const msg = msg: { | 10647 | const msg = msg: { |
| 10541 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}); | 10648 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}); |
| 10542 | errdefer msg.destroy(sema.gpa); | 10649 | errdefer msg.destroy(sema.gpa); |
| 10543 | switch (dest_ty.zigTypeTag(mod)) { | 10650 | switch (dest_ty.zigTypeTag(mod)) { |
| 10544 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(mod)}), | 10651 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10545 | .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(mod)}), | 10652 | .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10546 | else => {}, | 10653 | else => {}, |
| 10547 | } | 10654 | } |
| 10548 | 10655 | ||
| ... | @@ -10557,7 +10664,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10557,7 +10664,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10557 | else => unreachable, | 10664 | else => unreachable, |
| 10558 | }; | 10665 | }; |
| 10559 | return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{ | 10666 | return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{ |
| 10560 | operand_ty.fmt(mod), container, | 10667 | operand_ty.fmt(pt), container, |
| 10561 | }); | 10668 | }); |
| 10562 | }, | 10669 | }, |
| 10563 | 10670 | ||
| ... | @@ -10575,7 +10682,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -10575,7 +10682,8 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10575 | const tracy = trace(@src()); | 10682 | const tracy = trace(@src()); |
| 10576 | defer tracy.end(); | 10683 | defer tracy.end(); |
| 10577 | 10684 | ||
| 10578 | const mod = sema.mod; | 10685 | const pt = sema.pt; |
| 10686 | const mod = pt.zcu; | ||
| 10579 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10687 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10580 | const src = block.nodeOffset(inst_data.src_node); | 10688 | const src = block.nodeOffset(inst_data.src_node); |
| 10581 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 10689 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -10599,7 +10707,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -10599,7 +10707,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10599 | block, | 10707 | block, |
| 10600 | src, | 10708 | src, |
| 10601 | "expected float or vector type, found '{}'", | 10709 | "expected float or vector type, found '{}'", |
| 10602 | .{dest_ty.fmt(mod)}, | 10710 | .{dest_ty.fmt(pt)}, |
| 10603 | ), | 10711 | ), |
| 10604 | }; | 10712 | }; |
| 10605 | 10713 | ||
| ... | @@ -10609,21 +10717,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -10609,21 +10717,21 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10609 | block, | 10717 | block, |
| 10610 | operand_src, | 10718 | operand_src, |
| 10611 | "expected float or vector type, found '{}'", | 10719 | "expected float or vector type, found '{}'", |
| 10612 | .{operand_ty.fmt(mod)}, | 10720 | .{operand_ty.fmt(pt)}, |
| 10613 | ), | 10721 | ), |
| 10614 | } | 10722 | } |
| 10615 | 10723 | ||
| 10616 | if (try sema.resolveValue(operand)) |operand_val| { | 10724 | if (try sema.resolveValue(operand)) |operand_val| { |
| 10617 | if (!is_vector) { | 10725 | if (!is_vector) { |
| 10618 | return Air.internedToRef((try operand_val.floatCast(dest_ty, mod)).toIntern()); | 10726 | return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern()); |
| 10619 | } | 10727 | } |
| 10620 | const vec_len = operand_ty.vectorLen(mod); | 10728 | const vec_len = operand_ty.vectorLen(mod); |
| 10621 | const new_elems = try sema.arena.alloc(InternPool.Index, vec_len); | 10729 | const new_elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 10622 | for (new_elems, 0..) |*new_elem, i| { | 10730 | for (new_elems, 0..) |*new_elem, i| { |
| 10623 | const old_elem = try operand_val.elemValue(mod, i); | 10731 | const old_elem = try operand_val.elemValue(pt, i); |
| 10624 | new_elem.* = (try old_elem.floatCast(dest_scalar_ty, mod)).toIntern(); | 10732 | new_elem.* = (try old_elem.floatCast(dest_scalar_ty, pt)).toIntern(); |
| 10625 | } | 10733 | } |
| 10626 | return Air.internedToRef(try mod.intern(.{ .aggregate = .{ | 10734 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 10627 | .ty = dest_ty.toIntern(), | 10735 | .ty = dest_ty.toIntern(), |
| 10628 | .storage = .{ .elems = new_elems }, | 10736 | .storage = .{ .elems = new_elems }, |
| 10629 | } })); | 10737 | } })); |
| ... | @@ -10644,7 +10752,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -10644,7 +10752,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10644 | const vec_len = operand_ty.vectorLen(mod); | 10752 | const vec_len = operand_ty.vectorLen(mod); |
| 10645 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len); | 10753 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len); |
| 10646 | for (new_elems, 0..) |*new_elem, i| { | 10754 | for (new_elems, 0..) |*new_elem, i| { |
| 10647 | const idx_ref = try mod.intRef(Type.usize, i); | 10755 | const idx_ref = try pt.intRef(Type.usize, i); |
| 10648 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | 10756 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 10649 | new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem); | 10757 | new_elem.* = try block.addTyOp(.fptrunc, dest_scalar_ty, old_elem); |
| 10650 | } | 10758 | } |
| ... | @@ -10681,10 +10789,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -10681,10 +10789,9 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10681 | const tracy = trace(@src()); | 10789 | const tracy = trace(@src()); |
| 10682 | defer tracy.end(); | 10790 | defer tracy.end(); |
| 10683 | 10791 | ||
| 10684 | const mod = sema.mod; | ||
| 10685 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm; | 10792 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm; |
| 10686 | const array = try sema.resolveInst(inst_data.operand); | 10793 | const array = try sema.resolveInst(inst_data.operand); |
| 10687 | const elem_index = try mod.intRef(Type.usize, inst_data.idx); | 10794 | const elem_index = try sema.pt.intRef(Type.usize, inst_data.idx); |
| 10688 | return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false); | 10795 | return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false); |
| 10689 | } | 10796 | } |
| 10690 | 10797 | ||
| ... | @@ -10692,7 +10799,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10692,7 +10799,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10692 | const tracy = trace(@src()); | 10799 | const tracy = trace(@src()); |
| 10693 | defer tracy.end(); | 10800 | defer tracy.end(); |
| 10694 | 10801 | ||
| 10695 | const mod = sema.mod; | 10802 | const pt = sema.pt; |
| 10803 | const mod = pt.zcu; | ||
| 10696 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10804 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10697 | const src = block.nodeOffset(inst_data.src_node); | 10805 | const src = block.nodeOffset(inst_data.src_node); |
| 10698 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 10806 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -10703,7 +10811,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -10703,7 +10811,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10703 | const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node }); | 10811 | const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node }); |
| 10704 | const msg = msg: { | 10812 | const msg = msg: { |
| 10705 | const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{ | 10813 | const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{ |
| 10706 | indexable_ty.fmt(mod), | 10814 | indexable_ty.fmt(pt), |
| 10707 | }); | 10815 | }); |
| 10708 | errdefer msg.destroy(sema.gpa); | 10816 | errdefer msg.destroy(sema.gpa); |
| 10709 | if (indexable_ty.isIndexable(mod)) { | 10817 | if (indexable_ty.isIndexable(mod)) { |
| ... | @@ -10734,12 +10842,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile | ... | @@ -10734,12 +10842,13 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile |
| 10734 | const tracy = trace(@src()); | 10842 | const tracy = trace(@src()); |
| 10735 | defer tracy.end(); | 10843 | defer tracy.end(); |
| 10736 | 10844 | ||
| 10737 | const mod = sema.mod; | 10845 | const pt = sema.pt; |
| 10846 | const mod = pt.zcu; | ||
| 10738 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 10847 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10739 | const src = block.nodeOffset(inst_data.src_node); | 10848 | const src = block.nodeOffset(inst_data.src_node); |
| 10740 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; | 10849 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; |
| 10741 | const array_ptr = try sema.resolveInst(extra.ptr); | 10850 | const array_ptr = try sema.resolveInst(extra.ptr); |
| 10742 | const elem_index = try sema.mod.intRef(Type.usize, extra.index); | 10851 | const elem_index = try pt.intRef(Type.usize, extra.index); |
| 10743 | const array_ty = sema.typeOf(array_ptr).childType(mod); | 10852 | const array_ty = sema.typeOf(array_ptr).childType(mod); |
| 10744 | switch (array_ty.zigTypeTag(mod)) { | 10853 | switch (array_ty.zigTypeTag(mod)) { |
| 10745 | .Array, .Vector => {}, | 10854 | .Array, .Vector => {}, |
| ... | @@ -10892,7 +11001,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -10892,7 +11001,7 @@ const SwitchProngAnalysis = struct { |
| 10892 | inline_case_capture, | 11001 | inline_case_capture, |
| 10893 | ); | 11002 | ); |
| 10894 | 11003 | ||
| 10895 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { | 11004 | if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) { |
| 10896 | // This prong should be unreachable! | 11005 | // This prong should be unreachable! |
| 10897 | return .unreachable_value; | 11006 | return .unreachable_value; |
| 10898 | } | 11007 | } |
| ... | @@ -10948,7 +11057,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -10948,7 +11057,7 @@ const SwitchProngAnalysis = struct { |
| 10948 | inline_case_capture, | 11057 | inline_case_capture, |
| 10949 | ); | 11058 | ); |
| 10950 | 11059 | ||
| 10951 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { | 11060 | if (sema.typeOf(capture_ref).isNoReturn(sema.pt.zcu)) { |
| 10952 | // No need to analyze any further, the prong is unreachable | 11061 | // No need to analyze any further, the prong is unreachable |
| 10953 | return; | 11062 | return; |
| 10954 | } | 11063 | } |
| ... | @@ -10968,7 +11077,8 @@ const SwitchProngAnalysis = struct { | ... | @@ -10968,7 +11077,8 @@ const SwitchProngAnalysis = struct { |
| 10968 | inline_case_capture: Air.Inst.Ref, | 11077 | inline_case_capture: Air.Inst.Ref, |
| 10969 | ) CompileError!Air.Inst.Ref { | 11078 | ) CompileError!Air.Inst.Ref { |
| 10970 | const sema = spa.sema; | 11079 | const sema = spa.sema; |
| 10971 | const mod = sema.mod; | 11080 | const pt = sema.pt; |
| 11081 | const mod = pt.zcu; | ||
| 10972 | const operand_ty = sema.typeOf(spa.operand); | 11082 | const operand_ty = sema.typeOf(spa.operand); |
| 10973 | if (operand_ty.zigTypeTag(mod) != .Union) { | 11083 | if (operand_ty.zigTypeTag(mod) != .Union) { |
| 10974 | const tag_capture_src: LazySrcLoc = .{ | 11084 | const tag_capture_src: LazySrcLoc = .{ |
| ... | @@ -10976,7 +11086,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -10976,7 +11086,7 @@ const SwitchProngAnalysis = struct { |
| 10976 | .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture }, | 11086 | .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture }, |
| 10977 | }; | 11087 | }; |
| 10978 | return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{ | 11088 | return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{ |
| 10979 | operand_ty.fmt(mod), | 11089 | operand_ty.fmt(pt), |
| 10980 | }); | 11090 | }); |
| 10981 | } | 11091 | } |
| 10982 | assert(inline_case_capture != .none); | 11092 | assert(inline_case_capture != .none); |
| ... | @@ -10993,7 +11103,8 @@ const SwitchProngAnalysis = struct { | ... | @@ -10993,7 +11103,8 @@ const SwitchProngAnalysis = struct { |
| 10993 | inline_case_capture: Air.Inst.Ref, | 11103 | inline_case_capture: Air.Inst.Ref, |
| 10994 | ) CompileError!Air.Inst.Ref { | 11104 | ) CompileError!Air.Inst.Ref { |
| 10995 | const sema = spa.sema; | 11105 | const sema = spa.sema; |
| 10996 | const zcu = sema.mod; | 11106 | const pt = sema.pt; |
| 11107 | const zcu = pt.zcu; | ||
| 10997 | const ip = &zcu.intern_pool; | 11108 | const ip = &zcu.intern_pool; |
| 10998 | 11109 | ||
| 10999 | const zir_datas = sema.code.instructions.items(.data); | 11110 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -11010,7 +11121,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11010,7 +11121,7 @@ const SwitchProngAnalysis = struct { |
| 11010 | const union_obj = zcu.typeToUnion(operand_ty).?; | 11121 | const union_obj = zcu.typeToUnion(operand_ty).?; |
| 11011 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 11122 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 11012 | if (capture_byref) { | 11123 | if (capture_byref) { |
| 11013 | const ptr_field_ty = try zcu.ptrTypeSema(.{ | 11124 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 11014 | .child = field_ty.toIntern(), | 11125 | .child = field_ty.toIntern(), |
| 11015 | .flags = .{ | 11126 | .flags = .{ |
| 11016 | .is_const = !operand_ptr_ty.ptrIsMutable(zcu), | 11127 | .is_const = !operand_ptr_ty.ptrIsMutable(zcu), |
| ... | @@ -11019,7 +11130,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11019,7 +11130,7 @@ const SwitchProngAnalysis = struct { |
| 11019 | }, | 11130 | }, |
| 11020 | }); | 11131 | }); |
| 11021 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| { | 11132 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| { |
| 11022 | return Air.internedToRef((try union_ptr.ptrField(field_index, zcu)).toIntern()); | 11133 | return Air.internedToRef((try union_ptr.ptrField(field_index, pt)).toIntern()); |
| 11023 | } | 11134 | } |
| 11024 | return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty); | 11135 | return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty); |
| 11025 | } else { | 11136 | } else { |
| ... | @@ -11078,7 +11189,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11078,7 +11189,7 @@ const SwitchProngAnalysis = struct { |
| 11078 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); | 11189 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); |
| 11079 | for (dummy_captures, field_indices) |*dummy, field_idx| { | 11190 | for (dummy_captures, field_indices) |*dummy, field_idx| { |
| 11080 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11191 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11081 | dummy.* = try zcu.undefRef(field_ty); | 11192 | dummy.* = try pt.undefRef(field_ty); |
| 11082 | } | 11193 | } |
| 11083 | 11194 | ||
| 11084 | const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len); | 11195 | const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len); |
| ... | @@ -11113,7 +11224,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11113,7 +11224,7 @@ const SwitchProngAnalysis = struct { |
| 11113 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); | 11224 | const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len); |
| 11114 | for (field_indices, dummy_captures) |field_idx, *dummy| { | 11225 | for (field_indices, dummy_captures) |field_idx, *dummy| { |
| 11115 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); | 11226 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]); |
| 11116 | const field_ptr_ty = try zcu.ptrTypeSema(.{ | 11227 | const field_ptr_ty = try pt.ptrTypeSema(.{ |
| 11117 | .child = field_ty.toIntern(), | 11228 | .child = field_ty.toIntern(), |
| 11118 | .flags = .{ | 11229 | .flags = .{ |
| 11119 | .is_const = operand_ptr_info.flags.is_const, | 11230 | .is_const = operand_ptr_info.flags.is_const, |
| ... | @@ -11122,7 +11233,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11122,7 +11233,7 @@ const SwitchProngAnalysis = struct { |
| 11122 | .alignment = union_obj.fieldAlign(ip, field_idx), | 11233 | .alignment = union_obj.fieldAlign(ip, field_idx), |
| 11123 | }, | 11234 | }, |
| 11124 | }); | 11235 | }); |
| 11125 | dummy.* = try zcu.undefRef(field_ptr_ty); | 11236 | dummy.* = try pt.undefRef(field_ptr_ty); |
| 11126 | } | 11237 | } |
| 11127 | const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len); | 11238 | const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len); |
| 11128 | for (case_srcs, 0..) |*case_src, i| { | 11239 | for (case_srcs, 0..) |*case_src, i| { |
| ... | @@ -11148,9 +11259,9 @@ const SwitchProngAnalysis = struct { | ... | @@ -11148,9 +11259,9 @@ const SwitchProngAnalysis = struct { |
| 11148 | }; | 11259 | }; |
| 11149 | 11260 | ||
| 11150 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| { | 11261 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| { |
| 11151 | if (op_ptr_val.isUndef(zcu)) return zcu.undefRef(capture_ptr_ty); | 11262 | if (op_ptr_val.isUndef(zcu)) return pt.undefRef(capture_ptr_ty); |
| 11152 | const field_ptr_val = try op_ptr_val.ptrField(first_field_index, zcu); | 11263 | const field_ptr_val = try op_ptr_val.ptrField(first_field_index, pt); |
| 11153 | return Air.internedToRef((try zcu.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern()); | 11264 | return Air.internedToRef((try pt.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern()); |
| 11154 | } | 11265 | } |
| 11155 | 11266 | ||
| 11156 | try sema.requireRuntimeBlock(block, operand_src, null); | 11267 | try sema.requireRuntimeBlock(block, operand_src, null); |
| ... | @@ -11158,9 +11269,9 @@ const SwitchProngAnalysis = struct { | ... | @@ -11158,9 +11269,9 @@ const SwitchProngAnalysis = struct { |
| 11158 | } | 11269 | } |
| 11159 | 11270 | ||
| 11160 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| { | 11271 | if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |operand_val| { |
| 11161 | if (operand_val.isUndef(zcu)) return zcu.undefRef(capture_ty); | 11272 | if (operand_val.isUndef(zcu)) return pt.undefRef(capture_ty); |
| 11162 | const union_val = ip.indexToKey(operand_val.toIntern()).un; | 11273 | const union_val = ip.indexToKey(operand_val.toIntern()).un; |
| 11163 | if (Value.fromInterned(union_val.tag).isUndef(zcu)) return zcu.undefRef(capture_ty); | 11274 | if (Value.fromInterned(union_val.tag).isUndef(zcu)) return pt.undefRef(capture_ty); |
| 11164 | const uncoerced = Air.internedToRef(union_val.val); | 11275 | const uncoerced = Air.internedToRef(union_val.val); |
| 11165 | return sema.coerce(block, capture_ty, uncoerced, operand_src); | 11276 | return sema.coerce(block, capture_ty, uncoerced, operand_src); |
| 11166 | } | 11277 | } |
| ... | @@ -11304,7 +11415,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11304,7 +11415,7 @@ const SwitchProngAnalysis = struct { |
| 11304 | 11415 | ||
| 11305 | if (case_vals.len == 1) { | 11416 | if (case_vals.len == 1) { |
| 11306 | const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable; | 11417 | const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable; |
| 11307 | const item_ty = try zcu.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?); | 11418 | const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?); |
| 11308 | return sema.bitCast(block, item_ty, spa.operand, operand_src, null); | 11419 | return sema.bitCast(block, item_ty, spa.operand, operand_src, null); |
| 11309 | } | 11420 | } |
| 11310 | 11421 | ||
| ... | @@ -11314,7 +11425,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11314,7 +11425,7 @@ const SwitchProngAnalysis = struct { |
| 11314 | const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable; | 11425 | const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable; |
| 11315 | names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {}); | 11426 | names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {}); |
| 11316 | } | 11427 | } |
| 11317 | const error_ty = try zcu.errorSetFromUnsortedNames(names.keys()); | 11428 | const error_ty = try pt.errorSetFromUnsortedNames(names.keys()); |
| 11318 | return sema.bitCast(block, error_ty, spa.operand, operand_src, null); | 11429 | return sema.bitCast(block, error_ty, spa.operand, operand_src, null); |
| 11319 | }, | 11430 | }, |
| 11320 | else => { | 11431 | else => { |
| ... | @@ -11336,7 +11447,8 @@ fn switchCond( | ... | @@ -11336,7 +11447,8 @@ fn switchCond( |
| 11336 | src: LazySrcLoc, | 11447 | src: LazySrcLoc, |
| 11337 | operand: Air.Inst.Ref, | 11448 | operand: Air.Inst.Ref, |
| 11338 | ) CompileError!Air.Inst.Ref { | 11449 | ) CompileError!Air.Inst.Ref { |
| 11339 | const mod = sema.mod; | 11450 | const pt = sema.pt; |
| 11451 | const mod = pt.zcu; | ||
| 11340 | const operand_ty = sema.typeOf(operand); | 11452 | const operand_ty = sema.typeOf(operand); |
| 11341 | switch (operand_ty.zigTypeTag(mod)) { | 11453 | switch (operand_ty.zigTypeTag(mod)) { |
| 11342 | .Type, | 11454 | .Type, |
| ... | @@ -11353,7 +11465,7 @@ fn switchCond( | ... | @@ -11353,7 +11465,7 @@ fn switchCond( |
| 11353 | .Enum, | 11465 | .Enum, |
| 11354 | => { | 11466 | => { |
| 11355 | if (operand_ty.isSlice(mod)) { | 11467 | if (operand_ty.isSlice(mod)) { |
| 11356 | return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}); | 11468 | return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}); |
| 11357 | } | 11469 | } |
| 11358 | if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| { | 11470 | if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| { |
| 11359 | return Air.internedToRef(opv.toIntern()); | 11471 | return Air.internedToRef(opv.toIntern()); |
| ... | @@ -11362,7 +11474,7 @@ fn switchCond( | ... | @@ -11362,7 +11474,7 @@ fn switchCond( |
| 11362 | }, | 11474 | }, |
| 11363 | 11475 | ||
| 11364 | .Union => { | 11476 | .Union => { |
| 11365 | try operand_ty.resolveFields(mod); | 11477 | try operand_ty.resolveFields(pt); |
| 11366 | const enum_ty = operand_ty.unionTagType(mod) orelse { | 11478 | const enum_ty = operand_ty.unionTagType(mod) orelse { |
| 11367 | const msg = msg: { | 11479 | const msg = msg: { |
| 11368 | const msg = try sema.errMsg(src, "switch on union with no attached enum", .{}); | 11480 | const msg = try sema.errMsg(src, "switch on union with no attached enum", .{}); |
| ... | @@ -11388,7 +11500,7 @@ fn switchCond( | ... | @@ -11388,7 +11500,7 @@ fn switchCond( |
| 11388 | .Vector, | 11500 | .Vector, |
| 11389 | .Frame, | 11501 | .Frame, |
| 11390 | .AnyFrame, | 11502 | .AnyFrame, |
| 11391 | => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}), | 11503 | => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}), |
| 11392 | } | 11504 | } |
| 11393 | } | 11505 | } |
| 11394 | 11506 | ||
| ... | @@ -11398,7 +11510,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -11398,7 +11510,8 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11398 | const tracy = trace(@src()); | 11510 | const tracy = trace(@src()); |
| 11399 | defer tracy.end(); | 11511 | defer tracy.end(); |
| 11400 | 11512 | ||
| 11401 | const mod = sema.mod; | 11513 | const pt = sema.pt; |
| 11514 | const mod = pt.zcu; | ||
| 11402 | const gpa = sema.gpa; | 11515 | const gpa = sema.gpa; |
| 11403 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 11516 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 11404 | const switch_src = block.nodeOffset(inst_data.src_node); | 11517 | const switch_src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -11489,7 +11602,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -11489,7 +11602,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11489 | 11602 | ||
| 11490 | if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) { | 11603 | if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) { |
| 11491 | return sema.fail(block, switch_src, "expected error union type, found '{}'", .{ | 11604 | return sema.fail(block, switch_src, "expected error union type, found '{}'", .{ |
| 11492 | operand_ty.fmt(mod), | 11605 | operand_ty.fmt(pt), |
| 11493 | }); | 11606 | }); |
| 11494 | } | 11607 | } |
| 11495 | 11608 | ||
| ... | @@ -11571,7 +11684,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -11571,7 +11684,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11571 | if (operand_val.errorUnionIsPayload(mod)) { | 11684 | if (operand_val.errorUnionIsPayload(mod)) { |
| 11572 | return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges); | 11685 | return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges); |
| 11573 | } else { | 11686 | } else { |
| 11574 | const err_val = Value.fromInterned(try mod.intern(.{ | 11687 | const err_val = Value.fromInterned(try pt.intern(.{ |
| 11575 | .err = .{ | 11688 | .err = .{ |
| 11576 | .ty = operand_err_set_ty.toIntern(), | 11689 | .ty = operand_err_set_ty.toIntern(), |
| 11577 | .name = operand_val.getErrorName(mod).unwrap().?, | 11690 | .name = operand_val.getErrorName(mod).unwrap().?, |
| ... | @@ -11708,7 +11821,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11708,7 +11821,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11708 | const tracy = trace(@src()); | 11821 | const tracy = trace(@src()); |
| 11709 | defer tracy.end(); | 11822 | defer tracy.end(); |
| 11710 | 11823 | ||
| 11711 | const mod = sema.mod; | 11824 | const pt = sema.pt; |
| 11825 | const mod = pt.zcu; | ||
| 11712 | const gpa = sema.gpa; | 11826 | const gpa = sema.gpa; |
| 11713 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 11827 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 11714 | const src = block.nodeOffset(inst_data.src_node); | 11828 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -11783,7 +11897,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11783,7 +11897,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11783 | // Duplicate checking variables later also used for `inline else`. | 11897 | // Duplicate checking variables later also used for `inline else`. |
| 11784 | var seen_enum_fields: []?LazySrcLoc = &.{}; | 11898 | var seen_enum_fields: []?LazySrcLoc = &.{}; |
| 11785 | var seen_errors = SwitchErrorSet.init(gpa); | 11899 | var seen_errors = SwitchErrorSet.init(gpa); |
| 11786 | var range_set = RangeSet.init(gpa, mod); | 11900 | var range_set = RangeSet.init(gpa, pt); |
| 11787 | var true_count: u8 = 0; | 11901 | var true_count: u8 = 0; |
| 11788 | var false_count: u8 = 0; | 11902 | var false_count: u8 = 0; |
| 11789 | 11903 | ||
| ... | @@ -11924,7 +12038,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11924,7 +12038,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11924 | operand_ty.srcLoc(mod), | 12038 | operand_ty.srcLoc(mod), |
| 11925 | msg, | 12039 | msg, |
| 11926 | "enum '{}' declared here", | 12040 | "enum '{}' declared here", |
| 11927 | .{operand_ty.fmt(mod)}, | 12041 | .{operand_ty.fmt(pt)}, |
| 11928 | ); | 12042 | ); |
| 11929 | break :msg msg; | 12043 | break :msg msg; |
| 11930 | }; | 12044 | }; |
| ... | @@ -12030,8 +12144,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -12030,8 +12144,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12030 | 12144 | ||
| 12031 | check_range: { | 12145 | check_range: { |
| 12032 | if (operand_ty.zigTypeTag(mod) == .Int) { | 12146 | if (operand_ty.zigTypeTag(mod) == .Int) { |
| 12033 | const min_int = try operand_ty.minInt(mod, operand_ty); | 12147 | const min_int = try operand_ty.minInt(pt, operand_ty); |
| 12034 | const max_int = try operand_ty.maxInt(mod, operand_ty); | 12148 | const max_int = try operand_ty.maxInt(pt, operand_ty); |
| 12035 | if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) { | 12149 | if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) { |
| 12036 | if (special_prong == .@"else") { | 12150 | if (special_prong == .@"else") { |
| 12037 | return sema.fail( | 12151 | return sema.fail( |
| ... | @@ -12136,7 +12250,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -12136,7 +12250,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12136 | block, | 12250 | block, |
| 12137 | src, | 12251 | src, |
| 12138 | "else prong required when switching on type '{}'", | 12252 | "else prong required when switching on type '{}'", |
| 12139 | .{operand_ty.fmt(mod)}, | 12253 | .{operand_ty.fmt(pt)}, |
| 12140 | ); | 12254 | ); |
| 12141 | } | 12255 | } |
| 12142 | 12256 | ||
| ... | @@ -12212,7 +12326,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -12212,7 +12326,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12212 | .ComptimeFloat, | 12326 | .ComptimeFloat, |
| 12213 | .Float, | 12327 | .Float, |
| 12214 | => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{ | 12328 | => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{ |
| 12215 | operand_ty.fmt(mod), | 12329 | operand_ty.fmt(pt), |
| 12216 | }), | 12330 | }), |
| 12217 | } | 12331 | } |
| 12218 | 12332 | ||
| ... | @@ -12386,7 +12500,8 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12386,7 +12500,8 @@ fn analyzeSwitchRuntimeBlock( |
| 12386 | cond_dbg_node_index: Zir.Inst.Index, | 12500 | cond_dbg_node_index: Zir.Inst.Index, |
| 12387 | allow_err_code_unwrap: bool, | 12501 | allow_err_code_unwrap: bool, |
| 12388 | ) CompileError!Air.Inst.Ref { | 12502 | ) CompileError!Air.Inst.Ref { |
| 12389 | const mod = sema.mod; | 12503 | const pt = sema.pt; |
| 12504 | const mod = pt.zcu; | ||
| 12390 | const gpa = sema.gpa; | 12505 | const gpa = sema.gpa; |
| 12391 | const ip = &mod.intern_pool; | 12506 | const ip = &mod.intern_pool; |
| 12392 | 12507 | ||
| ... | @@ -12496,9 +12611,9 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12496,9 +12611,9 @@ fn analyzeSwitchRuntimeBlock( |
| 12496 | var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable; | 12611 | var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable; |
| 12497 | const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable; | 12612 | const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable; |
| 12498 | 12613 | ||
| 12499 | while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({ | 12614 | while (item.compareScalar(.lte, item_last, operand_ty, pt)) : ({ |
| 12500 | // Previous validation has resolved any possible lazy values. | 12615 | // Previous validation has resolved any possible lazy values. |
| 12501 | item = sema.intAddScalar(item, try mod.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) { | 12616 | item = sema.intAddScalar(item, try pt.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) { |
| 12502 | error.Overflow => unreachable, | 12617 | error.Overflow => unreachable, |
| 12503 | else => |e| return e, | 12618 | else => |e| return e, |
| 12504 | }; | 12619 | }; |
| ... | @@ -12537,7 +12652,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12537,7 +12652,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12537 | cases_extra.appendAssumeCapacity(@intFromEnum(item_ref)); | 12652 | cases_extra.appendAssumeCapacity(@intFromEnum(item_ref)); |
| 12538 | cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items)); | 12653 | cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items)); |
| 12539 | 12654 | ||
| 12540 | if (item.compareScalar(.eq, item_last, operand_ty, mod)) break; | 12655 | if (item.compareScalar(.eq, item_last, operand_ty, pt)) break; |
| 12541 | } | 12656 | } |
| 12542 | } | 12657 | } |
| 12543 | 12658 | ||
| ... | @@ -12744,14 +12859,14 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12744,14 +12859,14 @@ fn analyzeSwitchRuntimeBlock( |
| 12744 | .Enum => { | 12859 | .Enum => { |
| 12745 | if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) { | 12860 | if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) { |
| 12746 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ | 12861 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ |
| 12747 | operand_ty.fmt(mod), | 12862 | operand_ty.fmt(pt), |
| 12748 | }); | 12863 | }); |
| 12749 | } | 12864 | } |
| 12750 | for (seen_enum_fields, 0..) |f, i| { | 12865 | for (seen_enum_fields, 0..) |f, i| { |
| 12751 | if (f != null) continue; | 12866 | if (f != null) continue; |
| 12752 | cases_len += 1; | 12867 | cases_len += 1; |
| 12753 | 12868 | ||
| 12754 | const item_val = try mod.enumValueFieldIndex(operand_ty, @intCast(i)); | 12869 | const item_val = try pt.enumValueFieldIndex(operand_ty, @intCast(i)); |
| 12755 | const item_ref = Air.internedToRef(item_val.toIntern()); | 12870 | const item_ref = Air.internedToRef(item_val.toIntern()); |
| 12756 | 12871 | ||
| 12757 | case_block.instructions.shrinkRetainingCapacity(0); | 12872 | case_block.instructions.shrinkRetainingCapacity(0); |
| ... | @@ -12793,7 +12908,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12793,7 +12908,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12793 | .ErrorSet => { | 12908 | .ErrorSet => { |
| 12794 | if (operand_ty.isAnyError(mod)) { | 12909 | if (operand_ty.isAnyError(mod)) { |
| 12795 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ | 12910 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ |
| 12796 | operand_ty.fmt(mod), | 12911 | operand_ty.fmt(pt), |
| 12797 | }); | 12912 | }); |
| 12798 | } | 12913 | } |
| 12799 | const error_names = operand_ty.errorSetNames(mod); | 12914 | const error_names = operand_ty.errorSetNames(mod); |
| ... | @@ -12802,7 +12917,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12802,7 +12917,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12802 | if (seen_errors.contains(error_name)) continue; | 12917 | if (seen_errors.contains(error_name)) continue; |
| 12803 | cases_len += 1; | 12918 | cases_len += 1; |
| 12804 | 12919 | ||
| 12805 | const item_val = try mod.intern(.{ .err = .{ | 12920 | const item_val = try pt.intern(.{ .err = .{ |
| 12806 | .ty = operand_ty.toIntern(), | 12921 | .ty = operand_ty.toIntern(), |
| 12807 | .name = error_name, | 12922 | .name = error_name, |
| 12808 | } }); | 12923 | } }); |
| ... | @@ -12930,7 +13045,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12930,7 +13045,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12930 | } | 13045 | } |
| 12931 | }, | 13046 | }, |
| 12932 | else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ | 13047 | else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ |
| 12933 | operand_ty.fmt(mod), | 13048 | operand_ty.fmt(pt), |
| 12934 | }), | 13049 | }), |
| 12935 | }; | 13050 | }; |
| 12936 | 13051 | ||
| ... | @@ -13051,7 +13166,7 @@ fn resolveSwitchComptime( | ... | @@ -13051,7 +13166,7 @@ fn resolveSwitchComptime( |
| 13051 | 13166 | ||
| 13052 | const item = case_vals.items[scalar_i]; | 13167 | const item = case_vals.items[scalar_i]; |
| 13053 | const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable; | 13168 | const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable; |
| 13054 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 13169 | if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) { |
| 13055 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand); | 13170 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand); |
| 13056 | return spa.resolveProngComptime( | 13171 | return spa.resolveProngComptime( |
| 13057 | child_block, | 13172 | child_block, |
| ... | @@ -13088,7 +13203,7 @@ fn resolveSwitchComptime( | ... | @@ -13088,7 +13203,7 @@ fn resolveSwitchComptime( |
| 13088 | for (items) |item| { | 13203 | for (items) |item| { |
| 13089 | // Validation above ensured these will succeed. | 13204 | // Validation above ensured these will succeed. |
| 13090 | const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable; | 13205 | const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable; |
| 13091 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 13206 | if (operand_val.eql(item_val, operand_ty, sema.pt.zcu)) { |
| 13092 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand); | 13207 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand); |
| 13093 | return spa.resolveProngComptime( | 13208 | return spa.resolveProngComptime( |
| 13094 | child_block, | 13209 | child_block, |
| ... | @@ -13162,7 +13277,7 @@ fn resolveSwitchComptime( | ... | @@ -13162,7 +13277,7 @@ fn resolveSwitchComptime( |
| 13162 | } | 13277 | } |
| 13163 | 13278 | ||
| 13164 | const RangeSetUnhandledIterator = struct { | 13279 | const RangeSetUnhandledIterator = struct { |
| 13165 | mod: *Module, | 13280 | pt: Zcu.PerThread, |
| 13166 | cur: ?InternPool.Index, | 13281 | cur: ?InternPool.Index, |
| 13167 | max: InternPool.Index, | 13282 | max: InternPool.Index, |
| 13168 | range_i: usize, | 13283 | range_i: usize, |
| ... | @@ -13172,13 +13287,13 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -13172,13 +13287,13 @@ const RangeSetUnhandledIterator = struct { |
| 13172 | const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128); | 13287 | const preallocated_limbs = math.big.int.calcTwosCompLimbCount(128); |
| 13173 | 13288 | ||
| 13174 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { | 13289 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { |
| 13175 | const mod = sema.mod; | 13290 | const pt = sema.pt; |
| 13176 | const int_type = mod.intern_pool.indexToKey(ty.toIntern()).int_type; | 13291 | const int_type = pt.zcu.intern_pool.indexToKey(ty.toIntern()).int_type; |
| 13177 | const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits); | 13292 | const needed_limbs = math.big.int.calcTwosCompLimbCount(int_type.bits); |
| 13178 | return .{ | 13293 | return .{ |
| 13179 | .mod = mod, | 13294 | .pt = pt, |
| 13180 | .cur = (try ty.minInt(mod, ty)).toIntern(), | 13295 | .cur = (try ty.minInt(pt, ty)).toIntern(), |
| 13181 | .max = (try ty.maxInt(mod, ty)).toIntern(), | 13296 | .max = (try ty.maxInt(pt, ty)).toIntern(), |
| 13182 | .range_i = 0, | 13297 | .range_i = 0, |
| 13183 | .ranges = range_set.ranges.items, | 13298 | .ranges = range_set.ranges.items, |
| 13184 | .limbs = if (needed_limbs > preallocated_limbs) | 13299 | .limbs = if (needed_limbs > preallocated_limbs) |
| ... | @@ -13190,13 +13305,13 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -13190,13 +13305,13 @@ const RangeSetUnhandledIterator = struct { |
| 13190 | 13305 | ||
| 13191 | fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index { | 13306 | fn addOne(it: *const RangeSetUnhandledIterator, val: InternPool.Index) !?InternPool.Index { |
| 13192 | if (val == it.max) return null; | 13307 | if (val == it.max) return null; |
| 13193 | const int = it.mod.intern_pool.indexToKey(val).int; | 13308 | const int = it.pt.zcu.intern_pool.indexToKey(val).int; |
| 13194 | 13309 | ||
| 13195 | switch (int.storage) { | 13310 | switch (int.storage) { |
| 13196 | inline .u64, .i64 => |val_int| { | 13311 | inline .u64, .i64 => |val_int| { |
| 13197 | const next_int = @addWithOverflow(val_int, 1); | 13312 | const next_int = @addWithOverflow(val_int, 1); |
| 13198 | if (next_int[1] == 0) | 13313 | if (next_int[1] == 0) |
| 13199 | return (try it.mod.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern(); | 13314 | return (try it.pt.intValue(Type.fromInterned(int.ty), next_int[0])).toIntern(); |
| 13200 | }, | 13315 | }, |
| 13201 | .big_int => {}, | 13316 | .big_int => {}, |
| 13202 | .lazy_align, .lazy_size => unreachable, | 13317 | .lazy_align, .lazy_size => unreachable, |
| ... | @@ -13212,7 +13327,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -13212,7 +13327,7 @@ const RangeSetUnhandledIterator = struct { |
| 13212 | ); | 13327 | ); |
| 13213 | 13328 | ||
| 13214 | result_bigint.addScalar(val_bigint, 1); | 13329 | result_bigint.addScalar(val_bigint, 1); |
| 13215 | return (try it.mod.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern(); | 13330 | return (try it.pt.intValue_big(Type.fromInterned(int.ty), result_bigint.toConst())).toIntern(); |
| 13216 | } | 13331 | } |
| 13217 | 13332 | ||
| 13218 | fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index { | 13333 | fn next(it: *RangeSetUnhandledIterator) !?InternPool.Index { |
| ... | @@ -13274,7 +13389,8 @@ fn validateErrSetSwitch( | ... | @@ -13274,7 +13389,8 @@ fn validateErrSetSwitch( |
| 13274 | has_else: bool, | 13389 | has_else: bool, |
| 13275 | ) CompileError!?Type { | 13390 | ) CompileError!?Type { |
| 13276 | const gpa = sema.gpa; | 13391 | const gpa = sema.gpa; |
| 13277 | const mod = sema.mod; | 13392 | const pt = sema.pt; |
| 13393 | const mod = pt.zcu; | ||
| 13278 | const ip = &mod.intern_pool; | 13394 | const ip = &mod.intern_pool; |
| 13279 | 13395 | ||
| 13280 | const src_node_offset = inst_data.src_node; | 13396 | const src_node_offset = inst_data.src_node; |
| ... | @@ -13426,7 +13542,7 @@ fn validateErrSetSwitch( | ... | @@ -13426,7 +13542,7 @@ fn validateErrSetSwitch( |
| 13426 | } | 13542 | } |
| 13427 | // No need to keep the hash map metadata correct; here we | 13543 | // No need to keep the hash map metadata correct; here we |
| 13428 | // extract the (sorted) keys only. | 13544 | // extract the (sorted) keys only. |
| 13429 | return try mod.errorSetFromUnsortedNames(names.keys()); | 13545 | return try pt.errorSetFromUnsortedNames(names.keys()); |
| 13430 | }, | 13546 | }, |
| 13431 | } | 13547 | } |
| 13432 | return null; | 13548 | return null; |
| ... | @@ -13441,7 +13557,6 @@ fn validateSwitchRange( | ... | @@ -13441,7 +13557,6 @@ fn validateSwitchRange( |
| 13441 | operand_ty: Type, | 13557 | operand_ty: Type, |
| 13442 | item_src: LazySrcLoc, | 13558 | item_src: LazySrcLoc, |
| 13443 | ) CompileError![2]Air.Inst.Ref { | 13559 | ) CompileError![2]Air.Inst.Ref { |
| 13444 | const mod = sema.mod; | ||
| 13445 | const first_src: LazySrcLoc = .{ | 13560 | const first_src: LazySrcLoc = .{ |
| 13446 | .base_node_inst = item_src.base_node_inst, | 13561 | .base_node_inst = item_src.base_node_inst, |
| 13447 | .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item }, | 13562 | .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item }, |
| ... | @@ -13452,7 +13567,7 @@ fn validateSwitchRange( | ... | @@ -13452,7 +13567,7 @@ fn validateSwitchRange( |
| 13452 | }; | 13567 | }; |
| 13453 | const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src); | 13568 | const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src); |
| 13454 | const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, last_src); | 13569 | const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, last_src); |
| 13455 | if (try Value.fromInterned(first.val).compareAll(.gt, Value.fromInterned(last.val), operand_ty, mod)) { | 13570 | if (try Value.fromInterned(first.val).compareAll(.gt, Value.fromInterned(last.val), operand_ty, sema.pt)) { |
| 13456 | return sema.fail(block, item_src, "range start value is greater than the end value", .{}); | 13571 | return sema.fail(block, item_src, "range start value is greater than the end value", .{}); |
| 13457 | } | 13572 | } |
| 13458 | const maybe_prev_src = try range_set.add(first.val, last.val, item_src); | 13573 | const maybe_prev_src = try range_set.add(first.val, last.val, item_src); |
| ... | @@ -13483,7 +13598,7 @@ fn validateSwitchItemEnum( | ... | @@ -13483,7 +13598,7 @@ fn validateSwitchItemEnum( |
| 13483 | operand_ty: Type, | 13598 | operand_ty: Type, |
| 13484 | item_src: LazySrcLoc, | 13599 | item_src: LazySrcLoc, |
| 13485 | ) CompileError!Air.Inst.Ref { | 13600 | ) CompileError!Air.Inst.Ref { |
| 13486 | const ip = &sema.mod.intern_pool; | 13601 | const ip = &sema.pt.zcu.intern_pool; |
| 13487 | const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src); | 13602 | const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src); |
| 13488 | const int = ip.indexToKey(item.val).enum_tag.int; | 13603 | const int = ip.indexToKey(item.val).enum_tag.int; |
| 13489 | const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse { | 13604 | const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse { |
| ... | @@ -13505,9 +13620,8 @@ fn validateSwitchItemError( | ... | @@ -13505,9 +13620,8 @@ fn validateSwitchItemError( |
| 13505 | operand_ty: Type, | 13620 | operand_ty: Type, |
| 13506 | item_src: LazySrcLoc, | 13621 | item_src: LazySrcLoc, |
| 13507 | ) CompileError!Air.Inst.Ref { | 13622 | ) CompileError!Air.Inst.Ref { |
| 13508 | const ip = &sema.mod.intern_pool; | ||
| 13509 | const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src); | 13623 | const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src); |
| 13510 | const error_name = ip.indexToKey(item.val).err.name; | 13624 | const error_name = sema.pt.zcu.intern_pool.indexToKey(item.val).err.name; |
| 13511 | const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev| | 13625 | const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev| |
| 13512 | prev.value | 13626 | prev.value |
| 13513 | else | 13627 | else |
| ... | @@ -13593,7 +13707,7 @@ fn validateSwitchNoRange( | ... | @@ -13593,7 +13707,7 @@ fn validateSwitchNoRange( |
| 13593 | const msg = try sema.errMsg( | 13707 | const msg = try sema.errMsg( |
| 13594 | operand_src, | 13708 | operand_src, |
| 13595 | "ranges not allowed when switching on type '{}'", | 13709 | "ranges not allowed when switching on type '{}'", |
| 13596 | .{operand_ty.fmt(sema.mod)}, | 13710 | .{operand_ty.fmt(sema.pt)}, |
| 13597 | ); | 13711 | ); |
| 13598 | errdefer msg.destroy(sema.gpa); | 13712 | errdefer msg.destroy(sema.gpa); |
| 13599 | try sema.errNote( | 13713 | try sema.errNote( |
| ... | @@ -13615,7 +13729,8 @@ fn maybeErrorUnwrap( | ... | @@ -13615,7 +13729,8 @@ fn maybeErrorUnwrap( |
| 13615 | operand_src: LazySrcLoc, | 13729 | operand_src: LazySrcLoc, |
| 13616 | allow_err_code_inst: bool, | 13730 | allow_err_code_inst: bool, |
| 13617 | ) !bool { | 13731 | ) !bool { |
| 13618 | const mod = sema.mod; | 13732 | const pt = sema.pt; |
| 13733 | const mod = pt.zcu; | ||
| 13619 | if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false; | 13734 | if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false; |
| 13620 | 13735 | ||
| 13621 | const tags = sema.code.instructions.items(.tag); | 13736 | const tags = sema.code.instructions.items(.tag); |
| ... | @@ -13654,7 +13769,7 @@ fn maybeErrorUnwrap( | ... | @@ -13654,7 +13769,7 @@ fn maybeErrorUnwrap( |
| 13654 | return true; | 13769 | return true; |
| 13655 | } | 13770 | } |
| 13656 | 13771 | ||
| 13657 | const panic_fn = try mod.getBuiltin("panicUnwrapError"); | 13772 | const panic_fn = try pt.getBuiltin("panicUnwrapError"); |
| 13658 | const err_return_trace = try sema.getErrorReturnTrace(block); | 13773 | const err_return_trace = try sema.getErrorReturnTrace(block); |
| 13659 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; | 13774 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; |
| 13660 | try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check"); | 13775 | try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check"); |
| ... | @@ -13664,7 +13779,7 @@ fn maybeErrorUnwrap( | ... | @@ -13664,7 +13779,7 @@ fn maybeErrorUnwrap( |
| 13664 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 13779 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 13665 | const msg_inst = try sema.resolveInst(inst_data.operand); | 13780 | const msg_inst = try sema.resolveInst(inst_data.operand); |
| 13666 | 13781 | ||
| 13667 | const panic_fn = try mod.getBuiltin("panic"); | 13782 | const panic_fn = try pt.getBuiltin("panic"); |
| 13668 | const err_return_trace = try sema.getErrorReturnTrace(block); | 13783 | const err_return_trace = try sema.getErrorReturnTrace(block); |
| 13669 | const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value }; | 13784 | const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value }; |
| 13670 | try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check"); | 13785 | try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check"); |
| ... | @@ -13680,7 +13795,8 @@ fn maybeErrorUnwrap( | ... | @@ -13680,7 +13795,8 @@ fn maybeErrorUnwrap( |
| 13680 | } | 13795 | } |
| 13681 | 13796 | ||
| 13682 | fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void { | 13797 | fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void { |
| 13683 | const mod = sema.mod; | 13798 | const pt = sema.pt; |
| 13799 | const mod = pt.zcu; | ||
| 13684 | const index = cond.toIndex() orelse return; | 13800 | const index = cond.toIndex() orelse return; |
| 13685 | if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return; | 13801 | if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return; |
| 13686 | 13802 | ||
| ... | @@ -13713,14 +13829,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I | ... | @@ -13713,14 +13829,15 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I |
| 13713 | const src = block.nodeOffset(inst_data.src_node); | 13829 | const src = block.nodeOffset(inst_data.src_node); |
| 13714 | 13830 | ||
| 13715 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 13831 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 13716 | if (val.getErrorName(sema.mod).unwrap()) |name| { | 13832 | if (val.getErrorName(sema.pt.zcu).unwrap()) |name| { |
| 13717 | return sema.failWithComptimeErrorRetTrace(block, src, name); | 13833 | return sema.failWithComptimeErrorRetTrace(block, src, name); |
| 13718 | } | 13834 | } |
| 13719 | } | 13835 | } |
| 13720 | } | 13836 | } |
| 13721 | 13837 | ||
| 13722 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13838 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13723 | const mod = sema.mod; | 13839 | const pt = sema.pt; |
| 13840 | const mod = pt.zcu; | ||
| 13724 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 13841 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13725 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 13842 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 13726 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 13843 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -13729,7 +13846,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13729,7 +13846,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13729 | const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ | 13846 | const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ |
| 13730 | .needed_comptime_reason = "field name must be comptime-known", | 13847 | .needed_comptime_reason = "field name must be comptime-known", |
| 13731 | }); | 13848 | }); |
| 13732 | try ty.resolveFields(mod); | 13849 | try ty.resolveFields(pt); |
| 13733 | const ip = &mod.intern_pool; | 13850 | const ip = &mod.intern_pool; |
| 13734 | 13851 | ||
| 13735 | const has_field = hf: { | 13852 | const has_field = hf: { |
| ... | @@ -13764,14 +13881,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13764,14 +13881,15 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13764 | else => {}, | 13881 | else => {}, |
| 13765 | } | 13882 | } |
| 13766 | return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{ | 13883 | return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{ |
| 13767 | ty.fmt(mod), | 13884 | ty.fmt(pt), |
| 13768 | }); | 13885 | }); |
| 13769 | }; | 13886 | }; |
| 13770 | return if (has_field) .bool_true else .bool_false; | 13887 | return if (has_field) .bool_true else .bool_false; |
| 13771 | } | 13888 | } |
| 13772 | 13889 | ||
| 13773 | fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13890 | fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13774 | const mod = sema.mod; | 13891 | const pt = sema.pt; |
| 13892 | const mod = pt.zcu; | ||
| 13775 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 13893 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13776 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 13894 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 13777 | const src = block.nodeOffset(inst_data.src_node); | 13895 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -13804,7 +13922,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13804,7 +13922,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13804 | const tracy = trace(@src()); | 13922 | const tracy = trace(@src()); |
| 13805 | defer tracy.end(); | 13923 | defer tracy.end(); |
| 13806 | 13924 | ||
| 13807 | const zcu = sema.mod; | 13925 | const pt = sema.pt; |
| 13926 | const zcu = pt.zcu; | ||
| 13808 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 13927 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 13809 | const operand_src = block.tokenOffset(inst_data.src_tok); | 13928 | const operand_src = block.tokenOffset(inst_data.src_tok); |
| 13810 | const operand = inst_data.get(sema.code); | 13929 | const operand = inst_data.get(sema.code); |
| ... | @@ -13824,7 +13943,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13824,7 +13943,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13824 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); | 13943 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); |
| 13825 | }, | 13944 | }, |
| 13826 | }; | 13945 | }; |
| 13827 | try zcu.ensureFileAnalyzed(result.file_index); | 13946 | try pt.ensureFileAnalyzed(result.file_index); |
| 13828 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; | 13947 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; |
| 13829 | return sema.analyzeDeclVal(block, operand_src, file_root_decl_index); | 13948 | return sema.analyzeDeclVal(block, operand_src, file_root_decl_index); |
| 13830 | } | 13949 | } |
| ... | @@ -13833,7 +13952,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -13833,7 +13952,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 13833 | const tracy = trace(@src()); | 13952 | const tracy = trace(@src()); |
| 13834 | defer tracy.end(); | 13953 | defer tracy.end(); |
| 13835 | 13954 | ||
| 13836 | const mod = sema.mod; | 13955 | const pt = sema.pt; |
| 13837 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 13956 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 13838 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 13957 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 13839 | const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{ | 13958 | const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{ |
| ... | @@ -13844,7 +13963,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -13844,7 +13963,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 13844 | return sema.fail(block, operand_src, "file path name cannot be empty", .{}); | 13963 | return sema.fail(block, operand_src, "file path name cannot be empty", .{}); |
| 13845 | } | 13964 | } |
| 13846 | 13965 | ||
| 13847 | const val = mod.embedFile(block.getFileScope(mod), name, operand_src) catch |err| switch (err) { | 13966 | const val = pt.embedFile(block.getFileScope(pt.zcu), name, operand_src) catch |err| switch (err) { |
| 13848 | error.ImportOutsideModulePath => { | 13967 | error.ImportOutsideModulePath => { |
| 13849 | return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name}); | 13968 | return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name}); |
| 13850 | }, | 13969 | }, |
| ... | @@ -13859,7 +13978,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -13859,7 +13978,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 13859 | } | 13978 | } |
| 13860 | 13979 | ||
| 13861 | fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13980 | fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13862 | const mod = sema.mod; | 13981 | const pt = sema.pt; |
| 13982 | const mod = pt.zcu; | ||
| 13863 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 13983 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 13864 | const name = try mod.intern_pool.getOrPutString( | 13984 | const name = try mod.intern_pool.getOrPutString( |
| 13865 | sema.gpa, | 13985 | sema.gpa, |
| ... | @@ -13867,8 +13987,8 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R | ... | @@ -13867,8 +13987,8 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R |
| 13867 | .no_embedded_nulls, | 13987 | .no_embedded_nulls, |
| 13868 | ); | 13988 | ); |
| 13869 | _ = try mod.getErrorValue(name); | 13989 | _ = try mod.getErrorValue(name); |
| 13870 | const error_set_type = try mod.singleErrorSetType(name); | 13990 | const error_set_type = try pt.singleErrorSetType(name); |
| 13871 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 13991 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 13872 | .ty = error_set_type.toIntern(), | 13992 | .ty = error_set_type.toIntern(), |
| 13873 | .name = name, | 13993 | .name = name, |
| 13874 | } }))); | 13994 | } }))); |
| ... | @@ -13883,7 +14003,8 @@ fn zirShl( | ... | @@ -13883,7 +14003,8 @@ fn zirShl( |
| 13883 | const tracy = trace(@src()); | 14003 | const tracy = trace(@src()); |
| 13884 | defer tracy.end(); | 14004 | defer tracy.end(); |
| 13885 | 14005 | ||
| 13886 | const mod = sema.mod; | 14006 | const pt = sema.pt; |
| 14007 | const mod = pt.zcu; | ||
| 13887 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14008 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13888 | const src = block.nodeOffset(inst_data.src_node); | 14009 | const src = block.nodeOffset(inst_data.src_node); |
| 13889 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 14010 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -13906,53 +14027,53 @@ fn zirShl( | ... | @@ -13906,53 +14027,53 @@ fn zirShl( |
| 13906 | 14027 | ||
| 13907 | if (maybe_rhs_val) |rhs_val| { | 14028 | if (maybe_rhs_val) |rhs_val| { |
| 13908 | if (rhs_val.isUndef(mod)) { | 14029 | if (rhs_val.isUndef(mod)) { |
| 13909 | return mod.undefRef(sema.typeOf(lhs)); | 14030 | return pt.undefRef(sema.typeOf(lhs)); |
| 13910 | } | 14031 | } |
| 13911 | // If rhs is 0, return lhs without doing any calculations. | 14032 | // If rhs is 0, return lhs without doing any calculations. |
| 13912 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 14033 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 13913 | return lhs; | 14034 | return lhs; |
| 13914 | } | 14035 | } |
| 13915 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) { | 14036 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) { |
| 13916 | const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); | 14037 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); |
| 13917 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 14038 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| 13918 | var i: usize = 0; | 14039 | var i: usize = 0; |
| 13919 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 14040 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 13920 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14041 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 13921 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { | 14042 | if (rhs_elem.compareHetero(.gte, bit_value, pt)) { |
| 13922 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ | 14043 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 13923 | rhs_elem.fmtValue(mod, sema), | 14044 | rhs_elem.fmtValue(pt, sema), |
| 13924 | i, | 14045 | i, |
| 13925 | scalar_ty.fmt(mod), | 14046 | scalar_ty.fmt(pt), |
| 13926 | }); | 14047 | }); |
| 13927 | } | 14048 | } |
| 13928 | } | 14049 | } |
| 13929 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { | 14050 | } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { |
| 13930 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ | 14051 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 13931 | rhs_val.fmtValue(mod, sema), | 14052 | rhs_val.fmtValue(pt, sema), |
| 13932 | scalar_ty.fmt(mod), | 14053 | scalar_ty.fmt(pt), |
| 13933 | }); | 14054 | }); |
| 13934 | } | 14055 | } |
| 13935 | } | 14056 | } |
| 13936 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 14057 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| 13937 | var i: usize = 0; | 14058 | var i: usize = 0; |
| 13938 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 14059 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 13939 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14060 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 13940 | if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { | 14061 | if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), pt)) { |
| 13941 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 14062 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 13942 | rhs_elem.fmtValue(mod, sema), | 14063 | rhs_elem.fmtValue(pt, sema), |
| 13943 | i, | 14064 | i, |
| 13944 | }); | 14065 | }); |
| 13945 | } | 14066 | } |
| 13946 | } | 14067 | } |
| 13947 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { | 14068 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { |
| 13948 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 14069 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 13949 | rhs_val.fmtValue(mod, sema), | 14070 | rhs_val.fmtValue(pt, sema), |
| 13950 | }); | 14071 | }); |
| 13951 | } | 14072 | } |
| 13952 | } | 14073 | } |
| 13953 | 14074 | ||
| 13954 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { | 14075 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { |
| 13955 | if (lhs_val.isUndef(mod)) return mod.undefRef(lhs_ty); | 14076 | if (lhs_val.isUndef(mod)) return pt.undefRef(lhs_ty); |
| 13956 | const rhs_val = maybe_rhs_val orelse { | 14077 | const rhs_val = maybe_rhs_val orelse { |
| 13957 | if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | 14078 | if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { |
| 13958 | return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{}); | 14079 | return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{}); |
| ... | @@ -13960,17 +14081,17 @@ fn zirShl( | ... | @@ -13960,17 +14081,17 @@ fn zirShl( |
| 13960 | break :rs rhs_src; | 14081 | break :rs rhs_src; |
| 13961 | }; | 14082 | }; |
| 13962 | const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) | 14083 | const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) |
| 13963 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) | 14084 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, pt) |
| 13964 | else switch (air_tag) { | 14085 | else switch (air_tag) { |
| 13965 | .shl_exact => val: { | 14086 | .shl_exact => val: { |
| 13966 | const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod); | 14087 | const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, pt); |
| 13967 | if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) { | 14088 | if (shifted.overflow_bit.compareAllWithZero(.eq, pt)) { |
| 13968 | break :val shifted.wrapped_result; | 14089 | break :val shifted.wrapped_result; |
| 13969 | } | 14090 | } |
| 13970 | return sema.fail(block, src, "operation caused overflow", .{}); | 14091 | return sema.fail(block, src, "operation caused overflow", .{}); |
| 13971 | }, | 14092 | }, |
| 13972 | .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), | 14093 | .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, pt), |
| 13973 | .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), | 14094 | .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, pt), |
| 13974 | else => unreachable, | 14095 | else => unreachable, |
| 13975 | }; | 14096 | }; |
| 13976 | return Air.internedToRef(val.toIntern()); | 14097 | return Air.internedToRef(val.toIntern()); |
| ... | @@ -13981,7 +14102,7 @@ fn zirShl( | ... | @@ -13981,7 +14102,7 @@ fn zirShl( |
| 13981 | if (rhs_is_comptime_int or | 14102 | if (rhs_is_comptime_int or |
| 13982 | scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits) | 14103 | scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits) |
| 13983 | { | 14104 | { |
| 13984 | const max_int = Air.internedToRef((try lhs_ty.maxInt(mod, lhs_ty)).toIntern()); | 14105 | const max_int = Air.internedToRef((try lhs_ty.maxInt(pt, lhs_ty)).toIntern()); |
| 13985 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src }); | 14106 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src }); |
| 13986 | break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false); | 14107 | break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false); |
| 13987 | } else { | 14108 | } else { |
| ... | @@ -13993,7 +14114,7 @@ fn zirShl( | ... | @@ -13993,7 +14114,7 @@ fn zirShl( |
| 13993 | if (block.wantSafety()) { | 14114 | if (block.wantSafety()) { |
| 13994 | const bit_count = scalar_ty.intInfo(mod).bits; | 14115 | const bit_count = scalar_ty.intInfo(mod).bits; |
| 13995 | if (!std.math.isPowerOfTwo(bit_count)) { | 14116 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 13996 | const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count); | 14117 | const bit_count_val = try pt.intValue(scalar_rhs_ty, bit_count); |
| 13997 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | 14118 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { |
| 13998 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); | 14119 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); |
| 13999 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); | 14120 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); |
| ... | @@ -14034,7 +14155,7 @@ fn zirShl( | ... | @@ -14034,7 +14155,7 @@ fn zirShl( |
| 14034 | }) | 14155 | }) |
| 14035 | else | 14156 | else |
| 14036 | ov_bit; | 14157 | ov_bit; |
| 14037 | const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern()); | 14158 | const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); |
| 14038 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | 14159 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 14039 | 14160 | ||
| 14040 | try sema.addSafetyCheck(block, src, no_ov, .shl_overflow); | 14161 | try sema.addSafetyCheck(block, src, no_ov, .shl_overflow); |
| ... | @@ -14053,7 +14174,8 @@ fn zirShr( | ... | @@ -14053,7 +14174,8 @@ fn zirShr( |
| 14053 | const tracy = trace(@src()); | 14174 | const tracy = trace(@src()); |
| 14054 | defer tracy.end(); | 14175 | defer tracy.end(); |
| 14055 | 14176 | ||
| 14056 | const mod = sema.mod; | 14177 | const pt = sema.pt; |
| 14178 | const mod = pt.zcu; | ||
| 14057 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14179 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14058 | const src = block.nodeOffset(inst_data.src_node); | 14180 | const src = block.nodeOffset(inst_data.src_node); |
| 14059 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 14181 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -14071,61 +14193,61 @@ fn zirShr( | ... | @@ -14071,61 +14193,61 @@ fn zirShr( |
| 14071 | 14193 | ||
| 14072 | const runtime_src = if (maybe_rhs_val) |rhs_val| rs: { | 14194 | const runtime_src = if (maybe_rhs_val) |rhs_val| rs: { |
| 14073 | if (rhs_val.isUndef(mod)) { | 14195 | if (rhs_val.isUndef(mod)) { |
| 14074 | return mod.undefRef(lhs_ty); | 14196 | return pt.undefRef(lhs_ty); |
| 14075 | } | 14197 | } |
| 14076 | // If rhs is 0, return lhs without doing any calculations. | 14198 | // If rhs is 0, return lhs without doing any calculations. |
| 14077 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 14199 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 14078 | return lhs; | 14200 | return lhs; |
| 14079 | } | 14201 | } |
| 14080 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) { | 14202 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) { |
| 14081 | const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); | 14203 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); |
| 14082 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 14204 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| 14083 | var i: usize = 0; | 14205 | var i: usize = 0; |
| 14084 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 14206 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 14085 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14207 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14086 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { | 14208 | if (rhs_elem.compareHetero(.gte, bit_value, pt)) { |
| 14087 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ | 14209 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 14088 | rhs_elem.fmtValue(mod, sema), | 14210 | rhs_elem.fmtValue(pt, sema), |
| 14089 | i, | 14211 | i, |
| 14090 | scalar_ty.fmt(mod), | 14212 | scalar_ty.fmt(pt), |
| 14091 | }); | 14213 | }); |
| 14092 | } | 14214 | } |
| 14093 | } | 14215 | } |
| 14094 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { | 14216 | } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { |
| 14095 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ | 14217 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 14096 | rhs_val.fmtValue(mod, sema), | 14218 | rhs_val.fmtValue(pt, sema), |
| 14097 | scalar_ty.fmt(mod), | 14219 | scalar_ty.fmt(pt), |
| 14098 | }); | 14220 | }); |
| 14099 | } | 14221 | } |
| 14100 | } | 14222 | } |
| 14101 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | 14223 | if (rhs_ty.zigTypeTag(mod) == .Vector) { |
| 14102 | var i: usize = 0; | 14224 | var i: usize = 0; |
| 14103 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 14225 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 14104 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14226 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14105 | if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { | 14227 | if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(mod), 0), pt)) { |
| 14106 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 14228 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 14107 | rhs_elem.fmtValue(mod, sema), | 14229 | rhs_elem.fmtValue(pt, sema), |
| 14108 | i, | 14230 | i, |
| 14109 | }); | 14231 | }); |
| 14110 | } | 14232 | } |
| 14111 | } | 14233 | } |
| 14112 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { | 14234 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { |
| 14113 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 14235 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 14114 | rhs_val.fmtValue(mod, sema), | 14236 | rhs_val.fmtValue(pt, sema), |
| 14115 | }); | 14237 | }); |
| 14116 | } | 14238 | } |
| 14117 | if (maybe_lhs_val) |lhs_val| { | 14239 | if (maybe_lhs_val) |lhs_val| { |
| 14118 | if (lhs_val.isUndef(mod)) { | 14240 | if (lhs_val.isUndef(mod)) { |
| 14119 | return mod.undefRef(lhs_ty); | 14241 | return pt.undefRef(lhs_ty); |
| 14120 | } | 14242 | } |
| 14121 | if (air_tag == .shr_exact) { | 14243 | if (air_tag == .shr_exact) { |
| 14122 | // Detect if any ones would be shifted out. | 14244 | // Detect if any ones would be shifted out. |
| 14123 | const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod); | 14245 | const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, pt); |
| 14124 | if (!(try truncated.compareAllWithZeroSema(.eq, mod))) { | 14246 | if (!(try truncated.compareAllWithZeroSema(.eq, pt))) { |
| 14125 | return sema.fail(block, src, "exact shift shifted out 1 bits", .{}); | 14247 | return sema.fail(block, src, "exact shift shifted out 1 bits", .{}); |
| 14126 | } | 14248 | } |
| 14127 | } | 14249 | } |
| 14128 | const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, mod); | 14250 | const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, pt); |
| 14129 | return Air.internedToRef(val.toIntern()); | 14251 | return Air.internedToRef(val.toIntern()); |
| 14130 | } else { | 14252 | } else { |
| 14131 | break :rs lhs_src; | 14253 | break :rs lhs_src; |
| ... | @@ -14141,7 +14263,7 @@ fn zirShr( | ... | @@ -14141,7 +14263,7 @@ fn zirShr( |
| 14141 | if (block.wantSafety()) { | 14263 | if (block.wantSafety()) { |
| 14142 | const bit_count = scalar_ty.intInfo(mod).bits; | 14264 | const bit_count = scalar_ty.intInfo(mod).bits; |
| 14143 | if (!std.math.isPowerOfTwo(bit_count)) { | 14265 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 14144 | const bit_count_val = try mod.intValue(rhs_ty.scalarType(mod), bit_count); | 14266 | const bit_count_val = try pt.intValue(rhs_ty.scalarType(mod), bit_count); |
| 14145 | 14267 | ||
| 14146 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | 14268 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { |
| 14147 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); | 14269 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); |
| ... | @@ -14188,7 +14310,8 @@ fn zirBitwise( | ... | @@ -14188,7 +14310,8 @@ fn zirBitwise( |
| 14188 | const tracy = trace(@src()); | 14310 | const tracy = trace(@src()); |
| 14189 | defer tracy.end(); | 14311 | defer tracy.end(); |
| 14190 | 14312 | ||
| 14191 | const mod = sema.mod; | 14313 | const pt = sema.pt; |
| 14314 | const mod = pt.zcu; | ||
| 14192 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14315 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14193 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 14316 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 14194 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 14317 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -14220,9 +14343,9 @@ fn zirBitwise( | ... | @@ -14220,9 +14343,9 @@ fn zirBitwise( |
| 14220 | if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| { | 14343 | if (try sema.resolveValueIntable(casted_lhs)) |lhs_val| { |
| 14221 | if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| { | 14344 | if (try sema.resolveValueIntable(casted_rhs)) |rhs_val| { |
| 14222 | const result_val = switch (air_tag) { | 14345 | const result_val = switch (air_tag) { |
| 14223 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, mod), | 14346 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, pt), |
| 14224 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, mod), | 14347 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, pt), |
| 14225 | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, mod), | 14348 | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, pt), |
| 14226 | else => unreachable, | 14349 | else => unreachable, |
| 14227 | }; | 14350 | }; |
| 14228 | return Air.internedToRef(result_val.toIntern()); | 14351 | return Air.internedToRef(result_val.toIntern()); |
| ... | @@ -14242,7 +14365,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14242,7 +14365,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14242 | const tracy = trace(@src()); | 14365 | const tracy = trace(@src()); |
| 14243 | defer tracy.end(); | 14366 | defer tracy.end(); |
| 14244 | 14367 | ||
| 14245 | const mod = sema.mod; | 14368 | const pt = sema.pt; |
| 14369 | const mod = pt.zcu; | ||
| 14246 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 14370 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14247 | const src = block.nodeOffset(inst_data.src_node); | 14371 | const src = block.nodeOffset(inst_data.src_node); |
| 14248 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); | 14372 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| ... | @@ -14253,26 +14377,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14253,26 +14377,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14253 | 14377 | ||
| 14254 | if (scalar_type.zigTypeTag(mod) != .Int) { | 14378 | if (scalar_type.zigTypeTag(mod) != .Int) { |
| 14255 | return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{ | 14379 | return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{ |
| 14256 | operand_type.fmt(mod), | 14380 | operand_type.fmt(pt), |
| 14257 | }); | 14381 | }); |
| 14258 | } | 14382 | } |
| 14259 | 14383 | ||
| 14260 | if (try sema.resolveValue(operand)) |val| { | 14384 | if (try sema.resolveValue(operand)) |val| { |
| 14261 | if (val.isUndef(mod)) { | 14385 | if (val.isUndef(mod)) { |
| 14262 | return mod.undefRef(operand_type); | 14386 | return pt.undefRef(operand_type); |
| 14263 | } else if (operand_type.zigTypeTag(mod) == .Vector) { | 14387 | } else if (operand_type.zigTypeTag(mod) == .Vector) { |
| 14264 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod)); | 14388 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod)); |
| 14265 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 14389 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 14266 | for (elems, 0..) |*elem, i| { | 14390 | for (elems, 0..) |*elem, i| { |
| 14267 | const elem_val = try val.elemValue(mod, i); | 14391 | const elem_val = try val.elemValue(pt, i); |
| 14268 | elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern(); | 14392 | elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, pt)).toIntern(); |
| 14269 | } | 14393 | } |
| 14270 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 14394 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 14271 | .ty = operand_type.toIntern(), | 14395 | .ty = operand_type.toIntern(), |
| 14272 | .storage = .{ .elems = elems }, | 14396 | .storage = .{ .elems = elems }, |
| 14273 | } }))); | 14397 | } }))); |
| 14274 | } else { | 14398 | } else { |
| 14275 | const result_val = try val.bitwiseNot(operand_type, sema.arena, mod); | 14399 | const result_val = try val.bitwiseNot(operand_type, sema.arena, pt); |
| 14276 | return Air.internedToRef(result_val.toIntern()); | 14400 | return Air.internedToRef(result_val.toIntern()); |
| 14277 | } | 14401 | } |
| 14278 | } | 14402 | } |
| ... | @@ -14288,7 +14412,8 @@ fn analyzeTupleCat( | ... | @@ -14288,7 +14412,8 @@ fn analyzeTupleCat( |
| 14288 | lhs: Air.Inst.Ref, | 14412 | lhs: Air.Inst.Ref, |
| 14289 | rhs: Air.Inst.Ref, | 14413 | rhs: Air.Inst.Ref, |
| 14290 | ) CompileError!Air.Inst.Ref { | 14414 | ) CompileError!Air.Inst.Ref { |
| 14291 | const mod = sema.mod; | 14415 | const pt = sema.pt; |
| 14416 | const mod = pt.zcu; | ||
| 14292 | const lhs_ty = sema.typeOf(lhs); | 14417 | const lhs_ty = sema.typeOf(lhs); |
| 14293 | const rhs_ty = sema.typeOf(rhs); | 14418 | const rhs_ty = sema.typeOf(rhs); |
| 14294 | const src = block.nodeOffset(src_node); | 14419 | const src = block.nodeOffset(src_node); |
| ... | @@ -14344,14 +14469,14 @@ fn analyzeTupleCat( | ... | @@ -14344,14 +14469,14 @@ fn analyzeTupleCat( |
| 14344 | break :rs runtime_src; | 14469 | break :rs runtime_src; |
| 14345 | }; | 14470 | }; |
| 14346 | 14471 | ||
| 14347 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{ | 14472 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{ |
| 14348 | .types = types, | 14473 | .types = types, |
| 14349 | .values = values, | 14474 | .values = values, |
| 14350 | .names = &.{}, | 14475 | .names = &.{}, |
| 14351 | }); | 14476 | }); |
| 14352 | 14477 | ||
| 14353 | const runtime_src = opt_runtime_src orelse { | 14478 | const runtime_src = opt_runtime_src orelse { |
| 14354 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 14479 | const tuple_val = try pt.intern(.{ .aggregate = .{ |
| 14355 | .ty = tuple_ty, | 14480 | .ty = tuple_ty, |
| 14356 | .storage = .{ .elems = values }, | 14481 | .storage = .{ .elems = values }, |
| 14357 | } }); | 14482 | } }); |
| ... | @@ -14386,7 +14511,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14386,7 +14511,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14386 | const tracy = trace(@src()); | 14511 | const tracy = trace(@src()); |
| 14387 | defer tracy.end(); | 14512 | defer tracy.end(); |
| 14388 | 14513 | ||
| 14389 | const mod = sema.mod; | 14514 | const pt = sema.pt; |
| 14515 | const mod = pt.zcu; | ||
| 14390 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14516 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14391 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 14517 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 14392 | const lhs = try sema.resolveInst(extra.lhs); | 14518 | const lhs = try sema.resolveInst(extra.lhs); |
| ... | @@ -14406,11 +14532,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14406,11 +14532,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14406 | 14532 | ||
| 14407 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: { | 14533 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: { |
| 14408 | if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined); | 14534 | if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined); |
| 14409 | return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)}); | 14535 | return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)}); |
| 14410 | }; | 14536 | }; |
| 14411 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse { | 14537 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse { |
| 14412 | assert(!rhs_is_tuple); | 14538 | assert(!rhs_is_tuple); |
| 14413 | return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(mod)}); | 14539 | return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(pt)}); |
| 14414 | }; | 14540 | }; |
| 14415 | 14541 | ||
| 14416 | const resolved_elem_ty = t: { | 14542 | const resolved_elem_ty = t: { |
| ... | @@ -14472,7 +14598,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14472,7 +14598,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14472 | ), | 14598 | ), |
| 14473 | }; | 14599 | }; |
| 14474 | 14600 | ||
| 14475 | const result_ty = try mod.arrayType(.{ | 14601 | const result_ty = try pt.arrayType(.{ |
| 14476 | .len = result_len, | 14602 | .len = result_len, |
| 14477 | .sentinel = if (res_sent_val) |v| v.toIntern() else .none, | 14603 | .sentinel = if (res_sent_val) |v| v.toIntern() else .none, |
| 14478 | .child = resolved_elem_ty.toIntern(), | 14604 | .child = resolved_elem_ty.toIntern(), |
| ... | @@ -14512,7 +14638,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14512,7 +14638,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14512 | while (elem_i < lhs_len) : (elem_i += 1) { | 14638 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14513 | const lhs_elem_i = elem_i; | 14639 | const lhs_elem_i = elem_i; |
| 14514 | const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable"; | 14640 | const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable"; |
| 14515 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(mod, lhs_elem_i) else elem_default_val; | 14641 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(pt, lhs_elem_i) else elem_default_val; |
| 14516 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); | 14642 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 14517 | const operand_src = block.src(.{ .array_cat_lhs = .{ | 14643 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14518 | .array_cat_offset = inst_data.src_node, | 14644 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14525,7 +14651,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14525,7 +14651,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14525 | while (elem_i < result_len) : (elem_i += 1) { | 14651 | while (elem_i < result_len) : (elem_i += 1) { |
| 14526 | const rhs_elem_i = elem_i - lhs_len; | 14652 | const rhs_elem_i = elem_i - lhs_len; |
| 14527 | const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable"; | 14653 | const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable"; |
| 14528 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val; | 14654 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(pt, rhs_elem_i) else elem_default_val; |
| 14529 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); | 14655 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 14530 | const operand_src = block.src(.{ .array_cat_rhs = .{ | 14656 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14531 | .array_cat_offset = inst_data.src_node, | 14657 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14535,7 +14661,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14535,7 +14661,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14535 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); | 14661 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); |
| 14536 | element_vals[elem_i] = coerced_elem_val.toIntern(); | 14662 | element_vals[elem_i] = coerced_elem_val.toIntern(); |
| 14537 | } | 14663 | } |
| 14538 | return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{ | 14664 | return sema.addConstantMaybeRef(try pt.intern(.{ .aggregate = .{ |
| 14539 | .ty = result_ty.toIntern(), | 14665 | .ty = result_ty.toIntern(), |
| 14540 | .storage = .{ .elems = element_vals }, | 14666 | .storage = .{ .elems = element_vals }, |
| 14541 | } }), ptr_addrspace != null); | 14667 | } }), ptr_addrspace != null); |
| ... | @@ -14545,19 +14671,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14545,19 +14671,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14545 | try sema.requireRuntimeBlock(block, src, runtime_src); | 14671 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14546 | 14672 | ||
| 14547 | if (ptr_addrspace) |ptr_as| { | 14673 | if (ptr_addrspace) |ptr_as| { |
| 14548 | const alloc_ty = try mod.ptrTypeSema(.{ | 14674 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 14549 | .child = result_ty.toIntern(), | 14675 | .child = result_ty.toIntern(), |
| 14550 | .flags = .{ .address_space = ptr_as }, | 14676 | .flags = .{ .address_space = ptr_as }, |
| 14551 | }); | 14677 | }); |
| 14552 | const alloc = try block.addTy(.alloc, alloc_ty); | 14678 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 14553 | const elem_ptr_ty = try mod.ptrTypeSema(.{ | 14679 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 14554 | .child = resolved_elem_ty.toIntern(), | 14680 | .child = resolved_elem_ty.toIntern(), |
| 14555 | .flags = .{ .address_space = ptr_as }, | 14681 | .flags = .{ .address_space = ptr_as }, |
| 14556 | }); | 14682 | }); |
| 14557 | 14683 | ||
| 14558 | var elem_i: u32 = 0; | 14684 | var elem_i: u32 = 0; |
| 14559 | while (elem_i < lhs_len) : (elem_i += 1) { | 14685 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14560 | const elem_index = try mod.intRef(Type.usize, elem_i); | 14686 | const elem_index = try pt.intRef(Type.usize, elem_i); |
| 14561 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 14687 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 14562 | const operand_src = block.src(.{ .array_cat_lhs = .{ | 14688 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14563 | .array_cat_offset = inst_data.src_node, | 14689 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14568,8 +14694,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14568,8 +14694,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14568 | } | 14694 | } |
| 14569 | while (elem_i < result_len) : (elem_i += 1) { | 14695 | while (elem_i < result_len) : (elem_i += 1) { |
| 14570 | const rhs_elem_i = elem_i - lhs_len; | 14696 | const rhs_elem_i = elem_i - lhs_len; |
| 14571 | const elem_index = try mod.intRef(Type.usize, elem_i); | 14697 | const elem_index = try pt.intRef(Type.usize, elem_i); |
| 14572 | const rhs_index = try mod.intRef(Type.usize, rhs_elem_i); | 14698 | const rhs_index = try pt.intRef(Type.usize, rhs_elem_i); |
| 14573 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 14699 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 14574 | const operand_src = block.src(.{ .array_cat_rhs = .{ | 14700 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14575 | .array_cat_offset = inst_data.src_node, | 14701 | .array_cat_offset = inst_data.src_node, |
| ... | @@ -14579,9 +14705,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14579,9 +14705,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14579 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); | 14705 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); |
| 14580 | } | 14706 | } |
| 14581 | if (res_sent_val) |sent_val| { | 14707 | if (res_sent_val) |sent_val| { |
| 14582 | const elem_index = try mod.intRef(Type.usize, result_len); | 14708 | const elem_index = try pt.intRef(Type.usize, result_len); |
| 14583 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 14709 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 14584 | const init = Air.internedToRef((try mod.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); | 14710 | const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern()); |
| 14585 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); | 14711 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| 14586 | } | 14712 | } |
| 14587 | 14713 | ||
| ... | @@ -14592,7 +14718,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14592,7 +14718,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14592 | { | 14718 | { |
| 14593 | var elem_i: u32 = 0; | 14719 | var elem_i: u32 = 0; |
| 14594 | while (elem_i < lhs_len) : (elem_i += 1) { | 14720 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14595 | const index = try mod.intRef(Type.usize, elem_i); | 14721 | const index = try pt.intRef(Type.usize, elem_i); |
| 14596 | const operand_src = block.src(.{ .array_cat_lhs = .{ | 14722 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14597 | .array_cat_offset = inst_data.src_node, | 14723 | .array_cat_offset = inst_data.src_node, |
| 14598 | .elem_index = elem_i, | 14724 | .elem_index = elem_i, |
| ... | @@ -14602,7 +14728,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14602,7 +14728,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14602 | } | 14728 | } |
| 14603 | while (elem_i < result_len) : (elem_i += 1) { | 14729 | while (elem_i < result_len) : (elem_i += 1) { |
| 14604 | const rhs_elem_i = elem_i - lhs_len; | 14730 | const rhs_elem_i = elem_i - lhs_len; |
| 14605 | const index = try mod.intRef(Type.usize, rhs_elem_i); | 14731 | const index = try pt.intRef(Type.usize, rhs_elem_i); |
| 14606 | const operand_src = block.src(.{ .array_cat_rhs = .{ | 14732 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14607 | .array_cat_offset = inst_data.src_node, | 14733 | .array_cat_offset = inst_data.src_node, |
| 14608 | .elem_index = @intCast(rhs_elem_i), | 14734 | .elem_index = @intCast(rhs_elem_i), |
| ... | @@ -14616,7 +14742,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14616,7 +14742,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14616 | } | 14742 | } |
| 14617 | 14743 | ||
| 14618 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo { | 14744 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo { |
| 14619 | const mod = sema.mod; | 14745 | const pt = sema.pt; |
| 14746 | const mod = pt.zcu; | ||
| 14620 | const operand_ty = sema.typeOf(operand); | 14747 | const operand_ty = sema.typeOf(operand); |
| 14621 | switch (operand_ty.zigTypeTag(mod)) { | 14748 | switch (operand_ty.zigTypeTag(mod)) { |
| 14622 | .Array => return operand_ty.arrayInfo(mod), | 14749 | .Array => return operand_ty.arrayInfo(mod), |
| ... | @@ -14633,7 +14760,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -14633,7 +14760,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 14633 | .none => null, | 14760 | .none => null, |
| 14634 | else => Value.fromInterned(ptr_info.sentinel), | 14761 | else => Value.fromInterned(ptr_info.sentinel), |
| 14635 | }, | 14762 | }, |
| 14636 | .len = try val.sliceLen(mod), | 14763 | .len = try val.sliceLen(pt), |
| 14637 | }; | 14764 | }; |
| 14638 | }, | 14765 | }, |
| 14639 | .One => { | 14766 | .One => { |
| ... | @@ -14666,7 +14793,8 @@ fn analyzeTupleMul( | ... | @@ -14666,7 +14793,8 @@ fn analyzeTupleMul( |
| 14666 | operand: Air.Inst.Ref, | 14793 | operand: Air.Inst.Ref, |
| 14667 | factor: usize, | 14794 | factor: usize, |
| 14668 | ) CompileError!Air.Inst.Ref { | 14795 | ) CompileError!Air.Inst.Ref { |
| 14669 | const mod = sema.mod; | 14796 | const pt = sema.pt; |
| 14797 | const mod = pt.zcu; | ||
| 14670 | const operand_ty = sema.typeOf(operand); | 14798 | const operand_ty = sema.typeOf(operand); |
| 14671 | const src = block.nodeOffset(src_node); | 14799 | const src = block.nodeOffset(src_node); |
| 14672 | const len_src = block.src(.{ .node_offset_bin_rhs = src_node }); | 14800 | const len_src = block.src(.{ .node_offset_bin_rhs = src_node }); |
| ... | @@ -14702,14 +14830,14 @@ fn analyzeTupleMul( | ... | @@ -14702,14 +14830,14 @@ fn analyzeTupleMul( |
| 14702 | break :rs runtime_src; | 14830 | break :rs runtime_src; |
| 14703 | }; | 14831 | }; |
| 14704 | 14832 | ||
| 14705 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{ | 14833 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{ |
| 14706 | .types = types, | 14834 | .types = types, |
| 14707 | .values = values, | 14835 | .values = values, |
| 14708 | .names = &.{}, | 14836 | .names = &.{}, |
| 14709 | }); | 14837 | }); |
| 14710 | 14838 | ||
| 14711 | const runtime_src = opt_runtime_src orelse { | 14839 | const runtime_src = opt_runtime_src orelse { |
| 14712 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 14840 | const tuple_val = try pt.intern(.{ .aggregate = .{ |
| 14713 | .ty = tuple_ty, | 14841 | .ty = tuple_ty, |
| 14714 | .storage = .{ .elems = values }, | 14842 | .storage = .{ .elems = values }, |
| 14715 | } }); | 14843 | } }); |
| ... | @@ -14739,7 +14867,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14739,7 +14867,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14739 | const tracy = trace(@src()); | 14867 | const tracy = trace(@src()); |
| 14740 | defer tracy.end(); | 14868 | defer tracy.end(); |
| 14741 | 14869 | ||
| 14742 | const mod = sema.mod; | 14870 | const pt = sema.pt; |
| 14871 | const mod = pt.zcu; | ||
| 14743 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14872 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14744 | const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data; | 14873 | const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data; |
| 14745 | const uncoerced_lhs = try sema.resolveInst(extra.lhs); | 14874 | const uncoerced_lhs = try sema.resolveInst(extra.lhs); |
| ... | @@ -14762,12 +14891,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14762,12 +14891,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14762 | const lhs_len = uncoerced_lhs_ty.structFieldCount(mod); | 14891 | const lhs_len = uncoerced_lhs_ty.structFieldCount(mod); |
| 14763 | const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) { | 14892 | const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) { |
| 14764 | else => break :no_coerce, | 14893 | else => break :no_coerce, |
| 14765 | .Array => try mod.arrayType(.{ | 14894 | .Array => try pt.arrayType(.{ |
| 14766 | .child = res_ty.childType(mod).toIntern(), | 14895 | .child = res_ty.childType(mod).toIntern(), |
| 14767 | .len = lhs_len, | 14896 | .len = lhs_len, |
| 14768 | .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none, | 14897 | .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| 14769 | }), | 14898 | }), |
| 14770 | .Vector => try mod.vectorType(.{ | 14899 | .Vector => try pt.vectorType(.{ |
| 14771 | .child = res_ty.childType(mod).toIntern(), | 14900 | .child = res_ty.childType(mod).toIntern(), |
| 14772 | .len = lhs_len, | 14901 | .len = lhs_len, |
| 14773 | }), | 14902 | }), |
| ... | @@ -14796,7 +14925,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14796,7 +14925,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14796 | // Analyze the lhs first, to catch the case that someone tried to do exponentiation | 14925 | // Analyze the lhs first, to catch the case that someone tried to do exponentiation |
| 14797 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse { | 14926 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse { |
| 14798 | const msg = msg: { | 14927 | const msg = msg: { |
| 14799 | const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)}); | 14928 | const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)}); |
| 14800 | errdefer msg.destroy(sema.gpa); | 14929 | errdefer msg.destroy(sema.gpa); |
| 14801 | switch (lhs_ty.zigTypeTag(mod)) { | 14930 | switch (lhs_ty.zigTypeTag(mod)) { |
| 14802 | .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => { | 14931 | .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => { |
| ... | @@ -14818,7 +14947,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14818,7 +14947,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14818 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); | 14947 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |
| 14819 | const result_len = try sema.usizeCast(block, src, result_len_u64); | 14948 | const result_len = try sema.usizeCast(block, src, result_len_u64); |
| 14820 | 14949 | ||
| 14821 | const result_ty = try mod.arrayType(.{ | 14950 | const result_ty = try pt.arrayType(.{ |
| 14822 | .len = result_len, | 14951 | .len = result_len, |
| 14823 | .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none, | 14952 | .sentinel = if (lhs_info.sentinel) |s| s.toIntern() else .none, |
| 14824 | .child = lhs_info.elem_type.toIntern(), | 14953 | .child = lhs_info.elem_type.toIntern(), |
| ... | @@ -14839,8 +14968,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14839,8 +14968,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14839 | // Optimization for the common pattern of a single element repeated N times, such | 14968 | // Optimization for the common pattern of a single element repeated N times, such |
| 14840 | // as zero-filling a byte array. | 14969 | // as zero-filling a byte array. |
| 14841 | if (lhs_len == 1 and lhs_info.sentinel == null) { | 14970 | if (lhs_len == 1 and lhs_info.sentinel == null) { |
| 14842 | const elem_val = try lhs_sub_val.elemValue(mod, 0); | 14971 | const elem_val = try lhs_sub_val.elemValue(pt, 0); |
| 14843 | break :v try mod.intern(.{ .aggregate = .{ | 14972 | break :v try pt.intern(.{ .aggregate = .{ |
| 14844 | .ty = result_ty.toIntern(), | 14973 | .ty = result_ty.toIntern(), |
| 14845 | .storage = .{ .repeated_elem = elem_val.toIntern() }, | 14974 | .storage = .{ .repeated_elem = elem_val.toIntern() }, |
| 14846 | } }); | 14975 | } }); |
| ... | @@ -14851,12 +14980,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14851,12 +14980,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14851 | while (elem_i < result_len) { | 14980 | while (elem_i < result_len) { |
| 14852 | var lhs_i: usize = 0; | 14981 | var lhs_i: usize = 0; |
| 14853 | while (lhs_i < lhs_len) : (lhs_i += 1) { | 14982 | while (lhs_i < lhs_len) : (lhs_i += 1) { |
| 14854 | const elem_val = try lhs_sub_val.elemValue(mod, lhs_i); | 14983 | const elem_val = try lhs_sub_val.elemValue(pt, lhs_i); |
| 14855 | element_vals[elem_i] = elem_val.toIntern(); | 14984 | element_vals[elem_i] = elem_val.toIntern(); |
| 14856 | elem_i += 1; | 14985 | elem_i += 1; |
| 14857 | } | 14986 | } |
| 14858 | } | 14987 | } |
| 14859 | break :v try mod.intern(.{ .aggregate = .{ | 14988 | break :v try pt.intern(.{ .aggregate = .{ |
| 14860 | .ty = result_ty.toIntern(), | 14989 | .ty = result_ty.toIntern(), |
| 14861 | .storage = .{ .elems = element_vals }, | 14990 | .storage = .{ .elems = element_vals }, |
| 14862 | } }); | 14991 | } }); |
| ... | @@ -14870,17 +14999,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14870,17 +14999,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14870 | // to get the same elem values. | 14999 | // to get the same elem values. |
| 14871 | const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len); | 15000 | const lhs_vals = try sema.arena.alloc(Air.Inst.Ref, lhs_len); |
| 14872 | for (lhs_vals, 0..) |*lhs_val, idx| { | 15001 | for (lhs_vals, 0..) |*lhs_val, idx| { |
| 14873 | const idx_ref = try mod.intRef(Type.usize, idx); | 15002 | const idx_ref = try pt.intRef(Type.usize, idx); |
| 14874 | lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false); | 15003 | lhs_val.* = try sema.elemVal(block, lhs_src, lhs, idx_ref, src, false); |
| 14875 | } | 15004 | } |
| 14876 | 15005 | ||
| 14877 | if (ptr_addrspace) |ptr_as| { | 15006 | if (ptr_addrspace) |ptr_as| { |
| 14878 | const alloc_ty = try mod.ptrTypeSema(.{ | 15007 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 14879 | .child = result_ty.toIntern(), | 15008 | .child = result_ty.toIntern(), |
| 14880 | .flags = .{ .address_space = ptr_as }, | 15009 | .flags = .{ .address_space = ptr_as }, |
| 14881 | }); | 15010 | }); |
| 14882 | const alloc = try block.addTy(.alloc, alloc_ty); | 15011 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 14883 | const elem_ptr_ty = try mod.ptrTypeSema(.{ | 15012 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 14884 | .child = lhs_info.elem_type.toIntern(), | 15013 | .child = lhs_info.elem_type.toIntern(), |
| 14885 | .flags = .{ .address_space = ptr_as }, | 15014 | .flags = .{ .address_space = ptr_as }, |
| 14886 | }); | 15015 | }); |
| ... | @@ -14888,14 +15017,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14888,14 +15017,14 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14888 | var elem_i: usize = 0; | 15017 | var elem_i: usize = 0; |
| 14889 | while (elem_i < result_len) { | 15018 | while (elem_i < result_len) { |
| 14890 | for (lhs_vals) |lhs_val| { | 15019 | for (lhs_vals) |lhs_val| { |
| 14891 | const elem_index = try mod.intRef(Type.usize, elem_i); | 15020 | const elem_index = try pt.intRef(Type.usize, elem_i); |
| 14892 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 15021 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 14893 | try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store); | 15022 | try sema.storePtr2(block, src, elem_ptr, src, lhs_val, lhs_src, .store); |
| 14894 | elem_i += 1; | 15023 | elem_i += 1; |
| 14895 | } | 15024 | } |
| 14896 | } | 15025 | } |
| 14897 | if (lhs_info.sentinel) |sent_val| { | 15026 | if (lhs_info.sentinel) |sent_val| { |
| 14898 | const elem_index = try mod.intRef(Type.usize, result_len); | 15027 | const elem_index = try pt.intRef(Type.usize, result_len); |
| 14899 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); | 15028 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 14900 | const init = Air.internedToRef(sent_val.toIntern()); | 15029 | const init = Air.internedToRef(sent_val.toIntern()); |
| 14901 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); | 15030 | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| ... | @@ -14912,7 +15041,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14912,7 +15041,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14912 | } | 15041 | } |
| 14913 | 15042 | ||
| 14914 | fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15043 | fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14915 | const mod = sema.mod; | 15044 | const pt = sema.pt; |
| 15045 | const mod = pt.zcu; | ||
| 14916 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 15046 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14917 | const src = block.nodeOffset(inst_data.src_node); | 15047 | const src = block.nodeOffset(inst_data.src_node); |
| 14918 | const lhs_src = src; | 15048 | const lhs_src = src; |
| ... | @@ -14926,25 +15056,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14926,25 +15056,26 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14926 | .Int, .ComptimeInt, .Float, .ComptimeFloat => false, | 15056 | .Int, .ComptimeInt, .Float, .ComptimeFloat => false, |
| 14927 | else => true, | 15057 | else => true, |
| 14928 | }) { | 15058 | }) { |
| 14929 | return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}); | 15059 | return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}); |
| 14930 | } | 15060 | } |
| 14931 | 15061 | ||
| 14932 | if (rhs_scalar_ty.isAnyFloat()) { | 15062 | if (rhs_scalar_ty.isAnyFloat()) { |
| 14933 | // We handle float negation here to ensure negative zero is represented in the bits. | 15063 | // We handle float negation here to ensure negative zero is represented in the bits. |
| 14934 | if (try sema.resolveValue(rhs)) |rhs_val| { | 15064 | if (try sema.resolveValue(rhs)) |rhs_val| { |
| 14935 | if (rhs_val.isUndef(mod)) return mod.undefRef(rhs_ty); | 15065 | if (rhs_val.isUndef(mod)) return pt.undefRef(rhs_ty); |
| 14936 | return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, mod)).toIntern()); | 15066 | return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, pt)).toIntern()); |
| 14937 | } | 15067 | } |
| 14938 | try sema.requireRuntimeBlock(block, src, null); | 15068 | try sema.requireRuntimeBlock(block, src, null); |
| 14939 | return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs); | 15069 | return block.addUnOp(if (block.float_mode == .optimized) .neg_optimized else .neg, rhs); |
| 14940 | } | 15070 | } |
| 14941 | 15071 | ||
| 14942 | const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern()); | 15072 | const lhs = Air.internedToRef((try sema.splat(rhs_ty, try pt.intValue(rhs_scalar_ty, 0))).toIntern()); |
| 14943 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); | 15073 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); |
| 14944 | } | 15074 | } |
| 14945 | 15075 | ||
| 14946 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15076 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14947 | const mod = sema.mod; | 15077 | const pt = sema.pt; |
| 15078 | const mod = pt.zcu; | ||
| 14948 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 15079 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14949 | const src = block.nodeOffset(inst_data.src_node); | 15080 | const src = block.nodeOffset(inst_data.src_node); |
| 14950 | const lhs_src = src; | 15081 | const lhs_src = src; |
| ... | @@ -14956,10 +15087,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -14956,10 +15087,10 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 14956 | 15087 | ||
| 14957 | switch (rhs_scalar_ty.zigTypeTag(mod)) { | 15088 | switch (rhs_scalar_ty.zigTypeTag(mod)) { |
| 14958 | .Int, .ComptimeInt, .Float, .ComptimeFloat => {}, | 15089 | .Int, .ComptimeInt, .Float, .ComptimeFloat => {}, |
| 14959 | else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}), | 15090 | else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}), |
| 14960 | } | 15091 | } |
| 14961 | 15092 | ||
| 14962 | const lhs = Air.internedToRef((try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))).toIntern()); | 15093 | const lhs = Air.internedToRef((try sema.splat(rhs_ty, try pt.intValue(rhs_scalar_ty, 0))).toIntern()); |
| 14963 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); | 15094 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); |
| 14964 | } | 15095 | } |
| 14965 | 15096 | ||
| ... | @@ -14985,7 +15116,8 @@ fn zirArithmetic( | ... | @@ -14985,7 +15116,8 @@ fn zirArithmetic( |
| 14985 | } | 15116 | } |
| 14986 | 15117 | ||
| 14987 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15118 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14988 | const mod = sema.mod; | 15119 | const pt = sema.pt; |
| 15120 | const mod = pt.zcu; | ||
| 14989 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15121 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14990 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15122 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 14991 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15123 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15026,13 +15158,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15026,13 +15158,13 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15026 | // If lhs % rhs is 0, it doesn't matter. | 15158 | // If lhs % rhs is 0, it doesn't matter. |
| 15027 | const lhs_val = maybe_lhs_val orelse unreachable; | 15159 | const lhs_val = maybe_lhs_val orelse unreachable; |
| 15028 | const rhs_val = maybe_rhs_val orelse unreachable; | 15160 | const rhs_val = maybe_rhs_val orelse unreachable; |
| 15029 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable; | 15161 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt) catch unreachable; |
| 15030 | if (!rem.compareAllWithZero(.eq, mod)) { | 15162 | if (!rem.compareAllWithZero(.eq, pt)) { |
| 15031 | return sema.fail( | 15163 | return sema.fail( |
| 15032 | block, | 15164 | block, |
| 15033 | src, | 15165 | src, |
| 15034 | "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", | 15166 | "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", |
| 15035 | .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod, sema) }, | 15167 | .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValue(pt, sema) }, |
| 15036 | ); | 15168 | ); |
| 15037 | } | 15169 | } |
| 15038 | } | 15170 | } |
| ... | @@ -15068,10 +15200,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15068,10 +15200,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15068 | .Int, .ComptimeInt, .ComptimeFloat => { | 15200 | .Int, .ComptimeInt, .ComptimeFloat => { |
| 15069 | if (maybe_lhs_val) |lhs_val| { | 15201 | if (maybe_lhs_val) |lhs_val| { |
| 15070 | if (!lhs_val.isUndef(mod)) { | 15202 | if (!lhs_val.isUndef(mod)) { |
| 15071 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 15203 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15072 | const scalar_zero = switch (scalar_tag) { | 15204 | const scalar_zero = switch (scalar_tag) { |
| 15073 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15205 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15074 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15206 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15075 | else => unreachable, | 15207 | else => unreachable, |
| 15076 | }; | 15208 | }; |
| 15077 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 15209 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | @@ -15083,7 +15215,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15083,7 +15215,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15083 | if (rhs_val.isUndef(mod)) { | 15215 | if (rhs_val.isUndef(mod)) { |
| 15084 | return sema.failWithUseOfUndef(block, rhs_src); | 15216 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15085 | } | 15217 | } |
| 15086 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15218 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15087 | return sema.failWithDivideByZero(block, rhs_src); | 15219 | return sema.failWithDivideByZero(block, rhs_src); |
| 15088 | } | 15220 | } |
| 15089 | // TODO: if the RHS is one, return the LHS directly | 15221 | // TODO: if the RHS is one, return the LHS directly |
| ... | @@ -15097,25 +15229,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15097,25 +15229,25 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15097 | if (lhs_val.isUndef(mod)) { | 15229 | if (lhs_val.isUndef(mod)) { |
| 15098 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 15230 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 15099 | if (maybe_rhs_val) |rhs_val| { | 15231 | if (maybe_rhs_val) |rhs_val| { |
| 15100 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { | 15232 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15101 | return mod.undefRef(resolved_type); | 15233 | return pt.undefRef(resolved_type); |
| 15102 | } | 15234 | } |
| 15103 | } | 15235 | } |
| 15104 | return sema.failWithUseOfUndef(block, rhs_src); | 15236 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15105 | } | 15237 | } |
| 15106 | return mod.undefRef(resolved_type); | 15238 | return pt.undefRef(resolved_type); |
| 15107 | } | 15239 | } |
| 15108 | 15240 | ||
| 15109 | if (maybe_rhs_val) |rhs_val| { | 15241 | if (maybe_rhs_val) |rhs_val| { |
| 15110 | if (is_int) { | 15242 | if (is_int) { |
| 15111 | var overflow_idx: ?usize = null; | 15243 | var overflow_idx: ?usize = null; |
| 15112 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod); | 15244 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt); |
| 15113 | if (overflow_idx) |vec_idx| { | 15245 | if (overflow_idx) |vec_idx| { |
| 15114 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); | 15246 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); |
| 15115 | } | 15247 | } |
| 15116 | return Air.internedToRef(res.toIntern()); | 15248 | return Air.internedToRef(res.toIntern()); |
| 15117 | } else { | 15249 | } else { |
| 15118 | return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15250 | return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15119 | } | 15251 | } |
| 15120 | } else { | 15252 | } else { |
| 15121 | break :rs rhs_src; | 15253 | break :rs rhs_src; |
| ... | @@ -15138,7 +15270,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15138,7 +15270,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15138 | block, | 15270 | block, |
| 15139 | src, | 15271 | src, |
| 15140 | "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact", | 15272 | "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact", |
| 15141 | .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod) }, | 15273 | .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt) }, |
| 15142 | ); | 15274 | ); |
| 15143 | } | 15275 | } |
| 15144 | break :blk Air.Inst.Tag.div_trunc; | 15276 | break :blk Air.Inst.Tag.div_trunc; |
| ... | @@ -15150,7 +15282,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15150,7 +15282,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15150 | } | 15282 | } |
| 15151 | 15283 | ||
| 15152 | fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15284 | fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15153 | const mod = sema.mod; | 15285 | const pt = sema.pt; |
| 15286 | const mod = pt.zcu; | ||
| 15154 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15287 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15155 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15288 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15156 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15289 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15204,10 +15337,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15204,10 +15337,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15204 | if (lhs_val.isUndef(mod)) { | 15337 | if (lhs_val.isUndef(mod)) { |
| 15205 | return sema.failWithUseOfUndef(block, rhs_src); | 15338 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15206 | } else { | 15339 | } else { |
| 15207 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 15340 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15208 | const scalar_zero = switch (scalar_tag) { | 15341 | const scalar_zero = switch (scalar_tag) { |
| 15209 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15342 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15210 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15343 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15211 | else => unreachable, | 15344 | else => unreachable, |
| 15212 | }; | 15345 | }; |
| 15213 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 15346 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | @@ -15219,7 +15352,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15219,7 +15352,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15219 | if (rhs_val.isUndef(mod)) { | 15352 | if (rhs_val.isUndef(mod)) { |
| 15220 | return sema.failWithUseOfUndef(block, rhs_src); | 15353 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15221 | } | 15354 | } |
| 15222 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15355 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15223 | return sema.failWithDivideByZero(block, rhs_src); | 15356 | return sema.failWithDivideByZero(block, rhs_src); |
| 15224 | } | 15357 | } |
| 15225 | // TODO: if the RHS is one, return the LHS directly | 15358 | // TODO: if the RHS is one, return the LHS directly |
| ... | @@ -15227,22 +15360,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15227,22 +15360,22 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15227 | if (maybe_lhs_val) |lhs_val| { | 15360 | if (maybe_lhs_val) |lhs_val| { |
| 15228 | if (maybe_rhs_val) |rhs_val| { | 15361 | if (maybe_rhs_val) |rhs_val| { |
| 15229 | if (is_int) { | 15362 | if (is_int) { |
| 15230 | const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod); | 15363 | const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt); |
| 15231 | if (!(modulus_val.compareAllWithZero(.eq, mod))) { | 15364 | if (!(modulus_val.compareAllWithZero(.eq, pt))) { |
| 15232 | return sema.fail(block, src, "exact division produced remainder", .{}); | 15365 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 15233 | } | 15366 | } |
| 15234 | var overflow_idx: ?usize = null; | 15367 | var overflow_idx: ?usize = null; |
| 15235 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod); | 15368 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt); |
| 15236 | if (overflow_idx) |vec_idx| { | 15369 | if (overflow_idx) |vec_idx| { |
| 15237 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); | 15370 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); |
| 15238 | } | 15371 | } |
| 15239 | return Air.internedToRef(res.toIntern()); | 15372 | return Air.internedToRef(res.toIntern()); |
| 15240 | } else { | 15373 | } else { |
| 15241 | const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod); | 15374 | const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt); |
| 15242 | if (!(modulus_val.compareAllWithZero(.eq, mod))) { | 15375 | if (!(modulus_val.compareAllWithZero(.eq, pt))) { |
| 15243 | return sema.fail(block, src, "exact division produced remainder", .{}); | 15376 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 15244 | } | 15377 | } |
| 15245 | return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15378 | return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15246 | } | 15379 | } |
| 15247 | } else break :rs rhs_src; | 15380 | } else break :rs rhs_src; |
| 15248 | } else break :rs lhs_src; | 15381 | } else break :rs lhs_src; |
| ... | @@ -15286,8 +15419,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15286,8 +15419,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15286 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); | 15419 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 15287 | 15420 | ||
| 15288 | const scalar_zero = switch (scalar_tag) { | 15421 | const scalar_zero = switch (scalar_tag) { |
| 15289 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15422 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15290 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15423 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15291 | else => unreachable, | 15424 | else => unreachable, |
| 15292 | }; | 15425 | }; |
| 15293 | if (resolved_type.zigTypeTag(mod) == .Vector) { | 15426 | if (resolved_type.zigTypeTag(mod) == .Vector) { |
| ... | @@ -15315,7 +15448,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15315,7 +15448,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15315 | } | 15448 | } |
| 15316 | 15449 | ||
| 15317 | fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15450 | fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15318 | const mod = sema.mod; | 15451 | const pt = sema.pt; |
| 15452 | const mod = pt.zcu; | ||
| 15319 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15453 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15320 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15454 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15321 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15455 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15371,10 +15505,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15371,10 +15505,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15371 | // If the lhs is undefined, result is undefined. | 15505 | // If the lhs is undefined, result is undefined. |
| 15372 | if (maybe_lhs_val) |lhs_val| { | 15506 | if (maybe_lhs_val) |lhs_val| { |
| 15373 | if (!lhs_val.isUndef(mod)) { | 15507 | if (!lhs_val.isUndef(mod)) { |
| 15374 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 15508 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15375 | const scalar_zero = switch (scalar_tag) { | 15509 | const scalar_zero = switch (scalar_tag) { |
| 15376 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15510 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15377 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15511 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15378 | else => unreachable, | 15512 | else => unreachable, |
| 15379 | }; | 15513 | }; |
| 15380 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 15514 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | @@ -15386,7 +15520,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15386,7 +15520,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15386 | if (rhs_val.isUndef(mod)) { | 15520 | if (rhs_val.isUndef(mod)) { |
| 15387 | return sema.failWithUseOfUndef(block, rhs_src); | 15521 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15388 | } | 15522 | } |
| 15389 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15523 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15390 | return sema.failWithDivideByZero(block, rhs_src); | 15524 | return sema.failWithDivideByZero(block, rhs_src); |
| 15391 | } | 15525 | } |
| 15392 | // TODO: if the RHS is one, return the LHS directly | 15526 | // TODO: if the RHS is one, return the LHS directly |
| ... | @@ -15395,20 +15529,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15395,20 +15529,20 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15395 | if (lhs_val.isUndef(mod)) { | 15529 | if (lhs_val.isUndef(mod)) { |
| 15396 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 15530 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 15397 | if (maybe_rhs_val) |rhs_val| { | 15531 | if (maybe_rhs_val) |rhs_val| { |
| 15398 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { | 15532 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15399 | return mod.undefRef(resolved_type); | 15533 | return pt.undefRef(resolved_type); |
| 15400 | } | 15534 | } |
| 15401 | } | 15535 | } |
| 15402 | return sema.failWithUseOfUndef(block, rhs_src); | 15536 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15403 | } | 15537 | } |
| 15404 | return mod.undefRef(resolved_type); | 15538 | return pt.undefRef(resolved_type); |
| 15405 | } | 15539 | } |
| 15406 | 15540 | ||
| 15407 | if (maybe_rhs_val) |rhs_val| { | 15541 | if (maybe_rhs_val) |rhs_val| { |
| 15408 | if (is_int) { | 15542 | if (is_int) { |
| 15409 | return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15543 | return Air.internedToRef((try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15410 | } else { | 15544 | } else { |
| 15411 | return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15545 | return Air.internedToRef((try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15412 | } | 15546 | } |
| 15413 | } else break :rs rhs_src; | 15547 | } else break :rs rhs_src; |
| 15414 | } else break :rs lhs_src; | 15548 | } else break :rs lhs_src; |
| ... | @@ -15425,7 +15559,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15425,7 +15559,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15425 | } | 15559 | } |
| 15426 | 15560 | ||
| 15427 | fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15561 | fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15428 | const mod = sema.mod; | 15562 | const pt = sema.pt; |
| 15563 | const mod = pt.zcu; | ||
| 15429 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15564 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15430 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15565 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15431 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15566 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15481,10 +15616,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15481,10 +15616,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15481 | // If the lhs is undefined, result is undefined. | 15616 | // If the lhs is undefined, result is undefined. |
| 15482 | if (maybe_lhs_val) |lhs_val| { | 15617 | if (maybe_lhs_val) |lhs_val| { |
| 15483 | if (!lhs_val.isUndef(mod)) { | 15618 | if (!lhs_val.isUndef(mod)) { |
| 15484 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 15619 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15485 | const scalar_zero = switch (scalar_tag) { | 15620 | const scalar_zero = switch (scalar_tag) { |
| 15486 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15621 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15487 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15622 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15488 | else => unreachable, | 15623 | else => unreachable, |
| 15489 | }; | 15624 | }; |
| 15490 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 15625 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | @@ -15496,7 +15631,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15496,7 +15631,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15496 | if (rhs_val.isUndef(mod)) { | 15631 | if (rhs_val.isUndef(mod)) { |
| 15497 | return sema.failWithUseOfUndef(block, rhs_src); | 15632 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15498 | } | 15633 | } |
| 15499 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15634 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15500 | return sema.failWithDivideByZero(block, rhs_src); | 15635 | return sema.failWithDivideByZero(block, rhs_src); |
| 15501 | } | 15636 | } |
| 15502 | } | 15637 | } |
| ... | @@ -15504,25 +15639,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15504,25 +15639,25 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15504 | if (lhs_val.isUndef(mod)) { | 15639 | if (lhs_val.isUndef(mod)) { |
| 15505 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 15640 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 15506 | if (maybe_rhs_val) |rhs_val| { | 15641 | if (maybe_rhs_val) |rhs_val| { |
| 15507 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { | 15642 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15508 | return mod.undefRef(resolved_type); | 15643 | return pt.undefRef(resolved_type); |
| 15509 | } | 15644 | } |
| 15510 | } | 15645 | } |
| 15511 | return sema.failWithUseOfUndef(block, rhs_src); | 15646 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15512 | } | 15647 | } |
| 15513 | return mod.undefRef(resolved_type); | 15648 | return pt.undefRef(resolved_type); |
| 15514 | } | 15649 | } |
| 15515 | 15650 | ||
| 15516 | if (maybe_rhs_val) |rhs_val| { | 15651 | if (maybe_rhs_val) |rhs_val| { |
| 15517 | if (is_int) { | 15652 | if (is_int) { |
| 15518 | var overflow_idx: ?usize = null; | 15653 | var overflow_idx: ?usize = null; |
| 15519 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, mod); | 15654 | const res = try lhs_val.intDiv(rhs_val, resolved_type, &overflow_idx, sema.arena, pt); |
| 15520 | if (overflow_idx) |vec_idx| { | 15655 | if (overflow_idx) |vec_idx| { |
| 15521 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); | 15656 | return sema.failWithIntegerOverflow(block, src, resolved_type, res, vec_idx); |
| 15522 | } | 15657 | } |
| 15523 | return Air.internedToRef(res.toIntern()); | 15658 | return Air.internedToRef(res.toIntern()); |
| 15524 | } else { | 15659 | } else { |
| 15525 | return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15660 | return Air.internedToRef((try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15526 | } | 15661 | } |
| 15527 | } else break :rs rhs_src; | 15662 | } else break :rs rhs_src; |
| 15528 | } else break :rs lhs_src; | 15663 | } else break :rs lhs_src; |
| ... | @@ -15550,7 +15685,8 @@ fn addDivIntOverflowSafety( | ... | @@ -15550,7 +15685,8 @@ fn addDivIntOverflowSafety( |
| 15550 | casted_rhs: Air.Inst.Ref, | 15685 | casted_rhs: Air.Inst.Ref, |
| 15551 | is_int: bool, | 15686 | is_int: bool, |
| 15552 | ) CompileError!void { | 15687 | ) CompileError!void { |
| 15553 | const mod = sema.mod; | 15688 | const pt = sema.pt; |
| 15689 | const mod = pt.zcu; | ||
| 15554 | if (!is_int) return; | 15690 | if (!is_int) return; |
| 15555 | 15691 | ||
| 15556 | // If the LHS is unsigned, it cannot cause overflow. | 15692 | // If the LHS is unsigned, it cannot cause overflow. |
| ... | @@ -15561,19 +15697,19 @@ fn addDivIntOverflowSafety( | ... | @@ -15561,19 +15697,19 @@ fn addDivIntOverflowSafety( |
| 15561 | return; | 15697 | return; |
| 15562 | } | 15698 | } |
| 15563 | 15699 | ||
| 15564 | const min_int = try resolved_type.minInt(mod, resolved_type); | 15700 | const min_int = try resolved_type.minInt(pt, resolved_type); |
| 15565 | const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1); | 15701 | const neg_one_scalar = try pt.intValue(lhs_scalar_ty, -1); |
| 15566 | const neg_one = try sema.splat(resolved_type, neg_one_scalar); | 15702 | const neg_one = try sema.splat(resolved_type, neg_one_scalar); |
| 15567 | 15703 | ||
| 15568 | // If the LHS is comptime-known to be not equal to the min int, | 15704 | // If the LHS is comptime-known to be not equal to the min int, |
| 15569 | // no overflow is possible. | 15705 | // no overflow is possible. |
| 15570 | if (maybe_lhs_val) |lhs_val| { | 15706 | if (maybe_lhs_val) |lhs_val| { |
| 15571 | if (try lhs_val.compareAll(.neq, min_int, resolved_type, mod)) return; | 15707 | if (try lhs_val.compareAll(.neq, min_int, resolved_type, pt)) return; |
| 15572 | } | 15708 | } |
| 15573 | 15709 | ||
| 15574 | // If the RHS is comptime-known to not be equal to -1, no overflow is possible. | 15710 | // If the RHS is comptime-known to not be equal to -1, no overflow is possible. |
| 15575 | if (maybe_rhs_val) |rhs_val| { | 15711 | if (maybe_rhs_val) |rhs_val| { |
| 15576 | if (try rhs_val.compareAll(.neq, neg_one, resolved_type, mod)) return; | 15712 | if (try rhs_val.compareAll(.neq, neg_one, resolved_type, pt)) return; |
| 15577 | } | 15713 | } |
| 15578 | 15714 | ||
| 15579 | var ok: Air.Inst.Ref = .none; | 15715 | var ok: Air.Inst.Ref = .none; |
| ... | @@ -15634,11 +15770,12 @@ fn addDivByZeroSafety( | ... | @@ -15634,11 +15770,12 @@ fn addDivByZeroSafety( |
| 15634 | // emitted above. | 15770 | // emitted above. |
| 15635 | if (maybe_rhs_val != null) return; | 15771 | if (maybe_rhs_val != null) return; |
| 15636 | 15772 | ||
| 15637 | const mod = sema.mod; | 15773 | const pt = sema.pt; |
| 15774 | const mod = pt.zcu; | ||
| 15638 | const scalar_zero = if (is_int) | 15775 | const scalar_zero = if (is_int) |
| 15639 | try mod.intValue(resolved_type.scalarType(mod), 0) | 15776 | try pt.intValue(resolved_type.scalarType(mod), 0) |
| 15640 | else | 15777 | else |
| 15641 | try mod.floatValue(resolved_type.scalarType(mod), 0.0); | 15778 | try pt.floatValue(resolved_type.scalarType(mod), 0.0); |
| 15642 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { | 15779 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { |
| 15643 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 15780 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 15644 | const zero = Air.internedToRef(zero_val.toIntern()); | 15781 | const zero = Air.internedToRef(zero_val.toIntern()); |
| ... | @@ -15666,7 +15803,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst | ... | @@ -15666,7 +15803,8 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst |
| 15666 | } | 15803 | } |
| 15667 | 15804 | ||
| 15668 | fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15805 | fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15669 | const mod = sema.mod; | 15806 | const pt = sema.pt; |
| 15807 | const mod = pt.zcu; | ||
| 15670 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15808 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15671 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15809 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15672 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15810 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15721,16 +15859,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -15721,16 +15859,16 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15721 | if (lhs_val.isUndef(mod)) { | 15859 | if (lhs_val.isUndef(mod)) { |
| 15722 | return sema.failWithUseOfUndef(block, lhs_src); | 15860 | return sema.failWithUseOfUndef(block, lhs_src); |
| 15723 | } | 15861 | } |
| 15724 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 15862 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15725 | const scalar_zero = switch (scalar_tag) { | 15863 | const scalar_zero = switch (scalar_tag) { |
| 15726 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), | 15864 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), |
| 15727 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 15865 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), |
| 15728 | else => unreachable, | 15866 | else => unreachable, |
| 15729 | }; | 15867 | }; |
| 15730 | const zero_val = if (is_vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 15868 | const zero_val = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 15731 | .ty = resolved_type.toIntern(), | 15869 | .ty = resolved_type.toIntern(), |
| 15732 | .storage = .{ .repeated_elem = scalar_zero.toIntern() }, | 15870 | .storage = .{ .repeated_elem = scalar_zero.toIntern() }, |
| 15733 | } }))) else scalar_zero; | 15871 | } })) else scalar_zero; |
| 15734 | return Air.internedToRef(zero_val.toIntern()); | 15872 | return Air.internedToRef(zero_val.toIntern()); |
| 15735 | } | 15873 | } |
| 15736 | } else if (lhs_scalar_ty.isSignedInt(mod)) { | 15874 | } else if (lhs_scalar_ty.isSignedInt(mod)) { |
| ... | @@ -15740,18 +15878,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -15740,18 +15878,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15740 | if (rhs_val.isUndef(mod)) { | 15878 | if (rhs_val.isUndef(mod)) { |
| 15741 | return sema.failWithUseOfUndef(block, rhs_src); | 15879 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15742 | } | 15880 | } |
| 15743 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15881 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15744 | return sema.failWithDivideByZero(block, rhs_src); | 15882 | return sema.failWithDivideByZero(block, rhs_src); |
| 15745 | } | 15883 | } |
| 15746 | if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) { | 15884 | if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) { |
| 15747 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); | 15885 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 15748 | } | 15886 | } |
| 15749 | if (maybe_lhs_val) |lhs_val| { | 15887 | if (maybe_lhs_val) |lhs_val| { |
| 15750 | const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val); | 15888 | const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val); |
| 15751 | // If this answer could possibly be different by doing `intMod`, | 15889 | // If this answer could possibly be different by doing `intMod`, |
| 15752 | // we must emit a compile error. Otherwise, it's OK. | 15890 | // we must emit a compile error. Otherwise, it's OK. |
| 15753 | if (!(try lhs_val.compareAllWithZeroSema(.gte, mod)) and | 15891 | if (!(try lhs_val.compareAllWithZeroSema(.gte, pt)) and |
| 15754 | !(try rem_result.compareAllWithZeroSema(.eq, mod))) | 15892 | !(try rem_result.compareAllWithZeroSema(.eq, pt))) |
| 15755 | { | 15893 | { |
| 15756 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 15894 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 15757 | } | 15895 | } |
| ... | @@ -15769,17 +15907,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -15769,17 +15907,17 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15769 | if (rhs_val.isUndef(mod)) { | 15907 | if (rhs_val.isUndef(mod)) { |
| 15770 | return sema.failWithUseOfUndef(block, rhs_src); | 15908 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15771 | } | 15909 | } |
| 15772 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 15910 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15773 | return sema.failWithDivideByZero(block, rhs_src); | 15911 | return sema.failWithDivideByZero(block, rhs_src); |
| 15774 | } | 15912 | } |
| 15775 | if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) { | 15913 | if (!(try rhs_val.compareAllWithZeroSema(.gte, pt))) { |
| 15776 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); | 15914 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 15777 | } | 15915 | } |
| 15778 | if (maybe_lhs_val) |lhs_val| { | 15916 | if (maybe_lhs_val) |lhs_val| { |
| 15779 | if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, mod))) { | 15917 | if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, pt))) { |
| 15780 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 15918 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 15781 | } | 15919 | } |
| 15782 | return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15920 | return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15783 | } else { | 15921 | } else { |
| 15784 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 15922 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 15785 | } | 15923 | } |
| ... | @@ -15804,31 +15942,32 @@ fn intRem( | ... | @@ -15804,31 +15942,32 @@ fn intRem( |
| 15804 | lhs: Value, | 15942 | lhs: Value, |
| 15805 | rhs: Value, | 15943 | rhs: Value, |
| 15806 | ) CompileError!Value { | 15944 | ) CompileError!Value { |
| 15807 | const mod = sema.mod; | 15945 | const pt = sema.pt; |
| 15946 | const mod = pt.zcu; | ||
| 15808 | if (ty.zigTypeTag(mod) == .Vector) { | 15947 | if (ty.zigTypeTag(mod) == .Vector) { |
| 15809 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 15948 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 15810 | const scalar_ty = ty.scalarType(mod); | 15949 | const scalar_ty = ty.scalarType(mod); |
| 15811 | for (result_data, 0..) |*scalar, i| { | 15950 | for (result_data, 0..) |*scalar, i| { |
| 15812 | const lhs_elem = try lhs.elemValue(mod, i); | 15951 | const lhs_elem = try lhs.elemValue(pt, i); |
| 15813 | const rhs_elem = try rhs.elemValue(mod, i); | 15952 | const rhs_elem = try rhs.elemValue(pt, i); |
| 15814 | scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern(); | 15953 | scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern(); |
| 15815 | } | 15954 | } |
| 15816 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 15955 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 15817 | .ty = ty.toIntern(), | 15956 | .ty = ty.toIntern(), |
| 15818 | .storage = .{ .elems = result_data }, | 15957 | .storage = .{ .elems = result_data }, |
| 15819 | } }))); | 15958 | } })); |
| 15820 | } | 15959 | } |
| 15821 | return sema.intRemScalar(lhs, rhs, ty); | 15960 | return sema.intRemScalar(lhs, rhs, ty); |
| 15822 | } | 15961 | } |
| 15823 | 15962 | ||
| 15824 | fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value { | 15963 | fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value { |
| 15825 | const mod = sema.mod; | 15964 | const pt = sema.pt; |
| 15826 | // TODO is this a performance issue? maybe we should try the operation without | 15965 | // TODO is this a performance issue? maybe we should try the operation without |
| 15827 | // resorting to BigInt first. | 15966 | // resorting to BigInt first. |
| 15828 | var lhs_space: Value.BigIntSpace = undefined; | 15967 | var lhs_space: Value.BigIntSpace = undefined; |
| 15829 | var rhs_space: Value.BigIntSpace = undefined; | 15968 | var rhs_space: Value.BigIntSpace = undefined; |
| 15830 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema); | 15969 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); |
| 15831 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema); | 15970 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); |
| 15832 | const limbs_q = try sema.arena.alloc( | 15971 | const limbs_q = try sema.arena.alloc( |
| 15833 | math.big.Limb, | 15972 | math.big.Limb, |
| 15834 | lhs_bigint.limbs.len, | 15973 | lhs_bigint.limbs.len, |
| ... | @@ -15846,11 +15985,12 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr | ... | @@ -15846,11 +15985,12 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr |
| 15846 | var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; | 15985 | var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; |
| 15847 | var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; | 15986 | var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; |
| 15848 | result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); | 15987 | result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); |
| 15849 | return mod.intValue_big(scalar_ty, result_r.toConst()); | 15988 | return pt.intValue_big(scalar_ty, result_r.toConst()); |
| 15850 | } | 15989 | } |
| 15851 | 15990 | ||
| 15852 | fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15991 | fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15853 | const mod = sema.mod; | 15992 | const pt = sema.pt; |
| 15993 | const mod = pt.zcu; | ||
| 15854 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15994 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15855 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15995 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15856 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15996 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15904,11 +16044,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15904,11 +16044,11 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15904 | if (rhs_val.isUndef(mod)) { | 16044 | if (rhs_val.isUndef(mod)) { |
| 15905 | return sema.failWithUseOfUndef(block, rhs_src); | 16045 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15906 | } | 16046 | } |
| 15907 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 16047 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15908 | return sema.failWithDivideByZero(block, rhs_src); | 16048 | return sema.failWithDivideByZero(block, rhs_src); |
| 15909 | } | 16049 | } |
| 15910 | if (maybe_lhs_val) |lhs_val| { | 16050 | if (maybe_lhs_val) |lhs_val| { |
| 15911 | return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16051 | return Air.internedToRef((try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15912 | } | 16052 | } |
| 15913 | break :rs lhs_src; | 16053 | break :rs lhs_src; |
| 15914 | } else { | 16054 | } else { |
| ... | @@ -15920,16 +16060,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15920,16 +16060,16 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15920 | if (rhs_val.isUndef(mod)) { | 16060 | if (rhs_val.isUndef(mod)) { |
| 15921 | return sema.failWithUseOfUndef(block, rhs_src); | 16061 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15922 | } | 16062 | } |
| 15923 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 16063 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 15924 | return sema.failWithDivideByZero(block, rhs_src); | 16064 | return sema.failWithDivideByZero(block, rhs_src); |
| 15925 | } | 16065 | } |
| 15926 | } | 16066 | } |
| 15927 | if (maybe_lhs_val) |lhs_val| { | 16067 | if (maybe_lhs_val) |lhs_val| { |
| 15928 | if (lhs_val.isUndef(mod)) { | 16068 | if (lhs_val.isUndef(mod)) { |
| 15929 | return mod.undefRef(resolved_type); | 16069 | return pt.undefRef(resolved_type); |
| 15930 | } | 16070 | } |
| 15931 | if (maybe_rhs_val) |rhs_val| { | 16071 | if (maybe_rhs_val) |rhs_val| { |
| 15932 | return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16072 | return Air.internedToRef((try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 15933 | } else break :rs rhs_src; | 16073 | } else break :rs rhs_src; |
| 15934 | } else break :rs lhs_src; | 16074 | } else break :rs lhs_src; |
| 15935 | }; | 16075 | }; |
| ... | @@ -15945,7 +16085,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15945,7 +16085,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15945 | } | 16085 | } |
| 15946 | 16086 | ||
| 15947 | fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 16087 | fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15948 | const mod = sema.mod; | 16088 | const pt = sema.pt; |
| 16089 | const mod = pt.zcu; | ||
| 15949 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 16090 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15950 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 16091 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15951 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 16092 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | @@ -15999,7 +16140,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15999,7 +16140,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15999 | if (rhs_val.isUndef(mod)) { | 16140 | if (rhs_val.isUndef(mod)) { |
| 16000 | return sema.failWithUseOfUndef(block, rhs_src); | 16141 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16001 | } | 16142 | } |
| 16002 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 16143 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 16003 | return sema.failWithDivideByZero(block, rhs_src); | 16144 | return sema.failWithDivideByZero(block, rhs_src); |
| 16004 | } | 16145 | } |
| 16005 | if (maybe_lhs_val) |lhs_val| { | 16146 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -16015,16 +16156,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -16015,16 +16156,16 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16015 | if (rhs_val.isUndef(mod)) { | 16156 | if (rhs_val.isUndef(mod)) { |
| 16016 | return sema.failWithUseOfUndef(block, rhs_src); | 16157 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16017 | } | 16158 | } |
| 16018 | if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) { | 16159 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| 16019 | return sema.failWithDivideByZero(block, rhs_src); | 16160 | return sema.failWithDivideByZero(block, rhs_src); |
| 16020 | } | 16161 | } |
| 16021 | } | 16162 | } |
| 16022 | if (maybe_lhs_val) |lhs_val| { | 16163 | if (maybe_lhs_val) |lhs_val| { |
| 16023 | if (lhs_val.isUndef(mod)) { | 16164 | if (lhs_val.isUndef(mod)) { |
| 16024 | return mod.undefRef(resolved_type); | 16165 | return pt.undefRef(resolved_type); |
| 16025 | } | 16166 | } |
| 16026 | if (maybe_rhs_val) |rhs_val| { | 16167 | if (maybe_rhs_val) |rhs_val| { |
| 16027 | return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16168 | return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 16028 | } else break :rs rhs_src; | 16169 | } else break :rs rhs_src; |
| 16029 | } else break :rs lhs_src; | 16170 | } else break :rs lhs_src; |
| 16030 | }; | 16171 | }; |
| ... | @@ -16059,7 +16200,8 @@ fn zirOverflowArithmetic( | ... | @@ -16059,7 +16200,8 @@ fn zirOverflowArithmetic( |
| 16059 | 16200 | ||
| 16060 | const lhs_ty = sema.typeOf(uncasted_lhs); | 16201 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 16061 | const rhs_ty = sema.typeOf(uncasted_rhs); | 16202 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 16062 | const mod = sema.mod; | 16203 | const pt = sema.pt; |
| 16204 | const mod = pt.zcu; | ||
| 16063 | const ip = &mod.intern_pool; | 16205 | const ip = &mod.intern_pool; |
| 16064 | 16206 | ||
| 16065 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); | 16207 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| ... | @@ -16081,7 +16223,7 @@ fn zirOverflowArithmetic( | ... | @@ -16081,7 +16223,7 @@ fn zirOverflowArithmetic( |
| 16081 | const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src); | 16223 | const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src); |
| 16082 | 16224 | ||
| 16083 | if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) { | 16225 | if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) { |
| 16084 | return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)}); | 16226 | return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(pt)}); |
| 16085 | } | 16227 | } |
| 16086 | 16228 | ||
| 16087 | const maybe_lhs_val = try sema.resolveValue(lhs); | 16229 | const maybe_lhs_val = try sema.resolveValue(lhs); |
| ... | @@ -16095,19 +16237,19 @@ fn zirOverflowArithmetic( | ... | @@ -16095,19 +16237,19 @@ fn zirOverflowArithmetic( |
| 16095 | wrapped: Value = Value.@"unreachable", | 16237 | wrapped: Value = Value.@"unreachable", |
| 16096 | overflow_bit: Value, | 16238 | overflow_bit: Value, |
| 16097 | } = result: { | 16239 | } = result: { |
| 16098 | const zero_bit = try mod.intValue(Type.u1, 0); | 16240 | const zero_bit = try pt.intValue(Type.u1, 0); |
| 16099 | switch (zir_tag) { | 16241 | switch (zir_tag) { |
| 16100 | .add_with_overflow => { | 16242 | .add_with_overflow => { |
| 16101 | // If either of the arguments is zero, `false` is returned and the other is stored | 16243 | // If either of the arguments is zero, `false` is returned and the other is stored |
| 16102 | // to the result, even if it is undefined.. | 16244 | // to the result, even if it is undefined.. |
| 16103 | // Otherwise, if either of the argument is undefined, undefined is returned. | 16245 | // Otherwise, if either of the argument is undefined, undefined is returned. |
| 16104 | if (maybe_lhs_val) |lhs_val| { | 16246 | if (maybe_lhs_val) |lhs_val| { |
| 16105 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) { | 16247 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16106 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16248 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; |
| 16107 | } | 16249 | } |
| 16108 | } | 16250 | } |
| 16109 | if (maybe_rhs_val) |rhs_val| { | 16251 | if (maybe_rhs_val) |rhs_val| { |
| 16110 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) { | 16252 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16111 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16253 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16112 | } | 16254 | } |
| 16113 | } | 16255 | } |
| ... | @@ -16128,7 +16270,7 @@ fn zirOverflowArithmetic( | ... | @@ -16128,7 +16270,7 @@ fn zirOverflowArithmetic( |
| 16128 | if (maybe_rhs_val) |rhs_val| { | 16270 | if (maybe_rhs_val) |rhs_val| { |
| 16129 | if (rhs_val.isUndef(mod)) { | 16271 | if (rhs_val.isUndef(mod)) { |
| 16130 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 16272 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16131 | } else if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16273 | } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16132 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16274 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16133 | } else if (maybe_lhs_val) |lhs_val| { | 16275 | } else if (maybe_lhs_val) |lhs_val| { |
| 16134 | if (lhs_val.isUndef(mod)) { | 16276 | if (lhs_val.isUndef(mod)) { |
| ... | @@ -16144,10 +16286,10 @@ fn zirOverflowArithmetic( | ... | @@ -16144,10 +16286,10 @@ fn zirOverflowArithmetic( |
| 16144 | // If either of the arguments is zero, the result is zero and no overflow occured. | 16286 | // If either of the arguments is zero, the result is zero and no overflow occured. |
| 16145 | // If either of the arguments is one, the result is the other and no overflow occured. | 16287 | // If either of the arguments is one, the result is the other and no overflow occured. |
| 16146 | // Otherwise, if either of the arguments is undefined, both results are undefined. | 16288 | // Otherwise, if either of the arguments is undefined, both results are undefined. |
| 16147 | const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1); | 16289 | const scalar_one = try pt.intValue(dest_ty.scalarType(mod), 1); |
| 16148 | if (maybe_lhs_val) |lhs_val| { | 16290 | if (maybe_lhs_val) |lhs_val| { |
| 16149 | if (!lhs_val.isUndef(mod)) { | 16291 | if (!lhs_val.isUndef(mod)) { |
| 16150 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 16292 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16151 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16293 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16152 | } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { | 16294 | } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| 16153 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16295 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; |
| ... | @@ -16157,7 +16299,7 @@ fn zirOverflowArithmetic( | ... | @@ -16157,7 +16299,7 @@ fn zirOverflowArithmetic( |
| 16157 | 16299 | ||
| 16158 | if (maybe_rhs_val) |rhs_val| { | 16300 | if (maybe_rhs_val) |rhs_val| { |
| 16159 | if (!rhs_val.isUndef(mod)) { | 16301 | if (!rhs_val.isUndef(mod)) { |
| 16160 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16302 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16161 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; | 16303 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; |
| 16162 | } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { | 16304 | } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| 16163 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16305 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| ... | @@ -16171,7 +16313,7 @@ fn zirOverflowArithmetic( | ... | @@ -16171,7 +16313,7 @@ fn zirOverflowArithmetic( |
| 16171 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 16313 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16172 | } | 16314 | } |
| 16173 | 16315 | ||
| 16174 | const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod); | 16316 | const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, pt); |
| 16175 | break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; | 16317 | break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; |
| 16176 | } | 16318 | } |
| 16177 | } | 16319 | } |
| ... | @@ -16181,12 +16323,12 @@ fn zirOverflowArithmetic( | ... | @@ -16181,12 +16323,12 @@ fn zirOverflowArithmetic( |
| 16181 | // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred. | 16323 | // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred. |
| 16182 | // Oterhwise if either of the arguments is undefined, both results are undefined. | 16324 | // Oterhwise if either of the arguments is undefined, both results are undefined. |
| 16183 | if (maybe_lhs_val) |lhs_val| { | 16325 | if (maybe_lhs_val) |lhs_val| { |
| 16184 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) { | 16326 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16185 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16327 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16186 | } | 16328 | } |
| 16187 | } | 16329 | } |
| 16188 | if (maybe_rhs_val) |rhs_val| { | 16330 | if (maybe_rhs_val) |rhs_val| { |
| 16189 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) { | 16331 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16190 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; | 16332 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16191 | } | 16333 | } |
| 16192 | } | 16334 | } |
| ... | @@ -16196,7 +16338,7 @@ fn zirOverflowArithmetic( | ... | @@ -16196,7 +16338,7 @@ fn zirOverflowArithmetic( |
| 16196 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 16338 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16197 | } | 16339 | } |
| 16198 | 16340 | ||
| 16199 | const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, mod); | 16341 | const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, pt); |
| 16200 | break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; | 16342 | break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; |
| 16201 | } | 16343 | } |
| 16202 | } | 16344 | } |
| ... | @@ -16235,7 +16377,7 @@ fn zirOverflowArithmetic( | ... | @@ -16235,7 +16377,7 @@ fn zirOverflowArithmetic( |
| 16235 | } | 16377 | } |
| 16236 | 16378 | ||
| 16237 | if (result.inst == .none) { | 16379 | if (result.inst == .none) { |
| 16238 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 16380 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 16239 | .ty = tuple_ty.toIntern(), | 16381 | .ty = tuple_ty.toIntern(), |
| 16240 | .storage = .{ .elems = &.{ | 16382 | .storage = .{ .elems = &.{ |
| 16241 | result.wrapped.toIntern(), | 16383 | result.wrapped.toIntern(), |
| ... | @@ -16251,9 +16393,10 @@ fn zirOverflowArithmetic( | ... | @@ -16251,9 +16393,10 @@ fn zirOverflowArithmetic( |
| 16251 | } | 16393 | } |
| 16252 | 16394 | ||
| 16253 | fn splat(sema: *Sema, ty: Type, val: Value) !Value { | 16395 | fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 16254 | const mod = sema.mod; | 16396 | const pt = sema.pt; |
| 16397 | const mod = pt.zcu; | ||
| 16255 | if (ty.zigTypeTag(mod) != .Vector) return val; | 16398 | if (ty.zigTypeTag(mod) != .Vector) return val; |
| 16256 | const repeated = try mod.intern(.{ .aggregate = .{ | 16399 | const repeated = try pt.intern(.{ .aggregate = .{ |
| 16257 | .ty = ty.toIntern(), | 16400 | .ty = ty.toIntern(), |
| 16258 | .storage = .{ .repeated_elem = val.toIntern() }, | 16401 | .storage = .{ .repeated_elem = val.toIntern() }, |
| 16259 | } }); | 16402 | } }); |
| ... | @@ -16261,16 +16404,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { | ... | @@ -16261,16 +16404,17 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 16261 | } | 16404 | } |
| 16262 | 16405 | ||
| 16263 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { | 16406 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { |
| 16264 | const mod = sema.mod; | 16407 | const pt = sema.pt; |
| 16408 | const mod = pt.zcu; | ||
| 16265 | const ip = &mod.intern_pool; | 16409 | const ip = &mod.intern_pool; |
| 16266 | const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{ | 16410 | const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try pt.vectorType(.{ |
| 16267 | .len = ty.vectorLen(mod), | 16411 | .len = ty.vectorLen(mod), |
| 16268 | .child = .u1_type, | 16412 | .child = .u1_type, |
| 16269 | }) else Type.u1; | 16413 | }) else Type.u1; |
| 16270 | 16414 | ||
| 16271 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; | 16415 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; |
| 16272 | const values = [2]InternPool.Index{ .none, .none }; | 16416 | const values = [2]InternPool.Index{ .none, .none }; |
| 16273 | const tuple_ty = try ip.getAnonStructType(mod.gpa, .{ | 16417 | const tuple_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{ |
| 16274 | .types = &types, | 16418 | .types = &types, |
| 16275 | .values = &values, | 16419 | .values = &values, |
| 16276 | .names = &.{}, | 16420 | .names = &.{}, |
| ... | @@ -16290,7 +16434,8 @@ fn analyzeArithmetic( | ... | @@ -16290,7 +16434,8 @@ fn analyzeArithmetic( |
| 16290 | rhs_src: LazySrcLoc, | 16434 | rhs_src: LazySrcLoc, |
| 16291 | want_safety: bool, | 16435 | want_safety: bool, |
| 16292 | ) CompileError!Air.Inst.Ref { | 16436 | ) CompileError!Air.Inst.Ref { |
| 16293 | const mod = sema.mod; | 16437 | const pt = sema.pt; |
| 16438 | const mod = pt.zcu; | ||
| 16294 | const lhs_ty = sema.typeOf(lhs); | 16439 | const lhs_ty = sema.typeOf(lhs); |
| 16295 | const rhs_ty = sema.typeOf(rhs); | 16440 | const rhs_ty = sema.typeOf(rhs); |
| 16296 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | 16441 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); |
| ... | @@ -16337,7 +16482,7 @@ fn analyzeArithmetic( | ... | @@ -16337,7 +16482,7 @@ fn analyzeArithmetic( |
| 16337 | // overflow (max_int), causing illegal behavior. | 16482 | // overflow (max_int), causing illegal behavior. |
| 16338 | // For floats: either operand being undef makes the result undef. | 16483 | // For floats: either operand being undef makes the result undef. |
| 16339 | if (maybe_lhs_val) |lhs_val| { | 16484 | if (maybe_lhs_val) |lhs_val| { |
| 16340 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) { | 16485 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16341 | return casted_rhs; | 16486 | return casted_rhs; |
| 16342 | } | 16487 | } |
| 16343 | } | 16488 | } |
| ... | @@ -16346,10 +16491,10 @@ fn analyzeArithmetic( | ... | @@ -16346,10 +16491,10 @@ fn analyzeArithmetic( |
| 16346 | if (is_int) { | 16491 | if (is_int) { |
| 16347 | return sema.failWithUseOfUndef(block, rhs_src); | 16492 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16348 | } else { | 16493 | } else { |
| 16349 | return mod.undefRef(resolved_type); | 16494 | return pt.undefRef(resolved_type); |
| 16350 | } | 16495 | } |
| 16351 | } | 16496 | } |
| 16352 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16497 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16353 | return casted_lhs; | 16498 | return casted_lhs; |
| 16354 | } | 16499 | } |
| 16355 | } | 16500 | } |
| ... | @@ -16359,7 +16504,7 @@ fn analyzeArithmetic( | ... | @@ -16359,7 +16504,7 @@ fn analyzeArithmetic( |
| 16359 | if (is_int) { | 16504 | if (is_int) { |
| 16360 | return sema.failWithUseOfUndef(block, lhs_src); | 16505 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16361 | } else { | 16506 | } else { |
| 16362 | return mod.undefRef(resolved_type); | 16507 | return pt.undefRef(resolved_type); |
| 16363 | } | 16508 | } |
| 16364 | } | 16509 | } |
| 16365 | if (maybe_rhs_val) |rhs_val| { | 16510 | if (maybe_rhs_val) |rhs_val| { |
| ... | @@ -16371,7 +16516,7 @@ fn analyzeArithmetic( | ... | @@ -16371,7 +16516,7 @@ fn analyzeArithmetic( |
| 16371 | } | 16516 | } |
| 16372 | return Air.internedToRef(sum.toIntern()); | 16517 | return Air.internedToRef(sum.toIntern()); |
| 16373 | } else { | 16518 | } else { |
| 16374 | return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16519 | return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 16375 | } | 16520 | } |
| 16376 | } else break :rs .{ rhs_src, air_tag, .add_safe }; | 16521 | } else break :rs .{ rhs_src, air_tag, .add_safe }; |
| 16377 | } else break :rs .{ lhs_src, air_tag, .add_safe }; | 16522 | } else break :rs .{ lhs_src, air_tag, .add_safe }; |
| ... | @@ -16381,15 +16526,15 @@ fn analyzeArithmetic( | ... | @@ -16381,15 +16526,15 @@ fn analyzeArithmetic( |
| 16381 | // If either of the operands are zero, the other operand is returned. | 16526 | // If either of the operands are zero, the other operand is returned. |
| 16382 | // If either of the operands are undefined, the result is undefined. | 16527 | // If either of the operands are undefined, the result is undefined. |
| 16383 | if (maybe_lhs_val) |lhs_val| { | 16528 | if (maybe_lhs_val) |lhs_val| { |
| 16384 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) { | 16529 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16385 | return casted_rhs; | 16530 | return casted_rhs; |
| 16386 | } | 16531 | } |
| 16387 | } | 16532 | } |
| 16388 | if (maybe_rhs_val) |rhs_val| { | 16533 | if (maybe_rhs_val) |rhs_val| { |
| 16389 | if (rhs_val.isUndef(mod)) { | 16534 | if (rhs_val.isUndef(mod)) { |
| 16390 | return mod.undefRef(resolved_type); | 16535 | return pt.undefRef(resolved_type); |
| 16391 | } | 16536 | } |
| 16392 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16537 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16393 | return casted_lhs; | 16538 | return casted_lhs; |
| 16394 | } | 16539 | } |
| 16395 | if (maybe_lhs_val) |lhs_val| { | 16540 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -16402,26 +16547,26 @@ fn analyzeArithmetic( | ... | @@ -16402,26 +16547,26 @@ fn analyzeArithmetic( |
| 16402 | // If either of the operands are zero, then the other operand is returned. | 16547 | // If either of the operands are zero, then the other operand is returned. |
| 16403 | // If either of the operands are undefined, the result is undefined. | 16548 | // If either of the operands are undefined, the result is undefined. |
| 16404 | if (maybe_lhs_val) |lhs_val| { | 16549 | if (maybe_lhs_val) |lhs_val| { |
| 16405 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) { | 16550 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { |
| 16406 | return casted_rhs; | 16551 | return casted_rhs; |
| 16407 | } | 16552 | } |
| 16408 | } | 16553 | } |
| 16409 | if (maybe_rhs_val) |rhs_val| { | 16554 | if (maybe_rhs_val) |rhs_val| { |
| 16410 | if (rhs_val.isUndef(mod)) { | 16555 | if (rhs_val.isUndef(mod)) { |
| 16411 | return mod.undefRef(resolved_type); | 16556 | return pt.undefRef(resolved_type); |
| 16412 | } | 16557 | } |
| 16413 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16558 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16414 | return casted_lhs; | 16559 | return casted_lhs; |
| 16415 | } | 16560 | } |
| 16416 | if (maybe_lhs_val) |lhs_val| { | 16561 | if (maybe_lhs_val) |lhs_val| { |
| 16417 | if (lhs_val.isUndef(mod)) { | 16562 | if (lhs_val.isUndef(mod)) { |
| 16418 | return mod.undefRef(resolved_type); | 16563 | return pt.undefRef(resolved_type); |
| 16419 | } | 16564 | } |
| 16420 | 16565 | ||
| 16421 | const val = if (scalar_tag == .ComptimeInt) | 16566 | const val = if (scalar_tag == .ComptimeInt) |
| 16422 | try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined) | 16567 | try sema.intAdd(lhs_val, rhs_val, resolved_type, undefined) |
| 16423 | else | 16568 | else |
| 16424 | try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, mod); | 16569 | try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, pt); |
| 16425 | 16570 | ||
| 16426 | return Air.internedToRef(val.toIntern()); | 16571 | return Air.internedToRef(val.toIntern()); |
| 16427 | } else break :rs .{ | 16572 | } else break :rs .{ |
| ... | @@ -16448,10 +16593,10 @@ fn analyzeArithmetic( | ... | @@ -16448,10 +16593,10 @@ fn analyzeArithmetic( |
| 16448 | if (is_int) { | 16593 | if (is_int) { |
| 16449 | return sema.failWithUseOfUndef(block, rhs_src); | 16594 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16450 | } else { | 16595 | } else { |
| 16451 | return mod.undefRef(resolved_type); | 16596 | return pt.undefRef(resolved_type); |
| 16452 | } | 16597 | } |
| 16453 | } | 16598 | } |
| 16454 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16599 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16455 | return casted_lhs; | 16600 | return casted_lhs; |
| 16456 | } | 16601 | } |
| 16457 | } | 16602 | } |
| ... | @@ -16461,7 +16606,7 @@ fn analyzeArithmetic( | ... | @@ -16461,7 +16606,7 @@ fn analyzeArithmetic( |
| 16461 | if (is_int) { | 16606 | if (is_int) { |
| 16462 | return sema.failWithUseOfUndef(block, lhs_src); | 16607 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16463 | } else { | 16608 | } else { |
| 16464 | return mod.undefRef(resolved_type); | 16609 | return pt.undefRef(resolved_type); |
| 16465 | } | 16610 | } |
| 16466 | } | 16611 | } |
| 16467 | if (maybe_rhs_val) |rhs_val| { | 16612 | if (maybe_rhs_val) |rhs_val| { |
| ... | @@ -16473,7 +16618,7 @@ fn analyzeArithmetic( | ... | @@ -16473,7 +16618,7 @@ fn analyzeArithmetic( |
| 16473 | } | 16618 | } |
| 16474 | return Air.internedToRef(diff.toIntern()); | 16619 | return Air.internedToRef(diff.toIntern()); |
| 16475 | } else { | 16620 | } else { |
| 16476 | return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16621 | return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 16477 | } | 16622 | } |
| 16478 | } else break :rs .{ rhs_src, air_tag, .sub_safe }; | 16623 | } else break :rs .{ rhs_src, air_tag, .sub_safe }; |
| 16479 | } else break :rs .{ lhs_src, air_tag, .sub_safe }; | 16624 | } else break :rs .{ lhs_src, air_tag, .sub_safe }; |
| ... | @@ -16484,15 +16629,15 @@ fn analyzeArithmetic( | ... | @@ -16484,15 +16629,15 @@ fn analyzeArithmetic( |
| 16484 | // If either of the operands are undefined, the result is undefined. | 16629 | // If either of the operands are undefined, the result is undefined. |
| 16485 | if (maybe_rhs_val) |rhs_val| { | 16630 | if (maybe_rhs_val) |rhs_val| { |
| 16486 | if (rhs_val.isUndef(mod)) { | 16631 | if (rhs_val.isUndef(mod)) { |
| 16487 | return mod.undefRef(resolved_type); | 16632 | return pt.undefRef(resolved_type); |
| 16488 | } | 16633 | } |
| 16489 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16634 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16490 | return casted_lhs; | 16635 | return casted_lhs; |
| 16491 | } | 16636 | } |
| 16492 | } | 16637 | } |
| 16493 | if (maybe_lhs_val) |lhs_val| { | 16638 | if (maybe_lhs_val) |lhs_val| { |
| 16494 | if (lhs_val.isUndef(mod)) { | 16639 | if (lhs_val.isUndef(mod)) { |
| 16495 | return mod.undefRef(resolved_type); | 16640 | return pt.undefRef(resolved_type); |
| 16496 | } | 16641 | } |
| 16497 | if (maybe_rhs_val) |rhs_val| { | 16642 | if (maybe_rhs_val) |rhs_val| { |
| 16498 | return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); | 16643 | return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); |
| ... | @@ -16505,21 +16650,21 @@ fn analyzeArithmetic( | ... | @@ -16505,21 +16650,21 @@ fn analyzeArithmetic( |
| 16505 | // If either of the operands are undefined, the result is undefined. | 16650 | // If either of the operands are undefined, the result is undefined. |
| 16506 | if (maybe_rhs_val) |rhs_val| { | 16651 | if (maybe_rhs_val) |rhs_val| { |
| 16507 | if (rhs_val.isUndef(mod)) { | 16652 | if (rhs_val.isUndef(mod)) { |
| 16508 | return mod.undefRef(resolved_type); | 16653 | return pt.undefRef(resolved_type); |
| 16509 | } | 16654 | } |
| 16510 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16655 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16511 | return casted_lhs; | 16656 | return casted_lhs; |
| 16512 | } | 16657 | } |
| 16513 | } | 16658 | } |
| 16514 | if (maybe_lhs_val) |lhs_val| { | 16659 | if (maybe_lhs_val) |lhs_val| { |
| 16515 | if (lhs_val.isUndef(mod)) { | 16660 | if (lhs_val.isUndef(mod)) { |
| 16516 | return mod.undefRef(resolved_type); | 16661 | return pt.undefRef(resolved_type); |
| 16517 | } | 16662 | } |
| 16518 | if (maybe_rhs_val) |rhs_val| { | 16663 | if (maybe_rhs_val) |rhs_val| { |
| 16519 | const val = if (scalar_tag == .ComptimeInt) | 16664 | const val = if (scalar_tag == .ComptimeInt) |
| 16520 | try sema.intSub(lhs_val, rhs_val, resolved_type, undefined) | 16665 | try sema.intSub(lhs_val, rhs_val, resolved_type, undefined) |
| 16521 | else | 16666 | else |
| 16522 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod); | 16667 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, pt); |
| 16523 | 16668 | ||
| 16524 | return Air.internedToRef(val.toIntern()); | 16669 | return Air.internedToRef(val.toIntern()); |
| 16525 | } else break :rs .{ rhs_src, .sub_sat, .sub_sat }; | 16670 | } else break :rs .{ rhs_src, .sub_sat, .sub_sat }; |
| ... | @@ -16540,13 +16685,13 @@ fn analyzeArithmetic( | ... | @@ -16540,13 +16685,13 @@ fn analyzeArithmetic( |
| 16540 | // the result is nan. | 16685 | // the result is nan. |
| 16541 | // If either of the operands are nan, the result is nan. | 16686 | // If either of the operands are nan, the result is nan. |
| 16542 | const scalar_zero = switch (scalar_tag) { | 16687 | const scalar_zero = switch (scalar_tag) { |
| 16543 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), | 16688 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0), |
| 16544 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), | 16689 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 0), |
| 16545 | else => unreachable, | 16690 | else => unreachable, |
| 16546 | }; | 16691 | }; |
| 16547 | const scalar_one = switch (scalar_tag) { | 16692 | const scalar_one = switch (scalar_tag) { |
| 16548 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0), | 16693 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0), |
| 16549 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 1), | 16694 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 1), |
| 16550 | else => unreachable, | 16695 | else => unreachable, |
| 16551 | }; | 16696 | }; |
| 16552 | if (maybe_lhs_val) |lhs_val| { | 16697 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -16554,13 +16699,13 @@ fn analyzeArithmetic( | ... | @@ -16554,13 +16699,13 @@ fn analyzeArithmetic( |
| 16554 | if (lhs_val.isNan(mod)) { | 16699 | if (lhs_val.isNan(mod)) { |
| 16555 | return Air.internedToRef(lhs_val.toIntern()); | 16700 | return Air.internedToRef(lhs_val.toIntern()); |
| 16556 | } | 16701 | } |
| 16557 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) lz: { | 16702 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) lz: { |
| 16558 | if (maybe_rhs_val) |rhs_val| { | 16703 | if (maybe_rhs_val) |rhs_val| { |
| 16559 | if (rhs_val.isNan(mod)) { | 16704 | if (rhs_val.isNan(mod)) { |
| 16560 | return Air.internedToRef(rhs_val.toIntern()); | 16705 | return Air.internedToRef(rhs_val.toIntern()); |
| 16561 | } | 16706 | } |
| 16562 | if (rhs_val.isInf(mod)) { | 16707 | if (rhs_val.isInf(mod)) { |
| 16563 | return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern()); | 16708 | return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern()); |
| 16564 | } | 16709 | } |
| 16565 | } else if (resolved_type.isAnyFloat()) { | 16710 | } else if (resolved_type.isAnyFloat()) { |
| 16566 | break :lz; | 16711 | break :lz; |
| ... | @@ -16579,16 +16724,16 @@ fn analyzeArithmetic( | ... | @@ -16579,16 +16724,16 @@ fn analyzeArithmetic( |
| 16579 | if (is_int) { | 16724 | if (is_int) { |
| 16580 | return sema.failWithUseOfUndef(block, rhs_src); | 16725 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16581 | } else { | 16726 | } else { |
| 16582 | return mod.undefRef(resolved_type); | 16727 | return pt.undefRef(resolved_type); |
| 16583 | } | 16728 | } |
| 16584 | } | 16729 | } |
| 16585 | if (rhs_val.isNan(mod)) { | 16730 | if (rhs_val.isNan(mod)) { |
| 16586 | return Air.internedToRef(rhs_val.toIntern()); | 16731 | return Air.internedToRef(rhs_val.toIntern()); |
| 16587 | } | 16732 | } |
| 16588 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) rz: { | 16733 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) rz: { |
| 16589 | if (maybe_lhs_val) |lhs_val| { | 16734 | if (maybe_lhs_val) |lhs_val| { |
| 16590 | if (lhs_val.isInf(mod)) { | 16735 | if (lhs_val.isInf(mod)) { |
| 16591 | return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern()); | 16736 | return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern()); |
| 16592 | } | 16737 | } |
| 16593 | } else if (resolved_type.isAnyFloat()) { | 16738 | } else if (resolved_type.isAnyFloat()) { |
| 16594 | break :rz; | 16739 | break :rz; |
| ... | @@ -16604,18 +16749,18 @@ fn analyzeArithmetic( | ... | @@ -16604,18 +16749,18 @@ fn analyzeArithmetic( |
| 16604 | if (is_int) { | 16749 | if (is_int) { |
| 16605 | return sema.failWithUseOfUndef(block, lhs_src); | 16750 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16606 | } else { | 16751 | } else { |
| 16607 | return mod.undefRef(resolved_type); | 16752 | return pt.undefRef(resolved_type); |
| 16608 | } | 16753 | } |
| 16609 | } | 16754 | } |
| 16610 | if (is_int) { | 16755 | if (is_int) { |
| 16611 | var overflow_idx: ?usize = null; | 16756 | var overflow_idx: ?usize = null; |
| 16612 | const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, mod); | 16757 | const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, pt); |
| 16613 | if (overflow_idx) |vec_idx| { | 16758 | if (overflow_idx) |vec_idx| { |
| 16614 | return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx); | 16759 | return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx); |
| 16615 | } | 16760 | } |
| 16616 | return Air.internedToRef(product.toIntern()); | 16761 | return Air.internedToRef(product.toIntern()); |
| 16617 | } else { | 16762 | } else { |
| 16618 | return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16763 | return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 16619 | } | 16764 | } |
| 16620 | } else break :rs .{ lhs_src, air_tag, .mul_safe }; | 16765 | } else break :rs .{ lhs_src, air_tag, .mul_safe }; |
| 16621 | } else break :rs .{ rhs_src, air_tag, .mul_safe }; | 16766 | } else break :rs .{ rhs_src, air_tag, .mul_safe }; |
| ... | @@ -16626,18 +16771,18 @@ fn analyzeArithmetic( | ... | @@ -16626,18 +16771,18 @@ fn analyzeArithmetic( |
| 16626 | // If either of the operands are one, result is the other operand. | 16771 | // If either of the operands are one, result is the other operand. |
| 16627 | // If either of the operands are undefined, result is undefined. | 16772 | // If either of the operands are undefined, result is undefined. |
| 16628 | const scalar_zero = switch (scalar_tag) { | 16773 | const scalar_zero = switch (scalar_tag) { |
| 16629 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), | 16774 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0), |
| 16630 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), | 16775 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 0), |
| 16631 | else => unreachable, | 16776 | else => unreachable, |
| 16632 | }; | 16777 | }; |
| 16633 | const scalar_one = switch (scalar_tag) { | 16778 | const scalar_one = switch (scalar_tag) { |
| 16634 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0), | 16779 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0), |
| 16635 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 1), | 16780 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 1), |
| 16636 | else => unreachable, | 16781 | else => unreachable, |
| 16637 | }; | 16782 | }; |
| 16638 | if (maybe_lhs_val) |lhs_val| { | 16783 | if (maybe_lhs_val) |lhs_val| { |
| 16639 | if (!lhs_val.isUndef(mod)) { | 16784 | if (!lhs_val.isUndef(mod)) { |
| 16640 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 16785 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16641 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 16786 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16642 | return Air.internedToRef(zero_val.toIntern()); | 16787 | return Air.internedToRef(zero_val.toIntern()); |
| 16643 | } | 16788 | } |
| ... | @@ -16648,9 +16793,9 @@ fn analyzeArithmetic( | ... | @@ -16648,9 +16793,9 @@ fn analyzeArithmetic( |
| 16648 | } | 16793 | } |
| 16649 | if (maybe_rhs_val) |rhs_val| { | 16794 | if (maybe_rhs_val) |rhs_val| { |
| 16650 | if (rhs_val.isUndef(mod)) { | 16795 | if (rhs_val.isUndef(mod)) { |
| 16651 | return mod.undefRef(resolved_type); | 16796 | return pt.undefRef(resolved_type); |
| 16652 | } | 16797 | } |
| 16653 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16798 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16654 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 16799 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16655 | return Air.internedToRef(zero_val.toIntern()); | 16800 | return Air.internedToRef(zero_val.toIntern()); |
| 16656 | } | 16801 | } |
| ... | @@ -16659,9 +16804,9 @@ fn analyzeArithmetic( | ... | @@ -16659,9 +16804,9 @@ fn analyzeArithmetic( |
| 16659 | } | 16804 | } |
| 16660 | if (maybe_lhs_val) |lhs_val| { | 16805 | if (maybe_lhs_val) |lhs_val| { |
| 16661 | if (lhs_val.isUndef(mod)) { | 16806 | if (lhs_val.isUndef(mod)) { |
| 16662 | return mod.undefRef(resolved_type); | 16807 | return pt.undefRef(resolved_type); |
| 16663 | } | 16808 | } |
| 16664 | return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 16809 | return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| 16665 | } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap }; | 16810 | } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap }; |
| 16666 | } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap }; | 16811 | } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap }; |
| 16667 | }, | 16812 | }, |
| ... | @@ -16671,18 +16816,18 @@ fn analyzeArithmetic( | ... | @@ -16671,18 +16816,18 @@ fn analyzeArithmetic( |
| 16671 | // If either of the operands are one, result is the other operand. | 16816 | // If either of the operands are one, result is the other operand. |
| 16672 | // If either of the operands are undefined, result is undefined. | 16817 | // If either of the operands are undefined, result is undefined. |
| 16673 | const scalar_zero = switch (scalar_tag) { | 16818 | const scalar_zero = switch (scalar_tag) { |
| 16674 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), | 16819 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 0.0), |
| 16675 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), | 16820 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 0), |
| 16676 | else => unreachable, | 16821 | else => unreachable, |
| 16677 | }; | 16822 | }; |
| 16678 | const scalar_one = switch (scalar_tag) { | 16823 | const scalar_one = switch (scalar_tag) { |
| 16679 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0), | 16824 | .ComptimeFloat, .Float => try pt.floatValue(scalar_type, 1.0), |
| 16680 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 1), | 16825 | .ComptimeInt, .Int => try pt.intValue(scalar_type, 1), |
| 16681 | else => unreachable, | 16826 | else => unreachable, |
| 16682 | }; | 16827 | }; |
| 16683 | if (maybe_lhs_val) |lhs_val| { | 16828 | if (maybe_lhs_val) |lhs_val| { |
| 16684 | if (!lhs_val.isUndef(mod)) { | 16829 | if (!lhs_val.isUndef(mod)) { |
| 16685 | if (try lhs_val.compareAllWithZeroSema(.eq, mod)) { | 16830 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16686 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 16831 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16687 | return Air.internedToRef(zero_val.toIntern()); | 16832 | return Air.internedToRef(zero_val.toIntern()); |
| 16688 | } | 16833 | } |
| ... | @@ -16693,9 +16838,9 @@ fn analyzeArithmetic( | ... | @@ -16693,9 +16838,9 @@ fn analyzeArithmetic( |
| 16693 | } | 16838 | } |
| 16694 | if (maybe_rhs_val) |rhs_val| { | 16839 | if (maybe_rhs_val) |rhs_val| { |
| 16695 | if (rhs_val.isUndef(mod)) { | 16840 | if (rhs_val.isUndef(mod)) { |
| 16696 | return mod.undefRef(resolved_type); | 16841 | return pt.undefRef(resolved_type); |
| 16697 | } | 16842 | } |
| 16698 | if (try rhs_val.compareAllWithZeroSema(.eq, mod)) { | 16843 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16699 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 16844 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16700 | return Air.internedToRef(zero_val.toIntern()); | 16845 | return Air.internedToRef(zero_val.toIntern()); |
| 16701 | } | 16846 | } |
| ... | @@ -16704,13 +16849,13 @@ fn analyzeArithmetic( | ... | @@ -16704,13 +16849,13 @@ fn analyzeArithmetic( |
| 16704 | } | 16849 | } |
| 16705 | if (maybe_lhs_val) |lhs_val| { | 16850 | if (maybe_lhs_val) |lhs_val| { |
| 16706 | if (lhs_val.isUndef(mod)) { | 16851 | if (lhs_val.isUndef(mod)) { |
| 16707 | return mod.undefRef(resolved_type); | 16852 | return pt.undefRef(resolved_type); |
| 16708 | } | 16853 | } |
| 16709 | 16854 | ||
| 16710 | const val = if (scalar_tag == .ComptimeInt) | 16855 | const val = if (scalar_tag == .ComptimeInt) |
| 16711 | try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, mod) | 16856 | try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, pt) |
| 16712 | else | 16857 | else |
| 16713 | try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod); | 16858 | try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, pt); |
| 16714 | 16859 | ||
| 16715 | return Air.internedToRef(val.toIntern()); | 16860 | return Air.internedToRef(val.toIntern()); |
| 16716 | } else break :rs .{ lhs_src, .mul_sat, .mul_sat }; | 16861 | } else break :rs .{ lhs_src, .mul_sat, .mul_sat }; |
| ... | @@ -16758,7 +16903,7 @@ fn analyzeArithmetic( | ... | @@ -16758,7 +16903,7 @@ fn analyzeArithmetic( |
| 16758 | }) | 16903 | }) |
| 16759 | else | 16904 | else |
| 16760 | ov_bit; | 16905 | ov_bit; |
| 16761 | const zero_ov = Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern()); | 16906 | const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); |
| 16762 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | 16907 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 16763 | 16908 | ||
| 16764 | try sema.addSafetyCheck(block, src, no_ov, .integer_overflow); | 16909 | try sema.addSafetyCheck(block, src, no_ov, .integer_overflow); |
| ... | @@ -16782,7 +16927,8 @@ fn analyzePtrArithmetic( | ... | @@ -16782,7 +16927,8 @@ fn analyzePtrArithmetic( |
| 16782 | // TODO if the operand is comptime-known to be negative, or is a negative int, | 16927 | // TODO if the operand is comptime-known to be negative, or is a negative int, |
| 16783 | // coerce to isize instead of usize. | 16928 | // coerce to isize instead of usize. |
| 16784 | const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src); | 16929 | const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src); |
| 16785 | const mod = sema.mod; | 16930 | const pt = sema.pt; |
| 16931 | const mod = pt.zcu; | ||
| 16786 | const opt_ptr_val = try sema.resolveValue(ptr); | 16932 | const opt_ptr_val = try sema.resolveValue(ptr); |
| 16787 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); | 16933 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); |
| 16788 | const ptr_ty = sema.typeOf(ptr); | 16934 | const ptr_ty = sema.typeOf(ptr); |
| ... | @@ -16800,7 +16946,7 @@ fn analyzePtrArithmetic( | ... | @@ -16800,7 +16946,7 @@ fn analyzePtrArithmetic( |
| 16800 | // it being a multiple of the type size. | 16946 | // it being a multiple of the type size. |
| 16801 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); | 16947 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); |
| 16802 | const addend = if (opt_off_val) |off_val| a: { | 16948 | const addend = if (opt_off_val) |off_val| a: { |
| 16803 | const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(mod)); | 16949 | const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(pt)); |
| 16804 | break :a elem_size * off_int; | 16950 | break :a elem_size * off_int; |
| 16805 | } else elem_size; | 16951 | } else elem_size; |
| 16806 | 16952 | ||
| ... | @@ -16813,7 +16959,7 @@ fn analyzePtrArithmetic( | ... | @@ -16813,7 +16959,7 @@ fn analyzePtrArithmetic( |
| 16813 | )); | 16959 | )); |
| 16814 | assert(new_align != .none); | 16960 | assert(new_align != .none); |
| 16815 | 16961 | ||
| 16816 | break :t try mod.ptrTypeSema(.{ | 16962 | break :t try pt.ptrTypeSema(.{ |
| 16817 | .child = ptr_info.child, | 16963 | .child = ptr_info.child, |
| 16818 | .sentinel = ptr_info.sentinel, | 16964 | .sentinel = ptr_info.sentinel, |
| 16819 | .flags = .{ | 16965 | .flags = .{ |
| ... | @@ -16830,16 +16976,16 @@ fn analyzePtrArithmetic( | ... | @@ -16830,16 +16976,16 @@ fn analyzePtrArithmetic( |
| 16830 | const runtime_src = rs: { | 16976 | const runtime_src = rs: { |
| 16831 | if (opt_ptr_val) |ptr_val| { | 16977 | if (opt_ptr_val) |ptr_val| { |
| 16832 | if (opt_off_val) |offset_val| { | 16978 | if (opt_off_val) |offset_val| { |
| 16833 | if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty); | 16979 | if (ptr_val.isUndef(mod)) return pt.undefRef(new_ptr_ty); |
| 16834 | 16980 | ||
| 16835 | const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(mod)); | 16981 | const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt)); |
| 16836 | if (offset_int == 0) return ptr; | 16982 | if (offset_int == 0) return ptr; |
| 16837 | if (air_tag == .ptr_sub) { | 16983 | if (air_tag == .ptr_sub) { |
| 16838 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); | 16984 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); |
| 16839 | const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty); | 16985 | const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty); |
| 16840 | return Air.internedToRef(new_ptr_val.toIntern()); | 16986 | return Air.internedToRef(new_ptr_val.toIntern()); |
| 16841 | } else { | 16987 | } else { |
| 16842 | const new_ptr_val = try mod.getCoerced(try ptr_val.ptrElem(offset_int, mod), new_ptr_ty); | 16988 | const new_ptr_val = try pt.getCoerced(try ptr_val.ptrElem(offset_int, pt), new_ptr_ty); |
| 16843 | return Air.internedToRef(new_ptr_val.toIntern()); | 16989 | return Air.internedToRef(new_ptr_val.toIntern()); |
| 16844 | } | 16990 | } |
| 16845 | } else break :rs offset_src; | 16991 | } else break :rs offset_src; |
| ... | @@ -16879,6 +17025,8 @@ fn zirAsm( | ... | @@ -16879,6 +17025,8 @@ fn zirAsm( |
| 16879 | const tracy = trace(@src()); | 17025 | const tracy = trace(@src()); |
| 16880 | defer tracy.end(); | 17026 | defer tracy.end(); |
| 16881 | 17027 | ||
| 17028 | const pt = sema.pt; | ||
| 17029 | const mod = pt.zcu; | ||
| 16882 | const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand); | 17030 | const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand); |
| 16883 | const src = block.nodeOffset(extra.data.src_node); | 17031 | const src = block.nodeOffset(extra.data.src_node); |
| 16884 | const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node }); | 17032 | const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node }); |
| ... | @@ -16910,7 +17058,7 @@ fn zirAsm( | ... | @@ -16910,7 +17058,7 @@ fn zirAsm( |
| 16910 | if (is_volatile) { | 17058 | if (is_volatile) { |
| 16911 | return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{}); | 17059 | return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{}); |
| 16912 | } | 17060 | } |
| 16913 | try sema.mod.addGlobalAssembly(sema.owner_decl_index, asm_source); | 17061 | try mod.addGlobalAssembly(sema.owner_decl_index, asm_source); |
| 16914 | return .void_value; | 17062 | return .void_value; |
| 16915 | } | 17063 | } |
| 16916 | 17064 | ||
| ... | @@ -16959,7 +17107,6 @@ fn zirAsm( | ... | @@ -16959,7 +17107,6 @@ fn zirAsm( |
| 16959 | 17107 | ||
| 16960 | const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len); | 17108 | const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len); |
| 16961 | const inputs = try sema.arena.alloc(ConstraintName, inputs_len); | 17109 | const inputs = try sema.arena.alloc(ConstraintName, inputs_len); |
| 16962 | const mod = sema.mod; | ||
| 16963 | 17110 | ||
| 16964 | for (args, 0..) |*arg, arg_i| { | 17111 | for (args, 0..) |*arg, arg_i| { |
| 16965 | const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); | 17112 | const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); |
| ... | @@ -17049,7 +17196,8 @@ fn zirCmpEq( | ... | @@ -17049,7 +17196,8 @@ fn zirCmpEq( |
| 17049 | const tracy = trace(@src()); | 17196 | const tracy = trace(@src()); |
| 17050 | defer tracy.end(); | 17197 | defer tracy.end(); |
| 17051 | 17198 | ||
| 17052 | const mod = sema.mod; | 17199 | const pt = sema.pt; |
| 17200 | const mod = pt.zcu; | ||
| 17053 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 17201 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 17054 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 17202 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 17055 | const src: LazySrcLoc = block.nodeOffset(inst_data.src_node); | 17203 | const src: LazySrcLoc = block.nodeOffset(inst_data.src_node); |
| ... | @@ -17077,7 +17225,7 @@ fn zirCmpEq( | ... | @@ -17077,7 +17225,7 @@ fn zirCmpEq( |
| 17077 | 17225 | ||
| 17078 | if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) { | 17226 | if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) { |
| 17079 | const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty; | 17227 | const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty; |
| 17080 | return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(mod)}); | 17228 | return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(pt)}); |
| 17081 | } | 17229 | } |
| 17082 | 17230 | ||
| 17083 | if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) { | 17231 | if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) { |
| ... | @@ -17092,7 +17240,7 @@ fn zirCmpEq( | ... | @@ -17092,7 +17240,7 @@ fn zirCmpEq( |
| 17092 | if (try sema.resolveValue(lhs)) |lval| { | 17240 | if (try sema.resolveValue(lhs)) |lval| { |
| 17093 | if (try sema.resolveValue(rhs)) |rval| { | 17241 | if (try sema.resolveValue(rhs)) |rval| { |
| 17094 | if (lval.isUndef(mod) or rval.isUndef(mod)) { | 17242 | if (lval.isUndef(mod) or rval.isUndef(mod)) { |
| 17095 | return mod.undefRef(Type.bool); | 17243 | return pt.undefRef(Type.bool); |
| 17096 | } | 17244 | } |
| 17097 | const lkey = mod.intern_pool.indexToKey(lval.toIntern()); | 17245 | const lkey = mod.intern_pool.indexToKey(lval.toIntern()); |
| 17098 | const rkey = mod.intern_pool.indexToKey(rval.toIntern()); | 17246 | const rkey = mod.intern_pool.indexToKey(rval.toIntern()); |
| ... | @@ -17128,14 +17276,15 @@ fn analyzeCmpUnionTag( | ... | @@ -17128,14 +17276,15 @@ fn analyzeCmpUnionTag( |
| 17128 | tag_src: LazySrcLoc, | 17276 | tag_src: LazySrcLoc, |
| 17129 | op: std.math.CompareOperator, | 17277 | op: std.math.CompareOperator, |
| 17130 | ) CompileError!Air.Inst.Ref { | 17278 | ) CompileError!Air.Inst.Ref { |
| 17131 | const mod = sema.mod; | 17279 | const pt = sema.pt; |
| 17280 | const mod = pt.zcu; | ||
| 17132 | const union_ty = sema.typeOf(un); | 17281 | const union_ty = sema.typeOf(un); |
| 17133 | try union_ty.resolveFields(mod); | 17282 | try union_ty.resolveFields(pt); |
| 17134 | const union_tag_ty = union_ty.unionTagType(mod) orelse { | 17283 | const union_tag_ty = union_ty.unionTagType(mod) orelse { |
| 17135 | const msg = msg: { | 17284 | const msg = msg: { |
| 17136 | const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); | 17285 | const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); |
| 17137 | errdefer msg.destroy(sema.gpa); | 17286 | errdefer msg.destroy(sema.gpa); |
| 17138 | try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)}); | 17287 | try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)}); |
| 17139 | break :msg msg; | 17288 | break :msg msg; |
| 17140 | }; | 17289 | }; |
| 17141 | return sema.failWithOwnedErrorMsg(block, msg); | 17290 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | @@ -17146,7 +17295,7 @@ fn analyzeCmpUnionTag( | ... | @@ -17146,7 +17295,7 @@ fn analyzeCmpUnionTag( |
| 17146 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); | 17295 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); |
| 17147 | 17296 | ||
| 17148 | if (try sema.resolveValue(coerced_tag)) |enum_val| { | 17297 | if (try sema.resolveValue(coerced_tag)) |enum_val| { |
| 17149 | if (enum_val.isUndef(mod)) return mod.undefRef(Type.bool); | 17298 | if (enum_val.isUndef(mod)) return pt.undefRef(Type.bool); |
| 17150 | const field_ty = union_ty.unionFieldType(enum_val, mod).?; | 17299 | const field_ty = union_ty.unionFieldType(enum_val, mod).?; |
| 17151 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | 17300 | if (field_ty.zigTypeTag(mod) == .NoReturn) { |
| 17152 | return .bool_false; | 17301 | return .bool_false; |
| ... | @@ -17187,7 +17336,8 @@ fn analyzeCmp( | ... | @@ -17187,7 +17336,8 @@ fn analyzeCmp( |
| 17187 | rhs_src: LazySrcLoc, | 17336 | rhs_src: LazySrcLoc, |
| 17188 | is_equality_cmp: bool, | 17337 | is_equality_cmp: bool, |
| 17189 | ) CompileError!Air.Inst.Ref { | 17338 | ) CompileError!Air.Inst.Ref { |
| 17190 | const mod = sema.mod; | 17339 | const pt = sema.pt; |
| 17340 | const mod = pt.zcu; | ||
| 17191 | const lhs_ty = sema.typeOf(lhs); | 17341 | const lhs_ty = sema.typeOf(lhs); |
| 17192 | const rhs_ty = sema.typeOf(rhs); | 17342 | const rhs_ty = sema.typeOf(rhs); |
| 17193 | if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) { | 17343 | if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) { |
| ... | @@ -17215,7 +17365,7 @@ fn analyzeCmp( | ... | @@ -17215,7 +17365,7 @@ fn analyzeCmp( |
| 17215 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); | 17365 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 17216 | if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) { | 17366 | if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) { |
| 17217 | return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{ | 17367 | return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{ |
| 17218 | compareOperatorName(op), resolved_type.fmt(mod), | 17368 | compareOperatorName(op), resolved_type.fmt(pt), |
| 17219 | }); | 17369 | }); |
| 17220 | } | 17370 | } |
| 17221 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 17371 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| ... | @@ -17244,13 +17394,14 @@ fn cmpSelf( | ... | @@ -17244,13 +17394,14 @@ fn cmpSelf( |
| 17244 | lhs_src: LazySrcLoc, | 17394 | lhs_src: LazySrcLoc, |
| 17245 | rhs_src: LazySrcLoc, | 17395 | rhs_src: LazySrcLoc, |
| 17246 | ) CompileError!Air.Inst.Ref { | 17396 | ) CompileError!Air.Inst.Ref { |
| 17247 | const mod = sema.mod; | 17397 | const pt = sema.pt; |
| 17398 | const mod = pt.zcu; | ||
| 17248 | const resolved_type = sema.typeOf(casted_lhs); | 17399 | const resolved_type = sema.typeOf(casted_lhs); |
| 17249 | const runtime_src: LazySrcLoc = src: { | 17400 | const runtime_src: LazySrcLoc = src: { |
| 17250 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { | 17401 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { |
| 17251 | if (lhs_val.isUndef(mod)) return mod.undefRef(Type.bool); | 17402 | if (lhs_val.isUndef(mod)) return pt.undefRef(Type.bool); |
| 17252 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { | 17403 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 17253 | if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool); | 17404 | if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool); |
| 17254 | 17405 | ||
| 17255 | if (resolved_type.zigTypeTag(mod) == .Vector) { | 17406 | if (resolved_type.zigTypeTag(mod) == .Vector) { |
| 17256 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type); | 17407 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type); |
| ... | @@ -17273,7 +17424,7 @@ fn cmpSelf( | ... | @@ -17273,7 +17424,7 @@ fn cmpSelf( |
| 17273 | // bool eq/neq more efficiently. | 17424 | // bool eq/neq more efficiently. |
| 17274 | if (resolved_type.zigTypeTag(mod) == .Bool) { | 17425 | if (resolved_type.zigTypeTag(mod) == .Bool) { |
| 17275 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { | 17426 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 17276 | if (rhs_val.isUndef(mod)) return mod.undefRef(Type.bool); | 17427 | if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool); |
| 17277 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src); | 17428 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src); |
| 17278 | } | 17429 | } |
| 17279 | } | 17430 | } |
| ... | @@ -17310,24 +17461,24 @@ fn runtimeBoolCmp( | ... | @@ -17310,24 +17461,24 @@ fn runtimeBoolCmp( |
| 17310 | } | 17461 | } |
| 17311 | 17462 | ||
| 17312 | fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 17463 | fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 17313 | const mod = sema.mod; | 17464 | const pt = sema.pt; |
| 17314 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 17465 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 17315 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 17466 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 17316 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); | 17467 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 17317 | switch (ty.zigTypeTag(mod)) { | 17468 | switch (ty.zigTypeTag(pt.zcu)) { |
| 17318 | .Fn, | 17469 | .Fn, |
| 17319 | .NoReturn, | 17470 | .NoReturn, |
| 17320 | .Undefined, | 17471 | .Undefined, |
| 17321 | .Null, | 17472 | .Null, |
| 17322 | .Opaque, | 17473 | .Opaque, |
| 17323 | => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(mod)}), | 17474 | => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(pt)}), |
| 17324 | 17475 | ||
| 17325 | .Type, | 17476 | .Type, |
| 17326 | .EnumLiteral, | 17477 | .EnumLiteral, |
| 17327 | .ComptimeFloat, | 17478 | .ComptimeFloat, |
| 17328 | .ComptimeInt, | 17479 | .ComptimeInt, |
| 17329 | .Void, | 17480 | .Void, |
| 17330 | => return mod.intRef(Type.comptime_int, 0), | 17481 | => return pt.intRef(Type.comptime_int, 0), |
| 17331 | 17482 | ||
| 17332 | .Bool, | 17483 | .Bool, |
| 17333 | .Int, | 17484 | .Int, |
| ... | @@ -17345,12 +17496,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -17345,12 +17496,13 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 17345 | .AnyFrame, | 17496 | .AnyFrame, |
| 17346 | => {}, | 17497 | => {}, |
| 17347 | } | 17498 | } |
| 17348 | const val = try ty.lazyAbiSize(mod); | 17499 | const val = try ty.lazyAbiSize(pt); |
| 17349 | return Air.internedToRef(val.toIntern()); | 17500 | return Air.internedToRef(val.toIntern()); |
| 17350 | } | 17501 | } |
| 17351 | 17502 | ||
| 17352 | fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 17503 | fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 17353 | const mod = sema.mod; | 17504 | const pt = sema.pt; |
| 17505 | const mod = pt.zcu; | ||
| 17354 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 17506 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 17355 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 17507 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 17356 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); | 17508 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| ... | @@ -17360,14 +17512,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -17360,14 +17512,14 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17360 | .Undefined, | 17512 | .Undefined, |
| 17361 | .Null, | 17513 | .Null, |
| 17362 | .Opaque, | 17514 | .Opaque, |
| 17363 | => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(mod)}), | 17515 | => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(pt)}), |
| 17364 | 17516 | ||
| 17365 | .Type, | 17517 | .Type, |
| 17366 | .EnumLiteral, | 17518 | .EnumLiteral, |
| 17367 | .ComptimeFloat, | 17519 | .ComptimeFloat, |
| 17368 | .ComptimeInt, | 17520 | .ComptimeInt, |
| 17369 | .Void, | 17521 | .Void, |
| 17370 | => return mod.intRef(Type.comptime_int, 0), | 17522 | => return pt.intRef(Type.comptime_int, 0), |
| 17371 | 17523 | ||
| 17372 | .Bool, | 17524 | .Bool, |
| 17373 | .Int, | 17525 | .Int, |
| ... | @@ -17385,8 +17537,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -17385,8 +17537,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17385 | .AnyFrame, | 17537 | .AnyFrame, |
| 17386 | => {}, | 17538 | => {}, |
| 17387 | } | 17539 | } |
| 17388 | const bit_size = try operand_ty.bitSizeAdvanced(mod, .sema); | 17540 | const bit_size = try operand_ty.bitSizeAdvanced(pt, .sema); |
| 17389 | return mod.intRef(Type.comptime_int, bit_size); | 17541 | return pt.intRef(Type.comptime_int, bit_size); |
| 17390 | } | 17542 | } |
| 17391 | 17543 | ||
| 17392 | fn zirThis( | 17544 | fn zirThis( |
| ... | @@ -17394,14 +17546,16 @@ fn zirThis( | ... | @@ -17394,14 +17546,16 @@ fn zirThis( |
| 17394 | block: *Block, | 17546 | block: *Block, |
| 17395 | extended: Zir.Inst.Extended.InstData, | 17547 | extended: Zir.Inst.Extended.InstData, |
| 17396 | ) CompileError!Air.Inst.Ref { | 17548 | ) CompileError!Air.Inst.Ref { |
| 17397 | const mod = sema.mod; | 17549 | const pt = sema.pt; |
| 17550 | const mod = pt.zcu; | ||
| 17398 | const this_decl_index = mod.namespacePtr(block.namespace).decl_index; | 17551 | const this_decl_index = mod.namespacePtr(block.namespace).decl_index; |
| 17399 | const src = block.nodeOffset(@bitCast(extended.operand)); | 17552 | const src = block.nodeOffset(@bitCast(extended.operand)); |
| 17400 | return sema.analyzeDeclVal(block, src, this_decl_index); | 17553 | return sema.analyzeDeclVal(block, src, this_decl_index); |
| 17401 | } | 17554 | } |
| 17402 | 17555 | ||
| 17403 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 17556 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 17404 | const mod = sema.mod; | 17557 | const pt = sema.pt; |
| 17558 | const mod = pt.zcu; | ||
| 17405 | const ip = &mod.intern_pool; | 17559 | const ip = &mod.intern_pool; |
| 17406 | const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod); | 17560 | const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod); |
| 17407 | 17561 | ||
| ... | @@ -17489,7 +17643,7 @@ fn zirRetAddr( | ... | @@ -17489,7 +17643,7 @@ fn zirRetAddr( |
| 17489 | _ = extended; | 17643 | _ = extended; |
| 17490 | if (block.is_comptime) { | 17644 | if (block.is_comptime) { |
| 17491 | // TODO: we could give a meaningful lazy value here. #14938 | 17645 | // TODO: we could give a meaningful lazy value here. #14938 |
| 17492 | return sema.mod.intRef(Type.usize, 0); | 17646 | return sema.pt.intRef(Type.usize, 0); |
| 17493 | } else { | 17647 | } else { |
| 17494 | return block.addNoOp(.ret_addr); | 17648 | return block.addNoOp(.ret_addr); |
| 17495 | } | 17649 | } |
| ... | @@ -17514,7 +17668,8 @@ fn zirBuiltinSrc( | ... | @@ -17514,7 +17668,8 @@ fn zirBuiltinSrc( |
| 17514 | const tracy = trace(@src()); | 17668 | const tracy = trace(@src()); |
| 17515 | defer tracy.end(); | 17669 | defer tracy.end(); |
| 17516 | 17670 | ||
| 17517 | const mod = sema.mod; | 17671 | const pt = sema.pt; |
| 17672 | const mod = pt.zcu; | ||
| 17518 | const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data; | 17673 | const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data; |
| 17519 | const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index); | 17674 | const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index); |
| 17520 | const ip = &mod.intern_pool; | 17675 | const ip = &mod.intern_pool; |
| ... | @@ -17522,43 +17677,43 @@ fn zirBuiltinSrc( | ... | @@ -17522,43 +17677,43 @@ fn zirBuiltinSrc( |
| 17522 | 17677 | ||
| 17523 | const func_name_val = v: { | 17678 | const func_name_val = v: { |
| 17524 | const func_name_len = fn_owner_decl.name.length(ip); | 17679 | const func_name_len = fn_owner_decl.name.length(ip); |
| 17525 | const array_ty = try ip.get(gpa, .{ .array_type = .{ | 17680 | const array_ty = try pt.intern(.{ .array_type = .{ |
| 17526 | .len = func_name_len, | 17681 | .len = func_name_len, |
| 17527 | .sentinel = .zero_u8, | 17682 | .sentinel = .zero_u8, |
| 17528 | .child = .u8_type, | 17683 | .child = .u8_type, |
| 17529 | } }); | 17684 | } }); |
| 17530 | break :v try ip.get(gpa, .{ .slice = .{ | 17685 | break :v try pt.intern(.{ .slice = .{ |
| 17531 | .ty = .slice_const_u8_sentinel_0_type, | 17686 | .ty = .slice_const_u8_sentinel_0_type, |
| 17532 | .ptr = try ip.get(gpa, .{ .ptr = .{ | 17687 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17533 | .ty = .manyptr_const_u8_sentinel_0_type, | 17688 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17534 | .base_addr = .{ .anon_decl = .{ | 17689 | .base_addr = .{ .anon_decl = .{ |
| 17535 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17690 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 17536 | .val = try ip.get(gpa, .{ .aggregate = .{ | 17691 | .val = try pt.intern(.{ .aggregate = .{ |
| 17537 | .ty = array_ty, | 17692 | .ty = array_ty, |
| 17538 | .storage = .{ .bytes = fn_owner_decl.name.toString() }, | 17693 | .storage = .{ .bytes = fn_owner_decl.name.toString() }, |
| 17539 | } }), | 17694 | } }), |
| 17540 | } }, | 17695 | } }, |
| 17541 | .byte_offset = 0, | 17696 | .byte_offset = 0, |
| 17542 | } }), | 17697 | } }), |
| 17543 | .len = (try mod.intValue(Type.usize, func_name_len)).toIntern(), | 17698 | .len = (try pt.intValue(Type.usize, func_name_len)).toIntern(), |
| 17544 | } }); | 17699 | } }); |
| 17545 | }; | 17700 | }; |
| 17546 | 17701 | ||
| 17547 | const file_name_val = v: { | 17702 | const file_name_val = v: { |
| 17548 | // The compiler must not call realpath anywhere. | 17703 | // The compiler must not call realpath anywhere. |
| 17549 | const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena); | 17704 | const file_name = try fn_owner_decl.getFileScope(mod).fullPath(sema.arena); |
| 17550 | const array_ty = try ip.get(gpa, .{ .array_type = .{ | 17705 | const array_ty = try pt.intern(.{ .array_type = .{ |
| 17551 | .len = file_name.len, | 17706 | .len = file_name.len, |
| 17552 | .sentinel = .zero_u8, | 17707 | .sentinel = .zero_u8, |
| 17553 | .child = .u8_type, | 17708 | .child = .u8_type, |
| 17554 | } }); | 17709 | } }); |
| 17555 | break :v try ip.get(gpa, .{ .slice = .{ | 17710 | break :v try pt.intern(.{ .slice = .{ |
| 17556 | .ty = .slice_const_u8_sentinel_0_type, | 17711 | .ty = .slice_const_u8_sentinel_0_type, |
| 17557 | .ptr = try ip.get(gpa, .{ .ptr = .{ | 17712 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17558 | .ty = .manyptr_const_u8_sentinel_0_type, | 17713 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17559 | .base_addr = .{ .anon_decl = .{ | 17714 | .base_addr = .{ .anon_decl = .{ |
| 17560 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17715 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 17561 | .val = try ip.get(gpa, .{ .aggregate = .{ | 17716 | .val = try pt.intern(.{ .aggregate = .{ |
| 17562 | .ty = array_ty, | 17717 | .ty = array_ty, |
| 17563 | .storage = .{ | 17718 | .storage = .{ |
| 17564 | .bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls), | 17719 | .bytes = try ip.getOrPutString(gpa, file_name, .maybe_embedded_nulls), |
| ... | @@ -17567,35 +17722,36 @@ fn zirBuiltinSrc( | ... | @@ -17567,35 +17722,36 @@ fn zirBuiltinSrc( |
| 17567 | } }, | 17722 | } }, |
| 17568 | .byte_offset = 0, | 17723 | .byte_offset = 0, |
| 17569 | } }), | 17724 | } }), |
| 17570 | .len = (try mod.intValue(Type.usize, file_name.len)).toIntern(), | 17725 | .len = (try pt.intValue(Type.usize, file_name.len)).toIntern(), |
| 17571 | } }); | 17726 | } }); |
| 17572 | }; | 17727 | }; |
| 17573 | 17728 | ||
| 17574 | const src_loc_ty = try mod.getBuiltinType("SourceLocation"); | 17729 | const src_loc_ty = try pt.getBuiltinType("SourceLocation"); |
| 17575 | const fields = .{ | 17730 | const fields = .{ |
| 17576 | // file: [:0]const u8, | 17731 | // file: [:0]const u8, |
| 17577 | file_name_val, | 17732 | file_name_val, |
| 17578 | // fn_name: [:0]const u8, | 17733 | // fn_name: [:0]const u8, |
| 17579 | func_name_val, | 17734 | func_name_val, |
| 17580 | // line: u32, | 17735 | // line: u32, |
| 17581 | (try mod.intValue(Type.u32, extra.line + 1)).toIntern(), | 17736 | (try pt.intValue(Type.u32, extra.line + 1)).toIntern(), |
| 17582 | // column: u32, | 17737 | // column: u32, |
| 17583 | (try mod.intValue(Type.u32, extra.column + 1)).toIntern(), | 17738 | (try pt.intValue(Type.u32, extra.column + 1)).toIntern(), |
| 17584 | }; | 17739 | }; |
| 17585 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 17740 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 17586 | .ty = src_loc_ty.toIntern(), | 17741 | .ty = src_loc_ty.toIntern(), |
| 17587 | .storage = .{ .elems = &fields }, | 17742 | .storage = .{ .elems = &fields }, |
| 17588 | } }))); | 17743 | } }))); |
| 17589 | } | 17744 | } |
| 17590 | 17745 | ||
| 17591 | fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 17746 | fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 17592 | const mod = sema.mod; | 17747 | const pt = sema.pt; |
| 17748 | const mod = pt.zcu; | ||
| 17593 | const gpa = sema.gpa; | 17749 | const gpa = sema.gpa; |
| 17594 | const ip = &mod.intern_pool; | 17750 | const ip = &mod.intern_pool; |
| 17595 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 17751 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 17596 | const src = block.nodeOffset(inst_data.src_node); | 17752 | const src = block.nodeOffset(inst_data.src_node); |
| 17597 | const ty = try sema.resolveType(block, src, inst_data.operand); | 17753 | const ty = try sema.resolveType(block, src, inst_data.operand); |
| 17598 | const type_info_ty = try mod.getBuiltinType("Type"); | 17754 | const type_info_ty = try pt.getBuiltinType("Type"); |
| 17599 | const type_info_tag_ty = type_info_ty.unionTagType(mod).?; | 17755 | const type_info_tag_ty = type_info_ty.unionTagType(mod).?; |
| 17600 | 17756 | ||
| 17601 | if (ty.typeDeclInst(mod)) |type_decl_inst| { | 17757 | if (ty.typeDeclInst(mod)) |type_decl_inst| { |
| ... | @@ -17612,9 +17768,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17612,9 +17768,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17612 | .Undefined, | 17768 | .Undefined, |
| 17613 | .Null, | 17769 | .Null, |
| 17614 | .EnumLiteral, | 17770 | .EnumLiteral, |
| 17615 | => |type_info_tag| return Air.internedToRef((try mod.intern(.{ .un = .{ | 17771 | => |type_info_tag| return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17616 | .ty = type_info_ty.toIntern(), | 17772 | .ty = type_info_ty.toIntern(), |
| 17617 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(), | 17773 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(), |
| 17618 | .val = .void_value, | 17774 | .val = .void_value, |
| 17619 | } }))), | 17775 | } }))), |
| 17620 | .Fn => { | 17776 | .Fn => { |
| ... | @@ -17643,8 +17799,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17643,8 +17799,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17643 | for (param_vals, 0..) |*param_val, i| { | 17799 | for (param_vals, 0..) |*param_val, i| { |
| 17644 | const param_ty = func_ty_info.param_types.get(ip)[i]; | 17800 | const param_ty = func_ty_info.param_types.get(ip)[i]; |
| 17645 | const is_generic = param_ty == .generic_poison_type; | 17801 | const is_generic = param_ty == .generic_poison_type; |
| 17646 | const param_ty_val = try ip.get(gpa, .{ .opt = .{ | 17802 | const param_ty_val = try pt.intern(.{ .opt = .{ |
| 17647 | .ty = try ip.get(gpa, .{ .opt_type = .type_type }), | 17803 | .ty = try pt.intern(.{ .opt_type = .type_type }), |
| 17648 | .val = if (is_generic) .none else param_ty, | 17804 | .val = if (is_generic) .none else param_ty, |
| 17649 | } }); | 17805 | } }); |
| 17650 | 17806 | ||
| ... | @@ -17661,22 +17817,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17661,22 +17817,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17661 | // type: ?type, | 17817 | // type: ?type, |
| 17662 | param_ty_val, | 17818 | param_ty_val, |
| 17663 | }; | 17819 | }; |
| 17664 | param_val.* = try mod.intern(.{ .aggregate = .{ | 17820 | param_val.* = try pt.intern(.{ .aggregate = .{ |
| 17665 | .ty = param_info_ty.toIntern(), | 17821 | .ty = param_info_ty.toIntern(), |
| 17666 | .storage = .{ .elems = &param_fields }, | 17822 | .storage = .{ .elems = &param_fields }, |
| 17667 | } }); | 17823 | } }); |
| 17668 | } | 17824 | } |
| 17669 | 17825 | ||
| 17670 | const args_val = v: { | 17826 | const args_val = v: { |
| 17671 | const new_decl_ty = try mod.arrayType(.{ | 17827 | const new_decl_ty = try pt.arrayType(.{ |
| 17672 | .len = param_vals.len, | 17828 | .len = param_vals.len, |
| 17673 | .child = param_info_ty.toIntern(), | 17829 | .child = param_info_ty.toIntern(), |
| 17674 | }); | 17830 | }); |
| 17675 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 17831 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 17676 | .ty = new_decl_ty.toIntern(), | 17832 | .ty = new_decl_ty.toIntern(), |
| 17677 | .storage = .{ .elems = param_vals }, | 17833 | .storage = .{ .elems = param_vals }, |
| 17678 | } }); | 17834 | } }); |
| 17679 | const slice_ty = (try mod.ptrTypeSema(.{ | 17835 | const slice_ty = (try pt.ptrTypeSema(.{ |
| 17680 | .child = param_info_ty.toIntern(), | 17836 | .child = param_info_ty.toIntern(), |
| 17681 | .flags = .{ | 17837 | .flags = .{ |
| 17682 | .size = .Slice, | 17838 | .size = .Slice, |
| ... | @@ -17684,9 +17840,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17684,9 +17840,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17684 | }, | 17840 | }, |
| 17685 | })).toIntern(); | 17841 | })).toIntern(); |
| 17686 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 17842 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); |
| 17687 | break :v try mod.intern(.{ .slice = .{ | 17843 | break :v try pt.intern(.{ .slice = .{ |
| 17688 | .ty = slice_ty, | 17844 | .ty = slice_ty, |
| 17689 | .ptr = try mod.intern(.{ .ptr = .{ | 17845 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17690 | .ty = manyptr_ty, | 17846 | .ty = manyptr_ty, |
| 17691 | .base_addr = .{ .anon_decl = .{ | 17847 | .base_addr = .{ .anon_decl = .{ |
| 17692 | .orig_ty = manyptr_ty, | 17848 | .orig_ty = manyptr_ty, |
| ... | @@ -17694,23 +17850,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17694,23 +17850,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17694 | } }, | 17850 | } }, |
| 17695 | .byte_offset = 0, | 17851 | .byte_offset = 0, |
| 17696 | } }), | 17852 | } }), |
| 17697 | .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(), | 17853 | .len = (try pt.intValue(Type.usize, param_vals.len)).toIntern(), |
| 17698 | } }); | 17854 | } }); |
| 17699 | }; | 17855 | }; |
| 17700 | 17856 | ||
| 17701 | const ret_ty_opt = try mod.intern(.{ .opt = .{ | 17857 | const ret_ty_opt = try pt.intern(.{ .opt = .{ |
| 17702 | .ty = try ip.get(gpa, .{ .opt_type = .type_type }), | 17858 | .ty = try pt.intern(.{ .opt_type = .type_type }), |
| 17703 | .val = if (func_ty_info.return_type == .generic_poison_type) | 17859 | .val = if (func_ty_info.return_type == .generic_poison_type) |
| 17704 | .none | 17860 | .none |
| 17705 | else | 17861 | else |
| 17706 | func_ty_info.return_type, | 17862 | func_ty_info.return_type, |
| 17707 | } }); | 17863 | } }); |
| 17708 | 17864 | ||
| 17709 | const callconv_ty = try mod.getBuiltinType("CallingConvention"); | 17865 | const callconv_ty = try pt.getBuiltinType("CallingConvention"); |
| 17710 | 17866 | ||
| 17711 | const field_values = .{ | 17867 | const field_values = .{ |
| 17712 | // calling_convention: CallingConvention, | 17868 | // calling_convention: CallingConvention, |
| 17713 | (try mod.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(), | 17869 | (try pt.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(), |
| 17714 | // is_generic: bool, | 17870 | // is_generic: bool, |
| 17715 | Value.makeBool(func_ty_info.is_generic).toIntern(), | 17871 | Value.makeBool(func_ty_info.is_generic).toIntern(), |
| 17716 | // is_var_args: bool, | 17872 | // is_var_args: bool, |
| ... | @@ -17720,10 +17876,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17720,10 +17876,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17720 | // args: []const Fn.Param, | 17876 | // args: []const Fn.Param, |
| 17721 | args_val, | 17877 | args_val, |
| 17722 | }; | 17878 | }; |
| 17723 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 17879 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17724 | .ty = type_info_ty.toIntern(), | 17880 | .ty = type_info_ty.toIntern(), |
| 17725 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(), | 17881 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Fn))).toIntern(), |
| 17726 | .val = try mod.intern(.{ .aggregate = .{ | 17882 | .val = try pt.intern(.{ .aggregate = .{ |
| 17727 | .ty = fn_info_ty.toIntern(), | 17883 | .ty = fn_info_ty.toIntern(), |
| 17728 | .storage = .{ .elems = &field_values }, | 17884 | .storage = .{ .elems = &field_values }, |
| 17729 | } }), | 17885 | } }), |
| ... | @@ -17740,18 +17896,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17740,18 +17896,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17740 | const int_info_decl = mod.declPtr(int_info_decl_index); | 17896 | const int_info_decl = mod.declPtr(int_info_decl_index); |
| 17741 | const int_info_ty = int_info_decl.val.toType(); | 17897 | const int_info_ty = int_info_decl.val.toType(); |
| 17742 | 17898 | ||
| 17743 | const signedness_ty = try mod.getBuiltinType("Signedness"); | 17899 | const signedness_ty = try pt.getBuiltinType("Signedness"); |
| 17744 | const info = ty.intInfo(mod); | 17900 | const info = ty.intInfo(mod); |
| 17745 | const field_values = .{ | 17901 | const field_values = .{ |
| 17746 | // signedness: Signedness, | 17902 | // signedness: Signedness, |
| 17747 | (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), | 17903 | (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), |
| 17748 | // bits: u16, | 17904 | // bits: u16, |
| 17749 | (try mod.intValue(Type.u16, info.bits)).toIntern(), | 17905 | (try pt.intValue(Type.u16, info.bits)).toIntern(), |
| 17750 | }; | 17906 | }; |
| 17751 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 17907 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17752 | .ty = type_info_ty.toIntern(), | 17908 | .ty = type_info_ty.toIntern(), |
| 17753 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(), | 17909 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Int))).toIntern(), |
| 17754 | .val = try mod.intern(.{ .aggregate = .{ | 17910 | .val = try pt.intern(.{ .aggregate = .{ |
| 17755 | .ty = int_info_ty.toIntern(), | 17911 | .ty = int_info_ty.toIntern(), |
| 17756 | .storage = .{ .elems = &field_values }, | 17912 | .storage = .{ .elems = &field_values }, |
| 17757 | } }), | 17913 | } }), |
| ... | @@ -17770,12 +17926,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17770,12 +17926,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17770 | 17926 | ||
| 17771 | const field_vals = .{ | 17927 | const field_vals = .{ |
| 17772 | // bits: u16, | 17928 | // bits: u16, |
| 17773 | (try mod.intValue(Type.u16, ty.bitSize(mod))).toIntern(), | 17929 | (try pt.intValue(Type.u16, ty.bitSize(pt))).toIntern(), |
| 17774 | }; | 17930 | }; |
| 17775 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 17931 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17776 | .ty = type_info_ty.toIntern(), | 17932 | .ty = type_info_ty.toIntern(), |
| 17777 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(), | 17933 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Float))).toIntern(), |
| 17778 | .val = try mod.intern(.{ .aggregate = .{ | 17934 | .val = try pt.intern(.{ .aggregate = .{ |
| 17779 | .ty = float_info_ty.toIntern(), | 17935 | .ty = float_info_ty.toIntern(), |
| 17780 | .storage = .{ .elems = &field_vals }, | 17936 | .storage = .{ .elems = &field_vals }, |
| 17781 | } }), | 17937 | } }), |
| ... | @@ -17784,16 +17940,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17784,16 +17940,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17784 | .Pointer => { | 17940 | .Pointer => { |
| 17785 | const info = ty.ptrInfo(mod); | 17941 | const info = ty.ptrInfo(mod); |
| 17786 | const alignment = if (info.flags.alignment.toByteUnits()) |alignment| | 17942 | const alignment = if (info.flags.alignment.toByteUnits()) |alignment| |
| 17787 | try mod.intValue(Type.comptime_int, alignment) | 17943 | try pt.intValue(Type.comptime_int, alignment) |
| 17788 | else | 17944 | else |
| 17789 | try Type.fromInterned(info.child).lazyAbiAlignment(mod); | 17945 | try Type.fromInterned(info.child).lazyAbiAlignment(pt); |
| 17790 | 17946 | ||
| 17791 | const addrspace_ty = try mod.getBuiltinType("AddressSpace"); | 17947 | const addrspace_ty = try pt.getBuiltinType("AddressSpace"); |
| 17792 | const pointer_ty = t: { | 17948 | const pointer_ty = t: { |
| 17793 | const decl_index = (try sema.namespaceLookup( | 17949 | const decl_index = (try sema.namespaceLookup( |
| 17794 | block, | 17950 | block, |
| 17795 | src, | 17951 | src, |
| 17796 | (try mod.getBuiltinType("Type")).getNamespaceIndex(mod), | 17952 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 17797 | try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls), | 17953 | try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls), |
| 17798 | )).?; | 17954 | )).?; |
| 17799 | try sema.ensureDeclAnalyzed(decl_index); | 17955 | try sema.ensureDeclAnalyzed(decl_index); |
| ... | @@ -17814,7 +17970,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17814,7 +17970,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17814 | 17970 | ||
| 17815 | const field_values = .{ | 17971 | const field_values = .{ |
| 17816 | // size: Size, | 17972 | // size: Size, |
| 17817 | (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(), | 17973 | (try pt.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(), |
| 17818 | // is_const: bool, | 17974 | // is_const: bool, |
| 17819 | Value.makeBool(info.flags.is_const).toIntern(), | 17975 | Value.makeBool(info.flags.is_const).toIntern(), |
| 17820 | // is_volatile: bool, | 17976 | // is_volatile: bool, |
| ... | @@ -17822,7 +17978,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17822,7 +17978,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17822 | // alignment: comptime_int, | 17978 | // alignment: comptime_int, |
| 17823 | alignment.toIntern(), | 17979 | alignment.toIntern(), |
| 17824 | // address_space: AddressSpace | 17980 | // address_space: AddressSpace |
| 17825 | (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(), | 17981 | (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(), |
| 17826 | // child: type, | 17982 | // child: type, |
| 17827 | info.child, | 17983 | info.child, |
| 17828 | // is_allowzero: bool, | 17984 | // is_allowzero: bool, |
| ... | @@ -17833,10 +17989,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17833,10 +17989,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17833 | else => Value.fromInterned(info.sentinel), | 17989 | else => Value.fromInterned(info.sentinel), |
| 17834 | })).toIntern(), | 17990 | })).toIntern(), |
| 17835 | }; | 17991 | }; |
| 17836 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 17992 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17837 | .ty = type_info_ty.toIntern(), | 17993 | .ty = type_info_ty.toIntern(), |
| 17838 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(), | 17994 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Pointer))).toIntern(), |
| 17839 | .val = try mod.intern(.{ .aggregate = .{ | 17995 | .val = try pt.intern(.{ .aggregate = .{ |
| 17840 | .ty = pointer_ty.toIntern(), | 17996 | .ty = pointer_ty.toIntern(), |
| 17841 | .storage = .{ .elems = &field_values }, | 17997 | .storage = .{ .elems = &field_values }, |
| 17842 | } }), | 17998 | } }), |
| ... | @@ -17858,16 +18014,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17858,16 +18014,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17858 | const info = ty.arrayInfo(mod); | 18014 | const info = ty.arrayInfo(mod); |
| 17859 | const field_values = .{ | 18015 | const field_values = .{ |
| 17860 | // len: comptime_int, | 18016 | // len: comptime_int, |
| 17861 | (try mod.intValue(Type.comptime_int, info.len)).toIntern(), | 18017 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), |
| 17862 | // child: type, | 18018 | // child: type, |
| 17863 | info.elem_type.toIntern(), | 18019 | info.elem_type.toIntern(), |
| 17864 | // sentinel: ?*const anyopaque, | 18020 | // sentinel: ?*const anyopaque, |
| 17865 | (try sema.optRefValue(info.sentinel)).toIntern(), | 18021 | (try sema.optRefValue(info.sentinel)).toIntern(), |
| 17866 | }; | 18022 | }; |
| 17867 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18023 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17868 | .ty = type_info_ty.toIntern(), | 18024 | .ty = type_info_ty.toIntern(), |
| 17869 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(), | 18025 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Array))).toIntern(), |
| 17870 | .val = try mod.intern(.{ .aggregate = .{ | 18026 | .val = try pt.intern(.{ .aggregate = .{ |
| 17871 | .ty = array_field_ty.toIntern(), | 18027 | .ty = array_field_ty.toIntern(), |
| 17872 | .storage = .{ .elems = &field_values }, | 18028 | .storage = .{ .elems = &field_values }, |
| 17873 | } }), | 18029 | } }), |
| ... | @@ -17889,14 +18045,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17889,14 +18045,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17889 | const info = ty.arrayInfo(mod); | 18045 | const info = ty.arrayInfo(mod); |
| 17890 | const field_values = .{ | 18046 | const field_values = .{ |
| 17891 | // len: comptime_int, | 18047 | // len: comptime_int, |
| 17892 | (try mod.intValue(Type.comptime_int, info.len)).toIntern(), | 18048 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), |
| 17893 | // child: type, | 18049 | // child: type, |
| 17894 | info.elem_type.toIntern(), | 18050 | info.elem_type.toIntern(), |
| 17895 | }; | 18051 | }; |
| 17896 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18052 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17897 | .ty = type_info_ty.toIntern(), | 18053 | .ty = type_info_ty.toIntern(), |
| 17898 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(), | 18054 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Vector))).toIntern(), |
| 17899 | .val = try mod.intern(.{ .aggregate = .{ | 18055 | .val = try pt.intern(.{ .aggregate = .{ |
| 17900 | .ty = vector_field_ty.toIntern(), | 18056 | .ty = vector_field_ty.toIntern(), |
| 17901 | .storage = .{ .elems = &field_values }, | 18057 | .storage = .{ .elems = &field_values }, |
| 17902 | } }), | 18058 | } }), |
| ... | @@ -17919,10 +18075,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17919,10 +18075,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17919 | // child: type, | 18075 | // child: type, |
| 17920 | ty.optionalChild(mod).toIntern(), | 18076 | ty.optionalChild(mod).toIntern(), |
| 17921 | }; | 18077 | }; |
| 17922 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18078 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17923 | .ty = type_info_ty.toIntern(), | 18079 | .ty = type_info_ty.toIntern(), |
| 17924 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(), | 18080 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Optional))).toIntern(), |
| 17925 | .val = try mod.intern(.{ .aggregate = .{ | 18081 | .val = try pt.intern(.{ .aggregate = .{ |
| 17926 | .ty = optional_field_ty.toIntern(), | 18082 | .ty = optional_field_ty.toIntern(), |
| 17927 | .storage = .{ .elems = &field_values }, | 18083 | .storage = .{ .elems = &field_values }, |
| 17928 | } }), | 18084 | } }), |
| ... | @@ -17954,18 +18110,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17954,18 +18110,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17954 | const error_name = names.get(ip)[error_index]; | 18110 | const error_name = names.get(ip)[error_index]; |
| 17955 | const error_name_len = error_name.length(ip); | 18111 | const error_name_len = error_name.length(ip); |
| 17956 | const error_name_val = v: { | 18112 | const error_name_val = v: { |
| 17957 | const new_decl_ty = try mod.arrayType(.{ | 18113 | const new_decl_ty = try pt.arrayType(.{ |
| 17958 | .len = error_name_len, | 18114 | .len = error_name_len, |
| 17959 | .sentinel = .zero_u8, | 18115 | .sentinel = .zero_u8, |
| 17960 | .child = .u8_type, | 18116 | .child = .u8_type, |
| 17961 | }); | 18117 | }); |
| 17962 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18118 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 17963 | .ty = new_decl_ty.toIntern(), | 18119 | .ty = new_decl_ty.toIntern(), |
| 17964 | .storage = .{ .bytes = error_name.toString() }, | 18120 | .storage = .{ .bytes = error_name.toString() }, |
| 17965 | } }); | 18121 | } }); |
| 17966 | break :v try mod.intern(.{ .slice = .{ | 18122 | break :v try pt.intern(.{ .slice = .{ |
| 17967 | .ty = .slice_const_u8_sentinel_0_type, | 18123 | .ty = .slice_const_u8_sentinel_0_type, |
| 17968 | .ptr = try mod.intern(.{ .ptr = .{ | 18124 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17969 | .ty = .manyptr_const_u8_sentinel_0_type, | 18125 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17970 | .base_addr = .{ .anon_decl = .{ | 18126 | .base_addr = .{ .anon_decl = .{ |
| 17971 | .val = new_decl_val, | 18127 | .val = new_decl_val, |
| ... | @@ -17973,7 +18129,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17973,7 +18129,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17973 | } }, | 18129 | } }, |
| 17974 | .byte_offset = 0, | 18130 | .byte_offset = 0, |
| 17975 | } }), | 18131 | } }), |
| 17976 | .len = (try mod.intValue(Type.usize, error_name_len)).toIntern(), | 18132 | .len = (try pt.intValue(Type.usize, error_name_len)).toIntern(), |
| 17977 | } }); | 18133 | } }); |
| 17978 | }; | 18134 | }; |
| 17979 | 18135 | ||
| ... | @@ -17981,7 +18137,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17981,7 +18137,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17981 | // name: [:0]const u8, | 18137 | // name: [:0]const u8, |
| 17982 | error_name_val, | 18138 | error_name_val, |
| 17983 | }; | 18139 | }; |
| 17984 | field_val.* = try mod.intern(.{ .aggregate = .{ | 18140 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 17985 | .ty = error_field_ty.toIntern(), | 18141 | .ty = error_field_ty.toIntern(), |
| 17986 | .storage = .{ .elems = &error_field_fields }, | 18142 | .storage = .{ .elems = &error_field_fields }, |
| 17987 | } }); | 18143 | } }); |
| ... | @@ -17992,27 +18148,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17992,27 +18148,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17992 | }; | 18148 | }; |
| 17993 | 18149 | ||
| 17994 | // Build our ?[]const Error value | 18150 | // Build our ?[]const Error value |
| 17995 | const slice_errors_ty = try mod.ptrTypeSema(.{ | 18151 | const slice_errors_ty = try pt.ptrTypeSema(.{ |
| 17996 | .child = error_field_ty.toIntern(), | 18152 | .child = error_field_ty.toIntern(), |
| 17997 | .flags = .{ | 18153 | .flags = .{ |
| 17998 | .size = .Slice, | 18154 | .size = .Slice, |
| 17999 | .is_const = true, | 18155 | .is_const = true, |
| 18000 | }, | 18156 | }, |
| 18001 | }); | 18157 | }); |
| 18002 | const opt_slice_errors_ty = try mod.optionalType(slice_errors_ty.toIntern()); | 18158 | const opt_slice_errors_ty = try pt.optionalType(slice_errors_ty.toIntern()); |
| 18003 | const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: { | 18159 | const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: { |
| 18004 | const array_errors_ty = try mod.arrayType(.{ | 18160 | const array_errors_ty = try pt.arrayType(.{ |
| 18005 | .len = vals.len, | 18161 | .len = vals.len, |
| 18006 | .child = error_field_ty.toIntern(), | 18162 | .child = error_field_ty.toIntern(), |
| 18007 | }); | 18163 | }); |
| 18008 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18164 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18009 | .ty = array_errors_ty.toIntern(), | 18165 | .ty = array_errors_ty.toIntern(), |
| 18010 | .storage = .{ .elems = vals }, | 18166 | .storage = .{ .elems = vals }, |
| 18011 | } }); | 18167 | } }); |
| 18012 | const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(); | 18168 | const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(); |
| 18013 | break :v try mod.intern(.{ .slice = .{ | 18169 | break :v try pt.intern(.{ .slice = .{ |
| 18014 | .ty = slice_errors_ty.toIntern(), | 18170 | .ty = slice_errors_ty.toIntern(), |
| 18015 | .ptr = try mod.intern(.{ .ptr = .{ | 18171 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18016 | .ty = manyptr_errors_ty, | 18172 | .ty = manyptr_errors_ty, |
| 18017 | .base_addr = .{ .anon_decl = .{ | 18173 | .base_addr = .{ .anon_decl = .{ |
| 18018 | .orig_ty = manyptr_errors_ty, | 18174 | .orig_ty = manyptr_errors_ty, |
| ... | @@ -18020,18 +18176,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18020,18 +18176,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18020 | } }, | 18176 | } }, |
| 18021 | .byte_offset = 0, | 18177 | .byte_offset = 0, |
| 18022 | } }), | 18178 | } }), |
| 18023 | .len = (try mod.intValue(Type.usize, vals.len)).toIntern(), | 18179 | .len = (try pt.intValue(Type.usize, vals.len)).toIntern(), |
| 18024 | } }); | 18180 | } }); |
| 18025 | } else .none; | 18181 | } else .none; |
| 18026 | const errors_val = try mod.intern(.{ .opt = .{ | 18182 | const errors_val = try pt.intern(.{ .opt = .{ |
| 18027 | .ty = opt_slice_errors_ty.toIntern(), | 18183 | .ty = opt_slice_errors_ty.toIntern(), |
| 18028 | .val = errors_payload_val, | 18184 | .val = errors_payload_val, |
| 18029 | } }); | 18185 | } }); |
| 18030 | 18186 | ||
| 18031 | // Construct Type{ .ErrorSet = errors_val } | 18187 | // Construct Type{ .ErrorSet = errors_val } |
| 18032 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18188 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18033 | .ty = type_info_ty.toIntern(), | 18189 | .ty = type_info_ty.toIntern(), |
| 18034 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(), | 18190 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorSet))).toIntern(), |
| 18035 | .val = errors_val, | 18191 | .val = errors_val, |
| 18036 | } }))); | 18192 | } }))); |
| 18037 | }, | 18193 | }, |
| ... | @@ -18054,10 +18210,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18054,10 +18210,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18054 | // payload: type, | 18210 | // payload: type, |
| 18055 | ty.errorUnionPayload(mod).toIntern(), | 18211 | ty.errorUnionPayload(mod).toIntern(), |
| 18056 | }; | 18212 | }; |
| 18057 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18213 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18058 | .ty = type_info_ty.toIntern(), | 18214 | .ty = type_info_ty.toIntern(), |
| 18059 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(), | 18215 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.ErrorUnion))).toIntern(), |
| 18060 | .val = try mod.intern(.{ .aggregate = .{ | 18216 | .val = try pt.intern(.{ .aggregate = .{ |
| 18061 | .ty = error_union_field_ty.toIntern(), | 18217 | .ty = error_union_field_ty.toIntern(), |
| 18062 | .storage = .{ .elems = &field_values }, | 18218 | .storage = .{ .elems = &field_values }, |
| 18063 | } }), | 18219 | } }), |
| ... | @@ -18082,30 +18238,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18082,30 +18238,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18082 | for (enum_field_vals, 0..) |*field_val, tag_index| { | 18238 | for (enum_field_vals, 0..) |*field_val, tag_index| { |
| 18083 | const enum_type = ip.loadEnumType(ty.toIntern()); | 18239 | const enum_type = ip.loadEnumType(ty.toIntern()); |
| 18084 | const value_val = if (enum_type.values.len > 0) | 18240 | const value_val = if (enum_type.values.len > 0) |
| 18085 | try mod.intern_pool.getCoercedInts( | 18241 | try ip.getCoercedInts( |
| 18086 | mod.gpa, | 18242 | mod.gpa, |
| 18087 | mod.intern_pool.indexToKey(enum_type.values.get(ip)[tag_index]).int, | 18243 | pt.tid, |
| 18244 | ip.indexToKey(enum_type.values.get(ip)[tag_index]).int, | ||
| 18088 | .comptime_int_type, | 18245 | .comptime_int_type, |
| 18089 | ) | 18246 | ) |
| 18090 | else | 18247 | else |
| 18091 | (try mod.intValue(Type.comptime_int, tag_index)).toIntern(); | 18248 | (try pt.intValue(Type.comptime_int, tag_index)).toIntern(); |
| 18092 | 18249 | ||
| 18093 | // TODO: write something like getCoercedInts to avoid needing to dupe | 18250 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 18094 | const name_val = v: { | 18251 | const name_val = v: { |
| 18095 | const tag_name = enum_type.names.get(ip)[tag_index]; | 18252 | const tag_name = enum_type.names.get(ip)[tag_index]; |
| 18096 | const tag_name_len = tag_name.length(ip); | 18253 | const tag_name_len = tag_name.length(ip); |
| 18097 | const new_decl_ty = try mod.arrayType(.{ | 18254 | const new_decl_ty = try pt.arrayType(.{ |
| 18098 | .len = tag_name_len, | 18255 | .len = tag_name_len, |
| 18099 | .sentinel = .zero_u8, | 18256 | .sentinel = .zero_u8, |
| 18100 | .child = .u8_type, | 18257 | .child = .u8_type, |
| 18101 | }); | 18258 | }); |
| 18102 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18259 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18103 | .ty = new_decl_ty.toIntern(), | 18260 | .ty = new_decl_ty.toIntern(), |
| 18104 | .storage = .{ .bytes = tag_name.toString() }, | 18261 | .storage = .{ .bytes = tag_name.toString() }, |
| 18105 | } }); | 18262 | } }); |
| 18106 | break :v try mod.intern(.{ .slice = .{ | 18263 | break :v try pt.intern(.{ .slice = .{ |
| 18107 | .ty = .slice_const_u8_sentinel_0_type, | 18264 | .ty = .slice_const_u8_sentinel_0_type, |
| 18108 | .ptr = try mod.intern(.{ .ptr = .{ | 18265 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18109 | .ty = .manyptr_const_u8_sentinel_0_type, | 18266 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18110 | .base_addr = .{ .anon_decl = .{ | 18267 | .base_addr = .{ .anon_decl = .{ |
| 18111 | .val = new_decl_val, | 18268 | .val = new_decl_val, |
| ... | @@ -18113,7 +18270,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18113,7 +18270,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18113 | } }, | 18270 | } }, |
| 18114 | .byte_offset = 0, | 18271 | .byte_offset = 0, |
| 18115 | } }), | 18272 | } }), |
| 18116 | .len = (try mod.intValue(Type.usize, tag_name_len)).toIntern(), | 18273 | .len = (try pt.intValue(Type.usize, tag_name_len)).toIntern(), |
| 18117 | } }); | 18274 | } }); |
| 18118 | }; | 18275 | }; |
| 18119 | 18276 | ||
| ... | @@ -18123,22 +18280,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18123,22 +18280,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18123 | // value: comptime_int, | 18280 | // value: comptime_int, |
| 18124 | value_val, | 18281 | value_val, |
| 18125 | }; | 18282 | }; |
| 18126 | field_val.* = try mod.intern(.{ .aggregate = .{ | 18283 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18127 | .ty = enum_field_ty.toIntern(), | 18284 | .ty = enum_field_ty.toIntern(), |
| 18128 | .storage = .{ .elems = &enum_field_fields }, | 18285 | .storage = .{ .elems = &enum_field_fields }, |
| 18129 | } }); | 18286 | } }); |
| 18130 | } | 18287 | } |
| 18131 | 18288 | ||
| 18132 | const fields_val = v: { | 18289 | const fields_val = v: { |
| 18133 | const fields_array_ty = try mod.arrayType(.{ | 18290 | const fields_array_ty = try pt.arrayType(.{ |
| 18134 | .len = enum_field_vals.len, | 18291 | .len = enum_field_vals.len, |
| 18135 | .child = enum_field_ty.toIntern(), | 18292 | .child = enum_field_ty.toIntern(), |
| 18136 | }); | 18293 | }); |
| 18137 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18294 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18138 | .ty = fields_array_ty.toIntern(), | 18295 | .ty = fields_array_ty.toIntern(), |
| 18139 | .storage = .{ .elems = enum_field_vals }, | 18296 | .storage = .{ .elems = enum_field_vals }, |
| 18140 | } }); | 18297 | } }); |
| 18141 | const slice_ty = (try mod.ptrTypeSema(.{ | 18298 | const slice_ty = (try pt.ptrTypeSema(.{ |
| 18142 | .child = enum_field_ty.toIntern(), | 18299 | .child = enum_field_ty.toIntern(), |
| 18143 | .flags = .{ | 18300 | .flags = .{ |
| 18144 | .size = .Slice, | 18301 | .size = .Slice, |
| ... | @@ -18146,9 +18303,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18146,9 +18303,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18146 | }, | 18303 | }, |
| 18147 | })).toIntern(); | 18304 | })).toIntern(); |
| 18148 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 18305 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); |
| 18149 | break :v try mod.intern(.{ .slice = .{ | 18306 | break :v try pt.intern(.{ .slice = .{ |
| 18150 | .ty = slice_ty, | 18307 | .ty = slice_ty, |
| 18151 | .ptr = try mod.intern(.{ .ptr = .{ | 18308 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18152 | .ty = manyptr_ty, | 18309 | .ty = manyptr_ty, |
| 18153 | .base_addr = .{ .anon_decl = .{ | 18310 | .base_addr = .{ .anon_decl = .{ |
| 18154 | .val = new_decl_val, | 18311 | .val = new_decl_val, |
| ... | @@ -18156,7 +18313,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18156,7 +18313,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18156 | } }, | 18313 | } }, |
| 18157 | .byte_offset = 0, | 18314 | .byte_offset = 0, |
| 18158 | } }), | 18315 | } }), |
| 18159 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), | 18316 | .len = (try pt.intValue(Type.usize, enum_field_vals.len)).toIntern(), |
| 18160 | } }); | 18317 | } }); |
| 18161 | }; | 18318 | }; |
| 18162 | 18319 | ||
| ... | @@ -18184,10 +18341,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18184,10 +18341,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18184 | // is_exhaustive: bool, | 18341 | // is_exhaustive: bool, |
| 18185 | is_exhaustive.toIntern(), | 18342 | is_exhaustive.toIntern(), |
| 18186 | }; | 18343 | }; |
| 18187 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18344 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18188 | .ty = type_info_ty.toIntern(), | 18345 | .ty = type_info_ty.toIntern(), |
| 18189 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(), | 18346 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Enum))).toIntern(), |
| 18190 | .val = try mod.intern(.{ .aggregate = .{ | 18347 | .val = try pt.intern(.{ .aggregate = .{ |
| 18191 | .ty = type_enum_ty.toIntern(), | 18348 | .ty = type_enum_ty.toIntern(), |
| 18192 | .storage = .{ .elems = &field_values }, | 18349 | .storage = .{ .elems = &field_values }, |
| 18193 | } }), | 18350 | } }), |
| ... | @@ -18218,7 +18375,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18218,7 +18375,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18218 | break :t union_field_ty_decl.val.toType(); | 18375 | break :t union_field_ty_decl.val.toType(); |
| 18219 | }; | 18376 | }; |
| 18220 | 18377 | ||
| 18221 | try ty.resolveLayout(mod); // Getting alignment requires type layout | 18378 | try ty.resolveLayout(pt); // Getting alignment requires type layout |
| 18222 | const union_obj = mod.typeToUnion(ty).?; | 18379 | const union_obj = mod.typeToUnion(ty).?; |
| 18223 | const tag_type = union_obj.loadTagType(ip); | 18380 | const tag_type = union_obj.loadTagType(ip); |
| 18224 | const layout = union_obj.getLayout(ip); | 18381 | const layout = union_obj.getLayout(ip); |
| ... | @@ -18230,18 +18387,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18230,18 +18387,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18230 | const name_val = v: { | 18387 | const name_val = v: { |
| 18231 | const field_name = tag_type.names.get(ip)[field_index]; | 18388 | const field_name = tag_type.names.get(ip)[field_index]; |
| 18232 | const field_name_len = field_name.length(ip); | 18389 | const field_name_len = field_name.length(ip); |
| 18233 | const new_decl_ty = try mod.arrayType(.{ | 18390 | const new_decl_ty = try pt.arrayType(.{ |
| 18234 | .len = field_name_len, | 18391 | .len = field_name_len, |
| 18235 | .sentinel = .zero_u8, | 18392 | .sentinel = .zero_u8, |
| 18236 | .child = .u8_type, | 18393 | .child = .u8_type, |
| 18237 | }); | 18394 | }); |
| 18238 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18395 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18239 | .ty = new_decl_ty.toIntern(), | 18396 | .ty = new_decl_ty.toIntern(), |
| 18240 | .storage = .{ .bytes = field_name.toString() }, | 18397 | .storage = .{ .bytes = field_name.toString() }, |
| 18241 | } }); | 18398 | } }); |
| 18242 | break :v try mod.intern(.{ .slice = .{ | 18399 | break :v try pt.intern(.{ .slice = .{ |
| 18243 | .ty = .slice_const_u8_sentinel_0_type, | 18400 | .ty = .slice_const_u8_sentinel_0_type, |
| 18244 | .ptr = try mod.intern(.{ .ptr = .{ | 18401 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18245 | .ty = .manyptr_const_u8_sentinel_0_type, | 18402 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18246 | .base_addr = .{ .anon_decl = .{ | 18403 | .base_addr = .{ .anon_decl = .{ |
| 18247 | .val = new_decl_val, | 18404 | .val = new_decl_val, |
| ... | @@ -18249,12 +18406,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18249,12 +18406,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18249 | } }, | 18406 | } }, |
| 18250 | .byte_offset = 0, | 18407 | .byte_offset = 0, |
| 18251 | } }), | 18408 | } }), |
| 18252 | .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(), | 18409 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), |
| 18253 | } }); | 18410 | } }); |
| 18254 | }; | 18411 | }; |
| 18255 | 18412 | ||
| 18256 | const alignment = switch (layout) { | 18413 | const alignment = switch (layout) { |
| 18257 | .auto, .@"extern" => try mod.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema), | 18414 | .auto, .@"extern" => try pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema), |
| 18258 | .@"packed" => .none, | 18415 | .@"packed" => .none, |
| 18259 | }; | 18416 | }; |
| 18260 | 18417 | ||
| ... | @@ -18265,24 +18422,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18265,24 +18422,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18265 | // type: type, | 18422 | // type: type, |
| 18266 | field_ty, | 18423 | field_ty, |
| 18267 | // alignment: comptime_int, | 18424 | // alignment: comptime_int, |
| 18268 | (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), | 18425 | (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), |
| 18269 | }; | 18426 | }; |
| 18270 | field_val.* = try mod.intern(.{ .aggregate = .{ | 18427 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18271 | .ty = union_field_ty.toIntern(), | 18428 | .ty = union_field_ty.toIntern(), |
| 18272 | .storage = .{ .elems = &union_field_fields }, | 18429 | .storage = .{ .elems = &union_field_fields }, |
| 18273 | } }); | 18430 | } }); |
| 18274 | } | 18431 | } |
| 18275 | 18432 | ||
| 18276 | const fields_val = v: { | 18433 | const fields_val = v: { |
| 18277 | const array_fields_ty = try mod.arrayType(.{ | 18434 | const array_fields_ty = try pt.arrayType(.{ |
| 18278 | .len = union_field_vals.len, | 18435 | .len = union_field_vals.len, |
| 18279 | .child = union_field_ty.toIntern(), | 18436 | .child = union_field_ty.toIntern(), |
| 18280 | }); | 18437 | }); |
| 18281 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18438 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18282 | .ty = array_fields_ty.toIntern(), | 18439 | .ty = array_fields_ty.toIntern(), |
| 18283 | .storage = .{ .elems = union_field_vals }, | 18440 | .storage = .{ .elems = union_field_vals }, |
| 18284 | } }); | 18441 | } }); |
| 18285 | const slice_ty = (try mod.ptrTypeSema(.{ | 18442 | const slice_ty = (try pt.ptrTypeSema(.{ |
| 18286 | .child = union_field_ty.toIntern(), | 18443 | .child = union_field_ty.toIntern(), |
| 18287 | .flags = .{ | 18444 | .flags = .{ |
| 18288 | .size = .Slice, | 18445 | .size = .Slice, |
| ... | @@ -18290,9 +18447,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18290,9 +18447,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18290 | }, | 18447 | }, |
| 18291 | })).toIntern(); | 18448 | })).toIntern(); |
| 18292 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 18449 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); |
| 18293 | break :v try mod.intern(.{ .slice = .{ | 18450 | break :v try pt.intern(.{ .slice = .{ |
| 18294 | .ty = slice_ty, | 18451 | .ty = slice_ty, |
| 18295 | .ptr = try mod.intern(.{ .ptr = .{ | 18452 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18296 | .ty = manyptr_ty, | 18453 | .ty = manyptr_ty, |
| 18297 | .base_addr = .{ .anon_decl = .{ | 18454 | .base_addr = .{ .anon_decl = .{ |
| 18298 | .orig_ty = manyptr_ty, | 18455 | .orig_ty = manyptr_ty, |
| ... | @@ -18300,14 +18457,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18300,14 +18457,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18300 | } }, | 18457 | } }, |
| 18301 | .byte_offset = 0, | 18458 | .byte_offset = 0, |
| 18302 | } }), | 18459 | } }), |
| 18303 | .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(), | 18460 | .len = (try pt.intValue(Type.usize, union_field_vals.len)).toIntern(), |
| 18304 | } }); | 18461 | } }); |
| 18305 | }; | 18462 | }; |
| 18306 | 18463 | ||
| 18307 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18464 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 18308 | 18465 | ||
| 18309 | const enum_tag_ty_val = try mod.intern(.{ .opt = .{ | 18466 | const enum_tag_ty_val = try pt.intern(.{ .opt = .{ |
| 18310 | .ty = (try mod.optionalType(.type_type)).toIntern(), | 18467 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 18311 | .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none, | 18468 | .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none, |
| 18312 | } }); | 18469 | } }); |
| 18313 | 18470 | ||
| ... | @@ -18315,7 +18472,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18315,7 +18472,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18315 | const decl_index = (try sema.namespaceLookup( | 18472 | const decl_index = (try sema.namespaceLookup( |
| 18316 | block, | 18473 | block, |
| 18317 | src, | 18474 | src, |
| 18318 | (try mod.getBuiltinType("Type")).getNamespaceIndex(mod), | 18475 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 18319 | try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls), | 18476 | try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls), |
| 18320 | )).?; | 18477 | )).?; |
| 18321 | try sema.ensureDeclAnalyzed(decl_index); | 18478 | try sema.ensureDeclAnalyzed(decl_index); |
| ... | @@ -18325,7 +18482,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18325,7 +18482,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18325 | 18482 | ||
| 18326 | const field_values = .{ | 18483 | const field_values = .{ |
| 18327 | // layout: ContainerLayout, | 18484 | // layout: ContainerLayout, |
| 18328 | (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), | 18485 | (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), |
| 18329 | 18486 | ||
| 18330 | // tag_type: ?type, | 18487 | // tag_type: ?type, |
| 18331 | enum_tag_ty_val, | 18488 | enum_tag_ty_val, |
| ... | @@ -18334,10 +18491,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18334,10 +18491,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18334 | // decls: []const Declaration, | 18491 | // decls: []const Declaration, |
| 18335 | decls_val, | 18492 | decls_val, |
| 18336 | }; | 18493 | }; |
| 18337 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18494 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18338 | .ty = type_info_ty.toIntern(), | 18495 | .ty = type_info_ty.toIntern(), |
| 18339 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(), | 18496 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Union))).toIntern(), |
| 18340 | .val = try mod.intern(.{ .aggregate = .{ | 18497 | .val = try pt.intern(.{ .aggregate = .{ |
| 18341 | .ty = type_union_ty.toIntern(), | 18498 | .ty = type_union_ty.toIntern(), |
| 18342 | .storage = .{ .elems = &field_values }, | 18499 | .storage = .{ .elems = &field_values }, |
| 18343 | } }), | 18500 | } }), |
| ... | @@ -18368,7 +18525,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18368,7 +18525,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18368 | break :t struct_field_ty_decl.val.toType(); | 18525 | break :t struct_field_ty_decl.val.toType(); |
| 18369 | }; | 18526 | }; |
| 18370 | 18527 | ||
| 18371 | try ty.resolveLayout(mod); // Getting alignment requires type layout | 18528 | try ty.resolveLayout(pt); // Getting alignment requires type layout |
| 18372 | 18529 | ||
| 18373 | var struct_field_vals: []InternPool.Index = &.{}; | 18530 | var struct_field_vals: []InternPool.Index = &.{}; |
| 18374 | defer gpa.free(struct_field_vals); | 18531 | defer gpa.free(struct_field_vals); |
| ... | @@ -18385,18 +18542,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18385,18 +18542,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18385 | else | 18542 | else |
| 18386 | try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls); | 18543 | try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls); |
| 18387 | const field_name_len = field_name.length(ip); | 18544 | const field_name_len = field_name.length(ip); |
| 18388 | const new_decl_ty = try mod.arrayType(.{ | 18545 | const new_decl_ty = try pt.arrayType(.{ |
| 18389 | .len = field_name_len, | 18546 | .len = field_name_len, |
| 18390 | .sentinel = .zero_u8, | 18547 | .sentinel = .zero_u8, |
| 18391 | .child = .u8_type, | 18548 | .child = .u8_type, |
| 18392 | }); | 18549 | }); |
| 18393 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18550 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18394 | .ty = new_decl_ty.toIntern(), | 18551 | .ty = new_decl_ty.toIntern(), |
| 18395 | .storage = .{ .bytes = field_name.toString() }, | 18552 | .storage = .{ .bytes = field_name.toString() }, |
| 18396 | } }); | 18553 | } }); |
| 18397 | break :v try mod.intern(.{ .slice = .{ | 18554 | break :v try pt.intern(.{ .slice = .{ |
| 18398 | .ty = .slice_const_u8_sentinel_0_type, | 18555 | .ty = .slice_const_u8_sentinel_0_type, |
| 18399 | .ptr = try mod.intern(.{ .ptr = .{ | 18556 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18400 | .ty = .manyptr_const_u8_sentinel_0_type, | 18557 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18401 | .base_addr = .{ .anon_decl = .{ | 18558 | .base_addr = .{ .anon_decl = .{ |
| 18402 | .val = new_decl_val, | 18559 | .val = new_decl_val, |
| ... | @@ -18404,11 +18561,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18404,11 +18561,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18404 | } }, | 18561 | } }, |
| 18405 | .byte_offset = 0, | 18562 | .byte_offset = 0, |
| 18406 | } }), | 18563 | } }), |
| 18407 | .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(), | 18564 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), |
| 18408 | } }); | 18565 | } }); |
| 18409 | }; | 18566 | }; |
| 18410 | 18567 | ||
| 18411 | try Type.fromInterned(field_ty).resolveLayout(mod); | 18568 | try Type.fromInterned(field_ty).resolveLayout(pt); |
| 18412 | 18569 | ||
| 18413 | const is_comptime = field_val != .none; | 18570 | const is_comptime = field_val != .none; |
| 18414 | const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null; | 18571 | const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null; |
| ... | @@ -18423,9 +18580,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18423,9 +18580,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18423 | // is_comptime: bool, | 18580 | // is_comptime: bool, |
| 18424 | Value.makeBool(is_comptime).toIntern(), | 18581 | Value.makeBool(is_comptime).toIntern(), |
| 18425 | // alignment: comptime_int, | 18582 | // alignment: comptime_int, |
| 18426 | (try mod.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(mod).toByteUnits() orelse 0)).toIntern(), | 18583 | (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(pt).toByteUnits() orelse 0)).toIntern(), |
| 18427 | }; | 18584 | }; |
| 18428 | struct_field_val.* = try mod.intern(.{ .aggregate = .{ | 18585 | struct_field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18429 | .ty = struct_field_ty.toIntern(), | 18586 | .ty = struct_field_ty.toIntern(), |
| 18430 | .storage = .{ .elems = &struct_field_fields }, | 18587 | .storage = .{ .elems = &struct_field_fields }, |
| 18431 | } }); | 18588 | } }); |
| ... | @@ -18437,7 +18594,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18437,7 +18594,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18437 | }; | 18594 | }; |
| 18438 | struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); | 18595 | struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); |
| 18439 | 18596 | ||
| 18440 | try ty.resolveStructFieldInits(mod); | 18597 | try ty.resolveStructFieldInits(pt); |
| 18441 | 18598 | ||
| 18442 | for (struct_field_vals, 0..) |*field_val, field_index| { | 18599 | for (struct_field_vals, 0..) |*field_val, field_index| { |
| 18443 | const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name| | 18600 | const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | @@ -18449,18 +18606,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18449,18 +18606,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18449 | const field_init = struct_type.fieldInit(ip, field_index); | 18606 | const field_init = struct_type.fieldInit(ip, field_index); |
| 18450 | const field_is_comptime = struct_type.fieldIsComptime(ip, field_index); | 18607 | const field_is_comptime = struct_type.fieldIsComptime(ip, field_index); |
| 18451 | const name_val = v: { | 18608 | const name_val = v: { |
| 18452 | const new_decl_ty = try mod.arrayType(.{ | 18609 | const new_decl_ty = try pt.arrayType(.{ |
| 18453 | .len = field_name_len, | 18610 | .len = field_name_len, |
| 18454 | .sentinel = .zero_u8, | 18611 | .sentinel = .zero_u8, |
| 18455 | .child = .u8_type, | 18612 | .child = .u8_type, |
| 18456 | }); | 18613 | }); |
| 18457 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18614 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18458 | .ty = new_decl_ty.toIntern(), | 18615 | .ty = new_decl_ty.toIntern(), |
| 18459 | .storage = .{ .bytes = field_name.toString() }, | 18616 | .storage = .{ .bytes = field_name.toString() }, |
| 18460 | } }); | 18617 | } }); |
| 18461 | break :v try mod.intern(.{ .slice = .{ | 18618 | break :v try pt.intern(.{ .slice = .{ |
| 18462 | .ty = .slice_const_u8_sentinel_0_type, | 18619 | .ty = .slice_const_u8_sentinel_0_type, |
| 18463 | .ptr = try mod.intern(.{ .ptr = .{ | 18620 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18464 | .ty = .manyptr_const_u8_sentinel_0_type, | 18621 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18465 | .base_addr = .{ .anon_decl = .{ | 18622 | .base_addr = .{ .anon_decl = .{ |
| 18466 | .val = new_decl_val, | 18623 | .val = new_decl_val, |
| ... | @@ -18468,7 +18625,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18468,7 +18625,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18468 | } }, | 18625 | } }, |
| 18469 | .byte_offset = 0, | 18626 | .byte_offset = 0, |
| 18470 | } }), | 18627 | } }), |
| 18471 | .len = (try mod.intValue(Type.usize, field_name_len)).toIntern(), | 18628 | .len = (try pt.intValue(Type.usize, field_name_len)).toIntern(), |
| 18472 | } }); | 18629 | } }); |
| 18473 | }; | 18630 | }; |
| 18474 | 18631 | ||
| ... | @@ -18476,7 +18633,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18476,7 +18633,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18476 | const default_val_ptr = try sema.optRefValue(opt_default_val); | 18633 | const default_val_ptr = try sema.optRefValue(opt_default_val); |
| 18477 | const alignment = switch (struct_type.layout) { | 18634 | const alignment = switch (struct_type.layout) { |
| 18478 | .@"packed" => .none, | 18635 | .@"packed" => .none, |
| 18479 | else => try mod.structFieldAlignmentAdvanced( | 18636 | else => try pt.structFieldAlignmentAdvanced( |
| 18480 | struct_type.fieldAlign(ip, field_index), | 18637 | struct_type.fieldAlign(ip, field_index), |
| 18481 | field_ty, | 18638 | field_ty, |
| 18482 | struct_type.layout, | 18639 | struct_type.layout, |
| ... | @@ -18494,9 +18651,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18494,9 +18651,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18494 | // is_comptime: bool, | 18651 | // is_comptime: bool, |
| 18495 | Value.makeBool(field_is_comptime).toIntern(), | 18652 | Value.makeBool(field_is_comptime).toIntern(), |
| 18496 | // alignment: comptime_int, | 18653 | // alignment: comptime_int, |
| 18497 | (try mod.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), | 18654 | (try pt.intValue(Type.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(), |
| 18498 | }; | 18655 | }; |
| 18499 | field_val.* = try mod.intern(.{ .aggregate = .{ | 18656 | field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18500 | .ty = struct_field_ty.toIntern(), | 18657 | .ty = struct_field_ty.toIntern(), |
| 18501 | .storage = .{ .elems = &struct_field_fields }, | 18658 | .storage = .{ .elems = &struct_field_fields }, |
| 18502 | } }); | 18659 | } }); |
| ... | @@ -18504,15 +18661,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18504,15 +18661,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18504 | } | 18661 | } |
| 18505 | 18662 | ||
| 18506 | const fields_val = v: { | 18663 | const fields_val = v: { |
| 18507 | const array_fields_ty = try mod.arrayType(.{ | 18664 | const array_fields_ty = try pt.arrayType(.{ |
| 18508 | .len = struct_field_vals.len, | 18665 | .len = struct_field_vals.len, |
| 18509 | .child = struct_field_ty.toIntern(), | 18666 | .child = struct_field_ty.toIntern(), |
| 18510 | }); | 18667 | }); |
| 18511 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18668 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18512 | .ty = array_fields_ty.toIntern(), | 18669 | .ty = array_fields_ty.toIntern(), |
| 18513 | .storage = .{ .elems = struct_field_vals }, | 18670 | .storage = .{ .elems = struct_field_vals }, |
| 18514 | } }); | 18671 | } }); |
| 18515 | const slice_ty = (try mod.ptrTypeSema(.{ | 18672 | const slice_ty = (try pt.ptrTypeSema(.{ |
| 18516 | .child = struct_field_ty.toIntern(), | 18673 | .child = struct_field_ty.toIntern(), |
| 18517 | .flags = .{ | 18674 | .flags = .{ |
| 18518 | .size = .Slice, | 18675 | .size = .Slice, |
| ... | @@ -18520,9 +18677,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18520,9 +18677,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18520 | }, | 18677 | }, |
| 18521 | })).toIntern(); | 18678 | })).toIntern(); |
| 18522 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 18679 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); |
| 18523 | break :v try mod.intern(.{ .slice = .{ | 18680 | break :v try pt.intern(.{ .slice = .{ |
| 18524 | .ty = slice_ty, | 18681 | .ty = slice_ty, |
| 18525 | .ptr = try mod.intern(.{ .ptr = .{ | 18682 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18526 | .ty = manyptr_ty, | 18683 | .ty = manyptr_ty, |
| 18527 | .base_addr = .{ .anon_decl = .{ | 18684 | .base_addr = .{ .anon_decl = .{ |
| 18528 | .orig_ty = manyptr_ty, | 18685 | .orig_ty = manyptr_ty, |
| ... | @@ -18530,14 +18687,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18530,14 +18687,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18530 | } }, | 18687 | } }, |
| 18531 | .byte_offset = 0, | 18688 | .byte_offset = 0, |
| 18532 | } }), | 18689 | } }), |
| 18533 | .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(), | 18690 | .len = (try pt.intValue(Type.usize, struct_field_vals.len)).toIntern(), |
| 18534 | } }); | 18691 | } }); |
| 18535 | }; | 18692 | }; |
| 18536 | 18693 | ||
| 18537 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18694 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 18538 | 18695 | ||
| 18539 | const backing_integer_val = try mod.intern(.{ .opt = .{ | 18696 | const backing_integer_val = try pt.intern(.{ .opt = .{ |
| 18540 | .ty = (try mod.optionalType(.type_type)).toIntern(), | 18697 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 18541 | .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: { | 18698 | .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: { |
| 18542 | assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod)); | 18699 | assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod)); |
| 18543 | break :val packed_struct.backingIntType(ip).*; | 18700 | break :val packed_struct.backingIntType(ip).*; |
| ... | @@ -18548,7 +18705,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18548,7 +18705,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18548 | const decl_index = (try sema.namespaceLookup( | 18705 | const decl_index = (try sema.namespaceLookup( |
| 18549 | block, | 18706 | block, |
| 18550 | src, | 18707 | src, |
| 18551 | (try mod.getBuiltinType("Type")).getNamespaceIndex(mod), | 18708 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 18552 | try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls), | 18709 | try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls), |
| 18553 | )).?; | 18710 | )).?; |
| 18554 | try sema.ensureDeclAnalyzed(decl_index); | 18711 | try sema.ensureDeclAnalyzed(decl_index); |
| ... | @@ -18560,7 +18717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18560,7 +18717,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18560 | 18717 | ||
| 18561 | const field_values = [_]InternPool.Index{ | 18718 | const field_values = [_]InternPool.Index{ |
| 18562 | // layout: ContainerLayout, | 18719 | // layout: ContainerLayout, |
| 18563 | (try mod.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), | 18720 | (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), |
| 18564 | // backing_integer: ?type, | 18721 | // backing_integer: ?type, |
| 18565 | backing_integer_val, | 18722 | backing_integer_val, |
| 18566 | // fields: []const StructField, | 18723 | // fields: []const StructField, |
| ... | @@ -18570,10 +18727,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18570,10 +18727,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18570 | // is_tuple: bool, | 18727 | // is_tuple: bool, |
| 18571 | Value.makeBool(ty.isTuple(mod)).toIntern(), | 18728 | Value.makeBool(ty.isTuple(mod)).toIntern(), |
| 18572 | }; | 18729 | }; |
| 18573 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18730 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18574 | .ty = type_info_ty.toIntern(), | 18731 | .ty = type_info_ty.toIntern(), |
| 18575 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(), | 18732 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Struct))).toIntern(), |
| 18576 | .val = try mod.intern(.{ .aggregate = .{ | 18733 | .val = try pt.intern(.{ .aggregate = .{ |
| 18577 | .ty = type_struct_ty.toIntern(), | 18734 | .ty = type_struct_ty.toIntern(), |
| 18578 | .storage = .{ .elems = &field_values }, | 18735 | .storage = .{ .elems = &field_values }, |
| 18579 | } }), | 18736 | } }), |
| ... | @@ -18592,17 +18749,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18592,17 +18749,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18592 | break :t type_opaque_ty_decl.val.toType(); | 18749 | break :t type_opaque_ty_decl.val.toType(); |
| 18593 | }; | 18750 | }; |
| 18594 | 18751 | ||
| 18595 | try ty.resolveFields(mod); | 18752 | try ty.resolveFields(pt); |
| 18596 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18753 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 18597 | 18754 | ||
| 18598 | const field_values = .{ | 18755 | const field_values = .{ |
| 18599 | // decls: []const Declaration, | 18756 | // decls: []const Declaration, |
| 18600 | decls_val, | 18757 | decls_val, |
| 18601 | }; | 18758 | }; |
| 18602 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 18759 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18603 | .ty = type_info_ty.toIntern(), | 18760 | .ty = type_info_ty.toIntern(), |
| 18604 | .tag = (try mod.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(), | 18761 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.Opaque))).toIntern(), |
| 18605 | .val = try mod.intern(.{ .aggregate = .{ | 18762 | .val = try pt.intern(.{ .aggregate = .{ |
| 18606 | .ty = type_opaque_ty.toIntern(), | 18763 | .ty = type_opaque_ty.toIntern(), |
| 18607 | .storage = .{ .elems = &field_values }, | 18764 | .storage = .{ .elems = &field_values }, |
| 18608 | } }), | 18765 | } }), |
| ... | @@ -18620,7 +18777,8 @@ fn typeInfoDecls( | ... | @@ -18620,7 +18777,8 @@ fn typeInfoDecls( |
| 18620 | type_info_ty: Type, | 18777 | type_info_ty: Type, |
| 18621 | opt_namespace: InternPool.OptionalNamespaceIndex, | 18778 | opt_namespace: InternPool.OptionalNamespaceIndex, |
| 18622 | ) CompileError!InternPool.Index { | 18779 | ) CompileError!InternPool.Index { |
| 18623 | const mod = sema.mod; | 18780 | const pt = sema.pt; |
| 18781 | const mod = pt.zcu; | ||
| 18624 | const gpa = sema.gpa; | 18782 | const gpa = sema.gpa; |
| 18625 | 18783 | ||
| 18626 | const declaration_ty = t: { | 18784 | const declaration_ty = t: { |
| ... | @@ -18643,15 +18801,15 @@ fn typeInfoDecls( | ... | @@ -18643,15 +18801,15 @@ fn typeInfoDecls( |
| 18643 | 18801 | ||
| 18644 | try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces); | 18802 | try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces); |
| 18645 | 18803 | ||
| 18646 | const array_decl_ty = try mod.arrayType(.{ | 18804 | const array_decl_ty = try pt.arrayType(.{ |
| 18647 | .len = decl_vals.items.len, | 18805 | .len = decl_vals.items.len, |
| 18648 | .child = declaration_ty.toIntern(), | 18806 | .child = declaration_ty.toIntern(), |
| 18649 | }); | 18807 | }); |
| 18650 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18808 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18651 | .ty = array_decl_ty.toIntern(), | 18809 | .ty = array_decl_ty.toIntern(), |
| 18652 | .storage = .{ .elems = decl_vals.items }, | 18810 | .storage = .{ .elems = decl_vals.items }, |
| 18653 | } }); | 18811 | } }); |
| 18654 | const slice_ty = (try mod.ptrTypeSema(.{ | 18812 | const slice_ty = (try pt.ptrTypeSema(.{ |
| 18655 | .child = declaration_ty.toIntern(), | 18813 | .child = declaration_ty.toIntern(), |
| 18656 | .flags = .{ | 18814 | .flags = .{ |
| 18657 | .size = .Slice, | 18815 | .size = .Slice, |
| ... | @@ -18659,9 +18817,9 @@ fn typeInfoDecls( | ... | @@ -18659,9 +18817,9 @@ fn typeInfoDecls( |
| 18659 | }, | 18817 | }, |
| 18660 | })).toIntern(); | 18818 | })).toIntern(); |
| 18661 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 18819 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); |
| 18662 | return try mod.intern(.{ .slice = .{ | 18820 | return try pt.intern(.{ .slice = .{ |
| 18663 | .ty = slice_ty, | 18821 | .ty = slice_ty, |
| 18664 | .ptr = try mod.intern(.{ .ptr = .{ | 18822 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18665 | .ty = manyptr_ty, | 18823 | .ty = manyptr_ty, |
| 18666 | .base_addr = .{ .anon_decl = .{ | 18824 | .base_addr = .{ .anon_decl = .{ |
| 18667 | .orig_ty = manyptr_ty, | 18825 | .orig_ty = manyptr_ty, |
| ... | @@ -18669,7 +18827,7 @@ fn typeInfoDecls( | ... | @@ -18669,7 +18827,7 @@ fn typeInfoDecls( |
| 18669 | } }, | 18827 | } }, |
| 18670 | .byte_offset = 0, | 18828 | .byte_offset = 0, |
| 18671 | } }), | 18829 | } }), |
| 18672 | .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(), | 18830 | .len = (try pt.intValue(Type.usize, decl_vals.items.len)).toIntern(), |
| 18673 | } }); | 18831 | } }); |
| 18674 | } | 18832 | } |
| 18675 | 18833 | ||
| ... | @@ -18681,7 +18839,8 @@ fn typeInfoNamespaceDecls( | ... | @@ -18681,7 +18839,8 @@ fn typeInfoNamespaceDecls( |
| 18681 | decl_vals: *std.ArrayList(InternPool.Index), | 18839 | decl_vals: *std.ArrayList(InternPool.Index), |
| 18682 | seen_namespaces: *std.AutoHashMap(*Namespace, void), | 18840 | seen_namespaces: *std.AutoHashMap(*Namespace, void), |
| 18683 | ) !void { | 18841 | ) !void { |
| 18684 | const mod = sema.mod; | 18842 | const pt = sema.pt; |
| 18843 | const mod = pt.zcu; | ||
| 18685 | const ip = &mod.intern_pool; | 18844 | const ip = &mod.intern_pool; |
| 18686 | 18845 | ||
| 18687 | const namespace_index = opt_namespace_index.unwrap() orelse return; | 18846 | const namespace_index = opt_namespace_index.unwrap() orelse return; |
| ... | @@ -18703,18 +18862,18 @@ fn typeInfoNamespaceDecls( | ... | @@ -18703,18 +18862,18 @@ fn typeInfoNamespaceDecls( |
| 18703 | if (decl.kind != .named) continue; | 18862 | if (decl.kind != .named) continue; |
| 18704 | const name_val = v: { | 18863 | const name_val = v: { |
| 18705 | const decl_name_len = decl.name.length(ip); | 18864 | const decl_name_len = decl.name.length(ip); |
| 18706 | const new_decl_ty = try mod.arrayType(.{ | 18865 | const new_decl_ty = try pt.arrayType(.{ |
| 18707 | .len = decl_name_len, | 18866 | .len = decl_name_len, |
| 18708 | .sentinel = .zero_u8, | 18867 | .sentinel = .zero_u8, |
| 18709 | .child = .u8_type, | 18868 | .child = .u8_type, |
| 18710 | }); | 18869 | }); |
| 18711 | const new_decl_val = try mod.intern(.{ .aggregate = .{ | 18870 | const new_decl_val = try pt.intern(.{ .aggregate = .{ |
| 18712 | .ty = new_decl_ty.toIntern(), | 18871 | .ty = new_decl_ty.toIntern(), |
| 18713 | .storage = .{ .bytes = decl.name.toString() }, | 18872 | .storage = .{ .bytes = decl.name.toString() }, |
| 18714 | } }); | 18873 | } }); |
| 18715 | break :v try mod.intern(.{ .slice = .{ | 18874 | break :v try pt.intern(.{ .slice = .{ |
| 18716 | .ty = .slice_const_u8_sentinel_0_type, | 18875 | .ty = .slice_const_u8_sentinel_0_type, |
| 18717 | .ptr = try mod.intern(.{ .ptr = .{ | 18876 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18718 | .ty = .manyptr_const_u8_sentinel_0_type, | 18877 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18719 | .base_addr = .{ .anon_decl = .{ | 18878 | .base_addr = .{ .anon_decl = .{ |
| 18720 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18879 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| ... | @@ -18722,7 +18881,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -18722,7 +18881,7 @@ fn typeInfoNamespaceDecls( |
| 18722 | } }, | 18881 | } }, |
| 18723 | .byte_offset = 0, | 18882 | .byte_offset = 0, |
| 18724 | } }), | 18883 | } }), |
| 18725 | .len = (try mod.intValue(Type.usize, decl_name_len)).toIntern(), | 18884 | .len = (try pt.intValue(Type.usize, decl_name_len)).toIntern(), |
| 18726 | } }); | 18885 | } }); |
| 18727 | }; | 18886 | }; |
| 18728 | 18887 | ||
| ... | @@ -18730,7 +18889,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -18730,7 +18889,7 @@ fn typeInfoNamespaceDecls( |
| 18730 | //name: [:0]const u8, | 18889 | //name: [:0]const u8, |
| 18731 | name_val, | 18890 | name_val, |
| 18732 | }; | 18891 | }; |
| 18733 | try decl_vals.append(try mod.intern(.{ .aggregate = .{ | 18892 | try decl_vals.append(try pt.intern(.{ .aggregate = .{ |
| 18734 | .ty = declaration_ty.toIntern(), | 18893 | .ty = declaration_ty.toIntern(), |
| 18735 | .storage = .{ .elems = &fields }, | 18894 | .storage = .{ .elems = &fields }, |
| 18736 | } })); | 18895 | } })); |
| ... | @@ -18782,11 +18941,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil | ... | @@ -18782,11 +18941,12 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 18782 | } | 18941 | } |
| 18783 | 18942 | ||
| 18784 | fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type { | 18943 | fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type { |
| 18785 | const mod = sema.mod; | 18944 | const pt = sema.pt; |
| 18945 | const mod = pt.zcu; | ||
| 18786 | switch (operand.zigTypeTag(mod)) { | 18946 | switch (operand.zigTypeTag(mod)) { |
| 18787 | .ComptimeInt => return Type.comptime_int, | 18947 | .ComptimeInt => return Type.comptime_int, |
| 18788 | .Int => { | 18948 | .Int => { |
| 18789 | const bits = operand.bitSize(mod); | 18949 | const bits = operand.bitSize(pt); |
| 18790 | const count = if (bits == 0) | 18950 | const count = if (bits == 0) |
| 18791 | 0 | 18951 | 0 |
| 18792 | else blk: { | 18952 | else blk: { |
| ... | @@ -18797,12 +18957,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi | ... | @@ -18797,12 +18957,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 18797 | } | 18957 | } |
| 18798 | break :blk count; | 18958 | break :blk count; |
| 18799 | }; | 18959 | }; |
| 18800 | return mod.intType(.unsigned, count); | 18960 | return pt.intType(.unsigned, count); |
| 18801 | }, | 18961 | }, |
| 18802 | .Vector => { | 18962 | .Vector => { |
| 18803 | const elem_ty = operand.elemType2(mod); | 18963 | const elem_ty = operand.elemType2(mod); |
| 18804 | const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); | 18964 | const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); |
| 18805 | return mod.vectorType(.{ | 18965 | return pt.vectorType(.{ |
| 18806 | .len = operand.vectorLen(mod), | 18966 | .len = operand.vectorLen(mod), |
| 18807 | .child = log2_elem_ty.toIntern(), | 18967 | .child = log2_elem_ty.toIntern(), |
| 18808 | }); | 18968 | }); |
| ... | @@ -18813,7 +18973,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi | ... | @@ -18813,7 +18973,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 18813 | block, | 18973 | block, |
| 18814 | src, | 18974 | src, |
| 18815 | "bit shifting operation expected integer type, found '{}'", | 18975 | "bit shifting operation expected integer type, found '{}'", |
| 18816 | .{operand.fmt(mod)}, | 18976 | .{operand.fmt(pt)}, |
| 18817 | ); | 18977 | ); |
| 18818 | } | 18978 | } |
| 18819 | 18979 | ||
| ... | @@ -18865,7 +19025,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18865,7 +19025,8 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18865 | const tracy = trace(@src()); | 19025 | const tracy = trace(@src()); |
| 18866 | defer tracy.end(); | 19026 | defer tracy.end(); |
| 18867 | 19027 | ||
| 18868 | const mod = sema.mod; | 19028 | const pt = sema.pt; |
| 19029 | const mod = pt.zcu; | ||
| 18869 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 19030 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 18870 | const src = block.nodeOffset(inst_data.src_node); | 19031 | const src = block.nodeOffset(inst_data.src_node); |
| 18871 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); | 19032 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| ... | @@ -18874,7 +19035,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18874,7 +19035,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18874 | const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src); | 19035 | const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src); |
| 18875 | if (try sema.resolveValue(operand)) |val| { | 19036 | if (try sema.resolveValue(operand)) |val| { |
| 18876 | return if (val.isUndef(mod)) | 19037 | return if (val.isUndef(mod)) |
| 18877 | mod.undefRef(Type.bool) | 19038 | pt.undefRef(Type.bool) |
| 18878 | else if (val.toBool()) .bool_false else .bool_true; | 19039 | else if (val.toBool()) .bool_false else .bool_true; |
| 18879 | } | 19040 | } |
| 18880 | try sema.requireRuntimeBlock(block, src, null); | 19041 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -18890,7 +19051,8 @@ fn zirBoolBr( | ... | @@ -18890,7 +19051,8 @@ fn zirBoolBr( |
| 18890 | const tracy = trace(@src()); | 19051 | const tracy = trace(@src()); |
| 18891 | defer tracy.end(); | 19052 | defer tracy.end(); |
| 18892 | 19053 | ||
| 18893 | const mod = sema.mod; | 19054 | const pt = sema.pt; |
| 19055 | const mod = pt.zcu; | ||
| 18894 | const gpa = sema.gpa; | 19056 | const gpa = sema.gpa; |
| 18895 | 19057 | ||
| 18896 | const datas = sema.code.instructions.items(.data); | 19058 | const datas = sema.code.instructions.items(.data); |
| ... | @@ -19006,7 +19168,8 @@ fn finishCondBr( | ... | @@ -19006,7 +19168,8 @@ fn finishCondBr( |
| 19006 | } | 19168 | } |
| 19007 | 19169 | ||
| 19008 | fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { | 19170 | fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 19009 | const mod = sema.mod; | 19171 | const pt = sema.pt; |
| 19172 | const mod = pt.zcu; | ||
| 19010 | switch (ty.zigTypeTag(mod)) { | 19173 | switch (ty.zigTypeTag(mod)) { |
| 19011 | .Optional, .Null, .Undefined => return, | 19174 | .Optional, .Null, .Undefined => return, |
| 19012 | .Pointer => if (ty.isPtrLikeOptional(mod)) return, | 19175 | .Pointer => if (ty.isPtrLikeOptional(mod)) return, |
| ... | @@ -19038,7 +19201,8 @@ fn zirIsNonNullPtr( | ... | @@ -19038,7 +19201,8 @@ fn zirIsNonNullPtr( |
| 19038 | const tracy = trace(@src()); | 19201 | const tracy = trace(@src()); |
| 19039 | defer tracy.end(); | 19202 | defer tracy.end(); |
| 19040 | 19203 | ||
| 19041 | const mod = sema.mod; | 19204 | const pt = sema.pt; |
| 19205 | const mod = pt.zcu; | ||
| 19042 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 19206 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19043 | const src = block.nodeOffset(inst_data.src_node); | 19207 | const src = block.nodeOffset(inst_data.src_node); |
| 19044 | const ptr = try sema.resolveInst(inst_data.operand); | 19208 | const ptr = try sema.resolveInst(inst_data.operand); |
| ... | @@ -19051,11 +19215,12 @@ fn zirIsNonNullPtr( | ... | @@ -19051,11 +19215,12 @@ fn zirIsNonNullPtr( |
| 19051 | } | 19215 | } |
| 19052 | 19216 | ||
| 19053 | fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { | 19217 | fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 19054 | const mod = sema.mod; | 19218 | const pt = sema.pt; |
| 19219 | const mod = pt.zcu; | ||
| 19055 | switch (ty.zigTypeTag(mod)) { | 19220 | switch (ty.zigTypeTag(mod)) { |
| 19056 | .ErrorSet, .ErrorUnion, .Undefined => return, | 19221 | .ErrorSet, .ErrorUnion, .Undefined => return, |
| 19057 | else => return sema.fail(block, src, "expected error union type, found '{}'", .{ | 19222 | else => return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 19058 | ty.fmt(mod), | 19223 | ty.fmt(pt), |
| 19059 | }), | 19224 | }), |
| 19060 | } | 19225 | } |
| 19061 | } | 19226 | } |
| ... | @@ -19075,7 +19240,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -19075,7 +19240,8 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 19075 | const tracy = trace(@src()); | 19240 | const tracy = trace(@src()); |
| 19076 | defer tracy.end(); | 19241 | defer tracy.end(); |
| 19077 | 19242 | ||
| 19078 | const mod = sema.mod; | 19243 | const pt = sema.pt; |
| 19244 | const mod = pt.zcu; | ||
| 19079 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 19245 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19080 | const src = block.nodeOffset(inst_data.src_node); | 19246 | const src = block.nodeOffset(inst_data.src_node); |
| 19081 | const ptr = try sema.resolveInst(inst_data.operand); | 19247 | const ptr = try sema.resolveInst(inst_data.operand); |
| ... | @@ -19102,7 +19268,8 @@ fn zirCondbr( | ... | @@ -19102,7 +19268,8 @@ fn zirCondbr( |
| 19102 | const tracy = trace(@src()); | 19268 | const tracy = trace(@src()); |
| 19103 | defer tracy.end(); | 19269 | defer tracy.end(); |
| 19104 | 19270 | ||
| 19105 | const mod = sema.mod; | 19271 | const pt = sema.pt; |
| 19272 | const mod = pt.zcu; | ||
| 19106 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 19273 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19107 | const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node }); | 19274 | const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node }); |
| 19108 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); | 19275 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| ... | @@ -19177,10 +19344,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -19177,10 +19344,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19177 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); | 19344 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 19178 | const err_union = try sema.resolveInst(extra.data.operand); | 19345 | const err_union = try sema.resolveInst(extra.data.operand); |
| 19179 | const err_union_ty = sema.typeOf(err_union); | 19346 | const err_union_ty = sema.typeOf(err_union); |
| 19180 | const mod = sema.mod; | 19347 | const pt = sema.pt; |
| 19348 | const mod = pt.zcu; | ||
| 19181 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | 19349 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { |
| 19182 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ | 19350 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| 19183 | err_union_ty.fmt(mod), | 19351 | err_union_ty.fmt(pt), |
| 19184 | }); | 19352 | }); |
| 19185 | } | 19353 | } |
| 19186 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); | 19354 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| ... | @@ -19225,10 +19393,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -19225,10 +19393,11 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19225 | const operand = try sema.resolveInst(extra.data.operand); | 19393 | const operand = try sema.resolveInst(extra.data.operand); |
| 19226 | const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src); | 19394 | const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src); |
| 19227 | const err_union_ty = sema.typeOf(err_union); | 19395 | const err_union_ty = sema.typeOf(err_union); |
| 19228 | const mod = sema.mod; | 19396 | const pt = sema.pt; |
| 19397 | const mod = pt.zcu; | ||
| 19229 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | 19398 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { |
| 19230 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ | 19399 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| 19231 | err_union_ty.fmt(mod), | 19400 | err_union_ty.fmt(pt), |
| 19232 | }); | 19401 | }); |
| 19233 | } | 19402 | } |
| 19234 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); | 19403 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| ... | @@ -19251,7 +19420,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -19251,7 +19420,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19251 | 19420 | ||
| 19252 | const operand_ty = sema.typeOf(operand); | 19421 | const operand_ty = sema.typeOf(operand); |
| 19253 | const ptr_info = operand_ty.ptrInfo(mod); | 19422 | const ptr_info = operand_ty.ptrInfo(mod); |
| 19254 | const res_ty = try mod.ptrTypeSema(.{ | 19423 | const res_ty = try pt.ptrTypeSema(.{ |
| 19255 | .child = err_union_ty.errorUnionPayload(mod).toIntern(), | 19424 | .child = err_union_ty.errorUnionPayload(mod).toIntern(), |
| 19256 | .flags = .{ | 19425 | .flags = .{ |
| 19257 | .is_const = ptr_info.flags.is_const, | 19426 | .is_const = ptr_info.flags.is_const, |
| ... | @@ -19366,7 +19535,8 @@ fn zirRetErrValue( | ... | @@ -19366,7 +19535,8 @@ fn zirRetErrValue( |
| 19366 | block: *Block, | 19535 | block: *Block, |
| 19367 | inst: Zir.Inst.Index, | 19536 | inst: Zir.Inst.Index, |
| 19368 | ) CompileError!void { | 19537 | ) CompileError!void { |
| 19369 | const mod = sema.mod; | 19538 | const pt = sema.pt; |
| 19539 | const mod = pt.zcu; | ||
| 19370 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; | 19540 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 19371 | const src = block.tokenOffset(inst_data.src_tok); | 19541 | const src = block.tokenOffset(inst_data.src_tok); |
| 19372 | const err_name = try mod.intern_pool.getOrPutString( | 19542 | const err_name = try mod.intern_pool.getOrPutString( |
| ... | @@ -19376,8 +19546,8 @@ fn zirRetErrValue( | ... | @@ -19376,8 +19546,8 @@ fn zirRetErrValue( |
| 19376 | ); | 19546 | ); |
| 19377 | _ = try mod.getErrorValue(err_name); | 19547 | _ = try mod.getErrorValue(err_name); |
| 19378 | // Return the error code from the function. | 19548 | // Return the error code from the function. |
| 19379 | const error_set_type = try mod.singleErrorSetType(err_name); | 19549 | const error_set_type = try pt.singleErrorSetType(err_name); |
| 19380 | const result_inst = Air.internedToRef((try mod.intern(.{ .err = .{ | 19550 | const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{ |
| 19381 | .ty = error_set_type.toIntern(), | 19551 | .ty = error_set_type.toIntern(), |
| 19382 | .name = err_name, | 19552 | .name = err_name, |
| 19383 | } }))); | 19553 | } }))); |
| ... | @@ -19392,7 +19562,8 @@ fn zirRetImplicit( | ... | @@ -19392,7 +19562,8 @@ fn zirRetImplicit( |
| 19392 | const tracy = trace(@src()); | 19562 | const tracy = trace(@src()); |
| 19393 | defer tracy.end(); | 19563 | defer tracy.end(); |
| 19394 | 19564 | ||
| 19395 | const mod = sema.mod; | 19565 | const pt = sema.pt; |
| 19566 | const mod = pt.zcu; | ||
| 19396 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; | 19567 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; |
| 19397 | const r_brace_src = block.tokenOffset(inst_data.src_tok); | 19568 | const r_brace_src = block.tokenOffset(inst_data.src_tok); |
| 19398 | if (block.inlining == null and sema.func_is_naked) { | 19569 | if (block.inlining == null and sema.func_is_naked) { |
| ... | @@ -19412,7 +19583,7 @@ fn zirRetImplicit( | ... | @@ -19412,7 +19583,7 @@ fn zirRetImplicit( |
| 19412 | if (base_tag == .NoReturn) { | 19583 | if (base_tag == .NoReturn) { |
| 19413 | const msg = msg: { | 19584 | const msg = msg: { |
| 19414 | const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{ | 19585 | const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{ |
| 19415 | sema.fn_ret_ty.fmt(mod), | 19586 | sema.fn_ret_ty.fmt(pt), |
| 19416 | }); | 19587 | }); |
| 19417 | errdefer msg.destroy(sema.gpa); | 19588 | errdefer msg.destroy(sema.gpa); |
| 19418 | try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{}); | 19589 | try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{}); |
| ... | @@ -19422,7 +19593,7 @@ fn zirRetImplicit( | ... | @@ -19422,7 +19593,7 @@ fn zirRetImplicit( |
| 19422 | } else if (base_tag != .Void) { | 19593 | } else if (base_tag != .Void) { |
| 19423 | const msg = msg: { | 19594 | const msg = msg: { |
| 19424 | const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{ | 19595 | const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{ |
| 19425 | sema.fn_ret_ty.fmt(mod), | 19596 | sema.fn_ret_ty.fmt(pt), |
| 19426 | }); | 19597 | }); |
| 19427 | errdefer msg.destroy(sema.gpa); | 19598 | errdefer msg.destroy(sema.gpa); |
| 19428 | try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{}); | 19599 | try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{}); |
| ... | @@ -19474,7 +19645,7 @@ fn retWithErrTracing( | ... | @@ -19474,7 +19645,7 @@ fn retWithErrTracing( |
| 19474 | ret_tag: Air.Inst.Tag, | 19645 | ret_tag: Air.Inst.Tag, |
| 19475 | operand: Air.Inst.Ref, | 19646 | operand: Air.Inst.Ref, |
| 19476 | ) CompileError!void { | 19647 | ) CompileError!void { |
| 19477 | const mod = sema.mod; | 19648 | const pt = sema.pt; |
| 19478 | const need_check = switch (is_non_err) { | 19649 | const need_check = switch (is_non_err) { |
| 19479 | .bool_true => { | 19650 | .bool_true => { |
| 19480 | _ = try block.addUnOp(ret_tag, operand); | 19651 | _ = try block.addUnOp(ret_tag, operand); |
| ... | @@ -19484,11 +19655,11 @@ fn retWithErrTracing( | ... | @@ -19484,11 +19655,11 @@ fn retWithErrTracing( |
| 19484 | else => true, | 19655 | else => true, |
| 19485 | }; | 19656 | }; |
| 19486 | const gpa = sema.gpa; | 19657 | const gpa = sema.gpa; |
| 19487 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 19658 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 19488 | try stack_trace_ty.resolveFields(mod); | 19659 | try stack_trace_ty.resolveFields(pt); |
| 19489 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); | 19660 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 19490 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); | 19661 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 19491 | const return_err_fn = try mod.getBuiltin("returnError"); | 19662 | const return_err_fn = try pt.getBuiltin("returnError"); |
| 19492 | const args: [1]Air.Inst.Ref = .{err_return_trace}; | 19663 | const args: [1]Air.Inst.Ref = .{err_return_trace}; |
| 19493 | 19664 | ||
| 19494 | if (!need_check) { | 19665 | if (!need_check) { |
| ... | @@ -19524,12 +19695,14 @@ fn retWithErrTracing( | ... | @@ -19524,12 +19695,14 @@ fn retWithErrTracing( |
| 19524 | } | 19695 | } |
| 19525 | 19696 | ||
| 19526 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { | 19697 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 19527 | const mod = sema.mod; | 19698 | const pt = sema.pt; |
| 19699 | const mod = pt.zcu; | ||
| 19528 | return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing; | 19700 | return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing; |
| 19529 | } | 19701 | } |
| 19530 | 19702 | ||
| 19531 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 19703 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 19532 | const mod = sema.mod; | 19704 | const pt = sema.pt; |
| 19705 | const mod = pt.zcu; | ||
| 19533 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; | 19706 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; |
| 19534 | 19707 | ||
| 19535 | if (!block.ownerModule().error_tracing) return; | 19708 | if (!block.ownerModule().error_tracing) return; |
| ... | @@ -19559,7 +19732,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ | ... | @@ -19559,7 +19732,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19559 | const tracy = trace(@src()); | 19732 | const tracy = trace(@src()); |
| 19560 | defer tracy.end(); | 19733 | defer tracy.end(); |
| 19561 | 19734 | ||
| 19562 | const mod = sema.mod; | 19735 | const pt = sema.pt; |
| 19736 | const mod = pt.zcu; | ||
| 19563 | 19737 | ||
| 19564 | const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: { | 19738 | const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: { |
| 19565 | var block = start_block; | 19739 | var block = start_block; |
| ... | @@ -19597,7 +19771,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ | ... | @@ -19597,7 +19771,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19597 | if (is_non_error) return; | 19771 | if (is_non_error) return; |
| 19598 | 19772 | ||
| 19599 | const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index); | 19773 | const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index); |
| 19600 | const saved_index_int = saved_index_val.?.toUnsignedInt(mod); | 19774 | const saved_index_int = saved_index_val.?.toUnsignedInt(pt); |
| 19601 | assert(saved_index_int <= sema.comptime_err_ret_trace.items.len); | 19775 | assert(saved_index_int <= sema.comptime_err_ret_trace.items.len); |
| 19602 | sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int); | 19776 | sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int); |
| 19603 | return; | 19777 | return; |
| ... | @@ -19612,7 +19786,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ | ... | @@ -19612,7 +19786,8 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19612 | } | 19786 | } |
| 19613 | 19787 | ||
| 19614 | fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { | 19788 | fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| 19615 | const mod = sema.mod; | 19789 | const pt = sema.pt; |
| 19790 | const mod = pt.zcu; | ||
| 19616 | const ip = &mod.intern_pool; | 19791 | const ip = &mod.intern_pool; |
| 19617 | assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion); | 19792 | assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion); |
| 19618 | const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern(); | 19793 | const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern(); |
| ... | @@ -19632,7 +19807,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { | ... | @@ -19632,7 +19807,8 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| 19632 | 19807 | ||
| 19633 | fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void { | 19808 | fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void { |
| 19634 | const arena = sema.arena; | 19809 | const arena = sema.arena; |
| 19635 | const mod = sema.mod; | 19810 | const pt = sema.pt; |
| 19811 | const mod = pt.zcu; | ||
| 19636 | const ip = &mod.intern_pool; | 19812 | const ip = &mod.intern_pool; |
| 19637 | switch (op_ty.zigTypeTag(mod)) { | 19813 | switch (op_ty.zigTypeTag(mod)) { |
| 19638 | .ErrorSet => try ies.addErrorSet(op_ty, ip, arena), | 19814 | .ErrorSet => try ies.addErrorSet(op_ty, ip, arena), |
| ... | @@ -19651,7 +19827,8 @@ fn analyzeRet( | ... | @@ -19651,7 +19827,8 @@ fn analyzeRet( |
| 19651 | // Special case for returning an error to an inferred error set; we need to | 19827 | // Special case for returning an error to an inferred error set; we need to |
| 19652 | // add the error tag to the inferred error set of the in-scope function, so | 19828 | // add the error tag to the inferred error set of the in-scope function, so |
| 19653 | // that the coercion below works correctly. | 19829 | // that the coercion below works correctly. |
| 19654 | const mod = sema.mod; | 19830 | const pt = sema.pt; |
| 19831 | const mod = pt.zcu; | ||
| 19655 | if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) { | 19832 | if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) { |
| 19656 | try sema.addToInferredErrorSet(uncasted_operand); | 19833 | try sema.addToInferredErrorSet(uncasted_operand); |
| 19657 | } | 19834 | } |
| ... | @@ -19691,7 +19868,7 @@ fn analyzeRet( | ... | @@ -19691,7 +19868,7 @@ fn analyzeRet( |
| 19691 | return sema.failWithOwnedErrorMsg(block, msg); | 19868 | return sema.failWithOwnedErrorMsg(block, msg); |
| 19692 | } | 19869 | } |
| 19693 | 19870 | ||
| 19694 | try sema.fn_ret_ty.resolveLayout(mod); | 19871 | try sema.fn_ret_ty.resolveLayout(pt); |
| 19695 | 19872 | ||
| 19696 | try sema.validateRuntimeValue(block, operand_src, operand); | 19873 | try sema.validateRuntimeValue(block, operand_src, operand); |
| 19697 | 19874 | ||
| ... | @@ -19718,7 +19895,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19718,7 +19895,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19718 | const tracy = trace(@src()); | 19895 | const tracy = trace(@src()); |
| 19719 | defer tracy.end(); | 19896 | defer tracy.end(); |
| 19720 | 19897 | ||
| 19721 | const mod = sema.mod; | 19898 | const pt = sema.pt; |
| 19899 | const mod = pt.zcu; | ||
| 19722 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type; | 19900 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type; |
| 19723 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); | 19901 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); |
| 19724 | const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node }); | 19902 | const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node }); |
| ... | @@ -19773,7 +19951,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19773,7 +19951,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19773 | }, | 19951 | }, |
| 19774 | else => {}, | 19952 | else => {}, |
| 19775 | } | 19953 | } |
| 19776 | const align_bytes = (try val.getUnsignedIntAdvanced(mod, .sema)).?; | 19954 | const align_bytes = (try val.getUnsignedIntAdvanced(pt, .sema)).?; |
| 19777 | break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes); | 19955 | break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes); |
| 19778 | } else .none; | 19956 | } else .none; |
| 19779 | 19957 | ||
| ... | @@ -19804,13 +19982,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19804,13 +19982,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19804 | if (host_size != 0) { | 19982 | if (host_size != 0) { |
| 19805 | if (bit_offset >= host_size * 8) { | 19983 | if (bit_offset >= host_size * 8) { |
| 19806 | return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{ | 19984 | return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{ |
| 19807 | elem_ty.fmt(mod), bit_offset, bit_offset - host_size * 8, host_size, | 19985 | elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size, |
| 19808 | }); | 19986 | }); |
| 19809 | } | 19987 | } |
| 19810 | const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, .sema); | 19988 | const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, .sema); |
| 19811 | if (elem_bit_size > host_size * 8 - bit_offset) { | 19989 | if (elem_bit_size > host_size * 8 - bit_offset) { |
| 19812 | return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{ | 19990 | return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{ |
| 19813 | elem_ty.fmt(mod), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size, | 19991 | elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size, |
| 19814 | }); | 19992 | }); |
| 19815 | } | 19993 | } |
| 19816 | } | 19994 | } |
| ... | @@ -19824,7 +20002,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19824,7 +20002,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19824 | } else if (inst_data.size == .C) { | 20002 | } else if (inst_data.size == .C) { |
| 19825 | if (!try sema.validateExternType(elem_ty, .other)) { | 20003 | if (!try sema.validateExternType(elem_ty, .other)) { |
| 19826 | const msg = msg: { | 20004 | const msg = msg: { |
| 19827 | const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)}); | 20005 | const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)}); |
| 19828 | errdefer msg.destroy(sema.gpa); | 20006 | errdefer msg.destroy(sema.gpa); |
| 19829 | 20007 | ||
| 19830 | try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other); | 20008 | try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other); |
| ... | @@ -19841,14 +20019,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19841,14 +20019,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19841 | 20019 | ||
| 19842 | if (host_size != 0 and !try sema.validatePackedType(elem_ty)) { | 20020 | if (host_size != 0 and !try sema.validatePackedType(elem_ty)) { |
| 19843 | return sema.failWithOwnedErrorMsg(block, msg: { | 20021 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 19844 | const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(mod)}); | 20022 | const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(pt)}); |
| 19845 | errdefer msg.destroy(sema.gpa); | 20023 | errdefer msg.destroy(sema.gpa); |
| 19846 | try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty); | 20024 | try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty); |
| 19847 | break :msg msg; | 20025 | break :msg msg; |
| 19848 | }); | 20026 | }); |
| 19849 | } | 20027 | } |
| 19850 | 20028 | ||
| 19851 | const ty = try mod.ptrTypeSema(.{ | 20029 | const ty = try pt.ptrTypeSema(.{ |
| 19852 | .child = elem_ty.toIntern(), | 20030 | .child = elem_ty.toIntern(), |
| 19853 | .sentinel = sentinel, | 20031 | .sentinel = sentinel, |
| 19854 | .flags = .{ | 20032 | .flags = .{ |
| ... | @@ -19875,7 +20053,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -19875,7 +20053,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 19875 | const src = block.nodeOffset(inst_data.src_node); | 20053 | const src = block.nodeOffset(inst_data.src_node); |
| 19876 | const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node }); | 20054 | const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node }); |
| 19877 | const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand); | 20055 | const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 19878 | const mod = sema.mod; | 20056 | const pt = sema.pt; |
| 20057 | const mod = pt.zcu; | ||
| 19879 | 20058 | ||
| 19880 | switch (obj_ty.zigTypeTag(mod)) { | 20059 | switch (obj_ty.zigTypeTag(mod)) { |
| 19881 | .Struct => return sema.structInitEmpty(block, obj_ty, src, src), | 20060 | .Struct => return sema.structInitEmpty(block, obj_ty, src, src), |
| ... | @@ -19890,7 +20069,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is | ... | @@ -19890,7 +20069,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is |
| 19890 | const tracy = trace(@src()); | 20069 | const tracy = trace(@src()); |
| 19891 | defer tracy.end(); | 20070 | defer tracy.end(); |
| 19892 | 20071 | ||
| 19893 | const mod = sema.mod; | 20072 | const pt = sema.pt; |
| 20073 | const mod = pt.zcu; | ||
| 19894 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 20074 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19895 | const src = block.nodeOffset(inst_data.src_node); | 20075 | const src = block.nodeOffset(inst_data.src_node); |
| 19896 | const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { | 20076 | const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { |
| ... | @@ -19905,7 +20085,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is | ... | @@ -19905,7 +20085,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is |
| 19905 | break :ty ptr_ty.childType(mod); | 20085 | break :ty ptr_ty.childType(mod); |
| 19906 | } | 20086 | } |
| 19907 | // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`. | 20087 | // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`. |
| 19908 | break :ty try mod.arrayType(.{ | 20088 | break :ty try pt.arrayType(.{ |
| 19909 | .len = 0, | 20089 | .len = 0, |
| 19910 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | 20090 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| 19911 | .child = ptr_ty.childType(mod).toIntern(), | 20091 | .child = ptr_ty.childType(mod).toIntern(), |
| ... | @@ -19936,10 +20116,11 @@ fn structInitEmpty( | ... | @@ -19936,10 +20116,11 @@ fn structInitEmpty( |
| 19936 | dest_src: LazySrcLoc, | 20116 | dest_src: LazySrcLoc, |
| 19937 | init_src: LazySrcLoc, | 20117 | init_src: LazySrcLoc, |
| 19938 | ) CompileError!Air.Inst.Ref { | 20118 | ) CompileError!Air.Inst.Ref { |
| 19939 | const mod = sema.mod; | 20119 | const pt = sema.pt; |
| 20120 | const mod = pt.zcu; | ||
| 19940 | const gpa = sema.gpa; | 20121 | const gpa = sema.gpa; |
| 19941 | // This logic must be synchronized with that in `zirStructInit`. | 20122 | // This logic must be synchronized with that in `zirStructInit`. |
| 19942 | try struct_ty.resolveFields(mod); | 20123 | try struct_ty.resolveFields(pt); |
| 19943 | 20124 | ||
| 19944 | // The init values to use for the struct instance. | 20125 | // The init values to use for the struct instance. |
| 19945 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod)); | 20126 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod)); |
| ... | @@ -19950,7 +20131,8 @@ fn structInitEmpty( | ... | @@ -19950,7 +20131,8 @@ fn structInitEmpty( |
| 19950 | } | 20131 | } |
| 19951 | 20132 | ||
| 19952 | fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref { | 20133 | fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref { |
| 19953 | const mod = sema.mod; | 20134 | const pt = sema.pt; |
| 20135 | const mod = pt.zcu; | ||
| 19954 | const arr_len = obj_ty.arrayLen(mod); | 20136 | const arr_len = obj_ty.arrayLen(mod); |
| 19955 | if (arr_len != 0) { | 20137 | if (arr_len != 0) { |
| 19956 | if (obj_ty.zigTypeTag(mod) == .Array) { | 20138 | if (obj_ty.zigTypeTag(mod) == .Array) { |
| ... | @@ -19959,21 +20141,22 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com | ... | @@ -19959,21 +20141,22 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com |
| 19959 | return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len}); | 20141 | return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len}); |
| 19960 | } | 20142 | } |
| 19961 | } | 20143 | } |
| 19962 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 20144 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 19963 | .ty = obj_ty.toIntern(), | 20145 | .ty = obj_ty.toIntern(), |
| 19964 | .storage = .{ .elems = &.{} }, | 20146 | .storage = .{ .elems = &.{} }, |
| 19965 | } }))); | 20147 | } }))); |
| 19966 | } | 20148 | } |
| 19967 | 20149 | ||
| 19968 | fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 20150 | fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 20151 | const pt = sema.pt; | ||
| 19969 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 20152 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19970 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 20153 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 19971 | const field_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 20154 | const field_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 19972 | const init_src = block.builtinCallArgSrc(inst_data.src_node, 2); | 20155 | const init_src = block.builtinCallArgSrc(inst_data.src_node, 2); |
| 19973 | const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; | 20156 | const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; |
| 19974 | const union_ty = try sema.resolveType(block, ty_src, extra.union_type); | 20157 | const union_ty = try sema.resolveType(block, ty_src, extra.union_type); |
| 19975 | if (union_ty.zigTypeTag(sema.mod) != .Union) { | 20158 | if (union_ty.zigTypeTag(pt.zcu) != .Union) { |
| 19976 | return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)}); | 20159 | return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(pt)}); |
| 19977 | } | 20160 | } |
| 19978 | const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ | 20161 | const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ |
| 19979 | .needed_comptime_reason = "name of field being initialized must be comptime-known", | 20162 | .needed_comptime_reason = "name of field being initialized must be comptime-known", |
| ... | @@ -19992,7 +20175,8 @@ fn unionInit( | ... | @@ -19992,7 +20175,8 @@ fn unionInit( |
| 19992 | field_name: InternPool.NullTerminatedString, | 20175 | field_name: InternPool.NullTerminatedString, |
| 19993 | field_src: LazySrcLoc, | 20176 | field_src: LazySrcLoc, |
| 19994 | ) CompileError!Air.Inst.Ref { | 20177 | ) CompileError!Air.Inst.Ref { |
| 19995 | const mod = sema.mod; | 20178 | const pt = sema.pt; |
| 20179 | const mod = pt.zcu; | ||
| 19996 | const ip = &mod.intern_pool; | 20180 | const ip = &mod.intern_pool; |
| 19997 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); | 20181 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| 19998 | const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); | 20182 | const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); |
| ... | @@ -20000,8 +20184,8 @@ fn unionInit( | ... | @@ -20000,8 +20184,8 @@ fn unionInit( |
| 20000 | 20184 | ||
| 20001 | if (try sema.resolveValue(init)) |init_val| { | 20185 | if (try sema.resolveValue(init)) |init_val| { |
| 20002 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | 20186 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); |
| 20003 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); | 20187 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 20004 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 20188 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 20005 | .ty = union_ty.toIntern(), | 20189 | .ty = union_ty.toIntern(), |
| 20006 | .tag = tag_val.toIntern(), | 20190 | .tag = tag_val.toIntern(), |
| 20007 | .val = init_val.toIntern(), | 20191 | .val = init_val.toIntern(), |
| ... | @@ -20025,7 +20209,8 @@ fn zirStructInit( | ... | @@ -20025,7 +20209,8 @@ fn zirStructInit( |
| 20025 | const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index); | 20209 | const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index); |
| 20026 | const src = block.nodeOffset(inst_data.src_node); | 20210 | const src = block.nodeOffset(inst_data.src_node); |
| 20027 | 20211 | ||
| 20028 | const mod = sema.mod; | 20212 | const pt = sema.pt; |
| 20213 | const mod = pt.zcu; | ||
| 20029 | const ip = &mod.intern_pool; | 20214 | const ip = &mod.intern_pool; |
| 20030 | const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data; | 20215 | const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data; |
| 20031 | const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node; | 20216 | const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node; |
| ... | @@ -20038,7 +20223,7 @@ fn zirStructInit( | ... | @@ -20038,7 +20223,7 @@ fn zirStructInit( |
| 20038 | else => |e| return e, | 20223 | else => |e| return e, |
| 20039 | }; | 20224 | }; |
| 20040 | const resolved_ty = result_ty.optEuBaseType(mod); | 20225 | const resolved_ty = result_ty.optEuBaseType(mod); |
| 20041 | try resolved_ty.resolveLayout(mod); | 20226 | try resolved_ty.resolveLayout(pt); |
| 20042 | 20227 | ||
| 20043 | if (resolved_ty.zigTypeTag(mod) == .Struct) { | 20228 | if (resolved_ty.zigTypeTag(mod) == .Struct) { |
| 20044 | // This logic must be synchronized with that in `zirStructInitEmpty`. | 20229 | // This logic must be synchronized with that in `zirStructInitEmpty`. |
| ... | @@ -20079,8 +20264,8 @@ fn zirStructInit( | ... | @@ -20079,8 +20264,8 @@ fn zirStructInit( |
| 20079 | const field_ty = resolved_ty.structFieldType(field_index, mod); | 20264 | const field_ty = resolved_ty.structFieldType(field_index, mod); |
| 20080 | field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src); | 20265 | field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src); |
| 20081 | if (!is_packed) { | 20266 | if (!is_packed) { |
| 20082 | try resolved_ty.resolveStructFieldInits(mod); | 20267 | try resolved_ty.resolveStructFieldInits(pt); |
| 20083 | if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 20268 | if (try resolved_ty.structFieldValueComptime(pt, field_index)) |default_value| { |
| 20084 | const init_val = (try sema.resolveValue(field_inits[field_index])) orelse { | 20269 | const init_val = (try sema.resolveValue(field_inits[field_index])) orelse { |
| 20085 | return sema.failWithNeededComptime(block, field_src, .{ | 20270 | return sema.failWithNeededComptime(block, field_src, .{ |
| 20086 | .needed_comptime_reason = "value stored in comptime field must be comptime-known", | 20271 | .needed_comptime_reason = "value stored in comptime field must be comptime-known", |
| ... | @@ -20112,7 +20297,7 @@ fn zirStructInit( | ... | @@ -20112,7 +20297,7 @@ fn zirStructInit( |
| 20112 | ); | 20297 | ); |
| 20113 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); | 20298 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 20114 | const tag_ty = resolved_ty.unionTagTypeHypothetical(mod); | 20299 | const tag_ty = resolved_ty.unionTagTypeHypothetical(mod); |
| 20115 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); | 20300 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 20116 | const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); | 20301 | const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); |
| 20117 | 20302 | ||
| 20118 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | 20303 | if (field_ty.zigTypeTag(mod) == .NoReturn) { |
| ... | @@ -20132,11 +20317,11 @@ fn zirStructInit( | ... | @@ -20132,11 +20317,11 @@ fn zirStructInit( |
| 20132 | const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src); | 20317 | const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src); |
| 20133 | 20318 | ||
| 20134 | if (try sema.resolveValue(init_inst)) |val| { | 20319 | if (try sema.resolveValue(init_inst)) |val| { |
| 20135 | const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{ | 20320 | const struct_val = Value.fromInterned(try pt.intern(.{ .un = .{ |
| 20136 | .ty = resolved_ty.toIntern(), | 20321 | .ty = resolved_ty.toIntern(), |
| 20137 | .tag = tag_val.toIntern(), | 20322 | .tag = tag_val.toIntern(), |
| 20138 | .val = val.toIntern(), | 20323 | .val = val.toIntern(), |
| 20139 | } }))); | 20324 | } })); |
| 20140 | const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src); | 20325 | const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src); |
| 20141 | const final_val = (try sema.resolveValue(final_val_inst)).?; | 20326 | const final_val = (try sema.resolveValue(final_val_inst)).?; |
| 20142 | return sema.addConstantMaybeRef(final_val.toIntern(), is_ref); | 20327 | return sema.addConstantMaybeRef(final_val.toIntern(), is_ref); |
| ... | @@ -20152,7 +20337,7 @@ fn zirStructInit( | ... | @@ -20152,7 +20337,7 @@ fn zirStructInit( |
| 20152 | 20337 | ||
| 20153 | if (is_ref) { | 20338 | if (is_ref) { |
| 20154 | const target = mod.getTarget(); | 20339 | const target = mod.getTarget(); |
| 20155 | const alloc_ty = try mod.ptrTypeSema(.{ | 20340 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20156 | .child = result_ty.toIntern(), | 20341 | .child = result_ty.toIntern(), |
| 20157 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20342 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20158 | }); | 20343 | }); |
| ... | @@ -20182,7 +20367,8 @@ fn finishStructInit( | ... | @@ -20182,7 +20367,8 @@ fn finishStructInit( |
| 20182 | result_ty: Type, | 20367 | result_ty: Type, |
| 20183 | is_ref: bool, | 20368 | is_ref: bool, |
| 20184 | ) CompileError!Air.Inst.Ref { | 20369 | ) CompileError!Air.Inst.Ref { |
| 20185 | const mod = sema.mod; | 20370 | const pt = sema.pt; |
| 20371 | const mod = pt.zcu; | ||
| 20186 | const ip = &mod.intern_pool; | 20372 | const ip = &mod.intern_pool; |
| 20187 | 20373 | ||
| 20188 | var root_msg: ?*Module.ErrorMsg = null; | 20374 | var root_msg: ?*Module.ErrorMsg = null; |
| ... | @@ -20242,7 +20428,7 @@ fn finishStructInit( | ... | @@ -20242,7 +20428,7 @@ fn finishStructInit( |
| 20242 | continue; | 20428 | continue; |
| 20243 | } | 20429 | } |
| 20244 | 20430 | ||
| 20245 | try struct_ty.resolveStructFieldInits(mod); | 20431 | try struct_ty.resolveStructFieldInits(pt); |
| 20246 | 20432 | ||
| 20247 | const field_init = struct_type.fieldInit(ip, i); | 20433 | const field_init = struct_type.fieldInit(ip, i); |
| 20248 | if (field_init == .none) { | 20434 | if (field_init == .none) { |
| ... | @@ -20289,7 +20475,7 @@ fn finishStructInit( | ... | @@ -20289,7 +20475,7 @@ fn finishStructInit( |
| 20289 | for (elems, field_inits) |*elem, field_init| { | 20475 | for (elems, field_inits) |*elem, field_init| { |
| 20290 | elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern(); | 20476 | elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern(); |
| 20291 | } | 20477 | } |
| 20292 | const struct_val = try mod.intern(.{ .aggregate = .{ | 20478 | const struct_val = try pt.intern(.{ .aggregate = .{ |
| 20293 | .ty = struct_ty.toIntern(), | 20479 | .ty = struct_ty.toIntern(), |
| 20294 | .storage = .{ .elems = elems }, | 20480 | .storage = .{ .elems = elems }, |
| 20295 | } }); | 20481 | } }); |
| ... | @@ -20312,9 +20498,9 @@ fn finishStructInit( | ... | @@ -20312,9 +20498,9 @@ fn finishStructInit( |
| 20312 | } | 20498 | } |
| 20313 | 20499 | ||
| 20314 | if (is_ref) { | 20500 | if (is_ref) { |
| 20315 | try struct_ty.resolveLayout(mod); | 20501 | try struct_ty.resolveLayout(pt); |
| 20316 | const target = sema.mod.getTarget(); | 20502 | const target = mod.getTarget(); |
| 20317 | const alloc_ty = try mod.ptrTypeSema(.{ | 20503 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20318 | .child = result_ty.toIntern(), | 20504 | .child = result_ty.toIntern(), |
| 20319 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20505 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20320 | }); | 20506 | }); |
| ... | @@ -20334,7 +20520,7 @@ fn finishStructInit( | ... | @@ -20334,7 +20520,7 @@ fn finishStructInit( |
| 20334 | .init_node_offset = init_src.offset.node_offset.x, | 20520 | .init_node_offset = init_src.offset.node_offset.x, |
| 20335 | .elem_index = @intCast(runtime_index), | 20521 | .elem_index = @intCast(runtime_index), |
| 20336 | } })); | 20522 | } })); |
| 20337 | try struct_ty.resolveStructFieldInits(mod); | 20523 | try struct_ty.resolveStructFieldInits(pt); |
| 20338 | const struct_val = try block.addAggregateInit(struct_ty, field_inits); | 20524 | const struct_val = try block.addAggregateInit(struct_ty, field_inits); |
| 20339 | return sema.coerce(block, result_ty, struct_val, init_src); | 20525 | return sema.coerce(block, result_ty, struct_val, init_src); |
| 20340 | } | 20526 | } |
| ... | @@ -20364,7 +20550,8 @@ fn structInitAnon( | ... | @@ -20364,7 +20550,8 @@ fn structInitAnon( |
| 20364 | extra_end: usize, | 20550 | extra_end: usize, |
| 20365 | is_ref: bool, | 20551 | is_ref: bool, |
| 20366 | ) CompileError!Air.Inst.Ref { | 20552 | ) CompileError!Air.Inst.Ref { |
| 20367 | const mod = sema.mod; | 20553 | const pt = sema.pt; |
| 20554 | const mod = pt.zcu; | ||
| 20368 | const gpa = sema.gpa; | 20555 | const gpa = sema.gpa; |
| 20369 | const ip = &mod.intern_pool; | 20556 | const ip = &mod.intern_pool; |
| 20370 | const zir_datas = sema.code.instructions.items(.data); | 20557 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -20422,14 +20609,14 @@ fn structInitAnon( | ... | @@ -20422,14 +20609,14 @@ fn structInitAnon( |
| 20422 | break :rs runtime_index; | 20609 | break :rs runtime_index; |
| 20423 | }; | 20610 | }; |
| 20424 | 20611 | ||
| 20425 | const tuple_ty = try ip.getAnonStructType(gpa, .{ | 20612 | const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{ |
| 20426 | .names = names, | 20613 | .names = names, |
| 20427 | .types = types, | 20614 | .types = types, |
| 20428 | .values = values, | 20615 | .values = values, |
| 20429 | }); | 20616 | }); |
| 20430 | 20617 | ||
| 20431 | const runtime_index = opt_runtime_index orelse { | 20618 | const runtime_index = opt_runtime_index orelse { |
| 20432 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 20619 | const tuple_val = try pt.intern(.{ .aggregate = .{ |
| 20433 | .ty = tuple_ty, | 20620 | .ty = tuple_ty, |
| 20434 | .storage = .{ .elems = values }, | 20621 | .storage = .{ .elems = values }, |
| 20435 | } }); | 20622 | } }); |
| ... | @@ -20443,7 +20630,7 @@ fn structInitAnon( | ... | @@ -20443,7 +20630,7 @@ fn structInitAnon( |
| 20443 | 20630 | ||
| 20444 | if (is_ref) { | 20631 | if (is_ref) { |
| 20445 | const target = mod.getTarget(); | 20632 | const target = mod.getTarget(); |
| 20446 | const alloc_ty = try mod.ptrTypeSema(.{ | 20633 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20447 | .child = tuple_ty, | 20634 | .child = tuple_ty, |
| 20448 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20635 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20449 | }); | 20636 | }); |
| ... | @@ -20457,7 +20644,7 @@ fn structInitAnon( | ... | @@ -20457,7 +20644,7 @@ fn structInitAnon( |
| 20457 | }; | 20644 | }; |
| 20458 | extra_index = item.end; | 20645 | extra_index = item.end; |
| 20459 | 20646 | ||
| 20460 | const field_ptr_ty = try mod.ptrTypeSema(.{ | 20647 | const field_ptr_ty = try pt.ptrTypeSema(.{ |
| 20461 | .child = field_ty, | 20648 | .child = field_ty, |
| 20462 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20649 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20463 | }); | 20650 | }); |
| ... | @@ -20491,7 +20678,8 @@ fn zirArrayInit( | ... | @@ -20491,7 +20678,8 @@ fn zirArrayInit( |
| 20491 | inst: Zir.Inst.Index, | 20678 | inst: Zir.Inst.Index, |
| 20492 | is_ref: bool, | 20679 | is_ref: bool, |
| 20493 | ) CompileError!Air.Inst.Ref { | 20680 | ) CompileError!Air.Inst.Ref { |
| 20494 | const mod = sema.mod; | 20681 | const pt = sema.pt; |
| 20682 | const mod = pt.zcu; | ||
| 20495 | const gpa = sema.gpa; | 20683 | const gpa = sema.gpa; |
| 20496 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 20684 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 20497 | const src = block.nodeOffset(inst_data.src_node); | 20685 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -20550,8 +20738,8 @@ fn zirArrayInit( | ... | @@ -20550,8 +20738,8 @@ fn zirArrayInit( |
| 20550 | dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src); | 20738 | dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src); |
| 20551 | if (is_tuple) { | 20739 | if (is_tuple) { |
| 20552 | if (array_ty.structFieldIsComptime(i, mod)) | 20740 | if (array_ty.structFieldIsComptime(i, mod)) |
| 20553 | try array_ty.resolveStructFieldInits(mod); | 20741 | try array_ty.resolveStructFieldInits(pt); |
| 20554 | if (try array_ty.structFieldValueComptime(mod, i)) |field_val| { | 20742 | if (try array_ty.structFieldValueComptime(pt, i)) |field_val| { |
| 20555 | const init_val = try sema.resolveValue(dest.*) orelse { | 20743 | const init_val = try sema.resolveValue(dest.*) orelse { |
| 20556 | return sema.failWithNeededComptime(block, elem_src, .{ | 20744 | return sema.failWithNeededComptime(block, elem_src, .{ |
| 20557 | .needed_comptime_reason = "value stored in comptime field must be comptime-known", | 20745 | .needed_comptime_reason = "value stored in comptime field must be comptime-known", |
| ... | @@ -20581,7 +20769,7 @@ fn zirArrayInit( | ... | @@ -20581,7 +20769,7 @@ fn zirArrayInit( |
| 20581 | // We checked that all args are comptime above. | 20769 | // We checked that all args are comptime above. |
| 20582 | val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern(); | 20770 | val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern(); |
| 20583 | } | 20771 | } |
| 20584 | const arr_val = try mod.intern(.{ .aggregate = .{ | 20772 | const arr_val = try pt.intern(.{ .aggregate = .{ |
| 20585 | .ty = array_ty.toIntern(), | 20773 | .ty = array_ty.toIntern(), |
| 20586 | .storage = .{ .elems = elem_vals }, | 20774 | .storage = .{ .elems = elem_vals }, |
| 20587 | } }); | 20775 | } }); |
| ... | @@ -20597,7 +20785,7 @@ fn zirArrayInit( | ... | @@ -20597,7 +20785,7 @@ fn zirArrayInit( |
| 20597 | 20785 | ||
| 20598 | if (is_ref) { | 20786 | if (is_ref) { |
| 20599 | const target = mod.getTarget(); | 20787 | const target = mod.getTarget(); |
| 20600 | const alloc_ty = try mod.ptrTypeSema(.{ | 20788 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20601 | .child = result_ty.toIntern(), | 20789 | .child = result_ty.toIntern(), |
| 20602 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20790 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20603 | }); | 20791 | }); |
| ... | @@ -20606,27 +20794,27 @@ fn zirArrayInit( | ... | @@ -20606,27 +20794,27 @@ fn zirArrayInit( |
| 20606 | 20794 | ||
| 20607 | if (is_tuple) { | 20795 | if (is_tuple) { |
| 20608 | for (resolved_args, 0..) |arg, i| { | 20796 | for (resolved_args, 0..) |arg, i| { |
| 20609 | const elem_ptr_ty = try mod.ptrTypeSema(.{ | 20797 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 20610 | .child = array_ty.structFieldType(i, mod).toIntern(), | 20798 | .child = array_ty.structFieldType(i, mod).toIntern(), |
| 20611 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20799 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20612 | }); | 20800 | }); |
| 20613 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); | 20801 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| 20614 | 20802 | ||
| 20615 | const index = try mod.intRef(Type.usize, i); | 20803 | const index = try pt.intRef(Type.usize, i); |
| 20616 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); | 20804 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); |
| 20617 | _ = try block.addBinOp(.store, elem_ptr, arg); | 20805 | _ = try block.addBinOp(.store, elem_ptr, arg); |
| 20618 | } | 20806 | } |
| 20619 | return sema.makePtrConst(block, alloc); | 20807 | return sema.makePtrConst(block, alloc); |
| 20620 | } | 20808 | } |
| 20621 | 20809 | ||
| 20622 | const elem_ptr_ty = try mod.ptrTypeSema(.{ | 20810 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 20623 | .child = array_ty.elemType2(mod).toIntern(), | 20811 | .child = array_ty.elemType2(mod).toIntern(), |
| 20624 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20812 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20625 | }); | 20813 | }); |
| 20626 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); | 20814 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| 20627 | 20815 | ||
| 20628 | for (resolved_args, 0..) |arg, i| { | 20816 | for (resolved_args, 0..) |arg, i| { |
| 20629 | const index = try mod.intRef(Type.usize, i); | 20817 | const index = try pt.intRef(Type.usize, i); |
| 20630 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); | 20818 | const elem_ptr = try block.addPtrElemPtrTypeRef(base_ptr, index, elem_ptr_ty_ref); |
| 20631 | _ = try block.addBinOp(.store, elem_ptr, arg); | 20819 | _ = try block.addBinOp(.store, elem_ptr, arg); |
| 20632 | } | 20820 | } |
| ... | @@ -20656,7 +20844,8 @@ fn arrayInitAnon( | ... | @@ -20656,7 +20844,8 @@ fn arrayInitAnon( |
| 20656 | operands: []const Zir.Inst.Ref, | 20844 | operands: []const Zir.Inst.Ref, |
| 20657 | is_ref: bool, | 20845 | is_ref: bool, |
| 20658 | ) CompileError!Air.Inst.Ref { | 20846 | ) CompileError!Air.Inst.Ref { |
| 20659 | const mod = sema.mod; | 20847 | const pt = sema.pt; |
| 20848 | const mod = pt.zcu; | ||
| 20660 | const gpa = sema.gpa; | 20849 | const gpa = sema.gpa; |
| 20661 | const ip = &mod.intern_pool; | 20850 | const ip = &mod.intern_pool; |
| 20662 | 20851 | ||
| ... | @@ -20689,14 +20878,14 @@ fn arrayInitAnon( | ... | @@ -20689,14 +20878,14 @@ fn arrayInitAnon( |
| 20689 | break :rs runtime_src; | 20878 | break :rs runtime_src; |
| 20690 | }; | 20879 | }; |
| 20691 | 20880 | ||
| 20692 | const tuple_ty = try ip.getAnonStructType(gpa, .{ | 20881 | const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{ |
| 20693 | .types = types, | 20882 | .types = types, |
| 20694 | .values = values, | 20883 | .values = values, |
| 20695 | .names = &.{}, | 20884 | .names = &.{}, |
| 20696 | }); | 20885 | }); |
| 20697 | 20886 | ||
| 20698 | const runtime_src = opt_runtime_src orelse { | 20887 | const runtime_src = opt_runtime_src orelse { |
| 20699 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 20888 | const tuple_val = try pt.intern(.{ .aggregate = .{ |
| 20700 | .ty = tuple_ty, | 20889 | .ty = tuple_ty, |
| 20701 | .storage = .{ .elems = values }, | 20890 | .storage = .{ .elems = values }, |
| 20702 | } }); | 20891 | } }); |
| ... | @@ -20706,15 +20895,15 @@ fn arrayInitAnon( | ... | @@ -20706,15 +20895,15 @@ fn arrayInitAnon( |
| 20706 | try sema.requireRuntimeBlock(block, src, runtime_src); | 20895 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 20707 | 20896 | ||
| 20708 | if (is_ref) { | 20897 | if (is_ref) { |
| 20709 | const target = sema.mod.getTarget(); | 20898 | const target = sema.pt.zcu.getTarget(); |
| 20710 | const alloc_ty = try mod.ptrTypeSema(.{ | 20899 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20711 | .child = tuple_ty, | 20900 | .child = tuple_ty, |
| 20712 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20901 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20713 | }); | 20902 | }); |
| 20714 | const alloc = try block.addTy(.alloc, alloc_ty); | 20903 | const alloc = try block.addTy(.alloc, alloc_ty); |
| 20715 | for (operands, 0..) |operand, i_usize| { | 20904 | for (operands, 0..) |operand, i_usize| { |
| 20716 | const i: u32 = @intCast(i_usize); | 20905 | const i: u32 = @intCast(i_usize); |
| 20717 | const field_ptr_ty = try mod.ptrTypeSema(.{ | 20906 | const field_ptr_ty = try pt.ptrTypeSema(.{ |
| 20718 | .child = types[i], | 20907 | .child = types[i], |
| 20719 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, | 20908 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20720 | }); | 20909 | }); |
| ... | @@ -20752,7 +20941,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -20752,7 +20941,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 20752 | } | 20941 | } |
| 20753 | 20942 | ||
| 20754 | fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 20943 | fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 20755 | const mod = sema.mod; | 20944 | const pt = sema.pt; |
| 20945 | const mod = pt.zcu; | ||
| 20756 | const ip = &mod.intern_pool; | 20946 | const ip = &mod.intern_pool; |
| 20757 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 20947 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 20758 | const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; | 20948 | const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; |
| ... | @@ -20780,11 +20970,12 @@ fn fieldType( | ... | @@ -20780,11 +20970,12 @@ fn fieldType( |
| 20780 | field_src: LazySrcLoc, | 20970 | field_src: LazySrcLoc, |
| 20781 | ty_src: LazySrcLoc, | 20971 | ty_src: LazySrcLoc, |
| 20782 | ) CompileError!Air.Inst.Ref { | 20972 | ) CompileError!Air.Inst.Ref { |
| 20783 | const mod = sema.mod; | 20973 | const pt = sema.pt; |
| 20974 | const mod = pt.zcu; | ||
| 20784 | const ip = &mod.intern_pool; | 20975 | const ip = &mod.intern_pool; |
| 20785 | var cur_ty = aggregate_ty; | 20976 | var cur_ty = aggregate_ty; |
| 20786 | while (true) { | 20977 | while (true) { |
| 20787 | try cur_ty.resolveFields(mod); | 20978 | try cur_ty.resolveFields(pt); |
| 20788 | switch (cur_ty.zigTypeTag(mod)) { | 20979 | switch (cur_ty.zigTypeTag(mod)) { |
| 20789 | .Struct => switch (ip.indexToKey(cur_ty.toIntern())) { | 20980 | .Struct => switch (ip.indexToKey(cur_ty.toIntern())) { |
| 20790 | .anon_struct_type => |anon_struct| { | 20981 | .anon_struct_type => |anon_struct| { |
| ... | @@ -20823,7 +21014,7 @@ fn fieldType( | ... | @@ -20823,7 +21014,7 @@ fn fieldType( |
| 20823 | else => {}, | 21014 | else => {}, |
| 20824 | } | 21015 | } |
| 20825 | return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{ | 21016 | return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{ |
| 20826 | cur_ty.fmt(sema.mod), | 21017 | cur_ty.fmt(pt), |
| 20827 | }); | 21018 | }); |
| 20828 | } | 21019 | } |
| 20829 | } | 21020 | } |
| ... | @@ -20833,12 +21024,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -20833,12 +21024,13 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 20833 | } | 21024 | } |
| 20834 | 21025 | ||
| 20835 | fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | 21026 | fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 20836 | const mod = sema.mod; | 21027 | const pt = sema.pt; |
| 21028 | const mod = pt.zcu; | ||
| 20837 | const ip = &mod.intern_pool; | 21029 | const ip = &mod.intern_pool; |
| 20838 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 21030 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 20839 | try stack_trace_ty.resolveFields(mod); | 21031 | try stack_trace_ty.resolveFields(pt); |
| 20840 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); | 21032 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 20841 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); | 21033 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| 20842 | 21034 | ||
| 20843 | if (sema.owner_func_index != .none and | 21035 | if (sema.owner_func_index != .none and |
| 20844 | ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and | 21036 | ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and |
| ... | @@ -20846,7 +21038,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -20846,7 +21038,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 20846 | { | 21038 | { |
| 20847 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); | 21039 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 20848 | } | 21040 | } |
| 20849 | return Air.internedToRef((try mod.intern(.{ .opt = .{ | 21041 | return Air.internedToRef((try pt.intern(.{ .opt = .{ |
| 20850 | .ty = opt_ptr_stack_trace_ty.toIntern(), | 21042 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| 20851 | .val = .none, | 21043 | .val = .none, |
| 20852 | } }))); | 21044 | } }))); |
| ... | @@ -20862,19 +21054,20 @@ fn zirFrame( | ... | @@ -20862,19 +21054,20 @@ fn zirFrame( |
| 20862 | } | 21054 | } |
| 20863 | 21055 | ||
| 20864 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 21056 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 20865 | const mod = sema.mod; | 21057 | const pt = sema.pt; |
| 20866 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 21058 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 20867 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 21059 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 20868 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); | 21060 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 20869 | if (ty.isNoReturn(mod)) { | 21061 | if (ty.isNoReturn(pt.zcu)) { |
| 20870 | return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)}); | 21062 | return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(pt)}); |
| 20871 | } | 21063 | } |
| 20872 | const val = try ty.lazyAbiAlignment(mod); | 21064 | const val = try ty.lazyAbiAlignment(pt); |
| 20873 | return Air.internedToRef(val.toIntern()); | 21065 | return Air.internedToRef(val.toIntern()); |
| 20874 | } | 21066 | } |
| 20875 | 21067 | ||
| 20876 | fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 21068 | fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 20877 | const mod = sema.mod; | 21069 | const pt = sema.pt; |
| 21070 | const mod = pt.zcu; | ||
| 20878 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 21071 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 20879 | const src = block.nodeOffset(inst_data.src_node); | 21072 | const src = block.nodeOffset(inst_data.src_node); |
| 20880 | const operand = try sema.resolveInst(inst_data.operand); | 21073 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | @@ -20886,25 +21079,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -20886,25 +21079,25 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 20886 | } | 21079 | } |
| 20887 | if (try sema.resolveValue(operand)) |val| { | 21080 | if (try sema.resolveValue(operand)) |val| { |
| 20888 | if (!is_vector) { | 21081 | if (!is_vector) { |
| 20889 | if (val.isUndef(mod)) return mod.undefRef(Type.u1); | 21082 | if (val.isUndef(mod)) return pt.undefRef(Type.u1); |
| 20890 | if (val.toBool()) return Air.internedToRef((try mod.intValue(Type.u1, 1)).toIntern()); | 21083 | if (val.toBool()) return Air.internedToRef((try pt.intValue(Type.u1, 1)).toIntern()); |
| 20891 | return Air.internedToRef((try mod.intValue(Type.u1, 0)).toIntern()); | 21084 | return Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); |
| 20892 | } | 21085 | } |
| 20893 | const len = operand_ty.vectorLen(mod); | 21086 | const len = operand_ty.vectorLen(mod); |
| 20894 | const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len }); | 21087 | const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len }); |
| 20895 | if (val.isUndef(mod)) return mod.undefRef(dest_ty); | 21088 | if (val.isUndef(mod)) return pt.undefRef(dest_ty); |
| 20896 | const new_elems = try sema.arena.alloc(InternPool.Index, len); | 21089 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 20897 | for (new_elems, 0..) |*new_elem, i| { | 21090 | for (new_elems, 0..) |*new_elem, i| { |
| 20898 | const old_elem = try val.elemValue(mod, i); | 21091 | const old_elem = try val.elemValue(pt, i); |
| 20899 | const new_val = if (old_elem.isUndef(mod)) | 21092 | const new_val = if (old_elem.isUndef(mod)) |
| 20900 | try mod.undefValue(Type.u1) | 21093 | try pt.undefValue(Type.u1) |
| 20901 | else if (old_elem.toBool()) | 21094 | else if (old_elem.toBool()) |
| 20902 | try mod.intValue(Type.u1, 1) | 21095 | try pt.intValue(Type.u1, 1) |
| 20903 | else | 21096 | else |
| 20904 | try mod.intValue(Type.u1, 0); | 21097 | try pt.intValue(Type.u1, 0); |
| 20905 | new_elem.* = new_val.toIntern(); | 21098 | new_elem.* = new_val.toIntern(); |
| 20906 | } | 21099 | } |
| 20907 | return Air.internedToRef(try mod.intern(.{ .aggregate = .{ | 21100 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 20908 | .ty = dest_ty.toIntern(), | 21101 | .ty = dest_ty.toIntern(), |
| 20909 | .storage = .{ .elems = new_elems }, | 21102 | .storage = .{ .elems = new_elems }, |
| 20910 | } })); | 21103 | } })); |
| ... | @@ -20913,10 +21106,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -20913,10 +21106,10 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 20913 | return block.addUnOp(.int_from_bool, operand); | 21106 | return block.addUnOp(.int_from_bool, operand); |
| 20914 | } | 21107 | } |
| 20915 | const len = operand_ty.vectorLen(mod); | 21108 | const len = operand_ty.vectorLen(mod); |
| 20916 | const dest_ty = try mod.vectorType(.{ .child = .u1_type, .len = len }); | 21109 | const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len }); |
| 20917 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | 21110 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 20918 | for (new_elems, 0..) |*new_elem, i| { | 21111 | for (new_elems, 0..) |*new_elem, i| { |
| 20919 | const idx_ref = try mod.intRef(Type.usize, i); | 21112 | const idx_ref = try pt.intRef(Type.usize, i); |
| 20920 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | 21113 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 20921 | new_elem.* = try block.addUnOp(.int_from_bool, old_elem); | 21114 | new_elem.* = try block.addUnOp(.int_from_bool, old_elem); |
| 20922 | } | 21115 | } |
| ... | @@ -20930,7 +21123,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -20930,7 +21123,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 20930 | const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src); | 21123 | const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src); |
| 20931 | 21124 | ||
| 20932 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { | 21125 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 20933 | const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name; | 21126 | const err_name = sema.pt.zcu.intern_pool.indexToKey(val.toIntern()).err.name; |
| 20934 | return sema.addNullTerminatedStrLit(err_name); | 21127 | return sema.addNullTerminatedStrLit(err_name); |
| 20935 | } | 21128 | } |
| 20936 | 21129 | ||
| ... | @@ -20944,7 +21137,8 @@ fn zirAbs( | ... | @@ -20944,7 +21137,8 @@ fn zirAbs( |
| 20944 | block: *Block, | 21137 | block: *Block, |
| 20945 | inst: Zir.Inst.Index, | 21138 | inst: Zir.Inst.Index, |
| 20946 | ) CompileError!Air.Inst.Ref { | 21139 | ) CompileError!Air.Inst.Ref { |
| 20947 | const mod = sema.mod; | 21140 | const pt = sema.pt; |
| 21141 | const mod = pt.zcu; | ||
| 20948 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 21142 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 20949 | const operand = try sema.resolveInst(inst_data.operand); | 21143 | const operand = try sema.resolveInst(inst_data.operand); |
| 20950 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 21144 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -20953,12 +21147,12 @@ fn zirAbs( | ... | @@ -20953,12 +21147,12 @@ fn zirAbs( |
| 20953 | 21147 | ||
| 20954 | const result_ty = switch (scalar_ty.zigTypeTag(mod)) { | 21148 | const result_ty = switch (scalar_ty.zigTypeTag(mod)) { |
| 20955 | .ComptimeFloat, .Float, .ComptimeInt => operand_ty, | 21149 | .ComptimeFloat, .Float, .ComptimeInt => operand_ty, |
| 20956 | .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(mod) else return operand, | 21150 | .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(pt) else return operand, |
| 20957 | else => return sema.fail( | 21151 | else => return sema.fail( |
| 20958 | block, | 21152 | block, |
| 20959 | operand_src, | 21153 | operand_src, |
| 20960 | "expected integer, float, or vector of either integers or floats, found '{}'", | 21154 | "expected integer, float, or vector of either integers or floats, found '{}'", |
| 20961 | .{operand_ty.fmt(mod)}, | 21155 | .{operand_ty.fmt(pt)}, |
| 20962 | ), | 21156 | ), |
| 20963 | }; | 21157 | }; |
| 20964 | 21158 | ||
| ... | @@ -20972,30 +21166,31 @@ fn maybeConstantUnaryMath( | ... | @@ -20972,30 +21166,31 @@ fn maybeConstantUnaryMath( |
| 20972 | sema: *Sema, | 21166 | sema: *Sema, |
| 20973 | operand: Air.Inst.Ref, | 21167 | operand: Air.Inst.Ref, |
| 20974 | result_ty: Type, | 21168 | result_ty: Type, |
| 20975 | comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value, | 21169 | comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value, |
| 20976 | ) CompileError!?Air.Inst.Ref { | 21170 | ) CompileError!?Air.Inst.Ref { |
| 20977 | const mod = sema.mod; | 21171 | const pt = sema.pt; |
| 21172 | const mod = pt.zcu; | ||
| 20978 | switch (result_ty.zigTypeTag(mod)) { | 21173 | switch (result_ty.zigTypeTag(mod)) { |
| 20979 | .Vector => if (try sema.resolveValue(operand)) |val| { | 21174 | .Vector => if (try sema.resolveValue(operand)) |val| { |
| 20980 | const scalar_ty = result_ty.scalarType(mod); | 21175 | const scalar_ty = result_ty.scalarType(mod); |
| 20981 | const vec_len = result_ty.vectorLen(mod); | 21176 | const vec_len = result_ty.vectorLen(mod); |
| 20982 | if (val.isUndef(mod)) | 21177 | if (val.isUndef(mod)) |
| 20983 | return try mod.undefRef(result_ty); | 21178 | return try pt.undefRef(result_ty); |
| 20984 | 21179 | ||
| 20985 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 21180 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 20986 | for (elems, 0..) |*elem, i| { | 21181 | for (elems, 0..) |*elem, i| { |
| 20987 | const elem_val = try val.elemValue(sema.mod, i); | 21182 | const elem_val = try val.elemValue(pt, i); |
| 20988 | elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern(); | 21183 | elem.* = (try eval(elem_val, scalar_ty, sema.arena, pt)).toIntern(); |
| 20989 | } | 21184 | } |
| 20990 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 21185 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 20991 | .ty = result_ty.toIntern(), | 21186 | .ty = result_ty.toIntern(), |
| 20992 | .storage = .{ .elems = elems }, | 21187 | .storage = .{ .elems = elems }, |
| 20993 | } }))); | 21188 | } }))); |
| 20994 | }, | 21189 | }, |
| 20995 | else => if (try sema.resolveValue(operand)) |operand_val| { | 21190 | else => if (try sema.resolveValue(operand)) |operand_val| { |
| 20996 | if (operand_val.isUndef(mod)) | 21191 | if (operand_val.isUndef(mod)) |
| 20997 | return try mod.undefRef(result_ty); | 21192 | return try pt.undefRef(result_ty); |
| 20998 | const result_val = try eval(operand_val, result_ty, sema.arena, sema.mod); | 21193 | const result_val = try eval(operand_val, result_ty, sema.arena, pt); |
| 20999 | return Air.internedToRef(result_val.toIntern()); | 21194 | return Air.internedToRef(result_val.toIntern()); |
| 21000 | }, | 21195 | }, |
| 21001 | } | 21196 | } |
| ... | @@ -21007,12 +21202,13 @@ fn zirUnaryMath( | ... | @@ -21007,12 +21202,13 @@ fn zirUnaryMath( |
| 21007 | block: *Block, | 21202 | block: *Block, |
| 21008 | inst: Zir.Inst.Index, | 21203 | inst: Zir.Inst.Index, |
| 21009 | air_tag: Air.Inst.Tag, | 21204 | air_tag: Air.Inst.Tag, |
| 21010 | comptime eval: fn (Value, Type, Allocator, *Module) Allocator.Error!Value, | 21205 | comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value, |
| 21011 | ) CompileError!Air.Inst.Ref { | 21206 | ) CompileError!Air.Inst.Ref { |
| 21012 | const tracy = trace(@src()); | 21207 | const tracy = trace(@src()); |
| 21013 | defer tracy.end(); | 21208 | defer tracy.end(); |
| 21014 | 21209 | ||
| 21015 | const mod = sema.mod; | 21210 | const pt = sema.pt; |
| 21211 | const mod = pt.zcu; | ||
| 21016 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 21212 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 21017 | const operand = try sema.resolveInst(inst_data.operand); | 21213 | const operand = try sema.resolveInst(inst_data.operand); |
| 21018 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 21214 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -21025,7 +21221,7 @@ fn zirUnaryMath( | ... | @@ -21025,7 +21221,7 @@ fn zirUnaryMath( |
| 21025 | block, | 21221 | block, |
| 21026 | operand_src, | 21222 | operand_src, |
| 21027 | "expected vector of floats or float type, found '{}'", | 21223 | "expected vector of floats or float type, found '{}'", |
| 21028 | .{operand_ty.fmt(sema.mod)}, | 21224 | .{operand_ty.fmt(pt)}, |
| 21029 | ), | 21225 | ), |
| 21030 | } | 21226 | } |
| 21031 | 21227 | ||
| ... | @@ -21041,10 +21237,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21041,10 +21237,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21041 | const src = block.nodeOffset(inst_data.src_node); | 21237 | const src = block.nodeOffset(inst_data.src_node); |
| 21042 | const operand = try sema.resolveInst(inst_data.operand); | 21238 | const operand = try sema.resolveInst(inst_data.operand); |
| 21043 | const operand_ty = sema.typeOf(operand); | 21239 | const operand_ty = sema.typeOf(operand); |
| 21044 | const mod = sema.mod; | 21240 | const pt = sema.pt; |
| 21241 | const mod = pt.zcu; | ||
| 21045 | const ip = &mod.intern_pool; | 21242 | const ip = &mod.intern_pool; |
| 21046 | 21243 | ||
| 21047 | try operand_ty.resolveLayout(mod); | 21244 | try operand_ty.resolveLayout(pt); |
| 21048 | const enum_ty = switch (operand_ty.zigTypeTag(mod)) { | 21245 | const enum_ty = switch (operand_ty.zigTypeTag(mod)) { |
| 21049 | .EnumLiteral => { | 21246 | .EnumLiteral => { |
| 21050 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined); | 21247 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined); |
| ... | @@ -21053,9 +21250,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21053,9 +21250,9 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21053 | }, | 21250 | }, |
| 21054 | .Enum => operand_ty, | 21251 | .Enum => operand_ty, |
| 21055 | .Union => operand_ty.unionTagType(mod) orelse | 21252 | .Union => operand_ty.unionTagType(mod) orelse |
| 21056 | return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}), | 21253 | return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}), |
| 21057 | else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{ | 21254 | else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{ |
| 21058 | operand_ty.fmt(mod), | 21255 | operand_ty.fmt(pt), |
| 21059 | }), | 21256 | }), |
| 21060 | }; | 21257 | }; |
| 21061 | if (enum_ty.enumFieldCount(mod) == 0) { | 21258 | if (enum_ty.enumFieldCount(mod) == 0) { |
| ... | @@ -21063,7 +21260,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21063,7 +21260,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21063 | // it prevents a crash. | 21260 | // it prevents a crash. |
| 21064 | // https://github.com/ziglang/zig/issues/15909 | 21261 | // https://github.com/ziglang/zig/issues/15909 |
| 21065 | return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{ | 21262 | return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{ |
| 21066 | enum_ty.fmt(mod), | 21263 | enum_ty.fmt(pt), |
| 21067 | }); | 21264 | }); |
| 21068 | } | 21265 | } |
| 21069 | const enum_decl_index = enum_ty.getOwnerDecl(mod); | 21266 | const enum_decl_index = enum_ty.getOwnerDecl(mod); |
| ... | @@ -21072,7 +21269,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21072,7 +21269,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21072 | const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse { | 21269 | const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse { |
| 21073 | const msg = msg: { | 21270 | const msg = msg: { |
| 21074 | const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ | 21271 | const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ |
| 21075 | val.fmtValue(sema.mod, sema), mod.declPtr(enum_decl_index).name.fmt(ip), | 21272 | val.fmtValue(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip), |
| 21076 | }); | 21273 | }); |
| 21077 | errdefer msg.destroy(sema.gpa); | 21274 | errdefer msg.destroy(sema.gpa); |
| 21078 | try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{}); | 21275 | try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{}); |
| ... | @@ -21085,7 +21282,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21085,7 +21282,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21085 | return sema.addNullTerminatedStrLit(field_name); | 21282 | return sema.addNullTerminatedStrLit(field_name); |
| 21086 | } | 21283 | } |
| 21087 | try sema.requireRuntimeBlock(block, src, operand_src); | 21284 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 21088 | if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) { | 21285 | if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) { |
| 21089 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); | 21286 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); |
| 21090 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); | 21287 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); |
| 21091 | } | 21288 | } |
| ... | @@ -21101,7 +21298,8 @@ fn zirReify( | ... | @@ -21101,7 +21298,8 @@ fn zirReify( |
| 21101 | extended: Zir.Inst.Extended.InstData, | 21298 | extended: Zir.Inst.Extended.InstData, |
| 21102 | inst: Zir.Inst.Index, | 21299 | inst: Zir.Inst.Index, |
| 21103 | ) CompileError!Air.Inst.Ref { | 21300 | ) CompileError!Air.Inst.Ref { |
| 21104 | const mod = sema.mod; | 21301 | const pt = sema.pt; |
| 21302 | const mod = pt.zcu; | ||
| 21105 | const gpa = sema.gpa; | 21303 | const gpa = sema.gpa; |
| 21106 | const ip = &mod.intern_pool; | 21304 | const ip = &mod.intern_pool; |
| 21107 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | 21305 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); |
| ... | @@ -21120,7 +21318,7 @@ fn zirReify( | ... | @@ -21120,7 +21318,7 @@ fn zirReify( |
| 21120 | }, | 21318 | }, |
| 21121 | }, | 21319 | }, |
| 21122 | }; | 21320 | }; |
| 21123 | const type_info_ty = try mod.getBuiltinType("Type"); | 21321 | const type_info_ty = try pt.getBuiltinType("Type"); |
| 21124 | const uncasted_operand = try sema.resolveInst(extra.operand); | 21322 | const uncasted_operand = try sema.resolveInst(extra.operand); |
| 21125 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); | 21323 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); |
| 21126 | const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ | 21324 | const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ |
| ... | @@ -21145,36 +21343,36 @@ fn zirReify( | ... | @@ -21145,36 +21343,36 @@ fn zirReify( |
| 21145 | .Int => { | 21343 | .Int => { |
| 21146 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21344 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21147 | const signedness_val = try Value.fromInterned(union_val.val).fieldValue( | 21345 | const signedness_val = try Value.fromInterned(union_val.val).fieldValue( |
| 21148 | mod, | 21346 | pt, |
| 21149 | struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?, | 21347 | struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "signedness", .no_embedded_nulls)).?, |
| 21150 | ); | 21348 | ); |
| 21151 | const bits_val = try Value.fromInterned(union_val.val).fieldValue( | 21349 | const bits_val = try Value.fromInterned(union_val.val).fieldValue( |
| 21152 | mod, | 21350 | pt, |
| 21153 | struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?, | 21351 | struct_type.nameIndex(ip, try ip.getOrPutString(gpa, "bits", .no_embedded_nulls)).?, |
| 21154 | ); | 21352 | ); |
| 21155 | 21353 | ||
| 21156 | const signedness = mod.toEnum(std.builtin.Signedness, signedness_val); | 21354 | const signedness = mod.toEnum(std.builtin.Signedness, signedness_val); |
| 21157 | const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod)); | 21355 | const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt)); |
| 21158 | const ty = try mod.intType(signedness, bits); | 21356 | const ty = try pt.intType(signedness, bits); |
| 21159 | return Air.internedToRef(ty.toIntern()); | 21357 | return Air.internedToRef(ty.toIntern()); |
| 21160 | }, | 21358 | }, |
| 21161 | .Vector => { | 21359 | .Vector => { |
| 21162 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21360 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21163 | const len_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21361 | const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21164 | ip, | 21362 | ip, |
| 21165 | try ip.getOrPutString(gpa, "len", .no_embedded_nulls), | 21363 | try ip.getOrPutString(gpa, "len", .no_embedded_nulls), |
| 21166 | ).?); | 21364 | ).?); |
| 21167 | const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21365 | const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21168 | ip, | 21366 | ip, |
| 21169 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), | 21367 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), |
| 21170 | ).?); | 21368 | ).?); |
| 21171 | 21369 | ||
| 21172 | const len: u32 = @intCast(try len_val.toUnsignedIntSema(mod)); | 21370 | const len: u32 = @intCast(try len_val.toUnsignedIntSema(pt)); |
| 21173 | const child_ty = child_val.toType(); | 21371 | const child_ty = child_val.toType(); |
| 21174 | 21372 | ||
| 21175 | try sema.checkVectorElemType(block, src, child_ty); | 21373 | try sema.checkVectorElemType(block, src, child_ty); |
| 21176 | 21374 | ||
| 21177 | const ty = try mod.vectorType(.{ | 21375 | const ty = try pt.vectorType(.{ |
| 21178 | .len = len, | 21376 | .len = len, |
| 21179 | .child = child_ty.toIntern(), | 21377 | .child = child_ty.toIntern(), |
| 21180 | }); | 21378 | }); |
| ... | @@ -21182,12 +21380,12 @@ fn zirReify( | ... | @@ -21182,12 +21380,12 @@ fn zirReify( |
| 21182 | }, | 21380 | }, |
| 21183 | .Float => { | 21381 | .Float => { |
| 21184 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21382 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21185 | const bits_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21383 | const bits_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21186 | ip, | 21384 | ip, |
| 21187 | try ip.getOrPutString(gpa, "bits", .no_embedded_nulls), | 21385 | try ip.getOrPutString(gpa, "bits", .no_embedded_nulls), |
| 21188 | ).?); | 21386 | ).?); |
| 21189 | 21387 | ||
| 21190 | const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod)); | 21388 | const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt)); |
| 21191 | const ty = switch (bits) { | 21389 | const ty = switch (bits) { |
| 21192 | 16 => Type.f16, | 21390 | 16 => Type.f16, |
| 21193 | 32 => Type.f32, | 21391 | 32 => Type.f32, |
| ... | @@ -21200,35 +21398,35 @@ fn zirReify( | ... | @@ -21200,35 +21398,35 @@ fn zirReify( |
| 21200 | }, | 21398 | }, |
| 21201 | .Pointer => { | 21399 | .Pointer => { |
| 21202 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21400 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21203 | const size_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21401 | const size_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21204 | ip, | 21402 | ip, |
| 21205 | try ip.getOrPutString(gpa, "size", .no_embedded_nulls), | 21403 | try ip.getOrPutString(gpa, "size", .no_embedded_nulls), |
| 21206 | ).?); | 21404 | ).?); |
| 21207 | const is_const_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21405 | const is_const_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21208 | ip, | 21406 | ip, |
| 21209 | try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls), | 21407 | try ip.getOrPutString(gpa, "is_const", .no_embedded_nulls), |
| 21210 | ).?); | 21408 | ).?); |
| 21211 | const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21409 | const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21212 | ip, | 21410 | ip, |
| 21213 | try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls), | 21411 | try ip.getOrPutString(gpa, "is_volatile", .no_embedded_nulls), |
| 21214 | ).?); | 21412 | ).?); |
| 21215 | const alignment_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21413 | const alignment_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21216 | ip, | 21414 | ip, |
| 21217 | try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls), | 21415 | try ip.getOrPutString(gpa, "alignment", .no_embedded_nulls), |
| 21218 | ).?); | 21416 | ).?); |
| 21219 | const address_space_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21417 | const address_space_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21220 | ip, | 21418 | ip, |
| 21221 | try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls), | 21419 | try ip.getOrPutString(gpa, "address_space", .no_embedded_nulls), |
| 21222 | ).?); | 21420 | ).?); |
| 21223 | const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21421 | const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21224 | ip, | 21422 | ip, |
| 21225 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), | 21423 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), |
| 21226 | ).?); | 21424 | ).?); |
| 21227 | const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21425 | const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21228 | ip, | 21426 | ip, |
| 21229 | try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls), | 21427 | try ip.getOrPutString(gpa, "is_allowzero", .no_embedded_nulls), |
| 21230 | ).?); | 21428 | ).?); |
| 21231 | const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21429 | const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21232 | ip, | 21430 | ip, |
| 21233 | try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls), | 21431 | try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls), |
| 21234 | ).?); | 21432 | ).?); |
| ... | @@ -21237,7 +21435,7 @@ fn zirReify( | ... | @@ -21237,7 +21435,7 @@ fn zirReify( |
| 21237 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 21435 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 21238 | } | 21436 | } |
| 21239 | 21437 | ||
| 21240 | const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, .sema)).?; | 21438 | const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(pt, .sema)).?; |
| 21241 | if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) { | 21439 | if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) { |
| 21242 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int}); | 21440 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int}); |
| 21243 | } | 21441 | } |
| ... | @@ -21245,7 +21443,7 @@ fn zirReify( | ... | @@ -21245,7 +21443,7 @@ fn zirReify( |
| 21245 | 21443 | ||
| 21246 | const elem_ty = child_val.toType(); | 21444 | const elem_ty = child_val.toType(); |
| 21247 | if (abi_align != .none) { | 21445 | if (abi_align != .none) { |
| 21248 | try elem_ty.resolveLayout(mod); | 21446 | try elem_ty.resolveLayout(pt); |
| 21249 | } | 21447 | } |
| 21250 | 21448 | ||
| 21251 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); | 21449 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); |
| ... | @@ -21256,7 +21454,7 @@ fn zirReify( | ... | @@ -21256,7 +21454,7 @@ fn zirReify( |
| 21256 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); | 21454 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); |
| 21257 | } | 21455 | } |
| 21258 | const sentinel_ptr_val = sentinel_val.optionalValue(mod).?; | 21456 | const sentinel_ptr_val = sentinel_val.optionalValue(mod).?; |
| 21259 | const ptr_ty = try mod.singleMutPtrType(elem_ty); | 21457 | const ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 21260 | const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; | 21458 | const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; |
| 21261 | break :s sent_val.toIntern(); | 21459 | break :s sent_val.toIntern(); |
| 21262 | } | 21460 | } |
| ... | @@ -21274,7 +21472,7 @@ fn zirReify( | ... | @@ -21274,7 +21472,7 @@ fn zirReify( |
| 21274 | } else if (ptr_size == .C) { | 21472 | } else if (ptr_size == .C) { |
| 21275 | if (!try sema.validateExternType(elem_ty, .other)) { | 21473 | if (!try sema.validateExternType(elem_ty, .other)) { |
| 21276 | const msg = msg: { | 21474 | const msg = msg: { |
| 21277 | const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)}); | 21475 | const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)}); |
| 21278 | errdefer msg.destroy(gpa); | 21476 | errdefer msg.destroy(gpa); |
| 21279 | 21477 | ||
| 21280 | try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other); | 21478 | try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other); |
| ... | @@ -21289,7 +21487,7 @@ fn zirReify( | ... | @@ -21289,7 +21487,7 @@ fn zirReify( |
| 21289 | } | 21487 | } |
| 21290 | } | 21488 | } |
| 21291 | 21489 | ||
| 21292 | const ty = try mod.ptrTypeSema(.{ | 21490 | const ty = try pt.ptrTypeSema(.{ |
| 21293 | .child = elem_ty.toIntern(), | 21491 | .child = elem_ty.toIntern(), |
| 21294 | .sentinel = actual_sentinel, | 21492 | .sentinel = actual_sentinel, |
| 21295 | .flags = .{ | 21493 | .flags = .{ |
| ... | @@ -21305,27 +21503,27 @@ fn zirReify( | ... | @@ -21305,27 +21503,27 @@ fn zirReify( |
| 21305 | }, | 21503 | }, |
| 21306 | .Array => { | 21504 | .Array => { |
| 21307 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21505 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21308 | const len_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21506 | const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21309 | ip, | 21507 | ip, |
| 21310 | try ip.getOrPutString(gpa, "len", .no_embedded_nulls), | 21508 | try ip.getOrPutString(gpa, "len", .no_embedded_nulls), |
| 21311 | ).?); | 21509 | ).?); |
| 21312 | const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21510 | const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21313 | ip, | 21511 | ip, |
| 21314 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), | 21512 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), |
| 21315 | ).?); | 21513 | ).?); |
| 21316 | const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21514 | const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21317 | ip, | 21515 | ip, |
| 21318 | try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls), | 21516 | try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls), |
| 21319 | ).?); | 21517 | ).?); |
| 21320 | 21518 | ||
| 21321 | const len = try len_val.toUnsignedIntSema(mod); | 21519 | const len = try len_val.toUnsignedIntSema(pt); |
| 21322 | const child_ty = child_val.toType(); | 21520 | const child_ty = child_val.toType(); |
| 21323 | const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: { | 21521 | const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: { |
| 21324 | const ptr_ty = try mod.singleMutPtrType(child_ty); | 21522 | const ptr_ty = try pt.singleMutPtrType(child_ty); |
| 21325 | break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?; | 21523 | break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?; |
| 21326 | } else null; | 21524 | } else null; |
| 21327 | 21525 | ||
| 21328 | const ty = try mod.arrayType(.{ | 21526 | const ty = try pt.arrayType(.{ |
| 21329 | .len = len, | 21527 | .len = len, |
| 21330 | .sentinel = if (sentinel) |s| s.toIntern() else .none, | 21528 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 21331 | .child = child_ty.toIntern(), | 21529 | .child = child_ty.toIntern(), |
| ... | @@ -21334,23 +21532,23 @@ fn zirReify( | ... | @@ -21334,23 +21532,23 @@ fn zirReify( |
| 21334 | }, | 21532 | }, |
| 21335 | .Optional => { | 21533 | .Optional => { |
| 21336 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21534 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21337 | const child_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21535 | const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21338 | ip, | 21536 | ip, |
| 21339 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), | 21537 | try ip.getOrPutString(gpa, "child", .no_embedded_nulls), |
| 21340 | ).?); | 21538 | ).?); |
| 21341 | 21539 | ||
| 21342 | const child_ty = child_val.toType(); | 21540 | const child_ty = child_val.toType(); |
| 21343 | 21541 | ||
| 21344 | const ty = try mod.optionalType(child_ty.toIntern()); | 21542 | const ty = try pt.optionalType(child_ty.toIntern()); |
| 21345 | return Air.internedToRef(ty.toIntern()); | 21543 | return Air.internedToRef(ty.toIntern()); |
| 21346 | }, | 21544 | }, |
| 21347 | .ErrorUnion => { | 21545 | .ErrorUnion => { |
| 21348 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21546 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21349 | const error_set_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21547 | const error_set_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21350 | ip, | 21548 | ip, |
| 21351 | try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls), | 21549 | try ip.getOrPutString(gpa, "error_set", .no_embedded_nulls), |
| 21352 | ).?); | 21550 | ).?); |
| 21353 | const payload_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21551 | const payload_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21354 | ip, | 21552 | ip, |
| 21355 | try ip.getOrPutString(gpa, "payload", .no_embedded_nulls), | 21553 | try ip.getOrPutString(gpa, "payload", .no_embedded_nulls), |
| 21356 | ).?); | 21554 | ).?); |
| ... | @@ -21362,7 +21560,7 @@ fn zirReify( | ... | @@ -21362,7 +21560,7 @@ fn zirReify( |
| 21362 | return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{}); | 21560 | return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{}); |
| 21363 | } | 21561 | } |
| 21364 | 21562 | ||
| 21365 | const ty = try mod.errorUnionType(error_set_ty, payload_ty); | 21563 | const ty = try pt.errorUnionType(error_set_ty, payload_ty); |
| 21366 | return Air.internedToRef(ty.toIntern()); | 21564 | return Air.internedToRef(ty.toIntern()); |
| 21367 | }, | 21565 | }, |
| 21368 | .ErrorSet => { | 21566 | .ErrorSet => { |
| ... | @@ -21377,9 +21575,9 @@ fn zirReify( | ... | @@ -21377,9 +21575,9 @@ fn zirReify( |
| 21377 | var names: InferredErrorSet.NameMap = .{}; | 21575 | var names: InferredErrorSet.NameMap = .{}; |
| 21378 | try names.ensureUnusedCapacity(sema.arena, len); | 21576 | try names.ensureUnusedCapacity(sema.arena, len); |
| 21379 | for (0..len) |i| { | 21577 | for (0..len) |i| { |
| 21380 | const elem_val = try names_val.elemValue(mod, i); | 21578 | const elem_val = try names_val.elemValue(pt, i); |
| 21381 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); | 21579 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); |
| 21382 | const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21580 | const name_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex( |
| 21383 | ip, | 21581 | ip, |
| 21384 | try ip.getOrPutString(gpa, "name", .no_embedded_nulls), | 21582 | try ip.getOrPutString(gpa, "name", .no_embedded_nulls), |
| 21385 | ).?); | 21583 | ).?); |
| ... | @@ -21396,28 +21594,28 @@ fn zirReify( | ... | @@ -21396,28 +21594,28 @@ fn zirReify( |
| 21396 | } | 21594 | } |
| 21397 | } | 21595 | } |
| 21398 | 21596 | ||
| 21399 | const ty = try mod.errorSetFromUnsortedNames(names.keys()); | 21597 | const ty = try pt.errorSetFromUnsortedNames(names.keys()); |
| 21400 | return Air.internedToRef(ty.toIntern()); | 21598 | return Air.internedToRef(ty.toIntern()); |
| 21401 | }, | 21599 | }, |
| 21402 | .Struct => { | 21600 | .Struct => { |
| 21403 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21601 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21404 | const layout_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21602 | const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21405 | ip, | 21603 | ip, |
| 21406 | try ip.getOrPutString(gpa, "layout", .no_embedded_nulls), | 21604 | try ip.getOrPutString(gpa, "layout", .no_embedded_nulls), |
| 21407 | ).?); | 21605 | ).?); |
| 21408 | const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21606 | const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21409 | ip, | 21607 | ip, |
| 21410 | try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls), | 21608 | try ip.getOrPutString(gpa, "backing_integer", .no_embedded_nulls), |
| 21411 | ).?); | 21609 | ).?); |
| 21412 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21610 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21413 | ip, | 21611 | ip, |
| 21414 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), | 21612 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), |
| 21415 | ).?); | 21613 | ).?); |
| 21416 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21614 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21417 | ip, | 21615 | ip, |
| 21418 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), | 21616 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), |
| 21419 | ).?); | 21617 | ).?); |
| 21420 | const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21618 | const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21421 | ip, | 21619 | ip, |
| 21422 | try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls), | 21620 | try ip.getOrPutString(gpa, "is_tuple", .no_embedded_nulls), |
| 21423 | ).?); | 21621 | ).?); |
| ... | @@ -21425,7 +21623,7 @@ fn zirReify( | ... | @@ -21425,7 +21623,7 @@ fn zirReify( |
| 21425 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | 21623 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); |
| 21426 | 21624 | ||
| 21427 | // Decls | 21625 | // Decls |
| 21428 | if (try decls_val.sliceLen(mod) > 0) { | 21626 | if (try decls_val.sliceLen(pt) > 0) { |
| 21429 | return sema.fail(block, src, "reified structs must have no decls", .{}); | 21627 | return sema.fail(block, src, "reified structs must have no decls", .{}); |
| 21430 | } | 21628 | } |
| 21431 | 21629 | ||
| ... | @@ -21441,24 +21639,24 @@ fn zirReify( | ... | @@ -21441,24 +21639,24 @@ fn zirReify( |
| 21441 | }, | 21639 | }, |
| 21442 | .Enum => { | 21640 | .Enum => { |
| 21443 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21641 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21444 | const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21642 | const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21445 | ip, | 21643 | ip, |
| 21446 | try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls), | 21644 | try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls), |
| 21447 | ).?); | 21645 | ).?); |
| 21448 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21646 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21449 | ip, | 21647 | ip, |
| 21450 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), | 21648 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), |
| 21451 | ).?); | 21649 | ).?); |
| 21452 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21650 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21453 | ip, | 21651 | ip, |
| 21454 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), | 21652 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), |
| 21455 | ).?); | 21653 | ).?); |
| 21456 | const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21654 | const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21457 | ip, | 21655 | ip, |
| 21458 | try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls), | 21656 | try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls), |
| 21459 | ).?); | 21657 | ).?); |
| 21460 | 21658 | ||
| 21461 | if (try decls_val.sliceLen(mod) > 0) { | 21659 | if (try decls_val.sliceLen(pt) > 0) { |
| 21462 | return sema.fail(block, src, "reified enums must have no decls", .{}); | 21660 | return sema.fail(block, src, "reified enums must have no decls", .{}); |
| 21463 | } | 21661 | } |
| 21464 | 21662 | ||
| ... | @@ -21470,17 +21668,17 @@ fn zirReify( | ... | @@ -21470,17 +21668,17 @@ fn zirReify( |
| 21470 | }, | 21668 | }, |
| 21471 | .Opaque => { | 21669 | .Opaque => { |
| 21472 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21670 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21473 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21671 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21474 | ip, | 21672 | ip, |
| 21475 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), | 21673 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), |
| 21476 | ).?); | 21674 | ).?); |
| 21477 | 21675 | ||
| 21478 | // Decls | 21676 | // Decls |
| 21479 | if (try decls_val.sliceLen(mod) > 0) { | 21677 | if (try decls_val.sliceLen(pt) > 0) { |
| 21480 | return sema.fail(block, src, "reified opaque must have no decls", .{}); | 21678 | return sema.fail(block, src, "reified opaque must have no decls", .{}); |
| 21481 | } | 21679 | } |
| 21482 | 21680 | ||
| 21483 | const wip_ty = switch (try ip.getOpaqueType(gpa, .{ | 21681 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{ |
| 21484 | .has_namespace = false, | 21682 | .has_namespace = false, |
| 21485 | .key = .{ .reified = .{ | 21683 | .key = .{ .reified = .{ |
| 21486 | .zir_index = try block.trackZir(inst), | 21684 | .zir_index = try block.trackZir(inst), |
| ... | @@ -21501,30 +21699,30 @@ fn zirReify( | ... | @@ -21501,30 +21699,30 @@ fn zirReify( |
| 21501 | mod.declPtr(new_decl_index).owns_tv = true; | 21699 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21502 | errdefer mod.abortAnonDecl(new_decl_index); | 21700 | errdefer mod.abortAnonDecl(new_decl_index); |
| 21503 | 21701 | ||
| 21504 | try mod.finalizeAnonDecl(new_decl_index); | 21702 | try pt.finalizeAnonDecl(new_decl_index); |
| 21505 | 21703 | ||
| 21506 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 21704 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); |
| 21507 | }, | 21705 | }, |
| 21508 | .Union => { | 21706 | .Union => { |
| 21509 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21707 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21510 | const layout_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21708 | const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21511 | ip, | 21709 | ip, |
| 21512 | try ip.getOrPutString(gpa, "layout", .no_embedded_nulls), | 21710 | try ip.getOrPutString(gpa, "layout", .no_embedded_nulls), |
| 21513 | ).?); | 21711 | ).?); |
| 21514 | const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21712 | const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21515 | ip, | 21713 | ip, |
| 21516 | try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls), | 21714 | try ip.getOrPutString(gpa, "tag_type", .no_embedded_nulls), |
| 21517 | ).?); | 21715 | ).?); |
| 21518 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21716 | const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21519 | ip, | 21717 | ip, |
| 21520 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), | 21718 | try ip.getOrPutString(gpa, "fields", .no_embedded_nulls), |
| 21521 | ).?); | 21719 | ).?); |
| 21522 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21720 | const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21523 | ip, | 21721 | ip, |
| 21524 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), | 21722 | try ip.getOrPutString(gpa, "decls", .no_embedded_nulls), |
| 21525 | ).?); | 21723 | ).?); |
| 21526 | 21724 | ||
| 21527 | if (try decls_val.sliceLen(mod) > 0) { | 21725 | if (try decls_val.sliceLen(pt) > 0) { |
| 21528 | return sema.fail(block, src, "reified unions must have no decls", .{}); | 21726 | return sema.fail(block, src, "reified unions must have no decls", .{}); |
| 21529 | } | 21727 | } |
| 21530 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | 21728 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); |
| ... | @@ -21537,23 +21735,23 @@ fn zirReify( | ... | @@ -21537,23 +21735,23 @@ fn zirReify( |
| 21537 | }, | 21735 | }, |
| 21538 | .Fn => { | 21736 | .Fn => { |
| 21539 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21737 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| 21540 | const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21738 | const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21541 | ip, | 21739 | ip, |
| 21542 | try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls), | 21740 | try ip.getOrPutString(gpa, "calling_convention", .no_embedded_nulls), |
| 21543 | ).?); | 21741 | ).?); |
| 21544 | const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21742 | const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21545 | ip, | 21743 | ip, |
| 21546 | try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls), | 21744 | try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls), |
| 21547 | ).?); | 21745 | ).?); |
| 21548 | const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21746 | const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21549 | ip, | 21747 | ip, |
| 21550 | try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls), | 21748 | try ip.getOrPutString(gpa, "is_var_args", .no_embedded_nulls), |
| 21551 | ).?); | 21749 | ).?); |
| 21552 | const return_type_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21750 | const return_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21553 | ip, | 21751 | ip, |
| 21554 | try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls), | 21752 | try ip.getOrPutString(gpa, "return_type", .no_embedded_nulls), |
| 21555 | ).?); | 21753 | ).?); |
| 21556 | const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21754 | const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex( |
| 21557 | ip, | 21755 | ip, |
| 21558 | try ip.getOrPutString(gpa, "params", .no_embedded_nulls), | 21756 | try ip.getOrPutString(gpa, "params", .no_embedded_nulls), |
| 21559 | ).?); | 21757 | ).?); |
| ... | @@ -21581,17 +21779,17 @@ fn zirReify( | ... | @@ -21581,17 +21779,17 @@ fn zirReify( |
| 21581 | 21779 | ||
| 21582 | var noalias_bits: u32 = 0; | 21780 | var noalias_bits: u32 = 0; |
| 21583 | for (param_types, 0..) |*param_type, i| { | 21781 | for (param_types, 0..) |*param_type, i| { |
| 21584 | const elem_val = try params_val.elemValue(mod, i); | 21782 | const elem_val = try params_val.elemValue(pt, i); |
| 21585 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); | 21783 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); |
| 21586 | const param_is_generic_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21784 | const param_is_generic_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex( |
| 21587 | ip, | 21785 | ip, |
| 21588 | try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls), | 21786 | try ip.getOrPutString(gpa, "is_generic", .no_embedded_nulls), |
| 21589 | ).?); | 21787 | ).?); |
| 21590 | const param_is_noalias_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21788 | const param_is_noalias_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex( |
| 21591 | ip, | 21789 | ip, |
| 21592 | try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls), | 21790 | try ip.getOrPutString(gpa, "is_noalias", .no_embedded_nulls), |
| 21593 | ).?); | 21791 | ).?); |
| 21594 | const opt_param_type_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21792 | const opt_param_type_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex( |
| 21595 | ip, | 21793 | ip, |
| 21596 | try ip.getOrPutString(gpa, "type", .no_embedded_nulls), | 21794 | try ip.getOrPutString(gpa, "type", .no_embedded_nulls), |
| 21597 | ).?); | 21795 | ).?); |
| ... | @@ -21613,7 +21811,7 @@ fn zirReify( | ... | @@ -21613,7 +21811,7 @@ fn zirReify( |
| 21613 | } | 21811 | } |
| 21614 | } | 21812 | } |
| 21615 | 21813 | ||
| 21616 | const ty = try mod.funcType(.{ | 21814 | const ty = try pt.funcType(.{ |
| 21617 | .param_types = param_types, | 21815 | .param_types = param_types, |
| 21618 | .noalias_bits = noalias_bits, | 21816 | .noalias_bits = noalias_bits, |
| 21619 | .return_type = return_type.toIntern(), | 21817 | .return_type = return_type.toIntern(), |
| ... | @@ -21636,7 +21834,8 @@ fn reifyEnum( | ... | @@ -21636,7 +21834,8 @@ fn reifyEnum( |
| 21636 | fields_val: Value, | 21834 | fields_val: Value, |
| 21637 | name_strategy: Zir.Inst.NameStrategy, | 21835 | name_strategy: Zir.Inst.NameStrategy, |
| 21638 | ) CompileError!Air.Inst.Ref { | 21836 | ) CompileError!Air.Inst.Ref { |
| 21639 | const mod = sema.mod; | 21837 | const pt = sema.pt; |
| 21838 | const mod = pt.zcu; | ||
| 21640 | const gpa = sema.gpa; | 21839 | const gpa = sema.gpa; |
| 21641 | const ip = &mod.intern_pool; | 21840 | const ip = &mod.intern_pool; |
| 21642 | 21841 | ||
| ... | @@ -21656,10 +21855,10 @@ fn reifyEnum( | ... | @@ -21656,10 +21855,10 @@ fn reifyEnum( |
| 21656 | std.hash.autoHash(&hasher, fields_len); | 21855 | std.hash.autoHash(&hasher, fields_len); |
| 21657 | 21856 | ||
| 21658 | for (0..fields_len) |field_idx| { | 21857 | for (0..fields_len) |field_idx| { |
| 21659 | const field_info = try fields_val.elemValue(mod, field_idx); | 21858 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21660 | 21859 | ||
| 21661 | const field_name_val = try field_info.fieldValue(mod, 0); | 21860 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21662 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); | 21861 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1)); |
| 21663 | 21862 | ||
| 21664 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ | 21863 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ |
| 21665 | .needed_comptime_reason = "enum field name must be comptime-known", | 21864 | .needed_comptime_reason = "enum field name must be comptime-known", |
| ... | @@ -21671,7 +21870,7 @@ fn reifyEnum( | ... | @@ -21671,7 +21870,7 @@ fn reifyEnum( |
| 21671 | }); | 21870 | }); |
| 21672 | } | 21871 | } |
| 21673 | 21872 | ||
| 21674 | const wip_ty = switch (try ip.getEnumType(gpa, .{ | 21873 | const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{ |
| 21675 | .has_namespace = false, | 21874 | .has_namespace = false, |
| 21676 | .has_values = true, | 21875 | .has_values = true, |
| 21677 | .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive, | 21876 | .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive, |
| ... | @@ -21704,10 +21903,10 @@ fn reifyEnum( | ... | @@ -21704,10 +21903,10 @@ fn reifyEnum( |
| 21704 | wip_ty.setTagTy(ip, tag_ty.toIntern()); | 21903 | wip_ty.setTagTy(ip, tag_ty.toIntern()); |
| 21705 | 21904 | ||
| 21706 | for (0..fields_len) |field_idx| { | 21905 | for (0..fields_len) |field_idx| { |
| 21707 | const field_info = try fields_val.elemValue(mod, field_idx); | 21906 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21708 | 21907 | ||
| 21709 | const field_name_val = try field_info.fieldValue(mod, 0); | 21908 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21710 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); | 21909 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1)); |
| 21711 | 21910 | ||
| 21712 | // Don't pass a reason; first loop acts as an assertion that this is valid. | 21911 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 21713 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); | 21912 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| ... | @@ -21716,12 +21915,12 @@ fn reifyEnum( | ... | @@ -21716,12 +21915,12 @@ fn reifyEnum( |
| 21716 | // TODO: better source location | 21915 | // TODO: better source location |
| 21717 | return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ | 21916 | return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ |
| 21718 | field_name.fmt(ip), | 21917 | field_name.fmt(ip), |
| 21719 | field_value_val.fmtValue(mod, sema), | 21918 | field_value_val.fmtValue(pt, sema), |
| 21720 | tag_ty.fmt(mod), | 21919 | tag_ty.fmt(pt), |
| 21721 | }); | 21920 | }); |
| 21722 | } | 21921 | } |
| 21723 | 21922 | ||
| 21724 | const coerced_field_val = try mod.getCoerced(field_value_val, tag_ty); | 21923 | const coerced_field_val = try pt.getCoerced(field_value_val, tag_ty); |
| 21725 | if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| { | 21924 | if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| { |
| 21726 | return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) { | 21925 | return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) { |
| 21727 | .name => msg: { | 21926 | .name => msg: { |
| ... | @@ -21732,7 +21931,7 @@ fn reifyEnum( | ... | @@ -21732,7 +21931,7 @@ fn reifyEnum( |
| 21732 | break :msg msg; | 21931 | break :msg msg; |
| 21733 | }, | 21932 | }, |
| 21734 | .value => msg: { | 21933 | .value => msg: { |
| 21735 | const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod, sema)}); | 21934 | const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(pt, sema)}); |
| 21736 | errdefer msg.destroy(gpa); | 21935 | errdefer msg.destroy(gpa); |
| 21737 | _ = conflict.prev_field_idx; // TODO: this note is incorrect | 21936 | _ = conflict.prev_field_idx; // TODO: this note is incorrect |
| 21738 | try sema.errNote(src, msg, "other enum tag value here", .{}); | 21937 | try sema.errNote(src, msg, "other enum tag value here", .{}); |
| ... | @@ -21742,11 +21941,11 @@ fn reifyEnum( | ... | @@ -21742,11 +21941,11 @@ fn reifyEnum( |
| 21742 | } | 21941 | } |
| 21743 | } | 21942 | } |
| 21744 | 21943 | ||
| 21745 | if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(mod)) { | 21944 | if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(pt)) { |
| 21746 | return sema.fail(block, src, "non-exhaustive enum specified every value", .{}); | 21945 | return sema.fail(block, src, "non-exhaustive enum specified every value", .{}); |
| 21747 | } | 21946 | } |
| 21748 | 21947 | ||
| 21749 | try mod.finalizeAnonDecl(new_decl_index); | 21948 | try pt.finalizeAnonDecl(new_decl_index); |
| 21750 | return Air.internedToRef(wip_ty.index); | 21949 | return Air.internedToRef(wip_ty.index); |
| 21751 | } | 21950 | } |
| 21752 | 21951 | ||
| ... | @@ -21760,7 +21959,8 @@ fn reifyUnion( | ... | @@ -21760,7 +21959,8 @@ fn reifyUnion( |
| 21760 | fields_val: Value, | 21959 | fields_val: Value, |
| 21761 | name_strategy: Zir.Inst.NameStrategy, | 21960 | name_strategy: Zir.Inst.NameStrategy, |
| 21762 | ) CompileError!Air.Inst.Ref { | 21961 | ) CompileError!Air.Inst.Ref { |
| 21763 | const mod = sema.mod; | 21962 | const pt = sema.pt; |
| 21963 | const mod = pt.zcu; | ||
| 21764 | const gpa = sema.gpa; | 21964 | const gpa = sema.gpa; |
| 21765 | const ip = &mod.intern_pool; | 21965 | const ip = &mod.intern_pool; |
| 21766 | 21966 | ||
| ... | @@ -21782,11 +21982,11 @@ fn reifyUnion( | ... | @@ -21782,11 +21982,11 @@ fn reifyUnion( |
| 21782 | var any_aligns = false; | 21982 | var any_aligns = false; |
| 21783 | 21983 | ||
| 21784 | for (0..fields_len) |field_idx| { | 21984 | for (0..fields_len) |field_idx| { |
| 21785 | const field_info = try fields_val.elemValue(mod, field_idx); | 21985 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21786 | 21986 | ||
| 21787 | const field_name_val = try field_info.fieldValue(mod, 0); | 21987 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21788 | const field_type_val = try field_info.fieldValue(mod, 1); | 21988 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 21789 | const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 2)); | 21989 | const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2)); |
| 21790 | 21990 | ||
| 21791 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ | 21991 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ |
| 21792 | .needed_comptime_reason = "union field name must be comptime-known", | 21992 | .needed_comptime_reason = "union field name must be comptime-known", |
| ... | @@ -21798,12 +21998,12 @@ fn reifyUnion( | ... | @@ -21798,12 +21998,12 @@ fn reifyUnion( |
| 21798 | field_align_val.toIntern(), | 21998 | field_align_val.toIntern(), |
| 21799 | }); | 21999 | }); |
| 21800 | 22000 | ||
| 21801 | if (field_align_val.toUnsignedInt(mod) != 0) { | 22001 | if (field_align_val.toUnsignedInt(pt) != 0) { |
| 21802 | any_aligns = true; | 22002 | any_aligns = true; |
| 21803 | } | 22003 | } |
| 21804 | } | 22004 | } |
| 21805 | 22005 | ||
| 21806 | const wip_ty = switch (try ip.getUnionType(gpa, .{ | 22006 | const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{ |
| 21807 | .flags = .{ | 22007 | .flags = .{ |
| 21808 | .layout = layout, | 22008 | .layout = layout, |
| 21809 | .status = .none, | 22009 | .status = .none, |
| ... | @@ -21861,10 +22061,10 @@ fn reifyUnion( | ... | @@ -21861,10 +22061,10 @@ fn reifyUnion( |
| 21861 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); | 22061 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); |
| 21862 | 22062 | ||
| 21863 | for (field_types, 0..) |*field_ty, field_idx| { | 22063 | for (field_types, 0..) |*field_ty, field_idx| { |
| 21864 | const field_info = try fields_val.elemValue(mod, field_idx); | 22064 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21865 | 22065 | ||
| 21866 | const field_name_val = try field_info.fieldValue(mod, 0); | 22066 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21867 | const field_type_val = try field_info.fieldValue(mod, 1); | 22067 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 21868 | 22068 | ||
| 21869 | // Don't pass a reason; first loop acts as an assertion that this is valid. | 22069 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 21870 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); | 22070 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| ... | @@ -21872,7 +22072,7 @@ fn reifyUnion( | ... | @@ -21872,7 +22072,7 @@ fn reifyUnion( |
| 21872 | const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse { | 22072 | const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse { |
| 21873 | // TODO: better source location | 22073 | // TODO: better source location |
| 21874 | return sema.fail(block, src, "no field named '{}' in enum '{}'", .{ | 22074 | return sema.fail(block, src, "no field named '{}' in enum '{}'", .{ |
| 21875 | field_name.fmt(ip), enum_tag_ty.fmt(mod), | 22075 | field_name.fmt(ip), enum_tag_ty.fmt(pt), |
| 21876 | }); | 22076 | }); |
| 21877 | }; | 22077 | }; |
| 21878 | if (seen_tags.isSet(enum_index)) { | 22078 | if (seen_tags.isSet(enum_index)) { |
| ... | @@ -21883,7 +22083,7 @@ fn reifyUnion( | ... | @@ -21883,7 +22083,7 @@ fn reifyUnion( |
| 21883 | 22083 | ||
| 21884 | field_ty.* = field_type_val.toIntern(); | 22084 | field_ty.* = field_type_val.toIntern(); |
| 21885 | if (any_aligns) { | 22085 | if (any_aligns) { |
| 21886 | const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod); | 22086 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); |
| 21887 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | 22087 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { |
| 21888 | // TODO: better source location | 22088 | // TODO: better source location |
| 21889 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | 22089 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); |
| ... | @@ -21913,10 +22113,10 @@ fn reifyUnion( | ... | @@ -21913,10 +22113,10 @@ fn reifyUnion( |
| 21913 | try field_names.ensureTotalCapacity(sema.arena, fields_len); | 22113 | try field_names.ensureTotalCapacity(sema.arena, fields_len); |
| 21914 | 22114 | ||
| 21915 | for (field_types, 0..) |*field_ty, field_idx| { | 22115 | for (field_types, 0..) |*field_ty, field_idx| { |
| 21916 | const field_info = try fields_val.elemValue(mod, field_idx); | 22116 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21917 | 22117 | ||
| 21918 | const field_name_val = try field_info.fieldValue(mod, 0); | 22118 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21919 | const field_type_val = try field_info.fieldValue(mod, 1); | 22119 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 21920 | 22120 | ||
| 21921 | // Don't pass a reason; first loop acts as an assertion that this is valid. | 22121 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 21922 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); | 22122 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| ... | @@ -21928,7 +22128,7 @@ fn reifyUnion( | ... | @@ -21928,7 +22128,7 @@ fn reifyUnion( |
| 21928 | 22128 | ||
| 21929 | field_ty.* = field_type_val.toIntern(); | 22129 | field_ty.* = field_type_val.toIntern(); |
| 21930 | if (any_aligns) { | 22130 | if (any_aligns) { |
| 21931 | const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod); | 22131 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); |
| 21932 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | 22132 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { |
| 21933 | // TODO: better source location | 22133 | // TODO: better source location |
| 21934 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | 22134 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); |
| ... | @@ -21955,7 +22155,7 @@ fn reifyUnion( | ... | @@ -21955,7 +22155,7 @@ fn reifyUnion( |
| 21955 | } | 22155 | } |
| 21956 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) { | 22156 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) { |
| 21957 | return sema.failWithOwnedErrorMsg(block, msg: { | 22157 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 21958 | const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); | 22158 | const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 21959 | errdefer msg.destroy(gpa); | 22159 | errdefer msg.destroy(gpa); |
| 21960 | 22160 | ||
| 21961 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field); | 22161 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field); |
| ... | @@ -21965,7 +22165,7 @@ fn reifyUnion( | ... | @@ -21965,7 +22165,7 @@ fn reifyUnion( |
| 21965 | }); | 22165 | }); |
| 21966 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { | 22166 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 21967 | return sema.failWithOwnedErrorMsg(block, msg: { | 22167 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 21968 | const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); | 22168 | const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 21969 | errdefer msg.destroy(gpa); | 22169 | errdefer msg.destroy(gpa); |
| 21970 | 22170 | ||
| 21971 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); | 22171 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); |
| ... | @@ -21984,7 +22184,7 @@ fn reifyUnion( | ... | @@ -21984,7 +22184,7 @@ fn reifyUnion( |
| 21984 | loaded_union.tagTypePtr(ip).* = enum_tag_ty; | 22184 | loaded_union.tagTypePtr(ip).* = enum_tag_ty; |
| 21985 | loaded_union.flagsPtr(ip).status = .have_field_types; | 22185 | loaded_union.flagsPtr(ip).status = .have_field_types; |
| 21986 | 22186 | ||
| 21987 | try mod.finalizeAnonDecl(new_decl_index); | 22187 | try pt.finalizeAnonDecl(new_decl_index); |
| 21988 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | 22188 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); |
| 21989 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 22189 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); |
| 21990 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 22190 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); |
| ... | @@ -22001,7 +22201,8 @@ fn reifyStruct( | ... | @@ -22001,7 +22201,8 @@ fn reifyStruct( |
| 22001 | name_strategy: Zir.Inst.NameStrategy, | 22201 | name_strategy: Zir.Inst.NameStrategy, |
| 22002 | is_tuple: bool, | 22202 | is_tuple: bool, |
| 22003 | ) CompileError!Air.Inst.Ref { | 22203 | ) CompileError!Air.Inst.Ref { |
| 22004 | const mod = sema.mod; | 22204 | const pt = sema.pt; |
| 22205 | const mod = pt.zcu; | ||
| 22005 | const gpa = sema.gpa; | 22206 | const gpa = sema.gpa; |
| 22006 | const ip = &mod.intern_pool; | 22207 | const ip = &mod.intern_pool; |
| 22007 | 22208 | ||
| ... | @@ -22026,20 +22227,20 @@ fn reifyStruct( | ... | @@ -22026,20 +22227,20 @@ fn reifyStruct( |
| 22026 | var any_aligned_fields = false; | 22227 | var any_aligned_fields = false; |
| 22027 | 22228 | ||
| 22028 | for (0..fields_len) |field_idx| { | 22229 | for (0..fields_len) |field_idx| { |
| 22029 | const field_info = try fields_val.elemValue(mod, field_idx); | 22230 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 22030 | 22231 | ||
| 22031 | const field_name_val = try field_info.fieldValue(mod, 0); | 22232 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 22032 | const field_type_val = try field_info.fieldValue(mod, 1); | 22233 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 22033 | const field_default_value_val = try field_info.fieldValue(mod, 2); | 22234 | const field_default_value_val = try field_info.fieldValue(pt, 2); |
| 22034 | const field_is_comptime_val = try field_info.fieldValue(mod, 3); | 22235 | const field_is_comptime_val = try field_info.fieldValue(pt, 3); |
| 22035 | const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 4)); | 22236 | const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4)); |
| 22036 | 22237 | ||
| 22037 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ | 22238 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ |
| 22038 | .needed_comptime_reason = "struct field name must be comptime-known", | 22239 | .needed_comptime_reason = "struct field name must be comptime-known", |
| 22039 | }); | 22240 | }); |
| 22040 | const field_is_comptime = field_is_comptime_val.toBool(); | 22241 | const field_is_comptime = field_is_comptime_val.toBool(); |
| 22041 | const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(mod)) |ptr_val| d: { | 22242 | const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(mod)) |ptr_val| d: { |
| 22042 | const ptr_ty = try mod.singleConstPtrType(field_type_val.toType()); | 22243 | const ptr_ty = try pt.singleConstPtrType(field_type_val.toType()); |
| 22043 | // We need to do this deref here, so we won't check for this error case later on. | 22244 | // We need to do this deref here, so we won't check for this error case later on. |
| 22044 | const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime( | 22245 | const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime( |
| 22045 | block, | 22246 | block, |
| ... | @@ -22060,14 +22261,14 @@ fn reifyStruct( | ... | @@ -22060,14 +22261,14 @@ fn reifyStruct( |
| 22060 | 22261 | ||
| 22061 | if (field_is_comptime) any_comptime_fields = true; | 22262 | if (field_is_comptime) any_comptime_fields = true; |
| 22062 | if (field_default_value != .none) any_default_inits = true; | 22263 | if (field_default_value != .none) any_default_inits = true; |
| 22063 | switch (try field_alignment_val.orderAgainstZeroAdvanced(mod, .sema)) { | 22264 | switch (try field_alignment_val.orderAgainstZeroAdvanced(pt, .sema)) { |
| 22064 | .eq => {}, | 22265 | .eq => {}, |
| 22065 | .gt => any_aligned_fields = true, | 22266 | .gt => any_aligned_fields = true, |
| 22066 | .lt => unreachable, | 22267 | .lt => unreachable, |
| 22067 | } | 22268 | } |
| 22068 | } | 22269 | } |
| 22069 | 22270 | ||
| 22070 | const wip_ty = switch (try ip.getStructType(gpa, .{ | 22271 | const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{ |
| 22071 | .layout = layout, | 22272 | .layout = layout, |
| 22072 | .fields_len = fields_len, | 22273 | .fields_len = fields_len, |
| 22073 | .known_non_opv = false, | 22274 | .known_non_opv = false, |
| ... | @@ -22107,13 +22308,13 @@ fn reifyStruct( | ... | @@ -22107,13 +22308,13 @@ fn reifyStruct( |
| 22107 | const struct_type = ip.loadStructType(wip_ty.index); | 22308 | const struct_type = ip.loadStructType(wip_ty.index); |
| 22108 | 22309 | ||
| 22109 | for (0..fields_len) |field_idx| { | 22310 | for (0..fields_len) |field_idx| { |
| 22110 | const field_info = try fields_val.elemValue(mod, field_idx); | 22311 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 22111 | 22312 | ||
| 22112 | const field_name_val = try field_info.fieldValue(mod, 0); | 22313 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 22113 | const field_type_val = try field_info.fieldValue(mod, 1); | 22314 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 22114 | const field_default_value_val = try field_info.fieldValue(mod, 2); | 22315 | const field_default_value_val = try field_info.fieldValue(pt, 2); |
| 22115 | const field_is_comptime_val = try field_info.fieldValue(mod, 3); | 22316 | const field_is_comptime_val = try field_info.fieldValue(pt, 3); |
| 22116 | const field_alignment_val = try field_info.fieldValue(mod, 4); | 22317 | const field_alignment_val = try field_info.fieldValue(pt, 4); |
| 22117 | 22318 | ||
| 22118 | const field_ty = field_type_val.toType(); | 22319 | const field_ty = field_type_val.toType(); |
| 22119 | // Don't pass a reason; first loop acts as an assertion that this is valid. | 22320 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| ... | @@ -22143,7 +22344,7 @@ fn reifyStruct( | ... | @@ -22143,7 +22344,7 @@ fn reifyStruct( |
| 22143 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 22344 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 22144 | } | 22345 | } |
| 22145 | 22346 | ||
| 22146 | const byte_align = try field_alignment_val.toUnsignedIntSema(mod); | 22347 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); |
| 22147 | if (byte_align == 0) { | 22348 | if (byte_align == 0) { |
| 22148 | if (layout != .@"packed") { | 22349 | if (layout != .@"packed") { |
| 22149 | struct_type.field_aligns.get(ip)[field_idx] = .none; | 22350 | struct_type.field_aligns.get(ip)[field_idx] = .none; |
| ... | @@ -22168,7 +22369,7 @@ fn reifyStruct( | ... | @@ -22168,7 +22369,7 @@ fn reifyStruct( |
| 22168 | const field_default: InternPool.Index = d: { | 22369 | const field_default: InternPool.Index = d: { |
| 22169 | if (!any_default_inits) break :d .none; | 22370 | if (!any_default_inits) break :d .none; |
| 22170 | const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none; | 22371 | const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none; |
| 22171 | const ptr_ty = try mod.singleConstPtrType(field_ty); | 22372 | const ptr_ty = try pt.singleConstPtrType(field_ty); |
| 22172 | // Asserted comptime-dereferencable above. | 22373 | // Asserted comptime-dereferencable above. |
| 22173 | const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?; | 22374 | const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?; |
| 22174 | // We already resolved this for deduplication, so we may as well do it now. | 22375 | // We already resolved this for deduplication, so we may as well do it now. |
| ... | @@ -22204,7 +22405,7 @@ fn reifyStruct( | ... | @@ -22204,7 +22405,7 @@ fn reifyStruct( |
| 22204 | } | 22405 | } |
| 22205 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) { | 22406 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) { |
| 22206 | return sema.failWithOwnedErrorMsg(block, msg: { | 22407 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22207 | const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 22408 | const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 22208 | errdefer msg.destroy(gpa); | 22409 | errdefer msg.destroy(gpa); |
| 22209 | 22410 | ||
| 22210 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field); | 22411 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field); |
| ... | @@ -22214,7 +22415,7 @@ fn reifyStruct( | ... | @@ -22214,7 +22415,7 @@ fn reifyStruct( |
| 22214 | }); | 22415 | }); |
| 22215 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { | 22416 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 22216 | return sema.failWithOwnedErrorMsg(block, msg: { | 22417 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22217 | const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 22418 | const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 22218 | errdefer msg.destroy(gpa); | 22419 | errdefer msg.destroy(gpa); |
| 22219 | 22420 | ||
| 22220 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); | 22421 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); |
| ... | @@ -22229,7 +22430,7 @@ fn reifyStruct( | ... | @@ -22229,7 +22430,7 @@ fn reifyStruct( |
| 22229 | var fields_bit_sum: u64 = 0; | 22430 | var fields_bit_sum: u64 = 0; |
| 22230 | for (0..struct_type.field_types.len) |field_idx| { | 22431 | for (0..struct_type.field_types.len) |field_idx| { |
| 22231 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]); | 22432 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]); |
| 22232 | field_ty.resolveLayout(mod) catch |err| switch (err) { | 22433 | field_ty.resolveLayout(pt) catch |err| switch (err) { |
| 22233 | error.AnalysisFail => { | 22434 | error.AnalysisFail => { |
| 22234 | const msg = sema.err orelse return err; | 22435 | const msg = sema.err orelse return err; |
| 22235 | try sema.errNote(src, msg, "while checking a field of this struct", .{}); | 22436 | try sema.errNote(src, msg, "while checking a field of this struct", .{}); |
| ... | @@ -22237,7 +22438,7 @@ fn reifyStruct( | ... | @@ -22237,7 +22438,7 @@ fn reifyStruct( |
| 22237 | }, | 22438 | }, |
| 22238 | else => return err, | 22439 | else => return err, |
| 22239 | }; | 22440 | }; |
| 22240 | fields_bit_sum += field_ty.bitSize(mod); | 22441 | fields_bit_sum += field_ty.bitSize(pt); |
| 22241 | } | 22442 | } |
| 22242 | 22443 | ||
| 22243 | if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| { | 22444 | if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| { |
| ... | @@ -22245,20 +22446,21 @@ fn reifyStruct( | ... | @@ -22245,20 +22446,21 @@ fn reifyStruct( |
| 22245 | try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum); | 22446 | try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum); |
| 22246 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); | 22447 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); |
| 22247 | } else { | 22448 | } else { |
| 22248 | const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum)); | 22449 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); |
| 22249 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); | 22450 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); |
| 22250 | } | 22451 | } |
| 22251 | } | 22452 | } |
| 22252 | 22453 | ||
| 22253 | try mod.finalizeAnonDecl(new_decl_index); | 22454 | try pt.finalizeAnonDecl(new_decl_index); |
| 22254 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | 22455 | try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); |
| 22255 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 22456 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); |
| 22256 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 22457 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); |
| 22257 | } | 22458 | } |
| 22258 | 22459 | ||
| 22259 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { | 22460 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { |
| 22260 | const va_list_ty = try sema.mod.getBuiltinType("VaList"); | 22461 | const pt = sema.pt; |
| 22261 | const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty); | 22462 | const va_list_ty = try pt.getBuiltinType("VaList"); |
| 22463 | const va_list_ptr = try pt.singleMutPtrType(va_list_ty); | ||
| 22262 | 22464 | ||
| 22263 | const inst = try sema.resolveInst(zir_ref); | 22465 | const inst = try sema.resolveInst(zir_ref); |
| 22264 | return sema.coerce(block, va_list_ptr, inst, src); | 22466 | return sema.coerce(block, va_list_ptr, inst, src); |
| ... | @@ -22275,7 +22477,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -22275,7 +22477,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 22275 | 22477 | ||
| 22276 | if (!try sema.validateExternType(arg_ty, .param_ty)) { | 22478 | if (!try sema.validateExternType(arg_ty, .param_ty)) { |
| 22277 | const msg = msg: { | 22479 | const msg = msg: { |
| 22278 | const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.mod)}); | 22480 | const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.pt)}); |
| 22279 | errdefer msg.destroy(sema.gpa); | 22481 | errdefer msg.destroy(sema.gpa); |
| 22280 | 22482 | ||
| 22281 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty); | 22483 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty); |
| ... | @@ -22296,7 +22498,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) | ... | @@ -22296,7 +22498,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) |
| 22296 | const va_list_src = block.builtinCallArgSrc(extra.node, 0); | 22498 | const va_list_src = block.builtinCallArgSrc(extra.node, 0); |
| 22297 | 22499 | ||
| 22298 | const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand); | 22500 | const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand); |
| 22299 | const va_list_ty = try sema.mod.getBuiltinType("VaList"); | 22501 | const va_list_ty = try sema.pt.getBuiltinType("VaList"); |
| 22300 | 22502 | ||
| 22301 | try sema.requireRuntimeBlock(block, src, null); | 22503 | try sema.requireRuntimeBlock(block, src, null); |
| 22302 | return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref); | 22504 | return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref); |
| ... | @@ -22316,7 +22518,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -22316,7 +22518,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 22316 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 22518 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 22317 | const src = block.nodeOffset(@bitCast(extended.operand)); | 22519 | const src = block.nodeOffset(@bitCast(extended.operand)); |
| 22318 | 22520 | ||
| 22319 | const va_list_ty = try sema.mod.getBuiltinType("VaList"); | 22521 | const va_list_ty = try sema.pt.getBuiltinType("VaList"); |
| 22320 | try sema.requireRuntimeBlock(block, src, null); | 22522 | try sema.requireRuntimeBlock(block, src, null); |
| 22321 | return block.addInst(.{ | 22523 | return block.addInst(.{ |
| 22322 | .tag = .c_va_start, | 22524 | .tag = .c_va_start, |
| ... | @@ -22325,14 +22527,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) | ... | @@ -22325,14 +22527,15 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) |
| 22325 | } | 22527 | } |
| 22326 | 22528 | ||
| 22327 | fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22529 | fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22328 | const mod = sema.mod; | 22530 | const pt = sema.pt; |
| 22531 | const mod = pt.zcu; | ||
| 22329 | const ip = &mod.intern_pool; | 22532 | const ip = &mod.intern_pool; |
| 22330 | 22533 | ||
| 22331 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 22534 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 22332 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 22535 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 22333 | const ty = try sema.resolveType(block, ty_src, inst_data.operand); | 22536 | const ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 22334 | 22537 | ||
| 22335 | const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(mod)}, .no_embedded_nulls); | 22538 | const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(pt)}, .no_embedded_nulls); |
| 22336 | return sema.addNullTerminatedStrLit(type_name); | 22539 | return sema.addNullTerminatedStrLit(type_name); |
| 22337 | } | 22540 | } |
| 22338 | 22541 | ||
| ... | @@ -22349,7 +22552,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -22349,7 +22552,8 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 22349 | } | 22552 | } |
| 22350 | 22553 | ||
| 22351 | fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22554 | fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22352 | const mod = sema.mod; | 22555 | const pt = sema.pt; |
| 22556 | const mod = pt.zcu; | ||
| 22353 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 22557 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22354 | const src = block.nodeOffset(inst_data.src_node); | 22558 | const src = block.nodeOffset(inst_data.src_node); |
| 22355 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 22559 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -22380,23 +22584,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22380,23 +22584,23 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22380 | if (dest_scalar_ty.intInfo(mod).bits == 0) { | 22584 | if (dest_scalar_ty.intInfo(mod).bits == 0) { |
| 22381 | if (!is_vector) { | 22585 | if (!is_vector) { |
| 22382 | if (block.wantSafety()) { | 22586 | if (block.wantSafety()) { |
| 22383 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, operand, Air.internedToRef((try mod.floatValue(operand_ty, 0.0)).toIntern())); | 22587 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, operand, Air.internedToRef((try pt.floatValue(operand_ty, 0.0)).toIntern())); |
| 22384 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | 22588 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| 22385 | } | 22589 | } |
| 22386 | return Air.internedToRef((try mod.intValue(dest_ty, 0)).toIntern()); | 22590 | return Air.internedToRef((try pt.intValue(dest_ty, 0)).toIntern()); |
| 22387 | } | 22591 | } |
| 22388 | if (block.wantSafety()) { | 22592 | if (block.wantSafety()) { |
| 22389 | const len = dest_ty.vectorLen(mod); | 22593 | const len = dest_ty.vectorLen(mod); |
| 22390 | for (0..len) |i| { | 22594 | for (0..len) |i| { |
| 22391 | const idx_ref = try mod.intRef(Type.usize, i); | 22595 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22392 | const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref); | 22596 | const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 22393 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try mod.floatValue(operand_scalar_ty, 0.0)).toIntern())); | 22597 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, elem_ref, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 0.0)).toIntern())); |
| 22394 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | 22598 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| 22395 | } | 22599 | } |
| 22396 | } | 22600 | } |
| 22397 | return Air.internedToRef(try mod.intern(.{ .aggregate = .{ | 22601 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 22398 | .ty = dest_ty.toIntern(), | 22602 | .ty = dest_ty.toIntern(), |
| 22399 | .storage = .{ .repeated_elem = (try mod.intValue(dest_scalar_ty, 0)).toIntern() }, | 22603 | .storage = .{ .repeated_elem = (try pt.intValue(dest_scalar_ty, 0)).toIntern() }, |
| 22400 | } })); | 22604 | } })); |
| 22401 | } | 22605 | } |
| 22402 | if (!is_vector) { | 22606 | if (!is_vector) { |
| ... | @@ -22404,8 +22608,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22404,8 +22608,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22404 | if (block.wantSafety()) { | 22608 | if (block.wantSafety()) { |
| 22405 | const back = try block.addTyOp(.float_from_int, operand_ty, result); | 22609 | const back = try block.addTyOp(.float_from_int, operand_ty, result); |
| 22406 | const diff = try block.addBinOp(.sub, operand, back); | 22610 | const diff = try block.addBinOp(.sub, operand, back); |
| 22407 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try mod.floatValue(operand_ty, 1.0)).toIntern())); | 22611 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_ty, 1.0)).toIntern())); |
| 22408 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try mod.floatValue(operand_ty, -1.0)).toIntern())); | 22612 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_ty, -1.0)).toIntern())); |
| 22409 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); | 22613 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 22410 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | 22614 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| 22411 | } | 22615 | } |
| ... | @@ -22414,14 +22618,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22414,14 +22618,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22414 | const len = dest_ty.vectorLen(mod); | 22618 | const len = dest_ty.vectorLen(mod); |
| 22415 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | 22619 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 22416 | for (new_elems, 0..) |*new_elem, i| { | 22620 | for (new_elems, 0..) |*new_elem, i| { |
| 22417 | const idx_ref = try mod.intRef(Type.usize, i); | 22621 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22418 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | 22622 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 22419 | const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_scalar_ty, old_elem); | 22623 | const result = try block.addTyOp(if (block.float_mode == .optimized) .int_from_float_optimized else .int_from_float, dest_scalar_ty, old_elem); |
| 22420 | if (block.wantSafety()) { | 22624 | if (block.wantSafety()) { |
| 22421 | const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result); | 22625 | const back = try block.addTyOp(.float_from_int, operand_scalar_ty, result); |
| 22422 | const diff = try block.addBinOp(.sub, old_elem, back); | 22626 | const diff = try block.addBinOp(.sub, old_elem, back); |
| 22423 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try mod.floatValue(operand_scalar_ty, 1.0)).toIntern())); | 22627 | const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, 1.0)).toIntern())); |
| 22424 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try mod.floatValue(operand_scalar_ty, -1.0)).toIntern())); | 22628 | const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_scalar_ty, -1.0)).toIntern())); |
| 22425 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); | 22629 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 22426 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); | 22630 | try sema.addSafetyCheck(block, src, ok, .integer_part_out_of_bounds); |
| 22427 | } | 22631 | } |
| ... | @@ -22431,7 +22635,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22431,7 +22635,8 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22431 | } | 22635 | } |
| 22432 | 22636 | ||
| 22433 | fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22637 | fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22434 | const mod = sema.mod; | 22638 | const pt = sema.pt; |
| 22639 | const mod = pt.zcu; | ||
| 22435 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 22640 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22436 | const src = block.nodeOffset(inst_data.src_node); | 22641 | const src = block.nodeOffset(inst_data.src_node); |
| 22437 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 22642 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -22450,7 +22655,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22450,7 +22655,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22450 | _ = try sema.checkIntType(block, operand_src, operand_scalar_ty); | 22655 | _ = try sema.checkIntType(block, operand_src, operand_scalar_ty); |
| 22451 | 22656 | ||
| 22452 | if (try sema.resolveValue(operand)) |operand_val| { | 22657 | if (try sema.resolveValue(operand)) |operand_val| { |
| 22453 | const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, mod, .sema); | 22658 | const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema); |
| 22454 | return Air.internedToRef(result_val.toIntern()); | 22659 | return Air.internedToRef(result_val.toIntern()); |
| 22455 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) { | 22660 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) { |
| 22456 | return sema.failWithNeededComptime(block, operand_src, .{ | 22661 | return sema.failWithNeededComptime(block, operand_src, .{ |
| ... | @@ -22465,7 +22670,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22465,7 +22670,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22465 | const len = operand_ty.vectorLen(mod); | 22670 | const len = operand_ty.vectorLen(mod); |
| 22466 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | 22671 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 22467 | for (new_elems, 0..) |*new_elem, i| { | 22672 | for (new_elems, 0..) |*new_elem, i| { |
| 22468 | const idx_ref = try mod.intRef(Type.usize, i); | 22673 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22469 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); | 22674 | const old_elem = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| 22470 | new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem); | 22675 | new_elem.* = try block.addTyOp(.float_from_int, dest_scalar_ty, old_elem); |
| 22471 | } | 22676 | } |
| ... | @@ -22473,7 +22678,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -22473,7 +22678,8 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22473 | } | 22678 | } |
| 22474 | 22679 | ||
| 22475 | fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 22680 | fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22476 | const mod = sema.mod; | 22681 | const pt = sema.pt; |
| 22682 | const mod = pt.zcu; | ||
| 22477 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 22683 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22478 | const src = block.nodeOffset(inst_data.src_node); | 22684 | const src = block.nodeOffset(inst_data.src_node); |
| 22479 | 22685 | ||
| ... | @@ -22489,7 +22695,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22489,7 +22695,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22489 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | 22695 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; |
| 22490 | const operand_ty = if (is_vector) operand_ty: { | 22696 | const operand_ty = if (is_vector) operand_ty: { |
| 22491 | const len = dest_ty.vectorLen(mod); | 22697 | const len = dest_ty.vectorLen(mod); |
| 22492 | break :operand_ty try mod.vectorType(.{ .child = .usize_type, .len = len }); | 22698 | break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len }); |
| 22493 | } else Type.usize; | 22699 | } else Type.usize; |
| 22494 | 22700 | ||
| 22495 | const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src); | 22701 | const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src); |
| ... | @@ -22498,11 +22704,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22498,11 +22704,11 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22498 | try sema.checkPtrType(block, src, ptr_ty, true); | 22704 | try sema.checkPtrType(block, src, ptr_ty, true); |
| 22499 | 22705 | ||
| 22500 | const elem_ty = ptr_ty.elemType2(mod); | 22706 | const elem_ty = ptr_ty.elemType2(mod); |
| 22501 | const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, .sema); | 22707 | const ptr_align = try ptr_ty.ptrAlignmentAdvanced(pt, .sema); |
| 22502 | 22708 | ||
| 22503 | if (ptr_ty.isSlice(mod)) { | 22709 | if (ptr_ty.isSlice(mod)) { |
| 22504 | const msg = msg: { | 22710 | const msg = msg: { |
| 22505 | const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)}); | 22711 | const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(pt)}); |
| 22506 | errdefer msg.destroy(sema.gpa); | 22712 | errdefer msg.destroy(sema.gpa); |
| 22507 | try sema.errNote(src, msg, "slice length cannot be inferred from address", .{}); | 22713 | try sema.errNote(src, msg, "slice length cannot be inferred from address", .{}); |
| 22508 | break :msg msg; | 22714 | break :msg msg; |
| ... | @@ -22518,18 +22724,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22518,18 +22724,18 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22518 | const len = dest_ty.vectorLen(mod); | 22724 | const len = dest_ty.vectorLen(mod); |
| 22519 | const new_elems = try sema.arena.alloc(InternPool.Index, len); | 22725 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 22520 | for (new_elems, 0..) |*new_elem, i| { | 22726 | for (new_elems, 0..) |*new_elem, i| { |
| 22521 | const elem = try val.elemValue(mod, i); | 22727 | const elem = try val.elemValue(pt, i); |
| 22522 | const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align); | 22728 | const ptr_val = try sema.ptrFromIntVal(block, operand_src, elem, ptr_ty, ptr_align); |
| 22523 | new_elem.* = ptr_val.toIntern(); | 22729 | new_elem.* = ptr_val.toIntern(); |
| 22524 | } | 22730 | } |
| 22525 | return Air.internedToRef(try mod.intern(.{ .aggregate = .{ | 22731 | return Air.internedToRef(try pt.intern(.{ .aggregate = .{ |
| 22526 | .ty = dest_ty.toIntern(), | 22732 | .ty = dest_ty.toIntern(), |
| 22527 | .storage = .{ .elems = new_elems }, | 22733 | .storage = .{ .elems = new_elems }, |
| 22528 | } })); | 22734 | } })); |
| 22529 | } | 22735 | } |
| 22530 | if (try sema.typeRequiresComptime(ptr_ty)) { | 22736 | if (try sema.typeRequiresComptime(ptr_ty)) { |
| 22531 | return sema.failWithOwnedErrorMsg(block, msg: { | 22737 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22532 | const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(mod)}); | 22738 | const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)}); |
| 22533 | errdefer msg.destroy(sema.gpa); | 22739 | errdefer msg.destroy(sema.gpa); |
| 22534 | 22740 | ||
| 22535 | try sema.explainWhyTypeIsComptime(msg, src, ptr_ty); | 22741 | try sema.explainWhyTypeIsComptime(msg, src, ptr_ty); |
| ... | @@ -22545,7 +22751,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22545,7 +22751,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22545 | } | 22751 | } |
| 22546 | if (ptr_align.compare(.gt, .@"1")) { | 22752 | if (ptr_align.compare(.gt, .@"1")) { |
| 22547 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; | 22753 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; |
| 22548 | const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern()); | 22754 | const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern()); |
| 22549 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1); | 22755 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1); |
| 22550 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); | 22756 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| 22551 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); | 22757 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); |
| ... | @@ -22557,7 +22763,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22557,7 +22763,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22557 | const len = dest_ty.vectorLen(mod); | 22763 | const len = dest_ty.vectorLen(mod); |
| 22558 | if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) { | 22764 | if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) { |
| 22559 | for (0..len) |i| { | 22765 | for (0..len) |i| { |
| 22560 | const idx_ref = try mod.intRef(Type.usize, i); | 22766 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22561 | const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); | 22767 | const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); |
| 22562 | if (!ptr_ty.isAllowzeroPtr(mod)) { | 22768 | if (!ptr_ty.isAllowzeroPtr(mod)) { |
| 22563 | const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize); | 22769 | const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize); |
| ... | @@ -22565,7 +22771,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22565,7 +22771,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22565 | } | 22771 | } |
| 22566 | if (ptr_align.compare(.gt, .@"1")) { | 22772 | if (ptr_align.compare(.gt, .@"1")) { |
| 22567 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; | 22773 | const align_bytes_minus_1 = ptr_align.toByteUnits().? - 1; |
| 22568 | const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern()); | 22774 | const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern()); |
| 22569 | const remainder = try block.addBinOp(.bit_and, elem_coerced, align_minus_1); | 22775 | const remainder = try block.addBinOp(.bit_and, elem_coerced, align_minus_1); |
| 22570 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); | 22776 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| 22571 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); | 22777 | try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment); |
| ... | @@ -22575,7 +22781,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -22575,7 +22781,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22575 | 22781 | ||
| 22576 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); | 22782 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 22577 | for (new_elems, 0..) |*new_elem, i| { | 22783 | for (new_elems, 0..) |*new_elem, i| { |
| 22578 | const idx_ref = try mod.intRef(Type.usize, i); | 22784 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22579 | const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); | 22785 | const old_elem = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); |
| 22580 | new_elem.* = try block.addBitCast(ptr_ty, old_elem); | 22786 | new_elem.* = try block.addBitCast(ptr_ty, old_elem); |
| 22581 | } | 22787 | } |
| ... | @@ -22590,31 +22796,33 @@ fn ptrFromIntVal( | ... | @@ -22590,31 +22796,33 @@ fn ptrFromIntVal( |
| 22590 | ptr_ty: Type, | 22796 | ptr_ty: Type, |
| 22591 | ptr_align: Alignment, | 22797 | ptr_align: Alignment, |
| 22592 | ) !Value { | 22798 | ) !Value { |
| 22593 | const zcu = sema.mod; | 22799 | const pt = sema.pt; |
| 22800 | const zcu = pt.zcu; | ||
| 22594 | if (operand_val.isUndef(zcu)) { | 22801 | if (operand_val.isUndef(zcu)) { |
| 22595 | if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") { | 22802 | if (ptr_ty.isAllowzeroPtr(zcu) and ptr_align == .@"1") { |
| 22596 | return zcu.undefValue(ptr_ty); | 22803 | return pt.undefValue(ptr_ty); |
| 22597 | } | 22804 | } |
| 22598 | return sema.failWithUseOfUndef(block, operand_src); | 22805 | return sema.failWithUseOfUndef(block, operand_src); |
| 22599 | } | 22806 | } |
| 22600 | const addr = try operand_val.toUnsignedIntSema(zcu); | 22807 | const addr = try operand_val.toUnsignedIntSema(pt); |
| 22601 | if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0) | 22808 | if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0) |
| 22602 | return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(zcu)}); | 22809 | return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(pt)}); |
| 22603 | if (addr != 0 and ptr_align != .none and !ptr_align.check(addr)) | 22810 | if (addr != 0 and ptr_align != .none and !ptr_align.check(addr)) |
| 22604 | return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(zcu)}); | 22811 | return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)}); |
| 22605 | 22812 | ||
| 22606 | return switch (ptr_ty.zigTypeTag(zcu)) { | 22813 | return switch (ptr_ty.zigTypeTag(zcu)) { |
| 22607 | .Optional => Value.fromInterned((try zcu.intern(.{ .opt = .{ | 22814 | .Optional => Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 22608 | .ty = ptr_ty.toIntern(), | 22815 | .ty = ptr_ty.toIntern(), |
| 22609 | .val = if (addr == 0) .none else (try zcu.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(), | 22816 | .val = if (addr == 0) .none else (try pt.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(), |
| 22610 | } }))), | 22817 | } })), |
| 22611 | .Pointer => try zcu.ptrIntValue(ptr_ty, addr), | 22818 | .Pointer => try pt.ptrIntValue(ptr_ty, addr), |
| 22612 | else => unreachable, | 22819 | else => unreachable, |
| 22613 | }; | 22820 | }; |
| 22614 | } | 22821 | } |
| 22615 | 22822 | ||
| 22616 | fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 22823 | fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 22617 | const mod = sema.mod; | 22824 | const pt = sema.pt; |
| 22825 | const mod = pt.zcu; | ||
| 22618 | const ip = &mod.intern_pool; | 22826 | const ip = &mod.intern_pool; |
| 22619 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 22827 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 22620 | const src = block.nodeOffset(extra.node); | 22828 | const src = block.nodeOffset(extra.node); |
| ... | @@ -22642,8 +22850,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData | ... | @@ -22642,8 +22850,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22642 | errdefer msg.destroy(sema.gpa); | 22850 | errdefer msg.destroy(sema.gpa); |
| 22643 | const dest_ty = base_dest_ty.errorUnionPayload(mod); | 22851 | const dest_ty = base_dest_ty.errorUnionPayload(mod); |
| 22644 | const operand_ty = base_operand_ty.errorUnionPayload(mod); | 22852 | const operand_ty = base_operand_ty.errorUnionPayload(mod); |
| 22645 | try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)}); | 22853 | try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(pt)}); |
| 22646 | try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)}); | 22854 | try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(pt)}); |
| 22647 | try addDeclaredHereNote(sema, msg, dest_ty); | 22855 | try addDeclaredHereNote(sema, msg, dest_ty); |
| 22648 | try addDeclaredHereNote(sema, msg, operand_ty); | 22856 | try addDeclaredHereNote(sema, msg, operand_ty); |
| 22649 | break :msg msg; | 22857 | break :msg msg; |
| ... | @@ -22684,7 +22892,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData | ... | @@ -22684,7 +22892,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22684 | }; | 22892 | }; |
| 22685 | if (disjoint and dest_tag != .ErrorUnion) { | 22893 | if (disjoint and dest_tag != .ErrorUnion) { |
| 22686 | return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{ | 22894 | return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{ |
| 22687 | operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod), | 22895 | operand_ty.fmt(pt), dest_ty.fmt(pt), |
| 22688 | }); | 22896 | }); |
| 22689 | } | 22897 | } |
| 22690 | 22898 | ||
| ... | @@ -22700,24 +22908,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData | ... | @@ -22700,24 +22908,24 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22700 | } | 22908 | } |
| 22701 | if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) { | 22909 | if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) { |
| 22702 | return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{ | 22910 | return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{ |
| 22703 | error_name.fmt(ip), dest_ty.fmt(sema.mod), | 22911 | error_name.fmt(ip), dest_ty.fmt(pt), |
| 22704 | }); | 22912 | }); |
| 22705 | } | 22913 | } |
| 22706 | } | 22914 | } |
| 22707 | 22915 | ||
| 22708 | return Air.internedToRef((try mod.getCoerced(val, base_dest_ty)).toIntern()); | 22916 | return Air.internedToRef((try pt.getCoerced(val, base_dest_ty)).toIntern()); |
| 22709 | } | 22917 | } |
| 22710 | 22918 | ||
| 22711 | try sema.requireRuntimeBlock(block, src, operand_src); | 22919 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 22712 | const err_int_ty = try mod.errorIntType(); | 22920 | const err_int_ty = try pt.errorIntType(); |
| 22713 | if (block.wantSafety() and !dest_ty.isAnyError(mod) and | 22921 | if (block.wantSafety() and !dest_ty.isAnyError(mod) and |
| 22714 | dest_ty.toIntern() != .adhoc_inferred_error_set_type and | 22922 | dest_ty.toIntern() != .adhoc_inferred_error_set_type and |
| 22715 | sema.mod.backendSupportsFeature(.error_set_has_value)) | 22923 | mod.backendSupportsFeature(.error_set_has_value)) |
| 22716 | { | 22924 | { |
| 22717 | if (dest_tag == .ErrorUnion) { | 22925 | if (dest_tag == .ErrorUnion) { |
| 22718 | const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand); | 22926 | const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand); |
| 22719 | const err_int = try block.addBitCast(err_int_ty, err_code); | 22927 | const err_int = try block.addBitCast(err_int_ty, err_code); |
| 22720 | const zero_err = try mod.intRef(try mod.errorIntType(), 0); | 22928 | const zero_err = try pt.intRef(try pt.errorIntType(), 0); |
| 22721 | 22929 | ||
| 22722 | const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err); | 22930 | const is_zero = try block.addBinOp(.cmp_eq, err_int, zero_err); |
| 22723 | if (disjoint) { | 22931 | if (disjoint) { |
| ... | @@ -22786,7 +22994,8 @@ fn ptrCastFull( | ... | @@ -22786,7 +22994,8 @@ fn ptrCastFull( |
| 22786 | dest_ty: Type, | 22994 | dest_ty: Type, |
| 22787 | operation: []const u8, | 22995 | operation: []const u8, |
| 22788 | ) CompileError!Air.Inst.Ref { | 22996 | ) CompileError!Air.Inst.Ref { |
| 22789 | const mod = sema.mod; | 22997 | const pt = sema.pt; |
| 22998 | const mod = pt.zcu; | ||
| 22790 | const operand_ty = sema.typeOf(operand); | 22999 | const operand_ty = sema.typeOf(operand); |
| 22791 | 23000 | ||
| 22792 | try sema.checkPtrType(block, src, dest_ty, true); | 23001 | try sema.checkPtrType(block, src, dest_ty, true); |
| ... | @@ -22795,8 +23004,8 @@ fn ptrCastFull( | ... | @@ -22795,8 +23004,8 @@ fn ptrCastFull( |
| 22795 | const src_info = operand_ty.ptrInfo(mod); | 23004 | const src_info = operand_ty.ptrInfo(mod); |
| 22796 | const dest_info = dest_ty.ptrInfo(mod); | 23005 | const dest_info = dest_ty.ptrInfo(mod); |
| 22797 | 23006 | ||
| 22798 | try Type.fromInterned(src_info.child).resolveLayout(mod); | 23007 | try Type.fromInterned(src_info.child).resolveLayout(pt); |
| 22799 | try Type.fromInterned(dest_info.child).resolveLayout(mod); | 23008 | try Type.fromInterned(dest_info.child).resolveLayout(pt); |
| 22800 | 23009 | ||
| 22801 | const src_slice_like = src_info.flags.size == .Slice or | 23010 | const src_slice_like = src_info.flags.size == .Slice or |
| 22802 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array); | 23011 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array); |
| ... | @@ -22810,12 +23019,12 @@ fn ptrCastFull( | ... | @@ -22810,12 +23019,12 @@ fn ptrCastFull( |
| 22810 | 23019 | ||
| 22811 | if (dest_info.flags.size == .Slice) { | 23020 | if (dest_info.flags.size == .Slice) { |
| 22812 | const src_elem_size = switch (src_info.flags.size) { | 23021 | const src_elem_size = switch (src_info.flags.size) { |
| 22813 | .Slice => Type.fromInterned(src_info.child).abiSize(mod), | 23022 | .Slice => Type.fromInterned(src_info.child).abiSize(pt), |
| 22814 | // pointer to array | 23023 | // pointer to array |
| 22815 | .One => Type.fromInterned(src_info.child).childType(mod).abiSize(mod), | 23024 | .One => Type.fromInterned(src_info.child).childType(mod).abiSize(pt), |
| 22816 | else => unreachable, | 23025 | else => unreachable, |
| 22817 | }; | 23026 | }; |
| 22818 | const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(mod); | 23027 | const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(pt); |
| 22819 | if (src_elem_size != dest_elem_size) { | 23028 | if (src_elem_size != dest_elem_size) { |
| 22820 | return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation}); | 23029 | return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation}); |
| 22821 | } | 23030 | } |
| ... | @@ -22867,8 +23076,7 @@ fn ptrCastFull( | ... | @@ -22867,8 +23076,7 @@ fn ptrCastFull( |
| 22867 | if (imc_res == .ok) break :check_child; | 23076 | if (imc_res == .ok) break :check_child; |
| 22868 | return sema.failWithOwnedErrorMsg(block, msg: { | 23077 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22869 | const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{ | 23078 | const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{ |
| 22870 | src_child.fmt(mod), | 23079 | src_child.fmt(pt), dest_child.fmt(pt), |
| 22871 | dest_child.fmt(mod), | ||
| 22872 | }); | 23080 | }); |
| 22873 | errdefer msg.destroy(sema.gpa); | 23081 | errdefer msg.destroy(sema.gpa); |
| 22874 | try imc_res.report(sema, src, msg); | 23082 | try imc_res.report(sema, src, msg); |
| ... | @@ -22881,26 +23089,26 @@ fn ptrCastFull( | ... | @@ -22881,26 +23089,26 @@ fn ptrCastFull( |
| 22881 | if (dest_info.sentinel == .none) break :check_sent; | 23089 | if (dest_info.sentinel == .none) break :check_sent; |
| 22882 | if (src_info.flags.size == .C) break :check_sent; | 23090 | if (src_info.flags.size == .C) break :check_sent; |
| 22883 | if (src_info.sentinel != .none) { | 23091 | if (src_info.sentinel != .none) { |
| 22884 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child); | 23092 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child); |
| 22885 | if (dest_info.sentinel == coerced_sent) break :check_sent; | 23093 | if (dest_info.sentinel == coerced_sent) break :check_sent; |
| 22886 | } | 23094 | } |
| 22887 | if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) { | 23095 | if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) { |
| 22888 | // [*]nT -> []T | 23096 | // [*]nT -> []T |
| 22889 | const arr_ty = Type.fromInterned(src_info.child); | 23097 | const arr_ty = Type.fromInterned(src_info.child); |
| 22890 | if (arr_ty.sentinel(mod)) |src_sentinel| { | 23098 | if (arr_ty.sentinel(mod)) |src_sentinel| { |
| 22891 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, src_sentinel.toIntern(), dest_info.child); | 23099 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child); |
| 22892 | if (dest_info.sentinel == coerced_sent) break :check_sent; | 23100 | if (dest_info.sentinel == coerced_sent) break :check_sent; |
| 22893 | } | 23101 | } |
| 22894 | } | 23102 | } |
| 22895 | return sema.failWithOwnedErrorMsg(block, msg: { | 23103 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22896 | const msg = if (src_info.sentinel == .none) blk: { | 23104 | const msg = if (src_info.sentinel == .none) blk: { |
| 22897 | break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{ | 23105 | break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{ |
| 22898 | Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema), | 23106 | Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema), |
| 22899 | }); | 23107 | }); |
| 22900 | } else blk: { | 23108 | } else blk: { |
| 22901 | break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ | 23109 | break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ |
| 22902 | Value.fromInterned(src_info.sentinel).fmtValue(mod, sema), | 23110 | Value.fromInterned(src_info.sentinel).fmtValue(pt, sema), |
| 22903 | Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema), | 23111 | Value.fromInterned(dest_info.sentinel).fmtValue(pt, sema), |
| 22904 | }); | 23112 | }); |
| 22905 | }; | 23113 | }; |
| 22906 | errdefer msg.destroy(sema.gpa); | 23114 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -22941,8 +23149,8 @@ fn ptrCastFull( | ... | @@ -22941,8 +23149,8 @@ fn ptrCastFull( |
| 22941 | 23149 | ||
| 22942 | return sema.failWithOwnedErrorMsg(block, msg: { | 23150 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22943 | const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{ | 23151 | const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{ |
| 22944 | operand_ty.fmt(mod), | 23152 | operand_ty.fmt(pt), |
| 22945 | dest_ty.fmt(mod), | 23153 | dest_ty.fmt(pt), |
| 22946 | }); | 23154 | }); |
| 22947 | errdefer msg.destroy(sema.gpa); | 23155 | errdefer msg.destroy(sema.gpa); |
| 22948 | try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{}); | 23156 | try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{}); |
| ... | @@ -22956,12 +23164,12 @@ fn ptrCastFull( | ... | @@ -22956,12 +23164,12 @@ fn ptrCastFull( |
| 22956 | const src_align = if (src_info.flags.alignment != .none) | 23164 | const src_align = if (src_info.flags.alignment != .none) |
| 22957 | src_info.flags.alignment | 23165 | src_info.flags.alignment |
| 22958 | else | 23166 | else |
| 22959 | Type.fromInterned(src_info.child).abiAlignment(mod); | 23167 | Type.fromInterned(src_info.child).abiAlignment(pt); |
| 22960 | 23168 | ||
| 22961 | const dest_align = if (dest_info.flags.alignment != .none) | 23169 | const dest_align = if (dest_info.flags.alignment != .none) |
| 22962 | dest_info.flags.alignment | 23170 | dest_info.flags.alignment |
| 22963 | else | 23171 | else |
| 22964 | Type.fromInterned(dest_info.child).abiAlignment(mod); | 23172 | Type.fromInterned(dest_info.child).abiAlignment(pt); |
| 22965 | 23173 | ||
| 22966 | if (!flags.align_cast) { | 23174 | if (!flags.align_cast) { |
| 22967 | if (dest_align.compare(.gt, src_align)) { | 23175 | if (dest_align.compare(.gt, src_align)) { |
| ... | @@ -22969,10 +23177,10 @@ fn ptrCastFull( | ... | @@ -22969,10 +23177,10 @@ fn ptrCastFull( |
| 22969 | const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation}); | 23177 | const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation}); |
| 22970 | errdefer msg.destroy(sema.gpa); | 23178 | errdefer msg.destroy(sema.gpa); |
| 22971 | try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{ | 23179 | try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{ |
| 22972 | operand_ty.fmt(mod), src_align.toByteUnits() orelse 0, | 23180 | operand_ty.fmt(pt), src_align.toByteUnits() orelse 0, |
| 22973 | }); | 23181 | }); |
| 22974 | try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{ | 23182 | try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{ |
| 22975 | dest_ty.fmt(mod), dest_align.toByteUnits() orelse 0, | 23183 | dest_ty.fmt(pt), dest_align.toByteUnits() orelse 0, |
| 22976 | }); | 23184 | }); |
| 22977 | try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{}); | 23185 | try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{}); |
| 22978 | break :msg msg; | 23186 | break :msg msg; |
| ... | @@ -22986,10 +23194,10 @@ fn ptrCastFull( | ... | @@ -22986,10 +23194,10 @@ fn ptrCastFull( |
| 22986 | const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation}); | 23194 | const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation}); |
| 22987 | errdefer msg.destroy(sema.gpa); | 23195 | errdefer msg.destroy(sema.gpa); |
| 22988 | try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{ | 23196 | try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{ |
| 22989 | operand_ty.fmt(mod), @tagName(src_info.flags.address_space), | 23197 | operand_ty.fmt(pt), @tagName(src_info.flags.address_space), |
| 22990 | }); | 23198 | }); |
| 22991 | try sema.errNote(src, msg, "'{}' has address space '{s}'", .{ | 23199 | try sema.errNote(src, msg, "'{}' has address space '{s}'", .{ |
| 22992 | dest_ty.fmt(mod), @tagName(dest_info.flags.address_space), | 23200 | dest_ty.fmt(pt), @tagName(dest_info.flags.address_space), |
| 22993 | }); | 23201 | }); |
| 22994 | try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{}); | 23202 | try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{}); |
| 22995 | break :msg msg; | 23203 | break :msg msg; |
| ... | @@ -23044,9 +23252,9 @@ fn ptrCastFull( | ... | @@ -23044,9 +23252,9 @@ fn ptrCastFull( |
| 23044 | // Only convert to a many-pointer at first | 23252 | // Only convert to a many-pointer at first |
| 23045 | var info = dest_info; | 23253 | var info = dest_info; |
| 23046 | info.flags.size = .Many; | 23254 | info.flags.size = .Many; |
| 23047 | const ty = try mod.ptrTypeSema(info); | 23255 | const ty = try pt.ptrTypeSema(info); |
| 23048 | if (dest_ty.zigTypeTag(mod) == .Optional) { | 23256 | if (dest_ty.zigTypeTag(mod) == .Optional) { |
| 23049 | break :blk try mod.optionalType(ty.toIntern()); | 23257 | break :blk try pt.optionalType(ty.toIntern()); |
| 23050 | } else { | 23258 | } else { |
| 23051 | break :blk ty; | 23259 | break :blk ty; |
| 23052 | } | 23260 | } |
| ... | @@ -23059,10 +23267,10 @@ fn ptrCastFull( | ... | @@ -23059,10 +23267,10 @@ fn ptrCastFull( |
| 23059 | return sema.failWithUseOfUndef(block, operand_src); | 23267 | return sema.failWithUseOfUndef(block, operand_src); |
| 23060 | } | 23268 | } |
| 23061 | if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) { | 23269 | if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) { |
| 23062 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)}); | 23270 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)}); |
| 23063 | } | 23271 | } |
| 23064 | if (dest_align.compare(.gt, src_align)) { | 23272 | if (dest_align.compare(.gt, src_align)) { |
| 23065 | if (try ptr_val.getUnsignedIntAdvanced(mod, .sema)) |addr| { | 23273 | if (try ptr_val.getUnsignedIntAdvanced(pt, .sema)) |addr| { |
| 23066 | if (!dest_align.check(addr)) { | 23274 | if (!dest_align.check(addr)) { |
| 23067 | return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ | 23275 | return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ |
| 23068 | addr, | 23276 | addr, |
| ... | @@ -23072,12 +23280,12 @@ fn ptrCastFull( | ... | @@ -23072,12 +23280,12 @@ fn ptrCastFull( |
| 23072 | } | 23280 | } |
| 23073 | } | 23281 | } |
| 23074 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { | 23282 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { |
| 23075 | if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty); | 23283 | if (ptr_val.isUndef(mod)) return pt.undefRef(dest_ty); |
| 23076 | const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod)); | 23284 | const arr_len = try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod)); |
| 23077 | const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | 23285 | const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr; |
| 23078 | return Air.internedToRef((try mod.intern(.{ .slice = .{ | 23286 | return Air.internedToRef((try pt.intern(.{ .slice = .{ |
| 23079 | .ty = dest_ty.toIntern(), | 23287 | .ty = dest_ty.toIntern(), |
| 23080 | .ptr = try mod.intern(.{ .ptr = .{ | 23288 | .ptr = try pt.intern(.{ .ptr = .{ |
| 23081 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), | 23289 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), |
| 23082 | .base_addr = ptr_val_key.base_addr, | 23290 | .base_addr = ptr_val_key.base_addr, |
| 23083 | .byte_offset = ptr_val_key.byte_offset, | 23291 | .byte_offset = ptr_val_key.byte_offset, |
| ... | @@ -23086,7 +23294,7 @@ fn ptrCastFull( | ... | @@ -23086,7 +23294,7 @@ fn ptrCastFull( |
| 23086 | } }))); | 23294 | } }))); |
| 23087 | } else { | 23295 | } else { |
| 23088 | assert(dest_ptr_ty.eql(dest_ty, mod)); | 23296 | assert(dest_ptr_ty.eql(dest_ty, mod)); |
| 23089 | return Air.internedToRef((try mod.getCoerced(ptr_val, dest_ty)).toIntern()); | 23297 | return Air.internedToRef((try pt.getCoerced(ptr_val, dest_ty)).toIntern()); |
| 23090 | } | 23298 | } |
| 23091 | } | 23299 | } |
| 23092 | } | 23300 | } |
| ... | @@ -23112,7 +23320,7 @@ fn ptrCastFull( | ... | @@ -23112,7 +23320,7 @@ fn ptrCastFull( |
| 23112 | try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child))) | 23320 | try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child))) |
| 23113 | { | 23321 | { |
| 23114 | const align_bytes_minus_1 = dest_align.toByteUnits().? - 1; | 23322 | const align_bytes_minus_1 = dest_align.toByteUnits().? - 1; |
| 23115 | const align_minus_1 = Air.internedToRef((try mod.intValue(Type.usize, align_bytes_minus_1)).toIntern()); | 23323 | const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern()); |
| 23116 | const ptr_int = try block.addUnOp(.int_from_ptr, ptr); | 23324 | const ptr_int = try block.addUnOp(.int_from_ptr, ptr); |
| 23117 | const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1); | 23325 | const remainder = try block.addBinOp(.bit_and, ptr_int, align_minus_1); |
| 23118 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); | 23326 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| ... | @@ -23129,9 +23337,9 @@ fn ptrCastFull( | ... | @@ -23129,9 +23337,9 @@ fn ptrCastFull( |
| 23129 | // We can't change address spaces with a bitcast, so this requires two instructions | 23337 | // We can't change address spaces with a bitcast, so this requires two instructions |
| 23130 | var intermediate_info = src_info; | 23338 | var intermediate_info = src_info; |
| 23131 | intermediate_info.flags.address_space = dest_info.flags.address_space; | 23339 | intermediate_info.flags.address_space = dest_info.flags.address_space; |
| 23132 | const intermediate_ptr_ty = try mod.ptrTypeSema(intermediate_info); | 23340 | const intermediate_ptr_ty = try pt.ptrTypeSema(intermediate_info); |
| 23133 | const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: { | 23341 | const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: { |
| 23134 | break :blk try mod.optionalType(intermediate_ptr_ty.toIntern()); | 23342 | break :blk try pt.optionalType(intermediate_ptr_ty.toIntern()); |
| 23135 | } else intermediate_ptr_ty; | 23343 | } else intermediate_ptr_ty; |
| 23136 | const intermediate = try block.addInst(.{ | 23344 | const intermediate = try block.addInst(.{ |
| 23137 | .tag = .addrspace_cast, | 23345 | .tag = .addrspace_cast, |
| ... | @@ -23152,7 +23360,7 @@ fn ptrCastFull( | ... | @@ -23152,7 +23360,7 @@ fn ptrCastFull( |
| 23152 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { | 23360 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { |
| 23153 | // We have to construct a slice using the operand's child's array length | 23361 | // We have to construct a slice using the operand's child's array length |
| 23154 | // Note that we know from the check at the start of the function that operand_ty is slice-like | 23362 | // Note that we know from the check at the start of the function that operand_ty is slice-like |
| 23155 | const arr_len = Air.internedToRef((try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern()); | 23363 | const arr_len = Air.internedToRef((try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern()); |
| 23156 | return block.addInst(.{ | 23364 | return block.addInst(.{ |
| 23157 | .tag = .slice, | 23365 | .tag = .slice, |
| 23158 | .data = .{ .ty_pl = .{ | 23366 | .data = .{ .ty_pl = .{ |
| ... | @@ -23171,7 +23379,8 @@ fn ptrCastFull( | ... | @@ -23171,7 +23379,8 @@ fn ptrCastFull( |
| 23171 | } | 23379 | } |
| 23172 | 23380 | ||
| 23173 | fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 23381 | fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 23174 | const mod = sema.mod; | 23382 | const pt = sema.pt; |
| 23383 | const mod = pt.zcu; | ||
| 23175 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?; | 23384 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?; |
| 23176 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); | 23385 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); |
| 23177 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 23386 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| ... | @@ -23186,15 +23395,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst | ... | @@ -23186,15 +23395,15 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 23186 | if (flags.volatile_cast) ptr_info.flags.is_volatile = false; | 23395 | if (flags.volatile_cast) ptr_info.flags.is_volatile = false; |
| 23187 | 23396 | ||
| 23188 | const dest_ty = blk: { | 23397 | const dest_ty = blk: { |
| 23189 | const dest_ty = try mod.ptrTypeSema(ptr_info); | 23398 | const dest_ty = try pt.ptrTypeSema(ptr_info); |
| 23190 | if (operand_ty.zigTypeTag(mod) == .Optional) { | 23399 | if (operand_ty.zigTypeTag(mod) == .Optional) { |
| 23191 | break :blk try mod.optionalType(dest_ty.toIntern()); | 23400 | break :blk try pt.optionalType(dest_ty.toIntern()); |
| 23192 | } | 23401 | } |
| 23193 | break :blk dest_ty; | 23402 | break :blk dest_ty; |
| 23194 | }; | 23403 | }; |
| 23195 | 23404 | ||
| 23196 | if (try sema.resolveValue(operand)) |operand_val| { | 23405 | if (try sema.resolveValue(operand)) |operand_val| { |
| 23197 | return Air.internedToRef((try mod.getCoerced(operand_val, dest_ty)).toIntern()); | 23406 | return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern()); |
| 23198 | } | 23407 | } |
| 23199 | 23408 | ||
| 23200 | try sema.requireRuntimeBlock(block, src, null); | 23409 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -23204,7 +23413,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst | ... | @@ -23204,7 +23413,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 23204 | } | 23413 | } |
| 23205 | 23414 | ||
| 23206 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23415 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23207 | const mod = sema.mod; | 23416 | const pt = sema.pt; |
| 23417 | const mod = pt.zcu; | ||
| 23208 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 23418 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 23209 | const src = block.nodeOffset(inst_data.src_node); | 23419 | const src = block.nodeOffset(inst_data.src_node); |
| 23210 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 23420 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -23218,7 +23428,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23218,7 +23428,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23218 | const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector; | 23428 | const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector; |
| 23219 | const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector; | 23429 | const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector; |
| 23220 | if (operand_is_vector != dest_is_vector) { | 23430 | if (operand_is_vector != dest_is_vector) { |
| 23221 | return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(mod), operand_ty.fmt(mod) }); | 23431 | return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) }); |
| 23222 | } | 23432 | } |
| 23223 | 23433 | ||
| 23224 | if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | 23434 | if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { |
| ... | @@ -23239,7 +23449,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23239,7 +23449,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23239 | 23449 | ||
| 23240 | if (operand_info.signedness != dest_info.signedness) { | 23450 | if (operand_info.signedness != dest_info.signedness) { |
| 23241 | return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{ | 23451 | return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{ |
| 23242 | @tagName(dest_info.signedness), operand_ty.fmt(mod), | 23452 | @tagName(dest_info.signedness), operand_ty.fmt(pt), |
| 23243 | }); | 23453 | }); |
| 23244 | } | 23454 | } |
| 23245 | if (operand_info.bits < dest_info.bits) { | 23455 | if (operand_info.bits < dest_info.bits) { |
| ... | @@ -23247,7 +23457,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23247,7 +23457,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23247 | const msg = try sema.errMsg( | 23457 | const msg = try sema.errMsg( |
| 23248 | src, | 23458 | src, |
| 23249 | "destination type '{}' has more bits than source type '{}'", | 23459 | "destination type '{}' has more bits than source type '{}'", |
| 23250 | .{ dest_ty.fmt(mod), operand_ty.fmt(mod) }, | 23460 | .{ dest_ty.fmt(pt), operand_ty.fmt(pt) }, |
| 23251 | ); | 23461 | ); |
| 23252 | errdefer msg.destroy(sema.gpa); | 23462 | errdefer msg.destroy(sema.gpa); |
| 23253 | try sema.errNote(src, msg, "destination type has {d} bits", .{ | 23463 | try sema.errNote(src, msg, "destination type has {d} bits", .{ |
| ... | @@ -23263,20 +23473,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23263,20 +23473,20 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23263 | } | 23473 | } |
| 23264 | 23474 | ||
| 23265 | if (try sema.resolveValueIntable(operand)) |val| { | 23475 | if (try sema.resolveValueIntable(operand)) |val| { |
| 23266 | if (val.isUndef(mod)) return mod.undefRef(dest_ty); | 23476 | if (val.isUndef(mod)) return pt.undefRef(dest_ty); |
| 23267 | if (!dest_is_vector) { | 23477 | if (!dest_is_vector) { |
| 23268 | return Air.internedToRef((try mod.getCoerced( | 23478 | return Air.internedToRef((try pt.getCoerced( |
| 23269 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, mod), | 23479 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, pt), |
| 23270 | dest_ty, | 23480 | dest_ty, |
| 23271 | )).toIntern()); | 23481 | )).toIntern()); |
| 23272 | } | 23482 | } |
| 23273 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); | 23483 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); |
| 23274 | for (elems, 0..) |*elem, i| { | 23484 | for (elems, 0..) |*elem, i| { |
| 23275 | const elem_val = try val.elemValue(mod, i); | 23485 | const elem_val = try val.elemValue(pt, i); |
| 23276 | const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod); | 23486 | const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, pt); |
| 23277 | elem.* = (try mod.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern(); | 23487 | elem.* = (try pt.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern(); |
| 23278 | } | 23488 | } |
| 23279 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23489 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 23280 | .ty = dest_ty.toIntern(), | 23490 | .ty = dest_ty.toIntern(), |
| 23281 | .storage = .{ .elems = elems }, | 23491 | .storage = .{ .elems = elems }, |
| 23282 | } }))); | 23492 | } }))); |
| ... | @@ -23291,9 +23501,10 @@ fn zirBitCount( | ... | @@ -23291,9 +23501,10 @@ fn zirBitCount( |
| 23291 | block: *Block, | 23501 | block: *Block, |
| 23292 | inst: Zir.Inst.Index, | 23502 | inst: Zir.Inst.Index, |
| 23293 | air_tag: Air.Inst.Tag, | 23503 | air_tag: Air.Inst.Tag, |
| 23294 | comptime comptimeOp: fn (val: Value, ty: Type, mod: *Module) u64, | 23504 | comptime comptimeOp: fn (val: Value, ty: Type, pt: Zcu.PerThread) u64, |
| 23295 | ) CompileError!Air.Inst.Ref { | 23505 | ) CompileError!Air.Inst.Ref { |
| 23296 | const mod = sema.mod; | 23506 | const pt = sema.pt; |
| 23507 | const mod = pt.zcu; | ||
| 23297 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 23508 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 23298 | const src = block.nodeOffset(inst_data.src_node); | 23509 | const src = block.nodeOffset(inst_data.src_node); |
| 23299 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 23510 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -23306,25 +23517,25 @@ fn zirBitCount( | ... | @@ -23306,25 +23517,25 @@ fn zirBitCount( |
| 23306 | return Air.internedToRef(val.toIntern()); | 23517 | return Air.internedToRef(val.toIntern()); |
| 23307 | } | 23518 | } |
| 23308 | 23519 | ||
| 23309 | const result_scalar_ty = try mod.smallestUnsignedInt(bits); | 23520 | const result_scalar_ty = try pt.smallestUnsignedInt(bits); |
| 23310 | switch (operand_ty.zigTypeTag(mod)) { | 23521 | switch (operand_ty.zigTypeTag(mod)) { |
| 23311 | .Vector => { | 23522 | .Vector => { |
| 23312 | const vec_len = operand_ty.vectorLen(mod); | 23523 | const vec_len = operand_ty.vectorLen(mod); |
| 23313 | const result_ty = try mod.vectorType(.{ | 23524 | const result_ty = try pt.vectorType(.{ |
| 23314 | .len = vec_len, | 23525 | .len = vec_len, |
| 23315 | .child = result_scalar_ty.toIntern(), | 23526 | .child = result_scalar_ty.toIntern(), |
| 23316 | }); | 23527 | }); |
| 23317 | if (try sema.resolveValue(operand)) |val| { | 23528 | if (try sema.resolveValue(operand)) |val| { |
| 23318 | if (val.isUndef(mod)) return mod.undefRef(result_ty); | 23529 | if (val.isUndef(mod)) return pt.undefRef(result_ty); |
| 23319 | 23530 | ||
| 23320 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 23531 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23321 | const scalar_ty = operand_ty.scalarType(mod); | 23532 | const scalar_ty = operand_ty.scalarType(mod); |
| 23322 | for (elems, 0..) |*elem, i| { | 23533 | for (elems, 0..) |*elem, i| { |
| 23323 | const elem_val = try val.elemValue(mod, i); | 23534 | const elem_val = try val.elemValue(pt, i); |
| 23324 | const count = comptimeOp(elem_val, scalar_ty, mod); | 23535 | const count = comptimeOp(elem_val, scalar_ty, pt); |
| 23325 | elem.* = (try mod.intValue(result_scalar_ty, count)).toIntern(); | 23536 | elem.* = (try pt.intValue(result_scalar_ty, count)).toIntern(); |
| 23326 | } | 23537 | } |
| 23327 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23538 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 23328 | .ty = result_ty.toIntern(), | 23539 | .ty = result_ty.toIntern(), |
| 23329 | .storage = .{ .elems = elems }, | 23540 | .storage = .{ .elems = elems }, |
| 23330 | } }))); | 23541 | } }))); |
| ... | @@ -23335,8 +23546,8 @@ fn zirBitCount( | ... | @@ -23335,8 +23546,8 @@ fn zirBitCount( |
| 23335 | }, | 23546 | }, |
| 23336 | .Int => { | 23547 | .Int => { |
| 23337 | if (try sema.resolveValueResolveLazy(operand)) |val| { | 23548 | if (try sema.resolveValueResolveLazy(operand)) |val| { |
| 23338 | if (val.isUndef(mod)) return mod.undefRef(result_scalar_ty); | 23549 | if (val.isUndef(mod)) return pt.undefRef(result_scalar_ty); |
| 23339 | return mod.intRef(result_scalar_ty, comptimeOp(val, operand_ty, mod)); | 23550 | return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, pt)); |
| 23340 | } else { | 23551 | } else { |
| 23341 | try sema.requireRuntimeBlock(block, src, operand_src); | 23552 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 23342 | return block.addTyOp(air_tag, result_scalar_ty, operand); | 23553 | return block.addTyOp(air_tag, result_scalar_ty, operand); |
| ... | @@ -23347,7 +23558,8 @@ fn zirBitCount( | ... | @@ -23347,7 +23558,8 @@ fn zirBitCount( |
| 23347 | } | 23558 | } |
| 23348 | 23559 | ||
| 23349 | fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23560 | fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23350 | const mod = sema.mod; | 23561 | const pt = sema.pt; |
| 23562 | const mod = pt.zcu; | ||
| 23351 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 23563 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 23352 | const src = block.nodeOffset(inst_data.src_node); | 23564 | const src = block.nodeOffset(inst_data.src_node); |
| 23353 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 23565 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -23360,7 +23572,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23360,7 +23572,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23360 | block, | 23572 | block, |
| 23361 | operand_src, | 23573 | operand_src, |
| 23362 | "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits", | 23574 | "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits", |
| 23363 | .{ scalar_ty.fmt(mod), bits }, | 23575 | .{ scalar_ty.fmt(pt), bits }, |
| 23364 | ); | 23576 | ); |
| 23365 | } | 23577 | } |
| 23366 | 23578 | ||
| ... | @@ -23371,8 +23583,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23371,8 +23583,8 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23371 | switch (operand_ty.zigTypeTag(mod)) { | 23583 | switch (operand_ty.zigTypeTag(mod)) { |
| 23372 | .Int => { | 23584 | .Int => { |
| 23373 | const runtime_src = if (try sema.resolveValue(operand)) |val| { | 23585 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23374 | if (val.isUndef(mod)) return mod.undefRef(operand_ty); | 23586 | if (val.isUndef(mod)) return pt.undefRef(operand_ty); |
| 23375 | const result_val = try val.byteSwap(operand_ty, mod, sema.arena); | 23587 | const result_val = try val.byteSwap(operand_ty, pt, sema.arena); |
| 23376 | return Air.internedToRef(result_val.toIntern()); | 23588 | return Air.internedToRef(result_val.toIntern()); |
| 23377 | } else operand_src; | 23589 | } else operand_src; |
| 23378 | 23590 | ||
| ... | @@ -23382,15 +23594,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23382,15 +23594,15 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23382 | .Vector => { | 23594 | .Vector => { |
| 23383 | const runtime_src = if (try sema.resolveValue(operand)) |val| { | 23595 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23384 | if (val.isUndef(mod)) | 23596 | if (val.isUndef(mod)) |
| 23385 | return mod.undefRef(operand_ty); | 23597 | return pt.undefRef(operand_ty); |
| 23386 | 23598 | ||
| 23387 | const vec_len = operand_ty.vectorLen(mod); | 23599 | const vec_len = operand_ty.vectorLen(mod); |
| 23388 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 23600 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23389 | for (elems, 0..) |*elem, i| { | 23601 | for (elems, 0..) |*elem, i| { |
| 23390 | const elem_val = try val.elemValue(mod, i); | 23602 | const elem_val = try val.elemValue(pt, i); |
| 23391 | elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern(); | 23603 | elem.* = (try elem_val.byteSwap(scalar_ty, pt, sema.arena)).toIntern(); |
| 23392 | } | 23604 | } |
| 23393 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23605 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 23394 | .ty = operand_ty.toIntern(), | 23606 | .ty = operand_ty.toIntern(), |
| 23395 | .storage = .{ .elems = elems }, | 23607 | .storage = .{ .elems = elems }, |
| 23396 | } }))); | 23608 | } }))); |
| ... | @@ -23415,12 +23627,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -23415,12 +23627,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23415 | return Air.internedToRef(val.toIntern()); | 23627 | return Air.internedToRef(val.toIntern()); |
| 23416 | } | 23628 | } |
| 23417 | 23629 | ||
| 23418 | const mod = sema.mod; | 23630 | const pt = sema.pt; |
| 23631 | const mod = pt.zcu; | ||
| 23419 | switch (operand_ty.zigTypeTag(mod)) { | 23632 | switch (operand_ty.zigTypeTag(mod)) { |
| 23420 | .Int => { | 23633 | .Int => { |
| 23421 | const runtime_src = if (try sema.resolveValue(operand)) |val| { | 23634 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23422 | if (val.isUndef(mod)) return mod.undefRef(operand_ty); | 23635 | if (val.isUndef(mod)) return pt.undefRef(operand_ty); |
| 23423 | const result_val = try val.bitReverse(operand_ty, mod, sema.arena); | 23636 | const result_val = try val.bitReverse(operand_ty, pt, sema.arena); |
| 23424 | return Air.internedToRef(result_val.toIntern()); | 23637 | return Air.internedToRef(result_val.toIntern()); |
| 23425 | } else operand_src; | 23638 | } else operand_src; |
| 23426 | 23639 | ||
| ... | @@ -23430,15 +23643,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -23430,15 +23643,15 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23430 | .Vector => { | 23643 | .Vector => { |
| 23431 | const runtime_src = if (try sema.resolveValue(operand)) |val| { | 23644 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23432 | if (val.isUndef(mod)) | 23645 | if (val.isUndef(mod)) |
| 23433 | return mod.undefRef(operand_ty); | 23646 | return pt.undefRef(operand_ty); |
| 23434 | 23647 | ||
| 23435 | const vec_len = operand_ty.vectorLen(mod); | 23648 | const vec_len = operand_ty.vectorLen(mod); |
| 23436 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 23649 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23437 | for (elems, 0..) |*elem, i| { | 23650 | for (elems, 0..) |*elem, i| { |
| 23438 | const elem_val = try val.elemValue(mod, i); | 23651 | const elem_val = try val.elemValue(pt, i); |
| 23439 | elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern(); | 23652 | elem.* = (try elem_val.bitReverse(scalar_ty, pt, sema.arena)).toIntern(); |
| 23440 | } | 23653 | } |
| 23441 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23654 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 23442 | .ty = operand_ty.toIntern(), | 23655 | .ty = operand_ty.toIntern(), |
| 23443 | .storage = .{ .elems = elems }, | 23656 | .storage = .{ .elems = elems }, |
| 23444 | } }))); | 23657 | } }))); |
| ... | @@ -23453,13 +23666,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -23453,13 +23666,13 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23453 | 23666 | ||
| 23454 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23667 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23455 | const offset = try sema.bitOffsetOf(block, inst); | 23668 | const offset = try sema.bitOffsetOf(block, inst); |
| 23456 | return sema.mod.intRef(Type.comptime_int, offset); | 23669 | return sema.pt.intRef(Type.comptime_int, offset); |
| 23457 | } | 23670 | } |
| 23458 | 23671 | ||
| 23459 | fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 23672 | fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23460 | const offset = try sema.bitOffsetOf(block, inst); | 23673 | const offset = try sema.bitOffsetOf(block, inst); |
| 23461 | // TODO reminder to make this a compile error for packed structs | 23674 | // TODO reminder to make this a compile error for packed structs |
| 23462 | return sema.mod.intRef(Type.comptime_int, offset / 8); | 23675 | return sema.pt.intRef(Type.comptime_int, offset / 8); |
| 23463 | } | 23676 | } |
| 23464 | 23677 | ||
| 23465 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { | 23678 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { |
| ... | @@ -23474,12 +23687,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -23474,12 +23687,13 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23474 | .needed_comptime_reason = "name of field must be comptime-known", | 23687 | .needed_comptime_reason = "name of field must be comptime-known", |
| 23475 | }); | 23688 | }); |
| 23476 | 23689 | ||
| 23477 | const mod = sema.mod; | 23690 | const pt = sema.pt; |
| 23691 | const mod = pt.zcu; | ||
| 23478 | const ip = &mod.intern_pool; | 23692 | const ip = &mod.intern_pool; |
| 23479 | try ty.resolveLayout(mod); | 23693 | try ty.resolveLayout(pt); |
| 23480 | switch (ty.zigTypeTag(mod)) { | 23694 | switch (ty.zigTypeTag(mod)) { |
| 23481 | .Struct => {}, | 23695 | .Struct => {}, |
| 23482 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}), | 23696 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), |
| 23483 | } | 23697 | } |
| 23484 | 23698 | ||
| 23485 | const field_index = if (ty.isTuple(mod)) blk: { | 23699 | const field_index = if (ty.isTuple(mod)) blk: { |
| ... | @@ -23502,28 +23716,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -23502,28 +23716,30 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23502 | return bit_sum; | 23716 | return bit_sum; |
| 23503 | } | 23717 | } |
| 23504 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 23718 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 23505 | bit_sum += field_ty.bitSize(mod); | 23719 | bit_sum += field_ty.bitSize(pt); |
| 23506 | } else unreachable; | 23720 | } else unreachable; |
| 23507 | }, | 23721 | }, |
| 23508 | else => return ty.structFieldOffset(field_index, mod) * 8, | 23722 | else => return ty.structFieldOffset(field_index, pt) * 8, |
| 23509 | } | 23723 | } |
| 23510 | } | 23724 | } |
| 23511 | 23725 | ||
| 23512 | fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { | 23726 | fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { |
| 23513 | const mod = sema.mod; | 23727 | const pt = sema.pt; |
| 23728 | const mod = pt.zcu; | ||
| 23514 | switch (ty.zigTypeTag(mod)) { | 23729 | switch (ty.zigTypeTag(mod)) { |
| 23515 | .Struct, .Enum, .Union, .Opaque => return, | 23730 | .Struct, .Enum, .Union, .Opaque => return, |
| 23516 | else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(mod)}), | 23731 | else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(pt)}), |
| 23517 | } | 23732 | } |
| 23518 | } | 23733 | } |
| 23519 | 23734 | ||
| 23520 | /// Returns `true` if the type was a comptime_int. | 23735 | /// Returns `true` if the type was a comptime_int. |
| 23521 | fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { | 23736 | fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 23522 | const mod = sema.mod; | 23737 | const pt = sema.pt; |
| 23738 | const mod = pt.zcu; | ||
| 23523 | switch (try ty.zigTypeTagOrPoison(mod)) { | 23739 | switch (try ty.zigTypeTagOrPoison(mod)) { |
| 23524 | .ComptimeInt => return true, | 23740 | .ComptimeInt => return true, |
| 23525 | .Int => return false, | 23741 | .Int => return false, |
| 23526 | else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(mod)}), | 23742 | else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(pt)}), |
| 23527 | } | 23743 | } |
| 23528 | } | 23744 | } |
| 23529 | 23745 | ||
| ... | @@ -23533,7 +23749,8 @@ fn checkInvalidPtrArithmetic( | ... | @@ -23533,7 +23749,8 @@ fn checkInvalidPtrArithmetic( |
| 23533 | src: LazySrcLoc, | 23749 | src: LazySrcLoc, |
| 23534 | ty: Type, | 23750 | ty: Type, |
| 23535 | ) CompileError!void { | 23751 | ) CompileError!void { |
| 23536 | const mod = sema.mod; | 23752 | const pt = sema.pt; |
| 23753 | const mod = pt.zcu; | ||
| 23537 | switch (try ty.zigTypeTagOrPoison(mod)) { | 23754 | switch (try ty.zigTypeTagOrPoison(mod)) { |
| 23538 | .Pointer => switch (ty.ptrSize(mod)) { | 23755 | .Pointer => switch (ty.ptrSize(mod)) { |
| 23539 | .One, .Slice => return, | 23756 | .One, .Slice => return, |
| ... | @@ -23573,7 +23790,8 @@ fn checkPtrOperand( | ... | @@ -23573,7 +23790,8 @@ fn checkPtrOperand( |
| 23573 | ty_src: LazySrcLoc, | 23790 | ty_src: LazySrcLoc, |
| 23574 | ty: Type, | 23791 | ty: Type, |
| 23575 | ) CompileError!void { | 23792 | ) CompileError!void { |
| 23576 | const mod = sema.mod; | 23793 | const pt = sema.pt; |
| 23794 | const mod = pt.zcu; | ||
| 23577 | switch (ty.zigTypeTag(mod)) { | 23795 | switch (ty.zigTypeTag(mod)) { |
| 23578 | .Pointer => return, | 23796 | .Pointer => return, |
| 23579 | .Fn => { | 23797 | .Fn => { |
| ... | @@ -23581,7 +23799,7 @@ fn checkPtrOperand( | ... | @@ -23581,7 +23799,7 @@ fn checkPtrOperand( |
| 23581 | const msg = try sema.errMsg( | 23799 | const msg = try sema.errMsg( |
| 23582 | ty_src, | 23800 | ty_src, |
| 23583 | "expected pointer, found '{}'", | 23801 | "expected pointer, found '{}'", |
| 23584 | .{ty.fmt(mod)}, | 23802 | .{ty.fmt(pt)}, |
| 23585 | ); | 23803 | ); |
| 23586 | errdefer msg.destroy(sema.gpa); | 23804 | errdefer msg.destroy(sema.gpa); |
| 23587 | 23805 | ||
| ... | @@ -23594,7 +23812,7 @@ fn checkPtrOperand( | ... | @@ -23594,7 +23812,7 @@ fn checkPtrOperand( |
| 23594 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, | 23812 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, |
| 23595 | else => {}, | 23813 | else => {}, |
| 23596 | } | 23814 | } |
| 23597 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)}); | 23815 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)}); |
| 23598 | } | 23816 | } |
| 23599 | 23817 | ||
| 23600 | fn checkPtrType( | 23818 | fn checkPtrType( |
| ... | @@ -23604,7 +23822,8 @@ fn checkPtrType( | ... | @@ -23604,7 +23822,8 @@ fn checkPtrType( |
| 23604 | ty: Type, | 23822 | ty: Type, |
| 23605 | allow_slice: bool, | 23823 | allow_slice: bool, |
| 23606 | ) CompileError!void { | 23824 | ) CompileError!void { |
| 23607 | const mod = sema.mod; | 23825 | const pt = sema.pt; |
| 23826 | const mod = pt.zcu; | ||
| 23608 | switch (ty.zigTypeTag(mod)) { | 23827 | switch (ty.zigTypeTag(mod)) { |
| 23609 | .Pointer => if (allow_slice or !ty.isSlice(mod)) return, | 23828 | .Pointer => if (allow_slice or !ty.isSlice(mod)) return, |
| 23610 | .Fn => { | 23829 | .Fn => { |
| ... | @@ -23612,7 +23831,7 @@ fn checkPtrType( | ... | @@ -23612,7 +23831,7 @@ fn checkPtrType( |
| 23612 | const msg = try sema.errMsg( | 23831 | const msg = try sema.errMsg( |
| 23613 | ty_src, | 23832 | ty_src, |
| 23614 | "expected pointer type, found '{}'", | 23833 | "expected pointer type, found '{}'", |
| 23615 | .{ty.fmt(mod)}, | 23834 | .{ty.fmt(pt)}, |
| 23616 | ); | 23835 | ); |
| 23617 | errdefer msg.destroy(sema.gpa); | 23836 | errdefer msg.destroy(sema.gpa); |
| 23618 | 23837 | ||
| ... | @@ -23625,7 +23844,7 @@ fn checkPtrType( | ... | @@ -23625,7 +23844,7 @@ fn checkPtrType( |
| 23625 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, | 23844 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, |
| 23626 | else => {}, | 23845 | else => {}, |
| 23627 | } | 23846 | } |
| 23628 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(mod)}); | 23847 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)}); |
| 23629 | } | 23848 | } |
| 23630 | 23849 | ||
| 23631 | fn checkVectorElemType( | 23850 | fn checkVectorElemType( |
| ... | @@ -23634,13 +23853,14 @@ fn checkVectorElemType( | ... | @@ -23634,13 +23853,14 @@ fn checkVectorElemType( |
| 23634 | ty_src: LazySrcLoc, | 23853 | ty_src: LazySrcLoc, |
| 23635 | ty: Type, | 23854 | ty: Type, |
| 23636 | ) CompileError!void { | 23855 | ) CompileError!void { |
| 23637 | const mod = sema.mod; | 23856 | const pt = sema.pt; |
| 23857 | const mod = pt.zcu; | ||
| 23638 | switch (ty.zigTypeTag(mod)) { | 23858 | switch (ty.zigTypeTag(mod)) { |
| 23639 | .Int, .Float, .Bool => return, | 23859 | .Int, .Float, .Bool => return, |
| 23640 | .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return, | 23860 | .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return, |
| 23641 | else => {}, | 23861 | else => {}, |
| 23642 | } | 23862 | } |
| 23643 | return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(mod)}); | 23863 | return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(pt)}); |
| 23644 | } | 23864 | } |
| 23645 | 23865 | ||
| 23646 | fn checkFloatType( | 23866 | fn checkFloatType( |
| ... | @@ -23649,10 +23869,11 @@ fn checkFloatType( | ... | @@ -23649,10 +23869,11 @@ fn checkFloatType( |
| 23649 | ty_src: LazySrcLoc, | 23869 | ty_src: LazySrcLoc, |
| 23650 | ty: Type, | 23870 | ty: Type, |
| 23651 | ) CompileError!void { | 23871 | ) CompileError!void { |
| 23652 | const mod = sema.mod; | 23872 | const pt = sema.pt; |
| 23873 | const mod = pt.zcu; | ||
| 23653 | switch (ty.zigTypeTag(mod)) { | 23874 | switch (ty.zigTypeTag(mod)) { |
| 23654 | .ComptimeInt, .ComptimeFloat, .Float => {}, | 23875 | .ComptimeInt, .ComptimeFloat, .Float => {}, |
| 23655 | else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(mod)}), | 23876 | else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(pt)}), |
| 23656 | } | 23877 | } |
| 23657 | } | 23878 | } |
| 23658 | 23879 | ||
| ... | @@ -23662,14 +23883,15 @@ fn checkNumericType( | ... | @@ -23662,14 +23883,15 @@ fn checkNumericType( |
| 23662 | ty_src: LazySrcLoc, | 23883 | ty_src: LazySrcLoc, |
| 23663 | ty: Type, | 23884 | ty: Type, |
| 23664 | ) CompileError!void { | 23885 | ) CompileError!void { |
| 23665 | const mod = sema.mod; | 23886 | const pt = sema.pt; |
| 23887 | const mod = pt.zcu; | ||
| 23666 | switch (ty.zigTypeTag(mod)) { | 23888 | switch (ty.zigTypeTag(mod)) { |
| 23667 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, | 23889 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, |
| 23668 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | 23890 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { |
| 23669 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, | 23891 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, |
| 23670 | else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}), | 23892 | else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}), |
| 23671 | }, | 23893 | }, |
| 23672 | else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(mod)}), | 23894 | else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(pt)}), |
| 23673 | } | 23895 | } |
| 23674 | } | 23896 | } |
| 23675 | 23897 | ||
| ... | @@ -23683,7 +23905,8 @@ fn checkAtomicPtrOperand( | ... | @@ -23683,7 +23905,8 @@ fn checkAtomicPtrOperand( |
| 23683 | ptr_src: LazySrcLoc, | 23905 | ptr_src: LazySrcLoc, |
| 23684 | ptr_const: bool, | 23906 | ptr_const: bool, |
| 23685 | ) CompileError!Air.Inst.Ref { | 23907 | ) CompileError!Air.Inst.Ref { |
| 23686 | const mod = sema.mod; | 23908 | const pt = sema.pt; |
| 23909 | const mod = pt.zcu; | ||
| 23687 | var diag: Module.AtomicPtrAlignmentDiagnostics = .{}; | 23910 | var diag: Module.AtomicPtrAlignmentDiagnostics = .{}; |
| 23688 | const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) { | 23911 | const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) { |
| 23689 | error.OutOfMemory => return error.OutOfMemory, | 23912 | error.OutOfMemory => return error.OutOfMemory, |
| ... | @@ -23703,7 +23926,7 @@ fn checkAtomicPtrOperand( | ... | @@ -23703,7 +23926,7 @@ fn checkAtomicPtrOperand( |
| 23703 | block, | 23926 | block, |
| 23704 | elem_ty_src, | 23927 | elem_ty_src, |
| 23705 | "expected bool, integer, float, enum, or pointer type; found '{}'", | 23928 | "expected bool, integer, float, enum, or pointer type; found '{}'", |
| 23706 | .{elem_ty.fmt(mod)}, | 23929 | .{elem_ty.fmt(pt)}, |
| 23707 | ), | 23930 | ), |
| 23708 | }; | 23931 | }; |
| 23709 | 23932 | ||
| ... | @@ -23719,7 +23942,7 @@ fn checkAtomicPtrOperand( | ... | @@ -23719,7 +23942,7 @@ fn checkAtomicPtrOperand( |
| 23719 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) { | 23942 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) { |
| 23720 | .Pointer => ptr_ty.ptrInfo(mod), | 23943 | .Pointer => ptr_ty.ptrInfo(mod), |
| 23721 | else => { | 23944 | else => { |
| 23722 | const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data); | 23945 | const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data); |
| 23723 | _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); | 23946 | _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| 23724 | unreachable; | 23947 | unreachable; |
| 23725 | }, | 23948 | }, |
| ... | @@ -23729,7 +23952,7 @@ fn checkAtomicPtrOperand( | ... | @@ -23729,7 +23952,7 @@ fn checkAtomicPtrOperand( |
| 23729 | wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero; | 23952 | wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero; |
| 23730 | wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile; | 23953 | wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile; |
| 23731 | 23954 | ||
| 23732 | const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data); | 23955 | const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data); |
| 23733 | const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); | 23956 | const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| 23734 | 23957 | ||
| 23735 | return casted_ptr; | 23958 | return casted_ptr; |
| ... | @@ -23754,7 +23977,8 @@ fn checkIntOrVector( | ... | @@ -23754,7 +23977,8 @@ fn checkIntOrVector( |
| 23754 | operand: Air.Inst.Ref, | 23977 | operand: Air.Inst.Ref, |
| 23755 | operand_src: LazySrcLoc, | 23978 | operand_src: LazySrcLoc, |
| 23756 | ) CompileError!Type { | 23979 | ) CompileError!Type { |
| 23757 | const mod = sema.mod; | 23980 | const pt = sema.pt; |
| 23981 | const mod = pt.zcu; | ||
| 23758 | const operand_ty = sema.typeOf(operand); | 23982 | const operand_ty = sema.typeOf(operand); |
| 23759 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { | 23983 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { |
| 23760 | .Int => return operand_ty, | 23984 | .Int => return operand_ty, |
| ... | @@ -23763,12 +23987,12 @@ fn checkIntOrVector( | ... | @@ -23763,12 +23987,12 @@ fn checkIntOrVector( |
| 23763 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { | 23987 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { |
| 23764 | .Int => return elem_ty, | 23988 | .Int => return elem_ty, |
| 23765 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ | 23989 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ |
| 23766 | elem_ty.fmt(mod), | 23990 | elem_ty.fmt(pt), |
| 23767 | }), | 23991 | }), |
| 23768 | } | 23992 | } |
| 23769 | }, | 23993 | }, |
| 23770 | else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{ | 23994 | else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{ |
| 23771 | operand_ty.fmt(mod), | 23995 | operand_ty.fmt(pt), |
| 23772 | }), | 23996 | }), |
| 23773 | } | 23997 | } |
| 23774 | } | 23998 | } |
| ... | @@ -23779,7 +24003,8 @@ fn checkIntOrVectorAllowComptime( | ... | @@ -23779,7 +24003,8 @@ fn checkIntOrVectorAllowComptime( |
| 23779 | operand_ty: Type, | 24003 | operand_ty: Type, |
| 23780 | operand_src: LazySrcLoc, | 24004 | operand_src: LazySrcLoc, |
| 23781 | ) CompileError!Type { | 24005 | ) CompileError!Type { |
| 23782 | const mod = sema.mod; | 24006 | const pt = sema.pt; |
| 24007 | const mod = pt.zcu; | ||
| 23783 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { | 24008 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { |
| 23784 | .Int, .ComptimeInt => return operand_ty, | 24009 | .Int, .ComptimeInt => return operand_ty, |
| 23785 | .Vector => { | 24010 | .Vector => { |
| ... | @@ -23787,12 +24012,12 @@ fn checkIntOrVectorAllowComptime( | ... | @@ -23787,12 +24012,12 @@ fn checkIntOrVectorAllowComptime( |
| 23787 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { | 24012 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { |
| 23788 | .Int, .ComptimeInt => return elem_ty, | 24013 | .Int, .ComptimeInt => return elem_ty, |
| 23789 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ | 24014 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ |
| 23790 | elem_ty.fmt(mod), | 24015 | elem_ty.fmt(pt), |
| 23791 | }), | 24016 | }), |
| 23792 | } | 24017 | } |
| 23793 | }, | 24018 | }, |
| 23794 | else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{ | 24019 | else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{ |
| 23795 | operand_ty.fmt(mod), | 24020 | operand_ty.fmt(pt), |
| 23796 | }), | 24021 | }), |
| 23797 | } | 24022 | } |
| 23798 | } | 24023 | } |
| ... | @@ -23819,7 +24044,8 @@ fn checkSimdBinOp( | ... | @@ -23819,7 +24044,8 @@ fn checkSimdBinOp( |
| 23819 | lhs_src: LazySrcLoc, | 24044 | lhs_src: LazySrcLoc, |
| 23820 | rhs_src: LazySrcLoc, | 24045 | rhs_src: LazySrcLoc, |
| 23821 | ) CompileError!SimdBinOp { | 24046 | ) CompileError!SimdBinOp { |
| 23822 | const mod = sema.mod; | 24047 | const pt = sema.pt; |
| 24048 | const mod = pt.zcu; | ||
| 23823 | const lhs_ty = sema.typeOf(uncasted_lhs); | 24049 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 23824 | const rhs_ty = sema.typeOf(uncasted_rhs); | 24050 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 23825 | 24051 | ||
| ... | @@ -23851,7 +24077,8 @@ fn checkVectorizableBinaryOperands( | ... | @@ -23851,7 +24077,8 @@ fn checkVectorizableBinaryOperands( |
| 23851 | lhs_src: LazySrcLoc, | 24077 | lhs_src: LazySrcLoc, |
| 23852 | rhs_src: LazySrcLoc, | 24078 | rhs_src: LazySrcLoc, |
| 23853 | ) CompileError!void { | 24079 | ) CompileError!void { |
| 23854 | const mod = sema.mod; | 24080 | const pt = sema.pt; |
| 24081 | const mod = pt.zcu; | ||
| 23855 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | 24082 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); |
| 23856 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | 24083 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); |
| 23857 | if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return; | 24084 | if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return; |
| ... | @@ -23881,7 +24108,7 @@ fn checkVectorizableBinaryOperands( | ... | @@ -23881,7 +24108,7 @@ fn checkVectorizableBinaryOperands( |
| 23881 | } else { | 24108 | } else { |
| 23882 | const msg = msg: { | 24109 | const msg = msg: { |
| 23883 | const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{ | 24110 | const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{ |
| 23884 | lhs_ty.fmt(mod), rhs_ty.fmt(mod), | 24111 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 23885 | }); | 24112 | }); |
| 23886 | errdefer msg.destroy(sema.gpa); | 24113 | errdefer msg.destroy(sema.gpa); |
| 23887 | if (lhs_is_vector) { | 24114 | if (lhs_is_vector) { |
| ... | @@ -23903,10 +24130,11 @@ fn resolveExportOptions( | ... | @@ -23903,10 +24130,11 @@ fn resolveExportOptions( |
| 23903 | src: LazySrcLoc, | 24130 | src: LazySrcLoc, |
| 23904 | zir_ref: Zir.Inst.Ref, | 24131 | zir_ref: Zir.Inst.Ref, |
| 23905 | ) CompileError!Module.Export.Options { | 24132 | ) CompileError!Module.Export.Options { |
| 23906 | const mod = sema.mod; | 24133 | const pt = sema.pt; |
| 24134 | const mod = pt.zcu; | ||
| 23907 | const gpa = sema.gpa; | 24135 | const gpa = sema.gpa; |
| 23908 | const ip = &mod.intern_pool; | 24136 | const ip = &mod.intern_pool; |
| 23909 | const export_options_ty = try mod.getBuiltinType("ExportOptions"); | 24137 | const export_options_ty = try pt.getBuiltinType("ExportOptions"); |
| 23910 | const air_ref = try sema.resolveInst(zir_ref); | 24138 | const air_ref = try sema.resolveInst(zir_ref); |
| 23911 | const options = try sema.coerce(block, export_options_ty, air_ref, src); | 24139 | const options = try sema.coerce(block, export_options_ty, air_ref, src); |
| 23912 | 24140 | ||
| ... | @@ -23969,12 +24197,12 @@ fn resolveBuiltinEnum( | ... | @@ -23969,12 +24197,12 @@ fn resolveBuiltinEnum( |
| 23969 | comptime name: []const u8, | 24197 | comptime name: []const u8, |
| 23970 | reason: NeededComptimeReason, | 24198 | reason: NeededComptimeReason, |
| 23971 | ) CompileError!@field(std.builtin, name) { | 24199 | ) CompileError!@field(std.builtin, name) { |
| 23972 | const mod = sema.mod; | 24200 | const pt = sema.pt; |
| 23973 | const ty = try mod.getBuiltinType(name); | 24201 | const ty = try pt.getBuiltinType(name); |
| 23974 | const air_ref = try sema.resolveInst(zir_ref); | 24202 | const air_ref = try sema.resolveInst(zir_ref); |
| 23975 | const coerced = try sema.coerce(block, ty, air_ref, src); | 24203 | const coerced = try sema.coerce(block, ty, air_ref, src); |
| 23976 | const val = try sema.resolveConstDefinedValue(block, src, coerced, reason); | 24204 | const val = try sema.resolveConstDefinedValue(block, src, coerced, reason); |
| 23977 | return mod.toEnum(@field(std.builtin, name), val); | 24205 | return pt.zcu.toEnum(@field(std.builtin, name), val); |
| 23978 | } | 24206 | } |
| 23979 | 24207 | ||
| 23980 | fn resolveAtomicOrder( | 24208 | fn resolveAtomicOrder( |
| ... | @@ -24003,7 +24231,8 @@ fn zirCmpxchg( | ... | @@ -24003,7 +24231,8 @@ fn zirCmpxchg( |
| 24003 | block: *Block, | 24231 | block: *Block, |
| 24004 | extended: Zir.Inst.Extended.InstData, | 24232 | extended: Zir.Inst.Extended.InstData, |
| 24005 | ) CompileError!Air.Inst.Ref { | 24233 | ) CompileError!Air.Inst.Ref { |
| 24006 | const mod = sema.mod; | 24234 | const pt = sema.pt; |
| 24235 | const mod = pt.zcu; | ||
| 24007 | const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data; | 24236 | const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data; |
| 24008 | const air_tag: Air.Inst.Tag = switch (extended.small) { | 24237 | const air_tag: Air.Inst.Tag = switch (extended.small) { |
| 24009 | 0 => .cmpxchg_weak, | 24238 | 0 => .cmpxchg_weak, |
| ... | @@ -24026,7 +24255,7 @@ fn zirCmpxchg( | ... | @@ -24026,7 +24255,7 @@ fn zirCmpxchg( |
| 24026 | block, | 24255 | block, |
| 24027 | elem_ty_src, | 24256 | elem_ty_src, |
| 24028 | "expected bool, integer, enum, or pointer type; found '{}'", | 24257 | "expected bool, integer, enum, or pointer type; found '{}'", |
| 24029 | .{elem_ty.fmt(mod)}, | 24258 | .{elem_ty.fmt(pt)}, |
| 24030 | ); | 24259 | ); |
| 24031 | } | 24260 | } |
| 24032 | const uncasted_ptr = try sema.resolveInst(extra.ptr); | 24261 | const uncasted_ptr = try sema.resolveInst(extra.ptr); |
| ... | @@ -24052,11 +24281,11 @@ fn zirCmpxchg( | ... | @@ -24052,11 +24281,11 @@ fn zirCmpxchg( |
| 24052 | return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{}); | 24281 | return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{}); |
| 24053 | } | 24282 | } |
| 24054 | 24283 | ||
| 24055 | const result_ty = try mod.optionalType(elem_ty.toIntern()); | 24284 | const result_ty = try pt.optionalType(elem_ty.toIntern()); |
| 24056 | 24285 | ||
| 24057 | // special case zero bit types | 24286 | // special case zero bit types |
| 24058 | if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { | 24287 | if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { |
| 24059 | return Air.internedToRef((try mod.intern(.{ .opt = .{ | 24288 | return Air.internedToRef((try pt.intern(.{ .opt = .{ |
| 24060 | .ty = result_ty.toIntern(), | 24289 | .ty = result_ty.toIntern(), |
| 24061 | .val = .none, | 24290 | .val = .none, |
| 24062 | } }))); | 24291 | } }))); |
| ... | @@ -24068,11 +24297,11 @@ fn zirCmpxchg( | ... | @@ -24068,11 +24297,11 @@ fn zirCmpxchg( |
| 24068 | if (expected_val.isUndef(mod) or new_val.isUndef(mod)) { | 24297 | if (expected_val.isUndef(mod) or new_val.isUndef(mod)) { |
| 24069 | // TODO: this should probably cause the memory stored at the pointer | 24298 | // TODO: this should probably cause the memory stored at the pointer |
| 24070 | // to become undef as well | 24299 | // to become undef as well |
| 24071 | return mod.undefRef(result_ty); | 24300 | return pt.undefRef(result_ty); |
| 24072 | } | 24301 | } |
| 24073 | const ptr_ty = sema.typeOf(ptr); | 24302 | const ptr_ty = sema.typeOf(ptr); |
| 24074 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; | 24303 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; |
| 24075 | const result_val = try mod.intern(.{ .opt = .{ | 24304 | const result_val = try pt.intern(.{ .opt = .{ |
| 24076 | .ty = result_ty.toIntern(), | 24305 | .ty = result_ty.toIntern(), |
| 24077 | .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: { | 24306 | .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: { |
| 24078 | try sema.storePtr(block, src, ptr, new_value); | 24307 | try sema.storePtr(block, src, ptr, new_value); |
| ... | @@ -24103,17 +24332,18 @@ fn zirCmpxchg( | ... | @@ -24103,17 +24332,18 @@ fn zirCmpxchg( |
| 24103 | } | 24332 | } |
| 24104 | 24333 | ||
| 24105 | fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 24334 | fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24106 | const mod = sema.mod; | 24335 | const pt = sema.pt; |
| 24336 | const mod = pt.zcu; | ||
| 24107 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24337 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24108 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 24338 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 24109 | const src = block.nodeOffset(inst_data.src_node); | 24339 | const src = block.nodeOffset(inst_data.src_node); |
| 24110 | const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 24340 | const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 24111 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat"); | 24341 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat"); |
| 24112 | 24342 | ||
| 24113 | if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(mod)}); | 24343 | if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(pt)}); |
| 24114 | 24344 | ||
| 24115 | if (!dest_ty.hasRuntimeBits(mod)) { | 24345 | if (!dest_ty.hasRuntimeBits(pt)) { |
| 24116 | const empty_aggregate = try mod.intern(.{ .aggregate = .{ | 24346 | const empty_aggregate = try pt.intern(.{ .aggregate = .{ |
| 24117 | .ty = dest_ty.toIntern(), | 24347 | .ty = dest_ty.toIntern(), |
| 24118 | .storage = .{ .elems = &[_]InternPool.Index{} }, | 24348 | .storage = .{ .elems = &[_]InternPool.Index{} }, |
| 24119 | } }); | 24349 | } }); |
| ... | @@ -24124,7 +24354,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -24124,7 +24354,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 24124 | const scalar_ty = dest_ty.childType(mod); | 24354 | const scalar_ty = dest_ty.childType(mod); |
| 24125 | const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src); | 24355 | const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src); |
| 24126 | if (try sema.resolveValue(scalar)) |scalar_val| { | 24356 | if (try sema.resolveValue(scalar)) |scalar_val| { |
| 24127 | if (scalar_val.isUndef(mod)) return mod.undefRef(dest_ty); | 24357 | if (scalar_val.isUndef(mod)) return pt.undefRef(dest_ty); |
| 24128 | return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern()); | 24358 | return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern()); |
| 24129 | } | 24359 | } |
| 24130 | 24360 | ||
| ... | @@ -24142,10 +24372,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -24142,10 +24372,11 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24142 | }); | 24372 | }); |
| 24143 | const operand = try sema.resolveInst(extra.rhs); | 24373 | const operand = try sema.resolveInst(extra.rhs); |
| 24144 | const operand_ty = sema.typeOf(operand); | 24374 | const operand_ty = sema.typeOf(operand); |
| 24145 | const mod = sema.mod; | 24375 | const pt = sema.pt; |
| 24376 | const mod = pt.zcu; | ||
| 24146 | 24377 | ||
| 24147 | if (operand_ty.zigTypeTag(mod) != .Vector) { | 24378 | if (operand_ty.zigTypeTag(mod) != .Vector) { |
| 24148 | return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)}); | 24379 | return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(pt)}); |
| 24149 | } | 24380 | } |
| 24150 | 24381 | ||
| 24151 | const scalar_ty = operand_ty.childType(mod); | 24382 | const scalar_ty = operand_ty.childType(mod); |
| ... | @@ -24155,13 +24386,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -24155,13 +24386,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24155 | .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) { | 24386 | .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) { |
| 24156 | .Int, .Bool => {}, | 24387 | .Int, .Bool => {}, |
| 24157 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{ | 24388 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{ |
| 24158 | @tagName(operation), operand_ty.fmt(mod), | 24389 | @tagName(operation), operand_ty.fmt(pt), |
| 24159 | }), | 24390 | }), |
| 24160 | }, | 24391 | }, |
| 24161 | .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) { | 24392 | .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) { |
| 24162 | .Int, .Float => {}, | 24393 | .Int, .Float => {}, |
| 24163 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{ | 24394 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{ |
| 24164 | @tagName(operation), operand_ty.fmt(mod), | 24395 | @tagName(operation), operand_ty.fmt(pt), |
| 24165 | }), | 24396 | }), |
| 24166 | }, | 24397 | }, |
| 24167 | } | 24398 | } |
| ... | @@ -24174,20 +24405,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -24174,20 +24405,20 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24174 | } | 24405 | } |
| 24175 | 24406 | ||
| 24176 | if (try sema.resolveValue(operand)) |operand_val| { | 24407 | if (try sema.resolveValue(operand)) |operand_val| { |
| 24177 | if (operand_val.isUndef(mod)) return mod.undefRef(scalar_ty); | 24408 | if (operand_val.isUndef(mod)) return pt.undefRef(scalar_ty); |
| 24178 | 24409 | ||
| 24179 | var accum: Value = try operand_val.elemValue(mod, 0); | 24410 | var accum: Value = try operand_val.elemValue(pt, 0); |
| 24180 | var i: u32 = 1; | 24411 | var i: u32 = 1; |
| 24181 | while (i < vec_len) : (i += 1) { | 24412 | while (i < vec_len) : (i += 1) { |
| 24182 | const elem_val = try operand_val.elemValue(mod, i); | 24413 | const elem_val = try operand_val.elemValue(pt, i); |
| 24183 | switch (operation) { | 24414 | switch (operation) { |
| 24184 | .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod), | 24415 | .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, pt), |
| 24185 | .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod), | 24416 | .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, pt), |
| 24186 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, mod), | 24417 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, pt), |
| 24187 | .Min => accum = accum.numberMin(elem_val, mod), | 24418 | .Min => accum = accum.numberMin(elem_val, pt), |
| 24188 | .Max => accum = accum.numberMax(elem_val, mod), | 24419 | .Max => accum = accum.numberMax(elem_val, pt), |
| 24189 | .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty), | 24420 | .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty), |
| 24190 | .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, mod), | 24421 | .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, pt), |
| 24191 | } | 24422 | } |
| 24192 | } | 24423 | } |
| 24193 | return Air.internedToRef(accum.toIntern()); | 24424 | return Air.internedToRef(accum.toIntern()); |
| ... | @@ -24204,7 +24435,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -24204,7 +24435,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24204 | } | 24435 | } |
| 24205 | 24436 | ||
| 24206 | fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 24437 | fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24207 | const mod = sema.mod; | 24438 | const pt = sema.pt; |
| 24439 | const mod = pt.zcu; | ||
| 24208 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24440 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24209 | const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data; | 24441 | const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data; |
| 24210 | const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 24442 | const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | @@ -24219,9 +24451,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -24219,9 +24451,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 24219 | 24451 | ||
| 24220 | const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) { | 24452 | const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) { |
| 24221 | .Array, .Vector => sema.typeOf(mask).arrayLen(mod), | 24453 | .Array, .Vector => sema.typeOf(mask).arrayLen(mod), |
| 24222 | else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}), | 24454 | else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(pt)}), |
| 24223 | }; | 24455 | }; |
| 24224 | mask_ty = try mod.vectorType(.{ | 24456 | mask_ty = try pt.vectorType(.{ |
| 24225 | .len = @intCast(mask_len), | 24457 | .len = @intCast(mask_len), |
| 24226 | .child = .i32_type, | 24458 | .child = .i32_type, |
| 24227 | }); | 24459 | }); |
| ... | @@ -24242,51 +24474,51 @@ fn analyzeShuffle( | ... | @@ -24242,51 +24474,51 @@ fn analyzeShuffle( |
| 24242 | mask: Value, | 24474 | mask: Value, |
| 24243 | mask_len: u32, | 24475 | mask_len: u32, |
| 24244 | ) CompileError!Air.Inst.Ref { | 24476 | ) CompileError!Air.Inst.Ref { |
| 24245 | const mod = sema.mod; | 24477 | const pt = sema.pt; |
| 24246 | const a_src = block.builtinCallArgSrc(src_node, 1); | 24478 | const a_src = block.builtinCallArgSrc(src_node, 1); |
| 24247 | const b_src = block.builtinCallArgSrc(src_node, 2); | 24479 | const b_src = block.builtinCallArgSrc(src_node, 2); |
| 24248 | const mask_src = block.builtinCallArgSrc(src_node, 3); | 24480 | const mask_src = block.builtinCallArgSrc(src_node, 3); |
| 24249 | var a = a_arg; | 24481 | var a = a_arg; |
| 24250 | var b = b_arg; | 24482 | var b = b_arg; |
| 24251 | 24483 | ||
| 24252 | const res_ty = try mod.vectorType(.{ | 24484 | const res_ty = try pt.vectorType(.{ |
| 24253 | .len = mask_len, | 24485 | .len = mask_len, |
| 24254 | .child = elem_ty.toIntern(), | 24486 | .child = elem_ty.toIntern(), |
| 24255 | }); | 24487 | }); |
| 24256 | 24488 | ||
| 24257 | const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) { | 24489 | const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(pt.zcu)) { |
| 24258 | .Array, .Vector => sema.typeOf(a).arrayLen(mod), | 24490 | .Array, .Vector => sema.typeOf(a).arrayLen(pt.zcu), |
| 24259 | .Undefined => null, | 24491 | .Undefined => null, |
| 24260 | else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{ | 24492 | else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{ |
| 24261 | elem_ty.fmt(sema.mod), | 24493 | elem_ty.fmt(pt), |
| 24262 | sema.typeOf(a).fmt(sema.mod), | 24494 | sema.typeOf(a).fmt(pt), |
| 24263 | }), | 24495 | }), |
| 24264 | }; | 24496 | }; |
| 24265 | const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) { | 24497 | const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(pt.zcu)) { |
| 24266 | .Array, .Vector => sema.typeOf(b).arrayLen(mod), | 24498 | .Array, .Vector => sema.typeOf(b).arrayLen(pt.zcu), |
| 24267 | .Undefined => null, | 24499 | .Undefined => null, |
| 24268 | else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{ | 24500 | else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{ |
| 24269 | elem_ty.fmt(sema.mod), | 24501 | elem_ty.fmt(pt), |
| 24270 | sema.typeOf(b).fmt(sema.mod), | 24502 | sema.typeOf(b).fmt(pt), |
| 24271 | }), | 24503 | }), |
| 24272 | }; | 24504 | }; |
| 24273 | if (maybe_a_len == null and maybe_b_len == null) { | 24505 | if (maybe_a_len == null and maybe_b_len == null) { |
| 24274 | return mod.undefRef(res_ty); | 24506 | return pt.undefRef(res_ty); |
| 24275 | } | 24507 | } |
| 24276 | const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?); | 24508 | const a_len: u32 = @intCast(maybe_a_len orelse maybe_b_len.?); |
| 24277 | const b_len: u32 = @intCast(maybe_b_len orelse a_len); | 24509 | const b_len: u32 = @intCast(maybe_b_len orelse a_len); |
| 24278 | 24510 | ||
| 24279 | const a_ty = try mod.vectorType(.{ | 24511 | const a_ty = try pt.vectorType(.{ |
| 24280 | .len = a_len, | 24512 | .len = a_len, |
| 24281 | .child = elem_ty.toIntern(), | 24513 | .child = elem_ty.toIntern(), |
| 24282 | }); | 24514 | }); |
| 24283 | const b_ty = try mod.vectorType(.{ | 24515 | const b_ty = try pt.vectorType(.{ |
| 24284 | .len = b_len, | 24516 | .len = b_len, |
| 24285 | .child = elem_ty.toIntern(), | 24517 | .child = elem_ty.toIntern(), |
| 24286 | }); | 24518 | }); |
| 24287 | 24519 | ||
| 24288 | if (maybe_a_len == null) a = try mod.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src); | 24520 | if (maybe_a_len == null) a = try pt.undefRef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src); |
| 24289 | if (maybe_b_len == null) b = try mod.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src); | 24521 | if (maybe_b_len == null) b = try pt.undefRef(b_ty) else b = try sema.coerce(block, b_ty, b, b_src); |
| 24290 | 24522 | ||
| 24291 | const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){ | 24523 | const operand_info = [2]std.meta.Tuple(&.{ u64, LazySrcLoc, Type }){ |
| 24292 | .{ a_len, a_src, a_ty }, | 24524 | .{ a_len, a_src, a_ty }, |
| ... | @@ -24294,10 +24526,10 @@ fn analyzeShuffle( | ... | @@ -24294,10 +24526,10 @@ fn analyzeShuffle( |
| 24294 | }; | 24526 | }; |
| 24295 | 24527 | ||
| 24296 | for (0..@intCast(mask_len)) |i| { | 24528 | for (0..@intCast(mask_len)) |i| { |
| 24297 | const elem = try mask.elemValue(sema.mod, i); | 24529 | const elem = try mask.elemValue(pt, i); |
| 24298 | if (elem.isUndef(mod)) continue; | 24530 | if (elem.isUndef(pt.zcu)) continue; |
| 24299 | const elem_resolved = try sema.resolveLazyValue(elem); | 24531 | const elem_resolved = try sema.resolveLazyValue(elem); |
| 24300 | const int = elem_resolved.toSignedInt(mod); | 24532 | const int = elem_resolved.toSignedInt(pt); |
| 24301 | var unsigned: u32 = undefined; | 24533 | var unsigned: u32 = undefined; |
| 24302 | var chosen: u32 = undefined; | 24534 | var chosen: u32 = undefined; |
| 24303 | if (int >= 0) { | 24535 | if (int >= 0) { |
| ... | @@ -24314,7 +24546,7 @@ fn analyzeShuffle( | ... | @@ -24314,7 +24546,7 @@ fn analyzeShuffle( |
| 24314 | 24546 | ||
| 24315 | try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{ | 24547 | try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{ |
| 24316 | unsigned, | 24548 | unsigned, |
| 24317 | operand_info[chosen][2].fmt(sema.mod), | 24549 | operand_info[chosen][2].fmt(pt), |
| 24318 | }); | 24550 | }); |
| 24319 | 24551 | ||
| 24320 | if (chosen == 0) { | 24552 | if (chosen == 0) { |
| ... | @@ -24331,16 +24563,16 @@ fn analyzeShuffle( | ... | @@ -24331,16 +24563,16 @@ fn analyzeShuffle( |
| 24331 | if (try sema.resolveValue(b)) |b_val| { | 24563 | if (try sema.resolveValue(b)) |b_val| { |
| 24332 | const values = try sema.arena.alloc(InternPool.Index, mask_len); | 24564 | const values = try sema.arena.alloc(InternPool.Index, mask_len); |
| 24333 | for (values, 0..) |*value, i| { | 24565 | for (values, 0..) |*value, i| { |
| 24334 | const mask_elem_val = try mask.elemValue(sema.mod, i); | 24566 | const mask_elem_val = try mask.elemValue(pt, i); |
| 24335 | if (mask_elem_val.isUndef(mod)) { | 24567 | if (mask_elem_val.isUndef(pt.zcu)) { |
| 24336 | value.* = try mod.intern(.{ .undef = elem_ty.toIntern() }); | 24568 | value.* = try pt.intern(.{ .undef = elem_ty.toIntern() }); |
| 24337 | continue; | 24569 | continue; |
| 24338 | } | 24570 | } |
| 24339 | const int = mask_elem_val.toSignedInt(mod); | 24571 | const int = mask_elem_val.toSignedInt(pt); |
| 24340 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); | 24572 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); |
| 24341 | values[i] = (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).toIntern(); | 24573 | values[i] = (try (if (int >= 0) a_val else b_val).elemValue(pt, unsigned)).toIntern(); |
| 24342 | } | 24574 | } |
| 24343 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 24575 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 24344 | .ty = res_ty.toIntern(), | 24576 | .ty = res_ty.toIntern(), |
| 24345 | .storage = .{ .elems = values }, | 24577 | .storage = .{ .elems = values }, |
| 24346 | } }))); | 24578 | } }))); |
| ... | @@ -24359,21 +24591,21 @@ fn analyzeShuffle( | ... | @@ -24359,21 +24591,21 @@ fn analyzeShuffle( |
| 24359 | 24591 | ||
| 24360 | const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len); | 24592 | const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len); |
| 24361 | for (@intCast(0)..@intCast(min_len)) |i| { | 24593 | for (@intCast(0)..@intCast(min_len)) |i| { |
| 24362 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, i)).toIntern(); | 24594 | expand_mask_values[i] = (try pt.intValue(Type.comptime_int, i)).toIntern(); |
| 24363 | } | 24595 | } |
| 24364 | for (@intCast(min_len)..@intCast(max_len)) |i| { | 24596 | for (@intCast(min_len)..@intCast(max_len)) |i| { |
| 24365 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, -1)).toIntern(); | 24597 | expand_mask_values[i] = (try pt.intValue(Type.comptime_int, -1)).toIntern(); |
| 24366 | } | 24598 | } |
| 24367 | const expand_mask = try mod.intern(.{ .aggregate = .{ | 24599 | const expand_mask = try pt.intern(.{ .aggregate = .{ |
| 24368 | .ty = (try mod.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(), | 24600 | .ty = (try pt.vectorType(.{ .len = @intCast(max_len), .child = .comptime_int_type })).toIntern(), |
| 24369 | .storage = .{ .elems = expand_mask_values }, | 24601 | .storage = .{ .elems = expand_mask_values }, |
| 24370 | } }); | 24602 | } }); |
| 24371 | 24603 | ||
| 24372 | if (a_len < b_len) { | 24604 | if (a_len < b_len) { |
| 24373 | const undef = try mod.undefRef(a_ty); | 24605 | const undef = try pt.undefRef(a_ty); |
| 24374 | a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len)); | 24606 | a = try sema.analyzeShuffle(block, src_node, elem_ty, a, undef, Value.fromInterned(expand_mask), @intCast(max_len)); |
| 24375 | } else { | 24607 | } else { |
| 24376 | const undef = try mod.undefRef(b_ty); | 24608 | const undef = try pt.undefRef(b_ty); |
| 24377 | b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len)); | 24609 | b = try sema.analyzeShuffle(block, src_node, elem_ty, b, undef, Value.fromInterned(expand_mask), @intCast(max_len)); |
| 24378 | } | 24610 | } |
| 24379 | } | 24611 | } |
| ... | @@ -24393,7 +24625,8 @@ fn analyzeShuffle( | ... | @@ -24393,7 +24625,8 @@ fn analyzeShuffle( |
| 24393 | } | 24625 | } |
| 24394 | 24626 | ||
| 24395 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 24627 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 24396 | const mod = sema.mod; | 24628 | const pt = sema.pt; |
| 24629 | const mod = pt.zcu; | ||
| 24397 | const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data; | 24630 | const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data; |
| 24398 | 24631 | ||
| 24399 | const src = block.nodeOffset(extra.node); | 24632 | const src = block.nodeOffset(extra.node); |
| ... | @@ -24409,17 +24642,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -24409,17 +24642,17 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24409 | 24642 | ||
| 24410 | const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) { | 24643 | const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) { |
| 24411 | .Vector, .Array => pred_ty.arrayLen(mod), | 24644 | .Vector, .Array => pred_ty.arrayLen(mod), |
| 24412 | else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(mod)}), | 24645 | else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(pt)}), |
| 24413 | }; | 24646 | }; |
| 24414 | const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64)); | 24647 | const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64)); |
| 24415 | 24648 | ||
| 24416 | const bool_vec_ty = try mod.vectorType(.{ | 24649 | const bool_vec_ty = try pt.vectorType(.{ |
| 24417 | .len = vec_len, | 24650 | .len = vec_len, |
| 24418 | .child = .bool_type, | 24651 | .child = .bool_type, |
| 24419 | }); | 24652 | }); |
| 24420 | const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src); | 24653 | const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src); |
| 24421 | 24654 | ||
| 24422 | const vec_ty = try mod.vectorType(.{ | 24655 | const vec_ty = try pt.vectorType(.{ |
| 24423 | .len = vec_len, | 24656 | .len = vec_len, |
| 24424 | .child = elem_ty.toIntern(), | 24657 | .child = elem_ty.toIntern(), |
| 24425 | }); | 24658 | }); |
| ... | @@ -24431,23 +24664,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -24431,23 +24664,23 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24431 | const maybe_b = try sema.resolveValue(b); | 24664 | const maybe_b = try sema.resolveValue(b); |
| 24432 | 24665 | ||
| 24433 | const runtime_src = if (maybe_pred) |pred_val| rs: { | 24666 | const runtime_src = if (maybe_pred) |pred_val| rs: { |
| 24434 | if (pred_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24667 | if (pred_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24435 | 24668 | ||
| 24436 | if (maybe_a) |a_val| { | 24669 | if (maybe_a) |a_val| { |
| 24437 | if (a_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24670 | if (a_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24438 | 24671 | ||
| 24439 | if (maybe_b) |b_val| { | 24672 | if (maybe_b) |b_val| { |
| 24440 | if (b_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24673 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24441 | 24674 | ||
| 24442 | const elems = try sema.gpa.alloc(InternPool.Index, vec_len); | 24675 | const elems = try sema.gpa.alloc(InternPool.Index, vec_len); |
| 24443 | defer sema.gpa.free(elems); | 24676 | defer sema.gpa.free(elems); |
| 24444 | for (elems, 0..) |*elem, i| { | 24677 | for (elems, 0..) |*elem, i| { |
| 24445 | const pred_elem_val = try pred_val.elemValue(mod, i); | 24678 | const pred_elem_val = try pred_val.elemValue(pt, i); |
| 24446 | const should_choose_a = pred_elem_val.toBool(); | 24679 | const should_choose_a = pred_elem_val.toBool(); |
| 24447 | elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern(); | 24680 | elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(pt, i)).toIntern(); |
| 24448 | } | 24681 | } |
| 24449 | 24682 | ||
| 24450 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 24683 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 24451 | .ty = vec_ty.toIntern(), | 24684 | .ty = vec_ty.toIntern(), |
| 24452 | .storage = .{ .elems = elems }, | 24685 | .storage = .{ .elems = elems }, |
| 24453 | } }))); | 24686 | } }))); |
| ... | @@ -24456,16 +24689,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -24456,16 +24689,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24456 | } | 24689 | } |
| 24457 | } else { | 24690 | } else { |
| 24458 | if (maybe_b) |b_val| { | 24691 | if (maybe_b) |b_val| { |
| 24459 | if (b_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24692 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24460 | } | 24693 | } |
| 24461 | break :rs a_src; | 24694 | break :rs a_src; |
| 24462 | } | 24695 | } |
| 24463 | } else rs: { | 24696 | } else rs: { |
| 24464 | if (maybe_a) |a_val| { | 24697 | if (maybe_a) |a_val| { |
| 24465 | if (a_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24698 | if (a_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24466 | } | 24699 | } |
| 24467 | if (maybe_b) |b_val| { | 24700 | if (maybe_b) |b_val| { |
| 24468 | if (b_val.isUndef(mod)) return mod.undefRef(vec_ty); | 24701 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); |
| 24469 | } | 24702 | } |
| 24470 | break :rs pred_src; | 24703 | break :rs pred_src; |
| 24471 | }; | 24704 | }; |
| ... | @@ -24531,7 +24764,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -24531,7 +24764,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 24531 | } | 24764 | } |
| 24532 | 24765 | ||
| 24533 | fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 24766 | fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24534 | const mod = sema.mod; | 24767 | const pt = sema.pt; |
| 24768 | const mod = pt.zcu; | ||
| 24535 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24769 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24536 | const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; | 24770 | const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; |
| 24537 | const src = block.nodeOffset(inst_data.src_node); | 24771 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -24588,12 +24822,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -24588,12 +24822,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 24588 | .Xchg => operand_val, | 24822 | .Xchg => operand_val, |
| 24589 | .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty), | 24823 | .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty), |
| 24590 | .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty), | 24824 | .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty), |
| 24591 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, mod), | 24825 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, pt), |
| 24592 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, mod), | 24826 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, pt), |
| 24593 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, mod), | 24827 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, pt), |
| 24594 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, mod), | 24828 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, pt), |
| 24595 | .Max => stored_val.numberMax (operand_val, mod), | 24829 | .Max => stored_val.numberMax (operand_val, pt), |
| 24596 | .Min => stored_val.numberMin (operand_val, mod), | 24830 | .Min => stored_val.numberMin (operand_val, pt), |
| 24597 | // zig fmt: on | 24831 | // zig fmt: on |
| 24598 | }; | 24832 | }; |
| 24599 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); | 24833 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); |
| ... | @@ -24669,36 +24903,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -24669,36 +24903,37 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24669 | const maybe_mulend1 = try sema.resolveValue(mulend1); | 24903 | const maybe_mulend1 = try sema.resolveValue(mulend1); |
| 24670 | const maybe_mulend2 = try sema.resolveValue(mulend2); | 24904 | const maybe_mulend2 = try sema.resolveValue(mulend2); |
| 24671 | const maybe_addend = try sema.resolveValue(addend); | 24905 | const maybe_addend = try sema.resolveValue(addend); |
| 24672 | const mod = sema.mod; | 24906 | const pt = sema.pt; |
| 24907 | const mod = pt.zcu; | ||
| 24673 | 24908 | ||
| 24674 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | 24909 | switch (ty.scalarType(mod).zigTypeTag(mod)) { |
| 24675 | .ComptimeFloat, .Float => {}, | 24910 | .ComptimeFloat, .Float => {}, |
| 24676 | else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}), | 24911 | else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(pt)}), |
| 24677 | } | 24912 | } |
| 24678 | 24913 | ||
| 24679 | const runtime_src = if (maybe_mulend1) |mulend1_val| rs: { | 24914 | const runtime_src = if (maybe_mulend1) |mulend1_val| rs: { |
| 24680 | if (maybe_mulend2) |mulend2_val| { | 24915 | if (maybe_mulend2) |mulend2_val| { |
| 24681 | if (mulend2_val.isUndef(mod)) return mod.undefRef(ty); | 24916 | if (mulend2_val.isUndef(mod)) return pt.undefRef(ty); |
| 24682 | 24917 | ||
| 24683 | if (maybe_addend) |addend_val| { | 24918 | if (maybe_addend) |addend_val| { |
| 24684 | if (addend_val.isUndef(mod)) return mod.undefRef(ty); | 24919 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); |
| 24685 | const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, sema.mod); | 24920 | const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, pt); |
| 24686 | return Air.internedToRef(result_val.toIntern()); | 24921 | return Air.internedToRef(result_val.toIntern()); |
| 24687 | } else { | 24922 | } else { |
| 24688 | break :rs addend_src; | 24923 | break :rs addend_src; |
| 24689 | } | 24924 | } |
| 24690 | } else { | 24925 | } else { |
| 24691 | if (maybe_addend) |addend_val| { | 24926 | if (maybe_addend) |addend_val| { |
| 24692 | if (addend_val.isUndef(mod)) return mod.undefRef(ty); | 24927 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); |
| 24693 | } | 24928 | } |
| 24694 | break :rs mulend2_src; | 24929 | break :rs mulend2_src; |
| 24695 | } | 24930 | } |
| 24696 | } else rs: { | 24931 | } else rs: { |
| 24697 | if (maybe_mulend2) |mulend2_val| { | 24932 | if (maybe_mulend2) |mulend2_val| { |
| 24698 | if (mulend2_val.isUndef(mod)) return mod.undefRef(ty); | 24933 | if (mulend2_val.isUndef(mod)) return pt.undefRef(ty); |
| 24699 | } | 24934 | } |
| 24700 | if (maybe_addend) |addend_val| { | 24935 | if (maybe_addend) |addend_val| { |
| 24701 | if (addend_val.isUndef(mod)) return mod.undefRef(ty); | 24936 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); |
| 24702 | } | 24937 | } |
| 24703 | break :rs mulend1_src; | 24938 | break :rs mulend1_src; |
| 24704 | }; | 24939 | }; |
| ... | @@ -24720,7 +24955,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -24720,7 +24955,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 24720 | const tracy = trace(@src()); | 24955 | const tracy = trace(@src()); |
| 24721 | defer tracy.end(); | 24956 | defer tracy.end(); |
| 24722 | 24957 | ||
| 24723 | const mod = sema.mod; | 24958 | const pt = sema.pt; |
| 24959 | const mod = pt.zcu; | ||
| 24724 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24960 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24725 | const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 24961 | const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 24726 | const func_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 24962 | const func_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| ... | @@ -24730,7 +24966,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -24730,7 +24966,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 24730 | const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data; | 24966 | const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data; |
| 24731 | const func = try sema.resolveInst(extra.callee); | 24967 | const func = try sema.resolveInst(extra.callee); |
| 24732 | 24968 | ||
| 24733 | const modifier_ty = try mod.getBuiltinType("CallModifier"); | 24969 | const modifier_ty = try pt.getBuiltinType("CallModifier"); |
| 24734 | const air_ref = try sema.resolveInst(extra.modifier); | 24970 | const air_ref = try sema.resolveInst(extra.modifier); |
| 24735 | const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src); | 24971 | const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src); |
| 24736 | const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ | 24972 | const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ |
| ... | @@ -24783,7 +25019,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -24783,7 +25019,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 24783 | 25019 | ||
| 24784 | const args_ty = sema.typeOf(args); | 25020 | const args_ty = sema.typeOf(args); |
| 24785 | if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) { | 25021 | if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) { |
| 24786 | return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(sema.mod)}); | 25022 | return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)}); |
| 24787 | } | 25023 | } |
| 24788 | 25024 | ||
| 24789 | const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod)); | 25025 | const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod)); |
| ... | @@ -24812,7 +25048,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -24812,7 +25048,8 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 24812 | } | 25048 | } |
| 24813 | 25049 | ||
| 24814 | fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 25050 | fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 24815 | const zcu = sema.mod; | 25051 | const pt = sema.pt; |
| 25052 | const zcu = pt.zcu; | ||
| 24816 | const ip = &zcu.intern_pool; | 25053 | const ip = &zcu.intern_pool; |
| 24817 | 25054 | ||
| 24818 | const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data; | 25055 | const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data; |
| ... | @@ -24827,14 +25064,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24827,14 +25064,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24827 | try sema.checkPtrType(block, inst_src, parent_ptr_ty, true); | 25064 | try sema.checkPtrType(block, inst_src, parent_ptr_ty, true); |
| 24828 | const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); | 25065 | const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); |
| 24829 | if (parent_ptr_info.flags.size != .One) { | 25066 | if (parent_ptr_info.flags.size != .One) { |
| 24830 | return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(zcu)}); | 25067 | return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)}); |
| 24831 | } | 25068 | } |
| 24832 | const parent_ty = Type.fromInterned(parent_ptr_info.child); | 25069 | const parent_ty = Type.fromInterned(parent_ptr_info.child); |
| 24833 | switch (parent_ty.zigTypeTag(zcu)) { | 25070 | switch (parent_ty.zigTypeTag(zcu)) { |
| 24834 | .Struct, .Union => {}, | 25071 | .Struct, .Union => {}, |
| 24835 | else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}), | 25072 | else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}), |
| 24836 | } | 25073 | } |
| 24837 | try parent_ty.resolveLayout(zcu); | 25074 | try parent_ty.resolveLayout(pt); |
| 24838 | 25075 | ||
| 24839 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ | 25076 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ |
| 24840 | .needed_comptime_reason = "field name must be comptime-known", | 25077 | .needed_comptime_reason = "field name must be comptime-known", |
| ... | @@ -24865,7 +25102,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24865,7 +25102,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24865 | var actual_parent_ptr_info: InternPool.Key.PtrType = .{ | 25102 | var actual_parent_ptr_info: InternPool.Key.PtrType = .{ |
| 24866 | .child = parent_ty.toIntern(), | 25103 | .child = parent_ty.toIntern(), |
| 24867 | .flags = .{ | 25104 | .flags = .{ |
| 24868 | .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema), | 25105 | .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema), |
| 24869 | .is_const = field_ptr_info.flags.is_const, | 25106 | .is_const = field_ptr_info.flags.is_const, |
| 24870 | .is_volatile = field_ptr_info.flags.is_volatile, | 25107 | .is_volatile = field_ptr_info.flags.is_volatile, |
| 24871 | .is_allowzero = field_ptr_info.flags.is_allowzero, | 25108 | .is_allowzero = field_ptr_info.flags.is_allowzero, |
| ... | @@ -24877,7 +25114,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24877,7 +25114,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24877 | var actual_field_ptr_info: InternPool.Key.PtrType = .{ | 25114 | var actual_field_ptr_info: InternPool.Key.PtrType = .{ |
| 24878 | .child = field_ty.toIntern(), | 25115 | .child = field_ty.toIntern(), |
| 24879 | .flags = .{ | 25116 | .flags = .{ |
| 24880 | .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, .sema), | 25117 | .alignment = try field_ptr_ty.ptrAlignmentAdvanced(pt, .sema), |
| 24881 | .is_const = field_ptr_info.flags.is_const, | 25118 | .is_const = field_ptr_info.flags.is_const, |
| 24882 | .is_volatile = field_ptr_info.flags.is_volatile, | 25119 | .is_volatile = field_ptr_info.flags.is_volatile, |
| 24883 | .is_allowzero = field_ptr_info.flags.is_allowzero, | 25120 | .is_allowzero = field_ptr_info.flags.is_allowzero, |
| ... | @@ -24888,13 +25125,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24888,13 +25125,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24888 | switch (parent_ty.containerLayout(zcu)) { | 25125 | switch (parent_ty.containerLayout(zcu)) { |
| 24889 | .auto => { | 25126 | .auto => { |
| 24890 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict( | 25127 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict( |
| 24891 | if (zcu.typeToStruct(parent_ty)) |struct_obj| try zcu.structFieldAlignmentAdvanced( | 25128 | if (zcu.typeToStruct(parent_ty)) |struct_obj| try pt.structFieldAlignmentAdvanced( |
| 24892 | struct_obj.fieldAlign(ip, field_index), | 25129 | struct_obj.fieldAlign(ip, field_index), |
| 24893 | field_ty, | 25130 | field_ty, |
| 24894 | struct_obj.layout, | 25131 | struct_obj.layout, |
| 24895 | .sema, | 25132 | .sema, |
| 24896 | ) else if (zcu.typeToUnion(parent_ty)) |union_obj| | 25133 | ) else if (zcu.typeToUnion(parent_ty)) |union_obj| |
| 24897 | try zcu.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema) | 25134 | try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema) |
| 24898 | else | 25135 | else |
| 24899 | actual_field_ptr_info.flags.alignment, | 25136 | actual_field_ptr_info.flags.alignment, |
| 24900 | ); | 25137 | ); |
| ... | @@ -24903,7 +25140,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24903,7 +25140,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24903 | actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 }; | 25140 | actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 }; |
| 24904 | }, | 25141 | }, |
| 24905 | .@"extern" => { | 25142 | .@"extern" => { |
| 24906 | const field_offset = parent_ty.structFieldOffset(field_index, zcu); | 25143 | const field_offset = parent_ty.structFieldOffset(field_index, pt); |
| 24907 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0) | 25144 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0) |
| 24908 | Alignment.fromLog2Units(@ctz(field_offset)) | 25145 | Alignment.fromLog2Units(@ctz(field_offset)) |
| 24909 | else | 25146 | else |
| ... | @@ -24914,7 +25151,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24914,7 +25151,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24914 | }, | 25151 | }, |
| 24915 | .@"packed" => { | 25152 | .@"packed" => { |
| 24916 | const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) + | 25153 | const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) + |
| 24917 | (if (zcu.typeToStruct(parent_ty)) |struct_obj| zcu.structPackedFieldBitOffset(struct_obj, field_index) else 0) - | 25154 | (if (zcu.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, field_index) else 0) - |
| 24918 | actual_field_ptr_info.packed_offset.bit_offset), 8) catch | 25155 | actual_field_ptr_info.packed_offset.bit_offset), 8) catch |
| 24919 | return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{}); | 25156 | return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{}); |
| 24920 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0) | 25157 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0) |
| ... | @@ -24924,16 +25161,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24924,16 +25161,16 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24924 | }, | 25161 | }, |
| 24925 | } | 25162 | } |
| 24926 | 25163 | ||
| 24927 | const actual_field_ptr_ty = try zcu.ptrTypeSema(actual_field_ptr_info); | 25164 | const actual_field_ptr_ty = try pt.ptrTypeSema(actual_field_ptr_info); |
| 24928 | const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src); | 25165 | const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src); |
| 24929 | const actual_parent_ptr_ty = try zcu.ptrTypeSema(actual_parent_ptr_info); | 25166 | const actual_parent_ptr_ty = try pt.ptrTypeSema(actual_parent_ptr_info); |
| 24930 | 25167 | ||
| 24931 | const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: { | 25168 | const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: { |
| 24932 | switch (parent_ty.zigTypeTag(zcu)) { | 25169 | switch (parent_ty.zigTypeTag(zcu)) { |
| 24933 | .Struct => switch (parent_ty.containerLayout(zcu)) { | 25170 | .Struct => switch (parent_ty.containerLayout(zcu)) { |
| 24934 | .auto => {}, | 25171 | .auto => {}, |
| 24935 | .@"extern" => { | 25172 | .@"extern" => { |
| 24936 | const byte_offset = parent_ty.structFieldOffset(field_index, zcu); | 25173 | const byte_offset = parent_ty.structFieldOffset(field_index, pt); |
| 24937 | const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty); | 25174 | const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty); |
| 24938 | break :result Air.internedToRef(parent_ptr_val.toIntern()); | 25175 | break :result Air.internedToRef(parent_ptr_val.toIntern()); |
| 24939 | }, | 25176 | }, |
| ... | @@ -24941,7 +25178,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24941,7 +25178,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24941 | // Logic lifted from type computation above - I'm just assuming it's correct. | 25178 | // Logic lifted from type computation above - I'm just assuming it's correct. |
| 24942 | // `catch unreachable` since error case handled above. | 25179 | // `catch unreachable` since error case handled above. |
| 24943 | const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) + | 25180 | const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) + |
| 24944 | zcu.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) - | 25181 | pt.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) - |
| 24945 | actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable; | 25182 | actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable; |
| 24946 | const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty); | 25183 | const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty); |
| 24947 | break :result Air.internedToRef(parent_ptr_val.toIntern()); | 25184 | break :result Air.internedToRef(parent_ptr_val.toIntern()); |
| ... | @@ -24951,7 +25188,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24951,7 +25188,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24951 | .auto => {}, | 25188 | .auto => {}, |
| 24952 | .@"extern", .@"packed" => { | 25189 | .@"extern", .@"packed" => { |
| 24953 | // For an extern or packed union, just coerce the pointer. | 25190 | // For an extern or packed union, just coerce the pointer. |
| 24954 | const parent_ptr_val = try zcu.getCoerced(field_ptr_val, actual_parent_ptr_ty); | 25191 | const parent_ptr_val = try pt.getCoerced(field_ptr_val, actual_parent_ptr_ty); |
| 24955 | break :result Air.internedToRef(parent_ptr_val.toIntern()); | 25192 | break :result Air.internedToRef(parent_ptr_val.toIntern()); |
| 24956 | }, | 25193 | }, |
| 24957 | }, | 25194 | }, |
| ... | @@ -24980,7 +25217,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -24980,7 +25217,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 24980 | 25217 | ||
| 24981 | if (field.index != field_index) { | 25218 | if (field.index != field_index) { |
| 24982 | return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{ | 25219 | return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{ |
| 24983 | field_name.fmt(ip), field_index, field.index, parent_ty.fmt(zcu), | 25220 | field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt), |
| 24984 | }); | 25221 | }); |
| 24985 | } | 25222 | } |
| 24986 | break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src); | 25223 | break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src); |
| ... | @@ -25001,8 +25238,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins | ... | @@ -25001,8 +25238,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25001 | } | 25238 | } |
| 25002 | 25239 | ||
| 25003 | fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value { | 25240 | fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value { |
| 25004 | const zcu = sema.mod; | 25241 | const pt = sema.pt; |
| 25005 | if (byte_subtract == 0) return zcu.getCoerced(ptr_val, new_ty); | 25242 | const zcu = pt.zcu; |
| 25243 | if (byte_subtract == 0) return pt.getCoerced(ptr_val, new_ty); | ||
| 25006 | var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) { | 25244 | var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) { |
| 25007 | .undef => return sema.failWithUseOfUndef(block, src), | 25245 | .undef => return sema.failWithUseOfUndef(block, src), |
| 25008 | .ptr => |ptr| ptr, | 25246 | .ptr => |ptr| ptr, |
| ... | @@ -25018,7 +25256,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte | ... | @@ -25018,7 +25256,7 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte |
| 25018 | } | 25256 | } |
| 25019 | ptr.byte_offset -= byte_subtract; | 25257 | ptr.byte_offset -= byte_subtract; |
| 25020 | ptr.ty = new_ty.toIntern(); | 25258 | ptr.ty = new_ty.toIntern(); |
| 25021 | return Value.fromInterned(try zcu.intern(.{ .ptr = ptr })); | 25259 | return Value.fromInterned(try pt.intern(.{ .ptr = ptr })); |
| 25022 | } | 25260 | } |
| 25023 | 25261 | ||
| 25024 | fn zirMinMax( | 25262 | fn zirMinMax( |
| ... | @@ -25072,7 +25310,8 @@ fn analyzeMinMax( | ... | @@ -25072,7 +25310,8 @@ fn analyzeMinMax( |
| 25072 | ) CompileError!Air.Inst.Ref { | 25310 | ) CompileError!Air.Inst.Ref { |
| 25073 | assert(operands.len == operand_srcs.len); | 25311 | assert(operands.len == operand_srcs.len); |
| 25074 | assert(operands.len > 0); | 25312 | assert(operands.len > 0); |
| 25075 | const mod = sema.mod; | 25313 | const pt = sema.pt; |
| 25314 | const mod = pt.zcu; | ||
| 25076 | 25315 | ||
| 25077 | if (operands.len == 1) return operands[0]; | 25316 | if (operands.len == 1) return operands[0]; |
| 25078 | 25317 | ||
| ... | @@ -25115,15 +25354,15 @@ fn analyzeMinMax( | ... | @@ -25115,15 +25354,15 @@ fn analyzeMinMax( |
| 25115 | break :refine_bounds; | 25354 | break :refine_bounds; |
| 25116 | } | 25355 | } |
| 25117 | const scalar_bounds: ?[2]Value = bounds: { | 25356 | const scalar_bounds: ?[2]Value = bounds: { |
| 25118 | if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(mod); | 25357 | if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(pt); |
| 25119 | var cur_bounds: [2]Value = try Value.intValueBounds(try uncoerced_val.elemValue(mod, 0), mod) orelse break :bounds null; | 25358 | var cur_bounds: [2]Value = try Value.intValueBounds(try uncoerced_val.elemValue(pt, 0), pt) orelse break :bounds null; |
| 25120 | const len = try sema.usizeCast(block, src, ty.vectorLen(mod)); | 25359 | const len = try sema.usizeCast(block, src, ty.vectorLen(mod)); |
| 25121 | for (1..len) |i| { | 25360 | for (1..len) |i| { |
| 25122 | const elem = try uncoerced_val.elemValue(mod, i); | 25361 | const elem = try uncoerced_val.elemValue(pt, i); |
| 25123 | const elem_bounds = try elem.intValueBounds(mod) orelse break :bounds null; | 25362 | const elem_bounds = try elem.intValueBounds(pt) orelse break :bounds null; |
| 25124 | cur_bounds = .{ | 25363 | cur_bounds = .{ |
| 25125 | Value.numberMin(elem_bounds[0], cur_bounds[0], mod), | 25364 | Value.numberMin(elem_bounds[0], cur_bounds[0], pt), |
| 25126 | Value.numberMax(elem_bounds[1], cur_bounds[1], mod), | 25365 | Value.numberMax(elem_bounds[1], cur_bounds[1], pt), |
| 25127 | }; | 25366 | }; |
| 25128 | } | 25367 | } |
| 25129 | break :bounds cur_bounds; | 25368 | break :bounds cur_bounds; |
| ... | @@ -25134,8 +25373,8 @@ fn analyzeMinMax( | ... | @@ -25134,8 +25373,8 @@ fn analyzeMinMax( |
| 25134 | cur_max_scalar = bounds[1]; | 25373 | cur_max_scalar = bounds[1]; |
| 25135 | bounds_status = .defined; | 25374 | bounds_status = .defined; |
| 25136 | } else { | 25375 | } else { |
| 25137 | cur_min_scalar = opFunc(cur_min_scalar, bounds[0], mod); | 25376 | cur_min_scalar = opFunc(cur_min_scalar, bounds[0], pt); |
| 25138 | cur_max_scalar = opFunc(cur_max_scalar, bounds[1], mod); | 25377 | cur_max_scalar = opFunc(cur_max_scalar, bounds[1], pt); |
| 25139 | } | 25378 | } |
| 25140 | } | 25379 | } |
| 25141 | }, | 25380 | }, |
| ... | @@ -25153,18 +25392,18 @@ fn analyzeMinMax( | ... | @@ -25153,18 +25392,18 @@ fn analyzeMinMax( |
| 25153 | const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above | 25392 | const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above |
| 25154 | 25393 | ||
| 25155 | const vec_len = simd_op.len orelse { | 25394 | const vec_len = simd_op.len orelse { |
| 25156 | const result_val = opFunc(cur_val, operand_val, mod); | 25395 | const result_val = opFunc(cur_val, operand_val, pt); |
| 25157 | cur_minmax = Air.internedToRef(result_val.toIntern()); | 25396 | cur_minmax = Air.internedToRef(result_val.toIntern()); |
| 25158 | continue; | 25397 | continue; |
| 25159 | }; | 25398 | }; |
| 25160 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 25399 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 25161 | for (elems, 0..) |*elem, i| { | 25400 | for (elems, 0..) |*elem, i| { |
| 25162 | const lhs_elem_val = try cur_val.elemValue(mod, i); | 25401 | const lhs_elem_val = try cur_val.elemValue(pt, i); |
| 25163 | const rhs_elem_val = try operand_val.elemValue(mod, i); | 25402 | const rhs_elem_val = try operand_val.elemValue(pt, i); |
| 25164 | const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, mod); | 25403 | const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, pt); |
| 25165 | elem.* = (try mod.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern(); | 25404 | elem.* = (try pt.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern(); |
| 25166 | } | 25405 | } |
| 25167 | cur_minmax = Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 25406 | cur_minmax = Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 25168 | .ty = simd_op.result_ty.toIntern(), | 25407 | .ty = simd_op.result_ty.toIntern(), |
| 25169 | .storage = .{ .elems = elems }, | 25408 | .storage = .{ .elems = elems }, |
| 25170 | } }))); | 25409 | } }))); |
| ... | @@ -25191,8 +25430,8 @@ fn analyzeMinMax( | ... | @@ -25191,8 +25430,8 @@ fn analyzeMinMax( |
| 25191 | 25430 | ||
| 25192 | assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg | 25431 | assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg |
| 25193 | 25432 | ||
| 25194 | const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar); | 25433 | const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar); |
| 25195 | const refined_ty = if (orig_ty.isVector(mod)) try mod.vectorType(.{ | 25434 | const refined_ty = if (orig_ty.isVector(mod)) try pt.vectorType(.{ |
| 25196 | .len = orig_ty.vectorLen(mod), | 25435 | .len = orig_ty.vectorLen(mod), |
| 25197 | .child = refined_scalar_ty.toIntern(), | 25436 | .child = refined_scalar_ty.toIntern(), |
| 25198 | }) else refined_scalar_ty; | 25437 | }) else refined_scalar_ty; |
| ... | @@ -25226,8 +25465,8 @@ fn analyzeMinMax( | ... | @@ -25226,8 +25465,8 @@ fn analyzeMinMax( |
| 25226 | runtime_known.unset(0); // don't look at this operand in the loop below | 25465 | runtime_known.unset(0); // don't look at this operand in the loop below |
| 25227 | const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod); | 25466 | const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod); |
| 25228 | if (scalar_ty.isInt(mod)) { | 25467 | if (scalar_ty.isInt(mod)) { |
| 25229 | cur_min_scalar = try scalar_ty.minInt(mod, scalar_ty); | 25468 | cur_min_scalar = try scalar_ty.minInt(pt, scalar_ty); |
| 25230 | cur_max_scalar = try scalar_ty.maxInt(mod, scalar_ty); | 25469 | cur_max_scalar = try scalar_ty.maxInt(pt, scalar_ty); |
| 25231 | bounds_status = .defined; | 25470 | bounds_status = .defined; |
| 25232 | } else { | 25471 | } else { |
| 25233 | bounds_status = .non_integral; | 25472 | bounds_status = .non_integral; |
| ... | @@ -25242,7 +25481,7 @@ fn analyzeMinMax( | ... | @@ -25242,7 +25481,7 @@ fn analyzeMinMax( |
| 25242 | const rhs_src = operand_srcs[idx]; | 25481 | const rhs_src = operand_srcs[idx]; |
| 25243 | const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src); | 25482 | const simd_op = try sema.checkSimdBinOp(block, src, lhs, rhs, lhs_src, rhs_src); |
| 25244 | if (known_undef) { | 25483 | if (known_undef) { |
| 25245 | cur_minmax = try mod.undefRef(simd_op.result_ty); | 25484 | cur_minmax = try pt.undefRef(simd_op.result_ty); |
| 25246 | } else { | 25485 | } else { |
| 25247 | cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs); | 25486 | cur_minmax = try block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs); |
| 25248 | } | 25487 | } |
| ... | @@ -25254,15 +25493,15 @@ fn analyzeMinMax( | ... | @@ -25254,15 +25493,15 @@ fn analyzeMinMax( |
| 25254 | bounds_status = .non_integral; | 25493 | bounds_status = .non_integral; |
| 25255 | break :refine_bounds; | 25494 | break :refine_bounds; |
| 25256 | } | 25495 | } |
| 25257 | const scalar_min = try scalar_ty.minInt(mod, scalar_ty); | 25496 | const scalar_min = try scalar_ty.minInt(pt, scalar_ty); |
| 25258 | const scalar_max = try scalar_ty.maxInt(mod, scalar_ty); | 25497 | const scalar_max = try scalar_ty.maxInt(pt, scalar_ty); |
| 25259 | if (bounds_status == .unknown) { | 25498 | if (bounds_status == .unknown) { |
| 25260 | cur_min_scalar = scalar_min; | 25499 | cur_min_scalar = scalar_min; |
| 25261 | cur_max_scalar = scalar_max; | 25500 | cur_max_scalar = scalar_max; |
| 25262 | bounds_status = .defined; | 25501 | bounds_status = .defined; |
| 25263 | } else { | 25502 | } else { |
| 25264 | cur_min_scalar = opFunc(cur_min_scalar, scalar_min, mod); | 25503 | cur_min_scalar = opFunc(cur_min_scalar, scalar_min, pt); |
| 25265 | cur_max_scalar = opFunc(cur_max_scalar, scalar_max, mod); | 25504 | cur_max_scalar = opFunc(cur_max_scalar, scalar_max, pt); |
| 25266 | } | 25505 | } |
| 25267 | }, | 25506 | }, |
| 25268 | .non_integral => {}, | 25507 | .non_integral => {}, |
| ... | @@ -25276,8 +25515,8 @@ fn analyzeMinMax( | ... | @@ -25276,8 +25515,8 @@ fn analyzeMinMax( |
| 25276 | return cur_minmax.?; | 25515 | return cur_minmax.?; |
| 25277 | } | 25516 | } |
| 25278 | assert(bounds_status == .defined); // there were integral runtime operands | 25517 | assert(bounds_status == .defined); // there were integral runtime operands |
| 25279 | const refined_scalar_ty = try mod.intFittingRange(cur_min_scalar, cur_max_scalar); | 25518 | const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar); |
| 25280 | const refined_ty = if (unrefined_ty.isVector(mod)) try mod.vectorType(.{ | 25519 | const refined_ty = if (unrefined_ty.isVector(mod)) try pt.vectorType(.{ |
| 25281 | .len = unrefined_ty.vectorLen(mod), | 25520 | .len = unrefined_ty.vectorLen(mod), |
| 25282 | .child = refined_scalar_ty.toIntern(), | 25521 | .child = refined_scalar_ty.toIntern(), |
| 25283 | }) else refined_scalar_ty; | 25522 | }) else refined_scalar_ty; |
| ... | @@ -25291,15 +25530,16 @@ fn analyzeMinMax( | ... | @@ -25291,15 +25530,16 @@ fn analyzeMinMax( |
| 25291 | } | 25530 | } |
| 25292 | 25531 | ||
| 25293 | fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref { | 25532 | fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref { |
| 25294 | const mod = sema.mod; | 25533 | const pt = sema.pt; |
| 25534 | const mod = pt.zcu; | ||
| 25295 | const ptr_ty = sema.typeOf(ptr); | 25535 | const ptr_ty = sema.typeOf(ptr); |
| 25296 | const info = ptr_ty.ptrInfo(mod); | 25536 | const info = ptr_ty.ptrInfo(mod); |
| 25297 | if (info.flags.size == .One) { | 25537 | if (info.flags.size == .One) { |
| 25298 | // Already an array pointer. | 25538 | // Already an array pointer. |
| 25299 | return ptr; | 25539 | return ptr; |
| 25300 | } | 25540 | } |
| 25301 | const new_ty = try mod.ptrTypeSema(.{ | 25541 | const new_ty = try pt.ptrTypeSema(.{ |
| 25302 | .child = (try mod.arrayType(.{ | 25542 | .child = (try pt.arrayType(.{ |
| 25303 | .len = len, | 25543 | .len = len, |
| 25304 | .sentinel = info.sentinel, | 25544 | .sentinel = info.sentinel, |
| 25305 | .child = info.child, | 25545 | .child = info.child, |
| ... | @@ -25331,8 +25571,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25331,8 +25571,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25331 | const src_ty = sema.typeOf(src_ptr); | 25571 | const src_ty = sema.typeOf(src_ptr); |
| 25332 | const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr); | 25572 | const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr); |
| 25333 | const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr); | 25573 | const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr); |
| 25334 | const target = sema.mod.getTarget(); | 25574 | const pt = sema.pt; |
| 25335 | const mod = sema.mod; | 25575 | const mod = pt.zcu; |
| 25576 | const target = mod.getTarget(); | ||
| 25336 | 25577 | ||
| 25337 | if (dest_ty.isConstPtr(mod)) { | 25578 | if (dest_ty.isConstPtr(mod)) { |
| 25338 | return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{}); | 25579 | return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{}); |
| ... | @@ -25343,10 +25584,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25343,10 +25584,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25343 | const msg = try sema.errMsg(src, "unknown @memcpy length", .{}); | 25584 | const msg = try sema.errMsg(src, "unknown @memcpy length", .{}); |
| 25344 | errdefer msg.destroy(sema.gpa); | 25585 | errdefer msg.destroy(sema.gpa); |
| 25345 | try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{ | 25586 | try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{ |
| 25346 | dest_ty.fmt(sema.mod), | 25587 | dest_ty.fmt(pt), |
| 25347 | }); | 25588 | }); |
| 25348 | try sema.errNote(src_src, msg, "source type '{}' provides no length", .{ | 25589 | try sema.errNote(src_src, msg, "source type '{}' provides no length", .{ |
| 25349 | src_ty.fmt(sema.mod), | 25590 | src_ty.fmt(pt), |
| 25350 | }); | 25591 | }); |
| 25351 | break :msg msg; | 25592 | break :msg msg; |
| 25352 | }; | 25593 | }; |
| ... | @@ -25365,10 +25606,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25365,10 +25606,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25365 | const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{}); | 25606 | const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{}); |
| 25366 | errdefer msg.destroy(sema.gpa); | 25607 | errdefer msg.destroy(sema.gpa); |
| 25367 | try sema.errNote(dest_src, msg, "length {} here", .{ | 25608 | try sema.errNote(dest_src, msg, "length {} here", .{ |
| 25368 | dest_len_val.fmtValue(sema.mod, sema), | 25609 | dest_len_val.fmtValue(pt, sema), |
| 25369 | }); | 25610 | }); |
| 25370 | try sema.errNote(src_src, msg, "length {} here", .{ | 25611 | try sema.errNote(src_src, msg, "length {} here", .{ |
| 25371 | src_len_val.fmtValue(sema.mod, sema), | 25612 | src_len_val.fmtValue(pt, sema), |
| 25372 | }); | 25613 | }); |
| 25373 | break :msg msg; | 25614 | break :msg msg; |
| 25374 | }; | 25615 | }; |
| ... | @@ -25397,10 +25638,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25397,10 +25638,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25397 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { | 25638 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { |
| 25398 | if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src; | 25639 | if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src; |
| 25399 | if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| { | 25640 | if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| { |
| 25400 | const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, .sema)).?; | 25641 | const len_u64 = (try len_val.?.getUnsignedIntAdvanced(pt, .sema)).?; |
| 25401 | const len = try sema.usizeCast(block, dest_src, len_u64); | 25642 | const len = try sema.usizeCast(block, dest_src, len_u64); |
| 25402 | for (0..len) |i| { | 25643 | for (0..len) |i| { |
| 25403 | const elem_index = try mod.intRef(Type.usize, i); | 25644 | const elem_index = try pt.intRef(Type.usize, i); |
| 25404 | const dest_elem_ptr = try sema.elemPtrOneLayerOnly( | 25645 | const dest_elem_ptr = try sema.elemPtrOneLayerOnly( |
| 25405 | block, | 25646 | block, |
| 25406 | src, | 25647 | src, |
| ... | @@ -25456,7 +25697,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25456,7 +25697,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25456 | var new_dest_ptr = dest_ptr; | 25697 | var new_dest_ptr = dest_ptr; |
| 25457 | var new_src_ptr = src_ptr; | 25698 | var new_src_ptr = src_ptr; |
| 25458 | if (len_val) |val| { | 25699 | if (len_val) |val| { |
| 25459 | const len = try val.toUnsignedIntSema(mod); | 25700 | const len = try val.toUnsignedIntSema(pt); |
| 25460 | if (len == 0) { | 25701 | if (len == 0) { |
| 25461 | // This AIR instruction guarantees length > 0 if it is comptime-known. | 25702 | // This AIR instruction guarantees length > 0 if it is comptime-known. |
| 25462 | return; | 25703 | return; |
| ... | @@ -25503,7 +25744,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25503,7 +25744,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25503 | assert(dest_manyptr_ty_key.flags.size == .One); | 25744 | assert(dest_manyptr_ty_key.flags.size == .One); |
| 25504 | dest_manyptr_ty_key.child = dest_elem_ty.toIntern(); | 25745 | dest_manyptr_ty_key.child = dest_elem_ty.toIntern(); |
| 25505 | dest_manyptr_ty_key.flags.size = .Many; | 25746 | dest_manyptr_ty_key.flags.size = .Many; |
| 25506 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src); | 25747 | break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src); |
| 25507 | } else new_dest_ptr; | 25748 | } else new_dest_ptr; |
| 25508 | 25749 | ||
| 25509 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); | 25750 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); |
| ... | @@ -25514,7 +25755,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25514,7 +25755,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25514 | assert(src_manyptr_ty_key.flags.size == .One); | 25755 | assert(src_manyptr_ty_key.flags.size == .One); |
| 25515 | src_manyptr_ty_key.child = src_elem_ty.toIntern(); | 25756 | src_manyptr_ty_key.child = src_elem_ty.toIntern(); |
| 25516 | src_manyptr_ty_key.flags.size = .Many; | 25757 | src_manyptr_ty_key.flags.size = .Many; |
| 25517 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src); | 25758 | break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src); |
| 25518 | } else new_src_ptr; | 25759 | } else new_src_ptr; |
| 25519 | 25760 | ||
| 25520 | // ok1: dest >= src + len | 25761 | // ok1: dest >= src + len |
| ... | @@ -25537,7 +25778,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25537,7 +25778,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25537 | } | 25778 | } |
| 25538 | 25779 | ||
| 25539 | fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 25780 | fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 25540 | const mod = sema.mod; | 25781 | const pt = sema.pt; |
| 25782 | const mod = pt.zcu; | ||
| 25541 | const gpa = sema.gpa; | 25783 | const gpa = sema.gpa; |
| 25542 | const ip = &mod.intern_pool; | 25784 | const ip = &mod.intern_pool; |
| 25543 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 25785 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| ... | @@ -25569,7 +25811,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25569,7 +25811,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25569 | const msg = try sema.errMsg(src, "unknown @memset length", .{}); | 25811 | const msg = try sema.errMsg(src, "unknown @memset length", .{}); |
| 25570 | errdefer msg.destroy(sema.gpa); | 25812 | errdefer msg.destroy(sema.gpa); |
| 25571 | try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{ | 25813 | try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{ |
| 25572 | dest_ptr_ty.fmt(mod), | 25814 | dest_ptr_ty.fmt(pt), |
| 25573 | }); | 25815 | }); |
| 25574 | break :msg msg; | 25816 | break :msg msg; |
| 25575 | }); | 25817 | }); |
| ... | @@ -25581,7 +25823,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25581,7 +25823,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25581 | const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src; | 25823 | const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src; |
| 25582 | const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src); | 25824 | const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src); |
| 25583 | const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src; | 25825 | const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src; |
| 25584 | const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, .sema)).?; | 25826 | const len_u64 = (try len_val.getUnsignedIntAdvanced(pt, .sema)).?; |
| 25585 | const len = try sema.usizeCast(block, dest_src, len_u64); | 25827 | const len = try sema.usizeCast(block, dest_src, len_u64); |
| 25586 | if (len == 0) { | 25828 | if (len == 0) { |
| 25587 | // This AIR instruction guarantees length > 0 if it is comptime-known. | 25829 | // This AIR instruction guarantees length > 0 if it is comptime-known. |
| ... | @@ -25590,22 +25832,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25590,22 +25832,22 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25590 | 25832 | ||
| 25591 | if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src; | 25833 | if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src; |
| 25592 | const elem_val = try sema.resolveValue(elem) orelse break :rs value_src; | 25834 | const elem_val = try sema.resolveValue(elem) orelse break :rs value_src; |
| 25593 | const array_ty = try mod.arrayType(.{ | 25835 | const array_ty = try pt.arrayType(.{ |
| 25594 | .child = dest_elem_ty.toIntern(), | 25836 | .child = dest_elem_ty.toIntern(), |
| 25595 | .len = len_u64, | 25837 | .len = len_u64, |
| 25596 | }); | 25838 | }); |
| 25597 | const array_val = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 25839 | const array_val = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 25598 | .ty = array_ty.toIntern(), | 25840 | .ty = array_ty.toIntern(), |
| 25599 | .storage = .{ .repeated_elem = elem_val.toIntern() }, | 25841 | .storage = .{ .repeated_elem = elem_val.toIntern() }, |
| 25600 | } }))); | 25842 | } })); |
| 25601 | const array_ptr_ty = ty: { | 25843 | const array_ptr_ty = ty: { |
| 25602 | var info = dest_ptr_ty.ptrInfo(mod); | 25844 | var info = dest_ptr_ty.ptrInfo(mod); |
| 25603 | info.flags.size = .One; | 25845 | info.flags.size = .One; |
| 25604 | info.child = array_ty.toIntern(); | 25846 | info.child = array_ty.toIntern(); |
| 25605 | break :ty try mod.ptrType(info); | 25847 | break :ty try pt.ptrType(info); |
| 25606 | }; | 25848 | }; |
| 25607 | const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val; | 25849 | const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val; |
| 25608 | const array_ptr_val = try mod.getCoerced(raw_ptr_val, array_ptr_ty); | 25850 | const array_ptr_val = try pt.getCoerced(raw_ptr_val, array_ptr_ty); |
| 25609 | return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty); | 25851 | return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty); |
| 25610 | }; | 25852 | }; |
| 25611 | 25853 | ||
| ... | @@ -25658,7 +25900,8 @@ fn zirVarExtended( | ... | @@ -25658,7 +25900,8 @@ fn zirVarExtended( |
| 25658 | block: *Block, | 25900 | block: *Block, |
| 25659 | extended: Zir.Inst.Extended.InstData, | 25901 | extended: Zir.Inst.Extended.InstData, |
| 25660 | ) CompileError!Air.Inst.Ref { | 25902 | ) CompileError!Air.Inst.Ref { |
| 25661 | const mod = sema.mod; | 25903 | const pt = sema.pt; |
| 25904 | const mod = pt.zcu; | ||
| 25662 | const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); | 25905 | const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); |
| 25663 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); | 25906 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); |
| 25664 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); | 25907 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); |
| ... | @@ -25705,7 +25948,7 @@ fn zirVarExtended( | ... | @@ -25705,7 +25948,7 @@ fn zirVarExtended( |
| 25705 | 25948 | ||
| 25706 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); | 25949 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); |
| 25707 | 25950 | ||
| 25708 | return Air.internedToRef((try mod.intern(.{ .variable = .{ | 25951 | return Air.internedToRef((try pt.intern(.{ .variable = .{ |
| 25709 | .ty = var_ty.toIntern(), | 25952 | .ty = var_ty.toIntern(), |
| 25710 | .init = init_val, | 25953 | .init = init_val, |
| 25711 | .decl = sema.owner_decl_index, | 25954 | .decl = sema.owner_decl_index, |
| ... | @@ -25721,7 +25964,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25721,7 +25964,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25721 | const tracy = trace(@src()); | 25964 | const tracy = trace(@src()); |
| 25722 | defer tracy.end(); | 25965 | defer tracy.end(); |
| 25723 | 25966 | ||
| 25724 | const mod = sema.mod; | 25967 | const pt = sema.pt; |
| 25968 | const mod = pt.zcu; | ||
| 25725 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 25969 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 25726 | const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); | 25970 | const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 25727 | const target = mod.getTarget(); | 25971 | const target = mod.getTarget(); |
| ... | @@ -25761,7 +26005,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25761,7 +26005,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25761 | if (val.isGenericPoison()) { | 26005 | if (val.isGenericPoison()) { |
| 25762 | break :blk null; | 26006 | break :blk null; |
| 25763 | } | 26007 | } |
| 25764 | const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(mod)); | 26008 | const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(pt)); |
| 25765 | const default = target_util.defaultFunctionAlignment(target); | 26009 | const default = target_util.defaultFunctionAlignment(target); |
| 25766 | break :blk if (alignment == default) .none else alignment; | 26010 | break :blk if (alignment == default) .none else alignment; |
| 25767 | } else if (extra.data.bits.has_align_ref) blk: { | 26011 | } else if (extra.data.bits.has_align_ref) blk: { |
| ... | @@ -25781,7 +26025,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25781,7 +26025,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25781 | error.GenericPoison => break :blk null, | 26025 | error.GenericPoison => break :blk null, |
| 25782 | else => |e| return e, | 26026 | else => |e| return e, |
| 25783 | }; | 26027 | }; |
| 25784 | const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(mod)); | 26028 | const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(pt)); |
| 25785 | const default = target_util.defaultFunctionAlignment(target); | 26029 | const default = target_util.defaultFunctionAlignment(target); |
| 25786 | break :blk if (alignment == default) .none else alignment; | 26030 | break :blk if (alignment == default) .none else alignment; |
| 25787 | } else .none; | 26031 | } else .none; |
| ... | @@ -25857,7 +26101,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25857,7 +26101,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25857 | const body = sema.code.bodySlice(extra_index, body_len); | 26101 | const body = sema.code.bodySlice(extra_index, body_len); |
| 25858 | extra_index += body.len; | 26102 | extra_index += body.len; |
| 25859 | 26103 | ||
| 25860 | const cc_ty = try mod.getBuiltinType("CallingConvention"); | 26104 | const cc_ty = try pt.getBuiltinType("CallingConvention"); |
| 25861 | const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ | 26105 | const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{ |
| 25862 | .needed_comptime_reason = "calling convention must be comptime-known", | 26106 | .needed_comptime_reason = "calling convention must be comptime-known", |
| 25863 | }); | 26107 | }); |
| ... | @@ -25986,7 +26230,8 @@ fn zirCDefine( | ... | @@ -25986,7 +26230,8 @@ fn zirCDefine( |
| 25986 | block: *Block, | 26230 | block: *Block, |
| 25987 | extended: Zir.Inst.Extended.InstData, | 26231 | extended: Zir.Inst.Extended.InstData, |
| 25988 | ) CompileError!Air.Inst.Ref { | 26232 | ) CompileError!Air.Inst.Ref { |
| 25989 | const mod = sema.mod; | 26233 | const pt = sema.pt; |
| 26234 | const mod = pt.zcu; | ||
| 25990 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 26235 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 25991 | const name_src = block.builtinCallArgSrc(extra.node, 0); | 26236 | const name_src = block.builtinCallArgSrc(extra.node, 0); |
| 25992 | const val_src = block.builtinCallArgSrc(extra.node, 1); | 26237 | const val_src = block.builtinCallArgSrc(extra.node, 1); |
| ... | @@ -26014,7 +26259,7 @@ fn zirWasmMemorySize( | ... | @@ -26014,7 +26259,7 @@ fn zirWasmMemorySize( |
| 26014 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 26259 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 26015 | const index_src = block.builtinCallArgSrc(extra.node, 0); | 26260 | const index_src = block.builtinCallArgSrc(extra.node, 0); |
| 26016 | const builtin_src = block.nodeOffset(extra.node); | 26261 | const builtin_src = block.nodeOffset(extra.node); |
| 26017 | const target = sema.mod.getTarget(); | 26262 | const target = sema.pt.zcu.getTarget(); |
| 26018 | if (!target.isWasm()) { | 26263 | if (!target.isWasm()) { |
| 26019 | return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); | 26264 | return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 26020 | } | 26265 | } |
| ... | @@ -26041,7 +26286,7 @@ fn zirWasmMemoryGrow( | ... | @@ -26041,7 +26286,7 @@ fn zirWasmMemoryGrow( |
| 26041 | const builtin_src = block.nodeOffset(extra.node); | 26286 | const builtin_src = block.nodeOffset(extra.node); |
| 26042 | const index_src = block.builtinCallArgSrc(extra.node, 0); | 26287 | const index_src = block.builtinCallArgSrc(extra.node, 0); |
| 26043 | const delta_src = block.builtinCallArgSrc(extra.node, 1); | 26288 | const delta_src = block.builtinCallArgSrc(extra.node, 1); |
| 26044 | const target = sema.mod.getTarget(); | 26289 | const target = sema.pt.zcu.getTarget(); |
| 26045 | if (!target.isWasm()) { | 26290 | if (!target.isWasm()) { |
| 26046 | return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); | 26291 | return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 26047 | } | 26292 | } |
| ... | @@ -26067,10 +26312,11 @@ fn resolvePrefetchOptions( | ... | @@ -26067,10 +26312,11 @@ fn resolvePrefetchOptions( |
| 26067 | src: LazySrcLoc, | 26312 | src: LazySrcLoc, |
| 26068 | zir_ref: Zir.Inst.Ref, | 26313 | zir_ref: Zir.Inst.Ref, |
| 26069 | ) CompileError!std.builtin.PrefetchOptions { | 26314 | ) CompileError!std.builtin.PrefetchOptions { |
| 26070 | const mod = sema.mod; | 26315 | const pt = sema.pt; |
| 26316 | const mod = pt.zcu; | ||
| 26071 | const gpa = sema.gpa; | 26317 | const gpa = sema.gpa; |
| 26072 | const ip = &mod.intern_pool; | 26318 | const ip = &mod.intern_pool; |
| 26073 | const options_ty = try mod.getBuiltinType("PrefetchOptions"); | 26319 | const options_ty = try pt.getBuiltinType("PrefetchOptions"); |
| 26074 | const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src); | 26320 | const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src); |
| 26075 | 26321 | ||
| 26076 | const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | 26322 | const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| ... | @@ -26094,7 +26340,7 @@ fn resolvePrefetchOptions( | ... | @@ -26094,7 +26340,7 @@ fn resolvePrefetchOptions( |
| 26094 | 26340 | ||
| 26095 | return std.builtin.PrefetchOptions{ | 26341 | return std.builtin.PrefetchOptions{ |
| 26096 | .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val), | 26342 | .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val), |
| 26097 | .locality = @intCast(try locality_val.toUnsignedIntSema(mod)), | 26343 | .locality = @intCast(try locality_val.toUnsignedIntSema(pt)), |
| 26098 | .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val), | 26344 | .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val), |
| 26099 | }; | 26345 | }; |
| 26100 | } | 26346 | } |
| ... | @@ -26138,11 +26384,12 @@ fn resolveExternOptions( | ... | @@ -26138,11 +26384,12 @@ fn resolveExternOptions( |
| 26138 | linkage: std.builtin.GlobalLinkage = .strong, | 26384 | linkage: std.builtin.GlobalLinkage = .strong, |
| 26139 | is_thread_local: bool = false, | 26385 | is_thread_local: bool = false, |
| 26140 | } { | 26386 | } { |
| 26141 | const mod = sema.mod; | 26387 | const pt = sema.pt; |
| 26388 | const mod = pt.zcu; | ||
| 26142 | const gpa = sema.gpa; | 26389 | const gpa = sema.gpa; |
| 26143 | const ip = &mod.intern_pool; | 26390 | const ip = &mod.intern_pool; |
| 26144 | const options_inst = try sema.resolveInst(zir_ref); | 26391 | const options_inst = try sema.resolveInst(zir_ref); |
| 26145 | const extern_options_ty = try mod.getBuiltinType("ExternOptions"); | 26392 | const extern_options_ty = try pt.getBuiltinType("ExternOptions"); |
| 26146 | const options = try sema.coerce(block, extern_options_ty, options_inst, src); | 26393 | const options = try sema.coerce(block, extern_options_ty, options_inst, src); |
| 26147 | 26394 | ||
| 26148 | const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node }); | 26395 | const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node }); |
| ... | @@ -26203,7 +26450,8 @@ fn zirBuiltinExtern( | ... | @@ -26203,7 +26450,8 @@ fn zirBuiltinExtern( |
| 26203 | block: *Block, | 26450 | block: *Block, |
| 26204 | extended: Zir.Inst.Extended.InstData, | 26451 | extended: Zir.Inst.Extended.InstData, |
| 26205 | ) CompileError!Air.Inst.Ref { | 26452 | ) CompileError!Air.Inst.Ref { |
| 26206 | const mod = sema.mod; | 26453 | const pt = sema.pt; |
| 26454 | const mod = pt.zcu; | ||
| 26207 | const ip = &mod.intern_pool; | 26455 | const ip = &mod.intern_pool; |
| 26208 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 26456 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 26209 | const ty_src = block.builtinCallArgSrc(extra.node, 0); | 26457 | const ty_src = block.builtinCallArgSrc(extra.node, 0); |
| ... | @@ -26215,7 +26463,7 @@ fn zirBuiltinExtern( | ... | @@ -26215,7 +26463,7 @@ fn zirBuiltinExtern( |
| 26215 | } | 26463 | } |
| 26216 | if (!try sema.validateExternType(ty, .other)) { | 26464 | if (!try sema.validateExternType(ty, .other)) { |
| 26217 | const msg = msg: { | 26465 | const msg = msg: { |
| 26218 | const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)}); | 26466 | const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(pt)}); |
| 26219 | errdefer msg.destroy(sema.gpa); | 26467 | errdefer msg.destroy(sema.gpa); |
| 26220 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); | 26468 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); |
| 26221 | break :msg msg; | 26469 | break :msg msg; |
| ... | @@ -26226,7 +26474,7 @@ fn zirBuiltinExtern( | ... | @@ -26226,7 +26474,7 @@ fn zirBuiltinExtern( |
| 26226 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); | 26474 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| 26227 | 26475 | ||
| 26228 | if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) { | 26476 | if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) { |
| 26229 | ty = try mod.optionalType(ty.toIntern()); | 26477 | ty = try pt.optionalType(ty.toIntern()); |
| 26230 | } | 26478 | } |
| 26231 | const ptr_info = ty.ptrInfo(mod); | 26479 | const ptr_info = ty.ptrInfo(mod); |
| 26232 | 26480 | ||
| ... | @@ -26237,13 +26485,13 @@ fn zirBuiltinExtern( | ... | @@ -26237,13 +26485,13 @@ fn zirBuiltinExtern( |
| 26237 | new_decl_index, | 26485 | new_decl_index, |
| 26238 | Value.fromInterned( | 26486 | Value.fromInterned( |
| 26239 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) | 26487 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) |
| 26240 | try ip.getExternFunc(sema.gpa, .{ | 26488 | try ip.getExternFunc(sema.gpa, pt.tid, .{ |
| 26241 | .ty = ptr_info.child, | 26489 | .ty = ptr_info.child, |
| 26242 | .decl = new_decl_index, | 26490 | .decl = new_decl_index, |
| 26243 | .lib_name = options.library_name, | 26491 | .lib_name = options.library_name, |
| 26244 | }) | 26492 | }) |
| 26245 | else | 26493 | else |
| 26246 | try mod.intern(.{ .variable = .{ | 26494 | try pt.intern(.{ .variable = .{ |
| 26247 | .ty = ptr_info.child, | 26495 | .ty = ptr_info.child, |
| 26248 | .init = .none, | 26496 | .init = .none, |
| 26249 | .decl = new_decl_index, | 26497 | .decl = new_decl_index, |
| ... | @@ -26259,9 +26507,9 @@ fn zirBuiltinExtern( | ... | @@ -26259,9 +26507,9 @@ fn zirBuiltinExtern( |
| 26259 | new_decl.owns_tv = true; | 26507 | new_decl.owns_tv = true; |
| 26260 | // Note that this will queue the anon decl for codegen, so that the backend can | 26508 | // Note that this will queue the anon decl for codegen, so that the backend can |
| 26261 | // correctly handle the extern, including duplicate detection. | 26509 | // correctly handle the extern, including duplicate detection. |
| 26262 | try mod.finalizeAnonDecl(new_decl_index); | 26510 | try pt.finalizeAnonDecl(new_decl_index); |
| 26263 | 26511 | ||
| 26264 | return Air.internedToRef((try mod.getCoerced(Value.fromInterned((try mod.intern(.{ .ptr = .{ | 26512 | return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 26265 | .ty = switch (ip.indexToKey(ty.toIntern())) { | 26513 | .ty = switch (ip.indexToKey(ty.toIntern())) { |
| 26266 | .ptr_type => ty.toIntern(), | 26514 | .ptr_type => ty.toIntern(), |
| 26267 | .opt_type => |child_type| child_type, | 26515 | .opt_type => |child_type| child_type, |
| ... | @@ -26269,7 +26517,7 @@ fn zirBuiltinExtern( | ... | @@ -26269,7 +26517,7 @@ fn zirBuiltinExtern( |
| 26269 | }, | 26517 | }, |
| 26270 | .base_addr = .{ .decl = new_decl_index }, | 26518 | .base_addr = .{ .decl = new_decl_index }, |
| 26271 | .byte_offset = 0, | 26519 | .byte_offset = 0, |
| 26272 | } }))), ty)).toIntern()); | 26520 | } })), ty)).toIntern()); |
| 26273 | } | 26521 | } |
| 26274 | 26522 | ||
| 26275 | fn zirWorkItem( | 26523 | fn zirWorkItem( |
| ... | @@ -26281,7 +26529,7 @@ fn zirWorkItem( | ... | @@ -26281,7 +26529,7 @@ fn zirWorkItem( |
| 26281 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 26529 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 26282 | const dimension_src = block.builtinCallArgSrc(extra.node, 0); | 26530 | const dimension_src = block.builtinCallArgSrc(extra.node, 0); |
| 26283 | const builtin_src = block.nodeOffset(extra.node); | 26531 | const builtin_src = block.nodeOffset(extra.node); |
| 26284 | const target = sema.mod.getTarget(); | 26532 | const target = sema.pt.zcu.getTarget(); |
| 26285 | 26533 | ||
| 26286 | switch (target.cpu.arch) { | 26534 | switch (target.cpu.arch) { |
| 26287 | // TODO: Allow for other GPU targets. | 26535 | // TODO: Allow for other GPU targets. |
| ... | @@ -26344,11 +26592,12 @@ fn validateVarType( | ... | @@ -26344,11 +26592,12 @@ fn validateVarType( |
| 26344 | var_ty: Type, | 26592 | var_ty: Type, |
| 26345 | is_extern: bool, | 26593 | is_extern: bool, |
| 26346 | ) CompileError!void { | 26594 | ) CompileError!void { |
| 26347 | const mod = sema.mod; | 26595 | const pt = sema.pt; |
| 26596 | const mod = pt.zcu; | ||
| 26348 | if (is_extern) { | 26597 | if (is_extern) { |
| 26349 | if (!try sema.validateExternType(var_ty, .other)) { | 26598 | if (!try sema.validateExternType(var_ty, .other)) { |
| 26350 | const msg = msg: { | 26599 | const msg = msg: { |
| 26351 | const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)}); | 26600 | const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(pt)}); |
| 26352 | errdefer msg.destroy(sema.gpa); | 26601 | errdefer msg.destroy(sema.gpa); |
| 26353 | try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other); | 26602 | try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other); |
| 26354 | break :msg msg; | 26603 | break :msg msg; |
| ... | @@ -26361,7 +26610,7 @@ fn validateVarType( | ... | @@ -26361,7 +26610,7 @@ fn validateVarType( |
| 26361 | block, | 26610 | block, |
| 26362 | src, | 26611 | src, |
| 26363 | "non-extern variable with opaque type '{}'", | 26612 | "non-extern variable with opaque type '{}'", |
| 26364 | .{var_ty.fmt(mod)}, | 26613 | .{var_ty.fmt(pt)}, |
| 26365 | ); | 26614 | ); |
| 26366 | } | 26615 | } |
| 26367 | } | 26616 | } |
| ... | @@ -26369,7 +26618,7 @@ fn validateVarType( | ... | @@ -26369,7 +26618,7 @@ fn validateVarType( |
| 26369 | if (!try sema.typeRequiresComptime(var_ty)) return; | 26618 | if (!try sema.typeRequiresComptime(var_ty)) return; |
| 26370 | 26619 | ||
| 26371 | const msg = msg: { | 26620 | const msg = msg: { |
| 26372 | const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)}); | 26621 | const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(pt)}); |
| 26373 | errdefer msg.destroy(sema.gpa); | 26622 | errdefer msg.destroy(sema.gpa); |
| 26374 | 26623 | ||
| 26375 | try sema.explainWhyTypeIsComptime(msg, src, var_ty); | 26624 | try sema.explainWhyTypeIsComptime(msg, src, var_ty); |
| ... | @@ -26393,7 +26642,7 @@ fn explainWhyTypeIsComptime( | ... | @@ -26393,7 +26642,7 @@ fn explainWhyTypeIsComptime( |
| 26393 | var type_set = TypeSet{}; | 26642 | var type_set = TypeSet{}; |
| 26394 | defer type_set.deinit(sema.gpa); | 26643 | defer type_set.deinit(sema.gpa); |
| 26395 | 26644 | ||
| 26396 | try ty.resolveFully(sema.mod); | 26645 | try ty.resolveFully(sema.pt); |
| 26397 | return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set); | 26646 | return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set); |
| 26398 | } | 26647 | } |
| 26399 | 26648 | ||
| ... | @@ -26404,7 +26653,8 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26404,7 +26653,8 @@ fn explainWhyTypeIsComptimeInner( |
| 26404 | ty: Type, | 26653 | ty: Type, |
| 26405 | type_set: *TypeSet, | 26654 | type_set: *TypeSet, |
| 26406 | ) CompileError!void { | 26655 | ) CompileError!void { |
| 26407 | const mod = sema.mod; | 26656 | const pt = sema.pt; |
| 26657 | const mod = pt.zcu; | ||
| 26408 | const ip = &mod.intern_pool; | 26658 | const ip = &mod.intern_pool; |
| 26409 | switch (ty.zigTypeTag(mod)) { | 26659 | switch (ty.zigTypeTag(mod)) { |
| 26410 | .Bool, | 26660 | .Bool, |
| ... | @@ -26418,9 +26668,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26418,9 +26668,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26418 | => return, | 26668 | => return, |
| 26419 | 26669 | ||
| 26420 | .Fn => { | 26670 | .Fn => { |
| 26421 | try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{ | 26671 | try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{ty.fmt(pt)}); |
| 26422 | ty.fmt(sema.mod), | ||
| 26423 | }); | ||
| 26424 | }, | 26672 | }, |
| 26425 | 26673 | ||
| 26426 | .Type => { | 26674 | .Type => { |
| ... | @@ -26436,7 +26684,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26436,7 +26684,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26436 | => return, | 26684 | => return, |
| 26437 | 26685 | ||
| 26438 | .Opaque => { | 26686 | .Opaque => { |
| 26439 | try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)}); | 26687 | try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(pt)}); |
| 26440 | }, | 26688 | }, |
| 26441 | 26689 | ||
| 26442 | .Array, .Vector => { | 26690 | .Array, .Vector => { |
| ... | @@ -26453,7 +26701,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -26453,7 +26701,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26453 | .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}), | 26701 | .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}), |
| 26454 | else => {}, | 26702 | else => {}, |
| 26455 | } | 26703 | } |
| 26456 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(mod)) { | 26704 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(pt)) { |
| 26457 | try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{}); | 26705 | try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{}); |
| 26458 | } | 26706 | } |
| 26459 | return; | 26707 | return; |
| ... | @@ -26526,7 +26774,8 @@ fn validateExternType( | ... | @@ -26526,7 +26774,8 @@ fn validateExternType( |
| 26526 | ty: Type, | 26774 | ty: Type, |
| 26527 | position: ExternPosition, | 26775 | position: ExternPosition, |
| 26528 | ) !bool { | 26776 | ) !bool { |
| 26529 | const mod = sema.mod; | 26777 | const pt = sema.pt; |
| 26778 | const mod = pt.zcu; | ||
| 26530 | switch (ty.zigTypeTag(mod)) { | 26779 | switch (ty.zigTypeTag(mod)) { |
| 26531 | .Type, | 26780 | .Type, |
| 26532 | .ComptimeFloat, | 26781 | .ComptimeFloat, |
| ... | @@ -26557,7 +26806,7 @@ fn validateExternType( | ... | @@ -26557,7 +26806,7 @@ fn validateExternType( |
| 26557 | }, | 26806 | }, |
| 26558 | .Fn => { | 26807 | .Fn => { |
| 26559 | if (position != .other) return false; | 26808 | if (position != .other) return false; |
| 26560 | const target = sema.mod.getTarget(); | 26809 | const target = mod.getTarget(); |
| 26561 | // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI. | 26810 | // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI. |
| 26562 | // The goal is to experiment with more integrated CPU/GPU code. | 26811 | // The goal is to experiment with more integrated CPU/GPU code. |
| 26563 | if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) { | 26812 | if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) { |
| ... | @@ -26571,7 +26820,7 @@ fn validateExternType( | ... | @@ -26571,7 +26820,7 @@ fn validateExternType( |
| 26571 | .Struct, .Union => switch (ty.containerLayout(mod)) { | 26820 | .Struct, .Union => switch (ty.containerLayout(mod)) { |
| 26572 | .@"extern" => return true, | 26821 | .@"extern" => return true, |
| 26573 | .@"packed" => { | 26822 | .@"packed" => { |
| 26574 | const bit_size = try ty.bitSizeAdvanced(mod, .sema); | 26823 | const bit_size = try ty.bitSizeAdvanced(pt, .sema); |
| 26575 | switch (bit_size) { | 26824 | switch (bit_size) { |
| 26576 | 0, 8, 16, 32, 64, 128 => return true, | 26825 | 0, 8, 16, 32, 64, 128 => return true, |
| 26577 | else => return false, | 26826 | else => return false, |
| ... | @@ -26595,7 +26844,8 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -26595,7 +26844,8 @@ fn explainWhyTypeIsNotExtern( |
| 26595 | ty: Type, | 26844 | ty: Type, |
| 26596 | position: ExternPosition, | 26845 | position: ExternPosition, |
| 26597 | ) CompileError!void { | 26846 | ) CompileError!void { |
| 26598 | const mod = sema.mod; | 26847 | const pt = sema.pt; |
| 26848 | const mod = pt.zcu; | ||
| 26599 | switch (ty.zigTypeTag(mod)) { | 26849 | switch (ty.zigTypeTag(mod)) { |
| 26600 | .Opaque, | 26850 | .Opaque, |
| 26601 | .Bool, | 26851 | .Bool, |
| ... | @@ -26622,7 +26872,7 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -26622,7 +26872,7 @@ fn explainWhyTypeIsNotExtern( |
| 26622 | if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) { | 26872 | if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) { |
| 26623 | try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{}); | 26873 | try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{}); |
| 26624 | } else if (try sema.typeRequiresComptime(ty)) { | 26874 | } else if (try sema.typeRequiresComptime(ty)) { |
| 26625 | try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)}); | 26875 | try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(pt)}); |
| 26626 | try sema.explainWhyTypeIsComptime(msg, src_loc, ty); | 26876 | try sema.explainWhyTypeIsComptime(msg, src_loc, ty); |
| 26627 | } | 26877 | } |
| 26628 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other); | 26878 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other); |
| ... | @@ -26650,7 +26900,7 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -26650,7 +26900,7 @@ fn explainWhyTypeIsNotExtern( |
| 26650 | }, | 26900 | }, |
| 26651 | .Enum => { | 26901 | .Enum => { |
| 26652 | const tag_ty = ty.intTagType(mod); | 26902 | const tag_ty = ty.intTagType(mod); |
| 26653 | try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)}); | 26903 | try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(pt)}); |
| 26654 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); | 26904 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); |
| 26655 | }, | 26905 | }, |
| 26656 | .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}), | 26906 | .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}), |
| ... | @@ -26671,7 +26921,8 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -26671,7 +26921,8 @@ fn explainWhyTypeIsNotExtern( |
| 26671 | /// Returns true if `ty` is allowed in packed types. | 26921 | /// Returns true if `ty` is allowed in packed types. |
| 26672 | /// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only. | 26922 | /// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only. |
| 26673 | fn validatePackedType(sema: *Sema, ty: Type) !bool { | 26923 | fn validatePackedType(sema: *Sema, ty: Type) !bool { |
| 26674 | const zcu = sema.mod; | 26924 | const pt = sema.pt; |
| 26925 | const zcu = pt.zcu; | ||
| 26675 | return switch (ty.zigTypeTag(zcu)) { | 26926 | return switch (ty.zigTypeTag(zcu)) { |
| 26676 | .Type, | 26927 | .Type, |
| 26677 | .ComptimeFloat, | 26928 | .ComptimeFloat, |
| ... | @@ -26710,7 +26961,8 @@ fn explainWhyTypeIsNotPacked( | ... | @@ -26710,7 +26961,8 @@ fn explainWhyTypeIsNotPacked( |
| 26710 | src_loc: LazySrcLoc, | 26961 | src_loc: LazySrcLoc, |
| 26711 | ty: Type, | 26962 | ty: Type, |
| 26712 | ) CompileError!void { | 26963 | ) CompileError!void { |
| 26713 | const mod = sema.mod; | 26964 | const pt = sema.pt; |
| 26965 | const mod = pt.zcu; | ||
| 26714 | switch (ty.zigTypeTag(mod)) { | 26966 | switch (ty.zigTypeTag(mod)) { |
| 26715 | .Void, | 26967 | .Void, |
| 26716 | .Bool, | 26968 | .Bool, |
| ... | @@ -26750,10 +27002,11 @@ fn explainWhyTypeIsNotPacked( | ... | @@ -26750,10 +27002,11 @@ fn explainWhyTypeIsNotPacked( |
| 26750 | } | 27002 | } |
| 26751 | 27003 | ||
| 26752 | fn prepareSimplePanic(sema: *Sema) !void { | 27004 | fn prepareSimplePanic(sema: *Sema) !void { |
| 26753 | const mod = sema.mod; | 27005 | const pt = sema.pt; |
| 27006 | const mod = pt.zcu; | ||
| 26754 | 27007 | ||
| 26755 | if (mod.panic_func_index == .none) { | 27008 | if (mod.panic_func_index == .none) { |
| 26756 | const decl_index = (try mod.getBuiltinDecl("panic")); | 27009 | const decl_index = (try pt.getBuiltinDecl("panic")); |
| 26757 | // decl_index may be an alias; we must find the decl that actually | 27010 | // decl_index may be an alias; we must find the decl that actually |
| 26758 | // owns the function. | 27011 | // owns the function. |
| 26759 | try sema.ensureDeclAnalyzed(decl_index); | 27012 | try sema.ensureDeclAnalyzed(decl_index); |
| ... | @@ -26766,17 +27019,17 @@ fn prepareSimplePanic(sema: *Sema) !void { | ... | @@ -26766,17 +27019,17 @@ fn prepareSimplePanic(sema: *Sema) !void { |
| 26766 | } | 27019 | } |
| 26767 | 27020 | ||
| 26768 | if (mod.null_stack_trace == .none) { | 27021 | if (mod.null_stack_trace == .none) { |
| 26769 | const stack_trace_ty = try mod.getBuiltinType("StackTrace"); | 27022 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 26770 | try stack_trace_ty.resolveFields(mod); | 27023 | try stack_trace_ty.resolveFields(pt); |
| 26771 | const target = mod.getTarget(); | 27024 | const target = mod.getTarget(); |
| 26772 | const ptr_stack_trace_ty = try mod.ptrTypeSema(.{ | 27025 | const ptr_stack_trace_ty = try pt.ptrTypeSema(.{ |
| 26773 | .child = stack_trace_ty.toIntern(), | 27026 | .child = stack_trace_ty.toIntern(), |
| 26774 | .flags = .{ | 27027 | .flags = .{ |
| 26775 | .address_space = target_util.defaultAddressSpace(target, .global_constant), | 27028 | .address_space = target_util.defaultAddressSpace(target, .global_constant), |
| 26776 | }, | 27029 | }, |
| 26777 | }); | 27030 | }); |
| 26778 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); | 27031 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| 26779 | mod.null_stack_trace = try mod.intern(.{ .opt = .{ | 27032 | mod.null_stack_trace = try pt.intern(.{ .opt = .{ |
| 26780 | .ty = opt_ptr_stack_trace_ty.toIntern(), | 27033 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| 26781 | .val = .none, | 27034 | .val = .none, |
| 26782 | } }); | 27035 | } }); |
| ... | @@ -26787,13 +27040,14 @@ fn prepareSimplePanic(sema: *Sema) !void { | ... | @@ -26787,13 +27040,14 @@ fn prepareSimplePanic(sema: *Sema) !void { |
| 26787 | /// instructions. This function ensures the panic function will be available to | 27040 | /// instructions. This function ensures the panic function will be available to |
| 26788 | /// be called during that time. | 27041 | /// be called during that time. |
| 26789 | fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex { | 27042 | fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex { |
| 26790 | const mod = sema.mod; | 27043 | const pt = sema.pt; |
| 27044 | const mod = pt.zcu; | ||
| 26791 | const gpa = sema.gpa; | 27045 | const gpa = sema.gpa; |
| 26792 | if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; | 27046 | if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; |
| 26793 | 27047 | ||
| 26794 | try sema.prepareSimplePanic(); | 27048 | try sema.prepareSimplePanic(); |
| 26795 | 27049 | ||
| 26796 | const panic_messages_ty = try mod.getBuiltinType("panic_messages"); | 27050 | const panic_messages_ty = try pt.getBuiltinType("panic_messages"); |
| 26797 | const msg_decl_index = (sema.namespaceLookup( | 27051 | const msg_decl_index = (sema.namespaceLookup( |
| 26798 | block, | 27052 | block, |
| 26799 | LazySrcLoc.unneeded, | 27053 | LazySrcLoc.unneeded, |
| ... | @@ -26892,7 +27146,8 @@ fn addSafetyCheckExtra( | ... | @@ -26892,7 +27146,8 @@ fn addSafetyCheckExtra( |
| 26892 | } | 27146 | } |
| 26893 | 27147 | ||
| 26894 | fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void { | 27148 | fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void { |
| 26895 | const mod = sema.mod; | 27149 | const pt = sema.pt; |
| 27150 | const mod = pt.zcu; | ||
| 26896 | 27151 | ||
| 26897 | if (!mod.backendSupportsFeature(.panic_fn)) { | 27152 | if (!mod.backendSupportsFeature(.panic_fn)) { |
| 26898 | _ = try block.addNoOp(.trap); | 27153 | _ = try block.addNoOp(.trap); |
| ... | @@ -26905,8 +27160,8 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst. | ... | @@ -26905,8 +27160,8 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst. |
| 26905 | const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl); | 27160 | const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl); |
| 26906 | const null_stack_trace = Air.internedToRef(mod.null_stack_trace); | 27161 | const null_stack_trace = Air.internedToRef(mod.null_stack_trace); |
| 26907 | 27162 | ||
| 26908 | const opt_usize_ty = try mod.optionalType(.usize_type); | 27163 | const opt_usize_ty = try pt.optionalType(.usize_type); |
| 26909 | const null_ret_addr = Air.internedToRef((try mod.intern(.{ .opt = .{ | 27164 | const null_ret_addr = Air.internedToRef((try pt.intern(.{ .opt = .{ |
| 26910 | .ty = opt_usize_ty.toIntern(), | 27165 | .ty = opt_usize_ty.toIntern(), |
| 26911 | .val = .none, | 27166 | .val = .none, |
| 26912 | } }))); | 27167 | } }))); |
| ... | @@ -26921,9 +27176,10 @@ fn panicUnwrapError( | ... | @@ -26921,9 +27176,10 @@ fn panicUnwrapError( |
| 26921 | unwrap_err_tag: Air.Inst.Tag, | 27176 | unwrap_err_tag: Air.Inst.Tag, |
| 26922 | is_non_err_tag: Air.Inst.Tag, | 27177 | is_non_err_tag: Air.Inst.Tag, |
| 26923 | ) !void { | 27178 | ) !void { |
| 27179 | const pt = sema.pt; | ||
| 26924 | assert(!parent_block.is_comptime); | 27180 | assert(!parent_block.is_comptime); |
| 26925 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); | 27181 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); |
| 26926 | if (!sema.mod.comp.formatted_panics) { | 27182 | if (!pt.zcu.comp.formatted_panics) { |
| 26927 | return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error); | 27183 | return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error); |
| 26928 | } | 27184 | } |
| 26929 | const gpa = sema.gpa; | 27185 | const gpa = sema.gpa; |
| ... | @@ -26942,10 +27198,10 @@ fn panicUnwrapError( | ... | @@ -26942,10 +27198,10 @@ fn panicUnwrapError( |
| 26942 | defer fail_block.instructions.deinit(gpa); | 27198 | defer fail_block.instructions.deinit(gpa); |
| 26943 | 27199 | ||
| 26944 | { | 27200 | { |
| 26945 | if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) { | 27201 | if (!pt.zcu.backendSupportsFeature(.panic_unwrap_error)) { |
| 26946 | _ = try fail_block.addNoOp(.trap); | 27202 | _ = try fail_block.addNoOp(.trap); |
| 26947 | } else { | 27203 | } else { |
| 26948 | const panic_fn = try sema.mod.getBuiltin("panicUnwrapError"); | 27204 | const panic_fn = try sema.pt.getBuiltin("panicUnwrapError"); |
| 26949 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); | 27205 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); |
| 26950 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); | 27206 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); |
| 26951 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; | 27207 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; |
| ... | @@ -26965,7 +27221,7 @@ fn panicIndexOutOfBounds( | ... | @@ -26965,7 +27221,7 @@ fn panicIndexOutOfBounds( |
| 26965 | ) !void { | 27221 | ) !void { |
| 26966 | assert(!parent_block.is_comptime); | 27222 | assert(!parent_block.is_comptime); |
| 26967 | const ok = try parent_block.addBinOp(cmp_op, index, len); | 27223 | const ok = try parent_block.addBinOp(cmp_op, index, len); |
| 26968 | if (!sema.mod.comp.formatted_panics) { | 27224 | if (!sema.pt.zcu.comp.formatted_panics) { |
| 26969 | return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds); | 27225 | return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds); |
| 26970 | } | 27226 | } |
| 26971 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len }); | 27227 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len }); |
| ... | @@ -26980,7 +27236,7 @@ fn panicInactiveUnionField( | ... | @@ -26980,7 +27236,7 @@ fn panicInactiveUnionField( |
| 26980 | ) !void { | 27236 | ) !void { |
| 26981 | assert(!parent_block.is_comptime); | 27237 | assert(!parent_block.is_comptime); |
| 26982 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 27238 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 26983 | if (!sema.mod.comp.formatted_panics) { | 27239 | if (!sema.pt.zcu.comp.formatted_panics) { |
| 26984 | return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field); | 27240 | return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field); |
| 26985 | } | 27241 | } |
| 26986 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); | 27242 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); |
| ... | @@ -26996,7 +27252,8 @@ fn panicSentinelMismatch( | ... | @@ -26996,7 +27252,8 @@ fn panicSentinelMismatch( |
| 26996 | sentinel_index: Air.Inst.Ref, | 27252 | sentinel_index: Air.Inst.Ref, |
| 26997 | ) !void { | 27253 | ) !void { |
| 26998 | assert(!parent_block.is_comptime); | 27254 | assert(!parent_block.is_comptime); |
| 26999 | const mod = sema.mod; | 27255 | const pt = sema.pt; |
| 27256 | const mod = pt.zcu; | ||
| 27000 | const expected_sentinel_val = maybe_sentinel orelse return; | 27257 | const expected_sentinel_val = maybe_sentinel orelse return; |
| 27001 | const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern()); | 27258 | const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern()); |
| 27002 | 27259 | ||
| ... | @@ -27004,7 +27261,7 @@ fn panicSentinelMismatch( | ... | @@ -27004,7 +27261,7 @@ fn panicSentinelMismatch( |
| 27004 | const actual_sentinel = if (ptr_ty.isSlice(mod)) | 27261 | const actual_sentinel = if (ptr_ty.isSlice(mod)) |
| 27005 | try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index) | 27262 | try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index) |
| 27006 | else blk: { | 27263 | else blk: { |
| 27007 | const elem_ptr_ty = try ptr_ty.elemPtrType(null, mod); | 27264 | const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt); |
| 27008 | const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty); | 27265 | const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty); |
| 27009 | break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr); | 27266 | break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr); |
| 27010 | }; | 27267 | }; |
| ... | @@ -27022,13 +27279,13 @@ fn panicSentinelMismatch( | ... | @@ -27022,13 +27279,13 @@ fn panicSentinelMismatch( |
| 27022 | } else if (sentinel_ty.isSelfComparable(mod, true)) | 27279 | } else if (sentinel_ty.isSelfComparable(mod, true)) |
| 27023 | try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel) | 27280 | try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel) |
| 27024 | else { | 27281 | else { |
| 27025 | const panic_fn = try mod.getBuiltin("checkNonScalarSentinel"); | 27282 | const panic_fn = try pt.getBuiltin("checkNonScalarSentinel"); |
| 27026 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; | 27283 | const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel }; |
| 27027 | try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check"); | 27284 | try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check"); |
| 27028 | return; | 27285 | return; |
| 27029 | }; | 27286 | }; |
| 27030 | 27287 | ||
| 27031 | if (!sema.mod.comp.formatted_panics) { | 27288 | if (!pt.zcu.comp.formatted_panics) { |
| 27032 | return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch); | 27289 | return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch); |
| 27033 | } | 27290 | } |
| 27034 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); | 27291 | try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); |
| ... | @@ -27042,7 +27299,9 @@ fn safetyCheckFormatted( | ... | @@ -27042,7 +27299,9 @@ fn safetyCheckFormatted( |
| 27042 | func: []const u8, | 27299 | func: []const u8, |
| 27043 | args: []const Air.Inst.Ref, | 27300 | args: []const Air.Inst.Ref, |
| 27044 | ) CompileError!void { | 27301 | ) CompileError!void { |
| 27045 | assert(sema.mod.comp.formatted_panics); | 27302 | const pt = sema.pt; |
| 27303 | const zcu = pt.zcu; | ||
| 27304 | assert(zcu.comp.formatted_panics); | ||
| 27046 | const gpa = sema.gpa; | 27305 | const gpa = sema.gpa; |
| 27047 | 27306 | ||
| 27048 | var fail_block: Block = .{ | 27307 | var fail_block: Block = .{ |
| ... | @@ -27058,10 +27317,10 @@ fn safetyCheckFormatted( | ... | @@ -27058,10 +27317,10 @@ fn safetyCheckFormatted( |
| 27058 | 27317 | ||
| 27059 | defer fail_block.instructions.deinit(gpa); | 27318 | defer fail_block.instructions.deinit(gpa); |
| 27060 | 27319 | ||
| 27061 | if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) { | 27320 | if (!zcu.backendSupportsFeature(.safety_check_formatted)) { |
| 27062 | _ = try fail_block.addNoOp(.trap); | 27321 | _ = try fail_block.addNoOp(.trap); |
| 27063 | } else { | 27322 | } else { |
| 27064 | const panic_fn = try sema.mod.getBuiltin(func); | 27323 | const panic_fn = try pt.getBuiltin(func); |
| 27065 | try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check"); | 27324 | try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check"); |
| 27066 | } | 27325 | } |
| 27067 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 27326 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | @@ -27102,7 +27361,8 @@ fn fieldVal( | ... | @@ -27102,7 +27361,8 @@ fn fieldVal( |
| 27102 | // When editing this function, note that there is corresponding logic to be edited | 27361 | // When editing this function, note that there is corresponding logic to be edited |
| 27103 | // in `fieldPtr`. This function takes a value and returns a value. | 27362 | // in `fieldPtr`. This function takes a value and returns a value. |
| 27104 | 27363 | ||
| 27105 | const mod = sema.mod; | 27364 | const pt = sema.pt; |
| 27365 | const mod = pt.zcu; | ||
| 27106 | const ip = &mod.intern_pool; | 27366 | const ip = &mod.intern_pool; |
| 27107 | const object_src = src; // TODO better source location | 27367 | const object_src = src; // TODO better source location |
| 27108 | const object_ty = sema.typeOf(object); | 27368 | const object_ty = sema.typeOf(object); |
| ... | @@ -27120,10 +27380,10 @@ fn fieldVal( | ... | @@ -27120,10 +27380,10 @@ fn fieldVal( |
| 27120 | switch (inner_ty.zigTypeTag(mod)) { | 27380 | switch (inner_ty.zigTypeTag(mod)) { |
| 27121 | .Array => { | 27381 | .Array => { |
| 27122 | if (field_name.eqlSlice("len", ip)) { | 27382 | if (field_name.eqlSlice("len", ip)) { |
| 27123 | return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern()); | 27383 | return Air.internedToRef((try pt.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern()); |
| 27124 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { | 27384 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27125 | const ptr_info = object_ty.ptrInfo(mod); | 27385 | const ptr_info = object_ty.ptrInfo(mod); |
| 27126 | const result_ty = try mod.ptrTypeSema(.{ | 27386 | const result_ty = try pt.ptrTypeSema(.{ |
| 27127 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), | 27387 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), |
| 27128 | .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none, | 27388 | .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| 27129 | .flags = .{ | 27389 | .flags = .{ |
| ... | @@ -27143,7 +27403,7 @@ fn fieldVal( | ... | @@ -27143,7 +27403,7 @@ fn fieldVal( |
| 27143 | block, | 27403 | block, |
| 27144 | field_name_src, | 27404 | field_name_src, |
| 27145 | "no member named '{}' in '{}'", | 27405 | "no member named '{}' in '{}'", |
| 27146 | .{ field_name.fmt(ip), object_ty.fmt(mod) }, | 27406 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27147 | ); | 27407 | ); |
| 27148 | } | 27408 | } |
| 27149 | }, | 27409 | }, |
| ... | @@ -27167,7 +27427,7 @@ fn fieldVal( | ... | @@ -27167,7 +27427,7 @@ fn fieldVal( |
| 27167 | block, | 27427 | block, |
| 27168 | field_name_src, | 27428 | field_name_src, |
| 27169 | "no member named '{}' in '{}'", | 27429 | "no member named '{}' in '{}'", |
| 27170 | .{ field_name.fmt(ip), object_ty.fmt(mod) }, | 27430 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27171 | ); | 27431 | ); |
| 27172 | } | 27432 | } |
| 27173 | } | 27433 | } |
| ... | @@ -27194,7 +27454,7 @@ fn fieldVal( | ... | @@ -27194,7 +27454,7 @@ fn fieldVal( |
| 27194 | .error_set_type => |error_set_type| blk: { | 27454 | .error_set_type => |error_set_type| blk: { |
| 27195 | if (error_set_type.nameIndex(ip, field_name) != null) break :blk; | 27455 | if (error_set_type.nameIndex(ip, field_name) != null) break :blk; |
| 27196 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ | 27456 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ |
| 27197 | field_name.fmt(ip), child_type.fmt(mod), | 27457 | field_name.fmt(ip), child_type.fmt(pt), |
| 27198 | }); | 27458 | }); |
| 27199 | }, | 27459 | }, |
| 27200 | .inferred_error_set_type => { | 27460 | .inferred_error_set_type => { |
| ... | @@ -27210,8 +27470,8 @@ fn fieldVal( | ... | @@ -27210,8 +27470,8 @@ fn fieldVal( |
| 27210 | const error_set_type = if (!child_type.isAnyError(mod)) | 27470 | const error_set_type = if (!child_type.isAnyError(mod)) |
| 27211 | child_type | 27471 | child_type |
| 27212 | else | 27472 | else |
| 27213 | try mod.singleErrorSetType(field_name); | 27473 | try pt.singleErrorSetType(field_name); |
| 27214 | return Air.internedToRef((try mod.intern(.{ .err = .{ | 27474 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 27215 | .ty = error_set_type.toIntern(), | 27475 | .ty = error_set_type.toIntern(), |
| 27216 | .name = field_name, | 27476 | .name = field_name, |
| 27217 | } }))); | 27477 | } }))); |
| ... | @@ -27220,11 +27480,11 @@ fn fieldVal( | ... | @@ -27220,11 +27480,11 @@ fn fieldVal( |
| 27220 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | 27480 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { |
| 27221 | return inst; | 27481 | return inst; |
| 27222 | } | 27482 | } |
| 27223 | try child_type.resolveFields(mod); | 27483 | try child_type.resolveFields(pt); |
| 27224 | if (child_type.unionTagType(mod)) |enum_ty| { | 27484 | if (child_type.unionTagType(mod)) |enum_ty| { |
| 27225 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| { | 27485 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| { |
| 27226 | const field_index: u32 = @intCast(field_index_usize); | 27486 | const field_index: u32 = @intCast(field_index_usize); |
| 27227 | return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern()); | 27487 | return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern()); |
| 27228 | } | 27488 | } |
| 27229 | } | 27489 | } |
| 27230 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | 27490 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| ... | @@ -27236,7 +27496,7 @@ fn fieldVal( | ... | @@ -27236,7 +27496,7 @@ fn fieldVal( |
| 27236 | const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse | 27496 | const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse |
| 27237 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | 27497 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27238 | const field_index: u32 = @intCast(field_index_usize); | 27498 | const field_index: u32 = @intCast(field_index_usize); |
| 27239 | const enum_val = try mod.enumValueFieldIndex(child_type, field_index); | 27499 | const enum_val = try pt.enumValueFieldIndex(child_type, field_index); |
| 27240 | return Air.internedToRef(enum_val.toIntern()); | 27500 | return Air.internedToRef(enum_val.toIntern()); |
| 27241 | }, | 27501 | }, |
| 27242 | .Struct, .Opaque => { | 27502 | .Struct, .Opaque => { |
| ... | @@ -27247,7 +27507,7 @@ fn fieldVal( | ... | @@ -27247,7 +27507,7 @@ fn fieldVal( |
| 27247 | }, | 27507 | }, |
| 27248 | else => { | 27508 | else => { |
| 27249 | const msg = msg: { | 27509 | const msg = msg: { |
| 27250 | const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(mod)}); | 27510 | const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)}); |
| 27251 | errdefer msg.destroy(sema.gpa); | 27511 | errdefer msg.destroy(sema.gpa); |
| 27252 | if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | 27512 | if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); |
| 27253 | if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | 27513 | if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); |
| ... | @@ -27288,13 +27548,14 @@ fn fieldPtr( | ... | @@ -27288,13 +27548,14 @@ fn fieldPtr( |
| 27288 | // When editing this function, note that there is corresponding logic to be edited | 27548 | // When editing this function, note that there is corresponding logic to be edited |
| 27289 | // in `fieldVal`. This function takes a pointer and returns a pointer. | 27549 | // in `fieldVal`. This function takes a pointer and returns a pointer. |
| 27290 | 27550 | ||
| 27291 | const mod = sema.mod; | 27551 | const pt = sema.pt; |
| 27552 | const mod = pt.zcu; | ||
| 27292 | const ip = &mod.intern_pool; | 27553 | const ip = &mod.intern_pool; |
| 27293 | const object_ptr_src = src; // TODO better source location | 27554 | const object_ptr_src = src; // TODO better source location |
| 27294 | const object_ptr_ty = sema.typeOf(object_ptr); | 27555 | const object_ptr_ty = sema.typeOf(object_ptr); |
| 27295 | const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) { | 27556 | const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) { |
| 27296 | .Pointer => object_ptr_ty.childType(mod), | 27557 | .Pointer => object_ptr_ty.childType(mod), |
| 27297 | else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(mod)}), | 27558 | else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(pt)}), |
| 27298 | }; | 27559 | }; |
| 27299 | 27560 | ||
| 27300 | // Zig allows dereferencing a single pointer during field lookup. Note that | 27561 | // Zig allows dereferencing a single pointer during field lookup. Note that |
| ... | @@ -27310,11 +27571,11 @@ fn fieldPtr( | ... | @@ -27310,11 +27571,11 @@ fn fieldPtr( |
| 27310 | switch (inner_ty.zigTypeTag(mod)) { | 27571 | switch (inner_ty.zigTypeTag(mod)) { |
| 27311 | .Array => { | 27572 | .Array => { |
| 27312 | if (field_name.eqlSlice("len", ip)) { | 27573 | if (field_name.eqlSlice("len", ip)) { |
| 27313 | const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod)); | 27574 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod)); |
| 27314 | return anonDeclRef(sema, int_val.toIntern()); | 27575 | return anonDeclRef(sema, int_val.toIntern()); |
| 27315 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { | 27576 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27316 | const ptr_info = object_ty.ptrInfo(mod); | 27577 | const ptr_info = object_ty.ptrInfo(mod); |
| 27317 | const new_ptr_ty = try mod.ptrTypeSema(.{ | 27578 | const new_ptr_ty = try pt.ptrTypeSema(.{ |
| 27318 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), | 27579 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), |
| 27319 | .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none, | 27580 | .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| 27320 | .flags = .{ | 27581 | .flags = .{ |
| ... | @@ -27329,7 +27590,7 @@ fn fieldPtr( | ... | @@ -27329,7 +27590,7 @@ fn fieldPtr( |
| 27329 | .packed_offset = ptr_info.packed_offset, | 27590 | .packed_offset = ptr_info.packed_offset, |
| 27330 | }); | 27591 | }); |
| 27331 | const ptr_ptr_info = object_ptr_ty.ptrInfo(mod); | 27592 | const ptr_ptr_info = object_ptr_ty.ptrInfo(mod); |
| 27332 | const result_ty = try mod.ptrTypeSema(.{ | 27593 | const result_ty = try pt.ptrTypeSema(.{ |
| 27333 | .child = new_ptr_ty.toIntern(), | 27594 | .child = new_ptr_ty.toIntern(), |
| 27334 | .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | 27595 | .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, |
| 27335 | .flags = .{ | 27596 | .flags = .{ |
| ... | @@ -27348,7 +27609,7 @@ fn fieldPtr( | ... | @@ -27348,7 +27609,7 @@ fn fieldPtr( |
| 27348 | block, | 27609 | block, |
| 27349 | field_name_src, | 27610 | field_name_src, |
| 27350 | "no member named '{}' in '{}'", | 27611 | "no member named '{}' in '{}'", |
| 27351 | .{ field_name.fmt(ip), object_ty.fmt(mod) }, | 27612 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27352 | ); | 27613 | ); |
| 27353 | } | 27614 | } |
| 27354 | }, | 27615 | }, |
| ... | @@ -27363,7 +27624,7 @@ fn fieldPtr( | ... | @@ -27363,7 +27624,7 @@ fn fieldPtr( |
| 27363 | if (field_name.eqlSlice("ptr", ip)) { | 27624 | if (field_name.eqlSlice("ptr", ip)) { |
| 27364 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); | 27625 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); |
| 27365 | 27626 | ||
| 27366 | const result_ty = try mod.ptrTypeSema(.{ | 27627 | const result_ty = try pt.ptrTypeSema(.{ |
| 27367 | .child = slice_ptr_ty.toIntern(), | 27628 | .child = slice_ptr_ty.toIntern(), |
| 27368 | .flags = .{ | 27629 | .flags = .{ |
| 27369 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), | 27630 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), |
| ... | @@ -27373,7 +27634,7 @@ fn fieldPtr( | ... | @@ -27373,7 +27634,7 @@ fn fieldPtr( |
| 27373 | }); | 27634 | }); |
| 27374 | 27635 | ||
| 27375 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { | 27636 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| 27376 | return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, mod)).toIntern()); | 27637 | return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, pt)).toIntern()); |
| 27377 | } | 27638 | } |
| 27378 | try sema.requireRuntimeBlock(block, src, null); | 27639 | try sema.requireRuntimeBlock(block, src, null); |
| 27379 | 27640 | ||
| ... | @@ -27381,7 +27642,7 @@ fn fieldPtr( | ... | @@ -27381,7 +27642,7 @@ fn fieldPtr( |
| 27381 | try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr); | 27642 | try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr); |
| 27382 | return field_ptr; | 27643 | return field_ptr; |
| 27383 | } else if (field_name.eqlSlice("len", ip)) { | 27644 | } else if (field_name.eqlSlice("len", ip)) { |
| 27384 | const result_ty = try mod.ptrTypeSema(.{ | 27645 | const result_ty = try pt.ptrTypeSema(.{ |
| 27385 | .child = .usize_type, | 27646 | .child = .usize_type, |
| 27386 | .flags = .{ | 27647 | .flags = .{ |
| 27387 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), | 27648 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), |
| ... | @@ -27391,7 +27652,7 @@ fn fieldPtr( | ... | @@ -27391,7 +27652,7 @@ fn fieldPtr( |
| 27391 | }); | 27652 | }); |
| 27392 | 27653 | ||
| 27393 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { | 27654 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| 27394 | return Air.internedToRef((try val.ptrField(Value.slice_len_index, mod)).toIntern()); | 27655 | return Air.internedToRef((try val.ptrField(Value.slice_len_index, pt)).toIntern()); |
| 27395 | } | 27656 | } |
| 27396 | try sema.requireRuntimeBlock(block, src, null); | 27657 | try sema.requireRuntimeBlock(block, src, null); |
| 27397 | 27658 | ||
| ... | @@ -27403,7 +27664,7 @@ fn fieldPtr( | ... | @@ -27403,7 +27664,7 @@ fn fieldPtr( |
| 27403 | block, | 27664 | block, |
| 27404 | field_name_src, | 27665 | field_name_src, |
| 27405 | "no member named '{}' in '{}'", | 27666 | "no member named '{}' in '{}'", |
| 27406 | .{ field_name.fmt(ip), object_ty.fmt(mod) }, | 27667 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27407 | ); | 27668 | ); |
| 27408 | } | 27669 | } |
| 27409 | }, | 27670 | }, |
| ... | @@ -27433,7 +27694,7 @@ fn fieldPtr( | ... | @@ -27433,7 +27694,7 @@ fn fieldPtr( |
| 27433 | break :blk; | 27694 | break :blk; |
| 27434 | } | 27695 | } |
| 27435 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ | 27696 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ |
| 27436 | field_name.fmt(ip), child_type.fmt(mod), | 27697 | field_name.fmt(ip), child_type.fmt(pt), |
| 27437 | }); | 27698 | }); |
| 27438 | }, | 27699 | }, |
| 27439 | .inferred_error_set_type => { | 27700 | .inferred_error_set_type => { |
| ... | @@ -27449,8 +27710,8 @@ fn fieldPtr( | ... | @@ -27449,8 +27710,8 @@ fn fieldPtr( |
| 27449 | const error_set_type = if (!child_type.isAnyError(mod)) | 27710 | const error_set_type = if (!child_type.isAnyError(mod)) |
| 27450 | child_type | 27711 | child_type |
| 27451 | else | 27712 | else |
| 27452 | try mod.singleErrorSetType(field_name); | 27713 | try pt.singleErrorSetType(field_name); |
| 27453 | return anonDeclRef(sema, try mod.intern(.{ .err = .{ | 27714 | return anonDeclRef(sema, try pt.intern(.{ .err = .{ |
| 27454 | .ty = error_set_type.toIntern(), | 27715 | .ty = error_set_type.toIntern(), |
| 27455 | .name = field_name, | 27716 | .name = field_name, |
| 27456 | } })); | 27717 | } })); |
| ... | @@ -27459,11 +27720,11 @@ fn fieldPtr( | ... | @@ -27459,11 +27720,11 @@ fn fieldPtr( |
| 27459 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | 27720 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { |
| 27460 | return inst; | 27721 | return inst; |
| 27461 | } | 27722 | } |
| 27462 | try child_type.resolveFields(mod); | 27723 | try child_type.resolveFields(pt); |
| 27463 | if (child_type.unionTagType(mod)) |enum_ty| { | 27724 | if (child_type.unionTagType(mod)) |enum_ty| { |
| 27464 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { | 27725 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { |
| 27465 | const field_index_u32: u32 = @intCast(field_index); | 27726 | const field_index_u32: u32 = @intCast(field_index); |
| 27466 | const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32); | 27727 | const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32); |
| 27467 | return anonDeclRef(sema, idx_val.toIntern()); | 27728 | return anonDeclRef(sema, idx_val.toIntern()); |
| 27468 | } | 27729 | } |
| 27469 | } | 27730 | } |
| ... | @@ -27477,7 +27738,7 @@ fn fieldPtr( | ... | @@ -27477,7 +27738,7 @@ fn fieldPtr( |
| 27477 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | 27738 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27478 | }; | 27739 | }; |
| 27479 | const field_index_u32: u32 = @intCast(field_index); | 27740 | const field_index_u32: u32 = @intCast(field_index); |
| 27480 | const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32); | 27741 | const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32); |
| 27481 | return anonDeclRef(sema, idx_val.toIntern()); | 27742 | return anonDeclRef(sema, idx_val.toIntern()); |
| 27482 | }, | 27743 | }, |
| 27483 | .Struct, .Opaque => { | 27744 | .Struct, .Opaque => { |
| ... | @@ -27486,7 +27747,7 @@ fn fieldPtr( | ... | @@ -27486,7 +27747,7 @@ fn fieldPtr( |
| 27486 | } | 27747 | } |
| 27487 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | 27748 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27488 | }, | 27749 | }, |
| 27489 | else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(mod)}), | 27750 | else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(pt)}), |
| 27490 | } | 27751 | } |
| 27491 | }, | 27752 | }, |
| 27492 | .Struct => { | 27753 | .Struct => { |
| ... | @@ -27533,14 +27794,15 @@ fn fieldCallBind( | ... | @@ -27533,14 +27794,15 @@ fn fieldCallBind( |
| 27533 | // When editing this function, note that there is corresponding logic to be edited | 27794 | // When editing this function, note that there is corresponding logic to be edited |
| 27534 | // in `fieldVal`. This function takes a pointer and returns a pointer. | 27795 | // in `fieldVal`. This function takes a pointer and returns a pointer. |
| 27535 | 27796 | ||
| 27536 | const mod = sema.mod; | 27797 | const pt = sema.pt; |
| 27798 | const mod = pt.zcu; | ||
| 27537 | const ip = &mod.intern_pool; | 27799 | const ip = &mod.intern_pool; |
| 27538 | const raw_ptr_src = src; // TODO better source location | 27800 | const raw_ptr_src = src; // TODO better source location |
| 27539 | const raw_ptr_ty = sema.typeOf(raw_ptr); | 27801 | const raw_ptr_ty = sema.typeOf(raw_ptr); |
| 27540 | const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C)) | 27802 | const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C)) |
| 27541 | raw_ptr_ty.childType(mod) | 27803 | raw_ptr_ty.childType(mod) |
| 27542 | else | 27804 | else |
| 27543 | return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(mod)}); | 27805 | return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)}); |
| 27544 | 27806 | ||
| 27545 | // Optionally dereference a second pointer to get the concrete type. | 27807 | // Optionally dereference a second pointer to get the concrete type. |
| 27546 | const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One; | 27808 | const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One; |
| ... | @@ -27554,7 +27816,7 @@ fn fieldCallBind( | ... | @@ -27554,7 +27816,7 @@ fn fieldCallBind( |
| 27554 | find_field: { | 27816 | find_field: { |
| 27555 | switch (concrete_ty.zigTypeTag(mod)) { | 27817 | switch (concrete_ty.zigTypeTag(mod)) { |
| 27556 | .Struct => { | 27818 | .Struct => { |
| 27557 | try concrete_ty.resolveFields(mod); | 27819 | try concrete_ty.resolveFields(pt); |
| 27558 | if (mod.typeToStruct(concrete_ty)) |struct_type| { | 27820 | if (mod.typeToStruct(concrete_ty)) |struct_type| { |
| 27559 | const field_index = struct_type.nameIndex(ip, field_name) orelse | 27821 | const field_index = struct_type.nameIndex(ip, field_name) orelse |
| 27560 | break :find_field; | 27822 | break :find_field; |
| ... | @@ -27563,7 +27825,7 @@ fn fieldCallBind( | ... | @@ -27563,7 +27825,7 @@ fn fieldCallBind( |
| 27563 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); | 27825 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); |
| 27564 | } else if (concrete_ty.isTuple(mod)) { | 27826 | } else if (concrete_ty.isTuple(mod)) { |
| 27565 | if (field_name.eqlSlice("len", ip)) { | 27827 | if (field_name.eqlSlice("len", ip)) { |
| 27566 | return .{ .direct = try mod.intRef(Type.usize, concrete_ty.structFieldCount(mod)) }; | 27828 | return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) }; |
| 27567 | } | 27829 | } |
| 27568 | if (field_name.toUnsigned(ip)) |field_index| { | 27830 | if (field_name.toUnsigned(ip)) |field_index| { |
| 27569 | if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field; | 27831 | if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field; |
| ... | @@ -27580,7 +27842,7 @@ fn fieldCallBind( | ... | @@ -27580,7 +27842,7 @@ fn fieldCallBind( |
| 27580 | } | 27842 | } |
| 27581 | }, | 27843 | }, |
| 27582 | .Union => { | 27844 | .Union => { |
| 27583 | try concrete_ty.resolveFields(mod); | 27845 | try concrete_ty.resolveFields(pt); |
| 27584 | const union_obj = mod.typeToUnion(concrete_ty).?; | 27846 | const union_obj = mod.typeToUnion(concrete_ty).?; |
| 27585 | _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field; | 27847 | _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field; |
| 27586 | const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false); | 27848 | const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false); |
| ... | @@ -27661,7 +27923,7 @@ fn fieldCallBind( | ... | @@ -27661,7 +27923,7 @@ fn fieldCallBind( |
| 27661 | const msg = msg: { | 27923 | const msg = msg: { |
| 27662 | const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{ | 27924 | const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{ |
| 27663 | field_name.fmt(ip), | 27925 | field_name.fmt(ip), |
| 27664 | concrete_ty.fmt(mod), | 27926 | concrete_ty.fmt(pt), |
| 27665 | }); | 27927 | }); |
| 27666 | errdefer msg.destroy(sema.gpa); | 27928 | errdefer msg.destroy(sema.gpa); |
| 27667 | try sema.addDeclaredHereNote(msg, concrete_ty); | 27929 | try sema.addDeclaredHereNote(msg, concrete_ty); |
| ... | @@ -27689,8 +27951,9 @@ fn finishFieldCallBind( | ... | @@ -27689,8 +27951,9 @@ fn finishFieldCallBind( |
| 27689 | field_index: u32, | 27951 | field_index: u32, |
| 27690 | object_ptr: Air.Inst.Ref, | 27952 | object_ptr: Air.Inst.Ref, |
| 27691 | ) CompileError!ResolvedFieldCallee { | 27953 | ) CompileError!ResolvedFieldCallee { |
| 27692 | const mod = sema.mod; | 27954 | const pt = sema.pt; |
| 27693 | const ptr_field_ty = try mod.ptrTypeSema(.{ | 27955 | const mod = pt.zcu; |
| 27956 | const ptr_field_ty = try pt.ptrTypeSema(.{ | ||
| 27694 | .child = field_ty.toIntern(), | 27957 | .child = field_ty.toIntern(), |
| 27695 | .flags = .{ | 27958 | .flags = .{ |
| 27696 | .is_const = !ptr_ty.ptrIsMutable(mod), | 27959 | .is_const = !ptr_ty.ptrIsMutable(mod), |
| ... | @@ -27701,14 +27964,14 @@ fn finishFieldCallBind( | ... | @@ -27701,14 +27964,14 @@ fn finishFieldCallBind( |
| 27701 | const container_ty = ptr_ty.childType(mod); | 27964 | const container_ty = ptr_ty.childType(mod); |
| 27702 | if (container_ty.zigTypeTag(mod) == .Struct) { | 27965 | if (container_ty.zigTypeTag(mod) == .Struct) { |
| 27703 | if (container_ty.structFieldIsComptime(field_index, mod)) { | 27966 | if (container_ty.structFieldIsComptime(field_index, mod)) { |
| 27704 | try container_ty.resolveStructFieldInits(mod); | 27967 | try container_ty.resolveStructFieldInits(pt); |
| 27705 | const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?; | 27968 | const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?; |
| 27706 | return .{ .direct = Air.internedToRef(default_val.toIntern()) }; | 27969 | return .{ .direct = Air.internedToRef(default_val.toIntern()) }; |
| 27707 | } | 27970 | } |
| 27708 | } | 27971 | } |
| 27709 | 27972 | ||
| 27710 | if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| { | 27973 | if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| { |
| 27711 | const ptr_val = try struct_ptr_val.ptrField(field_index, mod); | 27974 | const ptr_val = try struct_ptr_val.ptrField(field_index, pt); |
| 27712 | const pointer = Air.internedToRef(ptr_val.toIntern()); | 27975 | const pointer = Air.internedToRef(ptr_val.toIntern()); |
| 27713 | return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) }; | 27976 | return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) }; |
| 27714 | } | 27977 | } |
| ... | @@ -27725,7 +27988,8 @@ fn namespaceLookup( | ... | @@ -27725,7 +27988,8 @@ fn namespaceLookup( |
| 27725 | opt_namespace: InternPool.OptionalNamespaceIndex, | 27988 | opt_namespace: InternPool.OptionalNamespaceIndex, |
| 27726 | decl_name: InternPool.NullTerminatedString, | 27989 | decl_name: InternPool.NullTerminatedString, |
| 27727 | ) CompileError!?InternPool.DeclIndex { | 27990 | ) CompileError!?InternPool.DeclIndex { |
| 27728 | const mod = sema.mod; | 27991 | const pt = sema.pt; |
| 27992 | const mod = pt.zcu; | ||
| 27729 | const gpa = sema.gpa; | 27993 | const gpa = sema.gpa; |
| 27730 | if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| { | 27994 | if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| { |
| 27731 | const decl = mod.declPtr(decl_index); | 27995 | const decl = mod.declPtr(decl_index); |
| ... | @@ -27780,16 +28044,17 @@ fn structFieldPtr( | ... | @@ -27780,16 +28044,17 @@ fn structFieldPtr( |
| 27780 | struct_ty: Type, | 28044 | struct_ty: Type, |
| 27781 | initializing: bool, | 28045 | initializing: bool, |
| 27782 | ) CompileError!Air.Inst.Ref { | 28046 | ) CompileError!Air.Inst.Ref { |
| 27783 | const mod = sema.mod; | 28047 | const pt = sema.pt; |
| 28048 | const mod = pt.zcu; | ||
| 27784 | const ip = &mod.intern_pool; | 28049 | const ip = &mod.intern_pool; |
| 27785 | assert(struct_ty.zigTypeTag(mod) == .Struct); | 28050 | assert(struct_ty.zigTypeTag(mod) == .Struct); |
| 27786 | 28051 | ||
| 27787 | try struct_ty.resolveFields(mod); | 28052 | try struct_ty.resolveFields(pt); |
| 27788 | try struct_ty.resolveLayout(mod); | 28053 | try struct_ty.resolveLayout(pt); |
| 27789 | 28054 | ||
| 27790 | if (struct_ty.isTuple(mod)) { | 28055 | if (struct_ty.isTuple(mod)) { |
| 27791 | if (field_name.eqlSlice("len", ip)) { | 28056 | if (field_name.eqlSlice("len", ip)) { |
| 27792 | const len_inst = try mod.intRef(Type.usize, struct_ty.structFieldCount(mod)); | 28057 | const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(mod)); |
| 27793 | return sema.analyzeRef(block, src, len_inst); | 28058 | return sema.analyzeRef(block, src, len_inst); |
| 27794 | } | 28059 | } |
| 27795 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); | 28060 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); |
| ... | @@ -27817,14 +28082,15 @@ fn structFieldPtrByIndex( | ... | @@ -27817,14 +28082,15 @@ fn structFieldPtrByIndex( |
| 27817 | struct_ty: Type, | 28082 | struct_ty: Type, |
| 27818 | initializing: bool, | 28083 | initializing: bool, |
| 27819 | ) CompileError!Air.Inst.Ref { | 28084 | ) CompileError!Air.Inst.Ref { |
| 27820 | const mod = sema.mod; | 28085 | const pt = sema.pt; |
| 28086 | const mod = pt.zcu; | ||
| 27821 | const ip = &mod.intern_pool; | 28087 | const ip = &mod.intern_pool; |
| 27822 | if (struct_ty.isAnonStruct(mod)) { | 28088 | if (struct_ty.isAnonStruct(mod)) { |
| 27823 | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing); | 28089 | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing); |
| 27824 | } | 28090 | } |
| 27825 | 28091 | ||
| 27826 | if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { | 28092 | if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { |
| 27827 | const val = try struct_ptr_val.ptrField(field_index, mod); | 28093 | const val = try struct_ptr_val.ptrField(field_index, pt); |
| 27828 | return Air.internedToRef(val.toIntern()); | 28094 | return Air.internedToRef(val.toIntern()); |
| 27829 | } | 28095 | } |
| 27830 | 28096 | ||
| ... | @@ -27848,7 +28114,7 @@ fn structFieldPtrByIndex( | ... | @@ -27848,7 +28114,7 @@ fn structFieldPtrByIndex( |
| 27848 | try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child)); | 28114 | try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child)); |
| 27849 | 28115 | ||
| 27850 | if (struct_type.layout == .@"packed") { | 28116 | if (struct_type.layout == .@"packed") { |
| 27851 | switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, mod)) { | 28117 | switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt)) { |
| 27852 | .bit_ptr => |packed_offset| { | 28118 | .bit_ptr => |packed_offset| { |
| 27853 | ptr_ty_data.flags.alignment = parent_align; | 28119 | ptr_ty_data.flags.alignment = parent_align; |
| 27854 | ptr_ty_data.packed_offset = packed_offset; | 28120 | ptr_ty_data.packed_offset = packed_offset; |
| ... | @@ -27861,14 +28127,14 @@ fn structFieldPtrByIndex( | ... | @@ -27861,14 +28127,14 @@ fn structFieldPtrByIndex( |
| 27861 | // For extern structs, field alignment might be bigger than type's | 28127 | // For extern structs, field alignment might be bigger than type's |
| 27862 | // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the | 28128 | // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the |
| 27863 | // second field is aligned as u32. | 28129 | // second field is aligned as u32. |
| 27864 | const field_offset = struct_ty.structFieldOffset(field_index, mod); | 28130 | const field_offset = struct_ty.structFieldOffset(field_index, pt); |
| 27865 | ptr_ty_data.flags.alignment = if (parent_align == .none) | 28131 | ptr_ty_data.flags.alignment = if (parent_align == .none) |
| 27866 | .none | 28132 | .none |
| 27867 | else | 28133 | else |
| 27868 | @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset))); | 28134 | @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset))); |
| 27869 | } else { | 28135 | } else { |
| 27870 | // Our alignment is capped at the field alignment. | 28136 | // Our alignment is capped at the field alignment. |
| 27871 | const field_align = try mod.structFieldAlignmentAdvanced( | 28137 | const field_align = try pt.structFieldAlignmentAdvanced( |
| 27872 | struct_type.fieldAlign(ip, field_index), | 28138 | struct_type.fieldAlign(ip, field_index), |
| 27873 | Type.fromInterned(field_ty), | 28139 | Type.fromInterned(field_ty), |
| 27874 | struct_type.layout, | 28140 | struct_type.layout, |
| ... | @@ -27880,11 +28146,11 @@ fn structFieldPtrByIndex( | ... | @@ -27880,11 +28146,11 @@ fn structFieldPtrByIndex( |
| 27880 | field_align.min(parent_align); | 28146 | field_align.min(parent_align); |
| 27881 | } | 28147 | } |
| 27882 | 28148 | ||
| 27883 | const ptr_field_ty = try mod.ptrTypeSema(ptr_ty_data); | 28149 | const ptr_field_ty = try pt.ptrTypeSema(ptr_ty_data); |
| 27884 | 28150 | ||
| 27885 | if (struct_type.fieldIsComptime(ip, field_index)) { | 28151 | if (struct_type.fieldIsComptime(ip, field_index)) { |
| 27886 | try struct_ty.resolveStructFieldInits(mod); | 28152 | try struct_ty.resolveStructFieldInits(pt); |
| 27887 | const val = try mod.intern(.{ .ptr = .{ | 28153 | const val = try pt.intern(.{ .ptr = .{ |
| 27888 | .ty = ptr_field_ty.toIntern(), | 28154 | .ty = ptr_field_ty.toIntern(), |
| 27889 | .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] }, | 28155 | .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] }, |
| 27890 | .byte_offset = 0, | 28156 | .byte_offset = 0, |
| ... | @@ -27905,11 +28171,12 @@ fn structFieldVal( | ... | @@ -27905,11 +28171,12 @@ fn structFieldVal( |
| 27905 | field_name_src: LazySrcLoc, | 28171 | field_name_src: LazySrcLoc, |
| 27906 | struct_ty: Type, | 28172 | struct_ty: Type, |
| 27907 | ) CompileError!Air.Inst.Ref { | 28173 | ) CompileError!Air.Inst.Ref { |
| 27908 | const mod = sema.mod; | 28174 | const pt = sema.pt; |
| 28175 | const mod = pt.zcu; | ||
| 27909 | const ip = &mod.intern_pool; | 28176 | const ip = &mod.intern_pool; |
| 27910 | assert(struct_ty.zigTypeTag(mod) == .Struct); | 28177 | assert(struct_ty.zigTypeTag(mod) == .Struct); |
| 27911 | 28178 | ||
| 27912 | try struct_ty.resolveFields(mod); | 28179 | try struct_ty.resolveFields(pt); |
| 27913 | 28180 | ||
| 27914 | switch (ip.indexToKey(struct_ty.toIntern())) { | 28181 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| 27915 | .struct_type => { | 28182 | .struct_type => { |
| ... | @@ -27920,7 +28187,7 @@ fn structFieldVal( | ... | @@ -27920,7 +28187,7 @@ fn structFieldVal( |
| 27920 | const field_index = struct_type.nameIndex(ip, field_name) orelse | 28187 | const field_index = struct_type.nameIndex(ip, field_name) orelse |
| 27921 | return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name); | 28188 | return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name); |
| 27922 | if (struct_type.fieldIsComptime(ip, field_index)) { | 28189 | if (struct_type.fieldIsComptime(ip, field_index)) { |
| 27923 | try struct_ty.resolveStructFieldInits(mod); | 28190 | try struct_ty.resolveStructFieldInits(pt); |
| 27924 | return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]); | 28191 | return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]); |
| 27925 | } | 28192 | } |
| 27926 | 28193 | ||
| ... | @@ -27929,15 +28196,15 @@ fn structFieldVal( | ... | @@ -27929,15 +28196,15 @@ fn structFieldVal( |
| 27929 | return Air.internedToRef(field_val.toIntern()); | 28196 | return Air.internedToRef(field_val.toIntern()); |
| 27930 | 28197 | ||
| 27931 | if (try sema.resolveValue(struct_byval)) |struct_val| { | 28198 | if (try sema.resolveValue(struct_byval)) |struct_val| { |
| 27932 | if (struct_val.isUndef(mod)) return mod.undefRef(field_ty); | 28199 | if (struct_val.isUndef(mod)) return pt.undefRef(field_ty); |
| 27933 | if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| { | 28200 | if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| { |
| 27934 | return Air.internedToRef(opv.toIntern()); | 28201 | return Air.internedToRef(opv.toIntern()); |
| 27935 | } | 28202 | } |
| 27936 | return Air.internedToRef((try struct_val.fieldValue(mod, field_index)).toIntern()); | 28203 | return Air.internedToRef((try struct_val.fieldValue(pt, field_index)).toIntern()); |
| 27937 | } | 28204 | } |
| 27938 | 28205 | ||
| 27939 | try sema.requireRuntimeBlock(block, src, null); | 28206 | try sema.requireRuntimeBlock(block, src, null); |
| 27940 | try field_ty.resolveLayout(mod); | 28207 | try field_ty.resolveLayout(pt); |
| 27941 | return block.addStructFieldVal(struct_byval, field_index, field_ty); | 28208 | return block.addStructFieldVal(struct_byval, field_index, field_ty); |
| 27942 | }, | 28209 | }, |
| 27943 | .anon_struct_type => |anon_struct| { | 28210 | .anon_struct_type => |anon_struct| { |
| ... | @@ -27961,9 +28228,10 @@ fn tupleFieldVal( | ... | @@ -27961,9 +28228,10 @@ fn tupleFieldVal( |
| 27961 | field_name_src: LazySrcLoc, | 28228 | field_name_src: LazySrcLoc, |
| 27962 | tuple_ty: Type, | 28229 | tuple_ty: Type, |
| 27963 | ) CompileError!Air.Inst.Ref { | 28230 | ) CompileError!Air.Inst.Ref { |
| 27964 | const mod = sema.mod; | 28231 | const pt = sema.pt; |
| 28232 | const mod = pt.zcu; | ||
| 27965 | if (field_name.eqlSlice("len", &mod.intern_pool)) { | 28233 | if (field_name.eqlSlice("len", &mod.intern_pool)) { |
| 27966 | return mod.intRef(Type.usize, tuple_ty.structFieldCount(mod)); | 28234 | return pt.intRef(Type.usize, tuple_ty.structFieldCount(mod)); |
| 27967 | } | 28235 | } |
| 27968 | const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src); | 28236 | const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src); |
| 27969 | return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty); | 28237 | return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty); |
| ... | @@ -27977,18 +28245,18 @@ fn tupleFieldIndex( | ... | @@ -27977,18 +28245,18 @@ fn tupleFieldIndex( |
| 27977 | field_name: InternPool.NullTerminatedString, | 28245 | field_name: InternPool.NullTerminatedString, |
| 27978 | field_name_src: LazySrcLoc, | 28246 | field_name_src: LazySrcLoc, |
| 27979 | ) CompileError!u32 { | 28247 | ) CompileError!u32 { |
| 27980 | const mod = sema.mod; | 28248 | const pt = sema.pt; |
| 27981 | const ip = &mod.intern_pool; | 28249 | const ip = &pt.zcu.intern_pool; |
| 27982 | assert(!field_name.eqlSlice("len", ip)); | 28250 | assert(!field_name.eqlSlice("len", ip)); |
| 27983 | if (field_name.toUnsigned(ip)) |field_index| { | 28251 | if (field_name.toUnsigned(ip)) |field_index| { |
| 27984 | if (field_index < tuple_ty.structFieldCount(mod)) return field_index; | 28252 | if (field_index < tuple_ty.structFieldCount(pt.zcu)) return field_index; |
| 27985 | return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{ | 28253 | return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{ |
| 27986 | field_name.fmt(ip), tuple_ty.fmt(mod), | 28254 | field_name.fmt(ip), tuple_ty.fmt(pt), |
| 27987 | }); | 28255 | }); |
| 27988 | } | 28256 | } |
| 27989 | 28257 | ||
| 27990 | return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{ | 28258 | return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{ |
| 27991 | field_name.fmt(ip), tuple_ty.fmt(mod), | 28259 | field_name.fmt(ip), tuple_ty.fmt(pt), |
| 27992 | }); | 28260 | }); |
| 27993 | } | 28261 | } |
| 27994 | 28262 | ||
| ... | @@ -28000,12 +28268,13 @@ fn tupleFieldValByIndex( | ... | @@ -28000,12 +28268,13 @@ fn tupleFieldValByIndex( |
| 28000 | field_index: u32, | 28268 | field_index: u32, |
| 28001 | tuple_ty: Type, | 28269 | tuple_ty: Type, |
| 28002 | ) CompileError!Air.Inst.Ref { | 28270 | ) CompileError!Air.Inst.Ref { |
| 28003 | const mod = sema.mod; | 28271 | const pt = sema.pt; |
| 28272 | const mod = pt.zcu; | ||
| 28004 | const field_ty = tuple_ty.structFieldType(field_index, mod); | 28273 | const field_ty = tuple_ty.structFieldType(field_index, mod); |
| 28005 | 28274 | ||
| 28006 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | 28275 | if (tuple_ty.structFieldIsComptime(field_index, mod)) |
| 28007 | try tuple_ty.resolveStructFieldInits(mod); | 28276 | try tuple_ty.resolveStructFieldInits(pt); |
| 28008 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 28277 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| { |
| 28009 | return Air.internedToRef(default_value.toIntern()); | 28278 | return Air.internedToRef(default_value.toIntern()); |
| 28010 | } | 28279 | } |
| 28011 | 28280 | ||
| ... | @@ -28014,9 +28283,9 @@ fn tupleFieldValByIndex( | ... | @@ -28014,9 +28283,9 @@ fn tupleFieldValByIndex( |
| 28014 | return Air.internedToRef(opv.toIntern()); | 28283 | return Air.internedToRef(opv.toIntern()); |
| 28015 | } | 28284 | } |
| 28016 | return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) { | 28285 | return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) { |
| 28017 | .undef => mod.undefRef(field_ty), | 28286 | .undef => pt.undefRef(field_ty), |
| 28018 | .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) { | 28287 | .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) { |
| 28019 | .bytes => |bytes| try mod.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)), | 28288 | .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)), |
| 28020 | .elems => |elems| Value.fromInterned(elems[field_index]), | 28289 | .elems => |elems| Value.fromInterned(elems[field_index]), |
| 28021 | .repeated_elem => |elem| Value.fromInterned(elem), | 28290 | .repeated_elem => |elem| Value.fromInterned(elem), |
| 28022 | }.toIntern()), | 28291 | }.toIntern()), |
| ... | @@ -28025,7 +28294,7 @@ fn tupleFieldValByIndex( | ... | @@ -28025,7 +28294,7 @@ fn tupleFieldValByIndex( |
| 28025 | } | 28294 | } |
| 28026 | 28295 | ||
| 28027 | try sema.requireRuntimeBlock(block, src, null); | 28296 | try sema.requireRuntimeBlock(block, src, null); |
| 28028 | try field_ty.resolveLayout(mod); | 28297 | try field_ty.resolveLayout(pt); |
| 28029 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); | 28298 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); |
| 28030 | } | 28299 | } |
| 28031 | 28300 | ||
| ... | @@ -28039,18 +28308,19 @@ fn unionFieldPtr( | ... | @@ -28039,18 +28308,19 @@ fn unionFieldPtr( |
| 28039 | union_ty: Type, | 28308 | union_ty: Type, |
| 28040 | initializing: bool, | 28309 | initializing: bool, |
| 28041 | ) CompileError!Air.Inst.Ref { | 28310 | ) CompileError!Air.Inst.Ref { |
| 28042 | const mod = sema.mod; | 28311 | const pt = sema.pt; |
| 28312 | const mod = pt.zcu; | ||
| 28043 | const ip = &mod.intern_pool; | 28313 | const ip = &mod.intern_pool; |
| 28044 | 28314 | ||
| 28045 | assert(union_ty.zigTypeTag(mod) == .Union); | 28315 | assert(union_ty.zigTypeTag(mod) == .Union); |
| 28046 | 28316 | ||
| 28047 | const union_ptr_ty = sema.typeOf(union_ptr); | 28317 | const union_ptr_ty = sema.typeOf(union_ptr); |
| 28048 | const union_ptr_info = union_ptr_ty.ptrInfo(mod); | 28318 | const union_ptr_info = union_ptr_ty.ptrInfo(mod); |
| 28049 | try union_ty.resolveFields(mod); | 28319 | try union_ty.resolveFields(pt); |
| 28050 | const union_obj = mod.typeToUnion(union_ty).?; | 28320 | const union_obj = mod.typeToUnion(union_ty).?; |
| 28051 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); | 28321 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 28052 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28322 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28053 | const ptr_field_ty = try mod.ptrTypeSema(.{ | 28323 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 28054 | .child = field_ty.toIntern(), | 28324 | .child = field_ty.toIntern(), |
| 28055 | .flags = .{ | 28325 | .flags = .{ |
| 28056 | .is_const = union_ptr_info.flags.is_const, | 28326 | .is_const = union_ptr_info.flags.is_const, |
| ... | @@ -28061,7 +28331,7 @@ fn unionFieldPtr( | ... | @@ -28061,7 +28331,7 @@ fn unionFieldPtr( |
| 28061 | union_ptr_info.flags.alignment | 28331 | union_ptr_info.flags.alignment |
| 28062 | else | 28332 | else |
| 28063 | try sema.typeAbiAlignment(union_ty); | 28333 | try sema.typeAbiAlignment(union_ty); |
| 28064 | const field_align = try mod.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema); | 28334 | const field_align = try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema); |
| 28065 | break :blk union_align.min(field_align); | 28335 | break :blk union_align.min(field_align); |
| 28066 | } else union_ptr_info.flags.alignment, | 28336 | } else union_ptr_info.flags.alignment, |
| 28067 | }, | 28337 | }, |
| ... | @@ -28087,9 +28357,9 @@ fn unionFieldPtr( | ... | @@ -28087,9 +28357,9 @@ fn unionFieldPtr( |
| 28087 | switch (union_obj.getLayout(ip)) { | 28357 | switch (union_obj.getLayout(ip)) { |
| 28088 | .auto => if (initializing) { | 28358 | .auto => if (initializing) { |
| 28089 | // Store to the union to initialize the tag. | 28359 | // Store to the union to initialize the tag. |
| 28090 | const field_tag = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28360 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28091 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28361 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28092 | const new_union_val = try mod.unionValue(union_ty, field_tag, try mod.undefValue(payload_ty)); | 28362 | const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty)); |
| 28093 | try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty); | 28363 | try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty); |
| 28094 | } else { | 28364 | } else { |
| 28095 | const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse | 28365 | const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse |
| ... | @@ -28098,7 +28368,7 @@ fn unionFieldPtr( | ... | @@ -28098,7 +28368,7 @@ fn unionFieldPtr( |
| 28098 | return sema.failWithUseOfUndef(block, src); | 28368 | return sema.failWithUseOfUndef(block, src); |
| 28099 | } | 28369 | } |
| 28100 | const un = ip.indexToKey(union_val.toIntern()).un; | 28370 | const un = ip.indexToKey(union_val.toIntern()).un; |
| 28101 | const field_tag = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28371 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28102 | const tag_matches = un.tag == field_tag.toIntern(); | 28372 | const tag_matches = un.tag == field_tag.toIntern(); |
| 28103 | if (!tag_matches) { | 28373 | if (!tag_matches) { |
| 28104 | const msg = msg: { | 28374 | const msg = msg: { |
| ... | @@ -28117,7 +28387,7 @@ fn unionFieldPtr( | ... | @@ -28117,7 +28387,7 @@ fn unionFieldPtr( |
| 28117 | }, | 28387 | }, |
| 28118 | .@"packed", .@"extern" => {}, | 28388 | .@"packed", .@"extern" => {}, |
| 28119 | } | 28389 | } |
| 28120 | const field_ptr_val = try union_ptr_val.ptrField(field_index, mod); | 28390 | const field_ptr_val = try union_ptr_val.ptrField(field_index, pt); |
| 28121 | return Air.internedToRef(field_ptr_val.toIntern()); | 28391 | return Air.internedToRef(field_ptr_val.toIntern()); |
| 28122 | } | 28392 | } |
| 28123 | 28393 | ||
| ... | @@ -28125,7 +28395,7 @@ fn unionFieldPtr( | ... | @@ -28125,7 +28395,7 @@ fn unionFieldPtr( |
| 28125 | if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and | 28395 | if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and |
| 28126 | union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1) | 28396 | union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1) |
| 28127 | { | 28397 | { |
| 28128 | const wanted_tag_val = try mod.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28398 | const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28129 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); | 28399 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); |
| 28130 | // TODO would it be better if get_union_tag supported pointers to unions? | 28400 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 28131 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); | 28401 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| ... | @@ -28148,21 +28418,22 @@ fn unionFieldVal( | ... | @@ -28148,21 +28418,22 @@ fn unionFieldVal( |
| 28148 | field_name_src: LazySrcLoc, | 28418 | field_name_src: LazySrcLoc, |
| 28149 | union_ty: Type, | 28419 | union_ty: Type, |
| 28150 | ) CompileError!Air.Inst.Ref { | 28420 | ) CompileError!Air.Inst.Ref { |
| 28151 | const zcu = sema.mod; | 28421 | const pt = sema.pt; |
| 28422 | const zcu = pt.zcu; | ||
| 28152 | const ip = &zcu.intern_pool; | 28423 | const ip = &zcu.intern_pool; |
| 28153 | assert(union_ty.zigTypeTag(zcu) == .Union); | 28424 | assert(union_ty.zigTypeTag(zcu) == .Union); |
| 28154 | 28425 | ||
| 28155 | try union_ty.resolveFields(zcu); | 28426 | try union_ty.resolveFields(pt); |
| 28156 | const union_obj = zcu.typeToUnion(union_ty).?; | 28427 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 28157 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); | 28428 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 28158 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28429 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28159 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?); | 28430 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?); |
| 28160 | 28431 | ||
| 28161 | if (try sema.resolveValue(union_byval)) |union_val| { | 28432 | if (try sema.resolveValue(union_byval)) |union_val| { |
| 28162 | if (union_val.isUndef(zcu)) return zcu.undefRef(field_ty); | 28433 | if (union_val.isUndef(zcu)) return pt.undefRef(field_ty); |
| 28163 | 28434 | ||
| 28164 | const un = ip.indexToKey(union_val.toIntern()).un; | 28435 | const un = ip.indexToKey(union_val.toIntern()).un; |
| 28165 | const field_tag = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28436 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28166 | const tag_matches = un.tag == field_tag.toIntern(); | 28437 | const tag_matches = un.tag == field_tag.toIntern(); |
| 28167 | switch (union_obj.getLayout(ip)) { | 28438 | switch (union_obj.getLayout(ip)) { |
| 28168 | .auto => { | 28439 | .auto => { |
| ... | @@ -28191,7 +28462,7 @@ fn unionFieldVal( | ... | @@ -28191,7 +28462,7 @@ fn unionFieldVal( |
| 28191 | .@"packed" => if (tag_matches) { | 28462 | .@"packed" => if (tag_matches) { |
| 28192 | // Fast path - no need to use bitcast logic. | 28463 | // Fast path - no need to use bitcast logic. |
| 28193 | return Air.internedToRef(un.val); | 28464 | return Air.internedToRef(un.val); |
| 28194 | } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(zcu, .sema), 0)) |field_val| { | 28465 | } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(pt, .sema), 0)) |field_val| { |
| 28195 | return Air.internedToRef(field_val.toIntern()); | 28466 | return Air.internedToRef(field_val.toIntern()); |
| 28196 | }, | 28467 | }, |
| 28197 | } | 28468 | } |
| ... | @@ -28201,7 +28472,7 @@ fn unionFieldVal( | ... | @@ -28201,7 +28472,7 @@ fn unionFieldVal( |
| 28201 | if (union_obj.getLayout(ip) == .auto and block.wantSafety() and | 28472 | if (union_obj.getLayout(ip) == .auto and block.wantSafety() and |
| 28202 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) | 28473 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) |
| 28203 | { | 28474 | { |
| 28204 | const wanted_tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28475 | const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28205 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); | 28476 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); |
| 28206 | const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval); | 28477 | const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval); |
| 28207 | try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag); | 28478 | try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag); |
| ... | @@ -28210,7 +28481,7 @@ fn unionFieldVal( | ... | @@ -28210,7 +28481,7 @@ fn unionFieldVal( |
| 28210 | _ = try block.addNoOp(.unreach); | 28481 | _ = try block.addNoOp(.unreach); |
| 28211 | return .unreachable_value; | 28482 | return .unreachable_value; |
| 28212 | } | 28483 | } |
| 28213 | try field_ty.resolveLayout(zcu); | 28484 | try field_ty.resolveLayout(pt); |
| 28214 | return block.addStructFieldVal(union_byval, field_index, field_ty); | 28485 | return block.addStructFieldVal(union_byval, field_index, field_ty); |
| 28215 | } | 28486 | } |
| 28216 | 28487 | ||
| ... | @@ -28224,13 +28495,14 @@ fn elemPtr( | ... | @@ -28224,13 +28495,14 @@ fn elemPtr( |
| 28224 | init: bool, | 28495 | init: bool, |
| 28225 | oob_safety: bool, | 28496 | oob_safety: bool, |
| 28226 | ) CompileError!Air.Inst.Ref { | 28497 | ) CompileError!Air.Inst.Ref { |
| 28227 | const mod = sema.mod; | 28498 | const pt = sema.pt; |
| 28499 | const mod = pt.zcu; | ||
| 28228 | const indexable_ptr_src = src; // TODO better source location | 28500 | const indexable_ptr_src = src; // TODO better source location |
| 28229 | const indexable_ptr_ty = sema.typeOf(indexable_ptr); | 28501 | const indexable_ptr_ty = sema.typeOf(indexable_ptr); |
| 28230 | 28502 | ||
| 28231 | const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) { | 28503 | const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) { |
| 28232 | .Pointer => indexable_ptr_ty.childType(mod), | 28504 | .Pointer => indexable_ptr_ty.childType(mod), |
| 28233 | else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(mod)}), | 28505 | else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}), |
| 28234 | }; | 28506 | }; |
| 28235 | try checkIndexable(sema, block, src, indexable_ty); | 28507 | try checkIndexable(sema, block, src, indexable_ty); |
| 28236 | 28508 | ||
| ... | @@ -28241,7 +28513,7 @@ fn elemPtr( | ... | @@ -28241,7 +28513,7 @@ fn elemPtr( |
| 28241 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ | 28513 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ |
| 28242 | .needed_comptime_reason = "tuple field access index must be comptime-known", | 28514 | .needed_comptime_reason = "tuple field access index must be comptime-known", |
| 28243 | }); | 28515 | }); |
| 28244 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod)); | 28516 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28245 | break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init); | 28517 | break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init); |
| 28246 | }, | 28518 | }, |
| 28247 | else => { | 28519 | else => { |
| ... | @@ -28267,7 +28539,8 @@ fn elemPtrOneLayerOnly( | ... | @@ -28267,7 +28539,8 @@ fn elemPtrOneLayerOnly( |
| 28267 | ) CompileError!Air.Inst.Ref { | 28539 | ) CompileError!Air.Inst.Ref { |
| 28268 | const indexable_src = src; // TODO better source location | 28540 | const indexable_src = src; // TODO better source location |
| 28269 | const indexable_ty = sema.typeOf(indexable); | 28541 | const indexable_ty = sema.typeOf(indexable); |
| 28270 | const mod = sema.mod; | 28542 | const pt = sema.pt; |
| 28543 | const mod = pt.zcu; | ||
| 28271 | 28544 | ||
| 28272 | try checkIndexable(sema, block, src, indexable_ty); | 28545 | try checkIndexable(sema, block, src, indexable_ty); |
| 28273 | 28546 | ||
| ... | @@ -28279,11 +28552,11 @@ fn elemPtrOneLayerOnly( | ... | @@ -28279,11 +28552,11 @@ fn elemPtrOneLayerOnly( |
| 28279 | const runtime_src = rs: { | 28552 | const runtime_src = rs: { |
| 28280 | const ptr_val = maybe_ptr_val orelse break :rs indexable_src; | 28553 | const ptr_val = maybe_ptr_val orelse break :rs indexable_src; |
| 28281 | const index_val = maybe_index_val orelse break :rs elem_index_src; | 28554 | const index_val = maybe_index_val orelse break :rs elem_index_src; |
| 28282 | const index: usize = @intCast(try index_val.toUnsignedIntSema(mod)); | 28555 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28283 | const elem_ptr = try ptr_val.ptrElem(index, mod); | 28556 | const elem_ptr = try ptr_val.ptrElem(index, pt); |
| 28284 | return Air.internedToRef(elem_ptr.toIntern()); | 28557 | return Air.internedToRef(elem_ptr.toIntern()); |
| 28285 | }; | 28558 | }; |
| 28286 | const result_ty = try indexable_ty.elemPtrType(null, mod); | 28559 | const result_ty = try indexable_ty.elemPtrType(null, pt); |
| 28287 | 28560 | ||
| 28288 | try sema.requireRuntimeBlock(block, src, runtime_src); | 28561 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 28289 | return block.addPtrElemPtr(indexable, elem_index, result_ty); | 28562 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| ... | @@ -28297,7 +28570,7 @@ fn elemPtrOneLayerOnly( | ... | @@ -28297,7 +28570,7 @@ fn elemPtrOneLayerOnly( |
| 28297 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ | 28570 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ |
| 28298 | .needed_comptime_reason = "tuple field access index must be comptime-known", | 28571 | .needed_comptime_reason = "tuple field access index must be comptime-known", |
| 28299 | }); | 28572 | }); |
| 28300 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod)); | 28573 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28301 | break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false); | 28574 | break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false); |
| 28302 | }, | 28575 | }, |
| 28303 | else => unreachable, // Guaranteed by checkIndexable | 28576 | else => unreachable, // Guaranteed by checkIndexable |
| ... | @@ -28319,7 +28592,8 @@ fn elemVal( | ... | @@ -28319,7 +28592,8 @@ fn elemVal( |
| 28319 | ) CompileError!Air.Inst.Ref { | 28592 | ) CompileError!Air.Inst.Ref { |
| 28320 | const indexable_src = src; // TODO better source location | 28593 | const indexable_src = src; // TODO better source location |
| 28321 | const indexable_ty = sema.typeOf(indexable); | 28594 | const indexable_ty = sema.typeOf(indexable); |
| 28322 | const mod = sema.mod; | 28595 | const pt = sema.pt; |
| 28596 | const mod = pt.zcu; | ||
| 28323 | 28597 | ||
| 28324 | try checkIndexable(sema, block, src, indexable_ty); | 28598 | try checkIndexable(sema, block, src, indexable_ty); |
| 28325 | 28599 | ||
| ... | @@ -28337,14 +28611,14 @@ fn elemVal( | ... | @@ -28337,14 +28611,14 @@ fn elemVal( |
| 28337 | const runtime_src = rs: { | 28611 | const runtime_src = rs: { |
| 28338 | const indexable_val = maybe_indexable_val orelse break :rs indexable_src; | 28612 | const indexable_val = maybe_indexable_val orelse break :rs indexable_src; |
| 28339 | const index_val = maybe_index_val orelse break :rs elem_index_src; | 28613 | const index_val = maybe_index_val orelse break :rs elem_index_src; |
| 28340 | const index: usize = @intCast(try index_val.toUnsignedIntSema(mod)); | 28614 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28341 | const elem_ty = indexable_ty.elemType2(mod); | 28615 | const elem_ty = indexable_ty.elemType2(mod); |
| 28342 | const many_ptr_ty = try mod.manyConstPtrType(elem_ty); | 28616 | const many_ptr_ty = try pt.manyConstPtrType(elem_ty); |
| 28343 | const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty); | 28617 | const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty); |
| 28344 | const elem_ptr_ty = try mod.singleConstPtrType(elem_ty); | 28618 | const elem_ptr_ty = try pt.singleConstPtrType(elem_ty); |
| 28345 | const elem_ptr_val = try many_ptr_val.ptrElem(index, mod); | 28619 | const elem_ptr_val = try many_ptr_val.ptrElem(index, pt); |
| 28346 | if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| { | 28620 | if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| { |
| 28347 | return Air.internedToRef((try mod.getCoerced(elem_val, elem_ty)).toIntern()); | 28621 | return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern()); |
| 28348 | } | 28622 | } |
| 28349 | break :rs indexable_src; | 28623 | break :rs indexable_src; |
| 28350 | }; | 28624 | }; |
| ... | @@ -28358,7 +28632,7 @@ fn elemVal( | ... | @@ -28358,7 +28632,7 @@ fn elemVal( |
| 28358 | if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent; | 28632 | if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent; |
| 28359 | const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent; | 28633 | const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent; |
| 28360 | const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent; | 28634 | const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent; |
| 28361 | const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(mod)); | 28635 | const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt)); |
| 28362 | if (index != inner_ty.arrayLen(mod)) break :arr_sent; | 28636 | if (index != inner_ty.arrayLen(mod)) break :arr_sent; |
| 28363 | return Air.internedToRef(sentinel.toIntern()); | 28637 | return Air.internedToRef(sentinel.toIntern()); |
| 28364 | } | 28638 | } |
| ... | @@ -28376,7 +28650,7 @@ fn elemVal( | ... | @@ -28376,7 +28650,7 @@ fn elemVal( |
| 28376 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ | 28650 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ |
| 28377 | .needed_comptime_reason = "tuple field access index must be comptime-known", | 28651 | .needed_comptime_reason = "tuple field access index must be comptime-known", |
| 28378 | }); | 28652 | }); |
| 28379 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod)); | 28653 | const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28380 | return sema.tupleField(block, indexable_src, indexable, elem_index_src, index); | 28654 | return sema.tupleField(block, indexable_src, indexable, elem_index_src, index); |
| 28381 | }, | 28655 | }, |
| 28382 | else => unreachable, | 28656 | else => unreachable, |
| ... | @@ -28391,13 +28665,12 @@ fn validateRuntimeElemAccess( | ... | @@ -28391,13 +28665,12 @@ fn validateRuntimeElemAccess( |
| 28391 | parent_ty: Type, | 28665 | parent_ty: Type, |
| 28392 | parent_src: LazySrcLoc, | 28666 | parent_src: LazySrcLoc, |
| 28393 | ) CompileError!void { | 28667 | ) CompileError!void { |
| 28394 | const mod = sema.mod; | ||
| 28395 | if (try sema.typeRequiresComptime(elem_ty)) { | 28668 | if (try sema.typeRequiresComptime(elem_ty)) { |
| 28396 | const msg = msg: { | 28669 | const msg = msg: { |
| 28397 | const msg = try sema.errMsg( | 28670 | const msg = try sema.errMsg( |
| 28398 | elem_index_src, | 28671 | elem_index_src, |
| 28399 | "values of type '{}' must be comptime-known, but index value is runtime-known", | 28672 | "values of type '{}' must be comptime-known, but index value is runtime-known", |
| 28400 | .{parent_ty.fmt(mod)}, | 28673 | .{parent_ty.fmt(sema.pt)}, |
| 28401 | ); | 28674 | ); |
| 28402 | errdefer msg.destroy(sema.gpa); | 28675 | errdefer msg.destroy(sema.gpa); |
| 28403 | 28676 | ||
| ... | @@ -28418,10 +28691,11 @@ fn tupleFieldPtr( | ... | @@ -28418,10 +28691,11 @@ fn tupleFieldPtr( |
| 28418 | field_index: u32, | 28691 | field_index: u32, |
| 28419 | init: bool, | 28692 | init: bool, |
| 28420 | ) CompileError!Air.Inst.Ref { | 28693 | ) CompileError!Air.Inst.Ref { |
| 28421 | const mod = sema.mod; | 28694 | const pt = sema.pt; |
| 28695 | const mod = pt.zcu; | ||
| 28422 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); | 28696 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); |
| 28423 | const tuple_ty = tuple_ptr_ty.childType(mod); | 28697 | const tuple_ty = tuple_ptr_ty.childType(mod); |
| 28424 | try tuple_ty.resolveFields(mod); | 28698 | try tuple_ty.resolveFields(pt); |
| 28425 | const field_count = tuple_ty.structFieldCount(mod); | 28699 | const field_count = tuple_ty.structFieldCount(mod); |
| 28426 | 28700 | ||
| 28427 | if (field_count == 0) { | 28701 | if (field_count == 0) { |
| ... | @@ -28435,7 +28709,7 @@ fn tupleFieldPtr( | ... | @@ -28435,7 +28709,7 @@ fn tupleFieldPtr( |
| 28435 | } | 28709 | } |
| 28436 | 28710 | ||
| 28437 | const field_ty = tuple_ty.structFieldType(field_index, mod); | 28711 | const field_ty = tuple_ty.structFieldType(field_index, mod); |
| 28438 | const ptr_field_ty = try mod.ptrTypeSema(.{ | 28712 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 28439 | .child = field_ty.toIntern(), | 28713 | .child = field_ty.toIntern(), |
| 28440 | .flags = .{ | 28714 | .flags = .{ |
| 28441 | .is_const = !tuple_ptr_ty.ptrIsMutable(mod), | 28715 | .is_const = !tuple_ptr_ty.ptrIsMutable(mod), |
| ... | @@ -28445,10 +28719,10 @@ fn tupleFieldPtr( | ... | @@ -28445,10 +28719,10 @@ fn tupleFieldPtr( |
| 28445 | }); | 28719 | }); |
| 28446 | 28720 | ||
| 28447 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | 28721 | if (tuple_ty.structFieldIsComptime(field_index, mod)) |
| 28448 | try tuple_ty.resolveStructFieldInits(mod); | 28722 | try tuple_ty.resolveStructFieldInits(pt); |
| 28449 | 28723 | ||
| 28450 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { | 28724 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_val| { |
| 28451 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 28725 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ |
| 28452 | .ty = ptr_field_ty.toIntern(), | 28726 | .ty = ptr_field_ty.toIntern(), |
| 28453 | .base_addr = .{ .comptime_field = default_val.toIntern() }, | 28727 | .base_addr = .{ .comptime_field = default_val.toIntern() }, |
| 28454 | .byte_offset = 0, | 28728 | .byte_offset = 0, |
| ... | @@ -28456,7 +28730,7 @@ fn tupleFieldPtr( | ... | @@ -28456,7 +28730,7 @@ fn tupleFieldPtr( |
| 28456 | } | 28730 | } |
| 28457 | 28731 | ||
| 28458 | if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| { | 28732 | if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| { |
| 28459 | const field_ptr_val = try tuple_ptr_val.ptrField(field_index, mod); | 28733 | const field_ptr_val = try tuple_ptr_val.ptrField(field_index, pt); |
| 28460 | return Air.internedToRef(field_ptr_val.toIntern()); | 28734 | return Air.internedToRef(field_ptr_val.toIntern()); |
| 28461 | } | 28735 | } |
| 28462 | 28736 | ||
| ... | @@ -28476,9 +28750,10 @@ fn tupleField( | ... | @@ -28476,9 +28750,10 @@ fn tupleField( |
| 28476 | field_index_src: LazySrcLoc, | 28750 | field_index_src: LazySrcLoc, |
| 28477 | field_index: u32, | 28751 | field_index: u32, |
| 28478 | ) CompileError!Air.Inst.Ref { | 28752 | ) CompileError!Air.Inst.Ref { |
| 28479 | const mod = sema.mod; | 28753 | const pt = sema.pt; |
| 28754 | const mod = pt.zcu; | ||
| 28480 | const tuple_ty = sema.typeOf(tuple); | 28755 | const tuple_ty = sema.typeOf(tuple); |
| 28481 | try tuple_ty.resolveFields(mod); | 28756 | try tuple_ty.resolveFields(pt); |
| 28482 | const field_count = tuple_ty.structFieldCount(mod); | 28757 | const field_count = tuple_ty.structFieldCount(mod); |
| 28483 | 28758 | ||
| 28484 | if (field_count == 0) { | 28759 | if (field_count == 0) { |
| ... | @@ -28494,20 +28769,20 @@ fn tupleField( | ... | @@ -28494,20 +28769,20 @@ fn tupleField( |
| 28494 | const field_ty = tuple_ty.structFieldType(field_index, mod); | 28769 | const field_ty = tuple_ty.structFieldType(field_index, mod); |
| 28495 | 28770 | ||
| 28496 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | 28771 | if (tuple_ty.structFieldIsComptime(field_index, mod)) |
| 28497 | try tuple_ty.resolveStructFieldInits(mod); | 28772 | try tuple_ty.resolveStructFieldInits(pt); |
| 28498 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 28773 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| { |
| 28499 | return Air.internedToRef(default_value.toIntern()); // comptime field | 28774 | return Air.internedToRef(default_value.toIntern()); // comptime field |
| 28500 | } | 28775 | } |
| 28501 | 28776 | ||
| 28502 | if (try sema.resolveValue(tuple)) |tuple_val| { | 28777 | if (try sema.resolveValue(tuple)) |tuple_val| { |
| 28503 | if (tuple_val.isUndef(mod)) return mod.undefRef(field_ty); | 28778 | if (tuple_val.isUndef(mod)) return pt.undefRef(field_ty); |
| 28504 | return Air.internedToRef((try tuple_val.fieldValue(mod, field_index)).toIntern()); | 28779 | return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern()); |
| 28505 | } | 28780 | } |
| 28506 | 28781 | ||
| 28507 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); | 28782 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); |
| 28508 | 28783 | ||
| 28509 | try sema.requireRuntimeBlock(block, tuple_src, null); | 28784 | try sema.requireRuntimeBlock(block, tuple_src, null); |
| 28510 | try field_ty.resolveLayout(mod); | 28785 | try field_ty.resolveLayout(pt); |
| 28511 | return block.addStructFieldVal(tuple, field_index, field_ty); | 28786 | return block.addStructFieldVal(tuple, field_index, field_ty); |
| 28512 | } | 28787 | } |
| 28513 | 28788 | ||
| ... | @@ -28521,7 +28796,8 @@ fn elemValArray( | ... | @@ -28521,7 +28796,8 @@ fn elemValArray( |
| 28521 | elem_index: Air.Inst.Ref, | 28796 | elem_index: Air.Inst.Ref, |
| 28522 | oob_safety: bool, | 28797 | oob_safety: bool, |
| 28523 | ) CompileError!Air.Inst.Ref { | 28798 | ) CompileError!Air.Inst.Ref { |
| 28524 | const mod = sema.mod; | 28799 | const pt = sema.pt; |
| 28800 | const mod = pt.zcu; | ||
| 28525 | const array_ty = sema.typeOf(array); | 28801 | const array_ty = sema.typeOf(array); |
| 28526 | const array_sent = array_ty.sentinel(mod); | 28802 | const array_sent = array_ty.sentinel(mod); |
| 28527 | const array_len = array_ty.arrayLen(mod); | 28803 | const array_len = array_ty.arrayLen(mod); |
| ... | @@ -28537,7 +28813,7 @@ fn elemValArray( | ... | @@ -28537,7 +28813,7 @@ fn elemValArray( |
| 28537 | const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index); | 28813 | const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index); |
| 28538 | 28814 | ||
| 28539 | if (maybe_index_val) |index_val| { | 28815 | if (maybe_index_val) |index_val| { |
| 28540 | const index: usize = @intCast(try index_val.toUnsignedIntSema(mod)); | 28816 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28541 | if (array_sent) |s| { | 28817 | if (array_sent) |s| { |
| 28542 | if (index == array_len) { | 28818 | if (index == array_len) { |
| 28543 | return Air.internedToRef(s.toIntern()); | 28819 | return Air.internedToRef(s.toIntern()); |
| ... | @@ -28550,11 +28826,11 @@ fn elemValArray( | ... | @@ -28550,11 +28826,11 @@ fn elemValArray( |
| 28550 | } | 28826 | } |
| 28551 | if (maybe_undef_array_val) |array_val| { | 28827 | if (maybe_undef_array_val) |array_val| { |
| 28552 | if (array_val.isUndef(mod)) { | 28828 | if (array_val.isUndef(mod)) { |
| 28553 | return mod.undefRef(elem_ty); | 28829 | return pt.undefRef(elem_ty); |
| 28554 | } | 28830 | } |
| 28555 | if (maybe_index_val) |index_val| { | 28831 | if (maybe_index_val) |index_val| { |
| 28556 | const index: usize = @intCast(try index_val.toUnsignedIntSema(mod)); | 28832 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28557 | const elem_val = try array_val.elemValue(mod, index); | 28833 | const elem_val = try array_val.elemValue(pt, index); |
| 28558 | return Air.internedToRef(elem_val.toIntern()); | 28834 | return Air.internedToRef(elem_val.toIntern()); |
| 28559 | } | 28835 | } |
| 28560 | } | 28836 | } |
| ... | @@ -28565,7 +28841,7 @@ fn elemValArray( | ... | @@ -28565,7 +28841,7 @@ fn elemValArray( |
| 28565 | if (oob_safety and block.wantSafety()) { | 28841 | if (oob_safety and block.wantSafety()) { |
| 28566 | // Runtime check is only needed if unable to comptime check | 28842 | // Runtime check is only needed if unable to comptime check |
| 28567 | if (maybe_index_val == null) { | 28843 | if (maybe_index_val == null) { |
| 28568 | const len_inst = try mod.intRef(Type.usize, array_len); | 28844 | const len_inst = try pt.intRef(Type.usize, array_len); |
| 28569 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; | 28845 | const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt; |
| 28570 | try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op); | 28846 | try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op); |
| 28571 | } | 28847 | } |
| ... | @@ -28589,7 +28865,8 @@ fn elemPtrArray( | ... | @@ -28589,7 +28865,8 @@ fn elemPtrArray( |
| 28589 | init: bool, | 28865 | init: bool, |
| 28590 | oob_safety: bool, | 28866 | oob_safety: bool, |
| 28591 | ) CompileError!Air.Inst.Ref { | 28867 | ) CompileError!Air.Inst.Ref { |
| 28592 | const mod = sema.mod; | 28868 | const pt = sema.pt; |
| 28869 | const mod = pt.zcu; | ||
| 28593 | const array_ptr_ty = sema.typeOf(array_ptr); | 28870 | const array_ptr_ty = sema.typeOf(array_ptr); |
| 28594 | const array_ty = array_ptr_ty.childType(mod); | 28871 | const array_ty = array_ptr_ty.childType(mod); |
| 28595 | const array_sent = array_ty.sentinel(mod) != null; | 28872 | const array_sent = array_ty.sentinel(mod) != null; |
| ... | @@ -28603,7 +28880,7 @@ fn elemPtrArray( | ... | @@ -28603,7 +28880,7 @@ fn elemPtrArray( |
| 28603 | const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr); | 28880 | const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr); |
| 28604 | // The index must not be undefined since it can be out of bounds. | 28881 | // The index must not be undefined since it can be out of bounds. |
| 28605 | const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: { | 28882 | const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: { |
| 28606 | const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod)); | 28883 | const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt)); |
| 28607 | if (index >= array_len_s) { | 28884 | if (index >= array_len_s) { |
| 28608 | const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else ""; | 28885 | const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else ""; |
| 28609 | return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label }); | 28886 | return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label }); |
| ... | @@ -28611,14 +28888,14 @@ fn elemPtrArray( | ... | @@ -28611,14 +28888,14 @@ fn elemPtrArray( |
| 28611 | break :o index; | 28888 | break :o index; |
| 28612 | } else null; | 28889 | } else null; |
| 28613 | 28890 | ||
| 28614 | const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, mod); | 28891 | const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt); |
| 28615 | 28892 | ||
| 28616 | if (maybe_undef_array_ptr_val) |array_ptr_val| { | 28893 | if (maybe_undef_array_ptr_val) |array_ptr_val| { |
| 28617 | if (array_ptr_val.isUndef(mod)) { | 28894 | if (array_ptr_val.isUndef(mod)) { |
| 28618 | return mod.undefRef(elem_ptr_ty); | 28895 | return pt.undefRef(elem_ptr_ty); |
| 28619 | } | 28896 | } |
| 28620 | if (offset) |index| { | 28897 | if (offset) |index| { |
| 28621 | const elem_ptr = try array_ptr_val.ptrElem(index, mod); | 28898 | const elem_ptr = try array_ptr_val.ptrElem(index, pt); |
| 28622 | return Air.internedToRef(elem_ptr.toIntern()); | 28899 | return Air.internedToRef(elem_ptr.toIntern()); |
| 28623 | } | 28900 | } |
| 28624 | } | 28901 | } |
| ... | @@ -28632,7 +28909,7 @@ fn elemPtrArray( | ... | @@ -28632,7 +28909,7 @@ fn elemPtrArray( |
| 28632 | 28909 | ||
| 28633 | // Runtime check is only needed if unable to comptime check. | 28910 | // Runtime check is only needed if unable to comptime check. |
| 28634 | if (oob_safety and block.wantSafety() and offset == null) { | 28911 | if (oob_safety and block.wantSafety() and offset == null) { |
| 28635 | const len_inst = try mod.intRef(Type.usize, array_len); | 28912 | const len_inst = try pt.intRef(Type.usize, array_len); |
| 28636 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; | 28913 | const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt; |
| 28637 | try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op); | 28914 | try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op); |
| 28638 | } | 28915 | } |
| ... | @@ -28650,7 +28927,8 @@ fn elemValSlice( | ... | @@ -28650,7 +28927,8 @@ fn elemValSlice( |
| 28650 | elem_index: Air.Inst.Ref, | 28927 | elem_index: Air.Inst.Ref, |
| 28651 | oob_safety: bool, | 28928 | oob_safety: bool, |
| 28652 | ) CompileError!Air.Inst.Ref { | 28929 | ) CompileError!Air.Inst.Ref { |
| 28653 | const mod = sema.mod; | 28930 | const pt = sema.pt; |
| 28931 | const mod = pt.zcu; | ||
| 28654 | const slice_ty = sema.typeOf(slice); | 28932 | const slice_ty = sema.typeOf(slice); |
| 28655 | const slice_sent = slice_ty.sentinel(mod) != null; | 28933 | const slice_sent = slice_ty.sentinel(mod) != null; |
| 28656 | const elem_ty = slice_ty.elemType2(mod); | 28934 | const elem_ty = slice_ty.elemType2(mod); |
| ... | @@ -28663,19 +28941,19 @@ fn elemValSlice( | ... | @@ -28663,19 +28941,19 @@ fn elemValSlice( |
| 28663 | 28941 | ||
| 28664 | if (maybe_slice_val) |slice_val| { | 28942 | if (maybe_slice_val) |slice_val| { |
| 28665 | runtime_src = elem_index_src; | 28943 | runtime_src = elem_index_src; |
| 28666 | const slice_len = try slice_val.sliceLen(mod); | 28944 | const slice_len = try slice_val.sliceLen(pt); |
| 28667 | const slice_len_s = slice_len + @intFromBool(slice_sent); | 28945 | const slice_len_s = slice_len + @intFromBool(slice_sent); |
| 28668 | if (slice_len_s == 0) { | 28946 | if (slice_len_s == 0) { |
| 28669 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); | 28947 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| 28670 | } | 28948 | } |
| 28671 | if (maybe_index_val) |index_val| { | 28949 | if (maybe_index_val) |index_val| { |
| 28672 | const index: usize = @intCast(try index_val.toUnsignedIntSema(mod)); | 28950 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28673 | if (index >= slice_len_s) { | 28951 | if (index >= slice_len_s) { |
| 28674 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; | 28952 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; |
| 28675 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); | 28953 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); |
| 28676 | } | 28954 | } |
| 28677 | const elem_ptr_ty = try slice_ty.elemPtrType(index, mod); | 28955 | const elem_ptr_ty = try slice_ty.elemPtrType(index, pt); |
| 28678 | const elem_ptr_val = try slice_val.ptrElem(index, mod); | 28956 | const elem_ptr_val = try slice_val.ptrElem(index, pt); |
| 28679 | if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| { | 28957 | if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| { |
| 28680 | return Air.internedToRef(elem_val.toIntern()); | 28958 | return Air.internedToRef(elem_val.toIntern()); |
| 28681 | } | 28959 | } |
| ... | @@ -28688,7 +28966,7 @@ fn elemValSlice( | ... | @@ -28688,7 +28966,7 @@ fn elemValSlice( |
| 28688 | try sema.requireRuntimeBlock(block, src, runtime_src); | 28966 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 28689 | if (oob_safety and block.wantSafety()) { | 28967 | if (oob_safety and block.wantSafety()) { |
| 28690 | const len_inst = if (maybe_slice_val) |slice_val| | 28968 | const len_inst = if (maybe_slice_val) |slice_val| |
| 28691 | try mod.intRef(Type.usize, try slice_val.sliceLen(mod)) | 28969 | try pt.intRef(Type.usize, try slice_val.sliceLen(pt)) |
| 28692 | else | 28970 | else |
| 28693 | try block.addTyOp(.slice_len, Type.usize, slice); | 28971 | try block.addTyOp(.slice_len, Type.usize, slice); |
| 28694 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 28972 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| ... | @@ -28707,24 +28985,25 @@ fn elemPtrSlice( | ... | @@ -28707,24 +28985,25 @@ fn elemPtrSlice( |
| 28707 | elem_index: Air.Inst.Ref, | 28985 | elem_index: Air.Inst.Ref, |
| 28708 | oob_safety: bool, | 28986 | oob_safety: bool, |
| 28709 | ) CompileError!Air.Inst.Ref { | 28987 | ) CompileError!Air.Inst.Ref { |
| 28710 | const mod = sema.mod; | 28988 | const pt = sema.pt; |
| 28989 | const mod = pt.zcu; | ||
| 28711 | const slice_ty = sema.typeOf(slice); | 28990 | const slice_ty = sema.typeOf(slice); |
| 28712 | const slice_sent = slice_ty.sentinel(mod) != null; | 28991 | const slice_sent = slice_ty.sentinel(mod) != null; |
| 28713 | 28992 | ||
| 28714 | const maybe_undef_slice_val = try sema.resolveValue(slice); | 28993 | const maybe_undef_slice_val = try sema.resolveValue(slice); |
| 28715 | // The index must not be undefined since it can be out of bounds. | 28994 | // The index must not be undefined since it can be out of bounds. |
| 28716 | const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: { | 28995 | const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: { |
| 28717 | const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod)); | 28996 | const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt)); |
| 28718 | break :o index; | 28997 | break :o index; |
| 28719 | } else null; | 28998 | } else null; |
| 28720 | 28999 | ||
| 28721 | const elem_ptr_ty = try slice_ty.elemPtrType(offset, mod); | 29000 | const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt); |
| 28722 | 29001 | ||
| 28723 | if (maybe_undef_slice_val) |slice_val| { | 29002 | if (maybe_undef_slice_val) |slice_val| { |
| 28724 | if (slice_val.isUndef(mod)) { | 29003 | if (slice_val.isUndef(mod)) { |
| 28725 | return mod.undefRef(elem_ptr_ty); | 29004 | return pt.undefRef(elem_ptr_ty); |
| 28726 | } | 29005 | } |
| 28727 | const slice_len = try slice_val.sliceLen(mod); | 29006 | const slice_len = try slice_val.sliceLen(pt); |
| 28728 | const slice_len_s = slice_len + @intFromBool(slice_sent); | 29007 | const slice_len_s = slice_len + @intFromBool(slice_sent); |
| 28729 | if (slice_len_s == 0) { | 29008 | if (slice_len_s == 0) { |
| 28730 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); | 29009 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| ... | @@ -28734,7 +29013,7 @@ fn elemPtrSlice( | ... | @@ -28734,7 +29013,7 @@ fn elemPtrSlice( |
| 28734 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; | 29013 | const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else ""; |
| 28735 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); | 29014 | return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label }); |
| 28736 | } | 29015 | } |
| 28737 | const elem_ptr_val = try slice_val.ptrElem(index, mod); | 29016 | const elem_ptr_val = try slice_val.ptrElem(index, pt); |
| 28738 | return Air.internedToRef(elem_ptr_val.toIntern()); | 29017 | return Air.internedToRef(elem_ptr_val.toIntern()); |
| 28739 | } | 29018 | } |
| 28740 | } | 29019 | } |
| ... | @@ -28747,7 +29026,7 @@ fn elemPtrSlice( | ... | @@ -28747,7 +29026,7 @@ fn elemPtrSlice( |
| 28747 | const len_inst = len: { | 29026 | const len_inst = len: { |
| 28748 | if (maybe_undef_slice_val) |slice_val| | 29027 | if (maybe_undef_slice_val) |slice_val| |
| 28749 | if (!slice_val.isUndef(mod)) | 29028 | if (!slice_val.isUndef(mod)) |
| 28750 | break :len try mod.intRef(Type.usize, try slice_val.sliceLen(mod)); | 29029 | break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt)); |
| 28751 | break :len try block.addTyOp(.slice_len, Type.usize, slice); | 29030 | break :len try block.addTyOp(.slice_len, Type.usize, slice); |
| 28752 | }; | 29031 | }; |
| 28753 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 29032 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| ... | @@ -28810,11 +29089,12 @@ fn coerceExtra( | ... | @@ -28810,11 +29089,12 @@ fn coerceExtra( |
| 28810 | opts: CoerceOpts, | 29089 | opts: CoerceOpts, |
| 28811 | ) CoersionError!Air.Inst.Ref { | 29090 | ) CoersionError!Air.Inst.Ref { |
| 28812 | if (dest_ty.isGenericPoison()) return inst; | 29091 | if (dest_ty.isGenericPoison()) return inst; |
| 28813 | const zcu = sema.mod; | 29092 | const pt = sema.pt; |
| 29093 | const zcu = pt.zcu; | ||
| 28814 | const dest_ty_src = inst_src; // TODO better source location | 29094 | const dest_ty_src = inst_src; // TODO better source location |
| 28815 | try dest_ty.resolveFields(zcu); | 29095 | try dest_ty.resolveFields(pt); |
| 28816 | const inst_ty = sema.typeOf(inst); | 29096 | const inst_ty = sema.typeOf(inst); |
| 28817 | try inst_ty.resolveFields(zcu); | 29097 | try inst_ty.resolveFields(pt); |
| 28818 | const target = zcu.getTarget(); | 29098 | const target = zcu.getTarget(); |
| 28819 | // If the types are the same, we can return the operand. | 29099 | // If the types are the same, we can return the operand. |
| 28820 | if (dest_ty.eql(inst_ty, zcu)) | 29100 | if (dest_ty.eql(inst_ty, zcu)) |
| ... | @@ -28838,12 +29118,12 @@ fn coerceExtra( | ... | @@ -28838,12 +29118,12 @@ fn coerceExtra( |
| 28838 | if (maybe_inst_val) |val| { | 29118 | if (maybe_inst_val) |val| { |
| 28839 | // undefined sets the optional bit also to undefined. | 29119 | // undefined sets the optional bit also to undefined. |
| 28840 | if (val.toIntern() == .undef) { | 29120 | if (val.toIntern() == .undef) { |
| 28841 | return zcu.undefRef(dest_ty); | 29121 | return pt.undefRef(dest_ty); |
| 28842 | } | 29122 | } |
| 28843 | 29123 | ||
| 28844 | // null to ?T | 29124 | // null to ?T |
| 28845 | if (val.toIntern() == .null_value) { | 29125 | if (val.toIntern() == .null_value) { |
| 28846 | return Air.internedToRef((try zcu.intern(.{ .opt = .{ | 29126 | return Air.internedToRef((try pt.intern(.{ .opt = .{ |
| 28847 | .ty = dest_ty.toIntern(), | 29127 | .ty = dest_ty.toIntern(), |
| 28848 | .val = .none, | 29128 | .val = .none, |
| 28849 | } }))); | 29129 | } }))); |
| ... | @@ -29018,7 +29298,7 @@ fn coerceExtra( | ... | @@ -29018,7 +29298,7 @@ fn coerceExtra( |
| 29018 | switch (dest_info.flags.size) { | 29298 | switch (dest_info.flags.size) { |
| 29019 | // coercion to C pointer | 29299 | // coercion to C pointer |
| 29020 | .C => switch (inst_ty.zigTypeTag(zcu)) { | 29300 | .C => switch (inst_ty.zigTypeTag(zcu)) { |
| 29021 | .Null => return Air.internedToRef(try zcu.intern(.{ .ptr = .{ | 29301 | .Null => return Air.internedToRef(try pt.intern(.{ .ptr = .{ |
| 29022 | .ty = dest_ty.toIntern(), | 29302 | .ty = dest_ty.toIntern(), |
| 29023 | .base_addr = .int, | 29303 | .base_addr = .int, |
| 29024 | .byte_offset = 0, | 29304 | .byte_offset = 0, |
| ... | @@ -29063,7 +29343,7 @@ fn coerceExtra( | ... | @@ -29063,7 +29343,7 @@ fn coerceExtra( |
| 29063 | if (inst_info.flags.size == .Slice) { | 29343 | if (inst_info.flags.size == .Slice) { |
| 29064 | assert(dest_info.sentinel == .none); | 29344 | assert(dest_info.sentinel == .none); |
| 29065 | if (inst_info.sentinel == .none or | 29345 | if (inst_info.sentinel == .none or |
| 29066 | inst_info.sentinel != (try zcu.intValue(Type.fromInterned(inst_info.child), 0)).toIntern()) | 29346 | inst_info.sentinel != (try pt.intValue(Type.fromInterned(inst_info.child), 0)).toIntern()) |
| 29067 | break :p; | 29347 | break :p; |
| 29068 | 29348 | ||
| 29069 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 29349 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -29112,7 +29392,7 @@ fn coerceExtra( | ... | @@ -29112,7 +29392,7 @@ fn coerceExtra( |
| 29112 | block, | 29392 | block, |
| 29113 | inst_src, | 29393 | inst_src, |
| 29114 | "array literal requires address-of operator (&) to coerce to slice type '{}'", | 29394 | "array literal requires address-of operator (&) to coerce to slice type '{}'", |
| 29115 | .{dest_ty.fmt(zcu)}, | 29395 | .{dest_ty.fmt(pt)}, |
| 29116 | ); | 29396 | ); |
| 29117 | } | 29397 | } |
| 29118 | 29398 | ||
| ... | @@ -29123,10 +29403,10 @@ fn coerceExtra( | ... | @@ -29123,10 +29403,10 @@ fn coerceExtra( |
| 29123 | // empty tuple to zero-length slice | 29403 | // empty tuple to zero-length slice |
| 29124 | // note that this allows coercing to a mutable slice. | 29404 | // note that this allows coercing to a mutable slice. |
| 29125 | if (inst_child_ty.structFieldCount(zcu) == 0) { | 29405 | if (inst_child_ty.structFieldCount(zcu) == 0) { |
| 29126 | const align_val = try dest_ty.ptrAlignmentAdvanced(zcu, .sema); | 29406 | const align_val = try dest_ty.ptrAlignmentAdvanced(pt, .sema); |
| 29127 | return Air.internedToRef(try zcu.intern(.{ .slice = .{ | 29407 | return Air.internedToRef(try pt.intern(.{ .slice = .{ |
| 29128 | .ty = dest_ty.toIntern(), | 29408 | .ty = dest_ty.toIntern(), |
| 29129 | .ptr = try zcu.intern(.{ .ptr = .{ | 29409 | .ptr = try pt.intern(.{ .ptr = .{ |
| 29130 | .ty = dest_ty.slicePtrFieldType(zcu).toIntern(), | 29410 | .ty = dest_ty.slicePtrFieldType(zcu).toIntern(), |
| 29131 | .base_addr = .int, | 29411 | .base_addr = .int, |
| 29132 | .byte_offset = align_val.toByteUnits().?, | 29412 | .byte_offset = align_val.toByteUnits().?, |
| ... | @@ -29138,7 +29418,7 @@ fn coerceExtra( | ... | @@ -29138,7 +29418,7 @@ fn coerceExtra( |
| 29138 | // pointer to tuple to slice | 29418 | // pointer to tuple to slice |
| 29139 | if (!dest_info.flags.is_const) { | 29419 | if (!dest_info.flags.is_const) { |
| 29140 | const err_msg = err_msg: { | 29420 | const err_msg = err_msg: { |
| 29141 | const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(zcu)}); | 29421 | const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(pt)}); |
| 29142 | errdefer err_msg.destroy(sema.gpa); | 29422 | errdefer err_msg.destroy(sema.gpa); |
| 29143 | try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); | 29423 | try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); |
| 29144 | break :err_msg err_msg; | 29424 | break :err_msg err_msg; |
| ... | @@ -29194,12 +29474,12 @@ fn coerceExtra( | ... | @@ -29194,12 +29474,12 @@ fn coerceExtra( |
| 29194 | // comptime-known integer to other number | 29474 | // comptime-known integer to other number |
| 29195 | if (!(try sema.intFitsInType(val, dest_ty, null))) { | 29475 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 29196 | if (!opts.report_err) return error.NotCoercible; | 29476 | if (!opts.report_err) return error.NotCoercible; |
| 29197 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(zcu), val.fmtValue(zcu, sema) }); | 29477 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) }); |
| 29198 | } | 29478 | } |
| 29199 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 29479 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 29200 | .undef => try zcu.undefRef(dest_ty), | 29480 | .undef => try pt.undefRef(dest_ty), |
| 29201 | .int => |int| Air.internedToRef( | 29481 | .int => |int| Air.internedToRef( |
| 29202 | try zcu.intern_pool.getCoercedInts(zcu.gpa, int, dest_ty.toIntern()), | 29482 | try zcu.intern_pool.getCoercedInts(zcu.gpa, pt.tid, int, dest_ty.toIntern()), |
| 29203 | ), | 29483 | ), |
| 29204 | else => unreachable, | 29484 | else => unreachable, |
| 29205 | }; | 29485 | }; |
| ... | @@ -29228,18 +29508,18 @@ fn coerceExtra( | ... | @@ -29228,18 +29508,18 @@ fn coerceExtra( |
| 29228 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) { | 29508 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) { |
| 29229 | .ComptimeFloat => { | 29509 | .ComptimeFloat => { |
| 29230 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); | 29510 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); |
| 29231 | const result_val = try val.floatCast(dest_ty, zcu); | 29511 | const result_val = try val.floatCast(dest_ty, pt); |
| 29232 | return Air.internedToRef(result_val.toIntern()); | 29512 | return Air.internedToRef(result_val.toIntern()); |
| 29233 | }, | 29513 | }, |
| 29234 | .Float => { | 29514 | .Float => { |
| 29235 | if (maybe_inst_val) |val| { | 29515 | if (maybe_inst_val) |val| { |
| 29236 | const result_val = try val.floatCast(dest_ty, zcu); | 29516 | const result_val = try val.floatCast(dest_ty, pt); |
| 29237 | if (!val.eql(try result_val.floatCast(inst_ty, zcu), inst_ty, zcu)) { | 29517 | if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) { |
| 29238 | return sema.fail( | 29518 | return sema.fail( |
| 29239 | block, | 29519 | block, |
| 29240 | inst_src, | 29520 | inst_src, |
| 29241 | "type '{}' cannot represent float value '{}'", | 29521 | "type '{}' cannot represent float value '{}'", |
| 29242 | .{ dest_ty.fmt(zcu), val.fmtValue(zcu, sema) }, | 29522 | .{ dest_ty.fmt(pt), val.fmtValue(pt, sema) }, |
| 29243 | ); | 29523 | ); |
| 29244 | } | 29524 | } |
| 29245 | return Air.internedToRef(result_val.toIntern()); | 29525 | return Air.internedToRef(result_val.toIntern()); |
| ... | @@ -29268,7 +29548,7 @@ fn coerceExtra( | ... | @@ -29268,7 +29548,7 @@ fn coerceExtra( |
| 29268 | } | 29548 | } |
| 29269 | break :int; | 29549 | break :int; |
| 29270 | }; | 29550 | }; |
| 29271 | const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, zcu, .sema); | 29551 | const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema); |
| 29272 | // TODO implement this compile error | 29552 | // TODO implement this compile error |
| 29273 | //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty); | 29553 | //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty); |
| 29274 | //if (!int_again_val.eql(val, inst_ty, zcu)) { | 29554 | //if (!int_again_val.eql(val, inst_ty, zcu)) { |
| ... | @@ -29276,7 +29556,7 @@ fn coerceExtra( | ... | @@ -29276,7 +29556,7 @@ fn coerceExtra( |
| 29276 | // block, | 29556 | // block, |
| 29277 | // inst_src, | 29557 | // inst_src, |
| 29278 | // "type '{}' cannot represent integer value '{}'", | 29558 | // "type '{}' cannot represent integer value '{}'", |
| 29279 | // .{ dest_ty.fmt(zcu), val }, | 29559 | // .{ dest_ty.fmt(pt), val }, |
| 29280 | // ); | 29560 | // ); |
| 29281 | //} | 29561 | //} |
| 29282 | return Air.internedToRef(result_val.toIntern()); | 29562 | return Air.internedToRef(result_val.toIntern()); |
| ... | @@ -29290,10 +29570,10 @@ fn coerceExtra( | ... | @@ -29290,10 +29570,10 @@ fn coerceExtra( |
| 29290 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; | 29570 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; |
| 29291 | const field_index = dest_ty.enumFieldIndex(string, zcu) orelse { | 29571 | const field_index = dest_ty.enumFieldIndex(string, zcu) orelse { |
| 29292 | return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{ | 29572 | return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{ |
| 29293 | string.fmt(&zcu.intern_pool), dest_ty.fmt(zcu), | 29573 | string.fmt(&zcu.intern_pool), dest_ty.fmt(pt), |
| 29294 | }); | 29574 | }); |
| 29295 | }; | 29575 | }; |
| 29296 | return Air.internedToRef((try zcu.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern()); | 29576 | return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern()); |
| 29297 | }, | 29577 | }, |
| 29298 | .Union => blk: { | 29578 | .Union => blk: { |
| 29299 | // union to its own tag type | 29579 | // union to its own tag type |
| ... | @@ -29308,12 +29588,12 @@ fn coerceExtra( | ... | @@ -29308,12 +29588,12 @@ fn coerceExtra( |
| 29308 | .ErrorUnion => eu: { | 29588 | .ErrorUnion => eu: { |
| 29309 | if (maybe_inst_val) |inst_val| { | 29589 | if (maybe_inst_val) |inst_val| { |
| 29310 | switch (inst_val.toIntern()) { | 29590 | switch (inst_val.toIntern()) { |
| 29311 | .undef => return zcu.undefRef(dest_ty), | 29591 | .undef => return pt.undefRef(dest_ty), |
| 29312 | else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) { | 29592 | else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) { |
| 29313 | .error_union => |error_union| switch (error_union.val) { | 29593 | .error_union => |error_union| switch (error_union.val) { |
| 29314 | .err_name => |err_name| { | 29594 | .err_name => |err_name| { |
| 29315 | const error_set_ty = inst_ty.errorUnionSet(zcu); | 29595 | const error_set_ty = inst_ty.errorUnionSet(zcu); |
| 29316 | const error_set_val = Air.internedToRef((try zcu.intern(.{ .err = .{ | 29596 | const error_set_val = Air.internedToRef((try pt.intern(.{ .err = .{ |
| 29317 | .ty = error_set_ty.toIntern(), | 29597 | .ty = error_set_ty.toIntern(), |
| 29318 | .name = err_name, | 29598 | .name = err_name, |
| 29319 | } }))); | 29599 | } }))); |
| ... | @@ -29370,7 +29650,7 @@ fn coerceExtra( | ... | @@ -29370,7 +29650,7 @@ fn coerceExtra( |
| 29370 | 29650 | ||
| 29371 | if (dest_ty.sentinel(zcu)) |dest_sent| { | 29651 | if (dest_ty.sentinel(zcu)) |dest_sent| { |
| 29372 | const src_sent = inst_ty.sentinel(zcu) orelse break :array_to_array; | 29652 | const src_sent = inst_ty.sentinel(zcu) orelse break :array_to_array; |
| 29373 | if (dest_sent.toIntern() != (try zcu.getCoerced(src_sent, dest_ty.childType(zcu))).toIntern()) { | 29653 | if (dest_sent.toIntern() != (try pt.getCoerced(src_sent, dest_ty.childType(zcu))).toIntern()) { |
| 29374 | break :array_to_array; | 29654 | break :array_to_array; |
| 29375 | } | 29655 | } |
| 29376 | } | 29656 | } |
| ... | @@ -29414,7 +29694,7 @@ fn coerceExtra( | ... | @@ -29414,7 +29694,7 @@ fn coerceExtra( |
| 29414 | // undefined to anything. We do this after the big switch above so that | 29694 | // undefined to anything. We do this after the big switch above so that |
| 29415 | // special logic has a chance to run first, such as `*[N]T` to `[]T` which | 29695 | // special logic has a chance to run first, such as `*[N]T` to `[]T` which |
| 29416 | // should initialize the length field of the slice. | 29696 | // should initialize the length field of the slice. |
| 29417 | if (maybe_inst_val) |val| if (val.toIntern() == .undef) return zcu.undefRef(dest_ty); | 29697 | if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty); |
| 29418 | 29698 | ||
| 29419 | if (!opts.report_err) return error.NotCoercible; | 29699 | if (!opts.report_err) return error.NotCoercible; |
| 29420 | 29700 | ||
| ... | @@ -29434,7 +29714,7 @@ fn coerceExtra( | ... | @@ -29434,7 +29714,7 @@ fn coerceExtra( |
| 29434 | } | 29714 | } |
| 29435 | 29715 | ||
| 29436 | const msg = msg: { | 29716 | const msg = msg: { |
| 29437 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(zcu), inst_ty.fmt(zcu) }); | 29717 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) }); |
| 29438 | errdefer msg.destroy(sema.gpa); | 29718 | errdefer msg.destroy(sema.gpa); |
| 29439 | 29719 | ||
| 29440 | // E!T to T | 29720 | // E!T to T |
| ... | @@ -29486,7 +29766,7 @@ fn coerceInMemory( | ... | @@ -29486,7 +29766,7 @@ fn coerceInMemory( |
| 29486 | val: Value, | 29766 | val: Value, |
| 29487 | dst_ty: Type, | 29767 | dst_ty: Type, |
| 29488 | ) CompileError!Air.Inst.Ref { | 29768 | ) CompileError!Air.Inst.Ref { |
| 29489 | return Air.internedToRef((try sema.mod.getCoerced(val, dst_ty)).toIntern()); | 29769 | return Air.internedToRef((try sema.pt.getCoerced(val, dst_ty)).toIntern()); |
| 29490 | } | 29770 | } |
| 29491 | 29771 | ||
| 29492 | const InMemoryCoercionResult = union(enum) { | 29772 | const InMemoryCoercionResult = union(enum) { |
| ... | @@ -29607,7 +29887,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29607,7 +29887,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29607 | } | 29887 | } |
| 29608 | 29888 | ||
| 29609 | fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void { | 29889 | fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void { |
| 29610 | const mod = sema.mod; | 29890 | const pt = sema.pt; |
| 29611 | var cur = res; | 29891 | var cur = res; |
| 29612 | while (true) switch (cur.*) { | 29892 | while (true) switch (cur.*) { |
| 29613 | .ok => unreachable, | 29893 | .ok => unreachable, |
| ... | @@ -29624,7 +29904,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29624,7 +29904,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29624 | }, | 29904 | }, |
| 29625 | .error_union_payload => |pair| { | 29905 | .error_union_payload => |pair| { |
| 29626 | try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{ | 29906 | try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{ |
| 29627 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 29907 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29628 | }); | 29908 | }); |
| 29629 | cur = pair.child; | 29909 | cur = pair.child; |
| 29630 | }, | 29910 | }, |
| ... | @@ -29637,18 +29917,18 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29637,18 +29917,18 @@ const InMemoryCoercionResult = union(enum) { |
| 29637 | .array_sentinel => |sentinel| { | 29917 | .array_sentinel => |sentinel| { |
| 29638 | if (sentinel.actual.toIntern() != .unreachable_value) { | 29918 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 29639 | try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ | 29919 | try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ |
| 29640 | sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema), | 29920 | sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema), |
| 29641 | }); | 29921 | }); |
| 29642 | } else { | 29922 | } else { |
| 29643 | try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{ | 29923 | try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{ |
| 29644 | sentinel.wanted.fmtValue(mod, sema), | 29924 | sentinel.wanted.fmtValue(pt, sema), |
| 29645 | }); | 29925 | }); |
| 29646 | } | 29926 | } |
| 29647 | break; | 29927 | break; |
| 29648 | }, | 29928 | }, |
| 29649 | .array_elem => |pair| { | 29929 | .array_elem => |pair| { |
| 29650 | try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{ | 29930 | try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{ |
| 29651 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 29931 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29652 | }); | 29932 | }); |
| 29653 | cur = pair.child; | 29933 | cur = pair.child; |
| 29654 | }, | 29934 | }, |
| ... | @@ -29660,19 +29940,19 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29660,19 +29940,19 @@ const InMemoryCoercionResult = union(enum) { |
| 29660 | }, | 29940 | }, |
| 29661 | .vector_elem => |pair| { | 29941 | .vector_elem => |pair| { |
| 29662 | try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{ | 29942 | try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{ |
| 29663 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 29943 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29664 | }); | 29944 | }); |
| 29665 | cur = pair.child; | 29945 | cur = pair.child; |
| 29666 | }, | 29946 | }, |
| 29667 | .optional_shape => |pair| { | 29947 | .optional_shape => |pair| { |
| 29668 | try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ | 29948 | try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ |
| 29669 | pair.actual.optionalChild(mod).fmt(mod), pair.wanted.optionalChild(mod).fmt(mod), | 29949 | pair.actual.optionalChild(pt.zcu).fmt(pt), pair.wanted.optionalChild(pt.zcu).fmt(pt), |
| 29670 | }); | 29950 | }); |
| 29671 | break; | 29951 | break; |
| 29672 | }, | 29952 | }, |
| 29673 | .optional_child => |pair| { | 29953 | .optional_child => |pair| { |
| 29674 | try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ | 29954 | try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ |
| 29675 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 29955 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29676 | }); | 29956 | }); |
| 29677 | cur = pair.child; | 29957 | cur = pair.child; |
| 29678 | }, | 29958 | }, |
| ... | @@ -29682,7 +29962,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29682,7 +29962,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29682 | }, | 29962 | }, |
| 29683 | .missing_error => |missing_errors| { | 29963 | .missing_error => |missing_errors| { |
| 29684 | for (missing_errors) |err| { | 29964 | for (missing_errors) |err| { |
| 29685 | try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)}); | 29965 | try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&pt.zcu.intern_pool)}); |
| 29686 | } | 29966 | } |
| 29687 | break; | 29967 | break; |
| 29688 | }, | 29968 | }, |
| ... | @@ -29736,7 +30016,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29736,7 +30016,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29736 | }, | 30016 | }, |
| 29737 | .fn_param => |param| { | 30017 | .fn_param => |param| { |
| 29738 | try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{ | 30018 | try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{ |
| 29739 | param.index, param.actual.fmt(mod), param.wanted.fmt(mod), | 30019 | param.index, param.actual.fmt(pt), param.wanted.fmt(pt), |
| 29740 | }); | 30020 | }); |
| 29741 | cur = param.child; | 30021 | cur = param.child; |
| 29742 | }, | 30022 | }, |
| ... | @@ -29746,13 +30026,13 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29746,13 +30026,13 @@ const InMemoryCoercionResult = union(enum) { |
| 29746 | }, | 30026 | }, |
| 29747 | .fn_return_type => |pair| { | 30027 | .fn_return_type => |pair| { |
| 29748 | try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{ | 30028 | try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{ |
| 29749 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30029 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29750 | }); | 30030 | }); |
| 29751 | cur = pair.child; | 30031 | cur = pair.child; |
| 29752 | }, | 30032 | }, |
| 29753 | .ptr_child => |pair| { | 30033 | .ptr_child => |pair| { |
| 29754 | try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{ | 30034 | try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{ |
| 29755 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30035 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29756 | }); | 30036 | }); |
| 29757 | cur = pair.child; | 30037 | cur = pair.child; |
| 29758 | }, | 30038 | }, |
| ... | @@ -29763,11 +30043,11 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29763,11 +30043,11 @@ const InMemoryCoercionResult = union(enum) { |
| 29763 | .ptr_sentinel => |sentinel| { | 30043 | .ptr_sentinel => |sentinel| { |
| 29764 | if (sentinel.actual.toIntern() != .unreachable_value) { | 30044 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 29765 | try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ | 30045 | try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ |
| 29766 | sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema), | 30046 | sentinel.actual.fmtValue(pt, sema), sentinel.wanted.fmtValue(pt, sema), |
| 29767 | }); | 30047 | }); |
| 29768 | } else { | 30048 | } else { |
| 29769 | try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{ | 30049 | try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{ |
| 29770 | sentinel.wanted.fmtValue(mod, sema), | 30050 | sentinel.wanted.fmtValue(pt, sema), |
| 29771 | }); | 30051 | }); |
| 29772 | } | 30052 | } |
| 29773 | break; | 30053 | break; |
| ... | @@ -29787,15 +30067,15 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29787,15 +30067,15 @@ const InMemoryCoercionResult = union(enum) { |
| 29787 | break; | 30067 | break; |
| 29788 | }, | 30068 | }, |
| 29789 | .ptr_allowzero => |pair| { | 30069 | .ptr_allowzero => |pair| { |
| 29790 | const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod); | 30070 | const wanted_allow_zero = pair.wanted.ptrAllowsZero(pt.zcu); |
| 29791 | const actual_allow_zero = pair.actual.ptrAllowsZero(mod); | 30071 | const actual_allow_zero = pair.actual.ptrAllowsZero(pt.zcu); |
| 29792 | if (actual_allow_zero and !wanted_allow_zero) { | 30072 | if (actual_allow_zero and !wanted_allow_zero) { |
| 29793 | try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{ | 30073 | try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{ |
| 29794 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30074 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29795 | }); | 30075 | }); |
| 29796 | } else { | 30076 | } else { |
| 29797 | try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{ | 30077 | try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{ |
| 29798 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30078 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29799 | }); | 30079 | }); |
| 29800 | } | 30080 | } |
| 29801 | break; | 30081 | break; |
| ... | @@ -29821,13 +30101,13 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29821,13 +30101,13 @@ const InMemoryCoercionResult = union(enum) { |
| 29821 | }, | 30101 | }, |
| 29822 | .double_ptr_to_anyopaque => |pair| { | 30102 | .double_ptr_to_anyopaque => |pair| { |
| 29823 | try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{ | 30103 | try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{ |
| 29824 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30104 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29825 | }); | 30105 | }); |
| 29826 | break; | 30106 | break; |
| 29827 | }, | 30107 | }, |
| 29828 | .slice_to_anyopaque => |pair| { | 30108 | .slice_to_anyopaque => |pair| { |
| 29829 | try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{ | 30109 | try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{ |
| 29830 | pair.actual.fmt(mod), pair.wanted.fmt(mod), | 30110 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29831 | }); | 30111 | }); |
| 29832 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); | 30112 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); |
| 29833 | break; | 30113 | break; |
| ... | @@ -29864,7 +30144,8 @@ pub fn coerceInMemoryAllowed( | ... | @@ -29864,7 +30144,8 @@ pub fn coerceInMemoryAllowed( |
| 29864 | dest_src: LazySrcLoc, | 30144 | dest_src: LazySrcLoc, |
| 29865 | src_src: LazySrcLoc, | 30145 | src_src: LazySrcLoc, |
| 29866 | ) CompileError!InMemoryCoercionResult { | 30146 | ) CompileError!InMemoryCoercionResult { |
| 29867 | const mod = sema.mod; | 30147 | const pt = sema.pt; |
| 30148 | const mod = pt.zcu; | ||
| 29868 | 30149 | ||
| 29869 | if (dest_ty.eql(src_ty, mod)) | 30150 | if (dest_ty.eql(src_ty, mod)) |
| 29870 | return .ok; | 30151 | return .ok; |
| ... | @@ -29968,7 +30249,7 @@ pub fn coerceInMemoryAllowed( | ... | @@ -29968,7 +30249,7 @@ pub fn coerceInMemoryAllowed( |
| 29968 | (src_info.sentinel != null and | 30249 | (src_info.sentinel != null and |
| 29969 | dest_info.sentinel != null and | 30250 | dest_info.sentinel != null and |
| 29970 | dest_info.sentinel.?.eql( | 30251 | dest_info.sentinel.?.eql( |
| 29971 | try mod.getCoerced(src_info.sentinel.?, dest_info.elem_type), | 30252 | try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type), |
| 29972 | dest_info.elem_type, | 30253 | dest_info.elem_type, |
| 29973 | mod, | 30254 | mod, |
| 29974 | )); | 30255 | )); |
| ... | @@ -30045,8 +30326,8 @@ pub fn coerceInMemoryAllowed( | ... | @@ -30045,8 +30326,8 @@ pub fn coerceInMemoryAllowed( |
| 30045 | // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M), | 30326 | // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M), |
| 30046 | // that is to say, the padding bits are not in the same place as the array [N]iM. | 30327 | // that is to say, the padding bits are not in the same place as the array [N]iM. |
| 30047 | // If there's no padding, the bitcast is possible. | 30328 | // If there's no padding, the bitcast is possible. |
| 30048 | const elem_bit_size = dest_elem_ty.bitSize(mod); | 30329 | const elem_bit_size = dest_elem_ty.bitSize(pt); |
| 30049 | const elem_abi_byte_size = dest_elem_ty.abiSize(mod); | 30330 | const elem_abi_byte_size = dest_elem_ty.abiSize(pt); |
| 30050 | if (elem_abi_byte_size * 8 == elem_bit_size) | 30331 | if (elem_abi_byte_size * 8 == elem_bit_size) |
| 30051 | return .ok; | 30332 | return .ok; |
| 30052 | } | 30333 | } |
| ... | @@ -30081,7 +30362,7 @@ pub fn coerceInMemoryAllowed( | ... | @@ -30081,7 +30362,7 @@ pub fn coerceInMemoryAllowed( |
| 30081 | const field_count = dest_ty.structFieldCount(mod); | 30362 | const field_count = dest_ty.structFieldCount(mod); |
| 30082 | for (0..field_count) |field_idx| { | 30363 | for (0..field_count) |field_idx| { |
| 30083 | if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple; | 30364 | if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple; |
| 30084 | if (dest_ty.structFieldAlign(field_idx, mod) != src_ty.structFieldAlign(field_idx, mod)) break :tuple; | 30365 | if (dest_ty.structFieldAlign(field_idx, pt) != src_ty.structFieldAlign(field_idx, pt)) break :tuple; |
| 30085 | const dest_field_ty = dest_ty.structFieldType(field_idx, mod); | 30366 | const dest_field_ty = dest_ty.structFieldType(field_idx, mod); |
| 30086 | const src_field_ty = src_ty.structFieldType(field_idx, mod); | 30367 | const src_field_ty = src_ty.structFieldType(field_idx, mod); |
| 30087 | const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src); | 30368 | const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src); |
| ... | @@ -30104,7 +30385,8 @@ fn coerceInMemoryAllowedErrorSets( | ... | @@ -30104,7 +30385,8 @@ fn coerceInMemoryAllowedErrorSets( |
| 30104 | dest_src: LazySrcLoc, | 30385 | dest_src: LazySrcLoc, |
| 30105 | src_src: LazySrcLoc, | 30386 | src_src: LazySrcLoc, |
| 30106 | ) !InMemoryCoercionResult { | 30387 | ) !InMemoryCoercionResult { |
| 30107 | const mod = sema.mod; | 30388 | const pt = sema.pt; |
| 30389 | const mod = pt.zcu; | ||
| 30108 | const gpa = sema.gpa; | 30390 | const gpa = sema.gpa; |
| 30109 | const ip = &mod.intern_pool; | 30391 | const ip = &mod.intern_pool; |
| 30110 | 30392 | ||
| ... | @@ -30202,7 +30484,8 @@ fn coerceInMemoryAllowedFns( | ... | @@ -30202,7 +30484,8 @@ fn coerceInMemoryAllowedFns( |
| 30202 | dest_src: LazySrcLoc, | 30484 | dest_src: LazySrcLoc, |
| 30203 | src_src: LazySrcLoc, | 30485 | src_src: LazySrcLoc, |
| 30204 | ) !InMemoryCoercionResult { | 30486 | ) !InMemoryCoercionResult { |
| 30205 | const mod = sema.mod; | 30487 | const pt = sema.pt; |
| 30488 | const mod = pt.zcu; | ||
| 30206 | const ip = &mod.intern_pool; | 30489 | const ip = &mod.intern_pool; |
| 30207 | 30490 | ||
| 30208 | const dest_info = mod.typeToFunc(dest_ty).?; | 30491 | const dest_info = mod.typeToFunc(dest_ty).?; |
| ... | @@ -30303,7 +30586,8 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -30303,7 +30586,8 @@ fn coerceInMemoryAllowedPtrs( |
| 30303 | dest_src: LazySrcLoc, | 30586 | dest_src: LazySrcLoc, |
| 30304 | src_src: LazySrcLoc, | 30587 | src_src: LazySrcLoc, |
| 30305 | ) !InMemoryCoercionResult { | 30588 | ) !InMemoryCoercionResult { |
| 30306 | const zcu = sema.mod; | 30589 | const pt = sema.pt; |
| 30590 | const zcu = pt.zcu; | ||
| 30307 | const dest_info = dest_ptr_ty.ptrInfo(zcu); | 30591 | const dest_info = dest_ptr_ty.ptrInfo(zcu); |
| 30308 | const src_info = src_ptr_ty.ptrInfo(zcu); | 30592 | const src_info = src_ptr_ty.ptrInfo(zcu); |
| 30309 | 30593 | ||
| ... | @@ -30381,7 +30665,7 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -30381,7 +30665,7 @@ fn coerceInMemoryAllowedPtrs( |
| 30381 | 30665 | ||
| 30382 | const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or | 30666 | const ok_sent = dest_info.sentinel == .none or src_info.flags.size == .C or |
| 30383 | (src_info.sentinel != .none and | 30667 | (src_info.sentinel != .none and |
| 30384 | dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, src_info.sentinel, dest_info.child)); | 30668 | dest_info.sentinel == try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child)); |
| 30385 | if (!ok_sent) { | 30669 | if (!ok_sent) { |
| 30386 | return InMemoryCoercionResult{ .ptr_sentinel = .{ | 30670 | return InMemoryCoercionResult{ .ptr_sentinel = .{ |
| 30387 | .actual = switch (src_info.sentinel) { | 30671 | .actual = switch (src_info.sentinel) { |
| ... | @@ -30432,7 +30716,8 @@ fn coerceVarArgParam( | ... | @@ -30432,7 +30716,8 @@ fn coerceVarArgParam( |
| 30432 | ) !Air.Inst.Ref { | 30716 | ) !Air.Inst.Ref { |
| 30433 | if (block.is_typeof) return inst; | 30717 | if (block.is_typeof) return inst; |
| 30434 | 30718 | ||
| 30435 | const mod = sema.mod; | 30719 | const pt = sema.pt; |
| 30720 | const mod = pt.zcu; | ||
| 30436 | const uncasted_ty = sema.typeOf(inst); | 30721 | const uncasted_ty = sema.typeOf(inst); |
| 30437 | const coerced = switch (uncasted_ty.zigTypeTag(mod)) { | 30722 | const coerced = switch (uncasted_ty.zigTypeTag(mod)) { |
| 30438 | // TODO consider casting to c_int/f64 if they fit | 30723 | // TODO consider casting to c_int/f64 if they fit |
| ... | @@ -30449,9 +30734,9 @@ fn coerceVarArgParam( | ... | @@ -30449,9 +30734,9 @@ fn coerceVarArgParam( |
| 30449 | }, | 30734 | }, |
| 30450 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), | 30735 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), |
| 30451 | .Float => float: { | 30736 | .Float => float: { |
| 30452 | const target = sema.mod.getTarget(); | 30737 | const target = mod.getTarget(); |
| 30453 | const double_bits = target.c_type_bit_size(.double); | 30738 | const double_bits = target.c_type_bit_size(.double); |
| 30454 | const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget()); | 30739 | const inst_bits = uncasted_ty.floatBits(target); |
| 30455 | if (inst_bits >= double_bits) break :float inst; | 30740 | if (inst_bits >= double_bits) break :float inst; |
| 30456 | switch (double_bits) { | 30741 | switch (double_bits) { |
| 30457 | 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src), | 30742 | 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src), |
| ... | @@ -30461,7 +30746,7 @@ fn coerceVarArgParam( | ... | @@ -30461,7 +30746,7 @@ fn coerceVarArgParam( |
| 30461 | }, | 30746 | }, |
| 30462 | else => if (uncasted_ty.isAbiInt(mod)) int: { | 30747 | else => if (uncasted_ty.isAbiInt(mod)) int: { |
| 30463 | if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst; | 30748 | if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst; |
| 30464 | const target = sema.mod.getTarget(); | 30749 | const target = mod.getTarget(); |
| 30465 | const uncasted_info = uncasted_ty.intInfo(mod); | 30750 | const uncasted_info = uncasted_ty.intInfo(mod); |
| 30466 | if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { | 30751 | if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { |
| 30467 | .signed => .int, | 30752 | .signed => .int, |
| ... | @@ -30491,7 +30776,7 @@ fn coerceVarArgParam( | ... | @@ -30491,7 +30776,7 @@ fn coerceVarArgParam( |
| 30491 | const coerced_ty = sema.typeOf(coerced); | 30776 | const coerced_ty = sema.typeOf(coerced); |
| 30492 | if (!try sema.validateExternType(coerced_ty, .param_ty)) { | 30777 | if (!try sema.validateExternType(coerced_ty, .param_ty)) { |
| 30493 | const msg = msg: { | 30778 | const msg = msg: { |
| 30494 | const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)}); | 30779 | const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(pt)}); |
| 30495 | errdefer msg.destroy(sema.gpa); | 30780 | errdefer msg.destroy(sema.gpa); |
| 30496 | 30781 | ||
| 30497 | try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty); | 30782 | try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty); |
| ... | @@ -30526,7 +30811,8 @@ fn storePtr2( | ... | @@ -30526,7 +30811,8 @@ fn storePtr2( |
| 30526 | operand_src: LazySrcLoc, | 30811 | operand_src: LazySrcLoc, |
| 30527 | air_tag: Air.Inst.Tag, | 30812 | air_tag: Air.Inst.Tag, |
| 30528 | ) CompileError!void { | 30813 | ) CompileError!void { |
| 30529 | const mod = sema.mod; | 30814 | const pt = sema.pt; |
| 30815 | const mod = pt.zcu; | ||
| 30530 | const ptr_ty = sema.typeOf(ptr); | 30816 | const ptr_ty = sema.typeOf(ptr); |
| 30531 | if (ptr_ty.isConstPtr(mod)) | 30817 | if (ptr_ty.isConstPtr(mod)) |
| 30532 | return sema.fail(block, ptr_src, "cannot assign to constant", .{}); | 30818 | return sema.fail(block, ptr_src, "cannot assign to constant", .{}); |
| ... | @@ -30548,7 +30834,7 @@ fn storePtr2( | ... | @@ -30548,7 +30834,7 @@ fn storePtr2( |
| 30548 | while (i < field_count) : (i += 1) { | 30834 | while (i < field_count) : (i += 1) { |
| 30549 | const elem_src = operand_src; // TODO better source location | 30835 | const elem_src = operand_src; // TODO better source location |
| 30550 | const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i); | 30836 | const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i); |
| 30551 | const elem_index = try mod.intRef(Type.usize, i); | 30837 | const elem_index = try pt.intRef(Type.usize, i); |
| 30552 | const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true); | 30838 | const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true); |
| 30553 | try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store); | 30839 | try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store); |
| 30554 | } | 30840 | } |
| ... | @@ -30620,7 +30906,7 @@ fn storePtr2( | ... | @@ -30620,7 +30906,7 @@ fn storePtr2( |
| 30620 | return; | 30906 | return; |
| 30621 | } | 30907 | } |
| 30622 | return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{ | 30908 | return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{ |
| 30623 | ptr_ty.fmt(sema.mod), | 30909 | ptr_ty.fmt(pt), |
| 30624 | }); | 30910 | }); |
| 30625 | } | 30911 | } |
| 30626 | 30912 | ||
| ... | @@ -30734,7 +31020,8 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins | ... | @@ -30734,7 +31020,8 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins |
| 30734 | /// pointer. Only if the final element type matches the vector element type, and the | 31020 | /// pointer. Only if the final element type matches the vector element type, and the |
| 30735 | /// lengths match. | 31021 | /// lengths match. |
| 30736 | fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { | 31022 | fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 30737 | const mod = sema.mod; | 31023 | const pt = sema.pt; |
| 31024 | const mod = pt.zcu; | ||
| 30738 | const array_ty = sema.typeOf(ptr).childType(mod); | 31025 | const array_ty = sema.typeOf(ptr).childType(mod); |
| 30739 | if (array_ty.zigTypeTag(mod) != .Array) return null; | 31026 | if (array_ty.zigTypeTag(mod) != .Array) return null; |
| 30740 | var ptr_ref = ptr; | 31027 | var ptr_ref = ptr; |
| ... | @@ -30751,7 +31038,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { | ... | @@ -30751,7 +31038,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 30751 | 31038 | ||
| 30752 | // We have a pointer-to-array and a pointer-to-vector. If the elements and | 31039 | // We have a pointer-to-array and a pointer-to-vector. If the elements and |
| 30753 | // lengths match, return the result. | 31040 | // lengths match, return the result. |
| 30754 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and | 31041 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), mod) and |
| 30755 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) | 31042 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) |
| 30756 | { | 31043 | { |
| 30757 | return ptr_ref; | 31044 | return ptr_ref; |
| ... | @@ -30770,17 +31057,18 @@ fn storePtrVal( | ... | @@ -30770,17 +31057,18 @@ fn storePtrVal( |
| 30770 | operand_val: Value, | 31057 | operand_val: Value, |
| 30771 | operand_ty: Type, | 31058 | operand_ty: Type, |
| 30772 | ) !void { | 31059 | ) !void { |
| 30773 | const zcu = sema.mod; | 31060 | const pt = sema.pt; |
| 31061 | const zcu = pt.zcu; | ||
| 30774 | const ip = &zcu.intern_pool; | 31062 | const ip = &zcu.intern_pool; |
| 30775 | // TODO: audit use sites to eliminate this coercion | 31063 | // TODO: audit use sites to eliminate this coercion |
| 30776 | const coerced_operand_val = try zcu.getCoerced(operand_val, operand_ty); | 31064 | const coerced_operand_val = try pt.getCoerced(operand_val, operand_ty); |
| 30777 | // TODO: audit use sites to eliminate this coercion | 31065 | // TODO: audit use sites to eliminate this coercion |
| 30778 | const ptr_ty = try zcu.ptrType(info: { | 31066 | const ptr_ty = try pt.ptrType(info: { |
| 30779 | var info = ptr_val.typeOf(zcu).ptrInfo(zcu); | 31067 | var info = ptr_val.typeOf(zcu).ptrInfo(zcu); |
| 30780 | info.child = operand_ty.toIntern(); | 31068 | info.child = operand_ty.toIntern(); |
| 30781 | break :info info; | 31069 | break :info info; |
| 30782 | }); | 31070 | }); |
| 30783 | const coerced_ptr_val = try zcu.getCoerced(ptr_val, ptr_ty); | 31071 | const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty); |
| 30784 | 31072 | ||
| 30785 | switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) { | 31073 | switch (try sema.storeComptimePtr(block, src, coerced_ptr_val, coerced_operand_val)) { |
| 30786 | .success => {}, | 31074 | .success => {}, |
| ... | @@ -30800,13 +31088,13 @@ fn storePtrVal( | ... | @@ -30800,13 +31088,13 @@ fn storePtrVal( |
| 30800 | block, | 31088 | block, |
| 30801 | src, | 31089 | src, |
| 30802 | "comptime dereference requires '{}' to have a well-defined layout", | 31090 | "comptime dereference requires '{}' to have a well-defined layout", |
| 30803 | .{ty.fmt(zcu)}, | 31091 | .{ty.fmt(pt)}, |
| 30804 | ), | 31092 | ), |
| 30805 | .out_of_bounds => |ty| return sema.fail( | 31093 | .out_of_bounds => |ty| return sema.fail( |
| 30806 | block, | 31094 | block, |
| 30807 | src, | 31095 | src, |
| 30808 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", | 31096 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", |
| 30809 | .{ ptr_ty.fmt(zcu), ty.fmt(zcu) }, | 31097 | .{ ptr_ty.fmt(pt), ty.fmt(pt) }, |
| 30810 | ), | 31098 | ), |
| 30811 | .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}), | 31099 | .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}), |
| 30812 | } | 31100 | } |
| ... | @@ -30820,31 +31108,32 @@ fn bitCast( | ... | @@ -30820,31 +31108,32 @@ fn bitCast( |
| 30820 | inst_src: LazySrcLoc, | 31108 | inst_src: LazySrcLoc, |
| 30821 | operand_src: ?LazySrcLoc, | 31109 | operand_src: ?LazySrcLoc, |
| 30822 | ) CompileError!Air.Inst.Ref { | 31110 | ) CompileError!Air.Inst.Ref { |
| 30823 | const zcu = sema.mod; | 31111 | const pt = sema.pt; |
| 30824 | try dest_ty.resolveLayout(zcu); | 31112 | const zcu = pt.zcu; |
| 31113 | try dest_ty.resolveLayout(pt); | ||
| 30825 | 31114 | ||
| 30826 | const old_ty = sema.typeOf(inst); | 31115 | const old_ty = sema.typeOf(inst); |
| 30827 | try old_ty.resolveLayout(zcu); | 31116 | try old_ty.resolveLayout(pt); |
| 30828 | 31117 | ||
| 30829 | const dest_bits = dest_ty.bitSize(zcu); | 31118 | const dest_bits = dest_ty.bitSize(pt); |
| 30830 | const old_bits = old_ty.bitSize(zcu); | 31119 | const old_bits = old_ty.bitSize(pt); |
| 30831 | 31120 | ||
| 30832 | if (old_bits != dest_bits) { | 31121 | if (old_bits != dest_bits) { |
| 30833 | return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{ | 31122 | return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{ |
| 30834 | dest_ty.fmt(zcu), | 31123 | dest_ty.fmt(pt), |
| 30835 | dest_bits, | 31124 | dest_bits, |
| 30836 | old_ty.fmt(zcu), | 31125 | old_ty.fmt(pt), |
| 30837 | old_bits, | 31126 | old_bits, |
| 30838 | }); | 31127 | }); |
| 30839 | } | 31128 | } |
| 30840 | 31129 | ||
| 30841 | if (try sema.resolveValue(inst)) |val| { | 31130 | if (try sema.resolveValue(inst)) |val| { |
| 30842 | if (val.isUndef(zcu)) | 31131 | if (val.isUndef(zcu)) |
| 30843 | return zcu.undefRef(dest_ty); | 31132 | return pt.undefRef(dest_ty); |
| 30844 | if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) { | 31133 | if (old_ty.zigTypeTag(zcu) == .ErrorSet and dest_ty.zigTypeTag(zcu) == .ErrorSet) { |
| 30845 | // Special case: we sometimes call `bitCast` on error set values, but they | 31134 | // Special case: we sometimes call `bitCast` on error set values, but they |
| 30846 | // don't have a well-defined layout, so we can't use `bitCastVal` on them. | 31135 | // don't have a well-defined layout, so we can't use `bitCastVal` on them. |
| 30847 | return Air.internedToRef((try zcu.getCoerced(val, dest_ty)).toIntern()); | 31136 | return Air.internedToRef((try pt.getCoerced(val, dest_ty)).toIntern()); |
| 30848 | } | 31137 | } |
| 30849 | if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| { | 31138 | if (try sema.bitCastVal(val, dest_ty, 0, 0, 0)) |result_val| { |
| 30850 | return Air.internedToRef(result_val.toIntern()); | 31139 | return Air.internedToRef(result_val.toIntern()); |
| ... | @@ -30862,16 +31151,17 @@ fn coerceArrayPtrToSlice( | ... | @@ -30862,16 +31151,17 @@ fn coerceArrayPtrToSlice( |
| 30862 | inst: Air.Inst.Ref, | 31151 | inst: Air.Inst.Ref, |
| 30863 | inst_src: LazySrcLoc, | 31152 | inst_src: LazySrcLoc, |
| 30864 | ) CompileError!Air.Inst.Ref { | 31153 | ) CompileError!Air.Inst.Ref { |
| 30865 | const mod = sema.mod; | 31154 | const pt = sema.pt; |
| 31155 | const mod = pt.zcu; | ||
| 30866 | if (try sema.resolveValue(inst)) |val| { | 31156 | if (try sema.resolveValue(inst)) |val| { |
| 30867 | const ptr_array_ty = sema.typeOf(inst); | 31157 | const ptr_array_ty = sema.typeOf(inst); |
| 30868 | const array_ty = ptr_array_ty.childType(mod); | 31158 | const array_ty = ptr_array_ty.childType(mod); |
| 30869 | const slice_ptr_ty = dest_ty.slicePtrFieldType(mod); | 31159 | const slice_ptr_ty = dest_ty.slicePtrFieldType(mod); |
| 30870 | const slice_ptr = try mod.getCoerced(val, slice_ptr_ty); | 31160 | const slice_ptr = try pt.getCoerced(val, slice_ptr_ty); |
| 30871 | const slice_val = try mod.intern(.{ .slice = .{ | 31161 | const slice_val = try pt.intern(.{ .slice = .{ |
| 30872 | .ty = dest_ty.toIntern(), | 31162 | .ty = dest_ty.toIntern(), |
| 30873 | .ptr = slice_ptr.toIntern(), | 31163 | .ptr = slice_ptr.toIntern(), |
| 30874 | .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), | 31164 | .len = (try pt.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), |
| 30875 | } }); | 31165 | } }); |
| 30876 | return Air.internedToRef(slice_val); | 31166 | return Air.internedToRef(slice_val); |
| 30877 | } | 31167 | } |
| ... | @@ -30880,7 +31170,8 @@ fn coerceArrayPtrToSlice( | ... | @@ -30880,7 +31170,8 @@ fn coerceArrayPtrToSlice( |
| 30880 | } | 31170 | } |
| 30881 | 31171 | ||
| 30882 | fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool { | 31172 | fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool { |
| 30883 | const mod = sema.mod; | 31173 | const pt = sema.pt; |
| 31174 | const mod = pt.zcu; | ||
| 30884 | const dest_info = dest_ty.ptrInfo(mod); | 31175 | const dest_info = dest_ty.ptrInfo(mod); |
| 30885 | const inst_info = inst_ty.ptrInfo(mod); | 31176 | const inst_info = inst_ty.ptrInfo(mod); |
| 30886 | const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or | 31177 | const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or |
| ... | @@ -30913,12 +31204,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul | ... | @@ -30913,12 +31204,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul |
| 30913 | const inst_align = if (inst_info.flags.alignment != .none) | 31204 | const inst_align = if (inst_info.flags.alignment != .none) |
| 30914 | inst_info.flags.alignment | 31205 | inst_info.flags.alignment |
| 30915 | else | 31206 | else |
| 30916 | Type.fromInterned(inst_info.child).abiAlignment(mod); | 31207 | Type.fromInterned(inst_info.child).abiAlignment(pt); |
| 30917 | 31208 | ||
| 30918 | const dest_align = if (dest_info.flags.alignment != .none) | 31209 | const dest_align = if (dest_info.flags.alignment != .none) |
| 30919 | dest_info.flags.alignment | 31210 | dest_info.flags.alignment |
| 30920 | else | 31211 | else |
| 30921 | Type.fromInterned(dest_info.child).abiAlignment(mod); | 31212 | Type.fromInterned(dest_info.child).abiAlignment(pt); |
| 30922 | 31213 | ||
| 30923 | if (dest_align.compare(.gt, inst_align)) { | 31214 | if (dest_align.compare(.gt, inst_align)) { |
| 30924 | in_memory_result.* = .{ .ptr_alignment = .{ | 31215 | in_memory_result.* = .{ .ptr_alignment = .{ |
| ... | @@ -30937,15 +31228,16 @@ fn coerceCompatiblePtrs( | ... | @@ -30937,15 +31228,16 @@ fn coerceCompatiblePtrs( |
| 30937 | inst: Air.Inst.Ref, | 31228 | inst: Air.Inst.Ref, |
| 30938 | inst_src: LazySrcLoc, | 31229 | inst_src: LazySrcLoc, |
| 30939 | ) !Air.Inst.Ref { | 31230 | ) !Air.Inst.Ref { |
| 30940 | const mod = sema.mod; | 31231 | const pt = sema.pt; |
| 31232 | const mod = pt.zcu; | ||
| 30941 | const inst_ty = sema.typeOf(inst); | 31233 | const inst_ty = sema.typeOf(inst); |
| 30942 | if (try sema.resolveValue(inst)) |val| { | 31234 | if (try sema.resolveValue(inst)) |val| { |
| 30943 | if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) { | 31235 | if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) { |
| 30944 | return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)}); | 31236 | return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)}); |
| 30945 | } | 31237 | } |
| 30946 | // The comptime Value representation is compatible with both types. | 31238 | // The comptime Value representation is compatible with both types. |
| 30947 | return Air.internedToRef( | 31239 | return Air.internedToRef( |
| 30948 | (try mod.getCoerced(val, dest_ty)).toIntern(), | 31240 | (try pt.getCoerced(val, dest_ty)).toIntern(), |
| 30949 | ); | 31241 | ); |
| 30950 | } | 31242 | } |
| 30951 | try sema.requireRuntimeBlock(block, inst_src, null); | 31243 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | @@ -30979,14 +31271,15 @@ fn coerceEnumToUnion( | ... | @@ -30979,14 +31271,15 @@ fn coerceEnumToUnion( |
| 30979 | inst: Air.Inst.Ref, | 31271 | inst: Air.Inst.Ref, |
| 30980 | inst_src: LazySrcLoc, | 31272 | inst_src: LazySrcLoc, |
| 30981 | ) !Air.Inst.Ref { | 31273 | ) !Air.Inst.Ref { |
| 30982 | const mod = sema.mod; | 31274 | const pt = sema.pt; |
| 31275 | const mod = pt.zcu; | ||
| 30983 | const ip = &mod.intern_pool; | 31276 | const ip = &mod.intern_pool; |
| 30984 | const inst_ty = sema.typeOf(inst); | 31277 | const inst_ty = sema.typeOf(inst); |
| 30985 | 31278 | ||
| 30986 | const tag_ty = union_ty.unionTagType(mod) orelse { | 31279 | const tag_ty = union_ty.unionTagType(mod) orelse { |
| 30987 | const msg = msg: { | 31280 | const msg = msg: { |
| 30988 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ | 31281 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ |
| 30989 | union_ty.fmt(sema.mod), inst_ty.fmt(sema.mod), | 31282 | union_ty.fmt(pt), inst_ty.fmt(pt), |
| 30990 | }); | 31283 | }); |
| 30991 | errdefer msg.destroy(sema.gpa); | 31284 | errdefer msg.destroy(sema.gpa); |
| 30992 | try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{}); | 31285 | try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{}); |
| ... | @@ -30998,15 +31291,15 @@ fn coerceEnumToUnion( | ... | @@ -30998,15 +31291,15 @@ fn coerceEnumToUnion( |
| 30998 | 31291 | ||
| 30999 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); | 31292 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); |
| 31000 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { | 31293 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 31001 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { | 31294 | const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse { |
| 31002 | return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ | 31295 | return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 31003 | union_ty.fmt(sema.mod), val.fmtValue(sema.mod, sema), | 31296 | union_ty.fmt(pt), val.fmtValue(pt, sema), |
| 31004 | }); | 31297 | }); |
| 31005 | }; | 31298 | }; |
| 31006 | 31299 | ||
| 31007 | const union_obj = mod.typeToUnion(union_ty).?; | 31300 | const union_obj = mod.typeToUnion(union_ty).?; |
| 31008 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 31301 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31009 | try field_ty.resolveFields(mod); | 31302 | try field_ty.resolveFields(pt); |
| 31010 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | 31303 | if (field_ty.zigTypeTag(mod) == .NoReturn) { |
| 31011 | const msg = msg: { | 31304 | const msg = msg: { |
| 31012 | const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{}); | 31305 | const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{}); |
| ... | @@ -31025,8 +31318,8 @@ fn coerceEnumToUnion( | ... | @@ -31025,8 +31318,8 @@ fn coerceEnumToUnion( |
| 31025 | const msg = msg: { | 31318 | const msg = msg: { |
| 31026 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; | 31319 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; |
| 31027 | const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{ | 31320 | const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{ |
| 31028 | inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), | 31321 | inst_ty.fmt(pt), union_ty.fmt(pt), |
| 31029 | field_ty.fmt(sema.mod), field_name.fmt(ip), | 31322 | field_ty.fmt(pt), field_name.fmt(ip), |
| 31030 | }); | 31323 | }); |
| 31031 | errdefer msg.destroy(sema.gpa); | 31324 | errdefer msg.destroy(sema.gpa); |
| 31032 | 31325 | ||
| ... | @@ -31039,7 +31332,7 @@ fn coerceEnumToUnion( | ... | @@ -31039,7 +31332,7 @@ fn coerceEnumToUnion( |
| 31039 | return sema.failWithOwnedErrorMsg(block, msg); | 31332 | return sema.failWithOwnedErrorMsg(block, msg); |
| 31040 | }; | 31333 | }; |
| 31041 | 31334 | ||
| 31042 | return Air.internedToRef((try mod.unionValue(union_ty, val, opv)).toIntern()); | 31335 | return Air.internedToRef((try pt.unionValue(union_ty, val, opv)).toIntern()); |
| 31043 | } | 31336 | } |
| 31044 | 31337 | ||
| 31045 | try sema.requireRuntimeBlock(block, inst_src, null); | 31338 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | @@ -31047,7 +31340,7 @@ fn coerceEnumToUnion( | ... | @@ -31047,7 +31340,7 @@ fn coerceEnumToUnion( |
| 31047 | if (tag_ty.isNonexhaustiveEnum(mod)) { | 31340 | if (tag_ty.isNonexhaustiveEnum(mod)) { |
| 31048 | const msg = msg: { | 31341 | const msg = msg: { |
| 31049 | const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{ | 31342 | const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{ |
| 31050 | union_ty.fmt(sema.mod), | 31343 | union_ty.fmt(pt), |
| 31051 | }); | 31344 | }); |
| 31052 | errdefer msg.destroy(sema.gpa); | 31345 | errdefer msg.destroy(sema.gpa); |
| 31053 | try sema.addDeclaredHereNote(msg, tag_ty); | 31346 | try sema.addDeclaredHereNote(msg, tag_ty); |
| ... | @@ -31066,7 +31359,7 @@ fn coerceEnumToUnion( | ... | @@ -31066,7 +31359,7 @@ fn coerceEnumToUnion( |
| 31066 | const err_msg = msg orelse try sema.errMsg( | 31359 | const err_msg = msg orelse try sema.errMsg( |
| 31067 | inst_src, | 31360 | inst_src, |
| 31068 | "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field", | 31361 | "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field", |
| 31069 | .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) }, | 31362 | .{ tag_ty.fmt(pt), union_ty.fmt(pt) }, |
| 31070 | ); | 31363 | ); |
| 31071 | msg = err_msg; | 31364 | msg = err_msg; |
| 31072 | 31365 | ||
| ... | @@ -31081,7 +31374,7 @@ fn coerceEnumToUnion( | ... | @@ -31081,7 +31374,7 @@ fn coerceEnumToUnion( |
| 31081 | } | 31374 | } |
| 31082 | 31375 | ||
| 31083 | // If the union has all fields 0 bits, the union value is just the enum value. | 31376 | // If the union has all fields 0 bits, the union value is just the enum value. |
| 31084 | if (union_ty.unionHasAllZeroBitFieldTypes(mod)) { | 31377 | if (union_ty.unionHasAllZeroBitFieldTypes(pt)) { |
| 31085 | return block.addBitCast(union_ty, enum_tag); | 31378 | return block.addBitCast(union_ty, enum_tag); |
| 31086 | } | 31379 | } |
| 31087 | 31380 | ||
| ... | @@ -31089,7 +31382,7 @@ fn coerceEnumToUnion( | ... | @@ -31089,7 +31382,7 @@ fn coerceEnumToUnion( |
| 31089 | const msg = try sema.errMsg( | 31382 | const msg = try sema.errMsg( |
| 31090 | inst_src, | 31383 | inst_src, |
| 31091 | "runtime coercion from enum '{}' to union '{}' which has non-void fields", | 31384 | "runtime coercion from enum '{}' to union '{}' which has non-void fields", |
| 31092 | .{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) }, | 31385 | .{ tag_ty.fmt(pt), union_ty.fmt(pt) }, |
| 31093 | ); | 31386 | ); |
| 31094 | errdefer msg.destroy(sema.gpa); | 31387 | errdefer msg.destroy(sema.gpa); |
| 31095 | 31388 | ||
| ... | @@ -31099,7 +31392,7 @@ fn coerceEnumToUnion( | ... | @@ -31099,7 +31392,7 @@ fn coerceEnumToUnion( |
| 31099 | if (!(try sema.typeHasRuntimeBits(field_ty))) continue; | 31392 | if (!(try sema.typeHasRuntimeBits(field_ty))) continue; |
| 31100 | try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ | 31393 | try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ |
| 31101 | field_name.fmt(ip), | 31394 | field_name.fmt(ip), |
| 31102 | field_ty.fmt(sema.mod), | 31395 | field_ty.fmt(pt), |
| 31103 | }); | 31396 | }); |
| 31104 | } | 31397 | } |
| 31105 | try sema.addDeclaredHereNote(msg, union_ty); | 31398 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | @@ -31116,7 +31409,8 @@ fn coerceAnonStructToUnion( | ... | @@ -31116,7 +31409,8 @@ fn coerceAnonStructToUnion( |
| 31116 | inst: Air.Inst.Ref, | 31409 | inst: Air.Inst.Ref, |
| 31117 | inst_src: LazySrcLoc, | 31410 | inst_src: LazySrcLoc, |
| 31118 | ) !Air.Inst.Ref { | 31411 | ) !Air.Inst.Ref { |
| 31119 | const mod = sema.mod; | 31412 | const pt = sema.pt; |
| 31413 | const mod = pt.zcu; | ||
| 31120 | const ip = &mod.intern_pool; | 31414 | const ip = &mod.intern_pool; |
| 31121 | const inst_ty = sema.typeOf(inst); | 31415 | const inst_ty = sema.typeOf(inst); |
| 31122 | const field_info: union(enum) { | 31416 | const field_info: union(enum) { |
| ... | @@ -31174,7 +31468,8 @@ fn coerceAnonStructToUnionPtrs( | ... | @@ -31174,7 +31468,8 @@ fn coerceAnonStructToUnionPtrs( |
| 31174 | ptr_anon_struct: Air.Inst.Ref, | 31468 | ptr_anon_struct: Air.Inst.Ref, |
| 31175 | anon_struct_src: LazySrcLoc, | 31469 | anon_struct_src: LazySrcLoc, |
| 31176 | ) !Air.Inst.Ref { | 31470 | ) !Air.Inst.Ref { |
| 31177 | const mod = sema.mod; | 31471 | const pt = sema.pt; |
| 31472 | const mod = pt.zcu; | ||
| 31178 | const union_ty = ptr_union_ty.childType(mod); | 31473 | const union_ty = ptr_union_ty.childType(mod); |
| 31179 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); | 31474 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); |
| 31180 | const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src); | 31475 | const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src); |
| ... | @@ -31189,7 +31484,8 @@ fn coerceAnonStructToStructPtrs( | ... | @@ -31189,7 +31484,8 @@ fn coerceAnonStructToStructPtrs( |
| 31189 | ptr_anon_struct: Air.Inst.Ref, | 31484 | ptr_anon_struct: Air.Inst.Ref, |
| 31190 | anon_struct_src: LazySrcLoc, | 31485 | anon_struct_src: LazySrcLoc, |
| 31191 | ) !Air.Inst.Ref { | 31486 | ) !Air.Inst.Ref { |
| 31192 | const mod = sema.mod; | 31487 | const pt = sema.pt; |
| 31488 | const mod = pt.zcu; | ||
| 31193 | const struct_ty = ptr_struct_ty.childType(mod); | 31489 | const struct_ty = ptr_struct_ty.childType(mod); |
| 31194 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); | 31490 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); |
| 31195 | const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src); | 31491 | const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src); |
| ... | @@ -31205,7 +31501,8 @@ fn coerceArrayLike( | ... | @@ -31205,7 +31501,8 @@ fn coerceArrayLike( |
| 31205 | inst: Air.Inst.Ref, | 31501 | inst: Air.Inst.Ref, |
| 31206 | inst_src: LazySrcLoc, | 31502 | inst_src: LazySrcLoc, |
| 31207 | ) !Air.Inst.Ref { | 31503 | ) !Air.Inst.Ref { |
| 31208 | const mod = sema.mod; | 31504 | const pt = sema.pt; |
| 31505 | const mod = pt.zcu; | ||
| 31209 | const inst_ty = sema.typeOf(inst); | 31506 | const inst_ty = sema.typeOf(inst); |
| 31210 | const target = mod.getTarget(); | 31507 | const target = mod.getTarget(); |
| 31211 | 31508 | ||
| ... | @@ -31226,7 +31523,7 @@ fn coerceArrayLike( | ... | @@ -31226,7 +31523,7 @@ fn coerceArrayLike( |
| 31226 | if (dest_len != inst_len) { | 31523 | if (dest_len != inst_len) { |
| 31227 | const msg = msg: { | 31524 | const msg = msg: { |
| 31228 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ | 31525 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ |
| 31229 | dest_ty.fmt(mod), inst_ty.fmt(mod), | 31526 | dest_ty.fmt(pt), inst_ty.fmt(pt), |
| 31230 | }); | 31527 | }); |
| 31231 | errdefer msg.destroy(sema.gpa); | 31528 | errdefer msg.destroy(sema.gpa); |
| 31232 | try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len}); | 31529 | try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len}); |
| ... | @@ -31270,7 +31567,7 @@ fn coerceArrayLike( | ... | @@ -31270,7 +31567,7 @@ fn coerceArrayLike( |
| 31270 | var runtime_src: ?LazySrcLoc = null; | 31567 | var runtime_src: ?LazySrcLoc = null; |
| 31271 | 31568 | ||
| 31272 | for (element_vals, element_refs, 0..) |*val, *ref, i| { | 31569 | for (element_vals, element_refs, 0..) |*val, *ref, i| { |
| 31273 | const index_ref = Air.internedToRef((try mod.intValue(Type.usize, i)).toIntern()); | 31570 | const index_ref = Air.internedToRef((try pt.intValue(Type.usize, i)).toIntern()); |
| 31274 | const src = inst_src; // TODO better source location | 31571 | const src = inst_src; // TODO better source location |
| 31275 | const elem_src = inst_src; // TODO better source location | 31572 | const elem_src = inst_src; // TODO better source location |
| 31276 | const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true); | 31573 | const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref, true); |
| ... | @@ -31290,7 +31587,7 @@ fn coerceArrayLike( | ... | @@ -31290,7 +31587,7 @@ fn coerceArrayLike( |
| 31290 | return block.addAggregateInit(dest_ty, element_refs); | 31587 | return block.addAggregateInit(dest_ty, element_refs); |
| 31291 | } | 31588 | } |
| 31292 | 31589 | ||
| 31293 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 31590 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 31294 | .ty = dest_ty.toIntern(), | 31591 | .ty = dest_ty.toIntern(), |
| 31295 | .storage = .{ .elems = element_vals }, | 31592 | .storage = .{ .elems = element_vals }, |
| 31296 | } }))); | 31593 | } }))); |
| ... | @@ -31305,7 +31602,8 @@ fn coerceTupleToArray( | ... | @@ -31305,7 +31602,8 @@ fn coerceTupleToArray( |
| 31305 | inst: Air.Inst.Ref, | 31602 | inst: Air.Inst.Ref, |
| 31306 | inst_src: LazySrcLoc, | 31603 | inst_src: LazySrcLoc, |
| 31307 | ) !Air.Inst.Ref { | 31604 | ) !Air.Inst.Ref { |
| 31308 | const mod = sema.mod; | 31605 | const pt = sema.pt; |
| 31606 | const mod = pt.zcu; | ||
| 31309 | const inst_ty = sema.typeOf(inst); | 31607 | const inst_ty = sema.typeOf(inst); |
| 31310 | const inst_len = inst_ty.arrayLen(mod); | 31608 | const inst_len = inst_ty.arrayLen(mod); |
| 31311 | const dest_len = dest_ty.arrayLen(mod); | 31609 | const dest_len = dest_ty.arrayLen(mod); |
| ... | @@ -31313,7 +31611,7 @@ fn coerceTupleToArray( | ... | @@ -31313,7 +31611,7 @@ fn coerceTupleToArray( |
| 31313 | if (dest_len != inst_len) { | 31611 | if (dest_len != inst_len) { |
| 31314 | const msg = msg: { | 31612 | const msg = msg: { |
| 31315 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ | 31613 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ |
| 31316 | dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod), | 31614 | dest_ty.fmt(pt), inst_ty.fmt(pt), |
| 31317 | }); | 31615 | }); |
| 31318 | errdefer msg.destroy(sema.gpa); | 31616 | errdefer msg.destroy(sema.gpa); |
| 31319 | try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len}); | 31617 | try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len}); |
| ... | @@ -31355,7 +31653,7 @@ fn coerceTupleToArray( | ... | @@ -31355,7 +31653,7 @@ fn coerceTupleToArray( |
| 31355 | return block.addAggregateInit(dest_ty, element_refs); | 31653 | return block.addAggregateInit(dest_ty, element_refs); |
| 31356 | } | 31654 | } |
| 31357 | 31655 | ||
| 31358 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 31656 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 31359 | .ty = dest_ty.toIntern(), | 31657 | .ty = dest_ty.toIntern(), |
| 31360 | .storage = .{ .elems = element_vals }, | 31658 | .storage = .{ .elems = element_vals }, |
| 31361 | } }))); | 31659 | } }))); |
| ... | @@ -31370,11 +31668,12 @@ fn coerceTupleToSlicePtrs( | ... | @@ -31370,11 +31668,12 @@ fn coerceTupleToSlicePtrs( |
| 31370 | ptr_tuple: Air.Inst.Ref, | 31668 | ptr_tuple: Air.Inst.Ref, |
| 31371 | tuple_src: LazySrcLoc, | 31669 | tuple_src: LazySrcLoc, |
| 31372 | ) !Air.Inst.Ref { | 31670 | ) !Air.Inst.Ref { |
| 31373 | const mod = sema.mod; | 31671 | const pt = sema.pt; |
| 31672 | const mod = pt.zcu; | ||
| 31374 | const tuple_ty = sema.typeOf(ptr_tuple).childType(mod); | 31673 | const tuple_ty = sema.typeOf(ptr_tuple).childType(mod); |
| 31375 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); | 31674 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 31376 | const slice_info = slice_ty.ptrInfo(mod); | 31675 | const slice_info = slice_ty.ptrInfo(mod); |
| 31377 | const array_ty = try mod.arrayType(.{ | 31676 | const array_ty = try pt.arrayType(.{ |
| 31378 | .len = tuple_ty.structFieldCount(mod), | 31677 | .len = tuple_ty.structFieldCount(mod), |
| 31379 | .sentinel = slice_info.sentinel, | 31678 | .sentinel = slice_info.sentinel, |
| 31380 | .child = slice_info.child, | 31679 | .child = slice_info.child, |
| ... | @@ -31396,7 +31695,8 @@ fn coerceTupleToArrayPtrs( | ... | @@ -31396,7 +31695,8 @@ fn coerceTupleToArrayPtrs( |
| 31396 | ptr_tuple: Air.Inst.Ref, | 31695 | ptr_tuple: Air.Inst.Ref, |
| 31397 | tuple_src: LazySrcLoc, | 31696 | tuple_src: LazySrcLoc, |
| 31398 | ) !Air.Inst.Ref { | 31697 | ) !Air.Inst.Ref { |
| 31399 | const mod = sema.mod; | 31698 | const pt = sema.pt; |
| 31699 | const mod = pt.zcu; | ||
| 31400 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); | 31700 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 31401 | const ptr_info = ptr_array_ty.ptrInfo(mod); | 31701 | const ptr_info = ptr_array_ty.ptrInfo(mod); |
| 31402 | const array_ty = Type.fromInterned(ptr_info.child); | 31702 | const array_ty = Type.fromInterned(ptr_info.child); |
| ... | @@ -31417,10 +31717,11 @@ fn coerceTupleToStruct( | ... | @@ -31417,10 +31717,11 @@ fn coerceTupleToStruct( |
| 31417 | inst: Air.Inst.Ref, | 31717 | inst: Air.Inst.Ref, |
| 31418 | inst_src: LazySrcLoc, | 31718 | inst_src: LazySrcLoc, |
| 31419 | ) !Air.Inst.Ref { | 31719 | ) !Air.Inst.Ref { |
| 31420 | const mod = sema.mod; | 31720 | const pt = sema.pt; |
| 31721 | const mod = pt.zcu; | ||
| 31421 | const ip = &mod.intern_pool; | 31722 | const ip = &mod.intern_pool; |
| 31422 | try struct_ty.resolveFields(mod); | 31723 | try struct_ty.resolveFields(pt); |
| 31423 | try struct_ty.resolveStructFieldInits(mod); | 31724 | try struct_ty.resolveStructFieldInits(pt); |
| 31424 | 31725 | ||
| 31425 | if (struct_ty.isTupleOrAnonStruct(mod)) { | 31726 | if (struct_ty.isTupleOrAnonStruct(mod)) { |
| 31426 | return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src); | 31727 | return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src); |
| ... | @@ -31461,7 +31762,7 @@ fn coerceTupleToStruct( | ... | @@ -31461,7 +31762,7 @@ fn coerceTupleToStruct( |
| 31461 | }; | 31762 | }; |
| 31462 | 31763 | ||
| 31463 | const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]); | 31764 | const field_init = Value.fromInterned(struct_type.field_inits.get(ip)[struct_field_index]); |
| 31464 | if (!init_val.eql(field_init, struct_field_ty, sema.mod)) { | 31765 | if (!init_val.eql(field_init, struct_field_ty, pt.zcu)) { |
| 31465 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index); | 31766 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, tuple_field_index); |
| 31466 | } | 31767 | } |
| 31467 | } | 31768 | } |
| ... | @@ -31512,7 +31813,7 @@ fn coerceTupleToStruct( | ... | @@ -31512,7 +31813,7 @@ fn coerceTupleToStruct( |
| 31512 | return block.addAggregateInit(struct_ty, field_refs); | 31813 | return block.addAggregateInit(struct_ty, field_refs); |
| 31513 | } | 31814 | } |
| 31514 | 31815 | ||
| 31515 | const struct_val = try mod.intern(.{ .aggregate = .{ | 31816 | const struct_val = try pt.intern(.{ .aggregate = .{ |
| 31516 | .ty = struct_ty.toIntern(), | 31817 | .ty = struct_ty.toIntern(), |
| 31517 | .storage = .{ .elems = field_vals }, | 31818 | .storage = .{ .elems = field_vals }, |
| 31518 | } }); | 31819 | } }); |
| ... | @@ -31529,7 +31830,8 @@ fn coerceTupleToTuple( | ... | @@ -31529,7 +31830,8 @@ fn coerceTupleToTuple( |
| 31529 | inst: Air.Inst.Ref, | 31830 | inst: Air.Inst.Ref, |
| 31530 | inst_src: LazySrcLoc, | 31831 | inst_src: LazySrcLoc, |
| 31531 | ) !Air.Inst.Ref { | 31832 | ) !Air.Inst.Ref { |
| 31532 | const mod = sema.mod; | 31833 | const pt = sema.pt; |
| 31834 | const mod = pt.zcu; | ||
| 31533 | const ip = &mod.intern_pool; | 31835 | const ip = &mod.intern_pool; |
| 31534 | const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) { | 31836 | const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) { |
| 31535 | .anon_struct_type => |anon_struct_type| anon_struct_type.types.len, | 31837 | .anon_struct_type => |anon_struct_type| anon_struct_type.types.len, |
| ... | @@ -31594,7 +31896,7 @@ fn coerceTupleToTuple( | ... | @@ -31594,7 +31896,7 @@ fn coerceTupleToTuple( |
| 31594 | }); | 31896 | }); |
| 31595 | }; | 31897 | }; |
| 31596 | 31898 | ||
| 31597 | if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), sema.mod)) { | 31899 | if (!init_val.eql(Value.fromInterned(default_val), Type.fromInterned(field_ty), pt.zcu)) { |
| 31598 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i); | 31900 | return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i); |
| 31599 | } | 31901 | } |
| 31600 | } | 31902 | } |
| ... | @@ -31659,7 +31961,7 @@ fn coerceTupleToTuple( | ... | @@ -31659,7 +31961,7 @@ fn coerceTupleToTuple( |
| 31659 | return block.addAggregateInit(tuple_ty, field_refs); | 31961 | return block.addAggregateInit(tuple_ty, field_refs); |
| 31660 | } | 31962 | } |
| 31661 | 31963 | ||
| 31662 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 31964 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 31663 | .ty = tuple_ty.toIntern(), | 31965 | .ty = tuple_ty.toIntern(), |
| 31664 | .storage = .{ .elems = field_vals }, | 31966 | .storage = .{ .elems = field_vals }, |
| 31665 | } }))); | 31967 | } }))); |
| ... | @@ -31689,17 +31991,19 @@ fn addReferenceEntry( | ... | @@ -31689,17 +31991,19 @@ fn addReferenceEntry( |
| 31689 | src: LazySrcLoc, | 31991 | src: LazySrcLoc, |
| 31690 | referenced_unit: AnalUnit, | 31992 | referenced_unit: AnalUnit, |
| 31691 | ) !void { | 31993 | ) !void { |
| 31692 | if (sema.mod.comp.reference_trace == 0) return; | 31994 | const zcu = sema.pt.zcu; |
| 31995 | if (zcu.comp.reference_trace == 0) return; | ||
| 31693 | const gop = try sema.references.getOrPut(sema.gpa, referenced_unit); | 31996 | const gop = try sema.references.getOrPut(sema.gpa, referenced_unit); |
| 31694 | if (gop.found_existing) return; | 31997 | if (gop.found_existing) return; |
| 31695 | // TODO: we need to figure out how to model inline calls here. | 31998 | // TODO: we need to figure out how to model inline calls here. |
| 31696 | // They aren't references in the analysis sense, but ought to show up in the reference trace! | 31999 | // They aren't references in the analysis sense, but ought to show up in the reference trace! |
| 31697 | // Would representing inline calls in the reference table cause excessive memory usage? | 32000 | // Would representing inline calls in the reference table cause excessive memory usage? |
| 31698 | try sema.mod.addUnitReference(sema.ownerUnit(), referenced_unit, src); | 32001 | try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src); |
| 31699 | } | 32002 | } |
| 31700 | 32003 | ||
| 31701 | pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void { | 32004 | pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void { |
| 31702 | const mod = sema.mod; | 32005 | const pt = sema.pt; |
| 32006 | const mod = pt.zcu; | ||
| 31703 | const ip = &mod.intern_pool; | 32007 | const ip = &mod.intern_pool; |
| 31704 | const decl = mod.declPtr(decl_index); | 32008 | const decl = mod.declPtr(decl_index); |
| 31705 | if (decl.analysis == .in_progress) { | 32009 | if (decl.analysis == .in_progress) { |
| ... | @@ -31710,7 +32014,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile | ... | @@ -31710,7 +32014,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile |
| 31710 | return sema.failWithOwnedErrorMsg(null, msg); | 32014 | return sema.failWithOwnedErrorMsg(null, msg); |
| 31711 | } | 32015 | } |
| 31712 | 32016 | ||
| 31713 | mod.ensureDeclAnalyzed(decl_index) catch |err| { | 32017 | pt.ensureDeclAnalyzed(decl_index) catch |err| { |
| 31714 | if (sema.owner_func_index != .none) { | 32018 | if (sema.owner_func_index != .none) { |
| 31715 | ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure; | 32019 | ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure; |
| 31716 | } else { | 32020 | } else { |
| ... | @@ -31721,9 +32025,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile | ... | @@ -31721,9 +32025,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile |
| 31721 | } | 32025 | } |
| 31722 | 32026 | ||
| 31723 | fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void { | 32027 | fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void { |
| 31724 | const mod = sema.mod; | 32028 | const pt = sema.pt; |
| 32029 | const mod = pt.zcu; | ||
| 31725 | const ip = &mod.intern_pool; | 32030 | const ip = &mod.intern_pool; |
| 31726 | mod.ensureFuncBodyAnalyzed(func) catch |err| { | 32031 | pt.ensureFuncBodyAnalyzed(func) catch |err| { |
| 31727 | if (sema.owner_func_index != .none) { | 32032 | if (sema.owner_func_index != .none) { |
| 31728 | ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure; | 32033 | ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure; |
| 31729 | } else { | 32034 | } else { |
| ... | @@ -31734,15 +32039,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void | ... | @@ -31734,15 +32039,15 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void |
| 31734 | } | 32039 | } |
| 31735 | 32040 | ||
| 31736 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | 32041 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| 31737 | const mod = sema.mod; | 32042 | const pt = sema.pt; |
| 31738 | const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque); | 32043 | const ptr_anyopaque_ty = try pt.singleConstPtrType(Type.anyopaque); |
| 31739 | return Value.fromInterned((try mod.intern(.{ .opt = .{ | 32044 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 31740 | .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), | 32045 | .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), |
| 31741 | .val = if (opt_val) |val| (try mod.getCoerced( | 32046 | .val = if (opt_val) |val| (try pt.getCoerced( |
| 31742 | Value.fromInterned(try sema.refValue(val.toIntern())), | 32047 | Value.fromInterned(try sema.refValue(val.toIntern())), |
| 31743 | ptr_anyopaque_ty, | 32048 | ptr_anyopaque_ty, |
| 31744 | )).toIntern() else .none, | 32049 | )).toIntern() else .none, |
| 31745 | } }))); | 32050 | } })); |
| 31746 | } | 32051 | } |
| 31747 | 32052 | ||
| 31748 | fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref { | 32053 | fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref { |
| ... | @@ -31754,7 +32059,8 @@ fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex | ... | @@ -31754,7 +32059,8 @@ fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex |
| 31754 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps | 32059 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps |
| 31755 | /// this function with `analyze_fn_body` set to true. | 32060 | /// this function with `analyze_fn_body` set to true. |
| 31756 | fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref { | 32061 | fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref { |
| 31757 | const mod = sema.mod; | 32062 | const pt = sema.pt; |
| 32063 | const mod = pt.zcu; | ||
| 31758 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index })); | 32064 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index })); |
| 31759 | try sema.ensureDeclAnalyzed(decl_index); | 32065 | try sema.ensureDeclAnalyzed(decl_index); |
| 31760 | 32066 | ||
| ... | @@ -31767,7 +32073,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl | ... | @@ -31767,7 +32073,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl |
| 31767 | }); | 32073 | }); |
| 31768 | // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type | 32074 | // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type |
| 31769 | try sema.declareDependency(.{ .decl_val = decl_index }); | 32075 | try sema.declareDependency(.{ .decl_val = decl_index }); |
| 31770 | const ptr_ty = try mod.ptrTypeSema(.{ | 32076 | const ptr_ty = try pt.ptrTypeSema(.{ |
| 31771 | .child = decl_val.typeOf(mod).toIntern(), | 32077 | .child = decl_val.typeOf(mod).toIntern(), |
| 31772 | .flags = .{ | 32078 | .flags = .{ |
| 31773 | .alignment = owner_decl.alignment, | 32079 | .alignment = owner_decl.alignment, |
| ... | @@ -31778,7 +32084,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl | ... | @@ -31778,7 +32084,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl |
| 31778 | if (analyze_fn_body) { | 32084 | if (analyze_fn_body) { |
| 31779 | try sema.maybeQueueFuncBodyAnalysis(src, decl_index); | 32085 | try sema.maybeQueueFuncBodyAnalysis(src, decl_index); |
| 31780 | } | 32086 | } |
| 31781 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 32087 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ |
| 31782 | .ty = ptr_ty.toIntern(), | 32088 | .ty = ptr_ty.toIntern(), |
| 31783 | .base_addr = .{ .decl = decl_index }, | 32089 | .base_addr = .{ .decl = decl_index }, |
| 31784 | .byte_offset = 0, | 32090 | .byte_offset = 0, |
| ... | @@ -31786,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl | ... | @@ -31786,7 +32092,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl |
| 31786 | } | 32092 | } |
| 31787 | 32093 | ||
| 31788 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void { | 32094 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void { |
| 31789 | const mod = sema.mod; | 32095 | const mod = sema.pt.zcu; |
| 31790 | const decl = mod.declPtr(decl_index); | 32096 | const decl = mod.declPtr(decl_index); |
| 31791 | const decl_val = try decl.valueOrFail(); | 32097 | const decl_val = try decl.valueOrFail(); |
| 31792 | if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return; | 32098 | if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return; |
| ... | @@ -31801,7 +32107,8 @@ fn analyzeRef( | ... | @@ -31801,7 +32107,8 @@ fn analyzeRef( |
| 31801 | src: LazySrcLoc, | 32107 | src: LazySrcLoc, |
| 31802 | operand: Air.Inst.Ref, | 32108 | operand: Air.Inst.Ref, |
| 31803 | ) CompileError!Air.Inst.Ref { | 32109 | ) CompileError!Air.Inst.Ref { |
| 31804 | const mod = sema.mod; | 32110 | const pt = sema.pt; |
| 32111 | const mod = pt.zcu; | ||
| 31805 | const operand_ty = sema.typeOf(operand); | 32112 | const operand_ty = sema.typeOf(operand); |
| 31806 | 32113 | ||
| 31807 | if (try sema.resolveValue(operand)) |val| { | 32114 | if (try sema.resolveValue(operand)) |val| { |
| ... | @@ -31814,14 +32121,14 @@ fn analyzeRef( | ... | @@ -31814,14 +32121,14 @@ fn analyzeRef( |
| 31814 | 32121 | ||
| 31815 | try sema.requireRuntimeBlock(block, src, null); | 32122 | try sema.requireRuntimeBlock(block, src, null); |
| 31816 | const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local); | 32123 | const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local); |
| 31817 | const ptr_type = try mod.ptrTypeSema(.{ | 32124 | const ptr_type = try pt.ptrTypeSema(.{ |
| 31818 | .child = operand_ty.toIntern(), | 32125 | .child = operand_ty.toIntern(), |
| 31819 | .flags = .{ | 32126 | .flags = .{ |
| 31820 | .is_const = true, | 32127 | .is_const = true, |
| 31821 | .address_space = address_space, | 32128 | .address_space = address_space, |
| 31822 | }, | 32129 | }, |
| 31823 | }); | 32130 | }); |
| 31824 | const mut_ptr_type = try mod.ptrTypeSema(.{ | 32131 | const mut_ptr_type = try pt.ptrTypeSema(.{ |
| 31825 | .child = operand_ty.toIntern(), | 32132 | .child = operand_ty.toIntern(), |
| 31826 | .flags = .{ .address_space = address_space }, | 32133 | .flags = .{ .address_space = address_space }, |
| 31827 | }); | 32134 | }); |
| ... | @@ -31839,14 +32146,15 @@ fn analyzeLoad( | ... | @@ -31839,14 +32146,15 @@ fn analyzeLoad( |
| 31839 | ptr: Air.Inst.Ref, | 32146 | ptr: Air.Inst.Ref, |
| 31840 | ptr_src: LazySrcLoc, | 32147 | ptr_src: LazySrcLoc, |
| 31841 | ) CompileError!Air.Inst.Ref { | 32148 | ) CompileError!Air.Inst.Ref { |
| 31842 | const mod = sema.mod; | 32149 | const pt = sema.pt; |
| 32150 | const mod = pt.zcu; | ||
| 31843 | const ptr_ty = sema.typeOf(ptr); | 32151 | const ptr_ty = sema.typeOf(ptr); |
| 31844 | const elem_ty = switch (ptr_ty.zigTypeTag(mod)) { | 32152 | const elem_ty = switch (ptr_ty.zigTypeTag(mod)) { |
| 31845 | .Pointer => ptr_ty.childType(mod), | 32153 | .Pointer => ptr_ty.childType(mod), |
| 31846 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}), | 32154 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}), |
| 31847 | }; | 32155 | }; |
| 31848 | if (elem_ty.zigTypeTag(mod) == .Opaque) { | 32156 | if (elem_ty.zigTypeTag(mod) == .Opaque) { |
| 31849 | return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(mod)}); | 32157 | return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(pt)}); |
| 31850 | } | 32158 | } |
| 31851 | 32159 | ||
| 31852 | if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| { | 32160 | if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| { |
| ... | @@ -31868,7 +32176,7 @@ fn analyzeLoad( | ... | @@ -31868,7 +32176,7 @@ fn analyzeLoad( |
| 31868 | return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs); | 32176 | return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs); |
| 31869 | } | 32177 | } |
| 31870 | return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{ | 32178 | return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{ |
| 31871 | ptr_ty.fmt(sema.mod), | 32179 | ptr_ty.fmt(pt), |
| 31872 | }); | 32180 | }); |
| 31873 | } | 32181 | } |
| 31874 | 32182 | ||
| ... | @@ -31882,10 +32190,11 @@ fn analyzeSlicePtr( | ... | @@ -31882,10 +32190,11 @@ fn analyzeSlicePtr( |
| 31882 | slice: Air.Inst.Ref, | 32190 | slice: Air.Inst.Ref, |
| 31883 | slice_ty: Type, | 32191 | slice_ty: Type, |
| 31884 | ) CompileError!Air.Inst.Ref { | 32192 | ) CompileError!Air.Inst.Ref { |
| 31885 | const mod = sema.mod; | 32193 | const pt = sema.pt; |
| 32194 | const mod = pt.zcu; | ||
| 31886 | const result_ty = slice_ty.slicePtrFieldType(mod); | 32195 | const result_ty = slice_ty.slicePtrFieldType(mod); |
| 31887 | if (try sema.resolveValue(slice)) |val| { | 32196 | if (try sema.resolveValue(slice)) |val| { |
| 31888 | if (val.isUndef(mod)) return mod.undefRef(result_ty); | 32197 | if (val.isUndef(mod)) return pt.undefRef(result_ty); |
| 31889 | return Air.internedToRef(val.slicePtr(mod).toIntern()); | 32198 | return Air.internedToRef(val.slicePtr(mod).toIntern()); |
| 31890 | } | 32199 | } |
| 31891 | try sema.requireRuntimeBlock(block, slice_src, null); | 32200 | try sema.requireRuntimeBlock(block, slice_src, null); |
| ... | @@ -31899,11 +32208,12 @@ fn analyzeOptionalSlicePtr( | ... | @@ -31899,11 +32208,12 @@ fn analyzeOptionalSlicePtr( |
| 31899 | opt_slice: Air.Inst.Ref, | 32208 | opt_slice: Air.Inst.Ref, |
| 31900 | opt_slice_ty: Type, | 32209 | opt_slice_ty: Type, |
| 31901 | ) CompileError!Air.Inst.Ref { | 32210 | ) CompileError!Air.Inst.Ref { |
| 31902 | const mod = sema.mod; | 32211 | const pt = sema.pt; |
| 32212 | const mod = pt.zcu; | ||
| 31903 | const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod); | 32213 | const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod); |
| 31904 | 32214 | ||
| 31905 | if (try sema.resolveValue(opt_slice)) |opt_val| { | 32215 | if (try sema.resolveValue(opt_slice)) |opt_val| { |
| 31906 | if (opt_val.isUndef(mod)) return mod.undefRef(result_ty); | 32216 | if (opt_val.isUndef(mod)) return pt.undefRef(result_ty); |
| 31907 | const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val| | 32217 | const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val| |
| 31908 | val.slicePtr(mod).toIntern() | 32218 | val.slicePtr(mod).toIntern() |
| 31909 | else | 32219 | else |
| ... | @@ -31924,12 +32234,13 @@ fn analyzeSliceLen( | ... | @@ -31924,12 +32234,13 @@ fn analyzeSliceLen( |
| 31924 | src: LazySrcLoc, | 32234 | src: LazySrcLoc, |
| 31925 | slice_inst: Air.Inst.Ref, | 32235 | slice_inst: Air.Inst.Ref, |
| 31926 | ) CompileError!Air.Inst.Ref { | 32236 | ) CompileError!Air.Inst.Ref { |
| 31927 | const mod = sema.mod; | 32237 | const pt = sema.pt; |
| 32238 | const mod = pt.zcu; | ||
| 31928 | if (try sema.resolveValue(slice_inst)) |slice_val| { | 32239 | if (try sema.resolveValue(slice_inst)) |slice_val| { |
| 31929 | if (slice_val.isUndef(mod)) { | 32240 | if (slice_val.isUndef(mod)) { |
| 31930 | return mod.undefRef(Type.usize); | 32241 | return pt.undefRef(Type.usize); |
| 31931 | } | 32242 | } |
| 31932 | return mod.intRef(Type.usize, try slice_val.sliceLen(mod)); | 32243 | return pt.intRef(Type.usize, try slice_val.sliceLen(pt)); |
| 31933 | } | 32244 | } |
| 31934 | try sema.requireRuntimeBlock(block, src, null); | 32245 | try sema.requireRuntimeBlock(block, src, null); |
| 31935 | return block.addTyOp(.slice_len, Type.usize, slice_inst); | 32246 | return block.addTyOp(.slice_len, Type.usize, slice_inst); |
| ... | @@ -31942,11 +32253,12 @@ fn analyzeIsNull( | ... | @@ -31942,11 +32253,12 @@ fn analyzeIsNull( |
| 31942 | operand: Air.Inst.Ref, | 32253 | operand: Air.Inst.Ref, |
| 31943 | invert_logic: bool, | 32254 | invert_logic: bool, |
| 31944 | ) CompileError!Air.Inst.Ref { | 32255 | ) CompileError!Air.Inst.Ref { |
| 31945 | const mod = sema.mod; | 32256 | const pt = sema.pt; |
| 32257 | const mod = pt.zcu; | ||
| 31946 | const result_ty = Type.bool; | 32258 | const result_ty = Type.bool; |
| 31947 | if (try sema.resolveValue(operand)) |opt_val| { | 32259 | if (try sema.resolveValue(operand)) |opt_val| { |
| 31948 | if (opt_val.isUndef(mod)) { | 32260 | if (opt_val.isUndef(mod)) { |
| 31949 | return mod.undefRef(result_ty); | 32261 | return pt.undefRef(result_ty); |
| 31950 | } | 32262 | } |
| 31951 | const is_null = opt_val.isNull(mod); | 32263 | const is_null = opt_val.isNull(mod); |
| 31952 | const bool_value = if (invert_logic) !is_null else is_null; | 32264 | const bool_value = if (invert_logic) !is_null else is_null; |
| ... | @@ -31972,7 +32284,8 @@ fn analyzePtrIsNonErrComptimeOnly( | ... | @@ -31972,7 +32284,8 @@ fn analyzePtrIsNonErrComptimeOnly( |
| 31972 | src: LazySrcLoc, | 32284 | src: LazySrcLoc, |
| 31973 | operand: Air.Inst.Ref, | 32285 | operand: Air.Inst.Ref, |
| 31974 | ) CompileError!Air.Inst.Ref { | 32286 | ) CompileError!Air.Inst.Ref { |
| 31975 | const mod = sema.mod; | 32287 | const pt = sema.pt; |
| 32288 | const mod = pt.zcu; | ||
| 31976 | const ptr_ty = sema.typeOf(operand); | 32289 | const ptr_ty = sema.typeOf(operand); |
| 31977 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); | 32290 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); |
| 31978 | const child_ty = ptr_ty.childType(mod); | 32291 | const child_ty = ptr_ty.childType(mod); |
| ... | @@ -31994,7 +32307,8 @@ fn analyzeIsNonErrComptimeOnly( | ... | @@ -31994,7 +32307,8 @@ fn analyzeIsNonErrComptimeOnly( |
| 31994 | src: LazySrcLoc, | 32307 | src: LazySrcLoc, |
| 31995 | operand: Air.Inst.Ref, | 32308 | operand: Air.Inst.Ref, |
| 31996 | ) CompileError!Air.Inst.Ref { | 32309 | ) CompileError!Air.Inst.Ref { |
| 31997 | const mod = sema.mod; | 32310 | const pt = sema.pt; |
| 32311 | const mod = pt.zcu; | ||
| 31998 | const ip = &mod.intern_pool; | 32312 | const ip = &mod.intern_pool; |
| 31999 | const operand_ty = sema.typeOf(operand); | 32313 | const operand_ty = sema.typeOf(operand); |
| 32000 | const ot = operand_ty.zigTypeTag(mod); | 32314 | const ot = operand_ty.zigTypeTag(mod); |
| ... | @@ -32014,7 +32328,7 @@ fn analyzeIsNonErrComptimeOnly( | ... | @@ -32014,7 +32328,7 @@ fn analyzeIsNonErrComptimeOnly( |
| 32014 | else => {}, | 32328 | else => {}, |
| 32015 | } | 32329 | } |
| 32016 | } else if (operand == .undef) { | 32330 | } else if (operand == .undef) { |
| 32017 | return mod.undefRef(Type.bool); | 32331 | return pt.undefRef(Type.bool); |
| 32018 | } else if (@intFromEnum(operand) < InternPool.static_len) { | 32332 | } else if (@intFromEnum(operand) < InternPool.static_len) { |
| 32019 | // None of the ref tags can be errors. | 32333 | // None of the ref tags can be errors. |
| 32020 | return .bool_true; | 32334 | return .bool_true; |
| ... | @@ -32098,7 +32412,7 @@ fn analyzeIsNonErrComptimeOnly( | ... | @@ -32098,7 +32412,7 @@ fn analyzeIsNonErrComptimeOnly( |
| 32098 | 32412 | ||
| 32099 | if (maybe_operand_val) |err_union| { | 32413 | if (maybe_operand_val) |err_union| { |
| 32100 | if (err_union.isUndef(mod)) { | 32414 | if (err_union.isUndef(mod)) { |
| 32101 | return mod.undefRef(Type.bool); | 32415 | return pt.undefRef(Type.bool); |
| 32102 | } | 32416 | } |
| 32103 | if (err_union.getErrorName(mod) == .none) { | 32417 | if (err_union.getErrorName(mod) == .none) { |
| 32104 | return .bool_true; | 32418 | return .bool_true; |
| ... | @@ -32153,13 +32467,14 @@ fn analyzeSlice( | ... | @@ -32153,13 +32467,14 @@ fn analyzeSlice( |
| 32153 | end_src: LazySrcLoc, | 32467 | end_src: LazySrcLoc, |
| 32154 | by_length: bool, | 32468 | by_length: bool, |
| 32155 | ) CompileError!Air.Inst.Ref { | 32469 | ) CompileError!Air.Inst.Ref { |
| 32156 | const mod = sema.mod; | 32470 | const pt = sema.pt; |
| 32471 | const mod = pt.zcu; | ||
| 32157 | // Slice expressions can operate on a variable whose type is an array. This requires | 32472 | // Slice expressions can operate on a variable whose type is an array. This requires |
| 32158 | // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. | 32473 | // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. |
| 32159 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); | 32474 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); |
| 32160 | const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) { | 32475 | const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) { |
| 32161 | .Pointer => ptr_ptr_ty.childType(mod), | 32476 | .Pointer => ptr_ptr_ty.childType(mod), |
| 32162 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(mod)}), | 32477 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(pt)}), |
| 32163 | }; | 32478 | }; |
| 32164 | 32479 | ||
| 32165 | var array_ty = ptr_ptr_child_ty; | 32480 | var array_ty = ptr_ptr_child_ty; |
| ... | @@ -32210,8 +32525,8 @@ fn analyzeSlice( | ... | @@ -32210,8 +32525,8 @@ fn analyzeSlice( |
| 32210 | msg, | 32525 | msg, |
| 32211 | "expected '{}', found '{}'", | 32526 | "expected '{}', found '{}'", |
| 32212 | .{ | 32527 | .{ |
| 32213 | Value.zero_comptime_int.fmtValue(mod, sema), | 32528 | Value.zero_comptime_int.fmtValue(pt, sema), |
| 32214 | start_value.fmtValue(mod, sema), | 32529 | start_value.fmtValue(pt, sema), |
| 32215 | }, | 32530 | }, |
| 32216 | ); | 32531 | ); |
| 32217 | break :msg msg; | 32532 | break :msg msg; |
| ... | @@ -32226,8 +32541,8 @@ fn analyzeSlice( | ... | @@ -32226,8 +32541,8 @@ fn analyzeSlice( |
| 32226 | msg, | 32541 | msg, |
| 32227 | "expected '{}', found '{}'", | 32542 | "expected '{}', found '{}'", |
| 32228 | .{ | 32543 | .{ |
| 32229 | Value.one_comptime_int.fmtValue(mod, sema), | 32544 | Value.one_comptime_int.fmtValue(pt, sema), |
| 32230 | end_value.fmtValue(mod, sema), | 32545 | end_value.fmtValue(pt, sema), |
| 32231 | }, | 32546 | }, |
| 32232 | ); | 32547 | ); |
| 32233 | break :msg msg; | 32548 | break :msg msg; |
| ... | @@ -32240,17 +32555,17 @@ fn analyzeSlice( | ... | @@ -32240,17 +32555,17 @@ fn analyzeSlice( |
| 32240 | block, | 32555 | block, |
| 32241 | end_src, | 32556 | end_src, |
| 32242 | "end index {} out of bounds for slice of single-item pointer", | 32557 | "end index {} out of bounds for slice of single-item pointer", |
| 32243 | .{end_value.fmtValue(mod, sema)}, | 32558 | .{end_value.fmtValue(pt, sema)}, |
| 32244 | ); | 32559 | ); |
| 32245 | } | 32560 | } |
| 32246 | } | 32561 | } |
| 32247 | 32562 | ||
| 32248 | array_ty = try mod.arrayType(.{ | 32563 | array_ty = try pt.arrayType(.{ |
| 32249 | .len = 1, | 32564 | .len = 1, |
| 32250 | .child = double_child_ty.toIntern(), | 32565 | .child = double_child_ty.toIntern(), |
| 32251 | }); | 32566 | }); |
| 32252 | const ptr_info = ptr_ptr_child_ty.ptrInfo(mod); | 32567 | const ptr_info = ptr_ptr_child_ty.ptrInfo(mod); |
| 32253 | slice_ty = try mod.ptrType(.{ | 32568 | slice_ty = try pt.ptrType(.{ |
| 32254 | .child = array_ty.toIntern(), | 32569 | .child = array_ty.toIntern(), |
| 32255 | .flags = .{ | 32570 | .flags = .{ |
| 32256 | .alignment = ptr_info.flags.alignment, | 32571 | .alignment = ptr_info.flags.alignment, |
| ... | @@ -32286,7 +32601,7 @@ fn analyzeSlice( | ... | @@ -32286,7 +32601,7 @@ fn analyzeSlice( |
| 32286 | elem_ty = ptr_ptr_child_ty.childType(mod); | 32601 | elem_ty = ptr_ptr_child_ty.childType(mod); |
| 32287 | }, | 32602 | }, |
| 32288 | }, | 32603 | }, |
| 32289 | else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}), | 32604 | else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(pt)}), |
| 32290 | } | 32605 | } |
| 32291 | 32606 | ||
| 32292 | const ptr = if (slice_ty.isSlice(mod)) | 32607 | const ptr = if (slice_ty.isSlice(mod)) |
| ... | @@ -32297,7 +32612,7 @@ fn analyzeSlice( | ... | @@ -32297,7 +32612,7 @@ fn analyzeSlice( |
| 32297 | assert(manyptr_ty_key.flags.size == .One); | 32612 | assert(manyptr_ty_key.flags.size == .One); |
| 32298 | manyptr_ty_key.child = elem_ty.toIntern(); | 32613 | manyptr_ty_key.child = elem_ty.toIntern(); |
| 32299 | manyptr_ty_key.flags.size = .Many; | 32614 | manyptr_ty_key.flags.size = .Many; |
| 32300 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src); | 32615 | break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src); |
| 32301 | } else ptr_or_slice; | 32616 | } else ptr_or_slice; |
| 32302 | 32617 | ||
| 32303 | const start = try sema.coerce(block, Type.usize, uncasted_start, start_src); | 32618 | const start = try sema.coerce(block, Type.usize, uncasted_start, start_src); |
| ... | @@ -32311,7 +32626,7 @@ fn analyzeSlice( | ... | @@ -32311,7 +32626,7 @@ fn analyzeSlice( |
| 32311 | var end_is_len = uncasted_end_opt == .none; | 32626 | var end_is_len = uncasted_end_opt == .none; |
| 32312 | const end = e: { | 32627 | const end = e: { |
| 32313 | if (array_ty.zigTypeTag(mod) == .Array) { | 32628 | if (array_ty.zigTypeTag(mod) == .Array) { |
| 32314 | const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod)); | 32629 | const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(mod)); |
| 32315 | 32630 | ||
| 32316 | if (!end_is_len) { | 32631 | if (!end_is_len) { |
| 32317 | const end = if (by_length) end: { | 32632 | const end = if (by_length) end: { |
| ... | @@ -32320,7 +32635,7 @@ fn analyzeSlice( | ... | @@ -32320,7 +32635,7 @@ fn analyzeSlice( |
| 32320 | break :end try sema.coerce(block, Type.usize, uncasted_end, end_src); | 32635 | break :end try sema.coerce(block, Type.usize, uncasted_end, end_src); |
| 32321 | } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); | 32636 | } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); |
| 32322 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { | 32637 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32323 | const len_s_val = try mod.intValue( | 32638 | const len_s_val = try pt.intValue( |
| 32324 | Type.usize, | 32639 | Type.usize, |
| 32325 | array_ty.arrayLenIncludingSentinel(mod), | 32640 | array_ty.arrayLenIncludingSentinel(mod), |
| 32326 | ); | 32641 | ); |
| ... | @@ -32335,8 +32650,8 @@ fn analyzeSlice( | ... | @@ -32335,8 +32650,8 @@ fn analyzeSlice( |
| 32335 | end_src, | 32650 | end_src, |
| 32336 | "end index {} out of bounds for array of length {}{s}", | 32651 | "end index {} out of bounds for array of length {}{s}", |
| 32337 | .{ | 32652 | .{ |
| 32338 | end_val.fmtValue(mod, sema), | 32653 | end_val.fmtValue(pt, sema), |
| 32339 | len_val.fmtValue(mod, sema), | 32654 | len_val.fmtValue(pt, sema), |
| 32340 | sentinel_label, | 32655 | sentinel_label, |
| 32341 | }, | 32656 | }, |
| 32342 | ); | 32657 | ); |
| ... | @@ -32366,9 +32681,9 @@ fn analyzeSlice( | ... | @@ -32366,9 +32681,9 @@ fn analyzeSlice( |
| 32366 | return sema.fail(block, src, "slice of undefined", .{}); | 32681 | return sema.fail(block, src, "slice of undefined", .{}); |
| 32367 | } | 32682 | } |
| 32368 | const has_sentinel = slice_ty.sentinel(mod) != null; | 32683 | const has_sentinel = slice_ty.sentinel(mod) != null; |
| 32369 | const slice_len = try slice_val.sliceLen(mod); | 32684 | const slice_len = try slice_val.sliceLen(pt); |
| 32370 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); | 32685 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); |
| 32371 | const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent); | 32686 | const slice_len_val_with_sentinel = try pt.intValue(Type.usize, len_plus_sent); |
| 32372 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) { | 32687 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) { |
| 32373 | const sentinel_label: []const u8 = if (has_sentinel) | 32688 | const sentinel_label: []const u8 = if (has_sentinel) |
| 32374 | " +1 (sentinel)" | 32689 | " +1 (sentinel)" |
| ... | @@ -32380,8 +32695,8 @@ fn analyzeSlice( | ... | @@ -32380,8 +32695,8 @@ fn analyzeSlice( |
| 32380 | end_src, | 32695 | end_src, |
| 32381 | "end index {} out of bounds for slice of length {d}{s}", | 32696 | "end index {} out of bounds for slice of length {d}{s}", |
| 32382 | .{ | 32697 | .{ |
| 32383 | end_val.fmtValue(mod, sema), | 32698 | end_val.fmtValue(pt, sema), |
| 32384 | try slice_val.sliceLen(mod), | 32699 | try slice_val.sliceLen(pt), |
| 32385 | sentinel_label, | 32700 | sentinel_label, |
| 32386 | }, | 32701 | }, |
| 32387 | ); | 32702 | ); |
| ... | @@ -32390,7 +32705,7 @@ fn analyzeSlice( | ... | @@ -32390,7 +32705,7 @@ fn analyzeSlice( |
| 32390 | // If the slice has a sentinel, we consider end_is_len | 32705 | // If the slice has a sentinel, we consider end_is_len |
| 32391 | // is only true if it equals the length WITHOUT the | 32706 | // is only true if it equals the length WITHOUT the |
| 32392 | // sentinel, so we don't add a sentinel type. | 32707 | // sentinel, so we don't add a sentinel type. |
| 32393 | const slice_len_val = try mod.intValue(Type.usize, slice_len); | 32708 | const slice_len_val = try pt.intValue(Type.usize, slice_len); |
| 32394 | if (end_val.eql(slice_len_val, Type.usize, mod)) { | 32709 | if (end_val.eql(slice_len_val, Type.usize, mod)) { |
| 32395 | end_is_len = true; | 32710 | end_is_len = true; |
| 32396 | } | 32711 | } |
| ... | @@ -32440,21 +32755,21 @@ fn analyzeSlice( | ... | @@ -32440,21 +32755,21 @@ fn analyzeSlice( |
| 32440 | start_src, | 32755 | start_src, |
| 32441 | "start index {} is larger than end index {}", | 32756 | "start index {} is larger than end index {}", |
| 32442 | .{ | 32757 | .{ |
| 32443 | start_val.fmtValue(mod, sema), | 32758 | start_val.fmtValue(pt, sema), |
| 32444 | end_val.fmtValue(mod, sema), | 32759 | end_val.fmtValue(pt, sema), |
| 32445 | }, | 32760 | }, |
| 32446 | ); | 32761 | ); |
| 32447 | } | 32762 | } |
| 32448 | checked_start_lte_end = true; | 32763 | checked_start_lte_end = true; |
| 32449 | if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: { | 32764 | if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: { |
| 32450 | const expected_sentinel = sentinel orelse break :sentinel_check; | 32765 | const expected_sentinel = sentinel orelse break :sentinel_check; |
| 32451 | const start_int = start_val.getUnsignedInt(mod).?; | 32766 | const start_int = start_val.getUnsignedInt(pt).?; |
| 32452 | const end_int = end_val.getUnsignedInt(mod).?; | 32767 | const end_int = end_val.getUnsignedInt(pt).?; |
| 32453 | const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int); | 32768 | const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int); |
| 32454 | 32769 | ||
| 32455 | const many_ptr_ty = try mod.manyConstPtrType(elem_ty); | 32770 | const many_ptr_ty = try pt.manyConstPtrType(elem_ty); |
| 32456 | const many_ptr_val = try mod.getCoerced(ptr_val, many_ptr_ty); | 32771 | const many_ptr_val = try pt.getCoerced(ptr_val, many_ptr_ty); |
| 32457 | const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, mod); | 32772 | const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, pt); |
| 32458 | const res = try sema.pointerDerefExtra(block, src, elem_ptr); | 32773 | const res = try sema.pointerDerefExtra(block, src, elem_ptr); |
| 32459 | const actual_sentinel = switch (res) { | 32774 | const actual_sentinel = switch (res) { |
| 32460 | .runtime_load => break :sentinel_check, | 32775 | .runtime_load => break :sentinel_check, |
| ... | @@ -32463,13 +32778,13 @@ fn analyzeSlice( | ... | @@ -32463,13 +32778,13 @@ fn analyzeSlice( |
| 32463 | block, | 32778 | block, |
| 32464 | src, | 32779 | src, |
| 32465 | "comptime dereference requires '{}' to have a well-defined layout", | 32780 | "comptime dereference requires '{}' to have a well-defined layout", |
| 32466 | .{ty.fmt(mod)}, | 32781 | .{ty.fmt(pt)}, |
| 32467 | ), | 32782 | ), |
| 32468 | .out_of_bounds => |ty| return sema.fail( | 32783 | .out_of_bounds => |ty| return sema.fail( |
| 32469 | block, | 32784 | block, |
| 32470 | end_src, | 32785 | end_src, |
| 32471 | "slice end index {d} exceeds bounds of containing decl of type '{}'", | 32786 | "slice end index {d} exceeds bounds of containing decl of type '{}'", |
| 32472 | .{ end_int, ty.fmt(mod) }, | 32787 | .{ end_int, ty.fmt(pt) }, |
| 32473 | ), | 32788 | ), |
| 32474 | }; | 32789 | }; |
| 32475 | 32790 | ||
| ... | @@ -32478,8 +32793,8 @@ fn analyzeSlice( | ... | @@ -32478,8 +32793,8 @@ fn analyzeSlice( |
| 32478 | const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{}); | 32793 | const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{}); |
| 32479 | errdefer msg.destroy(sema.gpa); | 32794 | errdefer msg.destroy(sema.gpa); |
| 32480 | try sema.errNote(src, msg, "expected '{}', found '{}'", .{ | 32795 | try sema.errNote(src, msg, "expected '{}', found '{}'", .{ |
| 32481 | expected_sentinel.fmtValue(mod, sema), | 32796 | expected_sentinel.fmtValue(pt, sema), |
| 32482 | actual_sentinel.fmtValue(mod, sema), | 32797 | actual_sentinel.fmtValue(pt, sema), |
| 32483 | }); | 32798 | }); |
| 32484 | 32799 | ||
| 32485 | break :msg msg; | 32800 | break :msg msg; |
| ... | @@ -32501,7 +32816,7 @@ fn analyzeSlice( | ... | @@ -32501,7 +32816,7 @@ fn analyzeSlice( |
| 32501 | assert(!block.is_comptime); | 32816 | assert(!block.is_comptime); |
| 32502 | try sema.requireRuntimeBlock(block, src, runtime_src.?); | 32817 | try sema.requireRuntimeBlock(block, src, runtime_src.?); |
| 32503 | const ok = try block.addBinOp(.cmp_lte, start, end); | 32818 | const ok = try block.addBinOp(.cmp_lte, start, end); |
| 32504 | if (!sema.mod.comp.formatted_panics) { | 32819 | if (!pt.zcu.comp.formatted_panics) { |
| 32505 | try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end); | 32820 | try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end); |
| 32506 | } else { | 32821 | } else { |
| 32507 | try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end }); | 32822 | try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end }); |
| ... | @@ -32517,10 +32832,10 @@ fn analyzeSlice( | ... | @@ -32517,10 +32832,10 @@ fn analyzeSlice( |
| 32517 | const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C; | 32832 | const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C; |
| 32518 | 32833 | ||
| 32519 | if (opt_new_len_val) |new_len_val| { | 32834 | if (opt_new_len_val) |new_len_val| { |
| 32520 | const new_len_int = try new_len_val.toUnsignedIntSema(mod); | 32835 | const new_len_int = try new_len_val.toUnsignedIntSema(pt); |
| 32521 | 32836 | ||
| 32522 | const return_ty = try mod.ptrTypeSema(.{ | 32837 | const return_ty = try pt.ptrTypeSema(.{ |
| 32523 | .child = (try mod.arrayType(.{ | 32838 | .child = (try pt.arrayType(.{ |
| 32524 | .len = new_len_int, | 32839 | .len = new_len_int, |
| 32525 | .sentinel = if (sentinel) |s| s.toIntern() else .none, | 32840 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 32526 | .child = elem_ty.toIntern(), | 32841 | .child = elem_ty.toIntern(), |
| ... | @@ -32546,7 +32861,7 @@ fn analyzeSlice( | ... | @@ -32546,7 +32861,7 @@ fn analyzeSlice( |
| 32546 | 32861 | ||
| 32547 | bounds_check: { | 32862 | bounds_check: { |
| 32548 | const actual_len = if (array_ty.zigTypeTag(mod) == .Array) | 32863 | const actual_len = if (array_ty.zigTypeTag(mod) == .Array) |
| 32549 | try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) | 32864 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) |
| 32550 | else if (slice_ty.isSlice(mod)) l: { | 32865 | else if (slice_ty.isSlice(mod)) l: { |
| 32551 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | 32866 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| 32552 | break :l if (slice_ty.sentinel(mod) == null) | 32867 | break :l if (slice_ty.sentinel(mod) == null) |
| ... | @@ -32570,18 +32885,18 @@ fn analyzeSlice( | ... | @@ -32570,18 +32885,18 @@ fn analyzeSlice( |
| 32570 | }; | 32885 | }; |
| 32571 | 32886 | ||
| 32572 | if (!new_ptr_val.isUndef(mod)) { | 32887 | if (!new_ptr_val.isUndef(mod)) { |
| 32573 | return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern()); | 32888 | return Air.internedToRef((try pt.getCoerced(new_ptr_val, return_ty)).toIntern()); |
| 32574 | } | 32889 | } |
| 32575 | 32890 | ||
| 32576 | // Special case: @as([]i32, undefined)[x..x] | 32891 | // Special case: @as([]i32, undefined)[x..x] |
| 32577 | if (new_len_int == 0) { | 32892 | if (new_len_int == 0) { |
| 32578 | return mod.undefRef(return_ty); | 32893 | return pt.undefRef(return_ty); |
| 32579 | } | 32894 | } |
| 32580 | 32895 | ||
| 32581 | return sema.fail(block, src, "non-zero length slice of undefined pointer", .{}); | 32896 | return sema.fail(block, src, "non-zero length slice of undefined pointer", .{}); |
| 32582 | } | 32897 | } |
| 32583 | 32898 | ||
| 32584 | const return_ty = try mod.ptrTypeSema(.{ | 32899 | const return_ty = try pt.ptrTypeSema(.{ |
| 32585 | .child = elem_ty.toIntern(), | 32900 | .child = elem_ty.toIntern(), |
| 32586 | .sentinel = if (sentinel) |s| s.toIntern() else .none, | 32901 | .sentinel = if (sentinel) |s| s.toIntern() else .none, |
| 32587 | .flags = .{ | 32902 | .flags = .{ |
| ... | @@ -32604,12 +32919,12 @@ fn analyzeSlice( | ... | @@ -32604,12 +32919,12 @@ fn analyzeSlice( |
| 32604 | 32919 | ||
| 32605 | // requirement: end <= len | 32920 | // requirement: end <= len |
| 32606 | const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array) | 32921 | const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array) |
| 32607 | try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) | 32922 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) |
| 32608 | else if (slice_ty.isSlice(mod)) blk: { | 32923 | else if (slice_ty.isSlice(mod)) blk: { |
| 32609 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { | 32924 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { |
| 32610 | // we don't need to add one for sentinels because the | 32925 | // we don't need to add one for sentinels because the |
| 32611 | // underlying value data includes the sentinel | 32926 | // underlying value data includes the sentinel |
| 32612 | break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(mod)); | 32927 | break :blk try pt.intRef(Type.usize, try slice_val.sliceLen(pt)); |
| 32613 | } | 32928 | } |
| 32614 | 32929 | ||
| 32615 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | 32930 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| ... | @@ -32657,7 +32972,8 @@ fn cmpNumeric( | ... | @@ -32657,7 +32972,8 @@ fn cmpNumeric( |
| 32657 | lhs_src: LazySrcLoc, | 32972 | lhs_src: LazySrcLoc, |
| 32658 | rhs_src: LazySrcLoc, | 32973 | rhs_src: LazySrcLoc, |
| 32659 | ) CompileError!Air.Inst.Ref { | 32974 | ) CompileError!Air.Inst.Ref { |
| 32660 | const mod = sema.mod; | 32975 | const pt = sema.pt; |
| 32976 | const mod = pt.zcu; | ||
| 32661 | const lhs_ty = sema.typeOf(uncasted_lhs); | 32977 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 32662 | const rhs_ty = sema.typeOf(uncasted_rhs); | 32978 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 32663 | 32979 | ||
| ... | @@ -32696,12 +33012,12 @@ fn cmpNumeric( | ... | @@ -32696,12 +33012,12 @@ fn cmpNumeric( |
| 32696 | } | 33012 | } |
| 32697 | 33013 | ||
| 32698 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | 33014 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { |
| 32699 | return mod.undefRef(Type.bool); | 33015 | return pt.undefRef(Type.bool); |
| 32700 | } | 33016 | } |
| 32701 | if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) { | 33017 | if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) { |
| 32702 | return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false; | 33018 | return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false; |
| 32703 | } | 33019 | } |
| 32704 | return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, .sema)) | 33020 | return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, pt, .sema)) |
| 32705 | .bool_true | 33021 | .bool_true |
| 32706 | else | 33022 | else |
| 32707 | .bool_false; | 33023 | .bool_false; |
| ... | @@ -32770,11 +33086,11 @@ fn cmpNumeric( | ... | @@ -32770,11 +33086,11 @@ fn cmpNumeric( |
| 32770 | // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, | 33086 | // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, |
| 32771 | // add/subtract 1. | 33087 | // add/subtract 1. |
| 32772 | const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| | 33088 | const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| |
| 32773 | !(try lhs_val.compareAllWithZeroSema(.gte, mod)) | 33089 | !(try lhs_val.compareAllWithZeroSema(.gte, pt)) |
| 32774 | else | 33090 | else |
| 32775 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod)); | 33091 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod)); |
| 32776 | const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| | 33092 | const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| |
| 32777 | !(try rhs_val.compareAllWithZeroSema(.gte, mod)) | 33093 | !(try rhs_val.compareAllWithZeroSema(.gte, pt)) |
| 32778 | else | 33094 | else |
| 32779 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod)); | 33095 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod)); |
| 32780 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; | 33096 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; |
| ... | @@ -32784,7 +33100,7 @@ fn cmpNumeric( | ... | @@ -32784,7 +33100,7 @@ fn cmpNumeric( |
| 32784 | var lhs_bits: usize = undefined; | 33100 | var lhs_bits: usize = undefined; |
| 32785 | if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| { | 33101 | if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| { |
| 32786 | if (lhs_val.isUndef(mod)) | 33102 | if (lhs_val.isUndef(mod)) |
| 32787 | return mod.undefRef(Type.bool); | 33103 | return pt.undefRef(Type.bool); |
| 32788 | if (lhs_val.isNan(mod)) switch (op) { | 33104 | if (lhs_val.isNan(mod)) switch (op) { |
| 32789 | .neq => return .bool_true, | 33105 | .neq => return .bool_true, |
| 32790 | else => return .bool_false, | 33106 | else => return .bool_false, |
| ... | @@ -32796,7 +33112,7 @@ fn cmpNumeric( | ... | @@ -32796,7 +33112,7 @@ fn cmpNumeric( |
| 32796 | .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false, | 33112 | .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false, |
| 32797 | }; | 33113 | }; |
| 32798 | if (!rhs_is_signed) { | 33114 | if (!rhs_is_signed) { |
| 32799 | switch (lhs_val.orderAgainstZero(mod)) { | 33115 | switch (lhs_val.orderAgainstZero(pt)) { |
| 32800 | .gt => {}, | 33116 | .gt => {}, |
| 32801 | .eq => switch (op) { // LHS = 0, RHS is unsigned | 33117 | .eq => switch (op) { // LHS = 0, RHS is unsigned |
| 32802 | .lte => return .bool_true, | 33118 | .lte => return .bool_true, |
| ... | @@ -32818,7 +33134,7 @@ fn cmpNumeric( | ... | @@ -32818,7 +33134,7 @@ fn cmpNumeric( |
| 32818 | } | 33134 | } |
| 32819 | } | 33135 | } |
| 32820 | 33136 | ||
| 32821 | var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod)); | 33137 | var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, pt)); |
| 32822 | defer bigint.deinit(); | 33138 | defer bigint.deinit(); |
| 32823 | if (lhs_val.floatHasFraction(mod)) { | 33139 | if (lhs_val.floatHasFraction(mod)) { |
| 32824 | if (lhs_is_signed) { | 33140 | if (lhs_is_signed) { |
| ... | @@ -32829,7 +33145,7 @@ fn cmpNumeric( | ... | @@ -32829,7 +33145,7 @@ fn cmpNumeric( |
| 32829 | } | 33145 | } |
| 32830 | lhs_bits = bigint.toConst().bitCountTwosComp(); | 33146 | lhs_bits = bigint.toConst().bitCountTwosComp(); |
| 32831 | } else { | 33147 | } else { |
| 32832 | lhs_bits = lhs_val.intBitCountTwosComp(mod); | 33148 | lhs_bits = lhs_val.intBitCountTwosComp(pt); |
| 32833 | } | 33149 | } |
| 32834 | lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed); | 33150 | lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed); |
| 32835 | } else if (lhs_is_float) { | 33151 | } else if (lhs_is_float) { |
| ... | @@ -32842,7 +33158,7 @@ fn cmpNumeric( | ... | @@ -32842,7 +33158,7 @@ fn cmpNumeric( |
| 32842 | var rhs_bits: usize = undefined; | 33158 | var rhs_bits: usize = undefined; |
| 32843 | if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| { | 33159 | if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| { |
| 32844 | if (rhs_val.isUndef(mod)) | 33160 | if (rhs_val.isUndef(mod)) |
| 32845 | return mod.undefRef(Type.bool); | 33161 | return pt.undefRef(Type.bool); |
| 32846 | if (rhs_val.isNan(mod)) switch (op) { | 33162 | if (rhs_val.isNan(mod)) switch (op) { |
| 32847 | .neq => return .bool_true, | 33163 | .neq => return .bool_true, |
| 32848 | else => return .bool_false, | 33164 | else => return .bool_false, |
| ... | @@ -32854,7 +33170,7 @@ fn cmpNumeric( | ... | @@ -32854,7 +33170,7 @@ fn cmpNumeric( |
| 32854 | .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true, | 33170 | .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true, |
| 32855 | }; | 33171 | }; |
| 32856 | if (!lhs_is_signed) { | 33172 | if (!lhs_is_signed) { |
| 32857 | switch (rhs_val.orderAgainstZero(mod)) { | 33173 | switch (rhs_val.orderAgainstZero(pt)) { |
| 32858 | .gt => {}, | 33174 | .gt => {}, |
| 32859 | .eq => switch (op) { // RHS = 0, LHS is unsigned | 33175 | .eq => switch (op) { // RHS = 0, LHS is unsigned |
| 32860 | .gte => return .bool_true, | 33176 | .gte => return .bool_true, |
| ... | @@ -32876,7 +33192,7 @@ fn cmpNumeric( | ... | @@ -32876,7 +33192,7 @@ fn cmpNumeric( |
| 32876 | } | 33192 | } |
| 32877 | } | 33193 | } |
| 32878 | 33194 | ||
| 32879 | var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod)); | 33195 | var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, pt)); |
| 32880 | defer bigint.deinit(); | 33196 | defer bigint.deinit(); |
| 32881 | if (rhs_val.floatHasFraction(mod)) { | 33197 | if (rhs_val.floatHasFraction(mod)) { |
| 32882 | if (rhs_is_signed) { | 33198 | if (rhs_is_signed) { |
| ... | @@ -32887,7 +33203,7 @@ fn cmpNumeric( | ... | @@ -32887,7 +33203,7 @@ fn cmpNumeric( |
| 32887 | } | 33203 | } |
| 32888 | rhs_bits = bigint.toConst().bitCountTwosComp(); | 33204 | rhs_bits = bigint.toConst().bitCountTwosComp(); |
| 32889 | } else { | 33205 | } else { |
| 32890 | rhs_bits = rhs_val.intBitCountTwosComp(mod); | 33206 | rhs_bits = rhs_val.intBitCountTwosComp(pt); |
| 32891 | } | 33207 | } |
| 32892 | rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed); | 33208 | rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed); |
| 32893 | } else if (rhs_is_float) { | 33209 | } else if (rhs_is_float) { |
| ... | @@ -32901,7 +33217,7 @@ fn cmpNumeric( | ... | @@ -32901,7 +33217,7 @@ fn cmpNumeric( |
| 32901 | const max_bits = @max(lhs_bits, rhs_bits); | 33217 | const max_bits = @max(lhs_bits, rhs_bits); |
| 32902 | const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits}); | 33218 | const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits}); |
| 32903 | const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned; | 33219 | const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned; |
| 32904 | break :blk try mod.intType(signedness, casted_bits); | 33220 | break :blk try pt.intType(signedness, casted_bits); |
| 32905 | }; | 33221 | }; |
| 32906 | const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src); | 33222 | const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src); |
| 32907 | const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src); | 33223 | const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src); |
| ... | @@ -32920,9 +33236,10 @@ fn compareIntsOnlyPossibleResult( | ... | @@ -32920,9 +33236,10 @@ fn compareIntsOnlyPossibleResult( |
| 32920 | op: std.math.CompareOperator, | 33236 | op: std.math.CompareOperator, |
| 32921 | rhs_ty: Type, | 33237 | rhs_ty: Type, |
| 32922 | ) Allocator.Error!?bool { | 33238 | ) Allocator.Error!?bool { |
| 32923 | const mod = sema.mod; | 33239 | const pt = sema.pt; |
| 33240 | const mod = pt.zcu; | ||
| 32924 | const rhs_info = rhs_ty.intInfo(mod); | 33241 | const rhs_info = rhs_ty.intInfo(mod); |
| 32925 | const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, .sema) catch unreachable; | 33242 | const vs_zero = lhs_val.orderAgainstZeroAdvanced(pt, .sema) catch unreachable; |
| 32926 | const is_zero = vs_zero == .eq; | 33243 | const is_zero = vs_zero == .eq; |
| 32927 | const is_negative = vs_zero == .lt; | 33244 | const is_negative = vs_zero == .lt; |
| 32928 | const is_positive = vs_zero == .gt; | 33245 | const is_positive = vs_zero == .gt; |
| ... | @@ -32954,7 +33271,7 @@ fn compareIntsOnlyPossibleResult( | ... | @@ -32954,7 +33271,7 @@ fn compareIntsOnlyPossibleResult( |
| 32954 | }; | 33271 | }; |
| 32955 | 33272 | ||
| 32956 | const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed); | 33273 | const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed); |
| 32957 | const req_bits = lhs_val.intBitCountTwosComp(mod) + sign_adj; | 33274 | const req_bits = lhs_val.intBitCountTwosComp(pt) + sign_adj; |
| 32958 | 33275 | ||
| 32959 | // No sized type can have more than 65535 bits. | 33276 | // No sized type can have more than 65535 bits. |
| 32960 | // The RHS type operand is either a runtime value or sized (but undefined) constant. | 33277 | // The RHS type operand is either a runtime value or sized (but undefined) constant. |
| ... | @@ -32981,11 +33298,11 @@ fn compareIntsOnlyPossibleResult( | ... | @@ -32981,11 +33298,11 @@ fn compareIntsOnlyPossibleResult( |
| 32981 | 33298 | ||
| 32982 | if (req_bits != rhs_info.bits) break :edge .{ false, false }; | 33299 | if (req_bits != rhs_info.bits) break :edge .{ false, false }; |
| 32983 | 33300 | ||
| 32984 | const ty = try mod.intType( | 33301 | const ty = try pt.intType( |
| 32985 | if (is_negative) .signed else .unsigned, | 33302 | if (is_negative) .signed else .unsigned, |
| 32986 | @intCast(req_bits), | 33303 | @intCast(req_bits), |
| 32987 | ); | 33304 | ); |
| 32988 | const pop_count = lhs_val.popCount(ty, mod); | 33305 | const pop_count = lhs_val.popCount(ty, pt); |
| 32989 | 33306 | ||
| 32990 | if (is_negative) { | 33307 | if (is_negative) { |
| 32991 | break :edge .{ pop_count == 1, false }; | 33308 | break :edge .{ pop_count == 1, false }; |
| ... | @@ -33015,7 +33332,8 @@ fn cmpVector( | ... | @@ -33015,7 +33332,8 @@ fn cmpVector( |
| 33015 | lhs_src: LazySrcLoc, | 33332 | lhs_src: LazySrcLoc, |
| 33016 | rhs_src: LazySrcLoc, | 33333 | rhs_src: LazySrcLoc, |
| 33017 | ) CompileError!Air.Inst.Ref { | 33334 | ) CompileError!Air.Inst.Ref { |
| 33018 | const mod = sema.mod; | 33335 | const pt = sema.pt; |
| 33336 | const mod = pt.zcu; | ||
| 33019 | const lhs_ty = sema.typeOf(lhs); | 33337 | const lhs_ty = sema.typeOf(lhs); |
| 33020 | const rhs_ty = sema.typeOf(rhs); | 33338 | const rhs_ty = sema.typeOf(rhs); |
| 33021 | assert(lhs_ty.zigTypeTag(mod) == .Vector); | 33339 | assert(lhs_ty.zigTypeTag(mod) == .Vector); |
| ... | @@ -33026,7 +33344,7 @@ fn cmpVector( | ... | @@ -33026,7 +33344,7 @@ fn cmpVector( |
| 33026 | const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src); | 33344 | const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src); |
| 33027 | const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src); | 33345 | const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src); |
| 33028 | 33346 | ||
| 33029 | const result_ty = try mod.vectorType(.{ | 33347 | const result_ty = try pt.vectorType(.{ |
| 33030 | .len = lhs_ty.vectorLen(mod), | 33348 | .len = lhs_ty.vectorLen(mod), |
| 33031 | .child = .bool_type, | 33349 | .child = .bool_type, |
| 33032 | }); | 33350 | }); |
| ... | @@ -33035,7 +33353,7 @@ fn cmpVector( | ... | @@ -33035,7 +33353,7 @@ fn cmpVector( |
| 33035 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { | 33353 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { |
| 33036 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { | 33354 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 33037 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | 33355 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { |
| 33038 | return mod.undefRef(result_ty); | 33356 | return pt.undefRef(result_ty); |
| 33039 | } | 33357 | } |
| 33040 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty); | 33358 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty); |
| 33041 | return Air.internedToRef(cmp_val.toIntern()); | 33359 | return Air.internedToRef(cmp_val.toIntern()); |
| ... | @@ -33059,7 +33377,7 @@ fn wrapOptional( | ... | @@ -33059,7 +33377,7 @@ fn wrapOptional( |
| 33059 | inst_src: LazySrcLoc, | 33377 | inst_src: LazySrcLoc, |
| 33060 | ) !Air.Inst.Ref { | 33378 | ) !Air.Inst.Ref { |
| 33061 | if (try sema.resolveValue(inst)) |val| { | 33379 | if (try sema.resolveValue(inst)) |val| { |
| 33062 | return Air.internedToRef((try sema.mod.intern(.{ .opt = .{ | 33380 | return Air.internedToRef((try sema.pt.intern(.{ .opt = .{ |
| 33063 | .ty = dest_ty.toIntern(), | 33381 | .ty = dest_ty.toIntern(), |
| 33064 | .val = val.toIntern(), | 33382 | .val = val.toIntern(), |
| 33065 | } }))); | 33383 | } }))); |
| ... | @@ -33076,11 +33394,12 @@ fn wrapErrorUnionPayload( | ... | @@ -33076,11 +33394,12 @@ fn wrapErrorUnionPayload( |
| 33076 | inst: Air.Inst.Ref, | 33394 | inst: Air.Inst.Ref, |
| 33077 | inst_src: LazySrcLoc, | 33395 | inst_src: LazySrcLoc, |
| 33078 | ) !Air.Inst.Ref { | 33396 | ) !Air.Inst.Ref { |
| 33079 | const mod = sema.mod; | 33397 | const pt = sema.pt; |
| 33398 | const mod = pt.zcu; | ||
| 33080 | const dest_payload_ty = dest_ty.errorUnionPayload(mod); | 33399 | const dest_payload_ty = dest_ty.errorUnionPayload(mod); |
| 33081 | const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false }); | 33400 | const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false }); |
| 33082 | if (try sema.resolveValue(coerced)) |val| { | 33401 | if (try sema.resolveValue(coerced)) |val| { |
| 33083 | return Air.internedToRef((try mod.intern(.{ .error_union = .{ | 33402 | return Air.internedToRef((try pt.intern(.{ .error_union = .{ |
| 33084 | .ty = dest_ty.toIntern(), | 33403 | .ty = dest_ty.toIntern(), |
| 33085 | .val = .{ .payload = val.toIntern() }, | 33404 | .val = .{ .payload = val.toIntern() }, |
| 33086 | } }))); | 33405 | } }))); |
| ... | @@ -33096,7 +33415,8 @@ fn wrapErrorUnionSet( | ... | @@ -33096,7 +33415,8 @@ fn wrapErrorUnionSet( |
| 33096 | inst: Air.Inst.Ref, | 33415 | inst: Air.Inst.Ref, |
| 33097 | inst_src: LazySrcLoc, | 33416 | inst_src: LazySrcLoc, |
| 33098 | ) !Air.Inst.Ref { | 33417 | ) !Air.Inst.Ref { |
| 33099 | const mod = sema.mod; | 33418 | const pt = sema.pt; |
| 33419 | const mod = pt.zcu; | ||
| 33100 | const ip = &mod.intern_pool; | 33420 | const ip = &mod.intern_pool; |
| 33101 | const inst_ty = sema.typeOf(inst); | 33421 | const inst_ty = sema.typeOf(inst); |
| 33102 | const dest_err_set_ty = dest_ty.errorUnionSet(mod); | 33422 | const dest_err_set_ty = dest_ty.errorUnionSet(mod); |
| ... | @@ -33140,7 +33460,7 @@ fn wrapErrorUnionSet( | ... | @@ -33140,7 +33460,7 @@ fn wrapErrorUnionSet( |
| 33140 | else => unreachable, | 33460 | else => unreachable, |
| 33141 | }, | 33461 | }, |
| 33142 | } | 33462 | } |
| 33143 | return Air.internedToRef((try mod.intern(.{ .error_union = .{ | 33463 | return Air.internedToRef((try pt.intern(.{ .error_union = .{ |
| 33144 | .ty = dest_ty.toIntern(), | 33464 | .ty = dest_ty.toIntern(), |
| 33145 | .val = .{ .err_name = expected_name }, | 33465 | .val = .{ .err_name = expected_name }, |
| 33146 | } }))); | 33466 | } }))); |
| ... | @@ -33158,14 +33478,15 @@ fn unionToTag( | ... | @@ -33158,14 +33478,15 @@ fn unionToTag( |
| 33158 | un: Air.Inst.Ref, | 33478 | un: Air.Inst.Ref, |
| 33159 | un_src: LazySrcLoc, | 33479 | un_src: LazySrcLoc, |
| 33160 | ) !Air.Inst.Ref { | 33480 | ) !Air.Inst.Ref { |
| 33161 | const mod = sema.mod; | 33481 | const pt = sema.pt; |
| 33482 | const mod = pt.zcu; | ||
| 33162 | if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| { | 33483 | if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| { |
| 33163 | return Air.internedToRef(opv.toIntern()); | 33484 | return Air.internedToRef(opv.toIntern()); |
| 33164 | } | 33485 | } |
| 33165 | if (try sema.resolveValue(un)) |un_val| { | 33486 | if (try sema.resolveValue(un)) |un_val| { |
| 33166 | const tag_val = un_val.unionTag(mod).?; | 33487 | const tag_val = un_val.unionTag(mod).?; |
| 33167 | if (tag_val.isUndef(mod)) | 33488 | if (tag_val.isUndef(mod)) |
| 33168 | return try mod.undefRef(enum_ty); | 33489 | return try pt.undefRef(enum_ty); |
| 33169 | return Air.internedToRef(tag_val.toIntern()); | 33490 | return Air.internedToRef(tag_val.toIntern()); |
| 33170 | } | 33491 | } |
| 33171 | try sema.requireRuntimeBlock(block, un_src, null); | 33492 | try sema.requireRuntimeBlock(block, un_src, null); |
| ... | @@ -33399,7 +33720,7 @@ const PeerResolveResult = union(enum) { | ... | @@ -33399,7 +33720,7 @@ const PeerResolveResult = union(enum) { |
| 33399 | instructions: []const Air.Inst.Ref, | 33720 | instructions: []const Air.Inst.Ref, |
| 33400 | candidate_srcs: PeerTypeCandidateSrc, | 33721 | candidate_srcs: PeerTypeCandidateSrc, |
| 33401 | ) !*Module.ErrorMsg { | 33722 | ) !*Module.ErrorMsg { |
| 33402 | const mod = sema.mod; | 33723 | const pt = sema.pt; |
| 33403 | 33724 | ||
| 33404 | var opt_msg: ?*Module.ErrorMsg = null; | 33725 | var opt_msg: ?*Module.ErrorMsg = null; |
| 33405 | errdefer if (opt_msg) |msg| msg.destroy(sema.gpa); | 33726 | errdefer if (opt_msg) |msg| msg.destroy(sema.gpa); |
| ... | @@ -33425,7 +33746,7 @@ const PeerResolveResult = union(enum) { | ... | @@ -33425,7 +33746,7 @@ const PeerResolveResult = union(enum) { |
| 33425 | }, | 33746 | }, |
| 33426 | .field_error => |field_error| { | 33747 | .field_error => |field_error| { |
| 33427 | const fmt = "struct field '{}' has conflicting types"; | 33748 | const fmt = "struct field '{}' has conflicting types"; |
| 33428 | const args = .{field_error.field_name.fmt(&mod.intern_pool)}; | 33749 | const args = .{field_error.field_name.fmt(&pt.zcu.intern_pool)}; |
| 33429 | if (opt_msg) |msg| { | 33750 | if (opt_msg) |msg| { |
| 33430 | try sema.errNote(src, msg, fmt, args); | 33751 | try sema.errNote(src, msg, fmt, args); |
| 33431 | } else { | 33752 | } else { |
| ... | @@ -33457,8 +33778,8 @@ const PeerResolveResult = union(enum) { | ... | @@ -33457,8 +33778,8 @@ const PeerResolveResult = union(enum) { |
| 33457 | 33778 | ||
| 33458 | const fmt = "incompatible types: '{}' and '{}'"; | 33779 | const fmt = "incompatible types: '{}' and '{}'"; |
| 33459 | const args = .{ | 33780 | const args = .{ |
| 33460 | conflict_tys[0].fmt(mod), | 33781 | conflict_tys[0].fmt(pt), |
| 33461 | conflict_tys[1].fmt(mod), | 33782 | conflict_tys[1].fmt(pt), |
| 33462 | }; | 33783 | }; |
| 33463 | const msg = if (opt_msg) |msg| msg: { | 33784 | const msg = if (opt_msg) |msg| msg: { |
| 33464 | try sema.errNote(src, msg, fmt, args); | 33785 | try sema.errNote(src, msg, fmt, args); |
| ... | @@ -33469,8 +33790,8 @@ const PeerResolveResult = union(enum) { | ... | @@ -33469,8 +33790,8 @@ const PeerResolveResult = union(enum) { |
| 33469 | break :msg msg; | 33790 | break :msg msg; |
| 33470 | }; | 33791 | }; |
| 33471 | 33792 | ||
| 33472 | if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(mod)}); | 33793 | if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(pt)}); |
| 33473 | if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(mod)}); | 33794 | if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(pt)}); |
| 33474 | 33795 | ||
| 33475 | // No child error | 33796 | // No child error |
| 33476 | break; | 33797 | break; |
| ... | @@ -33517,7 +33838,8 @@ fn resolvePeerTypesInner( | ... | @@ -33517,7 +33838,8 @@ fn resolvePeerTypesInner( |
| 33517 | peer_tys: []?Type, | 33838 | peer_tys: []?Type, |
| 33518 | peer_vals: []?Value, | 33839 | peer_vals: []?Value, |
| 33519 | ) !PeerResolveResult { | 33840 | ) !PeerResolveResult { |
| 33520 | const mod = sema.mod; | 33841 | const pt = sema.pt; |
| 33842 | const mod = pt.zcu; | ||
| 33521 | const ip = &mod.intern_pool; | 33843 | const ip = &mod.intern_pool; |
| 33522 | 33844 | ||
| 33523 | var strat_reason: usize = 0; | 33845 | var strat_reason: usize = 0; |
| ... | @@ -33581,7 +33903,7 @@ fn resolvePeerTypesInner( | ... | @@ -33581,7 +33903,7 @@ fn resolvePeerTypesInner( |
| 33581 | .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip), | 33903 | .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip), |
| 33582 | .err_name => val_ptr.* = null, | 33904 | .err_name => val_ptr.* = null, |
| 33583 | }, | 33905 | }, |
| 33584 | .undef => val_ptr.* = Value.fromInterned((try sema.mod.intern(.{ .undef = ty_ptr.*.?.toIntern() }))), | 33906 | .undef => val_ptr.* = Value.fromInterned(try pt.intern(.{ .undef = ty_ptr.*.?.toIntern() })), |
| 33585 | else => unreachable, | 33907 | else => unreachable, |
| 33586 | }; | 33908 | }; |
| 33587 | break :blk set_ty; | 33909 | break :blk set_ty; |
| ... | @@ -33604,7 +33926,7 @@ fn resolvePeerTypesInner( | ... | @@ -33604,7 +33926,7 @@ fn resolvePeerTypesInner( |
| 33604 | .success => |ty| ty, | 33926 | .success => |ty| ty, |
| 33605 | else => |result| return result, | 33927 | else => |result| return result, |
| 33606 | }; | 33928 | }; |
| 33607 | return .{ .success = try mod.errorUnionType(final_set.?, final_payload) }; | 33929 | return .{ .success = try pt.errorUnionType(final_set.?, final_payload) }; |
| 33608 | }, | 33930 | }, |
| 33609 | 33931 | ||
| 33610 | .nullable => { | 33932 | .nullable => { |
| ... | @@ -33642,7 +33964,7 @@ fn resolvePeerTypesInner( | ... | @@ -33642,7 +33964,7 @@ fn resolvePeerTypesInner( |
| 33642 | .success => |ty| ty, | 33964 | .success => |ty| ty, |
| 33643 | else => |result| return result, | 33965 | else => |result| return result, |
| 33644 | }; | 33966 | }; |
| 33645 | return .{ .success = try mod.optionalType(child_ty.toIntern()) }; | 33967 | return .{ .success = try pt.optionalType(child_ty.toIntern()) }; |
| 33646 | }, | 33968 | }, |
| 33647 | 33969 | ||
| 33648 | .array => { | 33970 | .array => { |
| ... | @@ -33730,7 +34052,7 @@ fn resolvePeerTypesInner( | ... | @@ -33730,7 +34052,7 @@ fn resolvePeerTypesInner( |
| 33730 | // There should always be at least one array or vector peer | 34052 | // There should always be at least one array or vector peer |
| 33731 | assert(opt_first_arr_idx != null); | 34053 | assert(opt_first_arr_idx != null); |
| 33732 | 34054 | ||
| 33733 | return .{ .success = try mod.arrayType(.{ | 34055 | return .{ .success = try pt.arrayType(.{ |
| 33734 | .len = len, | 34056 | .len = len, |
| 33735 | .child = elem_ty.toIntern(), | 34057 | .child = elem_ty.toIntern(), |
| 33736 | .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none, | 34058 | .sentinel = if (sentinel) |sent_val| sent_val.toIntern() else .none, |
| ... | @@ -33792,7 +34114,7 @@ fn resolvePeerTypesInner( | ... | @@ -33792,7 +34114,7 @@ fn resolvePeerTypesInner( |
| 33792 | else => |result| return result, | 34114 | else => |result| return result, |
| 33793 | }; | 34115 | }; |
| 33794 | 34116 | ||
| 33795 | return .{ .success = try mod.vectorType(.{ | 34117 | return .{ .success = try pt.vectorType(.{ |
| 33796 | .len = @intCast(len.?), | 34118 | .len = @intCast(len.?), |
| 33797 | .child = child_ty.toIntern(), | 34119 | .child = child_ty.toIntern(), |
| 33798 | }) }; | 34120 | }) }; |
| ... | @@ -33844,8 +34166,8 @@ fn resolvePeerTypesInner( | ... | @@ -33844,8 +34166,8 @@ fn resolvePeerTypesInner( |
| 33844 | }).toIntern(); | 34166 | }).toIntern(); |
| 33845 | 34167 | ||
| 33846 | if (ptr_info.sentinel != .none and peer_info.sentinel != .none) { | 34168 | if (ptr_info.sentinel != .none and peer_info.sentinel != .none) { |
| 33847 | const peer_sent = try ip.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child); | 34169 | const peer_sent = try ip.getCoerced(sema.gpa, pt.tid, ptr_info.sentinel, ptr_info.child); |
| 33848 | const ptr_sent = try ip.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child); | 34170 | const ptr_sent = try ip.getCoerced(sema.gpa, pt.tid, peer_info.sentinel, ptr_info.child); |
| 33849 | if (ptr_sent == peer_sent) { | 34171 | if (ptr_sent == peer_sent) { |
| 33850 | ptr_info.sentinel = ptr_sent; | 34172 | ptr_info.sentinel = ptr_sent; |
| 33851 | } else { | 34173 | } else { |
| ... | @@ -33860,12 +34182,12 @@ fn resolvePeerTypesInner( | ... | @@ -33860,12 +34182,12 @@ fn resolvePeerTypesInner( |
| 33860 | if (ptr_info.flags.alignment != .none) | 34182 | if (ptr_info.flags.alignment != .none) |
| 33861 | ptr_info.flags.alignment | 34183 | ptr_info.flags.alignment |
| 33862 | else | 34184 | else |
| 33863 | Type.fromInterned(ptr_info.child).abiAlignment(mod), | 34185 | Type.fromInterned(ptr_info.child).abiAlignment(pt), |
| 33864 | 34186 | ||
| 33865 | if (peer_info.flags.alignment != .none) | 34187 | if (peer_info.flags.alignment != .none) |
| 33866 | peer_info.flags.alignment | 34188 | peer_info.flags.alignment |
| 33867 | else | 34189 | else |
| 33868 | Type.fromInterned(peer_info.child).abiAlignment(mod), | 34190 | Type.fromInterned(peer_info.child).abiAlignment(pt), |
| 33869 | ); | 34191 | ); |
| 33870 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { | 34192 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { |
| 33871 | return .{ .conflict = .{ | 34193 | return .{ .conflict = .{ |
| ... | @@ -33888,7 +34210,7 @@ fn resolvePeerTypesInner( | ... | @@ -33888,7 +34210,7 @@ fn resolvePeerTypesInner( |
| 33888 | 34210 | ||
| 33889 | opt_ptr_info = ptr_info; | 34211 | opt_ptr_info = ptr_info; |
| 33890 | } | 34212 | } |
| 33891 | return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) }; | 34213 | return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) }; |
| 33892 | }, | 34214 | }, |
| 33893 | 34215 | ||
| 33894 | .ptr => { | 34216 | .ptr => { |
| ... | @@ -34004,7 +34326,7 @@ fn resolvePeerTypesInner( | ... | @@ -34004,7 +34326,7 @@ fn resolvePeerTypesInner( |
| 34004 | if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| { | 34326 | if (try sema.resolvePairInMemoryCoercible(block, src, cur_arr.elem_ty, peer_arr.elem_ty)) |elem_ty| { |
| 34005 | // *[n:x]T + *[n:y]T = *[n]T | 34327 | // *[n:x]T + *[n:y]T = *[n]T |
| 34006 | if (cur_arr.len == peer_arr.len) { | 34328 | if (cur_arr.len == peer_arr.len) { |
| 34007 | ptr_info.child = (try mod.arrayType(.{ | 34329 | ptr_info.child = (try pt.arrayType(.{ |
| 34008 | .len = cur_arr.len, | 34330 | .len = cur_arr.len, |
| 34009 | .child = elem_ty.toIntern(), | 34331 | .child = elem_ty.toIntern(), |
| 34010 | })).toIntern(); | 34332 | })).toIntern(); |
| ... | @@ -34148,12 +34470,12 @@ fn resolvePeerTypesInner( | ... | @@ -34148,12 +34470,12 @@ fn resolvePeerTypesInner( |
| 34148 | no_sentinel: { | 34470 | no_sentinel: { |
| 34149 | if (peer_sentinel == .none) break :no_sentinel; | 34471 | if (peer_sentinel == .none) break :no_sentinel; |
| 34150 | if (cur_sentinel == .none) break :no_sentinel; | 34472 | if (cur_sentinel == .none) break :no_sentinel; |
| 34151 | const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty); | 34473 | const peer_sent_coerced = try ip.getCoerced(sema.gpa, pt.tid, peer_sentinel, sentinel_ty); |
| 34152 | const cur_sent_coerced = try ip.getCoerced(sema.gpa, cur_sentinel, sentinel_ty); | 34474 | const cur_sent_coerced = try ip.getCoerced(sema.gpa, pt.tid, cur_sentinel, sentinel_ty); |
| 34153 | if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel; | 34475 | if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel; |
| 34154 | // Sentinels match | 34476 | // Sentinels match |
| 34155 | if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) { | 34477 | if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) { |
| 34156 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ | 34478 | .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{ |
| 34157 | .len = array_type.len, | 34479 | .len = array_type.len, |
| 34158 | .child = array_type.child, | 34480 | .child = array_type.child, |
| 34159 | .sentinel = cur_sent_coerced, | 34481 | .sentinel = cur_sent_coerced, |
| ... | @@ -34167,7 +34489,7 @@ fn resolvePeerTypesInner( | ... | @@ -34167,7 +34489,7 @@ fn resolvePeerTypesInner( |
| 34167 | // Clear existing sentinel | 34489 | // Clear existing sentinel |
| 34168 | ptr_info.sentinel = .none; | 34490 | ptr_info.sentinel = .none; |
| 34169 | switch (ip.indexToKey(ptr_info.child)) { | 34491 | switch (ip.indexToKey(ptr_info.child)) { |
| 34170 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ | 34492 | .array_type => |array_type| ptr_info.child = (try pt.arrayType(.{ |
| 34171 | .len = array_type.len, | 34493 | .len = array_type.len, |
| 34172 | .child = array_type.child, | 34494 | .child = array_type.child, |
| 34173 | .sentinel = .none, | 34495 | .sentinel = .none, |
| ... | @@ -34198,7 +34520,7 @@ fn resolvePeerTypesInner( | ... | @@ -34198,7 +34520,7 @@ fn resolvePeerTypesInner( |
| 34198 | }, | 34520 | }, |
| 34199 | } | 34521 | } |
| 34200 | 34522 | ||
| 34201 | return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) }; | 34523 | return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) }; |
| 34202 | }, | 34524 | }, |
| 34203 | 34525 | ||
| 34204 | .func => { | 34526 | .func => { |
| ... | @@ -34517,7 +34839,7 @@ fn resolvePeerTypesInner( | ... | @@ -34517,7 +34839,7 @@ fn resolvePeerTypesInner( |
| 34517 | continue; | 34839 | continue; |
| 34518 | }; | 34840 | }; |
| 34519 | peer_field_ty.* = ty.structFieldType(field_index, mod); | 34841 | peer_field_ty.* = ty.structFieldType(field_index, mod); |
| 34520 | peer_field_val.* = if (opt_val) |val| try val.fieldValue(mod, field_index) else null; | 34842 | peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null; |
| 34521 | } | 34843 | } |
| 34522 | 34844 | ||
| 34523 | // Resolve field type recursively | 34845 | // Resolve field type recursively |
| ... | @@ -34555,9 +34877,9 @@ fn resolvePeerTypesInner( | ... | @@ -34555,9 +34877,9 @@ fn resolvePeerTypesInner( |
| 34555 | var comptime_val: ?Value = null; | 34877 | var comptime_val: ?Value = null; |
| 34556 | for (peer_tys) |opt_ty| { | 34878 | for (peer_tys) |opt_ty| { |
| 34557 | const struct_ty = opt_ty orelse continue; | 34879 | const struct_ty = opt_ty orelse continue; |
| 34558 | try struct_ty.resolveStructFieldInits(mod); | 34880 | try struct_ty.resolveStructFieldInits(pt); |
| 34559 | 34881 | ||
| 34560 | const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse { | 34882 | const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse { |
| 34561 | comptime_val = null; | 34883 | comptime_val = null; |
| 34562 | break; | 34884 | break; |
| 34563 | }; | 34885 | }; |
| ... | @@ -34584,7 +34906,7 @@ fn resolvePeerTypesInner( | ... | @@ -34584,7 +34906,7 @@ fn resolvePeerTypesInner( |
| 34584 | field_val.* = if (comptime_val) |v| v.toIntern() else .none; | 34906 | field_val.* = if (comptime_val) |v| v.toIntern() else .none; |
| 34585 | } | 34907 | } |
| 34586 | 34908 | ||
| 34587 | const final_ty = try ip.getAnonStructType(mod.gpa, .{ | 34909 | const final_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{ |
| 34588 | .types = field_types, | 34910 | .types = field_types, |
| 34589 | .names = if (is_tuple) &.{} else field_names, | 34911 | .names = if (is_tuple) &.{} else field_names, |
| 34590 | .values = field_vals, | 34912 | .values = field_vals, |
| ... | @@ -34628,13 +34950,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1 | ... | @@ -34628,13 +34950,15 @@ fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1 |
| 34628 | } | 34950 | } |
| 34629 | 34951 | ||
| 34630 | fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type { | 34952 | fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type { |
| 34953 | const target = sema.pt.zcu.getTarget(); | ||
| 34954 | |||
| 34631 | // ty_b -> ty_a | 34955 | // ty_b -> ty_a |
| 34632 | if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, sema.mod.getTarget(), src, src)) { | 34956 | if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, target, src, src)) { |
| 34633 | return ty_a; | 34957 | return ty_a; |
| 34634 | } | 34958 | } |
| 34635 | 34959 | ||
| 34636 | // ty_a -> ty_b | 34960 | // ty_a -> ty_b |
| 34637 | if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, sema.mod.getTarget(), src, src)) { | 34961 | if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, target, src, src)) { |
| 34638 | return ty_b; | 34962 | return ty_b; |
| 34639 | } | 34963 | } |
| 34640 | 34964 | ||
| ... | @@ -34647,7 +34971,8 @@ const ArrayLike = struct { | ... | @@ -34647,7 +34971,8 @@ const ArrayLike = struct { |
| 34647 | elem_ty: Type, | 34971 | elem_ty: Type, |
| 34648 | }; | 34972 | }; |
| 34649 | fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { | 34973 | fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { |
| 34650 | const mod = sema.mod; | 34974 | const pt = sema.pt; |
| 34975 | const mod = pt.zcu; | ||
| 34651 | return switch (ty.zigTypeTag(mod)) { | 34976 | return switch (ty.zigTypeTag(mod)) { |
| 34652 | .Array => .{ | 34977 | .Array => .{ |
| 34653 | .len = ty.arrayLen(mod), | 34978 | .len = ty.arrayLen(mod), |
| ... | @@ -34676,7 +35001,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { | ... | @@ -34676,7 +35001,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { |
| 34676 | } | 35001 | } |
| 34677 | 35002 | ||
| 34678 | pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void { | 35003 | pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void { |
| 34679 | const mod = sema.mod; | 35004 | const pt = sema.pt; |
| 35005 | const mod = pt.zcu; | ||
| 34680 | const ip = &mod.intern_pool; | 35006 | const ip = &mod.intern_pool; |
| 34681 | 35007 | ||
| 34682 | if (sema.fn_ret_ty_ies) |ies| { | 35008 | if (sema.fn_ret_ty_ies) |ies| { |
| ... | @@ -34687,26 +35013,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void | ... | @@ -34687,26 +35013,27 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void |
| 34687 | } | 35013 | } |
| 34688 | 35014 | ||
| 34689 | pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void { | 35015 | pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void { |
| 34690 | const mod = sema.mod; | 35016 | const pt = sema.pt; |
| 35017 | const mod = pt.zcu; | ||
| 34691 | const ip = &mod.intern_pool; | 35018 | const ip = &mod.intern_pool; |
| 34692 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | 35019 | const fn_ty_info = mod.typeToFunc(fn_ty).?; |
| 34693 | 35020 | ||
| 34694 | try Type.fromInterned(fn_ty_info.return_type).resolveFully(mod); | 35021 | try Type.fromInterned(fn_ty_info.return_type).resolveFully(pt); |
| 34695 | 35022 | ||
| 34696 | if (mod.comp.config.any_error_tracing and | 35023 | if (mod.comp.config.any_error_tracing and |
| 34697 | Type.fromInterned(fn_ty_info.return_type).isError(mod)) | 35024 | Type.fromInterned(fn_ty_info.return_type).isError(mod)) |
| 34698 | { | 35025 | { |
| 34699 | // Ensure the type exists so that backends can assume that. | 35026 | // Ensure the type exists so that backends can assume that. |
| 34700 | _ = try mod.getBuiltinType("StackTrace"); | 35027 | _ = try pt.getBuiltinType("StackTrace"); |
| 34701 | } | 35028 | } |
| 34702 | 35029 | ||
| 34703 | for (0..fn_ty_info.param_types.len) |i| { | 35030 | for (0..fn_ty_info.param_types.len) |i| { |
| 34704 | try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(mod); | 35031 | try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(pt); |
| 34705 | } | 35032 | } |
| 34706 | } | 35033 | } |
| 34707 | 35034 | ||
| 34708 | fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { | 35035 | fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 34709 | return val.resolveLazy(sema.arena, sema.mod); | 35036 | return val.resolveLazy(sema.arena, sema.pt); |
| 34710 | } | 35037 | } |
| 34711 | 35038 | ||
| 34712 | /// Resolve a struct's alignment only without triggering resolution of its layout. | 35039 | /// Resolve a struct's alignment only without triggering resolution of its layout. |
| ... | @@ -34716,7 +35043,8 @@ pub fn resolveStructAlignment( | ... | @@ -34716,7 +35043,8 @@ pub fn resolveStructAlignment( |
| 34716 | ty: InternPool.Index, | 35043 | ty: InternPool.Index, |
| 34717 | struct_type: InternPool.LoadedStructType, | 35044 | struct_type: InternPool.LoadedStructType, |
| 34718 | ) SemaError!void { | 35045 | ) SemaError!void { |
| 34719 | const mod = sema.mod; | 35046 | const pt = sema.pt; |
| 35047 | const mod = pt.zcu; | ||
| 34720 | const ip = &mod.intern_pool; | 35048 | const ip = &mod.intern_pool; |
| 34721 | const target = mod.getTarget(); | 35049 | const target = mod.getTarget(); |
| 34722 | 35050 | ||
| ... | @@ -34754,7 +35082,7 @@ pub fn resolveStructAlignment( | ... | @@ -34754,7 +35082,7 @@ pub fn resolveStructAlignment( |
| 34754 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 35082 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 34755 | if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty)) | 35083 | if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty)) |
| 34756 | continue; | 35084 | continue; |
| 34757 | const field_align = try mod.structFieldAlignmentAdvanced( | 35085 | const field_align = try pt.structFieldAlignmentAdvanced( |
| 34758 | struct_type.fieldAlign(ip, i), | 35086 | struct_type.fieldAlign(ip, i), |
| 34759 | field_ty, | 35087 | field_ty, |
| 34760 | struct_type.layout, | 35088 | struct_type.layout, |
| ... | @@ -34767,7 +35095,8 @@ pub fn resolveStructAlignment( | ... | @@ -34767,7 +35095,8 @@ pub fn resolveStructAlignment( |
| 34767 | } | 35095 | } |
| 34768 | 35096 | ||
| 34769 | pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | 35097 | pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34770 | const zcu = sema.mod; | 35098 | const pt = sema.pt; |
| 35099 | const zcu = pt.zcu; | ||
| 34771 | const ip = &zcu.intern_pool; | 35100 | const ip = &zcu.intern_pool; |
| 34772 | const struct_type = zcu.typeToStruct(ty) orelse return; | 35101 | const struct_type = zcu.typeToStruct(ty) orelse return; |
| 34773 | 35102 | ||
| ... | @@ -34776,10 +35105,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -34776,10 +35105,10 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34776 | if (struct_type.haveLayout(ip)) | 35105 | if (struct_type.haveLayout(ip)) |
| 34777 | return; | 35106 | return; |
| 34778 | 35107 | ||
| 34779 | try ty.resolveFields(zcu); | 35108 | try ty.resolveFields(pt); |
| 34780 | 35109 | ||
| 34781 | if (struct_type.layout == .@"packed") { | 35110 | if (struct_type.layout == .@"packed") { |
| 34782 | semaBackingIntType(zcu, struct_type) catch |err| switch (err) { | 35111 | semaBackingIntType(pt, struct_type) catch |err| switch (err) { |
| 34783 | error.OutOfMemory, error.AnalysisFail => |e| return e, | 35112 | error.OutOfMemory, error.AnalysisFail => |e| return e, |
| 34784 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, | 35113 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, |
| 34785 | }; | 35114 | }; |
| ... | @@ -34790,7 +35119,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -34790,7 +35119,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34790 | const msg = try sema.errMsg( | 35119 | const msg = try sema.errMsg( |
| 34791 | ty.srcLoc(zcu), | 35120 | ty.srcLoc(zcu), |
| 34792 | "struct '{}' depends on itself", | 35121 | "struct '{}' depends on itself", |
| 34793 | .{ty.fmt(zcu)}, | 35122 | .{ty.fmt(pt)}, |
| 34794 | ); | 35123 | ); |
| 34795 | return sema.failWithOwnedErrorMsg(null, msg); | 35124 | return sema.failWithOwnedErrorMsg(null, msg); |
| 34796 | } | 35125 | } |
| ... | @@ -34818,7 +35147,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -34818,7 +35147,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34818 | }, | 35147 | }, |
| 34819 | else => return err, | 35148 | else => return err, |
| 34820 | }; | 35149 | }; |
| 34821 | field_align.* = try zcu.structFieldAlignmentAdvanced( | 35150 | field_align.* = try pt.structFieldAlignmentAdvanced( |
| 34822 | struct_type.fieldAlign(ip, i), | 35151 | struct_type.fieldAlign(ip, i), |
| 34823 | field_ty, | 35152 | field_ty, |
| 34824 | struct_type.layout, | 35153 | struct_type.layout, |
| ... | @@ -34911,7 +35240,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -34911,7 +35240,8 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34911 | _ = try sema.typeRequiresComptime(ty); | 35240 | _ = try sema.typeRequiresComptime(ty); |
| 34912 | } | 35241 | } |
| 34913 | 35242 | ||
| 34914 | fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) CompileError!void { | 35243 | fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructType) CompileError!void { |
| 35244 | const zcu = pt.zcu; | ||
| 34915 | const gpa = zcu.gpa; | 35245 | const gpa = zcu.gpa; |
| 34916 | const ip = &zcu.intern_pool; | 35246 | const ip = &zcu.intern_pool; |
| 34917 | 35247 | ||
| ... | @@ -34927,7 +35257,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi | ... | @@ -34927,7 +35257,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi |
| 34927 | defer comptime_err_ret_trace.deinit(); | 35257 | defer comptime_err_ret_trace.deinit(); |
| 34928 | 35258 | ||
| 34929 | var sema: Sema = .{ | 35259 | var sema: Sema = .{ |
| 34930 | .mod = zcu, | 35260 | .pt = pt, |
| 34931 | .gpa = gpa, | 35261 | .gpa = gpa, |
| 34932 | .arena = analysis_arena.allocator(), | 35262 | .arena = analysis_arena.allocator(), |
| 34933 | .code = zir, | 35263 | .code = zir, |
| ... | @@ -34958,7 +35288,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi | ... | @@ -34958,7 +35288,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi |
| 34958 | var accumulator: u64 = 0; | 35288 | var accumulator: u64 = 0; |
| 34959 | for (0..struct_type.field_types.len) |i| { | 35289 | for (0..struct_type.field_types.len) |i| { |
| 34960 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 35290 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 34961 | accumulator += try field_ty.bitSizeAdvanced(zcu, .sema); | 35291 | accumulator += try field_ty.bitSizeAdvanced(pt, .sema); |
| 34962 | } | 35292 | } |
| 34963 | break :blk accumulator; | 35293 | break :blk accumulator; |
| 34964 | }; | 35294 | }; |
| ... | @@ -35004,7 +35334,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi | ... | @@ -35004,7 +35334,7 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi |
| 35004 | if (fields_bit_sum > std.math.maxInt(u16)) { | 35334 | if (fields_bit_sum > std.math.maxInt(u16)) { |
| 35005 | return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); | 35335 | return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); |
| 35006 | } | 35336 | } |
| 35007 | const backing_int_ty = try zcu.intType(.unsigned, @intCast(fields_bit_sum)); | 35337 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); |
| 35008 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); | 35338 | struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); |
| 35009 | } | 35339 | } |
| 35010 | 35340 | ||
| ... | @@ -35012,26 +35342,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi | ... | @@ -35012,26 +35342,27 @@ fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) Compi |
| 35012 | } | 35342 | } |
| 35013 | 35343 | ||
| 35014 | fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void { | 35344 | fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void { |
| 35015 | const mod = sema.mod; | 35345 | const pt = sema.pt; |
| 35346 | const mod = pt.zcu; | ||
| 35016 | 35347 | ||
| 35017 | if (!backing_int_ty.isInt(mod)) { | 35348 | if (!backing_int_ty.isInt(mod)) { |
| 35018 | return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)}); | 35349 | return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(pt)}); |
| 35019 | } | 35350 | } |
| 35020 | if (backing_int_ty.bitSize(mod) != fields_bit_sum) { | 35351 | if (backing_int_ty.bitSize(pt) != fields_bit_sum) { |
| 35021 | return sema.fail( | 35352 | return sema.fail( |
| 35022 | block, | 35353 | block, |
| 35023 | src, | 35354 | src, |
| 35024 | "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}", | 35355 | "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}", |
| 35025 | .{ backing_int_ty.fmt(sema.mod), backing_int_ty.bitSize(mod), fields_bit_sum }, | 35356 | .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(pt), fields_bit_sum }, |
| 35026 | ); | 35357 | ); |
| 35027 | } | 35358 | } |
| 35028 | } | 35359 | } |
| 35029 | 35360 | ||
| 35030 | fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { | 35361 | fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 35031 | const mod = sema.mod; | 35362 | const pt = sema.pt; |
| 35032 | if (!ty.isIndexable(mod)) { | 35363 | if (!ty.isIndexable(pt.zcu)) { |
| 35033 | const msg = msg: { | 35364 | const msg = msg: { |
| 35034 | const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)}); | 35365 | const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(pt)}); |
| 35035 | errdefer msg.destroy(sema.gpa); | 35366 | errdefer msg.destroy(sema.gpa); |
| 35036 | try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{}); | 35367 | try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{}); |
| 35037 | break :msg msg; | 35368 | break :msg msg; |
| ... | @@ -35041,7 +35372,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { | ... | @@ -35041,7 +35372,8 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 35041 | } | 35372 | } |
| 35042 | 35373 | ||
| 35043 | fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { | 35374 | fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 35044 | const mod = sema.mod; | 35375 | const pt = sema.pt; |
| 35376 | const mod = pt.zcu; | ||
| 35045 | if (ty.zigTypeTag(mod) == .Pointer) { | 35377 | if (ty.zigTypeTag(mod) == .Pointer) { |
| 35046 | switch (ty.ptrSize(mod)) { | 35378 | switch (ty.ptrSize(mod)) { |
| 35047 | .Slice, .Many, .C => return, | 35379 | .Slice, .Many, .C => return, |
| ... | @@ -35054,7 +35386,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void | ... | @@ -35054,7 +35386,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void |
| 35054 | } | 35386 | } |
| 35055 | } | 35387 | } |
| 35056 | const msg = msg: { | 35388 | const msg = msg: { |
| 35057 | const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(sema.mod)}); | 35389 | const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(pt)}); |
| 35058 | errdefer msg.destroy(sema.gpa); | 35390 | errdefer msg.destroy(sema.gpa); |
| 35059 | try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{}); | 35391 | try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{}); |
| 35060 | break :msg msg; | 35392 | break :msg msg; |
| ... | @@ -35069,9 +35401,9 @@ pub fn resolveUnionAlignment( | ... | @@ -35069,9 +35401,9 @@ pub fn resolveUnionAlignment( |
| 35069 | ty: Type, | 35401 | ty: Type, |
| 35070 | union_type: InternPool.LoadedUnionType, | 35402 | union_type: InternPool.LoadedUnionType, |
| 35071 | ) SemaError!void { | 35403 | ) SemaError!void { |
| 35072 | const mod = sema.mod; | 35404 | const zcu = sema.pt.zcu; |
| 35073 | const ip = &mod.intern_pool; | 35405 | const ip = &zcu.intern_pool; |
| 35074 | const target = mod.getTarget(); | 35406 | const target = zcu.getTarget(); |
| 35075 | 35407 | ||
| 35076 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35408 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); |
| 35077 | 35409 | ||
| ... | @@ -35108,8 +35440,8 @@ pub fn resolveUnionAlignment( | ... | @@ -35108,8 +35440,8 @@ pub fn resolveUnionAlignment( |
| 35108 | 35440 | ||
| 35109 | /// This logic must be kept in sync with `Module.getUnionLayout`. | 35441 | /// This logic must be kept in sync with `Module.getUnionLayout`. |
| 35110 | pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | 35442 | pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35111 | const zcu = sema.mod; | 35443 | const pt = sema.pt; |
| 35112 | const ip = &zcu.intern_pool; | 35444 | const ip = &pt.zcu.intern_pool; |
| 35113 | 35445 | ||
| 35114 | try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index)); | 35446 | try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index)); |
| 35115 | 35447 | ||
| ... | @@ -35122,9 +35454,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35122,9 +35454,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35122 | .none, .have_field_types => {}, | 35454 | .none, .have_field_types => {}, |
| 35123 | .field_types_wip, .layout_wip => { | 35455 | .field_types_wip, .layout_wip => { |
| 35124 | const msg = try sema.errMsg( | 35456 | const msg = try sema.errMsg( |
| 35125 | ty.srcLoc(zcu), | 35457 | ty.srcLoc(pt.zcu), |
| 35126 | "union '{}' depends on itself", | 35458 | "union '{}' depends on itself", |
| 35127 | .{ty.fmt(zcu)}, | 35459 | .{ty.fmt(pt)}, |
| 35128 | ); | 35460 | ); |
| 35129 | return sema.failWithOwnedErrorMsg(null, msg); | 35461 | return sema.failWithOwnedErrorMsg(null, msg); |
| 35130 | }, | 35462 | }, |
| ... | @@ -35143,7 +35475,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35143,7 +35475,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35143 | for (0..union_type.field_types.len) |field_index| { | 35475 | for (0..union_type.field_types.len) |field_index| { |
| 35144 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); | 35476 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); |
| 35145 | 35477 | ||
| 35146 | if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(zcu) == .NoReturn) continue; // TODO: should this affect alignment? | 35478 | if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(pt.zcu) == .NoReturn) continue; // TODO: should this affect alignment? |
| 35147 | 35479 | ||
| 35148 | max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) { | 35480 | max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) { |
| 35149 | error.AnalysisFail => { | 35481 | error.AnalysisFail => { |
| ... | @@ -35185,7 +35517,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35185,7 +35517,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35185 | } else { | 35517 | } else { |
| 35186 | // {Payload, Tag} | 35518 | // {Payload, Tag} |
| 35187 | size += max_size; | 35519 | size += max_size; |
| 35188 | size = switch (zcu.getTarget().ofmt) { | 35520 | size = switch (pt.zcu.getTarget().ofmt) { |
| 35189 | .c => max_align, | 35521 | .c => max_align, |
| 35190 | else => tag_align, | 35522 | else => tag_align, |
| 35191 | }.forward(size); | 35523 | }.forward(size); |
| ... | @@ -35205,7 +35537,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35205,7 +35537,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35205 | 35537 | ||
| 35206 | if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { | 35538 | if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { |
| 35207 | const msg = try sema.errMsg( | 35539 | const msg = try sema.errMsg( |
| 35208 | ty.srcLoc(zcu), | 35540 | ty.srcLoc(pt.zcu), |
| 35209 | "union layout depends on it having runtime bits", | 35541 | "union layout depends on it having runtime bits", |
| 35210 | .{}, | 35542 | .{}, |
| 35211 | ); | 35543 | ); |
| ... | @@ -35213,10 +35545,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35213,10 +35545,10 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35213 | } | 35545 | } |
| 35214 | 35546 | ||
| 35215 | if (union_type.flagsPtr(ip).assumed_pointer_aligned and | 35547 | if (union_type.flagsPtr(ip).assumed_pointer_aligned and |
| 35216 | alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8)))) | 35548 | alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8)))) |
| 35217 | { | 35549 | { |
| 35218 | const msg = try sema.errMsg( | 35550 | const msg = try sema.errMsg( |
| 35219 | ty.srcLoc(zcu), | 35551 | ty.srcLoc(pt.zcu), |
| 35220 | "union layout depends on being pointer aligned", | 35552 | "union layout depends on being pointer aligned", |
| 35221 | .{}, | 35553 | .{}, |
| 35222 | ); | 35554 | ); |
| ... | @@ -35229,7 +35561,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35229,7 +35561,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35229 | pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { | 35561 | pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { |
| 35230 | try sema.resolveStructLayout(ty); | 35562 | try sema.resolveStructLayout(ty); |
| 35231 | 35563 | ||
| 35232 | const mod = sema.mod; | 35564 | const pt = sema.pt; |
| 35565 | const mod = pt.zcu; | ||
| 35233 | const ip = &mod.intern_pool; | 35566 | const ip = &mod.intern_pool; |
| 35234 | const struct_type = mod.typeToStruct(ty).?; | 35567 | const struct_type = mod.typeToStruct(ty).?; |
| 35235 | 35568 | ||
| ... | @@ -35244,14 +35577,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35244,14 +35577,15 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { |
| 35244 | 35577 | ||
| 35245 | for (0..struct_type.field_types.len) |i| { | 35578 | for (0..struct_type.field_types.len) |i| { |
| 35246 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 35579 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 35247 | try field_ty.resolveFully(mod); | 35580 | try field_ty.resolveFully(pt); |
| 35248 | } | 35581 | } |
| 35249 | } | 35582 | } |
| 35250 | 35583 | ||
| 35251 | pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { | 35584 | pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35252 | try sema.resolveUnionLayout(ty); | 35585 | try sema.resolveUnionLayout(ty); |
| 35253 | 35586 | ||
| 35254 | const mod = sema.mod; | 35587 | const pt = sema.pt; |
| 35588 | const mod = pt.zcu; | ||
| 35255 | const ip = &mod.intern_pool; | 35589 | const ip = &mod.intern_pool; |
| 35256 | const union_obj = mod.typeToUnion(ty).?; | 35590 | const union_obj = mod.typeToUnion(ty).?; |
| 35257 | 35591 | ||
| ... | @@ -35272,7 +35606,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35272,7 +35606,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35272 | union_obj.flagsPtr(ip).status = .fully_resolved_wip; | 35606 | union_obj.flagsPtr(ip).status = .fully_resolved_wip; |
| 35273 | for (0..union_obj.field_types.len) |field_index| { | 35607 | for (0..union_obj.field_types.len) |field_index| { |
| 35274 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 35608 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 35275 | try field_ty.resolveFully(mod); | 35609 | try field_ty.resolveFully(pt); |
| 35276 | } | 35610 | } |
| 35277 | union_obj.flagsPtr(ip).status = .fully_resolved; | 35611 | union_obj.flagsPtr(ip).status = .fully_resolved; |
| 35278 | } | 35612 | } |
| ... | @@ -35286,7 +35620,8 @@ pub fn resolveTypeFieldsStruct( | ... | @@ -35286,7 +35620,8 @@ pub fn resolveTypeFieldsStruct( |
| 35286 | ty: InternPool.Index, | 35620 | ty: InternPool.Index, |
| 35287 | struct_type: InternPool.LoadedStructType, | 35621 | struct_type: InternPool.LoadedStructType, |
| 35288 | ) SemaError!void { | 35622 | ) SemaError!void { |
| 35289 | const zcu = sema.mod; | 35623 | const pt = sema.pt; |
| 35624 | const zcu = pt.zcu; | ||
| 35290 | const ip = &zcu.intern_pool; | 35625 | const ip = &zcu.intern_pool; |
| 35291 | // If there is no owner decl it means the struct has no fields. | 35626 | // If there is no owner decl it means the struct has no fields. |
| 35292 | const owner_decl = struct_type.decl.unwrap() orelse return; | 35627 | const owner_decl = struct_type.decl.unwrap() orelse return; |
| ... | @@ -35310,13 +35645,13 @@ pub fn resolveTypeFieldsStruct( | ... | @@ -35310,13 +35645,13 @@ pub fn resolveTypeFieldsStruct( |
| 35310 | const msg = try sema.errMsg( | 35645 | const msg = try sema.errMsg( |
| 35311 | Type.fromInterned(ty).srcLoc(zcu), | 35646 | Type.fromInterned(ty).srcLoc(zcu), |
| 35312 | "struct '{}' depends on itself", | 35647 | "struct '{}' depends on itself", |
| 35313 | .{Type.fromInterned(ty).fmt(zcu)}, | 35648 | .{Type.fromInterned(ty).fmt(pt)}, |
| 35314 | ); | 35649 | ); |
| 35315 | return sema.failWithOwnedErrorMsg(null, msg); | 35650 | return sema.failWithOwnedErrorMsg(null, msg); |
| 35316 | } | 35651 | } |
| 35317 | defer struct_type.clearTypesWip(ip); | 35652 | defer struct_type.clearTypesWip(ip); |
| 35318 | 35653 | ||
| 35319 | semaStructFields(zcu, sema.arena, struct_type) catch |err| switch (err) { | 35654 | semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) { |
| 35320 | error.AnalysisFail => { | 35655 | error.AnalysisFail => { |
| 35321 | if (zcu.declPtr(owner_decl).analysis == .complete) { | 35656 | if (zcu.declPtr(owner_decl).analysis == .complete) { |
| 35322 | zcu.declPtr(owner_decl).analysis = .dependency_failure; | 35657 | zcu.declPtr(owner_decl).analysis = .dependency_failure; |
| ... | @@ -35329,7 +35664,8 @@ pub fn resolveTypeFieldsStruct( | ... | @@ -35329,7 +35664,8 @@ pub fn resolveTypeFieldsStruct( |
| 35329 | } | 35664 | } |
| 35330 | 35665 | ||
| 35331 | pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { | 35666 | pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35332 | const zcu = sema.mod; | 35667 | const pt = sema.pt; |
| 35668 | const zcu = pt.zcu; | ||
| 35333 | const ip = &zcu.intern_pool; | 35669 | const ip = &zcu.intern_pool; |
| 35334 | const struct_type = zcu.typeToStruct(ty) orelse return; | 35670 | const struct_type = zcu.typeToStruct(ty) orelse return; |
| 35335 | const owner_decl = struct_type.decl.unwrap() orelse return; | 35671 | const owner_decl = struct_type.decl.unwrap() orelse return; |
| ... | @@ -35345,13 +35681,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35345,13 +35681,13 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35345 | const msg = try sema.errMsg( | 35681 | const msg = try sema.errMsg( |
| 35346 | ty.srcLoc(zcu), | 35682 | ty.srcLoc(zcu), |
| 35347 | "struct '{}' depends on itself", | 35683 | "struct '{}' depends on itself", |
| 35348 | .{ty.fmt(zcu)}, | 35684 | .{ty.fmt(pt)}, |
| 35349 | ); | 35685 | ); |
| 35350 | return sema.failWithOwnedErrorMsg(null, msg); | 35686 | return sema.failWithOwnedErrorMsg(null, msg); |
| 35351 | } | 35687 | } |
| 35352 | defer struct_type.clearInitsWip(ip); | 35688 | defer struct_type.clearInitsWip(ip); |
| 35353 | 35689 | ||
| 35354 | semaStructFieldInits(zcu, sema.arena, struct_type) catch |err| switch (err) { | 35690 | semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) { |
| 35355 | error.AnalysisFail => { | 35691 | error.AnalysisFail => { |
| 35356 | if (zcu.declPtr(owner_decl).analysis == .complete) { | 35692 | if (zcu.declPtr(owner_decl).analysis == .complete) { |
| 35357 | zcu.declPtr(owner_decl).analysis = .dependency_failure; | 35693 | zcu.declPtr(owner_decl).analysis = .dependency_failure; |
| ... | @@ -35365,7 +35701,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35365,7 +35701,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35365 | } | 35701 | } |
| 35366 | 35702 | ||
| 35367 | pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void { | 35703 | pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void { |
| 35368 | const zcu = sema.mod; | 35704 | const pt = sema.pt; |
| 35705 | const zcu = pt.zcu; | ||
| 35369 | const ip = &zcu.intern_pool; | 35706 | const ip = &zcu.intern_pool; |
| 35370 | const owner_decl = zcu.declPtr(union_type.decl); | 35707 | const owner_decl = zcu.declPtr(union_type.decl); |
| 35371 | 35708 | ||
| ... | @@ -35387,7 +35724,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load | ... | @@ -35387,7 +35724,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load |
| 35387 | const msg = try sema.errMsg( | 35724 | const msg = try sema.errMsg( |
| 35388 | ty.srcLoc(zcu), | 35725 | ty.srcLoc(zcu), |
| 35389 | "union '{}' depends on itself", | 35726 | "union '{}' depends on itself", |
| 35390 | .{ty.fmt(zcu)}, | 35727 | .{ty.fmt(pt)}, |
| 35391 | ); | 35728 | ); |
| 35392 | return sema.failWithOwnedErrorMsg(null, msg); | 35729 | return sema.failWithOwnedErrorMsg(null, msg); |
| 35393 | }, | 35730 | }, |
| ... | @@ -35401,7 +35738,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load | ... | @@ -35401,7 +35738,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load |
| 35401 | 35738 | ||
| 35402 | union_type.flagsPtr(ip).status = .field_types_wip; | 35739 | union_type.flagsPtr(ip).status = .field_types_wip; |
| 35403 | errdefer union_type.flagsPtr(ip).status = .none; | 35740 | errdefer union_type.flagsPtr(ip).status = .none; |
| 35404 | semaUnionFields(zcu, sema.arena, union_type) catch |err| switch (err) { | 35741 | semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) { |
| 35405 | error.AnalysisFail => { | 35742 | error.AnalysisFail => { |
| 35406 | if (owner_decl.analysis == .complete) { | 35743 | if (owner_decl.analysis == .complete) { |
| 35407 | owner_decl.analysis = .dependency_failure; | 35744 | owner_decl.analysis = .dependency_failure; |
| ... | @@ -35422,7 +35759,8 @@ fn resolveInferredErrorSet( | ... | @@ -35422,7 +35759,8 @@ fn resolveInferredErrorSet( |
| 35422 | src: LazySrcLoc, | 35759 | src: LazySrcLoc, |
| 35423 | ies_index: InternPool.Index, | 35760 | ies_index: InternPool.Index, |
| 35424 | ) CompileError!InternPool.Index { | 35761 | ) CompileError!InternPool.Index { |
| 35425 | const mod = sema.mod; | 35762 | const pt = sema.pt; |
| 35763 | const mod = pt.zcu; | ||
| 35426 | const ip = &mod.intern_pool; | 35764 | const ip = &mod.intern_pool; |
| 35427 | const func_index = ip.iesFuncIndex(ies_index); | 35765 | const func_index = ip.iesFuncIndex(ies_index); |
| 35428 | const func = mod.funcInfo(func_index); | 35766 | const func = mod.funcInfo(func_index); |
| ... | @@ -35482,8 +35820,8 @@ pub fn resolveInferredErrorSetPtr( | ... | @@ -35482,8 +35820,8 @@ pub fn resolveInferredErrorSetPtr( |
| 35482 | src: LazySrcLoc, | 35820 | src: LazySrcLoc, |
| 35483 | ies: *InferredErrorSet, | 35821 | ies: *InferredErrorSet, |
| 35484 | ) CompileError!void { | 35822 | ) CompileError!void { |
| 35485 | const mod = sema.mod; | 35823 | const pt = sema.pt; |
| 35486 | const ip = &mod.intern_pool; | 35824 | const ip = &pt.zcu.intern_pool; |
| 35487 | 35825 | ||
| 35488 | if (ies.resolved != .none) return; | 35826 | if (ies.resolved != .none) return; |
| 35489 | 35827 | ||
| ... | @@ -35505,7 +35843,7 @@ pub fn resolveInferredErrorSetPtr( | ... | @@ -35505,7 +35843,7 @@ pub fn resolveInferredErrorSetPtr( |
| 35505 | } | 35843 | } |
| 35506 | } | 35844 | } |
| 35507 | 35845 | ||
| 35508 | const resolved_error_set_ty = try mod.errorSetFromUnsortedNames(ies.errors.keys()); | 35846 | const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys()); |
| 35509 | ies.resolved = resolved_error_set_ty.toIntern(); | 35847 | ies.resolved = resolved_error_set_ty.toIntern(); |
| 35510 | } | 35848 | } |
| 35511 | 35849 | ||
| ... | @@ -35515,12 +35853,13 @@ fn resolveAdHocInferredErrorSet( | ... | @@ -35515,12 +35853,13 @@ fn resolveAdHocInferredErrorSet( |
| 35515 | src: LazySrcLoc, | 35853 | src: LazySrcLoc, |
| 35516 | value: InternPool.Index, | 35854 | value: InternPool.Index, |
| 35517 | ) CompileError!InternPool.Index { | 35855 | ) CompileError!InternPool.Index { |
| 35518 | const mod = sema.mod; | 35856 | const pt = sema.pt; |
| 35857 | const mod = pt.zcu; | ||
| 35519 | const gpa = sema.gpa; | 35858 | const gpa = sema.gpa; |
| 35520 | const ip = &mod.intern_pool; | 35859 | const ip = &mod.intern_pool; |
| 35521 | const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value)); | 35860 | const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value)); |
| 35522 | if (new_ty == .none) return value; | 35861 | if (new_ty == .none) return value; |
| 35523 | return ip.getCoerced(gpa, value, new_ty); | 35862 | return ip.getCoerced(gpa, pt.tid, value, new_ty); |
| 35524 | } | 35863 | } |
| 35525 | 35864 | ||
| 35526 | fn resolveAdHocInferredErrorSetTy( | 35865 | fn resolveAdHocInferredErrorSetTy( |
| ... | @@ -35530,8 +35869,8 @@ fn resolveAdHocInferredErrorSetTy( | ... | @@ -35530,8 +35869,8 @@ fn resolveAdHocInferredErrorSetTy( |
| 35530 | ty: InternPool.Index, | 35869 | ty: InternPool.Index, |
| 35531 | ) CompileError!InternPool.Index { | 35870 | ) CompileError!InternPool.Index { |
| 35532 | const ies = sema.fn_ret_ty_ies orelse return .none; | 35871 | const ies = sema.fn_ret_ty_ies orelse return .none; |
| 35533 | const mod = sema.mod; | 35872 | const pt = sema.pt; |
| 35534 | const gpa = sema.gpa; | 35873 | const mod = pt.zcu; |
| 35535 | const ip = &mod.intern_pool; | 35874 | const ip = &mod.intern_pool; |
| 35536 | const error_union_info = switch (ip.indexToKey(ty)) { | 35875 | const error_union_info = switch (ip.indexToKey(ty)) { |
| 35537 | .error_union_type => |x| x, | 35876 | .error_union_type => |x| x, |
| ... | @@ -35541,7 +35880,7 @@ fn resolveAdHocInferredErrorSetTy( | ... | @@ -35541,7 +35880,7 @@ fn resolveAdHocInferredErrorSetTy( |
| 35541 | return .none; | 35880 | return .none; |
| 35542 | 35881 | ||
| 35543 | try sema.resolveInferredErrorSetPtr(block, src, ies); | 35882 | try sema.resolveInferredErrorSetPtr(block, src, ies); |
| 35544 | const new_ty = try ip.get(gpa, .{ .error_union_type = .{ | 35883 | const new_ty = try pt.intern(.{ .error_union_type = .{ |
| 35545 | .error_set_type = ies.resolved, | 35884 | .error_set_type = ies.resolved, |
| 35546 | .payload_type = error_union_info.payload_type, | 35885 | .payload_type = error_union_info.payload_type, |
| 35547 | } }); | 35886 | } }); |
| ... | @@ -35554,7 +35893,8 @@ fn resolveInferredErrorSetTy( | ... | @@ -35554,7 +35893,8 @@ fn resolveInferredErrorSetTy( |
| 35554 | src: LazySrcLoc, | 35893 | src: LazySrcLoc, |
| 35555 | ty: InternPool.Index, | 35894 | ty: InternPool.Index, |
| 35556 | ) CompileError!InternPool.Index { | 35895 | ) CompileError!InternPool.Index { |
| 35557 | const mod = sema.mod; | 35896 | const pt = sema.pt; |
| 35897 | const mod = pt.zcu; | ||
| 35558 | const ip = &mod.intern_pool; | 35898 | const ip = &mod.intern_pool; |
| 35559 | if (ty == .anyerror_type) return ty; | 35899 | if (ty == .anyerror_type) return ty; |
| 35560 | switch (ip.indexToKey(ty)) { | 35900 | switch (ip.indexToKey(ty)) { |
| ... | @@ -35614,10 +35954,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct { | ... | @@ -35614,10 +35954,11 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct { |
| 35614 | } | 35954 | } |
| 35615 | 35955 | ||
| 35616 | fn semaStructFields( | 35956 | fn semaStructFields( |
| 35617 | zcu: *Zcu, | 35957 | pt: Zcu.PerThread, |
| 35618 | arena: Allocator, | 35958 | arena: Allocator, |
| 35619 | struct_type: InternPool.LoadedStructType, | 35959 | struct_type: InternPool.LoadedStructType, |
| 35620 | ) CompileError!void { | 35960 | ) CompileError!void { |
| 35961 | const zcu = pt.zcu; | ||
| 35621 | const gpa = zcu.gpa; | 35962 | const gpa = zcu.gpa; |
| 35622 | const ip = &zcu.intern_pool; | 35963 | const ip = &zcu.intern_pool; |
| 35623 | const decl_index = struct_type.decl.unwrap() orelse return; | 35964 | const decl_index = struct_type.decl.unwrap() orelse return; |
| ... | @@ -35630,7 +35971,7 @@ fn semaStructFields( | ... | @@ -35630,7 +35971,7 @@ fn semaStructFields( |
| 35630 | 35971 | ||
| 35631 | if (fields_len == 0) switch (struct_type.layout) { | 35972 | if (fields_len == 0) switch (struct_type.layout) { |
| 35632 | .@"packed" => { | 35973 | .@"packed" => { |
| 35633 | try semaBackingIntType(zcu, struct_type); | 35974 | try semaBackingIntType(pt, struct_type); |
| 35634 | return; | 35975 | return; |
| 35635 | }, | 35976 | }, |
| 35636 | .auto, .@"extern" => { | 35977 | .auto, .@"extern" => { |
| ... | @@ -35644,7 +35985,7 @@ fn semaStructFields( | ... | @@ -35644,7 +35985,7 @@ fn semaStructFields( |
| 35644 | defer comptime_err_ret_trace.deinit(); | 35985 | defer comptime_err_ret_trace.deinit(); |
| 35645 | 35986 | ||
| 35646 | var sema: Sema = .{ | 35987 | var sema: Sema = .{ |
| 35647 | .mod = zcu, | 35988 | .pt = pt, |
| 35648 | .gpa = gpa, | 35989 | .gpa = gpa, |
| 35649 | .arena = arena, | 35990 | .arena = arena, |
| 35650 | .code = zir, | 35991 | .code = zir, |
| ... | @@ -35789,7 +36130,7 @@ fn semaStructFields( | ... | @@ -35789,7 +36130,7 @@ fn semaStructFields( |
| 35789 | switch (struct_type.layout) { | 36130 | switch (struct_type.layout) { |
| 35790 | .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) { | 36131 | .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) { |
| 35791 | const msg = msg: { | 36132 | const msg = msg: { |
| 35792 | const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); | 36133 | const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 35793 | errdefer msg.destroy(sema.gpa); | 36134 | errdefer msg.destroy(sema.gpa); |
| 35794 | 36135 | ||
| 35795 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field); | 36136 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field); |
| ... | @@ -35801,7 +36142,7 @@ fn semaStructFields( | ... | @@ -35801,7 +36142,7 @@ fn semaStructFields( |
| 35801 | }, | 36142 | }, |
| 35802 | .@"packed" => if (!try sema.validatePackedType(field_ty)) { | 36143 | .@"packed" => if (!try sema.validatePackedType(field_ty)) { |
| 35803 | const msg = msg: { | 36144 | const msg = msg: { |
| 35804 | const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); | 36145 | const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 35805 | errdefer msg.destroy(sema.gpa); | 36146 | errdefer msg.destroy(sema.gpa); |
| 35806 | 36147 | ||
| 35807 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); | 36148 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); |
| ... | @@ -35837,10 +36178,11 @@ fn semaStructFields( | ... | @@ -35837,10 +36178,11 @@ fn semaStructFields( |
| 35837 | 36178 | ||
| 35838 | // This logic must be kept in sync with `semaStructFields` | 36179 | // This logic must be kept in sync with `semaStructFields` |
| 35839 | fn semaStructFieldInits( | 36180 | fn semaStructFieldInits( |
| 35840 | zcu: *Zcu, | 36181 | pt: Zcu.PerThread, |
| 35841 | arena: Allocator, | 36182 | arena: Allocator, |
| 35842 | struct_type: InternPool.LoadedStructType, | 36183 | struct_type: InternPool.LoadedStructType, |
| 35843 | ) CompileError!void { | 36184 | ) CompileError!void { |
| 36185 | const zcu = pt.zcu; | ||
| 35844 | const gpa = zcu.gpa; | 36186 | const gpa = zcu.gpa; |
| 35845 | const ip = &zcu.intern_pool; | 36187 | const ip = &zcu.intern_pool; |
| 35846 | 36188 | ||
| ... | @@ -35857,7 +36199,7 @@ fn semaStructFieldInits( | ... | @@ -35857,7 +36199,7 @@ fn semaStructFieldInits( |
| 35857 | defer comptime_err_ret_trace.deinit(); | 36199 | defer comptime_err_ret_trace.deinit(); |
| 35858 | 36200 | ||
| 35859 | var sema: Sema = .{ | 36201 | var sema: Sema = .{ |
| 35860 | .mod = zcu, | 36202 | .pt = pt, |
| 35861 | .gpa = gpa, | 36203 | .gpa = gpa, |
| 35862 | .arena = arena, | 36204 | .arena = arena, |
| 35863 | .code = zir, | 36205 | .code = zir, |
| ... | @@ -35977,10 +36319,11 @@ fn semaStructFieldInits( | ... | @@ -35977,10 +36319,11 @@ fn semaStructFieldInits( |
| 35977 | try sema.flushExports(); | 36319 | try sema.flushExports(); |
| 35978 | } | 36320 | } |
| 35979 | 36321 | ||
| 35980 | fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { | 36322 | fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { |
| 35981 | const tracy = trace(@src()); | 36323 | const tracy = trace(@src()); |
| 35982 | defer tracy.end(); | 36324 | defer tracy.end(); |
| 35983 | 36325 | ||
| 36326 | const zcu = pt.zcu; | ||
| 35984 | const gpa = zcu.gpa; | 36327 | const gpa = zcu.gpa; |
| 35985 | const ip = &zcu.intern_pool; | 36328 | const ip = &zcu.intern_pool; |
| 35986 | const decl_index = union_type.decl; | 36329 | const decl_index = union_type.decl; |
| ... | @@ -36034,7 +36377,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36034,7 +36377,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36034 | defer comptime_err_ret_trace.deinit(); | 36377 | defer comptime_err_ret_trace.deinit(); |
| 36035 | 36378 | ||
| 36036 | var sema: Sema = .{ | 36379 | var sema: Sema = .{ |
| 36037 | .mod = zcu, | 36380 | .pt = pt, |
| 36038 | .gpa = gpa, | 36381 | .gpa = gpa, |
| 36039 | .arena = arena, | 36382 | .arena = arena, |
| 36040 | .code = zir, | 36383 | .code = zir, |
| ... | @@ -36081,17 +36424,17 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36081,17 +36424,17 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36081 | // The provided type is an integer type and we must construct the enum tag type here. | 36424 | // The provided type is an integer type and we must construct the enum tag type here. |
| 36082 | int_tag_ty = provided_ty; | 36425 | int_tag_ty = provided_ty; |
| 36083 | if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) { | 36426 | if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) { |
| 36084 | return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(zcu)}); | 36427 | return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(pt)}); |
| 36085 | } | 36428 | } |
| 36086 | 36429 | ||
| 36087 | if (fields_len > 0) { | 36430 | if (fields_len > 0) { |
| 36088 | const field_count_val = try zcu.intValue(Type.comptime_int, fields_len - 1); | 36431 | const field_count_val = try pt.intValue(Type.comptime_int, fields_len - 1); |
| 36089 | if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) { | 36432 | if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) { |
| 36090 | const msg = msg: { | 36433 | const msg = msg: { |
| 36091 | const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); | 36434 | const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); |
| 36092 | errdefer msg.destroy(sema.gpa); | 36435 | errdefer msg.destroy(sema.gpa); |
| 36093 | try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{ | 36436 | try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{ |
| 36094 | int_tag_ty.fmt(zcu), | 36437 | int_tag_ty.fmt(pt), |
| 36095 | fields_len - 1, | 36438 | fields_len - 1, |
| 36096 | }); | 36439 | }); |
| 36097 | break :msg msg; | 36440 | break :msg msg; |
| ... | @@ -36106,7 +36449,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36106,7 +36449,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36106 | union_type.tagTypePtr(ip).* = provided_ty.toIntern(); | 36449 | union_type.tagTypePtr(ip).* = provided_ty.toIntern(); |
| 36107 | const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) { | 36450 | const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) { |
| 36108 | .enum_type => ip.loadEnumType(provided_ty.toIntern()), | 36451 | .enum_type => ip.loadEnumType(provided_ty.toIntern()), |
| 36109 | else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(zcu)}), | 36452 | else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}), |
| 36110 | }; | 36453 | }; |
| 36111 | // The fields of the union must match the enum exactly. | 36454 | // The fields of the union must match the enum exactly. |
| 36112 | // A flag per field is used to check for missing and extraneous fields. | 36455 | // A flag per field is used to check for missing and extraneous fields. |
| ... | @@ -36202,7 +36545,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36202,7 +36545,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36202 | const val = if (last_tag_val) |val| | 36545 | const val = if (last_tag_val) |val| |
| 36203 | try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined) | 36546 | try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined) |
| 36204 | else | 36547 | else |
| 36205 | try zcu.intValue(int_tag_ty, 0); | 36548 | try pt.intValue(int_tag_ty, 0); |
| 36206 | last_tag_val = val; | 36549 | last_tag_val = val; |
| 36207 | 36550 | ||
| 36208 | break :blk val; | 36551 | break :blk val; |
| ... | @@ -36214,7 +36557,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36214,7 +36557,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36214 | .offset = .{ .container_field_value = @intCast(gop.index) }, | 36557 | .offset = .{ .container_field_value = @intCast(gop.index) }, |
| 36215 | }; | 36558 | }; |
| 36216 | const msg = msg: { | 36559 | const msg = msg: { |
| 36217 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(zcu, &sema)}); | 36560 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(pt, &sema)}); |
| 36218 | errdefer msg.destroy(gpa); | 36561 | errdefer msg.destroy(gpa); |
| 36219 | try sema.errNote(other_value_src, msg, "other occurrence here", .{}); | 36562 | try sema.errNote(other_value_src, msg, "other occurrence here", .{}); |
| 36220 | break :msg msg; | 36563 | break :msg msg; |
| ... | @@ -36244,7 +36587,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36244,7 +36587,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36244 | const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*); | 36587 | const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*); |
| 36245 | const enum_index = tag_info.nameIndex(ip, field_name) orelse { | 36588 | const enum_index = tag_info.nameIndex(ip, field_name) orelse { |
| 36246 | return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{ | 36589 | return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{ |
| 36247 | field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(zcu), | 36590 | field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(pt), |
| 36248 | }); | 36591 | }); |
| 36249 | }; | 36592 | }; |
| 36250 | 36593 | ||
| ... | @@ -36286,7 +36629,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36286,7 +36629,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36286 | !try sema.validateExternType(field_ty, .union_field)) | 36629 | !try sema.validateExternType(field_ty, .union_field)) |
| 36287 | { | 36630 | { |
| 36288 | const msg = msg: { | 36631 | const msg = msg: { |
| 36289 | const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); | 36632 | const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 36290 | errdefer msg.destroy(sema.gpa); | 36633 | errdefer msg.destroy(sema.gpa); |
| 36291 | 36634 | ||
| 36292 | try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); | 36635 | try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); |
| ... | @@ -36297,7 +36640,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni | ... | @@ -36297,7 +36640,7 @@ fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUni |
| 36297 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 36640 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 36298 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { | 36641 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 36299 | const msg = msg: { | 36642 | const msg = msg: { |
| 36300 | const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); | 36643 | const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)}); |
| 36301 | errdefer msg.destroy(sema.gpa); | 36644 | errdefer msg.destroy(sema.gpa); |
| 36302 | 36645 | ||
| 36303 | try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); | 36646 | try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); |
| ... | @@ -36366,7 +36709,8 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36366,7 +36709,8 @@ fn generateUnionTagTypeNumbered( |
| 36366 | enum_field_vals: []const InternPool.Index, | 36709 | enum_field_vals: []const InternPool.Index, |
| 36367 | union_owner_decl: *Module.Decl, | 36710 | union_owner_decl: *Module.Decl, |
| 36368 | ) !InternPool.Index { | 36711 | ) !InternPool.Index { |
| 36369 | const mod = sema.mod; | 36712 | const pt = sema.pt; |
| 36713 | const mod = pt.zcu; | ||
| 36370 | const gpa = sema.gpa; | 36714 | const gpa = sema.gpa; |
| 36371 | const ip = &mod.intern_pool; | 36715 | const ip = &mod.intern_pool; |
| 36372 | 36716 | ||
| ... | @@ -36390,11 +36734,11 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36390,11 +36734,11 @@ fn generateUnionTagTypeNumbered( |
| 36390 | new_decl.owns_tv = true; | 36734 | new_decl.owns_tv = true; |
| 36391 | new_decl.name_fully_qualified = true; | 36735 | new_decl.name_fully_qualified = true; |
| 36392 | 36736 | ||
| 36393 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{ | 36737 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36394 | .decl = new_decl_index, | 36738 | .decl = new_decl_index, |
| 36395 | .owner_union_ty = union_owner_decl.val.toIntern(), | 36739 | .owner_union_ty = union_owner_decl.val.toIntern(), |
| 36396 | .tag_ty = if (enum_field_vals.len == 0) | 36740 | .tag_ty = if (enum_field_vals.len == 0) |
| 36397 | (try mod.intType(.unsigned, 0)).toIntern() | 36741 | (try pt.intType(.unsigned, 0)).toIntern() |
| 36398 | else | 36742 | else |
| 36399 | ip.typeOf(enum_field_vals[0]), | 36743 | ip.typeOf(enum_field_vals[0]), |
| 36400 | .names = enum_field_names, | 36744 | .names = enum_field_names, |
| ... | @@ -36404,7 +36748,7 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36404,7 +36748,7 @@ fn generateUnionTagTypeNumbered( |
| 36404 | 36748 | ||
| 36405 | new_decl.val = Value.fromInterned(enum_ty); | 36749 | new_decl.val = Value.fromInterned(enum_ty); |
| 36406 | 36750 | ||
| 36407 | try mod.finalizeAnonDecl(new_decl_index); | 36751 | try pt.finalizeAnonDecl(new_decl_index); |
| 36408 | return enum_ty; | 36752 | return enum_ty; |
| 36409 | } | 36753 | } |
| 36410 | 36754 | ||
| ... | @@ -36414,7 +36758,8 @@ fn generateUnionTagTypeSimple( | ... | @@ -36414,7 +36758,8 @@ fn generateUnionTagTypeSimple( |
| 36414 | enum_field_names: []const InternPool.NullTerminatedString, | 36758 | enum_field_names: []const InternPool.NullTerminatedString, |
| 36415 | union_owner_decl: *Module.Decl, | 36759 | union_owner_decl: *Module.Decl, |
| 36416 | ) !InternPool.Index { | 36760 | ) !InternPool.Index { |
| 36417 | const mod = sema.mod; | 36761 | const pt = sema.pt; |
| 36762 | const mod = pt.zcu; | ||
| 36418 | const ip = &mod.intern_pool; | 36763 | const ip = &mod.intern_pool; |
| 36419 | const gpa = sema.gpa; | 36764 | const gpa = sema.gpa; |
| 36420 | 36765 | ||
| ... | @@ -36438,13 +36783,13 @@ fn generateUnionTagTypeSimple( | ... | @@ -36438,13 +36783,13 @@ fn generateUnionTagTypeSimple( |
| 36438 | }; | 36783 | }; |
| 36439 | errdefer mod.abortAnonDecl(new_decl_index); | 36784 | errdefer mod.abortAnonDecl(new_decl_index); |
| 36440 | 36785 | ||
| 36441 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, .{ | 36786 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36442 | .decl = new_decl_index, | 36787 | .decl = new_decl_index, |
| 36443 | .owner_union_ty = union_owner_decl.val.toIntern(), | 36788 | .owner_union_ty = union_owner_decl.val.toIntern(), |
| 36444 | .tag_ty = if (enum_field_names.len == 0) | 36789 | .tag_ty = if (enum_field_names.len == 0) |
| 36445 | (try mod.intType(.unsigned, 0)).toIntern() | 36790 | (try pt.intType(.unsigned, 0)).toIntern() |
| 36446 | else | 36791 | else |
| 36447 | (try mod.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(), | 36792 | (try pt.smallestUnsignedInt(enum_field_names.len - 1)).toIntern(), |
| 36448 | .names = enum_field_names, | 36793 | .names = enum_field_names, |
| 36449 | .values = &.{}, | 36794 | .values = &.{}, |
| 36450 | .tag_mode = .auto, | 36795 | .tag_mode = .auto, |
| ... | @@ -36454,7 +36799,7 @@ fn generateUnionTagTypeSimple( | ... | @@ -36454,7 +36799,7 @@ fn generateUnionTagTypeSimple( |
| 36454 | new_decl.owns_tv = true; | 36799 | new_decl.owns_tv = true; |
| 36455 | new_decl.val = Value.fromInterned(enum_ty); | 36800 | new_decl.val = Value.fromInterned(enum_ty); |
| 36456 | 36801 | ||
| 36457 | try mod.finalizeAnonDecl(new_decl_index); | 36802 | try pt.finalizeAnonDecl(new_decl_index); |
| 36458 | return enum_ty; | 36803 | return enum_ty; |
| 36459 | } | 36804 | } |
| 36460 | 36805 | ||
| ... | @@ -36464,12 +36809,13 @@ fn generateUnionTagTypeSimple( | ... | @@ -36464,12 +36809,13 @@ fn generateUnionTagTypeSimple( |
| 36464 | /// that the types are already resolved. | 36809 | /// that the types are already resolved. |
| 36465 | /// TODO assert the return value matches `ty.onePossibleValue` | 36810 | /// TODO assert the return value matches `ty.onePossibleValue` |
| 36466 | pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | 36811 | pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36467 | const zcu = sema.mod; | 36812 | const pt = sema.pt; |
| 36813 | const zcu = pt.zcu; | ||
| 36468 | const ip = &zcu.intern_pool; | 36814 | const ip = &zcu.intern_pool; |
| 36469 | return switch (ty.toIntern()) { | 36815 | return switch (ty.toIntern()) { |
| 36470 | .u0_type, | 36816 | .u0_type, |
| 36471 | .i0_type, | 36817 | .i0_type, |
| 36472 | => try zcu.intValue(ty, 0), | 36818 | => try pt.intValue(ty, 0), |
| 36473 | .u1_type, | 36819 | .u1_type, |
| 36474 | .u8_type, | 36820 | .u8_type, |
| 36475 | .i8_type, | 36821 | .i8_type, |
| ... | @@ -36532,7 +36878,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36532,7 +36878,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36532 | .anyframe_type => unreachable, | 36878 | .anyframe_type => unreachable, |
| 36533 | .null_type => Value.null, | 36879 | .null_type => Value.null, |
| 36534 | .undefined_type => Value.undef, | 36880 | .undefined_type => Value.undef, |
| 36535 | .optional_noreturn_type => try zcu.nullValue(ty), | 36881 | .optional_noreturn_type => try pt.nullValue(ty), |
| 36536 | .generic_poison_type => error.GenericPoison, | 36882 | .generic_poison_type => error.GenericPoison, |
| 36537 | .empty_struct_type => Value.empty_struct, | 36883 | .empty_struct_type => Value.empty_struct, |
| 36538 | // values, not types | 36884 | // values, not types |
| ... | @@ -36646,16 +36992,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36646,16 +36992,16 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36646 | => switch (ip.indexToKey(ty.toIntern())) { | 36992 | => switch (ip.indexToKey(ty.toIntern())) { |
| 36647 | inline .array_type, .vector_type => |seq_type, seq_tag| { | 36993 | inline .array_type, .vector_type => |seq_type, seq_tag| { |
| 36648 | const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none; | 36994 | const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none; |
| 36649 | if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 36995 | if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36650 | .ty = ty.toIntern(), | 36996 | .ty = ty.toIntern(), |
| 36651 | .storage = .{ .elems = &.{} }, | 36997 | .storage = .{ .elems = &.{} }, |
| 36652 | } }))); | 36998 | } })); |
| 36653 | 36999 | ||
| 36654 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| { | 37000 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| { |
| 36655 | return Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 37001 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36656 | .ty = ty.toIntern(), | 37002 | .ty = ty.toIntern(), |
| 36657 | .storage = .{ .repeated_elem = opv.toIntern() }, | 37003 | .storage = .{ .repeated_elem = opv.toIntern() }, |
| 36658 | } }))); | 37004 | } })); |
| 36659 | } | 37005 | } |
| 36660 | return null; | 37006 | return null; |
| 36661 | }, | 37007 | }, |
| ... | @@ -36663,17 +37009,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36663,17 +37009,17 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36663 | .struct_type => { | 37009 | .struct_type => { |
| 36664 | // Resolving the layout first helps to avoid loops. | 37010 | // Resolving the layout first helps to avoid loops. |
| 36665 | // If the type has a coherent layout, we can recurse through fields safely. | 37011 | // If the type has a coherent layout, we can recurse through fields safely. |
| 36666 | try ty.resolveLayout(zcu); | 37012 | try ty.resolveLayout(pt); |
| 36667 | 37013 | ||
| 36668 | const struct_type = ip.loadStructType(ty.toIntern()); | 37014 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 36669 | 37015 | ||
| 36670 | if (struct_type.field_types.len == 0) { | 37016 | if (struct_type.field_types.len == 0) { |
| 36671 | // In this case the struct has no fields at all and | 37017 | // In this case the struct has no fields at all and |
| 36672 | // therefore has one possible value. | 37018 | // therefore has one possible value. |
| 36673 | return Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 37019 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36674 | .ty = ty.toIntern(), | 37020 | .ty = ty.toIntern(), |
| 36675 | .storage = .{ .elems = &.{} }, | 37021 | .storage = .{ .elems = &.{} }, |
| 36676 | } }))); | 37022 | } })); |
| 36677 | } | 37023 | } |
| 36678 | 37024 | ||
| 36679 | const field_vals = try sema.arena.alloc( | 37025 | const field_vals = try sema.arena.alloc( |
| ... | @@ -36682,7 +37028,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36682,7 +37028,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36682 | ); | 37028 | ); |
| 36683 | for (field_vals, 0..) |*field_val, i| { | 37029 | for (field_vals, 0..) |*field_val, i| { |
| 36684 | if (struct_type.fieldIsComptime(ip, i)) { | 37030 | if (struct_type.fieldIsComptime(ip, i)) { |
| 36685 | try ty.resolveStructFieldInits(zcu); | 37031 | try ty.resolveStructFieldInits(pt); |
| 36686 | field_val.* = struct_type.field_inits.get(ip)[i]; | 37032 | field_val.* = struct_type.field_inits.get(ip)[i]; |
| 36687 | continue; | 37033 | continue; |
| 36688 | } | 37034 | } |
| ... | @@ -36694,10 +37040,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36694,10 +37040,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36694 | 37040 | ||
| 36695 | // In this case the struct has no runtime-known fields and | 37041 | // In this case the struct has no runtime-known fields and |
| 36696 | // therefore has one possible value. | 37042 | // therefore has one possible value. |
| 36697 | return Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 37043 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36698 | .ty = ty.toIntern(), | 37044 | .ty = ty.toIntern(), |
| 36699 | .storage = .{ .elems = field_vals }, | 37045 | .storage = .{ .elems = field_vals }, |
| 36700 | } }))); | 37046 | } })); |
| 36701 | }, | 37047 | }, |
| 36702 | 37048 | ||
| 36703 | .anon_struct_type => |tuple| { | 37049 | .anon_struct_type => |tuple| { |
| ... | @@ -36707,28 +37053,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36707,28 +37053,28 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36707 | // In this case the struct has all comptime-known fields and | 37053 | // In this case the struct has all comptime-known fields and |
| 36708 | // therefore has one possible value. | 37054 | // therefore has one possible value. |
| 36709 | // TODO: write something like getCoercedInts to avoid needing to dupe | 37055 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 36710 | return Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 37056 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 36711 | .ty = ty.toIntern(), | 37057 | .ty = ty.toIntern(), |
| 36712 | .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) }, | 37058 | .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) }, |
| 36713 | } }))); | 37059 | } })); |
| 36714 | }, | 37060 | }, |
| 36715 | 37061 | ||
| 36716 | .union_type => { | 37062 | .union_type => { |
| 36717 | // Resolving the layout first helps to avoid loops. | 37063 | // Resolving the layout first helps to avoid loops. |
| 36718 | // If the type has a coherent layout, we can recurse through fields safely. | 37064 | // If the type has a coherent layout, we can recurse through fields safely. |
| 36719 | try ty.resolveLayout(zcu); | 37065 | try ty.resolveLayout(pt); |
| 36720 | 37066 | ||
| 36721 | const union_obj = ip.loadUnionType(ty.toIntern()); | 37067 | const union_obj = ip.loadUnionType(ty.toIntern()); |
| 36722 | const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse | 37068 | const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse |
| 36723 | return null; | 37069 | return null; |
| 36724 | if (union_obj.field_types.len == 0) { | 37070 | if (union_obj.field_types.len == 0) { |
| 36725 | const only = try zcu.intern(.{ .empty_enum_value = ty.toIntern() }); | 37071 | const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() }); |
| 36726 | return Value.fromInterned(only); | 37072 | return Value.fromInterned(only); |
| 36727 | } | 37073 | } |
| 36728 | const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 37074 | const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 36729 | const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse | 37075 | const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse |
| 36730 | return null; | 37076 | return null; |
| 36731 | const only = try zcu.intern(.{ .un = .{ | 37077 | const only = try pt.intern(.{ .un = .{ |
| 36732 | .ty = ty.toIntern(), | 37078 | .ty = ty.toIntern(), |
| 36733 | .tag = tag_val.toIntern(), | 37079 | .tag = tag_val.toIntern(), |
| 36734 | .val = val_val.toIntern(), | 37080 | .val = val_val.toIntern(), |
| ... | @@ -36743,7 +37089,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36743,7 +37089,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36743 | if (enum_type.tag_ty == .comptime_int_type) return null; | 37089 | if (enum_type.tag_ty == .comptime_int_type) return null; |
| 36744 | 37090 | ||
| 36745 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| { | 37091 | if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| { |
| 36746 | const only = try zcu.intern(.{ .enum_tag = .{ | 37092 | const only = try pt.intern(.{ .enum_tag = .{ |
| 36747 | .ty = ty.toIntern(), | 37093 | .ty = ty.toIntern(), |
| 36748 | .int = int_opv.toIntern(), | 37094 | .int = int_opv.toIntern(), |
| 36749 | } }); | 37095 | } }); |
| ... | @@ -36753,18 +37099,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36753,18 +37099,19 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36753 | return null; | 37099 | return null; |
| 36754 | }, | 37100 | }, |
| 36755 | .auto, .explicit => { | 37101 | .auto, .explicit => { |
| 36756 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null; | 37102 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null; |
| 36757 | 37103 | ||
| 36758 | return Value.fromInterned(switch (enum_type.names.len) { | 37104 | return Value.fromInterned(switch (enum_type.names.len) { |
| 36759 | 0 => try zcu.intern(.{ .empty_enum_value = ty.toIntern() }), | 37105 | 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }), |
| 36760 | 1 => try zcu.intern(.{ .enum_tag = .{ | 37106 | 1 => try pt.intern(.{ .enum_tag = .{ |
| 36761 | .ty = ty.toIntern(), | 37107 | .ty = ty.toIntern(), |
| 36762 | .int = if (enum_type.values.len == 0) | 37108 | .int = if (enum_type.values.len == 0) |
| 36763 | (try zcu.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern() | 37109 | (try pt.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern() |
| 36764 | else | 37110 | else |
| 36765 | try zcu.intern_pool.getCoercedInts( | 37111 | try ip.getCoercedInts( |
| 36766 | zcu.gpa, | 37112 | zcu.gpa, |
| 36767 | zcu.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int, | 37113 | pt.tid, |
| 37114 | ip.indexToKey(enum_type.values.get(ip)[0]).int, | ||
| 36768 | enum_type.tag_ty, | 37115 | enum_type.tag_ty, |
| 36769 | ), | 37116 | ), |
| 36770 | } }), | 37117 | } }), |
| ... | @@ -36782,7 +37129,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36782,7 +37129,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36782 | 37129 | ||
| 36783 | /// Returns the type of the AIR instruction. | 37130 | /// Returns the type of the AIR instruction. |
| 36784 | fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type { | 37131 | fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type { |
| 36785 | return sema.getTmpAir().typeOf(inst, &sema.mod.intern_pool); | 37132 | return sema.getTmpAir().typeOf(inst, &sema.pt.zcu.intern_pool); |
| 36786 | } | 37133 | } |
| 36787 | 37134 | ||
| 36788 | pub fn getTmpAir(sema: Sema) Air { | 37135 | pub fn getTmpAir(sema: Sema) Air { |
| ... | @@ -36838,12 +37185,13 @@ fn analyzeComptimeAlloc( | ... | @@ -36838,12 +37185,13 @@ fn analyzeComptimeAlloc( |
| 36838 | var_type: Type, | 37185 | var_type: Type, |
| 36839 | alignment: Alignment, | 37186 | alignment: Alignment, |
| 36840 | ) CompileError!Air.Inst.Ref { | 37187 | ) CompileError!Air.Inst.Ref { |
| 36841 | const mod = sema.mod; | 37188 | const pt = sema.pt; |
| 37189 | const mod = pt.zcu; | ||
| 36842 | 37190 | ||
| 36843 | // Needed to make an anon decl with type `var_type` (the `finish()` call below). | 37191 | // Needed to make an anon decl with type `var_type` (the `finish()` call below). |
| 36844 | _ = try sema.typeHasOnePossibleValue(var_type); | 37192 | _ = try sema.typeHasOnePossibleValue(var_type); |
| 36845 | 37193 | ||
| 36846 | const ptr_type = try mod.ptrTypeSema(.{ | 37194 | const ptr_type = try pt.ptrTypeSema(.{ |
| 36847 | .child = var_type.toIntern(), | 37195 | .child = var_type.toIntern(), |
| 36848 | .flags = .{ | 37196 | .flags = .{ |
| 36849 | .alignment = alignment, | 37197 | .alignment = alignment, |
| ... | @@ -36853,7 +37201,7 @@ fn analyzeComptimeAlloc( | ... | @@ -36853,7 +37201,7 @@ fn analyzeComptimeAlloc( |
| 36853 | 37201 | ||
| 36854 | const alloc = try sema.newComptimeAlloc(block, var_type, alignment); | 37202 | const alloc = try sema.newComptimeAlloc(block, var_type, alignment); |
| 36855 | 37203 | ||
| 36856 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 37204 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ |
| 36857 | .ty = ptr_type.toIntern(), | 37205 | .ty = ptr_type.toIntern(), |
| 36858 | .base_addr = .{ .comptime_alloc = alloc }, | 37206 | .base_addr = .{ .comptime_alloc = alloc }, |
| 36859 | .byte_offset = 0, | 37207 | .byte_offset = 0, |
| ... | @@ -36896,13 +37244,14 @@ pub fn analyzeAsAddressSpace( | ... | @@ -36896,13 +37244,14 @@ pub fn analyzeAsAddressSpace( |
| 36896 | air_ref: Air.Inst.Ref, | 37244 | air_ref: Air.Inst.Ref, |
| 36897 | ctx: AddressSpaceContext, | 37245 | ctx: AddressSpaceContext, |
| 36898 | ) !std.builtin.AddressSpace { | 37246 | ) !std.builtin.AddressSpace { |
| 36899 | const mod = sema.mod; | 37247 | const pt = sema.pt; |
| 37248 | const mod = pt.zcu; | ||
| 36900 | const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); | 37249 | const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src); |
| 36901 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ | 37250 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ |
| 36902 | .needed_comptime_reason = "address space must be comptime-known", | 37251 | .needed_comptime_reason = "address space must be comptime-known", |
| 36903 | }); | 37252 | }); |
| 36904 | const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val); | 37253 | const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val); |
| 36905 | const target = sema.mod.getTarget(); | 37254 | const target = pt.zcu.getTarget(); |
| 36906 | const arch = target.cpu.arch; | 37255 | const arch = target.cpu.arch; |
| 36907 | 37256 | ||
| 36908 | const is_nv = arch == .nvptx or arch == .nvptx64; | 37257 | const is_nv = arch == .nvptx or arch == .nvptx64; |
| ... | @@ -36946,7 +37295,8 @@ pub fn analyzeAsAddressSpace( | ... | @@ -36946,7 +37295,8 @@ pub fn analyzeAsAddressSpace( |
| 36946 | /// Returns `null` if the pointer contents cannot be loaded at comptime. | 37295 | /// Returns `null` if the pointer contents cannot be loaded at comptime. |
| 36947 | fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value { | 37296 | fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value { |
| 36948 | // TODO: audit use sites to eliminate this coercion | 37297 | // TODO: audit use sites to eliminate this coercion |
| 36949 | const coerced_ptr_val = try sema.mod.getCoerced(ptr_val, ptr_ty); | 37298 | const pt = sema.pt; |
| 37299 | const coerced_ptr_val = try pt.getCoerced(ptr_val, ptr_ty); | ||
| 36950 | switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) { | 37300 | switch (try sema.pointerDerefExtra(block, src, coerced_ptr_val)) { |
| 36951 | .runtime_load => return null, | 37301 | .runtime_load => return null, |
| 36952 | .val => |v| return v, | 37302 | .val => |v| return v, |
| ... | @@ -36954,13 +37304,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr | ... | @@ -36954,13 +37304,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr |
| 36954 | block, | 37304 | block, |
| 36955 | src, | 37305 | src, |
| 36956 | "comptime dereference requires '{}' to have a well-defined layout", | 37306 | "comptime dereference requires '{}' to have a well-defined layout", |
| 36957 | .{ty.fmt(sema.mod)}, | 37307 | .{ty.fmt(pt)}, |
| 36958 | ), | 37308 | ), |
| 36959 | .out_of_bounds => |ty| return sema.fail( | 37309 | .out_of_bounds => |ty| return sema.fail( |
| 36960 | block, | 37310 | block, |
| 36961 | src, | 37311 | src, |
| 36962 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", | 37312 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", |
| 36963 | .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) }, | 37313 | .{ ptr_ty.fmt(pt), ty.fmt(pt) }, |
| 36964 | ), | 37314 | ), |
| 36965 | } | 37315 | } |
| 36966 | } | 37316 | } |
| ... | @@ -36973,10 +37323,10 @@ const DerefResult = union(enum) { | ... | @@ -36973,10 +37323,10 @@ const DerefResult = union(enum) { |
| 36973 | }; | 37323 | }; |
| 36974 | 37324 | ||
| 36975 | fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult { | 37325 | fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value) CompileError!DerefResult { |
| 36976 | const zcu = sema.mod; | 37326 | const pt = sema.pt; |
| 36977 | const ip = &zcu.intern_pool; | 37327 | const ip = &pt.zcu.intern_pool; |
| 36978 | switch (try sema.loadComptimePtr(block, src, ptr_val)) { | 37328 | switch (try sema.loadComptimePtr(block, src, ptr_val)) { |
| 36979 | .success => |mv| return .{ .val = try mv.intern(zcu, sema.arena) }, | 37329 | .success => |mv| return .{ .val = try mv.intern(pt, sema.arena) }, |
| 36980 | .runtime_load => return .runtime_load, | 37330 | .runtime_load => return .runtime_load, |
| 36981 | .undef => return sema.failWithUseOfUndef(block, src), | 37331 | .undef => return sema.failWithUseOfUndef(block, src), |
| 36982 | .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}), | 37332 | .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}), |
| ... | @@ -37001,7 +37351,8 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError | ... | @@ -37001,7 +37351,8 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError |
| 37001 | /// a type has zero bits, which can cause a "foo depends on itself" compile error. | 37351 | /// a type has zero bits, which can cause a "foo depends on itself" compile error. |
| 37002 | /// This logic must be kept in sync with `Type.isPtrLikeOptional`. | 37352 | /// This logic must be kept in sync with `Type.isPtrLikeOptional`. |
| 37003 | fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { | 37353 | fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 37004 | const mod = sema.mod; | 37354 | const pt = sema.pt; |
| 37355 | const mod = pt.zcu; | ||
| 37005 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 37356 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 37006 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 37357 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 37007 | .One, .Many, .C => ty, | 37358 | .One, .Many, .C => ty, |
| ... | @@ -37031,27 +37382,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { | ... | @@ -37031,27 +37382,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 37031 | /// `generic_poison` will return false. | 37382 | /// `generic_poison` will return false. |
| 37032 | /// May return false negatives when structs and unions are having their field types resolved. | 37383 | /// May return false negatives when structs and unions are having their field types resolved. |
| 37033 | pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool { | 37384 | pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool { |
| 37034 | return ty.comptimeOnlyAdvanced(sema.mod, .sema); | 37385 | return ty.comptimeOnlyAdvanced(sema.pt, .sema); |
| 37035 | } | 37386 | } |
| 37036 | 37387 | ||
| 37037 | pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool { | 37388 | pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool { |
| 37038 | return ty.hasRuntimeBitsAdvanced(sema.mod, false, .sema) catch |err| switch (err) { | 37389 | return ty.hasRuntimeBitsAdvanced(sema.pt, false, .sema) catch |err| switch (err) { |
| 37039 | error.NeedLazy => unreachable, | 37390 | error.NeedLazy => unreachable, |
| 37040 | else => |e| return e, | 37391 | else => |e| return e, |
| 37041 | }; | 37392 | }; |
| 37042 | } | 37393 | } |
| 37043 | 37394 | ||
| 37044 | pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 { | 37395 | pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 { |
| 37045 | try ty.resolveLayout(sema.mod); | 37396 | const pt = sema.pt; |
| 37046 | return ty.abiSize(sema.mod); | 37397 | try ty.resolveLayout(pt); |
| 37398 | return ty.abiSize(pt); | ||
| 37047 | } | 37399 | } |
| 37048 | 37400 | ||
| 37049 | pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment { | 37401 | pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment { |
| 37050 | return (try ty.abiAlignmentAdvanced(sema.mod, .sema)).scalar; | 37402 | return (try ty.abiAlignmentAdvanced(sema.pt, .sema)).scalar; |
| 37051 | } | 37403 | } |
| 37052 | 37404 | ||
| 37053 | pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { | 37405 | pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { |
| 37054 | return ty.fnHasRuntimeBitsAdvanced(sema.mod, .sema); | 37406 | return ty.fnHasRuntimeBitsAdvanced(sema.pt, .sema); |
| 37055 | } | 37407 | } |
| 37056 | 37408 | ||
| 37057 | fn unionFieldIndex( | 37409 | fn unionFieldIndex( |
| ... | @@ -37061,9 +37413,10 @@ fn unionFieldIndex( | ... | @@ -37061,9 +37413,10 @@ fn unionFieldIndex( |
| 37061 | field_name: InternPool.NullTerminatedString, | 37413 | field_name: InternPool.NullTerminatedString, |
| 37062 | field_src: LazySrcLoc, | 37414 | field_src: LazySrcLoc, |
| 37063 | ) !u32 { | 37415 | ) !u32 { |
| 37064 | const mod = sema.mod; | 37416 | const pt = sema.pt; |
| 37417 | const mod = pt.zcu; | ||
| 37065 | const ip = &mod.intern_pool; | 37418 | const ip = &mod.intern_pool; |
| 37066 | try union_ty.resolveFields(mod); | 37419 | try union_ty.resolveFields(pt); |
| 37067 | const union_obj = mod.typeToUnion(union_ty).?; | 37420 | const union_obj = mod.typeToUnion(union_ty).?; |
| 37068 | const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse | 37421 | const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse |
| 37069 | return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name); | 37422 | return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name); |
| ... | @@ -37077,9 +37430,10 @@ fn structFieldIndex( | ... | @@ -37077,9 +37430,10 @@ fn structFieldIndex( |
| 37077 | field_name: InternPool.NullTerminatedString, | 37430 | field_name: InternPool.NullTerminatedString, |
| 37078 | field_src: LazySrcLoc, | 37431 | field_src: LazySrcLoc, |
| 37079 | ) !u32 { | 37432 | ) !u32 { |
| 37080 | const mod = sema.mod; | 37433 | const pt = sema.pt; |
| 37434 | const mod = pt.zcu; | ||
| 37081 | const ip = &mod.intern_pool; | 37435 | const ip = &mod.intern_pool; |
| 37082 | try struct_ty.resolveFields(mod); | 37436 | try struct_ty.resolveFields(pt); |
| 37083 | if (struct_ty.isAnonStruct(mod)) { | 37437 | if (struct_ty.isAnonStruct(mod)) { |
| 37084 | return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src); | 37438 | return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src); |
| 37085 | } else { | 37439 | } else { |
| ... | @@ -37096,7 +37450,8 @@ fn anonStructFieldIndex( | ... | @@ -37096,7 +37450,8 @@ fn anonStructFieldIndex( |
| 37096 | field_name: InternPool.NullTerminatedString, | 37450 | field_name: InternPool.NullTerminatedString, |
| 37097 | field_src: LazySrcLoc, | 37451 | field_src: LazySrcLoc, |
| 37098 | ) !u32 { | 37452 | ) !u32 { |
| 37099 | const mod = sema.mod; | 37453 | const pt = sema.pt; |
| 37454 | const mod = pt.zcu; | ||
| 37100 | const ip = &mod.intern_pool; | 37455 | const ip = &mod.intern_pool; |
| 37101 | switch (ip.indexToKey(struct_ty.toIntern())) { | 37456 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| 37102 | .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| { | 37457 | .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| { |
| ... | @@ -37106,20 +37461,21 @@ fn anonStructFieldIndex( | ... | @@ -37106,20 +37461,21 @@ fn anonStructFieldIndex( |
| 37106 | else => unreachable, | 37461 | else => unreachable, |
| 37107 | } | 37462 | } |
| 37108 | return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{ | 37463 | return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{ |
| 37109 | field_name.fmt(ip), struct_ty.fmt(sema.mod), | 37464 | field_name.fmt(ip), struct_ty.fmt(pt), |
| 37110 | }); | 37465 | }); |
| 37111 | } | 37466 | } |
| 37112 | 37467 | ||
| 37113 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting | 37468 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting |
| 37114 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). | 37469 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). |
| 37115 | fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value { | 37470 | fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value { |
| 37471 | const pt = sema.pt; | ||
| 37116 | var overflow: usize = undefined; | 37472 | var overflow: usize = undefined; |
| 37117 | return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) { | 37473 | return sema.intAddInner(lhs, rhs, ty, &overflow) catch |err| switch (err) { |
| 37118 | error.Overflow => { | 37474 | error.Overflow => { |
| 37119 | const is_vec = ty.isVector(sema.mod); | 37475 | const is_vec = ty.isVector(pt.zcu); |
| 37120 | overflow_idx.* = if (is_vec) overflow else 0; | 37476 | overflow_idx.* = if (is_vec) overflow else 0; |
| 37121 | const safe_ty = if (is_vec) try sema.mod.vectorType(.{ | 37477 | const safe_ty = if (is_vec) try pt.vectorType(.{ |
| 37122 | .len = ty.vectorLen(sema.mod), | 37478 | .len = ty.vectorLen(pt.zcu), |
| 37123 | .child = .comptime_int_type, | 37479 | .child = .comptime_int_type, |
| 37124 | }) else Type.comptime_int; | 37480 | }) else Type.comptime_int; |
| 37125 | return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) { | 37481 | return sema.intAddInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) { |
| ... | @@ -37132,13 +37488,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) | ... | @@ -37132,13 +37488,14 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) |
| 37132 | } | 37488 | } |
| 37133 | 37489 | ||
| 37134 | fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value { | 37490 | fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value { |
| 37135 | const mod = sema.mod; | 37491 | const pt = sema.pt; |
| 37492 | const mod = pt.zcu; | ||
| 37136 | if (ty.zigTypeTag(mod) == .Vector) { | 37493 | if (ty.zigTypeTag(mod) == .Vector) { |
| 37137 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 37494 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 37138 | const scalar_ty = ty.scalarType(mod); | 37495 | const scalar_ty = ty.scalarType(mod); |
| 37139 | for (result_data, 0..) |*scalar, i| { | 37496 | for (result_data, 0..) |*scalar, i| { |
| 37140 | const lhs_elem = try lhs.elemValue(mod, i); | 37497 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37141 | const rhs_elem = try rhs.elemValue(mod, i); | 37498 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37142 | const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) { | 37499 | const val = sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) { |
| 37143 | error.Overflow => { | 37500 | error.Overflow => { |
| 37144 | overflow_idx.* = i; | 37501 | overflow_idx.* = i; |
| ... | @@ -37148,34 +37505,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi | ... | @@ -37148,34 +37505,34 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi |
| 37148 | }; | 37505 | }; |
| 37149 | scalar.* = val.toIntern(); | 37506 | scalar.* = val.toIntern(); |
| 37150 | } | 37507 | } |
| 37151 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37508 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37152 | .ty = ty.toIntern(), | 37509 | .ty = ty.toIntern(), |
| 37153 | .storage = .{ .elems = result_data }, | 37510 | .storage = .{ .elems = result_data }, |
| 37154 | } }))); | 37511 | } })); |
| 37155 | } | 37512 | } |
| 37156 | return sema.intAddScalar(lhs, rhs, ty); | 37513 | return sema.intAddScalar(lhs, rhs, ty); |
| 37157 | } | 37514 | } |
| 37158 | 37515 | ||
| 37159 | fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { | 37516 | fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { |
| 37160 | const mod = sema.mod; | 37517 | const pt = sema.pt; |
| 37161 | if (scalar_ty.toIntern() != .comptime_int_type) { | 37518 | if (scalar_ty.toIntern() != .comptime_int_type) { |
| 37162 | const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty); | 37519 | const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty); |
| 37163 | if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow; | 37520 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; |
| 37164 | return res.wrapped_result; | 37521 | return res.wrapped_result; |
| 37165 | } | 37522 | } |
| 37166 | // TODO is this a performance issue? maybe we should try the operation without | 37523 | // TODO is this a performance issue? maybe we should try the operation without |
| 37167 | // resorting to BigInt first. | 37524 | // resorting to BigInt first. |
| 37168 | var lhs_space: Value.BigIntSpace = undefined; | 37525 | var lhs_space: Value.BigIntSpace = undefined; |
| 37169 | var rhs_space: Value.BigIntSpace = undefined; | 37526 | var rhs_space: Value.BigIntSpace = undefined; |
| 37170 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema); | 37527 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); |
| 37171 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema); | 37528 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); |
| 37172 | const limbs = try sema.arena.alloc( | 37529 | const limbs = try sema.arena.alloc( |
| 37173 | std.math.big.Limb, | 37530 | std.math.big.Limb, |
| 37174 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, | 37531 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| 37175 | ); | 37532 | ); |
| 37176 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 37533 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 37177 | result_bigint.add(lhs_bigint, rhs_bigint); | 37534 | result_bigint.add(lhs_bigint, rhs_bigint); |
| 37178 | return mod.intValue_big(scalar_ty, result_bigint.toConst()); | 37535 | return pt.intValue_big(scalar_ty, result_bigint.toConst()); |
| 37179 | } | 37536 | } |
| 37180 | 37537 | ||
| 37181 | /// Supports both floats and ints; handles undefined. | 37538 | /// Supports both floats and ints; handles undefined. |
| ... | @@ -37185,15 +37542,16 @@ fn numberAddWrapScalar( | ... | @@ -37185,15 +37542,16 @@ fn numberAddWrapScalar( |
| 37185 | rhs: Value, | 37542 | rhs: Value, |
| 37186 | ty: Type, | 37543 | ty: Type, |
| 37187 | ) !Value { | 37544 | ) !Value { |
| 37188 | const mod = sema.mod; | 37545 | const pt = sema.pt; |
| 37189 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty); | 37546 | const mod = pt.zcu; |
| 37547 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty); | ||
| 37190 | 37548 | ||
| 37191 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | 37549 | if (ty.zigTypeTag(mod) == .ComptimeInt) { |
| 37192 | return sema.intAdd(lhs, rhs, ty, undefined); | 37550 | return sema.intAdd(lhs, rhs, ty, undefined); |
| 37193 | } | 37551 | } |
| 37194 | 37552 | ||
| 37195 | if (ty.isAnyFloat()) { | 37553 | if (ty.isAnyFloat()) { |
| 37196 | return Value.floatAdd(lhs, rhs, ty, sema.arena, mod); | 37554 | return Value.floatAdd(lhs, rhs, ty, sema.arena, pt); |
| 37197 | } | 37555 | } |
| 37198 | 37556 | ||
| 37199 | const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty); | 37557 | const overflow_result = try sema.intAddWithOverflow(lhs, rhs, ty); |
| ... | @@ -37203,13 +37561,14 @@ fn numberAddWrapScalar( | ... | @@ -37203,13 +37561,14 @@ fn numberAddWrapScalar( |
| 37203 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting | 37561 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting |
| 37204 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). | 37562 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). |
| 37205 | fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value { | 37563 | fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value { |
| 37564 | const pt = sema.pt; | ||
| 37206 | var overflow: usize = undefined; | 37565 | var overflow: usize = undefined; |
| 37207 | return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) { | 37566 | return sema.intSubInner(lhs, rhs, ty, &overflow) catch |err| switch (err) { |
| 37208 | error.Overflow => { | 37567 | error.Overflow => { |
| 37209 | const is_vec = ty.isVector(sema.mod); | 37568 | const is_vec = ty.isVector(pt.zcu); |
| 37210 | overflow_idx.* = if (is_vec) overflow else 0; | 37569 | overflow_idx.* = if (is_vec) overflow else 0; |
| 37211 | const safe_ty = if (is_vec) try sema.mod.vectorType(.{ | 37570 | const safe_ty = if (is_vec) try pt.vectorType(.{ |
| 37212 | .len = ty.vectorLen(sema.mod), | 37571 | .len = ty.vectorLen(pt.zcu), |
| 37213 | .child = .comptime_int_type, | 37572 | .child = .comptime_int_type, |
| 37214 | }) else Type.comptime_int; | 37573 | }) else Type.comptime_int; |
| 37215 | return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) { | 37574 | return sema.intSubInner(lhs, rhs, safe_ty, undefined) catch |err1| switch (err1) { |
| ... | @@ -37222,13 +37581,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) | ... | @@ -37222,13 +37581,13 @@ fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) |
| 37222 | } | 37581 | } |
| 37223 | 37582 | ||
| 37224 | fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value { | 37583 | fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value { |
| 37225 | const mod = sema.mod; | 37584 | const pt = sema.pt; |
| 37226 | if (ty.zigTypeTag(mod) == .Vector) { | 37585 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 37227 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 37586 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 37228 | const scalar_ty = ty.scalarType(mod); | 37587 | const scalar_ty = ty.scalarType(pt.zcu); |
| 37229 | for (result_data, 0..) |*scalar, i| { | 37588 | for (result_data, 0..) |*scalar, i| { |
| 37230 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 37589 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37231 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 37590 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37232 | const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) { | 37591 | const val = sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty) catch |err| switch (err) { |
| 37233 | error.Overflow => { | 37592 | error.Overflow => { |
| 37234 | overflow_idx.* = i; | 37593 | overflow_idx.* = i; |
| ... | @@ -37238,34 +37597,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi | ... | @@ -37238,34 +37597,34 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi |
| 37238 | }; | 37597 | }; |
| 37239 | scalar.* = val.toIntern(); | 37598 | scalar.* = val.toIntern(); |
| 37240 | } | 37599 | } |
| 37241 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37600 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37242 | .ty = ty.toIntern(), | 37601 | .ty = ty.toIntern(), |
| 37243 | .storage = .{ .elems = result_data }, | 37602 | .storage = .{ .elems = result_data }, |
| 37244 | } }))); | 37603 | } })); |
| 37245 | } | 37604 | } |
| 37246 | return sema.intSubScalar(lhs, rhs, ty); | 37605 | return sema.intSubScalar(lhs, rhs, ty); |
| 37247 | } | 37606 | } |
| 37248 | 37607 | ||
| 37249 | fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { | 37608 | fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { |
| 37250 | const mod = sema.mod; | 37609 | const pt = sema.pt; |
| 37251 | if (scalar_ty.toIntern() != .comptime_int_type) { | 37610 | if (scalar_ty.toIntern() != .comptime_int_type) { |
| 37252 | const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty); | 37611 | const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty); |
| 37253 | if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow; | 37612 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; |
| 37254 | return res.wrapped_result; | 37613 | return res.wrapped_result; |
| 37255 | } | 37614 | } |
| 37256 | // TODO is this a performance issue? maybe we should try the operation without | 37615 | // TODO is this a performance issue? maybe we should try the operation without |
| 37257 | // resorting to BigInt first. | 37616 | // resorting to BigInt first. |
| 37258 | var lhs_space: Value.BigIntSpace = undefined; | 37617 | var lhs_space: Value.BigIntSpace = undefined; |
| 37259 | var rhs_space: Value.BigIntSpace = undefined; | 37618 | var rhs_space: Value.BigIntSpace = undefined; |
| 37260 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema); | 37619 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); |
| 37261 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema); | 37620 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); |
| 37262 | const limbs = try sema.arena.alloc( | 37621 | const limbs = try sema.arena.alloc( |
| 37263 | std.math.big.Limb, | 37622 | std.math.big.Limb, |
| 37264 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, | 37623 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| 37265 | ); | 37624 | ); |
| 37266 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 37625 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 37267 | result_bigint.sub(lhs_bigint, rhs_bigint); | 37626 | result_bigint.sub(lhs_bigint, rhs_bigint); |
| 37268 | return mod.intValue_big(scalar_ty, result_bigint.toConst()); | 37627 | return pt.intValue_big(scalar_ty, result_bigint.toConst()); |
| 37269 | } | 37628 | } |
| 37270 | 37629 | ||
| 37271 | /// Supports both floats and ints; handles undefined. | 37630 | /// Supports both floats and ints; handles undefined. |
| ... | @@ -37275,15 +37634,16 @@ fn numberSubWrapScalar( | ... | @@ -37275,15 +37634,16 @@ fn numberSubWrapScalar( |
| 37275 | rhs: Value, | 37634 | rhs: Value, |
| 37276 | ty: Type, | 37635 | ty: Type, |
| 37277 | ) !Value { | 37636 | ) !Value { |
| 37278 | const mod = sema.mod; | 37637 | const pt = sema.pt; |
| 37279 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return mod.undefValue(ty); | 37638 | const mod = pt.zcu; |
| 37639 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty); | ||
| 37280 | 37640 | ||
| 37281 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | 37641 | if (ty.zigTypeTag(mod) == .ComptimeInt) { |
| 37282 | return sema.intSub(lhs, rhs, ty, undefined); | 37642 | return sema.intSub(lhs, rhs, ty, undefined); |
| 37283 | } | 37643 | } |
| 37284 | 37644 | ||
| 37285 | if (ty.isAnyFloat()) { | 37645 | if (ty.isAnyFloat()) { |
| 37286 | return Value.floatSub(lhs, rhs, ty, sema.arena, mod); | 37646 | return Value.floatSub(lhs, rhs, ty, sema.arena, pt); |
| 37287 | } | 37647 | } |
| 37288 | 37648 | ||
| 37289 | const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty); | 37649 | const overflow_result = try sema.intSubWithOverflow(lhs, rhs, ty); |
| ... | @@ -37296,28 +37656,29 @@ fn intSubWithOverflow( | ... | @@ -37296,28 +37656,29 @@ fn intSubWithOverflow( |
| 37296 | rhs: Value, | 37656 | rhs: Value, |
| 37297 | ty: Type, | 37657 | ty: Type, |
| 37298 | ) !Value.OverflowArithmeticResult { | 37658 | ) !Value.OverflowArithmeticResult { |
| 37299 | const mod = sema.mod; | 37659 | const pt = sema.pt; |
| 37660 | const mod = pt.zcu; | ||
| 37300 | if (ty.zigTypeTag(mod) == .Vector) { | 37661 | if (ty.zigTypeTag(mod) == .Vector) { |
| 37301 | const vec_len = ty.vectorLen(mod); | 37662 | const vec_len = ty.vectorLen(mod); |
| 37302 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); | 37663 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37303 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); | 37664 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37304 | const scalar_ty = ty.scalarType(mod); | 37665 | const scalar_ty = ty.scalarType(mod); |
| 37305 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { | 37666 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 37306 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 37667 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37307 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 37668 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37308 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 37669 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 37309 | of.* = of_math_result.overflow_bit.toIntern(); | 37670 | of.* = of_math_result.overflow_bit.toIntern(); |
| 37310 | scalar.* = of_math_result.wrapped_result.toIntern(); | 37671 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 37311 | } | 37672 | } |
| 37312 | return Value.OverflowArithmeticResult{ | 37673 | return Value.OverflowArithmeticResult{ |
| 37313 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37674 | .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37314 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 37675 | .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 37315 | .storage = .{ .elems = overflowed_data }, | 37676 | .storage = .{ .elems = overflowed_data }, |
| 37316 | } }))), | 37677 | } })), |
| 37317 | .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37678 | .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37318 | .ty = ty.toIntern(), | 37679 | .ty = ty.toIntern(), |
| 37319 | .storage = .{ .elems = result_data }, | 37680 | .storage = .{ .elems = result_data }, |
| 37320 | } }))), | 37681 | } })), |
| 37321 | }; | 37682 | }; |
| 37322 | } | 37683 | } |
| 37323 | return sema.intSubWithOverflowScalar(lhs, rhs, ty); | 37684 | return sema.intSubWithOverflowScalar(lhs, rhs, ty); |
| ... | @@ -37329,29 +37690,30 @@ fn intSubWithOverflowScalar( | ... | @@ -37329,29 +37690,30 @@ fn intSubWithOverflowScalar( |
| 37329 | rhs: Value, | 37690 | rhs: Value, |
| 37330 | ty: Type, | 37691 | ty: Type, |
| 37331 | ) !Value.OverflowArithmeticResult { | 37692 | ) !Value.OverflowArithmeticResult { |
| 37332 | const mod = sema.mod; | 37693 | const pt = sema.pt; |
| 37694 | const mod = pt.zcu; | ||
| 37333 | const info = ty.intInfo(mod); | 37695 | const info = ty.intInfo(mod); |
| 37334 | 37696 | ||
| 37335 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | 37697 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { |
| 37336 | return .{ | 37698 | return .{ |
| 37337 | .overflow_bit = try mod.undefValue(Type.u1), | 37699 | .overflow_bit = try pt.undefValue(Type.u1), |
| 37338 | .wrapped_result = try mod.undefValue(ty), | 37700 | .wrapped_result = try pt.undefValue(ty), |
| 37339 | }; | 37701 | }; |
| 37340 | } | 37702 | } |
| 37341 | 37703 | ||
| 37342 | var lhs_space: Value.BigIntSpace = undefined; | 37704 | var lhs_space: Value.BigIntSpace = undefined; |
| 37343 | var rhs_space: Value.BigIntSpace = undefined; | 37705 | var rhs_space: Value.BigIntSpace = undefined; |
| 37344 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema); | 37706 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); |
| 37345 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema); | 37707 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); |
| 37346 | const limbs = try sema.arena.alloc( | 37708 | const limbs = try sema.arena.alloc( |
| 37347 | std.math.big.Limb, | 37709 | std.math.big.Limb, |
| 37348 | std.math.big.int.calcTwosCompLimbCount(info.bits), | 37710 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| 37349 | ); | 37711 | ); |
| 37350 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 37712 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 37351 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 37713 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 37352 | const wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()); | 37714 | const wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()); |
| 37353 | return Value.OverflowArithmeticResult{ | 37715 | return Value.OverflowArithmeticResult{ |
| 37354 | .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)), | 37716 | .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)), |
| 37355 | .wrapped_result = wrapped_result, | 37717 | .wrapped_result = wrapped_result, |
| 37356 | }; | 37718 | }; |
| 37357 | } | 37719 | } |
| ... | @@ -37367,17 +37729,18 @@ fn intFromFloat( | ... | @@ -37367,17 +37729,18 @@ fn intFromFloat( |
| 37367 | int_ty: Type, | 37729 | int_ty: Type, |
| 37368 | mode: IntFromFloatMode, | 37730 | mode: IntFromFloatMode, |
| 37369 | ) CompileError!Value { | 37731 | ) CompileError!Value { |
| 37370 | const mod = sema.mod; | 37732 | const pt = sema.pt; |
| 37733 | const mod = pt.zcu; | ||
| 37371 | if (float_ty.zigTypeTag(mod) == .Vector) { | 37734 | if (float_ty.zigTypeTag(mod) == .Vector) { |
| 37372 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); | 37735 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); |
| 37373 | for (result_data, 0..) |*scalar, i| { | 37736 | for (result_data, 0..) |*scalar, i| { |
| 37374 | const elem_val = try val.elemValue(sema.mod, i); | 37737 | const elem_val = try val.elemValue(pt, i); |
| 37375 | scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern(); | 37738 | scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern(); |
| 37376 | } | 37739 | } |
| 37377 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37740 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37378 | .ty = int_ty.toIntern(), | 37741 | .ty = int_ty.toIntern(), |
| 37379 | .storage = .{ .elems = result_data }, | 37742 | .storage = .{ .elems = result_data }, |
| 37380 | } }))); | 37743 | } })); |
| 37381 | } | 37744 | } |
| 37382 | return sema.intFromFloatScalar(block, src, val, int_ty, mode); | 37745 | return sema.intFromFloatScalar(block, src, val, int_ty, mode); |
| 37383 | } | 37746 | } |
| ... | @@ -37415,7 +37778,8 @@ fn intFromFloatScalar( | ... | @@ -37415,7 +37778,8 @@ fn intFromFloatScalar( |
| 37415 | int_ty: Type, | 37778 | int_ty: Type, |
| 37416 | mode: IntFromFloatMode, | 37779 | mode: IntFromFloatMode, |
| 37417 | ) CompileError!Value { | 37780 | ) CompileError!Value { |
| 37418 | const mod = sema.mod; | 37781 | const pt = sema.pt; |
| 37782 | const mod = pt.zcu; | ||
| 37419 | 37783 | ||
| 37420 | if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src); | 37784 | if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src); |
| 37421 | 37785 | ||
| ... | @@ -37423,32 +37787,32 @@ fn intFromFloatScalar( | ... | @@ -37423,32 +37787,32 @@ fn intFromFloatScalar( |
| 37423 | block, | 37787 | block, |
| 37424 | src, | 37788 | src, |
| 37425 | "fractional component prevents float value '{}' from coercion to type '{}'", | 37789 | "fractional component prevents float value '{}' from coercion to type '{}'", |
| 37426 | .{ val.fmtValue(mod, sema), int_ty.fmt(mod) }, | 37790 | .{ val.fmtValue(pt, sema), int_ty.fmt(pt) }, |
| 37427 | ); | 37791 | ); |
| 37428 | 37792 | ||
| 37429 | const float = val.toFloat(f128, mod); | 37793 | const float = val.toFloat(f128, pt); |
| 37430 | if (std.math.isNan(float)) { | 37794 | if (std.math.isNan(float)) { |
| 37431 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ | 37795 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ |
| 37432 | int_ty.fmt(sema.mod), | 37796 | int_ty.fmt(pt), |
| 37433 | }); | 37797 | }); |
| 37434 | } | 37798 | } |
| 37435 | if (std.math.isInf(float)) { | 37799 | if (std.math.isInf(float)) { |
| 37436 | return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{ | 37800 | return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{ |
| 37437 | int_ty.fmt(sema.mod), | 37801 | int_ty.fmt(pt), |
| 37438 | }); | 37802 | }); |
| 37439 | } | 37803 | } |
| 37440 | 37804 | ||
| 37441 | var big_int = try float128IntPartToBigInt(sema.arena, float); | 37805 | var big_int = try float128IntPartToBigInt(sema.arena, float); |
| 37442 | defer big_int.deinit(); | 37806 | defer big_int.deinit(); |
| 37443 | 37807 | ||
| 37444 | const cti_result = try mod.intValue_big(Type.comptime_int, big_int.toConst()); | 37808 | const cti_result = try pt.intValue_big(Type.comptime_int, big_int.toConst()); |
| 37445 | 37809 | ||
| 37446 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { | 37810 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { |
| 37447 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ | 37811 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ |
| 37448 | val.fmtValue(sema.mod, sema), int_ty.fmt(sema.mod), | 37812 | val.fmtValue(pt, sema), int_ty.fmt(pt), |
| 37449 | }); | 37813 | }); |
| 37450 | } | 37814 | } |
| 37451 | return mod.getCoerced(cti_result, int_ty); | 37815 | return pt.getCoerced(cti_result, int_ty); |
| 37452 | } | 37816 | } |
| 37453 | 37817 | ||
| 37454 | /// Asserts the value is an integer, and the destination type is ComptimeInt or Int. | 37818 | /// Asserts the value is an integer, and the destination type is ComptimeInt or Int. |
| ... | @@ -37461,7 +37825,8 @@ fn intFitsInType( | ... | @@ -37461,7 +37825,8 @@ fn intFitsInType( |
| 37461 | ty: Type, | 37825 | ty: Type, |
| 37462 | vector_index: ?*usize, | 37826 | vector_index: ?*usize, |
| 37463 | ) CompileError!bool { | 37827 | ) CompileError!bool { |
| 37464 | const mod = sema.mod; | 37828 | const pt = sema.pt; |
| 37829 | const mod = pt.zcu; | ||
| 37465 | if (ty.toIntern() == .comptime_int_type) return true; | 37830 | if (ty.toIntern() == .comptime_int_type) return true; |
| 37466 | const info = ty.intInfo(mod); | 37831 | const info = ty.intInfo(mod); |
| 37467 | switch (val.toIntern()) { | 37832 | switch (val.toIntern()) { |
| ... | @@ -37528,22 +37893,23 @@ fn intFitsInType( | ... | @@ -37528,22 +37893,23 @@ fn intFitsInType( |
| 37528 | } | 37893 | } |
| 37529 | 37894 | ||
| 37530 | fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool { | 37895 | fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool { |
| 37531 | const mod = sema.mod; | 37896 | const pt = sema.pt; |
| 37532 | if (!(try int_val.compareAllWithZeroSema(.gte, mod))) return false; | 37897 | if (!(try int_val.compareAllWithZeroSema(.gte, pt))) return false; |
| 37533 | const end_val = try mod.intValue(tag_ty, end); | 37898 | const end_val = try pt.intValue(tag_ty, end); |
| 37534 | if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false; | 37899 | if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false; |
| 37535 | return true; | 37900 | return true; |
| 37536 | } | 37901 | } |
| 37537 | 37902 | ||
| 37538 | /// Asserts the type is an enum. | 37903 | /// Asserts the type is an enum. |
| 37539 | fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { | 37904 | fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { |
| 37540 | const mod = sema.mod; | 37905 | const pt = sema.pt; |
| 37906 | const mod = pt.zcu; | ||
| 37541 | const enum_type = mod.intern_pool.loadEnumType(ty.toIntern()); | 37907 | const enum_type = mod.intern_pool.loadEnumType(ty.toIntern()); |
| 37542 | assert(enum_type.tag_mode != .nonexhaustive); | 37908 | assert(enum_type.tag_mode != .nonexhaustive); |
| 37543 | // The `tagValueIndex` function call below relies on the type being the integer tag type. | 37909 | // The `tagValueIndex` function call below relies on the type being the integer tag type. |
| 37544 | // `getCoerced` assumes the value will fit the new type. | 37910 | // `getCoerced` assumes the value will fit the new type. |
| 37545 | if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false; | 37911 | if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false; |
| 37546 | const int_coerced = try mod.getCoerced(int, Type.fromInterned(enum_type.tag_ty)); | 37912 | const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty)); |
| 37547 | 37913 | ||
| 37548 | return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null; | 37914 | return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null; |
| 37549 | } | 37915 | } |
| ... | @@ -37554,28 +37920,29 @@ fn intAddWithOverflow( | ... | @@ -37554,28 +37920,29 @@ fn intAddWithOverflow( |
| 37554 | rhs: Value, | 37920 | rhs: Value, |
| 37555 | ty: Type, | 37921 | ty: Type, |
| 37556 | ) !Value.OverflowArithmeticResult { | 37922 | ) !Value.OverflowArithmeticResult { |
| 37557 | const mod = sema.mod; | 37923 | const pt = sema.pt; |
| 37924 | const mod = pt.zcu; | ||
| 37558 | if (ty.zigTypeTag(mod) == .Vector) { | 37925 | if (ty.zigTypeTag(mod) == .Vector) { |
| 37559 | const vec_len = ty.vectorLen(mod); | 37926 | const vec_len = ty.vectorLen(mod); |
| 37560 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); | 37927 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37561 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); | 37928 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37562 | const scalar_ty = ty.scalarType(mod); | 37929 | const scalar_ty = ty.scalarType(mod); |
| 37563 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { | 37930 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 37564 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 37931 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37565 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 37932 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37566 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 37933 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 37567 | of.* = of_math_result.overflow_bit.toIntern(); | 37934 | of.* = of_math_result.overflow_bit.toIntern(); |
| 37568 | scalar.* = of_math_result.wrapped_result.toIntern(); | 37935 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 37569 | } | 37936 | } |
| 37570 | return Value.OverflowArithmeticResult{ | 37937 | return Value.OverflowArithmeticResult{ |
| 37571 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37938 | .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37572 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 37939 | .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 37573 | .storage = .{ .elems = overflowed_data }, | 37940 | .storage = .{ .elems = overflowed_data }, |
| 37574 | } }))), | 37941 | } })), |
| 37575 | .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 37942 | .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37576 | .ty = ty.toIntern(), | 37943 | .ty = ty.toIntern(), |
| 37577 | .storage = .{ .elems = result_data }, | 37944 | .storage = .{ .elems = result_data }, |
| 37578 | } }))), | 37945 | } })), |
| 37579 | }; | 37946 | }; |
| 37580 | } | 37947 | } |
| 37581 | return sema.intAddWithOverflowScalar(lhs, rhs, ty); | 37948 | return sema.intAddWithOverflowScalar(lhs, rhs, ty); |
| ... | @@ -37587,29 +37954,30 @@ fn intAddWithOverflowScalar( | ... | @@ -37587,29 +37954,30 @@ fn intAddWithOverflowScalar( |
| 37587 | rhs: Value, | 37954 | rhs: Value, |
| 37588 | ty: Type, | 37955 | ty: Type, |
| 37589 | ) !Value.OverflowArithmeticResult { | 37956 | ) !Value.OverflowArithmeticResult { |
| 37590 | const mod = sema.mod; | 37957 | const pt = sema.pt; |
| 37958 | const mod = pt.zcu; | ||
| 37591 | const info = ty.intInfo(mod); | 37959 | const info = ty.intInfo(mod); |
| 37592 | 37960 | ||
| 37593 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | 37961 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { |
| 37594 | return .{ | 37962 | return .{ |
| 37595 | .overflow_bit = try mod.undefValue(Type.u1), | 37963 | .overflow_bit = try pt.undefValue(Type.u1), |
| 37596 | .wrapped_result = try mod.undefValue(ty), | 37964 | .wrapped_result = try pt.undefValue(ty), |
| 37597 | }; | 37965 | }; |
| 37598 | } | 37966 | } |
| 37599 | 37967 | ||
| 37600 | var lhs_space: Value.BigIntSpace = undefined; | 37968 | var lhs_space: Value.BigIntSpace = undefined; |
| 37601 | var rhs_space: Value.BigIntSpace = undefined; | 37969 | var rhs_space: Value.BigIntSpace = undefined; |
| 37602 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema); | 37970 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); |
| 37603 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema); | 37971 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); |
| 37604 | const limbs = try sema.arena.alloc( | 37972 | const limbs = try sema.arena.alloc( |
| 37605 | std.math.big.Limb, | 37973 | std.math.big.Limb, |
| 37606 | std.math.big.int.calcTwosCompLimbCount(info.bits), | 37974 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| 37607 | ); | 37975 | ); |
| 37608 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 37976 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 37609 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 37977 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 37610 | const result = try mod.intValue_big(ty, result_bigint.toConst()); | 37978 | const result = try pt.intValue_big(ty, result_bigint.toConst()); |
| 37611 | return Value.OverflowArithmeticResult{ | 37979 | return Value.OverflowArithmeticResult{ |
| 37612 | .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)), | 37980 | .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)), |
| 37613 | .wrapped_result = result, | 37981 | .wrapped_result = result, |
| 37614 | }; | 37982 | }; |
| 37615 | } | 37983 | } |
| ... | @@ -37625,12 +37993,13 @@ fn compareAll( | ... | @@ -37625,12 +37993,13 @@ fn compareAll( |
| 37625 | rhs: Value, | 37993 | rhs: Value, |
| 37626 | ty: Type, | 37994 | ty: Type, |
| 37627 | ) CompileError!bool { | 37995 | ) CompileError!bool { |
| 37628 | const mod = sema.mod; | 37996 | const pt = sema.pt; |
| 37997 | const mod = pt.zcu; | ||
| 37629 | if (ty.zigTypeTag(mod) == .Vector) { | 37998 | if (ty.zigTypeTag(mod) == .Vector) { |
| 37630 | var i: usize = 0; | 37999 | var i: usize = 0; |
| 37631 | while (i < ty.vectorLen(mod)) : (i += 1) { | 38000 | while (i < ty.vectorLen(mod)) : (i += 1) { |
| 37632 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 38001 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37633 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 38002 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37634 | if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) { | 38003 | if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) { |
| 37635 | return false; | 38004 | return false; |
| 37636 | } | 38005 | } |
| ... | @@ -37648,13 +38017,13 @@ fn compareScalar( | ... | @@ -37648,13 +38017,13 @@ fn compareScalar( |
| 37648 | rhs: Value, | 38017 | rhs: Value, |
| 37649 | ty: Type, | 38018 | ty: Type, |
| 37650 | ) CompileError!bool { | 38019 | ) CompileError!bool { |
| 37651 | const mod = sema.mod; | 38020 | const pt = sema.pt; |
| 37652 | const coerced_lhs = try mod.getCoerced(lhs, ty); | 38021 | const coerced_lhs = try pt.getCoerced(lhs, ty); |
| 37653 | const coerced_rhs = try mod.getCoerced(rhs, ty); | 38022 | const coerced_rhs = try pt.getCoerced(rhs, ty); |
| 37654 | switch (op) { | 38023 | switch (op) { |
| 37655 | .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty), | 38024 | .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty), |
| 37656 | .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)), | 38025 | .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)), |
| 37657 | else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, mod, .sema), | 38026 | else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, pt, .sema), |
| 37658 | } | 38027 | } |
| 37659 | } | 38028 | } |
| 37660 | 38029 | ||
| ... | @@ -37664,7 +38033,7 @@ fn valuesEqual( | ... | @@ -37664,7 +38033,7 @@ fn valuesEqual( |
| 37664 | rhs: Value, | 38033 | rhs: Value, |
| 37665 | ty: Type, | 38034 | ty: Type, |
| 37666 | ) CompileError!bool { | 38035 | ) CompileError!bool { |
| 37667 | return lhs.eql(rhs, ty, sema.mod); | 38036 | return lhs.eql(rhs, ty, sema.pt.zcu); |
| 37668 | } | 38037 | } |
| 37669 | 38038 | ||
| 37670 | /// Asserts the values are comparable vectors of type `ty`. | 38039 | /// Asserts the values are comparable vectors of type `ty`. |
| ... | @@ -37675,29 +38044,30 @@ fn compareVector( | ... | @@ -37675,29 +38044,30 @@ fn compareVector( |
| 37675 | rhs: Value, | 38044 | rhs: Value, |
| 37676 | ty: Type, | 38045 | ty: Type, |
| 37677 | ) !Value { | 38046 | ) !Value { |
| 37678 | const mod = sema.mod; | 38047 | const pt = sema.pt; |
| 38048 | const mod = pt.zcu; | ||
| 37679 | assert(ty.zigTypeTag(mod) == .Vector); | 38049 | assert(ty.zigTypeTag(mod) == .Vector); |
| 37680 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 38050 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 37681 | for (result_data, 0..) |*scalar, i| { | 38051 | for (result_data, 0..) |*scalar, i| { |
| 37682 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 38052 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37683 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 38053 | const rhs_elem = try rhs.elemValue(pt, i); |
| 37684 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)); | 38054 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)); |
| 37685 | scalar.* = Value.makeBool(res_bool).toIntern(); | 38055 | scalar.* = Value.makeBool(res_bool).toIntern(); |
| 37686 | } | 38056 | } |
| 37687 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38057 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37688 | .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), | 38058 | .ty = (try pt.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), |
| 37689 | .storage = .{ .elems = result_data }, | 38059 | .storage = .{ .elems = result_data }, |
| 37690 | } }))); | 38060 | } })); |
| 37691 | } | 38061 | } |
| 37692 | 38062 | ||
| 37693 | /// Merge lhs with rhs. | 38063 | /// Merge lhs with rhs. |
| 37694 | /// Asserts that lhs and rhs are both error sets and are resolved. | 38064 | /// Asserts that lhs and rhs are both error sets and are resolved. |
| 37695 | fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { | 38065 | fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { |
| 37696 | const mod = sema.mod; | 38066 | const pt = sema.pt; |
| 37697 | const ip = &mod.intern_pool; | 38067 | const ip = &pt.zcu.intern_pool; |
| 37698 | const arena = sema.arena; | 38068 | const arena = sema.arena; |
| 37699 | const lhs_names = lhs.errorSetNames(mod); | 38069 | const lhs_names = lhs.errorSetNames(pt.zcu); |
| 37700 | const rhs_names = rhs.errorSetNames(mod); | 38070 | const rhs_names = rhs.errorSetNames(pt.zcu); |
| 37701 | var names: InferredErrorSet.NameMap = .{}; | 38071 | var names: InferredErrorSet.NameMap = .{}; |
| 37702 | try names.ensureUnusedCapacity(arena, lhs_names.len); | 38072 | try names.ensureUnusedCapacity(arena, lhs_names.len); |
| 37703 | 38073 | ||
| ... | @@ -37708,7 +38078,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { | ... | @@ -37708,7 +38078,7 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { |
| 37708 | try names.put(arena, rhs_names.get(ip)[rhs_index], {}); | 38078 | try names.put(arena, rhs_names.get(ip)[rhs_index], {}); |
| 37709 | } | 38079 | } |
| 37710 | 38080 | ||
| 37711 | return mod.errorSetFromUnsortedNames(names.keys()); | 38081 | return pt.errorSetFromUnsortedNames(names.keys()); |
| 37712 | } | 38082 | } |
| 37713 | 38083 | ||
| 37714 | /// Avoids crashing the compiler when asking if inferred allocations are noreturn. | 38084 | /// Avoids crashing the compiler when asking if inferred allocations are noreturn. |
| ... | @@ -37718,7 +38088,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { | ... | @@ -37718,7 +38088,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { |
| 37718 | .inferred_alloc, .inferred_alloc_comptime => return false, | 38088 | .inferred_alloc, .inferred_alloc_comptime => return false, |
| 37719 | else => {}, | 38089 | else => {}, |
| 37720 | }; | 38090 | }; |
| 37721 | return sema.typeOf(ref).isNoReturn(sema.mod); | 38091 | return sema.typeOf(ref).isNoReturn(sema.pt.zcu); |
| 37722 | } | 38092 | } |
| 37723 | 38093 | ||
| 37724 | /// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type. | 38094 | /// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type. |
| ... | @@ -37727,11 +38097,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool | ... | @@ -37727,11 +38097,12 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool |
| 37727 | .inferred_alloc, .inferred_alloc_comptime => return false, | 38097 | .inferred_alloc, .inferred_alloc_comptime => return false, |
| 37728 | else => {}, | 38098 | else => {}, |
| 37729 | }; | 38099 | }; |
| 37730 | return sema.typeOf(ref).zigTypeTag(sema.mod) == tag; | 38100 | return sema.typeOf(ref).zigTypeTag(sema.pt.zcu) == tag; |
| 37731 | } | 38101 | } |
| 37732 | 38102 | ||
| 37733 | pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { | 38103 | pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { |
| 37734 | if (!sema.mod.comp.debug_incremental) return; | 38104 | const zcu = sema.pt.zcu; |
| 38105 | if (!zcu.comp.debug_incremental) return; | ||
| 37735 | 38106 | ||
| 37736 | // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields | 38107 | // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields |
| 37737 | // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would | 38108 | // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would |
| ... | @@ -37747,11 +38118,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { | ... | @@ -37747,11 +38118,11 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { |
| 37747 | else | 38118 | else |
| 37748 | .{ .decl = sema.owner_decl_index }, | 38119 | .{ .decl = sema.owner_decl_index }, |
| 37749 | ); | 38120 | ); |
| 37750 | try sema.mod.intern_pool.addDependency(sema.gpa, depender, dependee); | 38121 | try zcu.intern_pool.addDependency(sema.gpa, depender, dependee); |
| 37751 | } | 38122 | } |
| 37752 | 38123 | ||
| 37753 | fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { | 38124 | fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { |
| 37754 | return switch (sema.mod.intern_pool.indexToKey(val.toIntern())) { | 38125 | return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 37755 | .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)), | 38126 | .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)), |
| 37756 | .ptr => |ptr| switch (ptr.base_addr) { | 38127 | .ptr => |ptr| switch (ptr.base_addr) { |
| 37757 | .anon_decl, .decl, .int => false, | 38128 | .anon_decl, .decl, .int => false, |
| ... | @@ -37766,7 +38137,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { | ... | @@ -37766,7 +38137,7 @@ fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { |
| 37766 | 38137 | ||
| 37767 | fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool { | 38138 | fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool { |
| 37768 | const val = ptr.toInterned() orelse return true; | 38139 | const val = ptr.toInterned() orelse return true; |
| 37769 | return !Value.fromInterned(val).canMutateComptimeVarState(sema.mod); | 38140 | return !Value.fromInterned(val).canMutateComptimeVarState(sema.pt.zcu); |
| 37770 | } | 38141 | } |
| 37771 | 38142 | ||
| 37772 | fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void { | 38143 | fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void { |
| ... | @@ -37781,7 +38152,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai | ... | @@ -37781,7 +38152,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai |
| 37781 | 38152 | ||
| 37782 | /// Returns true if any value contained in `val` is undefined. | 38153 | /// Returns true if any value contained in `val` is undefined. |
| 37783 | fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool { | 38154 | fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool { |
| 37784 | const mod = sema.mod; | 38155 | const pt = sema.pt; |
| 38156 | const mod = pt.zcu; | ||
| 37785 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 38157 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 37786 | .undef => true, | 38158 | .undef => true, |
| 37787 | .simple_value => |v| v == .undefined, | 38159 | .simple_value => |v| v == .undefined, |
| ... | @@ -37807,13 +38179,14 @@ fn sliceToIpString( | ... | @@ -37807,13 +38179,14 @@ fn sliceToIpString( |
| 37807 | slice_val: Value, | 38179 | slice_val: Value, |
| 37808 | reason: NeededComptimeReason, | 38180 | reason: NeededComptimeReason, |
| 37809 | ) CompileError!InternPool.NullTerminatedString { | 38181 | ) CompileError!InternPool.NullTerminatedString { |
| 37810 | const zcu = sema.mod; | 38182 | const pt = sema.pt; |
| 38183 | const zcu = pt.zcu; | ||
| 37811 | const slice_ty = slice_val.typeOf(zcu); | 38184 | const slice_ty = slice_val.typeOf(zcu); |
| 37812 | assert(slice_ty.isSlice(zcu)); | 38185 | assert(slice_ty.isSlice(zcu)); |
| 37813 | assert(slice_ty.childType(zcu).toIntern() == .u8_type); | 38186 | assert(slice_ty.childType(zcu).toIntern() == .u8_type); |
| 37814 | const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason); | 38187 | const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason); |
| 37815 | const array_ty = array_val.typeOf(zcu); | 38188 | const array_ty = array_val.typeOf(zcu); |
| 37816 | return array_val.toIpString(array_ty, zcu); | 38189 | return array_val.toIpString(array_ty, pt); |
| 37817 | } | 38190 | } |
| 37818 | 38191 | ||
| 37819 | /// Given a slice value, attempts to dereference it into a comptime-known array. | 38192 | /// Given a slice value, attempts to dereference it into a comptime-known array. |
| ... | @@ -37840,7 +38213,8 @@ fn maybeDerefSliceAsArray( | ... | @@ -37840,7 +38213,8 @@ fn maybeDerefSliceAsArray( |
| 37840 | src: LazySrcLoc, | 38213 | src: LazySrcLoc, |
| 37841 | slice_val: Value, | 38214 | slice_val: Value, |
| 37842 | ) CompileError!?Value { | 38215 | ) CompileError!?Value { |
| 37843 | const zcu = sema.mod; | 38216 | const pt = sema.pt; |
| 38217 | const zcu = pt.zcu; | ||
| 37844 | const ip = &zcu.intern_pool; | 38218 | const ip = &zcu.intern_pool; |
| 37845 | assert(slice_val.typeOf(zcu).isSlice(zcu)); | 38219 | assert(slice_val.typeOf(zcu).isSlice(zcu)); |
| 37846 | const slice = switch (ip.indexToKey(slice_val.toIntern())) { | 38220 | const slice = switch (ip.indexToKey(slice_val.toIntern())) { |
| ... | @@ -37849,19 +38223,19 @@ fn maybeDerefSliceAsArray( | ... | @@ -37849,19 +38223,19 @@ fn maybeDerefSliceAsArray( |
| 37849 | else => unreachable, | 38223 | else => unreachable, |
| 37850 | }; | 38224 | }; |
| 37851 | const elem_ty = Type.fromInterned(slice.ty).childType(zcu); | 38225 | const elem_ty = Type.fromInterned(slice.ty).childType(zcu); |
| 37852 | const len = try Value.fromInterned(slice.len).toUnsignedIntSema(zcu); | 38226 | const len = try Value.fromInterned(slice.len).toUnsignedIntSema(pt); |
| 37853 | const array_ty = try zcu.arrayType(.{ | 38227 | const array_ty = try pt.arrayType(.{ |
| 37854 | .child = elem_ty.toIntern(), | 38228 | .child = elem_ty.toIntern(), |
| 37855 | .len = len, | 38229 | .len = len, |
| 37856 | }); | 38230 | }); |
| 37857 | const ptr_ty = try zcu.ptrTypeSema(p: { | 38231 | const ptr_ty = try pt.ptrTypeSema(p: { |
| 37858 | var p = Type.fromInterned(slice.ty).ptrInfo(zcu); | 38232 | var p = Type.fromInterned(slice.ty).ptrInfo(zcu); |
| 37859 | p.flags.size = .One; | 38233 | p.flags.size = .One; |
| 37860 | p.child = array_ty.toIntern(); | 38234 | p.child = array_ty.toIntern(); |
| 37861 | p.sentinel = .none; | 38235 | p.sentinel = .none; |
| 37862 | break :p p; | 38236 | break :p p; |
| 37863 | }); | 38237 | }); |
| 37864 | const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty); | 38238 | const casted_ptr = try pt.getCoerced(Value.fromInterned(slice.ptr), ptr_ty); |
| 37865 | return sema.pointerDeref(block, src, casted_ptr, ptr_ty); | 38239 | return sema.pointerDeref(block, src, casted_ptr, ptr_ty); |
| 37866 | } | 38240 | } |
| 37867 | 38241 | ||
| ... | @@ -37879,7 +38253,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check: | ... | @@ -37879,7 +38253,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check: |
| 37879 | pub fn flushExports(sema: *Sema) !void { | 38253 | pub fn flushExports(sema: *Sema) !void { |
| 37880 | if (sema.exports.items.len == 0) return; | 38254 | if (sema.exports.items.len == 0) return; |
| 37881 | 38255 | ||
| 37882 | const zcu = sema.mod; | 38256 | const zcu = sema.pt.zcu; |
| 37883 | const gpa = zcu.gpa; | 38257 | const gpa = zcu.gpa; |
| 37884 | 38258 | ||
| 37885 | const unit = sema.ownerUnit(); | 38259 | const unit = sema.ownerUnit(); |
src/Sema/bitcast.zig+96-92| ... | @@ -69,7 +69,8 @@ fn bitCastInner( | ... | @@ -69,7 +69,8 @@ fn bitCastInner( |
| 69 | host_bits: u64, | 69 | host_bits: u64, |
| 70 | bit_offset: u64, | 70 | bit_offset: u64, |
| 71 | ) BitCastError!Value { | 71 | ) BitCastError!Value { |
| 72 | const zcu = sema.mod; | 72 | const pt = sema.pt; |
| 73 | const zcu = pt.zcu; | ||
| 73 | const endian = zcu.getTarget().cpu.arch.endian(); | 74 | const endian = zcu.getTarget().cpu.arch.endian(); |
| 74 | 75 | ||
| 75 | if (dest_ty.toIntern() == val.typeOf(zcu).toIntern() and bit_offset == 0) { | 76 | if (dest_ty.toIntern() == val.typeOf(zcu).toIntern() and bit_offset == 0) { |
| ... | @@ -78,29 +79,29 @@ fn bitCastInner( | ... | @@ -78,29 +79,29 @@ fn bitCastInner( |
| 78 | 79 | ||
| 79 | const val_ty = val.typeOf(zcu); | 80 | const val_ty = val.typeOf(zcu); |
| 80 | 81 | ||
| 81 | try val_ty.resolveLayout(zcu); | 82 | try val_ty.resolveLayout(pt); |
| 82 | try dest_ty.resolveLayout(zcu); | 83 | try dest_ty.resolveLayout(pt); |
| 83 | 84 | ||
| 84 | assert(val_ty.hasWellDefinedLayout(zcu)); | 85 | assert(val_ty.hasWellDefinedLayout(zcu)); |
| 85 | 86 | ||
| 86 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) | 87 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) |
| 87 | .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) } | 88 | .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) } |
| 88 | else | 89 | else |
| 89 | .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 }; | 90 | .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 }; |
| 90 | 91 | ||
| 91 | const skip_bits = switch (endian) { | 92 | const skip_bits = switch (endian) { |
| 92 | .little => bit_offset + byte_offset * 8, | 93 | .little => bit_offset + byte_offset * 8, |
| 93 | .big => if (host_bits > 0) | 94 | .big => if (host_bits > 0) |
| 94 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset | 95 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset |
| 95 | else | 96 | else |
| 96 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - dest_ty.bitSize(zcu), | 97 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - dest_ty.bitSize(pt), |
| 97 | }; | 98 | }; |
| 98 | 99 | ||
| 99 | var unpack: UnpackValueBits = .{ | 100 | var unpack: UnpackValueBits = .{ |
| 100 | .zcu = zcu, | 101 | .pt = sema.pt, |
| 101 | .arena = sema.arena, | 102 | .arena = sema.arena, |
| 102 | .skip_bits = skip_bits, | 103 | .skip_bits = skip_bits, |
| 103 | .remaining_bits = dest_ty.bitSize(zcu), | 104 | .remaining_bits = dest_ty.bitSize(pt), |
| 104 | .unpacked = std.ArrayList(InternPool.Index).init(sema.arena), | 105 | .unpacked = std.ArrayList(InternPool.Index).init(sema.arena), |
| 105 | }; | 106 | }; |
| 106 | switch (endian) { | 107 | switch (endian) { |
| ... | @@ -116,7 +117,7 @@ fn bitCastInner( | ... | @@ -116,7 +117,7 @@ fn bitCastInner( |
| 116 | try unpack.padding(host_pad_bits); | 117 | try unpack.padding(host_pad_bits); |
| 117 | 118 | ||
| 118 | var pack: PackValueBits = .{ | 119 | var pack: PackValueBits = .{ |
| 119 | .zcu = zcu, | 120 | .pt = sema.pt, |
| 120 | .arena = sema.arena, | 121 | .arena = sema.arena, |
| 121 | .unpacked = unpack.unpacked.items, | 122 | .unpacked = unpack.unpacked.items, |
| 122 | }; | 123 | }; |
| ... | @@ -131,33 +132,34 @@ fn bitCastSpliceInner( | ... | @@ -131,33 +132,34 @@ fn bitCastSpliceInner( |
| 131 | host_bits: u64, | 132 | host_bits: u64, |
| 132 | bit_offset: u64, | 133 | bit_offset: u64, |
| 133 | ) BitCastError!Value { | 134 | ) BitCastError!Value { |
| 134 | const zcu = sema.mod; | 135 | const pt = sema.pt; |
| 136 | const zcu = pt.zcu; | ||
| 135 | const endian = zcu.getTarget().cpu.arch.endian(); | 137 | const endian = zcu.getTarget().cpu.arch.endian(); |
| 136 | const val_ty = val.typeOf(zcu); | 138 | const val_ty = val.typeOf(zcu); |
| 137 | const splice_val_ty = splice_val.typeOf(zcu); | 139 | const splice_val_ty = splice_val.typeOf(zcu); |
| 138 | 140 | ||
| 139 | try val_ty.resolveLayout(zcu); | 141 | try val_ty.resolveLayout(pt); |
| 140 | try splice_val_ty.resolveLayout(zcu); | 142 | try splice_val_ty.resolveLayout(pt); |
| 141 | 143 | ||
| 142 | const splice_bits = splice_val_ty.bitSize(zcu); | 144 | const splice_bits = splice_val_ty.bitSize(pt); |
| 143 | 145 | ||
| 144 | const splice_offset = switch (endian) { | 146 | const splice_offset = switch (endian) { |
| 145 | .little => bit_offset + byte_offset * 8, | 147 | .little => bit_offset + byte_offset * 8, |
| 146 | .big => if (host_bits > 0) | 148 | .big => if (host_bits > 0) |
| 147 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset | 149 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset |
| 148 | else | 150 | else |
| 149 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - splice_bits, | 151 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - splice_bits, |
| 150 | }; | 152 | }; |
| 151 | 153 | ||
| 152 | assert(splice_offset + splice_bits <= val_ty.abiSize(zcu) * 8); | 154 | assert(splice_offset + splice_bits <= val_ty.abiSize(pt) * 8); |
| 153 | 155 | ||
| 154 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) | 156 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) |
| 155 | .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) } | 157 | .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) } |
| 156 | else | 158 | else |
| 157 | .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 }; | 159 | .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 }; |
| 158 | 160 | ||
| 159 | var unpack: UnpackValueBits = .{ | 161 | var unpack: UnpackValueBits = .{ |
| 160 | .zcu = zcu, | 162 | .pt = pt, |
| 161 | .arena = sema.arena, | 163 | .arena = sema.arena, |
| 162 | .skip_bits = 0, | 164 | .skip_bits = 0, |
| 163 | .remaining_bits = splice_offset, | 165 | .remaining_bits = splice_offset, |
| ... | @@ -179,7 +181,7 @@ fn bitCastSpliceInner( | ... | @@ -179,7 +181,7 @@ fn bitCastSpliceInner( |
| 179 | try unpack.add(splice_val); | 181 | try unpack.add(splice_val); |
| 180 | 182 | ||
| 181 | unpack.skip_bits = splice_offset + splice_bits; | 183 | unpack.skip_bits = splice_offset + splice_bits; |
| 182 | unpack.remaining_bits = val_ty.abiSize(zcu) * 8 - splice_offset - splice_bits; | 184 | unpack.remaining_bits = val_ty.abiSize(pt) * 8 - splice_offset - splice_bits; |
| 183 | switch (endian) { | 185 | switch (endian) { |
| 184 | .little => { | 186 | .little => { |
| 185 | try unpack.add(val); | 187 | try unpack.add(val); |
| ... | @@ -193,7 +195,7 @@ fn bitCastSpliceInner( | ... | @@ -193,7 +195,7 @@ fn bitCastSpliceInner( |
| 193 | try unpack.padding(host_pad_bits); | 195 | try unpack.padding(host_pad_bits); |
| 194 | 196 | ||
| 195 | var pack: PackValueBits = .{ | 197 | var pack: PackValueBits = .{ |
| 196 | .zcu = zcu, | 198 | .pt = pt, |
| 197 | .arena = sema.arena, | 199 | .arena = sema.arena, |
| 198 | .unpacked = unpack.unpacked.items, | 200 | .unpacked = unpack.unpacked.items, |
| 199 | }; | 201 | }; |
| ... | @@ -209,7 +211,7 @@ fn bitCastSpliceInner( | ... | @@ -209,7 +211,7 @@ fn bitCastSpliceInner( |
| 209 | /// of values in *packed* memory - therefore, on big-endian targets, the first element of this | 211 | /// of values in *packed* memory - therefore, on big-endian targets, the first element of this |
| 210 | /// list contains bits from the *final* byte of the value. | 212 | /// list contains bits from the *final* byte of the value. |
| 211 | const UnpackValueBits = struct { | 213 | const UnpackValueBits = struct { |
| 212 | zcu: *Zcu, | 214 | pt: Zcu.PerThread, |
| 213 | arena: Allocator, | 215 | arena: Allocator, |
| 214 | skip_bits: u64, | 216 | skip_bits: u64, |
| 215 | remaining_bits: u64, | 217 | remaining_bits: u64, |
| ... | @@ -217,7 +219,8 @@ const UnpackValueBits = struct { | ... | @@ -217,7 +219,8 @@ const UnpackValueBits = struct { |
| 217 | unpacked: std.ArrayList(InternPool.Index), | 219 | unpacked: std.ArrayList(InternPool.Index), |
| 218 | 220 | ||
| 219 | fn add(unpack: *UnpackValueBits, val: Value) BitCastError!void { | 221 | fn add(unpack: *UnpackValueBits, val: Value) BitCastError!void { |
| 220 | const zcu = unpack.zcu; | 222 | const pt = unpack.pt; |
| 223 | const zcu = pt.zcu; | ||
| 221 | const endian = zcu.getTarget().cpu.arch.endian(); | 224 | const endian = zcu.getTarget().cpu.arch.endian(); |
| 222 | const ip = &zcu.intern_pool; | 225 | const ip = &zcu.intern_pool; |
| 223 | 226 | ||
| ... | @@ -226,7 +229,7 @@ const UnpackValueBits = struct { | ... | @@ -226,7 +229,7 @@ const UnpackValueBits = struct { |
| 226 | } | 229 | } |
| 227 | 230 | ||
| 228 | const ty = val.typeOf(zcu); | 231 | const ty = val.typeOf(zcu); |
| 229 | const bit_size = ty.bitSize(zcu); | 232 | const bit_size = ty.bitSize(pt); |
| 230 | 233 | ||
| 231 | if (unpack.skip_bits >= bit_size) { | 234 | if (unpack.skip_bits >= bit_size) { |
| 232 | unpack.skip_bits -= bit_size; | 235 | unpack.skip_bits -= bit_size; |
| ... | @@ -279,7 +282,7 @@ const UnpackValueBits = struct { | ... | @@ -279,7 +282,7 @@ const UnpackValueBits = struct { |
| 279 | .little => i, | 282 | .little => i, |
| 280 | .big => len - i - 1, | 283 | .big => len - i - 1, |
| 281 | }; | 284 | }; |
| 282 | const elem_val = try val.elemValue(zcu, real_idx); | 285 | const elem_val = try val.elemValue(pt, real_idx); |
| 283 | try unpack.add(elem_val); | 286 | try unpack.add(elem_val); |
| 284 | } | 287 | } |
| 285 | }, | 288 | }, |
| ... | @@ -288,7 +291,7 @@ const UnpackValueBits = struct { | ... | @@ -288,7 +291,7 @@ const UnpackValueBits = struct { |
| 288 | // The final element does not have trailing padding. | 291 | // The final element does not have trailing padding. |
| 289 | // Elements are reversed in packed memory on BE targets. | 292 | // Elements are reversed in packed memory on BE targets. |
| 290 | const elem_ty = ty.childType(zcu); | 293 | const elem_ty = ty.childType(zcu); |
| 291 | const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu); | 294 | const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt); |
| 292 | const len = ty.arrayLen(zcu); | 295 | const len = ty.arrayLen(zcu); |
| 293 | const maybe_sent = ty.sentinel(zcu); | 296 | const maybe_sent = ty.sentinel(zcu); |
| 294 | 297 | ||
| ... | @@ -303,7 +306,7 @@ const UnpackValueBits = struct { | ... | @@ -303,7 +306,7 @@ const UnpackValueBits = struct { |
| 303 | .little => i, | 306 | .little => i, |
| 304 | .big => len - i - 1, | 307 | .big => len - i - 1, |
| 305 | }; | 308 | }; |
| 306 | const elem_val = try val.elemValue(zcu, @intCast(real_idx)); | 309 | const elem_val = try val.elemValue(pt, @intCast(real_idx)); |
| 307 | try unpack.add(elem_val); | 310 | try unpack.add(elem_val); |
| 308 | if (i != len - 1) try unpack.padding(pad_bits); | 311 | if (i != len - 1) try unpack.padding(pad_bits); |
| 309 | } | 312 | } |
| ... | @@ -320,12 +323,12 @@ const UnpackValueBits = struct { | ... | @@ -320,12 +323,12 @@ const UnpackValueBits = struct { |
| 320 | var cur_bit_off: u64 = 0; | 323 | var cur_bit_off: u64 = 0; |
| 321 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); | 324 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); |
| 322 | while (it.next()) |field_idx| { | 325 | while (it.next()) |field_idx| { |
| 323 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8; | 326 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8; |
| 324 | const pad_bits = want_bit_off - cur_bit_off; | 327 | const pad_bits = want_bit_off - cur_bit_off; |
| 325 | const field_val = try val.fieldValue(zcu, field_idx); | 328 | const field_val = try val.fieldValue(pt, field_idx); |
| 326 | try unpack.padding(pad_bits); | 329 | try unpack.padding(pad_bits); |
| 327 | try unpack.add(field_val); | 330 | try unpack.add(field_val); |
| 328 | cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(zcu); | 331 | cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(pt); |
| 329 | } | 332 | } |
| 330 | // Add trailing padding bits. | 333 | // Add trailing padding bits. |
| 331 | try unpack.padding(bit_size - cur_bit_off); | 334 | try unpack.padding(bit_size - cur_bit_off); |
| ... | @@ -334,13 +337,13 @@ const UnpackValueBits = struct { | ... | @@ -334,13 +337,13 @@ const UnpackValueBits = struct { |
| 334 | var cur_bit_off: u64 = bit_size; | 337 | var cur_bit_off: u64 = bit_size; |
| 335 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip); | 338 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip); |
| 336 | while (it.next()) |field_idx| { | 339 | while (it.next()) |field_idx| { |
| 337 | const field_val = try val.fieldValue(zcu, field_idx); | 340 | const field_val = try val.fieldValue(pt, field_idx); |
| 338 | const field_ty = field_val.typeOf(zcu); | 341 | const field_ty = field_val.typeOf(zcu); |
| 339 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu); | 342 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt); |
| 340 | const pad_bits = cur_bit_off - want_bit_off; | 343 | const pad_bits = cur_bit_off - want_bit_off; |
| 341 | try unpack.padding(pad_bits); | 344 | try unpack.padding(pad_bits); |
| 342 | try unpack.add(field_val); | 345 | try unpack.add(field_val); |
| 343 | cur_bit_off = want_bit_off - field_ty.bitSize(zcu); | 346 | cur_bit_off = want_bit_off - field_ty.bitSize(pt); |
| 344 | } | 347 | } |
| 345 | assert(cur_bit_off == 0); | 348 | assert(cur_bit_off == 0); |
| 346 | }, | 349 | }, |
| ... | @@ -349,7 +352,7 @@ const UnpackValueBits = struct { | ... | @@ -349,7 +352,7 @@ const UnpackValueBits = struct { |
| 349 | // Just add all fields in order. There are no padding bits. | 352 | // Just add all fields in order. There are no padding bits. |
| 350 | // This is identical between LE and BE targets. | 353 | // This is identical between LE and BE targets. |
| 351 | for (0..ty.structFieldCount(zcu)) |i| { | 354 | for (0..ty.structFieldCount(zcu)) |i| { |
| 352 | const field_val = try val.fieldValue(zcu, i); | 355 | const field_val = try val.fieldValue(pt, i); |
| 353 | try unpack.add(field_val); | 356 | try unpack.add(field_val); |
| 354 | } | 357 | } |
| 355 | }, | 358 | }, |
| ... | @@ -363,7 +366,7 @@ const UnpackValueBits = struct { | ... | @@ -363,7 +366,7 @@ const UnpackValueBits = struct { |
| 363 | // This correctly handles the case where `tag == .none`, since the payload is then | 366 | // This correctly handles the case where `tag == .none`, since the payload is then |
| 364 | // either an integer or a byte array, both of which we can unpack. | 367 | // either an integer or a byte array, both of which we can unpack. |
| 365 | const payload_val = Value.fromInterned(un.val); | 368 | const payload_val = Value.fromInterned(un.val); |
| 366 | const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(zcu); | 369 | const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(pt); |
| 367 | if (endian == .little or ty.containerLayout(zcu) == .@"packed") { | 370 | if (endian == .little or ty.containerLayout(zcu) == .@"packed") { |
| 368 | try unpack.add(payload_val); | 371 | try unpack.add(payload_val); |
| 369 | try unpack.padding(pad_bits); | 372 | try unpack.padding(pad_bits); |
| ... | @@ -377,31 +380,31 @@ const UnpackValueBits = struct { | ... | @@ -377,31 +380,31 @@ const UnpackValueBits = struct { |
| 377 | 380 | ||
| 378 | fn padding(unpack: *UnpackValueBits, pad_bits: u64) BitCastError!void { | 381 | fn padding(unpack: *UnpackValueBits, pad_bits: u64) BitCastError!void { |
| 379 | if (pad_bits == 0) return; | 382 | if (pad_bits == 0) return; |
| 380 | const zcu = unpack.zcu; | 383 | const pt = unpack.pt; |
| 381 | // Figure out how many full bytes and leftover bits there are. | 384 | // Figure out how many full bytes and leftover bits there are. |
| 382 | const bytes = pad_bits / 8; | 385 | const bytes = pad_bits / 8; |
| 383 | const bits = pad_bits % 8; | 386 | const bits = pad_bits % 8; |
| 384 | // Add undef u8 values for the bytes... | 387 | // Add undef u8 values for the bytes... |
| 385 | const undef_u8 = try zcu.undefValue(Type.u8); | 388 | const undef_u8 = try pt.undefValue(Type.u8); |
| 386 | for (0..@intCast(bytes)) |_| { | 389 | for (0..@intCast(bytes)) |_| { |
| 387 | try unpack.primitive(undef_u8); | 390 | try unpack.primitive(undef_u8); |
| 388 | } | 391 | } |
| 389 | // ...and an undef int for the leftover bits. | 392 | // ...and an undef int for the leftover bits. |
| 390 | if (bits == 0) return; | 393 | if (bits == 0) return; |
| 391 | const bits_ty = try zcu.intType(.unsigned, @intCast(bits)); | 394 | const bits_ty = try pt.intType(.unsigned, @intCast(bits)); |
| 392 | const bits_val = try zcu.undefValue(bits_ty); | 395 | const bits_val = try pt.undefValue(bits_ty); |
| 393 | try unpack.primitive(bits_val); | 396 | try unpack.primitive(bits_val); |
| 394 | } | 397 | } |
| 395 | 398 | ||
| 396 | fn primitive(unpack: *UnpackValueBits, val: Value) BitCastError!void { | 399 | fn primitive(unpack: *UnpackValueBits, val: Value) BitCastError!void { |
| 397 | const zcu = unpack.zcu; | 400 | const pt = unpack.pt; |
| 398 | 401 | ||
| 399 | if (unpack.remaining_bits == 0) { | 402 | if (unpack.remaining_bits == 0) { |
| 400 | return; | 403 | return; |
| 401 | } | 404 | } |
| 402 | 405 | ||
| 403 | const ty = val.typeOf(zcu); | 406 | const ty = val.typeOf(pt.zcu); |
| 404 | const bit_size = ty.bitSize(zcu); | 407 | const bit_size = ty.bitSize(pt); |
| 405 | 408 | ||
| 406 | // Note that this skips all zero-bit types. | 409 | // Note that this skips all zero-bit types. |
| 407 | if (unpack.skip_bits >= bit_size) { | 410 | if (unpack.skip_bits >= bit_size) { |
| ... | @@ -425,21 +428,21 @@ const UnpackValueBits = struct { | ... | @@ -425,21 +428,21 @@ const UnpackValueBits = struct { |
| 425 | } | 428 | } |
| 426 | 429 | ||
| 427 | fn splitPrimitive(unpack: *UnpackValueBits, val: Value, bit_offset: u64, bit_count: u64) BitCastError!void { | 430 | fn splitPrimitive(unpack: *UnpackValueBits, val: Value, bit_offset: u64, bit_count: u64) BitCastError!void { |
| 428 | const zcu = unpack.zcu; | 431 | const pt = unpack.pt; |
| 429 | const ty = val.typeOf(zcu); | 432 | const ty = val.typeOf(pt.zcu); |
| 430 | 433 | ||
| 431 | const val_bits = ty.bitSize(zcu); | 434 | const val_bits = ty.bitSize(pt); |
| 432 | assert(bit_offset + bit_count <= val_bits); | 435 | assert(bit_offset + bit_count <= val_bits); |
| 433 | 436 | ||
| 434 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 437 | switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 435 | // In the `ptr` case, this will return `error.ReinterpretDeclRef` | 438 | // In the `ptr` case, this will return `error.ReinterpretDeclRef` |
| 436 | // if we're trying to split a non-integer pointer value. | 439 | // if we're trying to split a non-integer pointer value. |
| 437 | .int, .float, .enum_tag, .ptr, .opt => { | 440 | .int, .float, .enum_tag, .ptr, .opt => { |
| 438 | // This @intCast is okay because no primitive can exceed the size of a u16. | 441 | // This @intCast is okay because no primitive can exceed the size of a u16. |
| 439 | const int_ty = try zcu.intType(.unsigned, @intCast(bit_count)); | 442 | const int_ty = try unpack.pt.intType(.unsigned, @intCast(bit_count)); |
| 440 | const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8)); | 443 | const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8)); |
| 441 | try val.writeToPackedMemory(ty, zcu, buf, 0); | 444 | try val.writeToPackedMemory(ty, unpack.pt, buf, 0); |
| 442 | const sub_val = try Value.readFromPackedMemory(int_ty, zcu, buf, @intCast(bit_offset), unpack.arena); | 445 | const sub_val = try Value.readFromPackedMemory(int_ty, unpack.pt, buf, @intCast(bit_offset), unpack.arena); |
| 443 | try unpack.primitive(sub_val); | 446 | try unpack.primitive(sub_val); |
| 444 | }, | 447 | }, |
| 445 | .undef => try unpack.padding(bit_count), | 448 | .undef => try unpack.padding(bit_count), |
| ... | @@ -456,13 +459,14 @@ const UnpackValueBits = struct { | ... | @@ -456,13 +459,14 @@ const UnpackValueBits = struct { |
| 456 | /// reconstructs a value of an arbitrary type, with correct handling of `undefined` | 459 | /// reconstructs a value of an arbitrary type, with correct handling of `undefined` |
| 457 | /// values and of pointers which align in virtual memory. | 460 | /// values and of pointers which align in virtual memory. |
| 458 | const PackValueBits = struct { | 461 | const PackValueBits = struct { |
| 459 | zcu: *Zcu, | 462 | pt: Zcu.PerThread, |
| 460 | arena: Allocator, | 463 | arena: Allocator, |
| 461 | bit_offset: u64 = 0, | 464 | bit_offset: u64 = 0, |
| 462 | unpacked: []const InternPool.Index, | 465 | unpacked: []const InternPool.Index, |
| 463 | 466 | ||
| 464 | fn get(pack: *PackValueBits, ty: Type) BitCastError!Value { | 467 | fn get(pack: *PackValueBits, ty: Type) BitCastError!Value { |
| 465 | const zcu = pack.zcu; | 468 | const pt = pack.pt; |
| 469 | const zcu = pt.zcu; | ||
| 466 | const endian = zcu.getTarget().cpu.arch.endian(); | 470 | const endian = zcu.getTarget().cpu.arch.endian(); |
| 467 | const ip = &zcu.intern_pool; | 471 | const ip = &zcu.intern_pool; |
| 468 | const arena = pack.arena; | 472 | const arena = pack.arena; |
| ... | @@ -485,7 +489,7 @@ const PackValueBits = struct { | ... | @@ -485,7 +489,7 @@ const PackValueBits = struct { |
| 485 | } | 489 | } |
| 486 | }, | 490 | }, |
| 487 | } | 491 | } |
| 488 | return Value.fromInterned(try zcu.intern(.{ .aggregate = .{ | 492 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 489 | .ty = ty.toIntern(), | 493 | .ty = ty.toIntern(), |
| 490 | .storage = .{ .elems = elems }, | 494 | .storage = .{ .elems = elems }, |
| 491 | } })); | 495 | } })); |
| ... | @@ -495,12 +499,12 @@ const PackValueBits = struct { | ... | @@ -495,12 +499,12 @@ const PackValueBits = struct { |
| 495 | const len = ty.arrayLen(zcu); | 499 | const len = ty.arrayLen(zcu); |
| 496 | const elem_ty = ty.childType(zcu); | 500 | const elem_ty = ty.childType(zcu); |
| 497 | const maybe_sent = ty.sentinel(zcu); | 501 | const maybe_sent = ty.sentinel(zcu); |
| 498 | const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu); | 502 | const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt); |
| 499 | const elems = try arena.alloc(InternPool.Index, @intCast(len)); | 503 | const elems = try arena.alloc(InternPool.Index, @intCast(len)); |
| 500 | 504 | ||
| 501 | if (endian == .big and maybe_sent != null) { | 505 | if (endian == .big and maybe_sent != null) { |
| 502 | // TODO: validate sentinel was preserved! | 506 | // TODO: validate sentinel was preserved! |
| 503 | try pack.padding(elem_ty.bitSize(zcu)); | 507 | try pack.padding(elem_ty.bitSize(pt)); |
| 504 | if (len != 0) try pack.padding(pad_bits); | 508 | if (len != 0) try pack.padding(pad_bits); |
| 505 | } | 509 | } |
| 506 | 510 | ||
| ... | @@ -516,10 +520,10 @@ const PackValueBits = struct { | ... | @@ -516,10 +520,10 @@ const PackValueBits = struct { |
| 516 | if (endian == .little and maybe_sent != null) { | 520 | if (endian == .little and maybe_sent != null) { |
| 517 | // TODO: validate sentinel was preserved! | 521 | // TODO: validate sentinel was preserved! |
| 518 | if (len != 0) try pack.padding(pad_bits); | 522 | if (len != 0) try pack.padding(pad_bits); |
| 519 | try pack.padding(elem_ty.bitSize(zcu)); | 523 | try pack.padding(elem_ty.bitSize(pt)); |
| 520 | } | 524 | } |
| 521 | 525 | ||
| 522 | return Value.fromInterned(try zcu.intern(.{ .aggregate = .{ | 526 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 523 | .ty = ty.toIntern(), | 527 | .ty = ty.toIntern(), |
| 524 | .storage = .{ .elems = elems }, | 528 | .storage = .{ .elems = elems }, |
| 525 | } })); | 529 | } })); |
| ... | @@ -534,23 +538,23 @@ const PackValueBits = struct { | ... | @@ -534,23 +538,23 @@ const PackValueBits = struct { |
| 534 | var cur_bit_off: u64 = 0; | 538 | var cur_bit_off: u64 = 0; |
| 535 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); | 539 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); |
| 536 | while (it.next()) |field_idx| { | 540 | while (it.next()) |field_idx| { |
| 537 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8; | 541 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8; |
| 538 | try pack.padding(want_bit_off - cur_bit_off); | 542 | try pack.padding(want_bit_off - cur_bit_off); |
| 539 | const field_ty = ty.structFieldType(field_idx, zcu); | 543 | const field_ty = ty.structFieldType(field_idx, zcu); |
| 540 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); | 544 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); |
| 541 | cur_bit_off = want_bit_off + field_ty.bitSize(zcu); | 545 | cur_bit_off = want_bit_off + field_ty.bitSize(pt); |
| 542 | } | 546 | } |
| 543 | try pack.padding(ty.bitSize(zcu) - cur_bit_off); | 547 | try pack.padding(ty.bitSize(pt) - cur_bit_off); |
| 544 | }, | 548 | }, |
| 545 | .big => { | 549 | .big => { |
| 546 | var cur_bit_off: u64 = ty.bitSize(zcu); | 550 | var cur_bit_off: u64 = ty.bitSize(pt); |
| 547 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip); | 551 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip); |
| 548 | while (it.next()) |field_idx| { | 552 | while (it.next()) |field_idx| { |
| 549 | const field_ty = ty.structFieldType(field_idx, zcu); | 553 | const field_ty = ty.structFieldType(field_idx, zcu); |
| 550 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu); | 554 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt); |
| 551 | try pack.padding(cur_bit_off - want_bit_off); | 555 | try pack.padding(cur_bit_off - want_bit_off); |
| 552 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); | 556 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); |
| 553 | cur_bit_off = want_bit_off - field_ty.bitSize(zcu); | 557 | cur_bit_off = want_bit_off - field_ty.bitSize(pt); |
| 554 | } | 558 | } |
| 555 | assert(cur_bit_off == 0); | 559 | assert(cur_bit_off == 0); |
| 556 | }, | 560 | }, |
| ... | @@ -559,10 +563,10 @@ const PackValueBits = struct { | ... | @@ -559,10 +563,10 @@ const PackValueBits = struct { |
| 559 | // Fill those values now. | 563 | // Fill those values now. |
| 560 | for (elems, 0..) |*elem, field_idx| { | 564 | for (elems, 0..) |*elem, field_idx| { |
| 561 | if (elem.* != .none) continue; | 565 | if (elem.* != .none) continue; |
| 562 | const val = (try ty.structFieldValueComptime(zcu, field_idx)).?; | 566 | const val = (try ty.structFieldValueComptime(pt, field_idx)).?; |
| 563 | elem.* = val.toIntern(); | 567 | elem.* = val.toIntern(); |
| 564 | } | 568 | } |
| 565 | return Value.fromInterned(try zcu.intern(.{ .aggregate = .{ | 569 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 566 | .ty = ty.toIntern(), | 570 | .ty = ty.toIntern(), |
| 567 | .storage = .{ .elems = elems }, | 571 | .storage = .{ .elems = elems }, |
| 568 | } })); | 572 | } })); |
| ... | @@ -575,7 +579,7 @@ const PackValueBits = struct { | ... | @@ -575,7 +579,7 @@ const PackValueBits = struct { |
| 575 | const field_ty = ty.structFieldType(i, zcu); | 579 | const field_ty = ty.structFieldType(i, zcu); |
| 576 | elem.* = (try pack.get(field_ty)).toIntern(); | 580 | elem.* = (try pack.get(field_ty)).toIntern(); |
| 577 | } | 581 | } |
| 578 | return Value.fromInterned(try zcu.intern(.{ .aggregate = .{ | 582 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 579 | .ty = ty.toIntern(), | 583 | .ty = ty.toIntern(), |
| 580 | .storage = .{ .elems = elems }, | 584 | .storage = .{ .elems = elems }, |
| 581 | } })); | 585 | } })); |
| ... | @@ -591,7 +595,7 @@ const PackValueBits = struct { | ... | @@ -591,7 +595,7 @@ const PackValueBits = struct { |
| 591 | const prev_unpacked = pack.unpacked; | 595 | const prev_unpacked = pack.unpacked; |
| 592 | const prev_bit_offset = pack.bit_offset; | 596 | const prev_bit_offset = pack.bit_offset; |
| 593 | 597 | ||
| 594 | const backing_ty = try ty.unionBackingType(zcu); | 598 | const backing_ty = try ty.unionBackingType(pt); |
| 595 | 599 | ||
| 596 | backing: { | 600 | backing: { |
| 597 | const backing_val = pack.get(backing_ty) catch |err| switch (err) { | 601 | const backing_val = pack.get(backing_ty) catch |err| switch (err) { |
| ... | @@ -607,7 +611,7 @@ const PackValueBits = struct { | ... | @@ -607,7 +611,7 @@ const PackValueBits = struct { |
| 607 | pack.bit_offset = prev_bit_offset; | 611 | pack.bit_offset = prev_bit_offset; |
| 608 | break :backing; | 612 | break :backing; |
| 609 | } | 613 | } |
| 610 | return Value.fromInterned(try zcu.intern(.{ .un = .{ | 614 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 611 | .ty = ty.toIntern(), | 615 | .ty = ty.toIntern(), |
| 612 | .tag = .none, | 616 | .tag = .none, |
| 613 | .val = backing_val.toIntern(), | 617 | .val = backing_val.toIntern(), |
| ... | @@ -618,16 +622,16 @@ const PackValueBits = struct { | ... | @@ -618,16 +622,16 @@ const PackValueBits = struct { |
| 618 | for (field_order, 0..) |*f, i| f.* = @intCast(i); | 622 | for (field_order, 0..) |*f, i| f.* = @intCast(i); |
| 619 | // Sort `field_order` to put the fields with the largest bit sizes first. | 623 | // Sort `field_order` to put the fields with the largest bit sizes first. |
| 620 | const SizeSortCtx = struct { | 624 | const SizeSortCtx = struct { |
| 621 | zcu: *Zcu, | 625 | pt: Zcu.PerThread, |
| 622 | field_types: []const InternPool.Index, | 626 | field_types: []const InternPool.Index, |
| 623 | fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool { | 627 | fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool { |
| 624 | const a_ty = Type.fromInterned(ctx.field_types[a_idx]); | 628 | const a_ty = Type.fromInterned(ctx.field_types[a_idx]); |
| 625 | const b_ty = Type.fromInterned(ctx.field_types[b_idx]); | 629 | const b_ty = Type.fromInterned(ctx.field_types[b_idx]); |
| 626 | return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu); | 630 | return a_ty.bitSize(ctx.pt) > b_ty.bitSize(ctx.pt); |
| 627 | } | 631 | } |
| 628 | }; | 632 | }; |
| 629 | std.mem.sortUnstable(u32, field_order, SizeSortCtx{ | 633 | std.mem.sortUnstable(u32, field_order, SizeSortCtx{ |
| 630 | .zcu = zcu, | 634 | .pt = pt, |
| 631 | .field_types = zcu.typeToUnion(ty).?.field_types.get(ip), | 635 | .field_types = zcu.typeToUnion(ty).?.field_types.get(ip), |
| 632 | }, SizeSortCtx.lessThan); | 636 | }, SizeSortCtx.lessThan); |
| 633 | 637 | ||
| ... | @@ -635,7 +639,7 @@ const PackValueBits = struct { | ... | @@ -635,7 +639,7 @@ const PackValueBits = struct { |
| 635 | 639 | ||
| 636 | for (field_order) |field_idx| { | 640 | for (field_order) |field_idx| { |
| 637 | const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]); | 641 | const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]); |
| 638 | const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu); | 642 | const pad_bits = ty.bitSize(pt) - field_ty.bitSize(pt); |
| 639 | if (!padding_after) try pack.padding(pad_bits); | 643 | if (!padding_after) try pack.padding(pad_bits); |
| 640 | const field_val = pack.get(field_ty) catch |err| switch (err) { | 644 | const field_val = pack.get(field_ty) catch |err| switch (err) { |
| 641 | error.ReinterpretDeclRef => { | 645 | error.ReinterpretDeclRef => { |
| ... | @@ -651,8 +655,8 @@ const PackValueBits = struct { | ... | @@ -651,8 +655,8 @@ const PackValueBits = struct { |
| 651 | pack.bit_offset = prev_bit_offset; | 655 | pack.bit_offset = prev_bit_offset; |
| 652 | continue; | 656 | continue; |
| 653 | } | 657 | } |
| 654 | const tag_val = try zcu.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx); | 658 | const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx); |
| 655 | return Value.fromInterned(try zcu.intern(.{ .un = .{ | 659 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 656 | .ty = ty.toIntern(), | 660 | .ty = ty.toIntern(), |
| 657 | .tag = tag_val.toIntern(), | 661 | .tag = tag_val.toIntern(), |
| 658 | .val = field_val.toIntern(), | 662 | .val = field_val.toIntern(), |
| ... | @@ -662,7 +666,7 @@ const PackValueBits = struct { | ... | @@ -662,7 +666,7 @@ const PackValueBits = struct { |
| 662 | // No field could represent the value. Just do whatever happens when we try to read | 666 | // No field could represent the value. Just do whatever happens when we try to read |
| 663 | // the backing type - either `undefined` or `error.ReinterpretDeclRef`. | 667 | // the backing type - either `undefined` or `error.ReinterpretDeclRef`. |
| 664 | const backing_val = try pack.get(backing_ty); | 668 | const backing_val = try pack.get(backing_ty); |
| 665 | return Value.fromInterned(try zcu.intern(.{ .un = .{ | 669 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 666 | .ty = ty.toIntern(), | 670 | .ty = ty.toIntern(), |
| 667 | .tag = .none, | 671 | .tag = .none, |
| 668 | .val = backing_val.toIntern(), | 672 | .val = backing_val.toIntern(), |
| ... | @@ -677,14 +681,14 @@ const PackValueBits = struct { | ... | @@ -677,14 +681,14 @@ const PackValueBits = struct { |
| 677 | } | 681 | } |
| 678 | 682 | ||
| 679 | fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value { | 683 | fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value { |
| 680 | const zcu = pack.zcu; | 684 | const pt = pack.pt; |
| 681 | const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu)); | 685 | const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(pt)); |
| 682 | 686 | ||
| 683 | for (vals) |val| { | 687 | for (vals) |val| { |
| 684 | if (!Value.fromInterned(val).isUndef(zcu)) break; | 688 | if (!Value.fromInterned(val).isUndef(pt.zcu)) break; |
| 685 | } else { | 689 | } else { |
| 686 | // All bits of the value are `undefined`. | 690 | // All bits of the value are `undefined`. |
| 687 | return zcu.undefValue(want_ty); | 691 | return pt.undefValue(want_ty); |
| 688 | } | 692 | } |
| 689 | 693 | ||
| 690 | // TODO: we need to decide how to handle partially-undef values here. | 694 | // TODO: we need to decide how to handle partially-undef values here. |
| ... | @@ -702,9 +706,9 @@ const PackValueBits = struct { | ... | @@ -702,9 +706,9 @@ const PackValueBits = struct { |
| 702 | ptr_cast: { | 706 | ptr_cast: { |
| 703 | if (vals.len != 1) break :ptr_cast; | 707 | if (vals.len != 1) break :ptr_cast; |
| 704 | const val = Value.fromInterned(vals[0]); | 708 | const val = Value.fromInterned(vals[0]); |
| 705 | if (!val.typeOf(zcu).isPtrAtRuntime(zcu)) break :ptr_cast; | 709 | if (!val.typeOf(pt.zcu).isPtrAtRuntime(pt.zcu)) break :ptr_cast; |
| 706 | if (!want_ty.isPtrAtRuntime(zcu)) break :ptr_cast; | 710 | if (!want_ty.isPtrAtRuntime(pt.zcu)) break :ptr_cast; |
| 707 | return zcu.getCoerced(val, want_ty); | 711 | return pt.getCoerced(val, want_ty); |
| 708 | } | 712 | } |
| 709 | 713 | ||
| 710 | // Reinterpret via an in-memory buffer. | 714 | // Reinterpret via an in-memory buffer. |
| ... | @@ -712,8 +716,8 @@ const PackValueBits = struct { | ... | @@ -712,8 +716,8 @@ const PackValueBits = struct { |
| 712 | var buf_bits: u64 = 0; | 716 | var buf_bits: u64 = 0; |
| 713 | for (vals) |ip_val| { | 717 | for (vals) |ip_val| { |
| 714 | const val = Value.fromInterned(ip_val); | 718 | const val = Value.fromInterned(ip_val); |
| 715 | const ty = val.typeOf(zcu); | 719 | const ty = val.typeOf(pt.zcu); |
| 716 | buf_bits += ty.bitSize(zcu); | 720 | buf_bits += ty.bitSize(pt); |
| 717 | } | 721 | } |
| 718 | 722 | ||
| 719 | const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8)); | 723 | const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8)); |
| ... | @@ -722,25 +726,25 @@ const PackValueBits = struct { | ... | @@ -722,25 +726,25 @@ const PackValueBits = struct { |
| 722 | var cur_bit_off: usize = 0; | 726 | var cur_bit_off: usize = 0; |
| 723 | for (vals) |ip_val| { | 727 | for (vals) |ip_val| { |
| 724 | const val = Value.fromInterned(ip_val); | 728 | const val = Value.fromInterned(ip_val); |
| 725 | const ty = val.typeOf(zcu); | 729 | const ty = val.typeOf(pt.zcu); |
| 726 | if (!val.isUndef(zcu)) { | 730 | if (!val.isUndef(pt.zcu)) { |
| 727 | try val.writeToPackedMemory(ty, zcu, buf, cur_bit_off); | 731 | try val.writeToPackedMemory(ty, pt, buf, cur_bit_off); |
| 728 | } | 732 | } |
| 729 | cur_bit_off += @intCast(ty.bitSize(zcu)); | 733 | cur_bit_off += @intCast(ty.bitSize(pt)); |
| 730 | } | 734 | } |
| 731 | 735 | ||
| 732 | return Value.readFromPackedMemory(want_ty, zcu, buf, @intCast(bit_offset), pack.arena); | 736 | return Value.readFromPackedMemory(want_ty, pt, buf, @intCast(bit_offset), pack.arena); |
| 733 | } | 737 | } |
| 734 | 738 | ||
| 735 | fn prepareBits(pack: *PackValueBits, need_bits: u64) struct { []const InternPool.Index, u64 } { | 739 | fn prepareBits(pack: *PackValueBits, need_bits: u64) struct { []const InternPool.Index, u64 } { |
| 736 | if (need_bits == 0) return .{ &.{}, 0 }; | 740 | if (need_bits == 0) return .{ &.{}, 0 }; |
| 737 | 741 | ||
| 738 | const zcu = pack.zcu; | 742 | const pt = pack.pt; |
| 739 | 743 | ||
| 740 | var bits: u64 = 0; | 744 | var bits: u64 = 0; |
| 741 | var len: usize = 0; | 745 | var len: usize = 0; |
| 742 | while (bits < pack.bit_offset + need_bits) { | 746 | while (bits < pack.bit_offset + need_bits) { |
| 743 | bits += Value.fromInterned(pack.unpacked[len]).typeOf(zcu).bitSize(zcu); | 747 | bits += Value.fromInterned(pack.unpacked[len]).typeOf(pt.zcu).bitSize(pt); |
| 744 | len += 1; | 748 | len += 1; |
| 745 | } | 749 | } |
| 746 | 750 | ||
| ... | @@ -753,7 +757,7 @@ const PackValueBits = struct { | ... | @@ -753,7 +757,7 @@ const PackValueBits = struct { |
| 753 | pack.bit_offset = 0; | 757 | pack.bit_offset = 0; |
| 754 | } else { | 758 | } else { |
| 755 | pack.unpacked = pack.unpacked[len - 1 ..]; | 759 | pack.unpacked = pack.unpacked[len - 1 ..]; |
| 756 | pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(zcu).bitSize(zcu) - extra_bits; | 760 | pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(pt.zcu).bitSize(pt) - extra_bits; |
| 757 | } | 761 | } |
| 758 | 762 | ||
| 759 | return .{ result_vals, result_offset }; | 763 | return .{ result_vals, result_offset }; |
src/Sema/comptime_ptr_access.zig+57-54| ... | @@ -12,19 +12,19 @@ pub const ComptimeLoadResult = union(enum) { | ... | @@ -12,19 +12,19 @@ pub const ComptimeLoadResult = union(enum) { |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | pub fn loadComptimePtr(sema: *Sema, block: *Block, src: LazySrcLoc, ptr: Value) !ComptimeLoadResult { | 14 | pub fn loadComptimePtr(sema: *Sema, block: *Block, src: LazySrcLoc, ptr: Value) !ComptimeLoadResult { |
| 15 | const zcu = sema.mod; | 15 | const pt = sema.pt; |
| 16 | const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu); | 16 | const ptr_info = ptr.typeOf(pt.zcu).ptrInfo(pt.zcu); |
| 17 | // TODO: host size for vectors is terrible | 17 | // TODO: host size for vectors is terrible |
| 18 | const host_bits = switch (ptr_info.flags.vector_index) { | 18 | const host_bits = switch (ptr_info.flags.vector_index) { |
| 19 | .none => ptr_info.packed_offset.host_size * 8, | 19 | .none => ptr_info.packed_offset.host_size * 8, |
| 20 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu), | 20 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt), |
| 21 | }; | 21 | }; |
| 22 | const bit_offset = if (host_bits != 0) bit_offset: { | 22 | const bit_offset = if (host_bits != 0) bit_offset: { |
| 23 | const child_bits = Type.fromInterned(ptr_info.child).bitSize(zcu); | 23 | const child_bits = Type.fromInterned(ptr_info.child).bitSize(pt); |
| 24 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { | 24 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 25 | .none => 0, | 25 | .none => 0, |
| 26 | .runtime => return .runtime_load, | 26 | .runtime => return .runtime_load, |
| 27 | else => |idx| switch (zcu.getTarget().cpu.arch.endian()) { | 27 | else => |idx| switch (pt.zcu.getTarget().cpu.arch.endian()) { |
| 28 | .little => child_bits * @intFromEnum(idx), | 28 | .little => child_bits * @intFromEnum(idx), |
| 29 | .big => host_bits - child_bits * (@intFromEnum(idx) + 1), // element order reversed on big endian | 29 | .big => host_bits - child_bits * (@intFromEnum(idx) + 1), // element order reversed on big endian |
| 30 | }, | 30 | }, |
| ... | @@ -60,28 +60,29 @@ pub fn storeComptimePtr( | ... | @@ -60,28 +60,29 @@ pub fn storeComptimePtr( |
| 60 | ptr: Value, | 60 | ptr: Value, |
| 61 | store_val: Value, | 61 | store_val: Value, |
| 62 | ) !ComptimeStoreResult { | 62 | ) !ComptimeStoreResult { |
| 63 | const zcu = sema.mod; | 63 | const pt = sema.pt; |
| 64 | const zcu = pt.zcu; | ||
| 64 | const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu); | 65 | const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu); |
| 65 | assert(store_val.typeOf(zcu).toIntern() == ptr_info.child); | 66 | assert(store_val.typeOf(zcu).toIntern() == ptr_info.child); |
| 66 | // TODO: host size for vectors is terrible | 67 | // TODO: host size for vectors is terrible |
| 67 | const host_bits = switch (ptr_info.flags.vector_index) { | 68 | const host_bits = switch (ptr_info.flags.vector_index) { |
| 68 | .none => ptr_info.packed_offset.host_size * 8, | 69 | .none => ptr_info.packed_offset.host_size * 8, |
| 69 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu), | 70 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt), |
| 70 | }; | 71 | }; |
| 71 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { | 72 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 72 | .none => 0, | 73 | .none => 0, |
| 73 | .runtime => return .runtime_store, | 74 | .runtime => return .runtime_store, |
| 74 | else => |idx| switch (zcu.getTarget().cpu.arch.endian()) { | 75 | else => |idx| switch (zcu.getTarget().cpu.arch.endian()) { |
| 75 | .little => Type.fromInterned(ptr_info.child).bitSize(zcu) * @intFromEnum(idx), | 76 | .little => Type.fromInterned(ptr_info.child).bitSize(pt) * @intFromEnum(idx), |
| 76 | .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(zcu) * (@intFromEnum(idx) + 1), // element order reversed on big endian | 77 | .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(pt) * (@intFromEnum(idx) + 1), // element order reversed on big endian |
| 77 | }, | 78 | }, |
| 78 | }; | 79 | }; |
| 79 | const pseudo_store_ty = if (host_bits > 0) t: { | 80 | const pseudo_store_ty = if (host_bits > 0) t: { |
| 80 | const need_bits = Type.fromInterned(ptr_info.child).bitSize(zcu); | 81 | const need_bits = Type.fromInterned(ptr_info.child).bitSize(pt); |
| 81 | if (need_bits + bit_offset > host_bits) { | 82 | if (need_bits + bit_offset > host_bits) { |
| 82 | return .exceeds_host_size; | 83 | return .exceeds_host_size; |
| 83 | } | 84 | } |
| 84 | break :t try zcu.intType(.unsigned, @intCast(host_bits)); | 85 | break :t try sema.pt.intType(.unsigned, @intCast(host_bits)); |
| 85 | } else Type.fromInterned(ptr_info.child); | 86 | } else Type.fromInterned(ptr_info.child); |
| 86 | 87 | ||
| 87 | const strat = try prepareComptimePtrStore(sema, block, src, ptr, pseudo_store_ty, 0); | 88 | const strat = try prepareComptimePtrStore(sema, block, src, ptr, pseudo_store_ty, 0); |
| ... | @@ -103,7 +104,7 @@ pub fn storeComptimePtr( | ... | @@ -103,7 +104,7 @@ pub fn storeComptimePtr( |
| 103 | .needed_well_defined => |ty| return .{ .needed_well_defined = ty }, | 104 | .needed_well_defined => |ty| return .{ .needed_well_defined = ty }, |
| 104 | .out_of_bounds => |ty| return .{ .out_of_bounds = ty }, | 105 | .out_of_bounds => |ty| return .{ .out_of_bounds = ty }, |
| 105 | }; | 106 | }; |
| 106 | const expected = try expected_mv.intern(zcu, sema.arena); | 107 | const expected = try expected_mv.intern(pt, sema.arena); |
| 107 | if (store_val.toIntern() != expected.toIntern()) { | 108 | if (store_val.toIntern() != expected.toIntern()) { |
| 108 | return .{ .comptime_field_mismatch = expected }; | 109 | return .{ .comptime_field_mismatch = expected }; |
| 109 | } | 110 | } |
| ... | @@ -126,14 +127,14 @@ pub fn storeComptimePtr( | ... | @@ -126,14 +127,14 @@ pub fn storeComptimePtr( |
| 126 | switch (strat) { | 127 | switch (strat) { |
| 127 | .direct => |direct| { | 128 | .direct => |direct| { |
| 128 | const want_ty = direct.val.typeOf(zcu); | 129 | const want_ty = direct.val.typeOf(zcu); |
| 129 | const coerced_store_val = try zcu.getCoerced(store_val, want_ty); | 130 | const coerced_store_val = try pt.getCoerced(store_val, want_ty); |
| 130 | direct.val.* = .{ .interned = coerced_store_val.toIntern() }; | 131 | direct.val.* = .{ .interned = coerced_store_val.toIntern() }; |
| 131 | return .success; | 132 | return .success; |
| 132 | }, | 133 | }, |
| 133 | .index => |index| { | 134 | .index => |index| { |
| 134 | const want_ty = index.val.typeOf(zcu).childType(zcu); | 135 | const want_ty = index.val.typeOf(zcu).childType(zcu); |
| 135 | const coerced_store_val = try zcu.getCoerced(store_val, want_ty); | 136 | const coerced_store_val = try pt.getCoerced(store_val, want_ty); |
| 136 | try index.val.setElem(zcu, sema.arena, @intCast(index.elem_index), .{ .interned = coerced_store_val.toIntern() }); | 137 | try index.val.setElem(pt, sema.arena, @intCast(index.elem_index), .{ .interned = coerced_store_val.toIntern() }); |
| 137 | return .success; | 138 | return .success; |
| 138 | }, | 139 | }, |
| 139 | .flat_index => |flat| { | 140 | .flat_index => |flat| { |
| ... | @@ -149,7 +150,7 @@ pub fn storeComptimePtr( | ... | @@ -149,7 +150,7 @@ pub fn storeComptimePtr( |
| 149 | // Better would be to gather all the store targets into an array. | 150 | // Better would be to gather all the store targets into an array. |
| 150 | var index: u64 = flat.flat_elem_index + idx; | 151 | var index: u64 = flat.flat_elem_index + idx; |
| 151 | const val_ptr, const final_idx = (try recursiveIndex(sema, flat.val, &index)).?; | 152 | const val_ptr, const final_idx = (try recursiveIndex(sema, flat.val, &index)).?; |
| 152 | try val_ptr.setElem(zcu, sema.arena, @intCast(final_idx), .{ .interned = elem }); | 153 | try val_ptr.setElem(pt, sema.arena, @intCast(final_idx), .{ .interned = elem }); |
| 153 | } | 154 | } |
| 154 | return .success; | 155 | return .success; |
| 155 | }, | 156 | }, |
| ... | @@ -165,9 +166,9 @@ pub fn storeComptimePtr( | ... | @@ -165,9 +166,9 @@ pub fn storeComptimePtr( |
| 165 | .direct => |direct| .{ direct.val, 0 }, | 166 | .direct => |direct| .{ direct.val, 0 }, |
| 166 | .index => |index| .{ | 167 | .index => |index| .{ |
| 167 | index.val, | 168 | index.val, |
| 168 | index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(zcu), | 169 | index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(pt), |
| 169 | }, | 170 | }, |
| 170 | .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(zcu) }, | 171 | .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(pt) }, |
| 171 | .reinterpret => |reinterpret| .{ reinterpret.val, reinterpret.byte_offset }, | 172 | .reinterpret => |reinterpret| .{ reinterpret.val, reinterpret.byte_offset }, |
| 172 | else => unreachable, | 173 | else => unreachable, |
| 173 | }; | 174 | }; |
| ... | @@ -181,7 +182,7 @@ pub fn storeComptimePtr( | ... | @@ -181,7 +182,7 @@ pub fn storeComptimePtr( |
| 181 | } | 182 | } |
| 182 | 183 | ||
| 183 | const new_val = try sema.bitCastSpliceVal( | 184 | const new_val = try sema.bitCastSpliceVal( |
| 184 | try val_ptr.intern(zcu, sema.arena), | 185 | try val_ptr.intern(pt, sema.arena), |
| 185 | store_val, | 186 | store_val, |
| 186 | byte_offset, | 187 | byte_offset, |
| 187 | host_bits, | 188 | host_bits, |
| ... | @@ -205,7 +206,8 @@ fn loadComptimePtrInner( | ... | @@ -205,7 +206,8 @@ fn loadComptimePtrInner( |
| 205 | /// before `load_ty`. Otherwise, it is ignored and may be `undefined`. | 206 | /// before `load_ty`. Otherwise, it is ignored and may be `undefined`. |
| 206 | array_offset: u64, | 207 | array_offset: u64, |
| 207 | ) !ComptimeLoadResult { | 208 | ) !ComptimeLoadResult { |
| 208 | const zcu = sema.mod; | 209 | const pt = sema.pt; |
| 210 | const zcu = pt.zcu; | ||
| 209 | const ip = &zcu.intern_pool; | 211 | const ip = &zcu.intern_pool; |
| 210 | 212 | ||
| 211 | const ptr = switch (ip.indexToKey(ptr_val.toIntern())) { | 213 | const ptr = switch (ip.indexToKey(ptr_val.toIntern())) { |
| ... | @@ -263,7 +265,7 @@ fn loadComptimePtrInner( | ... | @@ -263,7 +265,7 @@ fn loadComptimePtrInner( |
| 263 | const load_one_ty, const load_count = load_ty.arrayBase(zcu); | 265 | const load_one_ty, const load_count = load_ty.arrayBase(zcu); |
| 264 | const count = if (load_one_ty.toIntern() == base_ty.toIntern()) load_count else 1; | 266 | const count = if (load_one_ty.toIntern() == base_ty.toIntern()) load_count else 1; |
| 265 | 267 | ||
| 266 | const want_ty = try zcu.arrayType(.{ | 268 | const want_ty = try sema.pt.arrayType(.{ |
| 267 | .len = count, | 269 | .len = count, |
| 268 | .child = base_ty.toIntern(), | 270 | .child = base_ty.toIntern(), |
| 269 | }); | 271 | }); |
| ... | @@ -285,7 +287,7 @@ fn loadComptimePtrInner( | ... | @@ -285,7 +287,7 @@ fn loadComptimePtrInner( |
| 285 | 287 | ||
| 286 | const agg_ty = agg_val.typeOf(zcu); | 288 | const agg_ty = agg_val.typeOf(zcu); |
| 287 | switch (agg_ty.zigTypeTag(zcu)) { | 289 | switch (agg_ty.zigTypeTag(zcu)) { |
| 288 | .Struct, .Pointer => break :val try agg_val.getElem(zcu, @intCast(base_index.index)), | 290 | .Struct, .Pointer => break :val try agg_val.getElem(sema.pt, @intCast(base_index.index)), |
| 289 | .Union => { | 291 | .Union => { |
| 290 | const tag_val: Value, const payload_mv: MutableValue = switch (agg_val) { | 292 | const tag_val: Value, const payload_mv: MutableValue = switch (agg_val) { |
| 291 | .un => |un| .{ Value.fromInterned(un.tag), un.payload.* }, | 293 | .un => |un| .{ Value.fromInterned(un.tag), un.payload.* }, |
| ... | @@ -427,7 +429,7 @@ fn loadComptimePtrInner( | ... | @@ -427,7 +429,7 @@ fn loadComptimePtrInner( |
| 427 | const next_elem_off = elem_size * (elem_idx + 1); | 429 | const next_elem_off = elem_size * (elem_idx + 1); |
| 428 | if (cur_offset + need_bytes <= next_elem_off) { | 430 | if (cur_offset + need_bytes <= next_elem_off) { |
| 429 | // We can look at a single array element. | 431 | // We can look at a single array element. |
| 430 | cur_val = try cur_val.getElem(zcu, @intCast(elem_idx)); | 432 | cur_val = try cur_val.getElem(sema.pt, @intCast(elem_idx)); |
| 431 | cur_offset -= elem_idx * elem_size; | 433 | cur_offset -= elem_idx * elem_size; |
| 432 | } else { | 434 | } else { |
| 433 | break; | 435 | break; |
| ... | @@ -437,10 +439,10 @@ fn loadComptimePtrInner( | ... | @@ -437,10 +439,10 @@ fn loadComptimePtrInner( |
| 437 | .auto => unreachable, // ill-defined layout | 439 | .auto => unreachable, // ill-defined layout |
| 438 | .@"packed" => break, // let the bitcast logic handle this | 440 | .@"packed" => break, // let the bitcast logic handle this |
| 439 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { | 441 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 440 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | 442 | const start_off = cur_ty.structFieldOffset(field_idx, pt); |
| 441 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); | 443 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); |
| 442 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { | 444 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 443 | cur_val = try cur_val.getElem(zcu, field_idx); | 445 | cur_val = try cur_val.getElem(sema.pt, field_idx); |
| 444 | cur_offset -= start_off; | 446 | cur_offset -= start_off; |
| 445 | break; | 447 | break; |
| 446 | } | 448 | } |
| ... | @@ -482,7 +484,7 @@ fn loadComptimePtrInner( | ... | @@ -482,7 +484,7 @@ fn loadComptimePtrInner( |
| 482 | } | 484 | } |
| 483 | 485 | ||
| 484 | const result_val = try sema.bitCastVal( | 486 | const result_val = try sema.bitCastVal( |
| 485 | try cur_val.intern(zcu, sema.arena), | 487 | try cur_val.intern(sema.pt, sema.arena), |
| 486 | load_ty, | 488 | load_ty, |
| 487 | cur_offset, | 489 | cur_offset, |
| 488 | host_bits, | 490 | host_bits, |
| ... | @@ -564,7 +566,8 @@ fn prepareComptimePtrStore( | ... | @@ -564,7 +566,8 @@ fn prepareComptimePtrStore( |
| 564 | /// before `store_ty`. Otherwise, it is ignored and may be `undefined`. | 566 | /// before `store_ty`. Otherwise, it is ignored and may be `undefined`. |
| 565 | array_offset: u64, | 567 | array_offset: u64, |
| 566 | ) !ComptimeStoreStrategy { | 568 | ) !ComptimeStoreStrategy { |
| 567 | const zcu = sema.mod; | 569 | const pt = sema.pt; |
| 570 | const zcu = pt.zcu; | ||
| 568 | const ip = &zcu.intern_pool; | 571 | const ip = &zcu.intern_pool; |
| 569 | 572 | ||
| 570 | const ptr = switch (ip.indexToKey(ptr_val.toIntern())) { | 573 | const ptr = switch (ip.indexToKey(ptr_val.toIntern())) { |
| ... | @@ -587,14 +590,14 @@ fn prepareComptimePtrStore( | ... | @@ -587,14 +590,14 @@ fn prepareComptimePtrStore( |
| 587 | const eu_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { | 590 | const eu_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { |
| 588 | .direct => |direct| .{ direct.val, direct.alloc }, | 591 | .direct => |direct| .{ direct.val, direct.alloc }, |
| 589 | .index => |index| .{ | 592 | .index => |index| .{ |
| 590 | try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)), | 593 | try index.val.elem(pt, sema.arena, @intCast(index.elem_index)), |
| 591 | index.alloc, | 594 | index.alloc, |
| 592 | }, | 595 | }, |
| 593 | .flat_index => unreachable, // base_ty is not an array | 596 | .flat_index => unreachable, // base_ty is not an array |
| 594 | .reinterpret => unreachable, // base_ty has ill-defined layout | 597 | .reinterpret => unreachable, // base_ty has ill-defined layout |
| 595 | else => |err| return err, | 598 | else => |err| return err, |
| 596 | }; | 599 | }; |
| 597 | try eu_val_ptr.unintern(zcu, sema.arena, false, false); | 600 | try eu_val_ptr.unintern(pt, sema.arena, false, false); |
| 598 | switch (eu_val_ptr.*) { | 601 | switch (eu_val_ptr.*) { |
| 599 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { | 602 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { |
| 600 | .undef => return .undef, | 603 | .undef => return .undef, |
| ... | @@ -614,14 +617,14 @@ fn prepareComptimePtrStore( | ... | @@ -614,14 +617,14 @@ fn prepareComptimePtrStore( |
| 614 | const opt_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { | 617 | const opt_val_ptr, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { |
| 615 | .direct => |direct| .{ direct.val, direct.alloc }, | 618 | .direct => |direct| .{ direct.val, direct.alloc }, |
| 616 | .index => |index| .{ | 619 | .index => |index| .{ |
| 617 | try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)), | 620 | try index.val.elem(pt, sema.arena, @intCast(index.elem_index)), |
| 618 | index.alloc, | 621 | index.alloc, |
| 619 | }, | 622 | }, |
| 620 | .flat_index => unreachable, // base_ty is not an array | 623 | .flat_index => unreachable, // base_ty is not an array |
| 621 | .reinterpret => unreachable, // base_ty has ill-defined layout | 624 | .reinterpret => unreachable, // base_ty has ill-defined layout |
| 622 | else => |err| return err, | 625 | else => |err| return err, |
| 623 | }; | 626 | }; |
| 624 | try opt_val_ptr.unintern(zcu, sema.arena, false, false); | 627 | try opt_val_ptr.unintern(pt, sema.arena, false, false); |
| 625 | switch (opt_val_ptr.*) { | 628 | switch (opt_val_ptr.*) { |
| 626 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { | 629 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { |
| 627 | .undef => return .undef, | 630 | .undef => return .undef, |
| ... | @@ -648,7 +651,7 @@ fn prepareComptimePtrStore( | ... | @@ -648,7 +651,7 @@ fn prepareComptimePtrStore( |
| 648 | const store_one_ty, const store_count = store_ty.arrayBase(zcu); | 651 | const store_one_ty, const store_count = store_ty.arrayBase(zcu); |
| 649 | const count = if (store_one_ty.toIntern() == base_ty.toIntern()) store_count else 1; | 652 | const count = if (store_one_ty.toIntern() == base_ty.toIntern()) store_count else 1; |
| 650 | 653 | ||
| 651 | const want_ty = try zcu.arrayType(.{ | 654 | const want_ty = try pt.arrayType(.{ |
| 652 | .len = count, | 655 | .len = count, |
| 653 | .child = base_ty.toIntern(), | 656 | .child = base_ty.toIntern(), |
| 654 | }); | 657 | }); |
| ... | @@ -668,7 +671,7 @@ fn prepareComptimePtrStore( | ... | @@ -668,7 +671,7 @@ fn prepareComptimePtrStore( |
| 668 | const agg_val, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { | 671 | const agg_val, const alloc = switch (try prepareComptimePtrStore(sema, block, src, base_ptr, base_ty, undefined)) { |
| 669 | .direct => |direct| .{ direct.val, direct.alloc }, | 672 | .direct => |direct| .{ direct.val, direct.alloc }, |
| 670 | .index => |index| .{ | 673 | .index => |index| .{ |
| 671 | try index.val.elem(zcu, sema.arena, @intCast(index.elem_index)), | 674 | try index.val.elem(pt, sema.arena, @intCast(index.elem_index)), |
| 672 | index.alloc, | 675 | index.alloc, |
| 673 | }, | 676 | }, |
| 674 | .flat_index => unreachable, // base_ty is not an array | 677 | .flat_index => unreachable, // base_ty is not an array |
| ... | @@ -679,14 +682,14 @@ fn prepareComptimePtrStore( | ... | @@ -679,14 +682,14 @@ fn prepareComptimePtrStore( |
| 679 | const agg_ty = agg_val.typeOf(zcu); | 682 | const agg_ty = agg_val.typeOf(zcu); |
| 680 | switch (agg_ty.zigTypeTag(zcu)) { | 683 | switch (agg_ty.zigTypeTag(zcu)) { |
| 681 | .Struct, .Pointer => break :strat .{ .direct = .{ | 684 | .Struct, .Pointer => break :strat .{ .direct = .{ |
| 682 | .val = try agg_val.elem(zcu, sema.arena, @intCast(base_index.index)), | 685 | .val = try agg_val.elem(pt, sema.arena, @intCast(base_index.index)), |
| 683 | .alloc = alloc, | 686 | .alloc = alloc, |
| 684 | } }, | 687 | } }, |
| 685 | .Union => { | 688 | .Union => { |
| 686 | if (agg_val.* == .interned and Value.fromInterned(agg_val.interned).isUndef(zcu)) { | 689 | if (agg_val.* == .interned and Value.fromInterned(agg_val.interned).isUndef(zcu)) { |
| 687 | return .undef; | 690 | return .undef; |
| 688 | } | 691 | } |
| 689 | try agg_val.unintern(zcu, sema.arena, false, false); | 692 | try agg_val.unintern(pt, sema.arena, false, false); |
| 690 | const un = agg_val.un; | 693 | const un = agg_val.un; |
| 691 | const tag_ty = agg_ty.unionTagTypeHypothetical(zcu); | 694 | const tag_ty = agg_ty.unionTagTypeHypothetical(zcu); |
| 692 | if (tag_ty.enumTagFieldIndex(Value.fromInterned(un.tag), zcu).? != base_index.index) { | 695 | if (tag_ty.enumTagFieldIndex(Value.fromInterned(un.tag), zcu).? != base_index.index) { |
| ... | @@ -847,7 +850,7 @@ fn prepareComptimePtrStore( | ... | @@ -847,7 +850,7 @@ fn prepareComptimePtrStore( |
| 847 | const next_elem_off = elem_size * (elem_idx + 1); | 850 | const next_elem_off = elem_size * (elem_idx + 1); |
| 848 | if (cur_offset + need_bytes <= next_elem_off) { | 851 | if (cur_offset + need_bytes <= next_elem_off) { |
| 849 | // We can look at a single array element. | 852 | // We can look at a single array element. |
| 850 | cur_val = try cur_val.elem(zcu, sema.arena, @intCast(elem_idx)); | 853 | cur_val = try cur_val.elem(pt, sema.arena, @intCast(elem_idx)); |
| 851 | cur_offset -= elem_idx * elem_size; | 854 | cur_offset -= elem_idx * elem_size; |
| 852 | } else { | 855 | } else { |
| 853 | break; | 856 | break; |
| ... | @@ -857,10 +860,10 @@ fn prepareComptimePtrStore( | ... | @@ -857,10 +860,10 @@ fn prepareComptimePtrStore( |
| 857 | .auto => unreachable, // ill-defined layout | 860 | .auto => unreachable, // ill-defined layout |
| 858 | .@"packed" => break, // let the bitcast logic handle this | 861 | .@"packed" => break, // let the bitcast logic handle this |
| 859 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { | 862 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 860 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | 863 | const start_off = cur_ty.structFieldOffset(field_idx, pt); |
| 861 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); | 864 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); |
| 862 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { | 865 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 863 | cur_val = try cur_val.elem(zcu, sema.arena, field_idx); | 866 | cur_val = try cur_val.elem(pt, sema.arena, field_idx); |
| 864 | cur_offset -= start_off; | 867 | cur_offset -= start_off; |
| 865 | break; | 868 | break; |
| 866 | } | 869 | } |
| ... | @@ -874,7 +877,7 @@ fn prepareComptimePtrStore( | ... | @@ -874,7 +877,7 @@ fn prepareComptimePtrStore( |
| 874 | // Otherwise, we might traverse into a union field which doesn't allow pointers. | 877 | // Otherwise, we might traverse into a union field which doesn't allow pointers. |
| 875 | // Figure out a solution! | 878 | // Figure out a solution! |
| 876 | if (true) break; | 879 | if (true) break; |
| 877 | try cur_val.unintern(zcu, sema.arena, false, false); | 880 | try cur_val.unintern(pt, sema.arena, false, false); |
| 878 | const payload = switch (cur_val.*) { | 881 | const payload = switch (cur_val.*) { |
| 879 | .un => |un| un.payload, | 882 | .un => |un| un.payload, |
| 880 | else => unreachable, | 883 | else => unreachable, |
| ... | @@ -918,7 +921,7 @@ fn flattenArray( | ... | @@ -918,7 +921,7 @@ fn flattenArray( |
| 918 | ) Allocator.Error!void { | 921 | ) Allocator.Error!void { |
| 919 | if (next_idx.* == out.len) return; | 922 | if (next_idx.* == out.len) return; |
| 920 | 923 | ||
| 921 | const zcu = sema.mod; | 924 | const zcu = sema.pt.zcu; |
| 922 | 925 | ||
| 923 | const ty = val.typeOf(zcu); | 926 | const ty = val.typeOf(zcu); |
| 924 | const base_elem_count = ty.arrayBase(zcu)[1]; | 927 | const base_elem_count = ty.arrayBase(zcu)[1]; |
| ... | @@ -928,7 +931,7 @@ fn flattenArray( | ... | @@ -928,7 +931,7 @@ fn flattenArray( |
| 928 | } | 931 | } |
| 929 | 932 | ||
| 930 | if (ty.zigTypeTag(zcu) != .Array) { | 933 | if (ty.zigTypeTag(zcu) != .Array) { |
| 931 | out[@intCast(next_idx.*)] = (try val.intern(zcu, sema.arena)).toIntern(); | 934 | out[@intCast(next_idx.*)] = (try val.intern(sema.pt, sema.arena)).toIntern(); |
| 932 | next_idx.* += 1; | 935 | next_idx.* += 1; |
| 933 | return; | 936 | return; |
| 934 | } | 937 | } |
| ... | @@ -942,7 +945,7 @@ fn flattenArray( | ... | @@ -942,7 +945,7 @@ fn flattenArray( |
| 942 | skip.* -= arr_base_elem_count; | 945 | skip.* -= arr_base_elem_count; |
| 943 | continue; | 946 | continue; |
| 944 | } | 947 | } |
| 945 | try flattenArray(sema, try val.getElem(zcu, elem_idx), skip, next_idx, out); | 948 | try flattenArray(sema, try val.getElem(sema.pt, elem_idx), skip, next_idx, out); |
| 946 | } | 949 | } |
| 947 | if (ty.sentinel(zcu)) |s| { | 950 | if (ty.sentinel(zcu)) |s| { |
| 948 | try flattenArray(sema, .{ .interned = s.toIntern() }, skip, next_idx, out); | 951 | try flattenArray(sema, .{ .interned = s.toIntern() }, skip, next_idx, out); |
| ... | @@ -957,13 +960,13 @@ fn unflattenArray( | ... | @@ -957,13 +960,13 @@ fn unflattenArray( |
| 957 | elems: []const InternPool.Index, | 960 | elems: []const InternPool.Index, |
| 958 | next_idx: *u64, | 961 | next_idx: *u64, |
| 959 | ) Allocator.Error!Value { | 962 | ) Allocator.Error!Value { |
| 960 | const zcu = sema.mod; | 963 | const zcu = sema.pt.zcu; |
| 961 | const arena = sema.arena; | 964 | const arena = sema.arena; |
| 962 | 965 | ||
| 963 | if (ty.zigTypeTag(zcu) != .Array) { | 966 | if (ty.zigTypeTag(zcu) != .Array) { |
| 964 | const val = Value.fromInterned(elems[@intCast(next_idx.*)]); | 967 | const val = Value.fromInterned(elems[@intCast(next_idx.*)]); |
| 965 | next_idx.* += 1; | 968 | next_idx.* += 1; |
| 966 | return zcu.getCoerced(val, ty); | 969 | return sema.pt.getCoerced(val, ty); |
| 967 | } | 970 | } |
| 968 | 971 | ||
| 969 | const elem_ty = ty.childType(zcu); | 972 | const elem_ty = ty.childType(zcu); |
| ... | @@ -975,7 +978,7 @@ fn unflattenArray( | ... | @@ -975,7 +978,7 @@ fn unflattenArray( |
| 975 | // TODO: validate sentinel | 978 | // TODO: validate sentinel |
| 976 | _ = try unflattenArray(sema, elem_ty, elems, next_idx); | 979 | _ = try unflattenArray(sema, elem_ty, elems, next_idx); |
| 977 | } | 980 | } |
| 978 | return Value.fromInterned(try zcu.intern(.{ .aggregate = .{ | 981 | return Value.fromInterned(try sema.pt.intern(.{ .aggregate = .{ |
| 979 | .ty = ty.toIntern(), | 982 | .ty = ty.toIntern(), |
| 980 | .storage = .{ .elems = buf }, | 983 | .storage = .{ .elems = buf }, |
| 981 | } })); | 984 | } })); |
| ... | @@ -990,25 +993,25 @@ fn recursiveIndex( | ... | @@ -990,25 +993,25 @@ fn recursiveIndex( |
| 990 | mv: *MutableValue, | 993 | mv: *MutableValue, |
| 991 | index: *u64, | 994 | index: *u64, |
| 992 | ) !?struct { *MutableValue, u64 } { | 995 | ) !?struct { *MutableValue, u64 } { |
| 993 | const zcu = sema.mod; | 996 | const pt = sema.pt; |
| 994 | 997 | ||
| 995 | const ty = mv.typeOf(zcu); | 998 | const ty = mv.typeOf(pt.zcu); |
| 996 | assert(ty.zigTypeTag(zcu) == .Array); | 999 | assert(ty.zigTypeTag(pt.zcu) == .Array); |
| 997 | 1000 | ||
| 998 | const ty_base_elems = ty.arrayBase(zcu)[1]; | 1001 | const ty_base_elems = ty.arrayBase(pt.zcu)[1]; |
| 999 | if (index.* >= ty_base_elems) { | 1002 | if (index.* >= ty_base_elems) { |
| 1000 | index.* -= ty_base_elems; | 1003 | index.* -= ty_base_elems; |
| 1001 | return null; | 1004 | return null; |
| 1002 | } | 1005 | } |
| 1003 | 1006 | ||
| 1004 | const elem_ty = ty.childType(zcu); | 1007 | const elem_ty = ty.childType(pt.zcu); |
| 1005 | if (elem_ty.zigTypeTag(zcu) != .Array) { | 1008 | if (elem_ty.zigTypeTag(pt.zcu) != .Array) { |
| 1006 | assert(index.* < ty.arrayLenIncludingSentinel(zcu)); // should be handled by initial check | 1009 | assert(index.* < ty.arrayLenIncludingSentinel(pt.zcu)); // should be handled by initial check |
| 1007 | return .{ mv, index.* }; | 1010 | return .{ mv, index.* }; |
| 1008 | } | 1011 | } |
| 1009 | 1012 | ||
| 1010 | for (0..@intCast(ty.arrayLenIncludingSentinel(zcu))) |elem_index| { | 1013 | for (0..@intCast(ty.arrayLenIncludingSentinel(pt.zcu))) |elem_index| { |
| 1011 | if (try recursiveIndex(sema, try mv.elem(zcu, sema.arena, elem_index), index)) |result| { | 1014 | if (try recursiveIndex(sema, try mv.elem(pt, sema.arena, elem_index), index)) |result| { |
| 1012 | return result; | 1015 | return result; |
| 1013 | } | 1016 | } |
| 1014 | } | 1017 | } |
src/Type.zig+376-361| ... | @@ -136,16 +136,16 @@ pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt | ... | @@ -136,16 +136,16 @@ pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt |
| 136 | 136 | ||
| 137 | pub const Formatter = std.fmt.Formatter(format2); | 137 | pub const Formatter = std.fmt.Formatter(format2); |
| 138 | 138 | ||
| 139 | pub fn fmt(ty: Type, module: *Module) Formatter { | 139 | pub fn fmt(ty: Type, pt: Zcu.PerThread) Formatter { |
| 140 | return .{ .data = .{ | 140 | return .{ .data = .{ |
| 141 | .ty = ty, | 141 | .ty = ty, |
| 142 | .module = module, | 142 | .pt = pt, |
| 143 | } }; | 143 | } }; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | const FormatContext = struct { | 146 | const FormatContext = struct { |
| 147 | ty: Type, | 147 | ty: Type, |
| 148 | module: *Module, | 148 | pt: Zcu.PerThread, |
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | fn format2( | 151 | fn format2( |
| ... | @@ -156,7 +156,7 @@ fn format2( | ... | @@ -156,7 +156,7 @@ fn format2( |
| 156 | ) !void { | 156 | ) !void { |
| 157 | comptime assert(unused_format_string.len == 0); | 157 | comptime assert(unused_format_string.len == 0); |
| 158 | _ = options; | 158 | _ = options; |
| 159 | return print(ctx.ty, writer, ctx.module); | 159 | return print(ctx.ty, writer, ctx.pt); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) { | 162 | pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) { |
| ... | @@ -178,7 +178,8 @@ pub fn dump( | ... | @@ -178,7 +178,8 @@ pub fn dump( |
| 178 | 178 | ||
| 179 | /// Prints a name suitable for `@typeName`. | 179 | /// Prints a name suitable for `@typeName`. |
| 180 | /// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels. | 180 | /// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels. |
| 181 | pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void { | 181 | pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error!void { |
| 182 | const mod = pt.zcu; | ||
| 182 | const ip = &mod.intern_pool; | 183 | const ip = &mod.intern_pool; |
| 183 | switch (ip.indexToKey(ty.toIntern())) { | 184 | switch (ip.indexToKey(ty.toIntern())) { |
| 184 | .int_type => |int_type| { | 185 | .int_type => |int_type| { |
| ... | @@ -193,8 +194,8 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -193,8 +194,8 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 193 | 194 | ||
| 194 | if (info.sentinel != .none) switch (info.flags.size) { | 195 | if (info.sentinel != .none) switch (info.flags.size) { |
| 195 | .One, .C => unreachable, | 196 | .One, .C => unreachable, |
| 196 | .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod, null)}), | 197 | .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}), |
| 197 | .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod, null)}), | 198 | .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt, null)}), |
| 198 | } else switch (info.flags.size) { | 199 | } else switch (info.flags.size) { |
| 199 | .One => try writer.writeAll("*"), | 200 | .One => try writer.writeAll("*"), |
| 200 | .Many => try writer.writeAll("[*]"), | 201 | .Many => try writer.writeAll("[*]"), |
| ... | @@ -208,7 +209,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -208,7 +209,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 208 | const alignment = if (info.flags.alignment != .none) | 209 | const alignment = if (info.flags.alignment != .none) |
| 209 | info.flags.alignment | 210 | info.flags.alignment |
| 210 | else | 211 | else |
| 211 | Type.fromInterned(info.child).abiAlignment(mod); | 212 | Type.fromInterned(info.child).abiAlignment(pt); |
| 212 | try writer.print("align({d}", .{alignment.toByteUnits() orelse 0}); | 213 | try writer.print("align({d}", .{alignment.toByteUnits() orelse 0}); |
| 213 | 214 | ||
| 214 | if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) { | 215 | if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) { |
| ... | @@ -230,39 +231,39 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -230,39 +231,39 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 230 | if (info.flags.is_volatile) try writer.writeAll("volatile "); | 231 | if (info.flags.is_volatile) try writer.writeAll("volatile "); |
| 231 | if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero "); | 232 | if (info.flags.is_allowzero and info.flags.size != .C) try writer.writeAll("allowzero "); |
| 232 | 233 | ||
| 233 | try print(Type.fromInterned(info.child), writer, mod); | 234 | try print(Type.fromInterned(info.child), writer, pt); |
| 234 | return; | 235 | return; |
| 235 | }, | 236 | }, |
| 236 | .array_type => |array_type| { | 237 | .array_type => |array_type| { |
| 237 | if (array_type.sentinel == .none) { | 238 | if (array_type.sentinel == .none) { |
| 238 | try writer.print("[{d}]", .{array_type.len}); | 239 | try writer.print("[{d}]", .{array_type.len}); |
| 239 | try print(Type.fromInterned(array_type.child), writer, mod); | 240 | try print(Type.fromInterned(array_type.child), writer, pt); |
| 240 | } else { | 241 | } else { |
| 241 | try writer.print("[{d}:{}]", .{ | 242 | try writer.print("[{d}:{}]", .{ |
| 242 | array_type.len, | 243 | array_type.len, |
| 243 | Value.fromInterned(array_type.sentinel).fmtValue(mod, null), | 244 | Value.fromInterned(array_type.sentinel).fmtValue(pt, null), |
| 244 | }); | 245 | }); |
| 245 | try print(Type.fromInterned(array_type.child), writer, mod); | 246 | try print(Type.fromInterned(array_type.child), writer, pt); |
| 246 | } | 247 | } |
| 247 | return; | 248 | return; |
| 248 | }, | 249 | }, |
| 249 | .vector_type => |vector_type| { | 250 | .vector_type => |vector_type| { |
| 250 | try writer.print("@Vector({d}, ", .{vector_type.len}); | 251 | try writer.print("@Vector({d}, ", .{vector_type.len}); |
| 251 | try print(Type.fromInterned(vector_type.child), writer, mod); | 252 | try print(Type.fromInterned(vector_type.child), writer, pt); |
| 252 | try writer.writeAll(")"); | 253 | try writer.writeAll(")"); |
| 253 | return; | 254 | return; |
| 254 | }, | 255 | }, |
| 255 | .opt_type => |child| { | 256 | .opt_type => |child| { |
| 256 | try writer.writeByte('?'); | 257 | try writer.writeByte('?'); |
| 257 | return print(Type.fromInterned(child), writer, mod); | 258 | return print(Type.fromInterned(child), writer, pt); |
| 258 | }, | 259 | }, |
| 259 | .error_union_type => |error_union_type| { | 260 | .error_union_type => |error_union_type| { |
| 260 | try print(Type.fromInterned(error_union_type.error_set_type), writer, mod); | 261 | try print(Type.fromInterned(error_union_type.error_set_type), writer, pt); |
| 261 | try writer.writeByte('!'); | 262 | try writer.writeByte('!'); |
| 262 | if (error_union_type.payload_type == .generic_poison_type) { | 263 | if (error_union_type.payload_type == .generic_poison_type) { |
| 263 | try writer.writeAll("anytype"); | 264 | try writer.writeAll("anytype"); |
| 264 | } else { | 265 | } else { |
| 265 | try print(Type.fromInterned(error_union_type.payload_type), writer, mod); | 266 | try print(Type.fromInterned(error_union_type.payload_type), writer, pt); |
| 266 | } | 267 | } |
| 267 | return; | 268 | return; |
| 268 | }, | 269 | }, |
| ... | @@ -355,10 +356,10 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -355,10 +356,10 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 355 | try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)}); | 356 | try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)}); |
| 356 | } | 357 | } |
| 357 | 358 | ||
| 358 | try print(Type.fromInterned(field_ty), writer, mod); | 359 | try print(Type.fromInterned(field_ty), writer, pt); |
| 359 | 360 | ||
| 360 | if (val != .none) { | 361 | if (val != .none) { |
| 361 | try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod, null)}); | 362 | try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt, null)}); |
| 362 | } | 363 | } |
| 363 | } | 364 | } |
| 364 | try writer.writeAll("}"); | 365 | try writer.writeAll("}"); |
| ... | @@ -395,7 +396,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -395,7 +396,7 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 395 | if (param_ty == .generic_poison_type) { | 396 | if (param_ty == .generic_poison_type) { |
| 396 | try writer.writeAll("anytype"); | 397 | try writer.writeAll("anytype"); |
| 397 | } else { | 398 | } else { |
| 398 | try print(Type.fromInterned(param_ty), writer, mod); | 399 | try print(Type.fromInterned(param_ty), writer, pt); |
| 399 | } | 400 | } |
| 400 | } | 401 | } |
| 401 | if (fn_info.is_var_args) { | 402 | if (fn_info.is_var_args) { |
| ... | @@ -413,13 +414,13 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void | ... | @@ -413,13 +414,13 @@ pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void |
| 413 | if (fn_info.return_type == .generic_poison_type) { | 414 | if (fn_info.return_type == .generic_poison_type) { |
| 414 | try writer.writeAll("anytype"); | 415 | try writer.writeAll("anytype"); |
| 415 | } else { | 416 | } else { |
| 416 | try print(Type.fromInterned(fn_info.return_type), writer, mod); | 417 | try print(Type.fromInterned(fn_info.return_type), writer, pt); |
| 417 | } | 418 | } |
| 418 | }, | 419 | }, |
| 419 | .anyframe_type => |child| { | 420 | .anyframe_type => |child| { |
| 420 | if (child == .none) return writer.writeAll("anyframe"); | 421 | if (child == .none) return writer.writeAll("anyframe"); |
| 421 | try writer.writeAll("anyframe->"); | 422 | try writer.writeAll("anyframe->"); |
| 422 | return print(Type.fromInterned(child), writer, mod); | 423 | return print(Type.fromInterned(child), writer, pt); |
| 423 | }, | 424 | }, |
| 424 | 425 | ||
| 425 | // values, not types | 426 | // values, not types |
| ... | @@ -475,10 +476,11 @@ const RuntimeBitsError = SemaError || error{NeedLazy}; | ... | @@ -475,10 +476,11 @@ const RuntimeBitsError = SemaError || error{NeedLazy}; |
| 475 | /// may return false positives. | 476 | /// may return false positives. |
| 476 | pub fn hasRuntimeBitsAdvanced( | 477 | pub fn hasRuntimeBitsAdvanced( |
| 477 | ty: Type, | 478 | ty: Type, |
| 478 | mod: *Module, | 479 | pt: Zcu.PerThread, |
| 479 | ignore_comptime_only: bool, | 480 | ignore_comptime_only: bool, |
| 480 | strat: ResolveStratLazy, | 481 | strat: ResolveStratLazy, |
| 481 | ) RuntimeBitsError!bool { | 482 | ) RuntimeBitsError!bool { |
| 483 | const mod = pt.zcu; | ||
| 482 | const ip = &mod.intern_pool; | 484 | const ip = &mod.intern_pool; |
| 483 | return switch (ty.toIntern()) { | 485 | return switch (ty.toIntern()) { |
| 484 | // False because it is a comptime-only type. | 486 | // False because it is a comptime-only type. |
| ... | @@ -490,16 +492,16 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -490,16 +492,16 @@ pub fn hasRuntimeBitsAdvanced( |
| 490 | // to comptime-only types do not, with the exception of function pointers. | 492 | // to comptime-only types do not, with the exception of function pointers. |
| 491 | if (ignore_comptime_only) return true; | 493 | if (ignore_comptime_only) return true; |
| 492 | return switch (strat) { | 494 | return switch (strat) { |
| 493 | .sema => !try ty.comptimeOnlyAdvanced(mod, .sema), | 495 | .sema => !try ty.comptimeOnlyAdvanced(pt, .sema), |
| 494 | .eager => !ty.comptimeOnly(mod), | 496 | .eager => !ty.comptimeOnly(pt), |
| 495 | .lazy => error.NeedLazy, | 497 | .lazy => error.NeedLazy, |
| 496 | }; | 498 | }; |
| 497 | }, | 499 | }, |
| 498 | .anyframe_type => true, | 500 | .anyframe_type => true, |
| 499 | .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and | 501 | .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and |
| 500 | try Type.fromInterned(array_type.child).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), | 502 | try Type.fromInterned(array_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), |
| 501 | .vector_type => |vector_type| return vector_type.len > 0 and | 503 | .vector_type => |vector_type| return vector_type.len > 0 and |
| 502 | try Type.fromInterned(vector_type.child).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), | 504 | try Type.fromInterned(vector_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), |
| 503 | .opt_type => |child| { | 505 | .opt_type => |child| { |
| 504 | const child_ty = Type.fromInterned(child); | 506 | const child_ty = Type.fromInterned(child); |
| 505 | if (child_ty.isNoReturn(mod)) { | 507 | if (child_ty.isNoReturn(mod)) { |
| ... | @@ -508,8 +510,8 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -508,8 +510,8 @@ pub fn hasRuntimeBitsAdvanced( |
| 508 | } | 510 | } |
| 509 | if (ignore_comptime_only) return true; | 511 | if (ignore_comptime_only) return true; |
| 510 | return switch (strat) { | 512 | return switch (strat) { |
| 511 | .sema => !try child_ty.comptimeOnlyAdvanced(mod, .sema), | 513 | .sema => !try child_ty.comptimeOnlyAdvanced(pt, .sema), |
| 512 | .eager => !child_ty.comptimeOnly(mod), | 514 | .eager => !child_ty.comptimeOnly(pt), |
| 513 | .lazy => error.NeedLazy, | 515 | .lazy => error.NeedLazy, |
| 514 | }; | 516 | }; |
| 515 | }, | 517 | }, |
| ... | @@ -580,14 +582,14 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -580,14 +582,14 @@ pub fn hasRuntimeBitsAdvanced( |
| 580 | return true; | 582 | return true; |
| 581 | } | 583 | } |
| 582 | switch (strat) { | 584 | switch (strat) { |
| 583 | .sema => try ty.resolveFields(mod), | 585 | .sema => try ty.resolveFields(pt), |
| 584 | .eager => assert(struct_type.haveFieldTypes(ip)), | 586 | .eager => assert(struct_type.haveFieldTypes(ip)), |
| 585 | .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy, | 587 | .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy, |
| 586 | } | 588 | } |
| 587 | for (0..struct_type.field_types.len) |i| { | 589 | for (0..struct_type.field_types.len) |i| { |
| 588 | if (struct_type.comptime_bits.getBit(ip, i)) continue; | 590 | if (struct_type.comptime_bits.getBit(ip, i)) continue; |
| 589 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 591 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 590 | if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) | 592 | if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) |
| 591 | return true; | 593 | return true; |
| 592 | } else { | 594 | } else { |
| 593 | return false; | 595 | return false; |
| ... | @@ -596,7 +598,7 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -596,7 +598,7 @@ pub fn hasRuntimeBitsAdvanced( |
| 596 | .anon_struct_type => |tuple| { | 598 | .anon_struct_type => |tuple| { |
| 597 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { | 599 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 598 | if (val != .none) continue; // comptime field | 600 | if (val != .none) continue; // comptime field |
| 599 | if (try Type.fromInterned(field_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true; | 601 | if (try Type.fromInterned(field_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) return true; |
| 600 | } | 602 | } |
| 601 | return false; | 603 | return false; |
| 602 | }, | 604 | }, |
| ... | @@ -617,21 +619,21 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -617,21 +619,21 @@ pub fn hasRuntimeBitsAdvanced( |
| 617 | // tag_ty will be `none` if this union's tag type is not resolved yet, | 619 | // tag_ty will be `none` if this union's tag type is not resolved yet, |
| 618 | // in which case we want control flow to continue down below. | 620 | // in which case we want control flow to continue down below. |
| 619 | if (tag_ty != .none and | 621 | if (tag_ty != .none and |
| 620 | try Type.fromInterned(tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) | 622 | try Type.fromInterned(tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) |
| 621 | { | 623 | { |
| 622 | return true; | 624 | return true; |
| 623 | } | 625 | } |
| 624 | }, | 626 | }, |
| 625 | } | 627 | } |
| 626 | switch (strat) { | 628 | switch (strat) { |
| 627 | .sema => try ty.resolveFields(mod), | 629 | .sema => try ty.resolveFields(pt), |
| 628 | .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()), | 630 | .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()), |
| 629 | .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes()) | 631 | .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes()) |
| 630 | return error.NeedLazy, | 632 | return error.NeedLazy, |
| 631 | } | 633 | } |
| 632 | for (0..union_type.field_types.len) |field_index| { | 634 | for (0..union_type.field_types.len) |field_index| { |
| 633 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); | 635 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); |
| 634 | if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) | 636 | if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) |
| 635 | return true; | 637 | return true; |
| 636 | } else { | 638 | } else { |
| 637 | return false; | 639 | return false; |
| ... | @@ -639,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced( | ... | @@ -639,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced( |
| 639 | }, | 641 | }, |
| 640 | 642 | ||
| 641 | .opaque_type => true, | 643 | .opaque_type => true, |
| 642 | .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), | 644 | .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), |
| 643 | 645 | ||
| 644 | // values, not types | 646 | // values, not types |
| 645 | .undef, | 647 | .undef, |
| ... | @@ -777,41 +779,41 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { | ... | @@ -777,41 +779,41 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { |
| 777 | }; | 779 | }; |
| 778 | } | 780 | } |
| 779 | 781 | ||
| 780 | pub fn hasRuntimeBits(ty: Type, mod: *Module) bool { | 782 | pub fn hasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { |
| 781 | return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable; | 783 | return hasRuntimeBitsAdvanced(ty, pt, false, .eager) catch unreachable; |
| 782 | } | 784 | } |
| 783 | 785 | ||
| 784 | pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool { | 786 | pub fn hasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool { |
| 785 | return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable; | 787 | return hasRuntimeBitsAdvanced(ty, pt, true, .eager) catch unreachable; |
| 786 | } | 788 | } |
| 787 | 789 | ||
| 788 | pub fn fnHasRuntimeBits(ty: Type, mod: *Module) bool { | 790 | pub fn fnHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { |
| 789 | return ty.fnHasRuntimeBitsAdvanced(mod, .normal) catch unreachable; | 791 | return ty.fnHasRuntimeBitsAdvanced(pt, .normal) catch unreachable; |
| 790 | } | 792 | } |
| 791 | 793 | ||
| 792 | /// Determines whether a function type has runtime bits, i.e. whether a | 794 | /// Determines whether a function type has runtime bits, i.e. whether a |
| 793 | /// function with this type can exist at runtime. | 795 | /// function with this type can exist at runtime. |
| 794 | /// Asserts that `ty` is a function type. | 796 | /// Asserts that `ty` is a function type. |
| 795 | pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool { | 797 | pub fn fnHasRuntimeBitsAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool { |
| 796 | const fn_info = mod.typeToFunc(ty).?; | 798 | const fn_info = pt.zcu.typeToFunc(ty).?; |
| 797 | if (fn_info.is_generic) return false; | 799 | if (fn_info.is_generic) return false; |
| 798 | if (fn_info.is_var_args) return true; | 800 | if (fn_info.is_var_args) return true; |
| 799 | if (fn_info.cc == .Inline) return false; | 801 | if (fn_info.cc == .Inline) return false; |
| 800 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(mod, strat); | 802 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(pt, strat); |
| 801 | } | 803 | } |
| 802 | 804 | ||
| 803 | pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool { | 805 | pub fn isFnOrHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { |
| 804 | switch (ty.zigTypeTag(mod)) { | 806 | switch (ty.zigTypeTag(pt.zcu)) { |
| 805 | .Fn => return ty.fnHasRuntimeBits(mod), | 807 | .Fn => return ty.fnHasRuntimeBits(pt), |
| 806 | else => return ty.hasRuntimeBits(mod), | 808 | else => return ty.hasRuntimeBits(pt), |
| 807 | } | 809 | } |
| 808 | } | 810 | } |
| 809 | 811 | ||
| 810 | /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive. | 812 | /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive. |
| 811 | pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool { | 813 | pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool { |
| 812 | return switch (ty.zigTypeTag(mod)) { | 814 | return switch (ty.zigTypeTag(pt.zcu)) { |
| 813 | .Fn => true, | 815 | .Fn => true, |
| 814 | else => return ty.hasRuntimeBitsIgnoreComptime(mod), | 816 | else => return ty.hasRuntimeBitsIgnoreComptime(pt), |
| 815 | }; | 817 | }; |
| 816 | } | 818 | } |
| 817 | 819 | ||
| ... | @@ -820,24 +822,24 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool { | ... | @@ -820,24 +822,24 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool { |
| 820 | } | 822 | } |
| 821 | 823 | ||
| 822 | /// Returns `none` if the pointer is naturally aligned and the element type is 0-bit. | 824 | /// Returns `none` if the pointer is naturally aligned and the element type is 0-bit. |
| 823 | pub fn ptrAlignment(ty: Type, mod: *Module) Alignment { | 825 | pub fn ptrAlignment(ty: Type, pt: Zcu.PerThread) Alignment { |
| 824 | return ptrAlignmentAdvanced(ty, mod, .normal) catch unreachable; | 826 | return ptrAlignmentAdvanced(ty, pt, .normal) catch unreachable; |
| 825 | } | 827 | } |
| 826 | 828 | ||
| 827 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) !Alignment { | 829 | pub fn ptrAlignmentAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment { |
| 828 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 830 | return switch (pt.zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 829 | .ptr_type => |ptr_type| { | 831 | .ptr_type => |ptr_type| { |
| 830 | if (ptr_type.flags.alignment != .none) | 832 | if (ptr_type.flags.alignment != .none) |
| 831 | return ptr_type.flags.alignment; | 833 | return ptr_type.flags.alignment; |
| 832 | 834 | ||
| 833 | if (strat == .sema) { | 835 | if (strat == .sema) { |
| 834 | const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .sema); | 836 | const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .sema); |
| 835 | return res.scalar; | 837 | return res.scalar; |
| 836 | } | 838 | } |
| 837 | 839 | ||
| 838 | return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | 840 | return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar; |
| 839 | }, | 841 | }, |
| 840 | .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, strat), | 842 | .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(pt, strat), |
| 841 | else => unreachable, | 843 | else => unreachable, |
| 842 | }; | 844 | }; |
| 843 | } | 845 | } |
| ... | @@ -851,16 +853,16 @@ pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { | ... | @@ -851,16 +853,16 @@ pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { |
| 851 | } | 853 | } |
| 852 | 854 | ||
| 853 | /// Never returns `none`. Asserts that all necessary type resolution is already done. | 855 | /// Never returns `none`. Asserts that all necessary type resolution is already done. |
| 854 | pub fn abiAlignment(ty: Type, mod: *Module) Alignment { | 856 | pub fn abiAlignment(ty: Type, pt: Zcu.PerThread) Alignment { |
| 855 | return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | 857 | return (ty.abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar; |
| 856 | } | 858 | } |
| 857 | 859 | ||
| 858 | /// May capture a reference to `ty`. | 860 | /// May capture a reference to `ty`. |
| 859 | /// Returned value has type `comptime_int`. | 861 | /// Returned value has type `comptime_int`. |
| 860 | pub fn lazyAbiAlignment(ty: Type, mod: *Module) !Value { | 862 | pub fn lazyAbiAlignment(ty: Type, pt: Zcu.PerThread) !Value { |
| 861 | switch (try ty.abiAlignmentAdvanced(mod, .lazy)) { | 863 | switch (try ty.abiAlignmentAdvanced(pt, .lazy)) { |
| 862 | .val => |val| return val, | 864 | .val => |val| return val, |
| 863 | .scalar => |x| return mod.intValue(Type.comptime_int, x.toByteUnits() orelse 0), | 865 | .scalar => |x| return pt.intValue(Type.comptime_int, x.toByteUnits() orelse 0), |
| 864 | } | 866 | } |
| 865 | } | 867 | } |
| 866 | 868 | ||
| ... | @@ -907,38 +909,39 @@ pub const ResolveStrat = enum { | ... | @@ -907,38 +909,39 @@ pub const ResolveStrat = enum { |
| 907 | /// necessary, possibly returning a CompileError. | 909 | /// necessary, possibly returning a CompileError. |
| 908 | pub fn abiAlignmentAdvanced( | 910 | pub fn abiAlignmentAdvanced( |
| 909 | ty: Type, | 911 | ty: Type, |
| 910 | mod: *Module, | 912 | pt: Zcu.PerThread, |
| 911 | strat: ResolveStratLazy, | 913 | strat: ResolveStratLazy, |
| 912 | ) SemaError!AbiAlignmentAdvanced { | 914 | ) SemaError!AbiAlignmentAdvanced { |
| 915 | const mod = pt.zcu; | ||
| 913 | const target = mod.getTarget(); | 916 | const target = mod.getTarget(); |
| 914 | const use_llvm = mod.comp.config.use_llvm; | 917 | const use_llvm = mod.comp.config.use_llvm; |
| 915 | const ip = &mod.intern_pool; | 918 | const ip = &mod.intern_pool; |
| 916 | 919 | ||
| 917 | switch (ty.toIntern()) { | 920 | switch (ty.toIntern()) { |
| 918 | .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" }, | 921 | .empty_struct_type => return .{ .scalar = .@"1" }, |
| 919 | else => switch (ip.indexToKey(ty.toIntern())) { | 922 | else => switch (ip.indexToKey(ty.toIntern())) { |
| 920 | .int_type => |int_type| { | 923 | .int_type => |int_type| { |
| 921 | if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" }; | 924 | if (int_type.bits == 0) return .{ .scalar = .@"1" }; |
| 922 | return .{ .scalar = intAbiAlignment(int_type.bits, target, use_llvm) }; | 925 | return .{ .scalar = intAbiAlignment(int_type.bits, target, use_llvm) }; |
| 923 | }, | 926 | }, |
| 924 | .ptr_type, .anyframe_type => { | 927 | .ptr_type, .anyframe_type => { |
| 925 | return .{ .scalar = ptrAbiAlignment(target) }; | 928 | return .{ .scalar = ptrAbiAlignment(target) }; |
| 926 | }, | 929 | }, |
| 927 | .array_type => |array_type| { | 930 | .array_type => |array_type| { |
| 928 | return Type.fromInterned(array_type.child).abiAlignmentAdvanced(mod, strat); | 931 | return Type.fromInterned(array_type.child).abiAlignmentAdvanced(pt, strat); |
| 929 | }, | 932 | }, |
| 930 | .vector_type => |vector_type| { | 933 | .vector_type => |vector_type| { |
| 931 | if (vector_type.len == 0) return .{ .scalar = .@"1" }; | 934 | if (vector_type.len == 0) return .{ .scalar = .@"1" }; |
| 932 | switch (mod.comp.getZigBackend()) { | 935 | switch (mod.comp.getZigBackend()) { |
| 933 | else => { | 936 | else => { |
| 934 | const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, .sema)); | 937 | const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, .sema)); |
| 935 | if (elem_bits == 0) return .{ .scalar = .@"1" }; | 938 | if (elem_bits == 0) return .{ .scalar = .@"1" }; |
| 936 | const bytes = ((elem_bits * vector_type.len) + 7) / 8; | 939 | const bytes = ((elem_bits * vector_type.len) + 7) / 8; |
| 937 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); | 940 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); |
| 938 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; | 941 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; |
| 939 | }, | 942 | }, |
| 940 | .stage2_c => { | 943 | .stage2_c => { |
| 941 | return Type.fromInterned(vector_type.child).abiAlignmentAdvanced(mod, strat); | 944 | return Type.fromInterned(vector_type.child).abiAlignmentAdvanced(pt, strat); |
| 942 | }, | 945 | }, |
| 943 | .stage2_x86_64 => { | 946 | .stage2_x86_64 => { |
| 944 | if (vector_type.child == .bool_type) { | 947 | if (vector_type.child == .bool_type) { |
| ... | @@ -949,7 +952,7 @@ pub fn abiAlignmentAdvanced( | ... | @@ -949,7 +952,7 @@ pub fn abiAlignmentAdvanced( |
| 949 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); | 952 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); |
| 950 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; | 953 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; |
| 951 | } | 954 | } |
| 952 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar); | 955 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); |
| 953 | if (elem_bytes == 0) return .{ .scalar = .@"1" }; | 956 | if (elem_bytes == 0) return .{ .scalar = .@"1" }; |
| 954 | const bytes = elem_bytes * vector_type.len; | 957 | const bytes = elem_bytes * vector_type.len; |
| 955 | if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" }; | 958 | if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" }; |
| ... | @@ -959,12 +962,12 @@ pub fn abiAlignmentAdvanced( | ... | @@ -959,12 +962,12 @@ pub fn abiAlignmentAdvanced( |
| 959 | } | 962 | } |
| 960 | }, | 963 | }, |
| 961 | 964 | ||
| 962 | .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat), | 965 | .opt_type => return ty.abiAlignmentAdvancedOptional(pt, strat), |
| 963 | .error_union_type => |info| return abiAlignmentAdvancedErrorUnion(ty, mod, strat, Type.fromInterned(info.payload_type)), | 966 | .error_union_type => |info| return ty.abiAlignmentAdvancedErrorUnion(pt, strat, Type.fromInterned(info.payload_type)), |
| 964 | 967 | ||
| 965 | .error_set_type, .inferred_error_set_type => { | 968 | .error_set_type, .inferred_error_set_type => { |
| 966 | const bits = mod.errorSetBits(); | 969 | const bits = mod.errorSetBits(); |
| 967 | if (bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" }; | 970 | if (bits == 0) return .{ .scalar = .@"1" }; |
| 968 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; | 971 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; |
| 969 | }, | 972 | }, |
| 970 | 973 | ||
| ... | @@ -1012,10 +1015,7 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1012,10 +1015,7 @@ pub fn abiAlignmentAdvanced( |
| 1012 | }, | 1015 | }, |
| 1013 | .f80 => switch (target.c_type_bit_size(.longdouble)) { | 1016 | .f80 => switch (target.c_type_bit_size(.longdouble)) { |
| 1014 | 80 => return .{ .scalar = cTypeAlign(target, .longdouble) }, | 1017 | 80 => return .{ .scalar = cTypeAlign(target, .longdouble) }, |
| 1015 | else => { | 1018 | else => return .{ .scalar = Type.u80.abiAlignment(pt) }, |
| 1016 | const u80_ty: Type = .{ .ip_index = .u80_type }; | ||
| 1017 | return .{ .scalar = abiAlignment(u80_ty, mod) }; | ||
| 1018 | }, | ||
| 1019 | }, | 1019 | }, |
| 1020 | .f128 => switch (target.c_type_bit_size(.longdouble)) { | 1020 | .f128 => switch (target.c_type_bit_size(.longdouble)) { |
| 1021 | 128 => return .{ .scalar = cTypeAlign(target, .longdouble) }, | 1021 | 128 => return .{ .scalar = cTypeAlign(target, .longdouble) }, |
| ... | @@ -1024,7 +1024,7 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1024,7 +1024,7 @@ pub fn abiAlignmentAdvanced( |
| 1024 | 1024 | ||
| 1025 | .anyerror, .adhoc_inferred_error_set => { | 1025 | .anyerror, .adhoc_inferred_error_set => { |
| 1026 | const bits = mod.errorSetBits(); | 1026 | const bits = mod.errorSetBits(); |
| 1027 | if (bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" }; | 1027 | if (bits == 0) return .{ .scalar = .@"1" }; |
| 1028 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; | 1028 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; |
| 1029 | }, | 1029 | }, |
| 1030 | 1030 | ||
| ... | @@ -1044,22 +1044,22 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1044,22 +1044,22 @@ pub fn abiAlignmentAdvanced( |
| 1044 | const struct_type = ip.loadStructType(ty.toIntern()); | 1044 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 1045 | if (struct_type.layout == .@"packed") { | 1045 | if (struct_type.layout == .@"packed") { |
| 1046 | switch (strat) { | 1046 | switch (strat) { |
| 1047 | .sema => try ty.resolveLayout(mod), | 1047 | .sema => try ty.resolveLayout(pt), |
| 1048 | .lazy => if (struct_type.backingIntType(ip).* == .none) return .{ | 1048 | .lazy => if (struct_type.backingIntType(ip).* == .none) return .{ |
| 1049 | .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1049 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1050 | .ty = .comptime_int_type, | 1050 | .ty = .comptime_int_type, |
| 1051 | .storage = .{ .lazy_align = ty.toIntern() }, | 1051 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1052 | } }))), | 1052 | } })), |
| 1053 | }, | 1053 | }, |
| 1054 | .eager => {}, | 1054 | .eager => {}, |
| 1055 | } | 1055 | } |
| 1056 | return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(mod) }; | 1056 | return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(pt) }; |
| 1057 | } | 1057 | } |
| 1058 | 1058 | ||
| 1059 | if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) { | 1059 | if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) { |
| 1060 | .eager => unreachable, // struct alignment not resolved | 1060 | .eager => unreachable, // struct alignment not resolved |
| 1061 | .sema => try ty.resolveStructAlignment(mod), | 1061 | .sema => try ty.resolveStructAlignment(pt), |
| 1062 | .lazy => return .{ .val = Value.fromInterned(try mod.intern(.{ .int = .{ | 1062 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1063 | .ty = .comptime_int_type, | 1063 | .ty = .comptime_int_type, |
| 1064 | .storage = .{ .lazy_align = ty.toIntern() }, | 1064 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1065 | } })) }, | 1065 | } })) }, |
| ... | @@ -1071,15 +1071,15 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1071,15 +1071,15 @@ pub fn abiAlignmentAdvanced( |
| 1071 | var big_align: Alignment = .@"1"; | 1071 | var big_align: Alignment = .@"1"; |
| 1072 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { | 1072 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 1073 | if (val != .none) continue; // comptime field | 1073 | if (val != .none) continue; // comptime field |
| 1074 | switch (try Type.fromInterned(field_ty).abiAlignmentAdvanced(mod, strat)) { | 1074 | switch (try Type.fromInterned(field_ty).abiAlignmentAdvanced(pt, strat)) { |
| 1075 | .scalar => |field_align| big_align = big_align.max(field_align), | 1075 | .scalar => |field_align| big_align = big_align.max(field_align), |
| 1076 | .val => switch (strat) { | 1076 | .val => switch (strat) { |
| 1077 | .eager => unreachable, // field type alignment not resolved | 1077 | .eager => unreachable, // field type alignment not resolved |
| 1078 | .sema => unreachable, // passed to abiAlignmentAdvanced above | 1078 | .sema => unreachable, // passed to abiAlignmentAdvanced above |
| 1079 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1079 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1080 | .ty = .comptime_int_type, | 1080 | .ty = .comptime_int_type, |
| 1081 | .storage = .{ .lazy_align = ty.toIntern() }, | 1081 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1082 | } }))) }, | 1082 | } })) }, |
| 1083 | }, | 1083 | }, |
| 1084 | } | 1084 | } |
| 1085 | } | 1085 | } |
| ... | @@ -1090,18 +1090,18 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1090,18 +1090,18 @@ pub fn abiAlignmentAdvanced( |
| 1090 | 1090 | ||
| 1091 | if (union_type.flagsPtr(ip).alignment == .none) switch (strat) { | 1091 | if (union_type.flagsPtr(ip).alignment == .none) switch (strat) { |
| 1092 | .eager => unreachable, // union layout not resolved | 1092 | .eager => unreachable, // union layout not resolved |
| 1093 | .sema => try ty.resolveUnionAlignment(mod), | 1093 | .sema => try ty.resolveUnionAlignment(pt), |
| 1094 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1094 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1095 | .ty = .comptime_int_type, | 1095 | .ty = .comptime_int_type, |
| 1096 | .storage = .{ .lazy_align = ty.toIntern() }, | 1096 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1097 | } }))) }, | 1097 | } })) }, |
| 1098 | }; | 1098 | }; |
| 1099 | 1099 | ||
| 1100 | return .{ .scalar = union_type.flagsPtr(ip).alignment }; | 1100 | return .{ .scalar = union_type.flagsPtr(ip).alignment }; |
| 1101 | }, | 1101 | }, |
| 1102 | .opaque_type => return .{ .scalar = .@"1" }, | 1102 | .opaque_type => return .{ .scalar = .@"1" }, |
| 1103 | .enum_type => return .{ | 1103 | .enum_type => return .{ |
| 1104 | .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(mod), | 1104 | .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(pt), |
| 1105 | }, | 1105 | }, |
| 1106 | 1106 | ||
| 1107 | // values, not types | 1107 | // values, not types |
| ... | @@ -1131,91 +1131,92 @@ pub fn abiAlignmentAdvanced( | ... | @@ -1131,91 +1131,92 @@ pub fn abiAlignmentAdvanced( |
| 1131 | 1131 | ||
| 1132 | fn abiAlignmentAdvancedErrorUnion( | 1132 | fn abiAlignmentAdvancedErrorUnion( |
| 1133 | ty: Type, | 1133 | ty: Type, |
| 1134 | mod: *Module, | 1134 | pt: Zcu.PerThread, |
| 1135 | strat: ResolveStratLazy, | 1135 | strat: ResolveStratLazy, |
| 1136 | payload_ty: Type, | 1136 | payload_ty: Type, |
| 1137 | ) SemaError!AbiAlignmentAdvanced { | 1137 | ) SemaError!AbiAlignmentAdvanced { |
| 1138 | // This code needs to be kept in sync with the equivalent switch prong | 1138 | // This code needs to be kept in sync with the equivalent switch prong |
| 1139 | // in abiSizeAdvanced. | 1139 | // in abiSizeAdvanced. |
| 1140 | const code_align = abiAlignment(Type.anyerror, mod); | 1140 | const code_align = Type.anyerror.abiAlignment(pt); |
| 1141 | switch (strat) { | 1141 | switch (strat) { |
| 1142 | .eager, .sema => { | 1142 | .eager, .sema => { |
| 1143 | if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { | 1143 | if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { |
| 1144 | error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1144 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1145 | .ty = .comptime_int_type, | 1145 | .ty = .comptime_int_type, |
| 1146 | .storage = .{ .lazy_align = ty.toIntern() }, | 1146 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1147 | } }))) }, | 1147 | } })) }, |
| 1148 | else => |e| return e, | 1148 | else => |e| return e, |
| 1149 | })) { | 1149 | })) { |
| 1150 | return .{ .scalar = code_align }; | 1150 | return .{ .scalar = code_align }; |
| 1151 | } | 1151 | } |
| 1152 | return .{ .scalar = code_align.max( | 1152 | return .{ .scalar = code_align.max( |
| 1153 | (try payload_ty.abiAlignmentAdvanced(mod, strat)).scalar, | 1153 | (try payload_ty.abiAlignmentAdvanced(pt, strat)).scalar, |
| 1154 | ) }; | 1154 | ) }; |
| 1155 | }, | 1155 | }, |
| 1156 | .lazy => { | 1156 | .lazy => { |
| 1157 | switch (try payload_ty.abiAlignmentAdvanced(mod, strat)) { | 1157 | switch (try payload_ty.abiAlignmentAdvanced(pt, strat)) { |
| 1158 | .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) }, | 1158 | .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) }, |
| 1159 | .val => {}, | 1159 | .val => {}, |
| 1160 | } | 1160 | } |
| 1161 | return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1161 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1162 | .ty = .comptime_int_type, | 1162 | .ty = .comptime_int_type, |
| 1163 | .storage = .{ .lazy_align = ty.toIntern() }, | 1163 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1164 | } }))) }; | 1164 | } })) }; |
| 1165 | }, | 1165 | }, |
| 1166 | } | 1166 | } |
| 1167 | } | 1167 | } |
| 1168 | 1168 | ||
| 1169 | fn abiAlignmentAdvancedOptional( | 1169 | fn abiAlignmentAdvancedOptional( |
| 1170 | ty: Type, | 1170 | ty: Type, |
| 1171 | mod: *Module, | 1171 | pt: Zcu.PerThread, |
| 1172 | strat: ResolveStratLazy, | 1172 | strat: ResolveStratLazy, |
| 1173 | ) SemaError!AbiAlignmentAdvanced { | 1173 | ) SemaError!AbiAlignmentAdvanced { |
| 1174 | const mod = pt.zcu; | ||
| 1174 | const target = mod.getTarget(); | 1175 | const target = mod.getTarget(); |
| 1175 | const child_type = ty.optionalChild(mod); | 1176 | const child_type = ty.optionalChild(mod); |
| 1176 | 1177 | ||
| 1177 | switch (child_type.zigTypeTag(mod)) { | 1178 | switch (child_type.zigTypeTag(mod)) { |
| 1178 | .Pointer => return .{ .scalar = ptrAbiAlignment(target) }, | 1179 | .Pointer => return .{ .scalar = ptrAbiAlignment(target) }, |
| 1179 | .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat), | 1180 | .ErrorSet => return Type.anyerror.abiAlignmentAdvanced(pt, strat), |
| 1180 | .NoReturn => return .{ .scalar = .@"1" }, | 1181 | .NoReturn => return .{ .scalar = .@"1" }, |
| 1181 | else => {}, | 1182 | else => {}, |
| 1182 | } | 1183 | } |
| 1183 | 1184 | ||
| 1184 | switch (strat) { | 1185 | switch (strat) { |
| 1185 | .eager, .sema => { | 1186 | .eager, .sema => { |
| 1186 | if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { | 1187 | if (!(child_type.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { |
| 1187 | error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1188 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1188 | .ty = .comptime_int_type, | 1189 | .ty = .comptime_int_type, |
| 1189 | .storage = .{ .lazy_align = ty.toIntern() }, | 1190 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1190 | } }))) }, | 1191 | } })) }, |
| 1191 | else => |e| return e, | 1192 | else => |e| return e, |
| 1192 | })) { | 1193 | })) { |
| 1193 | return .{ .scalar = .@"1" }; | 1194 | return .{ .scalar = .@"1" }; |
| 1194 | } | 1195 | } |
| 1195 | return child_type.abiAlignmentAdvanced(mod, strat); | 1196 | return child_type.abiAlignmentAdvanced(pt, strat); |
| 1196 | }, | 1197 | }, |
| 1197 | .lazy => switch (try child_type.abiAlignmentAdvanced(mod, strat)) { | 1198 | .lazy => switch (try child_type.abiAlignmentAdvanced(pt, strat)) { |
| 1198 | .scalar => |x| return .{ .scalar = x.max(.@"1") }, | 1199 | .scalar => |x| return .{ .scalar = x.max(.@"1") }, |
| 1199 | .val => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1200 | .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1200 | .ty = .comptime_int_type, | 1201 | .ty = .comptime_int_type, |
| 1201 | .storage = .{ .lazy_align = ty.toIntern() }, | 1202 | .storage = .{ .lazy_align = ty.toIntern() }, |
| 1202 | } }))) }, | 1203 | } })) }, |
| 1203 | }, | 1204 | }, |
| 1204 | } | 1205 | } |
| 1205 | } | 1206 | } |
| 1206 | 1207 | ||
| 1207 | /// May capture a reference to `ty`. | 1208 | /// May capture a reference to `ty`. |
| 1208 | pub fn lazyAbiSize(ty: Type, mod: *Module) !Value { | 1209 | pub fn lazyAbiSize(ty: Type, pt: Zcu.PerThread) !Value { |
| 1209 | switch (try ty.abiSizeAdvanced(mod, .lazy)) { | 1210 | switch (try ty.abiSizeAdvanced(pt, .lazy)) { |
| 1210 | .val => |val| return val, | 1211 | .val => |val| return val, |
| 1211 | .scalar => |x| return mod.intValue(Type.comptime_int, x), | 1212 | .scalar => |x| return pt.intValue(Type.comptime_int, x), |
| 1212 | } | 1213 | } |
| 1213 | } | 1214 | } |
| 1214 | 1215 | ||
| 1215 | /// Asserts the type has the ABI size already resolved. | 1216 | /// Asserts the type has the ABI size already resolved. |
| 1216 | /// Types that return false for hasRuntimeBits() return 0. | 1217 | /// Types that return false for hasRuntimeBits() return 0. |
| 1217 | pub fn abiSize(ty: Type, mod: *Module) u64 { | 1218 | pub fn abiSize(ty: Type, pt: Zcu.PerThread) u64 { |
| 1218 | return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar; | 1219 | return (abiSizeAdvanced(ty, pt, .eager) catch unreachable).scalar; |
| 1219 | } | 1220 | } |
| 1220 | 1221 | ||
| 1221 | const AbiSizeAdvanced = union(enum) { | 1222 | const AbiSizeAdvanced = union(enum) { |
| ... | @@ -1231,38 +1232,39 @@ const AbiSizeAdvanced = union(enum) { | ... | @@ -1231,38 +1232,39 @@ const AbiSizeAdvanced = union(enum) { |
| 1231 | /// necessary, possibly returning a CompileError. | 1232 | /// necessary, possibly returning a CompileError. |
| 1232 | pub fn abiSizeAdvanced( | 1233 | pub fn abiSizeAdvanced( |
| 1233 | ty: Type, | 1234 | ty: Type, |
| 1234 | mod: *Module, | 1235 | pt: Zcu.PerThread, |
| 1235 | strat: ResolveStratLazy, | 1236 | strat: ResolveStratLazy, |
| 1236 | ) SemaError!AbiSizeAdvanced { | 1237 | ) SemaError!AbiSizeAdvanced { |
| 1238 | const mod = pt.zcu; | ||
| 1237 | const target = mod.getTarget(); | 1239 | const target = mod.getTarget(); |
| 1238 | const use_llvm = mod.comp.config.use_llvm; | 1240 | const use_llvm = mod.comp.config.use_llvm; |
| 1239 | const ip = &mod.intern_pool; | 1241 | const ip = &mod.intern_pool; |
| 1240 | 1242 | ||
| 1241 | switch (ty.toIntern()) { | 1243 | switch (ty.toIntern()) { |
| 1242 | .empty_struct_type => return AbiSizeAdvanced{ .scalar = 0 }, | 1244 | .empty_struct_type => return .{ .scalar = 0 }, |
| 1243 | 1245 | ||
| 1244 | else => switch (ip.indexToKey(ty.toIntern())) { | 1246 | else => switch (ip.indexToKey(ty.toIntern())) { |
| 1245 | .int_type => |int_type| { | 1247 | .int_type => |int_type| { |
| 1246 | if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 }; | 1248 | if (int_type.bits == 0) return .{ .scalar = 0 }; |
| 1247 | return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target, use_llvm) }; | 1249 | return .{ .scalar = intAbiSize(int_type.bits, target, use_llvm) }; |
| 1248 | }, | 1250 | }, |
| 1249 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 1251 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1250 | .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, | 1252 | .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, |
| 1251 | else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | 1253 | else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, |
| 1252 | }, | 1254 | }, |
| 1253 | .anyframe_type => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | 1255 | .anyframe_type => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, |
| 1254 | 1256 | ||
| 1255 | .array_type => |array_type| { | 1257 | .array_type => |array_type| { |
| 1256 | const len = array_type.lenIncludingSentinel(); | 1258 | const len = array_type.lenIncludingSentinel(); |
| 1257 | if (len == 0) return .{ .scalar = 0 }; | 1259 | if (len == 0) return .{ .scalar = 0 }; |
| 1258 | switch (try Type.fromInterned(array_type.child).abiSizeAdvanced(mod, strat)) { | 1260 | switch (try Type.fromInterned(array_type.child).abiSizeAdvanced(pt, strat)) { |
| 1259 | .scalar => |elem_size| return .{ .scalar = len * elem_size }, | 1261 | .scalar => |elem_size| return .{ .scalar = len * elem_size }, |
| 1260 | .val => switch (strat) { | 1262 | .val => switch (strat) { |
| 1261 | .sema, .eager => unreachable, | 1263 | .sema, .eager => unreachable, |
| 1262 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1264 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1263 | .ty = .comptime_int_type, | 1265 | .ty = .comptime_int_type, |
| 1264 | .storage = .{ .lazy_size = ty.toIntern() }, | 1266 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1265 | } }))) }, | 1267 | } })) }, |
| 1266 | }, | 1268 | }, |
| 1267 | } | 1269 | } |
| 1268 | }, | 1270 | }, |
| ... | @@ -1270,71 +1272,71 @@ pub fn abiSizeAdvanced( | ... | @@ -1270,71 +1272,71 @@ pub fn abiSizeAdvanced( |
| 1270 | const sub_strat: ResolveStrat = switch (strat) { | 1272 | const sub_strat: ResolveStrat = switch (strat) { |
| 1271 | .sema => .sema, | 1273 | .sema => .sema, |
| 1272 | .eager => .normal, | 1274 | .eager => .normal, |
| 1273 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1275 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1274 | .ty = .comptime_int_type, | 1276 | .ty = .comptime_int_type, |
| 1275 | .storage = .{ .lazy_size = ty.toIntern() }, | 1277 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1276 | } }))) }, | 1278 | } })) }, |
| 1277 | }; | 1279 | }; |
| 1278 | const alignment = switch (try ty.abiAlignmentAdvanced(mod, strat)) { | 1280 | const alignment = switch (try ty.abiAlignmentAdvanced(pt, strat)) { |
| 1279 | .scalar => |x| x, | 1281 | .scalar => |x| x, |
| 1280 | .val => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1282 | .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1281 | .ty = .comptime_int_type, | 1283 | .ty = .comptime_int_type, |
| 1282 | .storage = .{ .lazy_size = ty.toIntern() }, | 1284 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1283 | } }))) }, | 1285 | } })) }, |
| 1284 | }; | 1286 | }; |
| 1285 | const total_bytes = switch (mod.comp.getZigBackend()) { | 1287 | const total_bytes = switch (mod.comp.getZigBackend()) { |
| 1286 | else => total_bytes: { | 1288 | else => total_bytes: { |
| 1287 | const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, sub_strat); | 1289 | const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, sub_strat); |
| 1288 | const total_bits = elem_bits * vector_type.len; | 1290 | const total_bits = elem_bits * vector_type.len; |
| 1289 | break :total_bytes (total_bits + 7) / 8; | 1291 | break :total_bytes (total_bits + 7) / 8; |
| 1290 | }, | 1292 | }, |
| 1291 | .stage2_c => total_bytes: { | 1293 | .stage2_c => total_bytes: { |
| 1292 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar); | 1294 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); |
| 1293 | break :total_bytes elem_bytes * vector_type.len; | 1295 | break :total_bytes elem_bytes * vector_type.len; |
| 1294 | }, | 1296 | }, |
| 1295 | .stage2_x86_64 => total_bytes: { | 1297 | .stage2_x86_64 => total_bytes: { |
| 1296 | if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable; | 1298 | if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable; |
| 1297 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(mod, strat)).scalar); | 1299 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); |
| 1298 | break :total_bytes elem_bytes * vector_type.len; | 1300 | break :total_bytes elem_bytes * vector_type.len; |
| 1299 | }, | 1301 | }, |
| 1300 | }; | 1302 | }; |
| 1301 | return AbiSizeAdvanced{ .scalar = alignment.forward(total_bytes) }; | 1303 | return .{ .scalar = alignment.forward(total_bytes) }; |
| 1302 | }, | 1304 | }, |
| 1303 | 1305 | ||
| 1304 | .opt_type => return ty.abiSizeAdvancedOptional(mod, strat), | 1306 | .opt_type => return ty.abiSizeAdvancedOptional(pt, strat), |
| 1305 | 1307 | ||
| 1306 | .error_set_type, .inferred_error_set_type => { | 1308 | .error_set_type, .inferred_error_set_type => { |
| 1307 | const bits = mod.errorSetBits(); | 1309 | const bits = mod.errorSetBits(); |
| 1308 | if (bits == 0) return AbiSizeAdvanced{ .scalar = 0 }; | 1310 | if (bits == 0) return .{ .scalar = 0 }; |
| 1309 | return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target, use_llvm) }; | 1311 | return .{ .scalar = intAbiSize(bits, target, use_llvm) }; |
| 1310 | }, | 1312 | }, |
| 1311 | 1313 | ||
| 1312 | .error_union_type => |error_union_type| { | 1314 | .error_union_type => |error_union_type| { |
| 1313 | const payload_ty = Type.fromInterned(error_union_type.payload_type); | 1315 | const payload_ty = Type.fromInterned(error_union_type.payload_type); |
| 1314 | // This code needs to be kept in sync with the equivalent switch prong | 1316 | // This code needs to be kept in sync with the equivalent switch prong |
| 1315 | // in abiAlignmentAdvanced. | 1317 | // in abiAlignmentAdvanced. |
| 1316 | const code_size = abiSize(Type.anyerror, mod); | 1318 | const code_size = Type.anyerror.abiSize(pt); |
| 1317 | if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { | 1319 | if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { |
| 1318 | error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1320 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1319 | .ty = .comptime_int_type, | 1321 | .ty = .comptime_int_type, |
| 1320 | .storage = .{ .lazy_size = ty.toIntern() }, | 1322 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1321 | } }))) }, | 1323 | } })) }, |
| 1322 | else => |e| return e, | 1324 | else => |e| return e, |
| 1323 | })) { | 1325 | })) { |
| 1324 | // Same as anyerror. | 1326 | // Same as anyerror. |
| 1325 | return AbiSizeAdvanced{ .scalar = code_size }; | 1327 | return .{ .scalar = code_size }; |
| 1326 | } | 1328 | } |
| 1327 | const code_align = abiAlignment(Type.anyerror, mod); | 1329 | const code_align = Type.anyerror.abiAlignment(pt); |
| 1328 | const payload_align = abiAlignment(payload_ty, mod); | 1330 | const payload_align = payload_ty.abiAlignment(pt); |
| 1329 | const payload_size = switch (try payload_ty.abiSizeAdvanced(mod, strat)) { | 1331 | const payload_size = switch (try payload_ty.abiSizeAdvanced(pt, strat)) { |
| 1330 | .scalar => |elem_size| elem_size, | 1332 | .scalar => |elem_size| elem_size, |
| 1331 | .val => switch (strat) { | 1333 | .val => switch (strat) { |
| 1332 | .sema => unreachable, | 1334 | .sema => unreachable, |
| 1333 | .eager => unreachable, | 1335 | .eager => unreachable, |
| 1334 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1336 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1335 | .ty = .comptime_int_type, | 1337 | .ty = .comptime_int_type, |
| 1336 | .storage = .{ .lazy_size = ty.toIntern() }, | 1338 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1337 | } }))) }, | 1339 | } })) }, |
| 1338 | }, | 1340 | }, |
| 1339 | }; | 1341 | }; |
| 1340 | 1342 | ||
| ... | @@ -1350,7 +1352,7 @@ pub fn abiSizeAdvanced( | ... | @@ -1350,7 +1352,7 @@ pub fn abiSizeAdvanced( |
| 1350 | size += code_size; | 1352 | size += code_size; |
| 1351 | size = payload_align.forward(size); | 1353 | size = payload_align.forward(size); |
| 1352 | } | 1354 | } |
| 1353 | return AbiSizeAdvanced{ .scalar = size }; | 1355 | return .{ .scalar = size }; |
| 1354 | }, | 1356 | }, |
| 1355 | .func_type => unreachable, // represents machine code; not a pointer | 1357 | .func_type => unreachable, // represents machine code; not a pointer |
| 1356 | .simple_type => |t| switch (t) { | 1358 | .simple_type => |t| switch (t) { |
| ... | @@ -1362,34 +1364,31 @@ pub fn abiSizeAdvanced( | ... | @@ -1362,34 +1364,31 @@ pub fn abiSizeAdvanced( |
| 1362 | .float_mode, | 1364 | .float_mode, |
| 1363 | .reduce_op, | 1365 | .reduce_op, |
| 1364 | .call_modifier, | 1366 | .call_modifier, |
| 1365 | => return AbiSizeAdvanced{ .scalar = 1 }, | 1367 | => return .{ .scalar = 1 }, |
| 1366 | 1368 | ||
| 1367 | .f16 => return AbiSizeAdvanced{ .scalar = 2 }, | 1369 | .f16 => return .{ .scalar = 2 }, |
| 1368 | .f32 => return AbiSizeAdvanced{ .scalar = 4 }, | 1370 | .f32 => return .{ .scalar = 4 }, |
| 1369 | .f64 => return AbiSizeAdvanced{ .scalar = 8 }, | 1371 | .f64 => return .{ .scalar = 8 }, |
| 1370 | .f128 => return AbiSizeAdvanced{ .scalar = 16 }, | 1372 | .f128 => return .{ .scalar = 16 }, |
| 1371 | .f80 => switch (target.c_type_bit_size(.longdouble)) { | 1373 | .f80 => switch (target.c_type_bit_size(.longdouble)) { |
| 1372 | 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) }, | 1374 | 80 => return .{ .scalar = target.c_type_byte_size(.longdouble) }, |
| 1373 | else => { | 1375 | else => return .{ .scalar = Type.u80.abiSize(pt) }, |
| 1374 | const u80_ty: Type = .{ .ip_index = .u80_type }; | ||
| 1375 | return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, mod) }; | ||
| 1376 | }, | ||
| 1377 | }, | 1376 | }, |
| 1378 | 1377 | ||
| 1379 | .usize, | 1378 | .usize, |
| 1380 | .isize, | 1379 | .isize, |
| 1381 | => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | 1380 | => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, |
| 1382 | 1381 | ||
| 1383 | .c_char => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.char) }, | 1382 | .c_char => return .{ .scalar = target.c_type_byte_size(.char) }, |
| 1384 | .c_short => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.short) }, | 1383 | .c_short => return .{ .scalar = target.c_type_byte_size(.short) }, |
| 1385 | .c_ushort => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ushort) }, | 1384 | .c_ushort => return .{ .scalar = target.c_type_byte_size(.ushort) }, |
| 1386 | .c_int => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.int) }, | 1385 | .c_int => return .{ .scalar = target.c_type_byte_size(.int) }, |
| 1387 | .c_uint => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.uint) }, | 1386 | .c_uint => return .{ .scalar = target.c_type_byte_size(.uint) }, |
| 1388 | .c_long => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.long) }, | 1387 | .c_long => return .{ .scalar = target.c_type_byte_size(.long) }, |
| 1389 | .c_ulong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulong) }, | 1388 | .c_ulong => return .{ .scalar = target.c_type_byte_size(.ulong) }, |
| 1390 | .c_longlong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longlong) }, | 1389 | .c_longlong => return .{ .scalar = target.c_type_byte_size(.longlong) }, |
| 1391 | .c_ulonglong => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ulonglong) }, | 1390 | .c_ulonglong => return .{ .scalar = target.c_type_byte_size(.ulonglong) }, |
| 1392 | .c_longdouble => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) }, | 1391 | .c_longdouble => return .{ .scalar = target.c_type_byte_size(.longdouble) }, |
| 1393 | 1392 | ||
| 1394 | .anyopaque, | 1393 | .anyopaque, |
| 1395 | .void, | 1394 | .void, |
| ... | @@ -1399,12 +1398,12 @@ pub fn abiSizeAdvanced( | ... | @@ -1399,12 +1398,12 @@ pub fn abiSizeAdvanced( |
| 1399 | .null, | 1398 | .null, |
| 1400 | .undefined, | 1399 | .undefined, |
| 1401 | .enum_literal, | 1400 | .enum_literal, |
| 1402 | => return AbiSizeAdvanced{ .scalar = 0 }, | 1401 | => return .{ .scalar = 0 }, |
| 1403 | 1402 | ||
| 1404 | .anyerror, .adhoc_inferred_error_set => { | 1403 | .anyerror, .adhoc_inferred_error_set => { |
| 1405 | const bits = mod.errorSetBits(); | 1404 | const bits = mod.errorSetBits(); |
| 1406 | if (bits == 0) return AbiSizeAdvanced{ .scalar = 0 }; | 1405 | if (bits == 0) return .{ .scalar = 0 }; |
| 1407 | return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target, use_llvm) }; | 1406 | return .{ .scalar = intAbiSize(bits, target, use_llvm) }; |
| 1408 | }, | 1407 | }, |
| 1409 | 1408 | ||
| 1410 | .prefetch_options => unreachable, // missing call to resolveTypeFields | 1409 | .prefetch_options => unreachable, // missing call to resolveTypeFields |
| ... | @@ -1418,22 +1417,22 @@ pub fn abiSizeAdvanced( | ... | @@ -1418,22 +1417,22 @@ pub fn abiSizeAdvanced( |
| 1418 | .struct_type => { | 1417 | .struct_type => { |
| 1419 | const struct_type = ip.loadStructType(ty.toIntern()); | 1418 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 1420 | switch (strat) { | 1419 | switch (strat) { |
| 1421 | .sema => try ty.resolveLayout(mod), | 1420 | .sema => try ty.resolveLayout(pt), |
| 1422 | .lazy => switch (struct_type.layout) { | 1421 | .lazy => switch (struct_type.layout) { |
| 1423 | .@"packed" => { | 1422 | .@"packed" => { |
| 1424 | if (struct_type.backingIntType(ip).* == .none) return .{ | 1423 | if (struct_type.backingIntType(ip).* == .none) return .{ |
| 1425 | .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1424 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1426 | .ty = .comptime_int_type, | 1425 | .ty = .comptime_int_type, |
| 1427 | .storage = .{ .lazy_size = ty.toIntern() }, | 1426 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1428 | } }))), | 1427 | } })), |
| 1429 | }; | 1428 | }; |
| 1430 | }, | 1429 | }, |
| 1431 | .auto, .@"extern" => { | 1430 | .auto, .@"extern" => { |
| 1432 | if (!struct_type.haveLayout(ip)) return .{ | 1431 | if (!struct_type.haveLayout(ip)) return .{ |
| 1433 | .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1432 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1434 | .ty = .comptime_int_type, | 1433 | .ty = .comptime_int_type, |
| 1435 | .storage = .{ .lazy_size = ty.toIntern() }, | 1434 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1436 | } }))), | 1435 | } })), |
| 1437 | }; | 1436 | }; |
| 1438 | }, | 1437 | }, |
| 1439 | }, | 1438 | }, |
| ... | @@ -1441,7 +1440,7 @@ pub fn abiSizeAdvanced( | ... | @@ -1441,7 +1440,7 @@ pub fn abiSizeAdvanced( |
| 1441 | } | 1440 | } |
| 1442 | switch (struct_type.layout) { | 1441 | switch (struct_type.layout) { |
| 1443 | .@"packed" => return .{ | 1442 | .@"packed" => return .{ |
| 1444 | .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(mod), | 1443 | .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(pt), |
| 1445 | }, | 1444 | }, |
| 1446 | .auto, .@"extern" => { | 1445 | .auto, .@"extern" => { |
| 1447 | assert(struct_type.haveLayout(ip)); | 1446 | assert(struct_type.haveLayout(ip)); |
| ... | @@ -1451,25 +1450,25 @@ pub fn abiSizeAdvanced( | ... | @@ -1451,25 +1450,25 @@ pub fn abiSizeAdvanced( |
| 1451 | }, | 1450 | }, |
| 1452 | .anon_struct_type => |tuple| { | 1451 | .anon_struct_type => |tuple| { |
| 1453 | switch (strat) { | 1452 | switch (strat) { |
| 1454 | .sema => try ty.resolveLayout(mod), | 1453 | .sema => try ty.resolveLayout(pt), |
| 1455 | .lazy, .eager => {}, | 1454 | .lazy, .eager => {}, |
| 1456 | } | 1455 | } |
| 1457 | const field_count = tuple.types.len; | 1456 | const field_count = tuple.types.len; |
| 1458 | if (field_count == 0) { | 1457 | if (field_count == 0) { |
| 1459 | return AbiSizeAdvanced{ .scalar = 0 }; | 1458 | return .{ .scalar = 0 }; |
| 1460 | } | 1459 | } |
| 1461 | return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, mod) }; | 1460 | return .{ .scalar = ty.structFieldOffset(field_count, pt) }; |
| 1462 | }, | 1461 | }, |
| 1463 | 1462 | ||
| 1464 | .union_type => { | 1463 | .union_type => { |
| 1465 | const union_type = ip.loadUnionType(ty.toIntern()); | 1464 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 1466 | switch (strat) { | 1465 | switch (strat) { |
| 1467 | .sema => try ty.resolveLayout(mod), | 1466 | .sema => try ty.resolveLayout(pt), |
| 1468 | .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{ | 1467 | .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{ |
| 1469 | .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1468 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1470 | .ty = .comptime_int_type, | 1469 | .ty = .comptime_int_type, |
| 1471 | .storage = .{ .lazy_size = ty.toIntern() }, | 1470 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1472 | } }))), | 1471 | } })), |
| 1473 | }, | 1472 | }, |
| 1474 | .eager => {}, | 1473 | .eager => {}, |
| 1475 | } | 1474 | } |
| ... | @@ -1478,7 +1477,7 @@ pub fn abiSizeAdvanced( | ... | @@ -1478,7 +1477,7 @@ pub fn abiSizeAdvanced( |
| 1478 | return .{ .scalar = union_type.size(ip).* }; | 1477 | return .{ .scalar = union_type.size(ip).* }; |
| 1479 | }, | 1478 | }, |
| 1480 | .opaque_type => unreachable, // no size available | 1479 | .opaque_type => unreachable, // no size available |
| 1481 | .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(mod) }, | 1480 | .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(pt) }, |
| 1482 | 1481 | ||
| 1483 | // values, not types | 1482 | // values, not types |
| 1484 | .undef, | 1483 | .undef, |
| ... | @@ -1507,36 +1506,37 @@ pub fn abiSizeAdvanced( | ... | @@ -1507,36 +1506,37 @@ pub fn abiSizeAdvanced( |
| 1507 | 1506 | ||
| 1508 | fn abiSizeAdvancedOptional( | 1507 | fn abiSizeAdvancedOptional( |
| 1509 | ty: Type, | 1508 | ty: Type, |
| 1510 | mod: *Module, | 1509 | pt: Zcu.PerThread, |
| 1511 | strat: ResolveStratLazy, | 1510 | strat: ResolveStratLazy, |
| 1512 | ) SemaError!AbiSizeAdvanced { | 1511 | ) SemaError!AbiSizeAdvanced { |
| 1512 | const mod = pt.zcu; | ||
| 1513 | const child_ty = ty.optionalChild(mod); | 1513 | const child_ty = ty.optionalChild(mod); |
| 1514 | 1514 | ||
| 1515 | if (child_ty.isNoReturn(mod)) { | 1515 | if (child_ty.isNoReturn(mod)) { |
| 1516 | return AbiSizeAdvanced{ .scalar = 0 }; | 1516 | return .{ .scalar = 0 }; |
| 1517 | } | 1517 | } |
| 1518 | 1518 | ||
| 1519 | if (!(child_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { | 1519 | if (!(child_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { |
| 1520 | error.NeedLazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1520 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1521 | .ty = .comptime_int_type, | 1521 | .ty = .comptime_int_type, |
| 1522 | .storage = .{ .lazy_size = ty.toIntern() }, | 1522 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1523 | } }))) }, | 1523 | } })) }, |
| 1524 | else => |e| return e, | 1524 | else => |e| return e, |
| 1525 | })) return AbiSizeAdvanced{ .scalar = 1 }; | 1525 | })) return .{ .scalar = 1 }; |
| 1526 | 1526 | ||
| 1527 | if (ty.optionalReprIsPayload(mod)) { | 1527 | if (ty.optionalReprIsPayload(mod)) { |
| 1528 | return abiSizeAdvanced(child_ty, mod, strat); | 1528 | return child_ty.abiSizeAdvanced(pt, strat); |
| 1529 | } | 1529 | } |
| 1530 | 1530 | ||
| 1531 | const payload_size = switch (try child_ty.abiSizeAdvanced(mod, strat)) { | 1531 | const payload_size = switch (try child_ty.abiSizeAdvanced(pt, strat)) { |
| 1532 | .scalar => |elem_size| elem_size, | 1532 | .scalar => |elem_size| elem_size, |
| 1533 | .val => switch (strat) { | 1533 | .val => switch (strat) { |
| 1534 | .sema => unreachable, | 1534 | .sema => unreachable, |
| 1535 | .eager => unreachable, | 1535 | .eager => unreachable, |
| 1536 | .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{ | 1536 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1537 | .ty = .comptime_int_type, | 1537 | .ty = .comptime_int_type, |
| 1538 | .storage = .{ .lazy_size = ty.toIntern() }, | 1538 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1539 | } }))) }, | 1539 | } })) }, |
| 1540 | }, | 1540 | }, |
| 1541 | }; | 1541 | }; |
| 1542 | 1542 | ||
| ... | @@ -1544,8 +1544,8 @@ fn abiSizeAdvancedOptional( | ... | @@ -1544,8 +1544,8 @@ fn abiSizeAdvancedOptional( |
| 1544 | // field and a boolean as the second. Since the child type's abi alignment is | 1544 | // field and a boolean as the second. Since the child type's abi alignment is |
| 1545 | // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal | 1545 | // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal |
| 1546 | // to the child type's ABI alignment. | 1546 | // to the child type's ABI alignment. |
| 1547 | return AbiSizeAdvanced{ | 1547 | return .{ |
| 1548 | .scalar = (child_ty.abiAlignment(mod).toByteUnits() orelse 0) + payload_size, | 1548 | .scalar = (child_ty.abiAlignment(pt).toByteUnits() orelse 0) + payload_size, |
| 1549 | }; | 1549 | }; |
| 1550 | } | 1550 | } |
| 1551 | 1551 | ||
| ... | @@ -1675,15 +1675,16 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 { | ... | @@ -1675,15 +1675,16 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 { |
| 1675 | }; | 1675 | }; |
| 1676 | } | 1676 | } |
| 1677 | 1677 | ||
| 1678 | pub fn bitSize(ty: Type, mod: *Module) u64 { | 1678 | pub fn bitSize(ty: Type, pt: Zcu.PerThread) u64 { |
| 1679 | return bitSizeAdvanced(ty, mod, .normal) catch unreachable; | 1679 | return bitSizeAdvanced(ty, pt, .normal) catch unreachable; |
| 1680 | } | 1680 | } |
| 1681 | 1681 | ||
| 1682 | pub fn bitSizeAdvanced( | 1682 | pub fn bitSizeAdvanced( |
| 1683 | ty: Type, | 1683 | ty: Type, |
| 1684 | mod: *Module, | 1684 | pt: Zcu.PerThread, |
| 1685 | strat: ResolveStrat, | 1685 | strat: ResolveStrat, |
| 1686 | ) SemaError!u64 { | 1686 | ) SemaError!u64 { |
| 1687 | const mod = pt.zcu; | ||
| 1687 | const target = mod.getTarget(); | 1688 | const target = mod.getTarget(); |
| 1688 | const ip = &mod.intern_pool; | 1689 | const ip = &mod.intern_pool; |
| 1689 | 1690 | ||
| ... | @@ -1702,22 +1703,22 @@ pub fn bitSizeAdvanced( | ... | @@ -1702,22 +1703,22 @@ pub fn bitSizeAdvanced( |
| 1702 | if (len == 0) return 0; | 1703 | if (len == 0) return 0; |
| 1703 | const elem_ty = Type.fromInterned(array_type.child); | 1704 | const elem_ty = Type.fromInterned(array_type.child); |
| 1704 | const elem_size = @max( | 1705 | const elem_size = @max( |
| 1705 | (try elem_ty.abiAlignmentAdvanced(mod, strat_lazy)).scalar.toByteUnits() orelse 0, | 1706 | (try elem_ty.abiAlignmentAdvanced(pt, strat_lazy)).scalar.toByteUnits() orelse 0, |
| 1706 | (try elem_ty.abiSizeAdvanced(mod, strat_lazy)).scalar, | 1707 | (try elem_ty.abiSizeAdvanced(pt, strat_lazy)).scalar, |
| 1707 | ); | 1708 | ); |
| 1708 | if (elem_size == 0) return 0; | 1709 | if (elem_size == 0) return 0; |
| 1709 | const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, strat); | 1710 | const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, strat); |
| 1710 | return (len - 1) * 8 * elem_size + elem_bit_size; | 1711 | return (len - 1) * 8 * elem_size + elem_bit_size; |
| 1711 | }, | 1712 | }, |
| 1712 | .vector_type => |vector_type| { | 1713 | .vector_type => |vector_type| { |
| 1713 | const child_ty = Type.fromInterned(vector_type.child); | 1714 | const child_ty = Type.fromInterned(vector_type.child); |
| 1714 | const elem_bit_size = try bitSizeAdvanced(child_ty, mod, strat); | 1715 | const elem_bit_size = try child_ty.bitSizeAdvanced(pt, strat); |
| 1715 | return elem_bit_size * vector_type.len; | 1716 | return elem_bit_size * vector_type.len; |
| 1716 | }, | 1717 | }, |
| 1717 | .opt_type => { | 1718 | .opt_type => { |
| 1718 | // Optionals and error unions are not packed so their bitsize | 1719 | // Optionals and error unions are not packed so their bitsize |
| 1719 | // includes padding bits. | 1720 | // includes padding bits. |
| 1720 | return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8; | 1721 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; |
| 1721 | }, | 1722 | }, |
| 1722 | 1723 | ||
| 1723 | .error_set_type, .inferred_error_set_type => return mod.errorSetBits(), | 1724 | .error_set_type, .inferred_error_set_type => return mod.errorSetBits(), |
| ... | @@ -1725,7 +1726,7 @@ pub fn bitSizeAdvanced( | ... | @@ -1725,7 +1726,7 @@ pub fn bitSizeAdvanced( |
| 1725 | .error_union_type => { | 1726 | .error_union_type => { |
| 1726 | // Optionals and error unions are not packed so their bitsize | 1727 | // Optionals and error unions are not packed so their bitsize |
| 1727 | // includes padding bits. | 1728 | // includes padding bits. |
| 1728 | return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8; | 1729 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; |
| 1729 | }, | 1730 | }, |
| 1730 | .func_type => unreachable, // represents machine code; not a pointer | 1731 | .func_type => unreachable, // represents machine code; not a pointer |
| 1731 | .simple_type => |t| switch (t) { | 1732 | .simple_type => |t| switch (t) { |
| ... | @@ -1783,42 +1784,42 @@ pub fn bitSizeAdvanced( | ... | @@ -1783,42 +1784,42 @@ pub fn bitSizeAdvanced( |
| 1783 | const struct_type = ip.loadStructType(ty.toIntern()); | 1784 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 1784 | const is_packed = struct_type.layout == .@"packed"; | 1785 | const is_packed = struct_type.layout == .@"packed"; |
| 1785 | if (strat == .sema) { | 1786 | if (strat == .sema) { |
| 1786 | try ty.resolveFields(mod); | 1787 | try ty.resolveFields(pt); |
| 1787 | if (is_packed) try ty.resolveLayout(mod); | 1788 | if (is_packed) try ty.resolveLayout(pt); |
| 1788 | } | 1789 | } |
| 1789 | if (is_packed) { | 1790 | if (is_packed) { |
| 1790 | return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(mod, strat); | 1791 | return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(pt, strat); |
| 1791 | } | 1792 | } |
| 1792 | return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8; | 1793 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; |
| 1793 | }, | 1794 | }, |
| 1794 | 1795 | ||
| 1795 | .anon_struct_type => { | 1796 | .anon_struct_type => { |
| 1796 | if (strat == .sema) try ty.resolveFields(mod); | 1797 | if (strat == .sema) try ty.resolveFields(pt); |
| 1797 | return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8; | 1798 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; |
| 1798 | }, | 1799 | }, |
| 1799 | 1800 | ||
| 1800 | .union_type => { | 1801 | .union_type => { |
| 1801 | const union_type = ip.loadUnionType(ty.toIntern()); | 1802 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 1802 | const is_packed = ty.containerLayout(mod) == .@"packed"; | 1803 | const is_packed = ty.containerLayout(mod) == .@"packed"; |
| 1803 | if (strat == .sema) { | 1804 | if (strat == .sema) { |
| 1804 | try ty.resolveFields(mod); | 1805 | try ty.resolveFields(pt); |
| 1805 | if (is_packed) try ty.resolveLayout(mod); | 1806 | if (is_packed) try ty.resolveLayout(pt); |
| 1806 | } | 1807 | } |
| 1807 | if (!is_packed) { | 1808 | if (!is_packed) { |
| 1808 | return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8; | 1809 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; |
| 1809 | } | 1810 | } |
| 1810 | assert(union_type.flagsPtr(ip).status.haveFieldTypes()); | 1811 | assert(union_type.flagsPtr(ip).status.haveFieldTypes()); |
| 1811 | 1812 | ||
| 1812 | var size: u64 = 0; | 1813 | var size: u64 = 0; |
| 1813 | for (0..union_type.field_types.len) |field_index| { | 1814 | for (0..union_type.field_types.len) |field_index| { |
| 1814 | const field_ty = union_type.field_types.get(ip)[field_index]; | 1815 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| 1815 | size = @max(size, try bitSizeAdvanced(Type.fromInterned(field_ty), mod, strat)); | 1816 | size = @max(size, try Type.fromInterned(field_ty).bitSizeAdvanced(pt, strat)); |
| 1816 | } | 1817 | } |
| 1817 | 1818 | ||
| 1818 | return size; | 1819 | return size; |
| 1819 | }, | 1820 | }, |
| 1820 | .opaque_type => unreachable, | 1821 | .opaque_type => unreachable, |
| 1821 | .enum_type => return bitSizeAdvanced(Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), mod, strat), | 1822 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).bitSizeAdvanced(pt, strat), |
| 1822 | 1823 | ||
| 1823 | // values, not types | 1824 | // values, not types |
| 1824 | .undef, | 1825 | .undef, |
| ... | @@ -1870,7 +1871,7 @@ pub fn isSinglePointer(ty: Type, mod: *const Module) bool { | ... | @@ -1870,7 +1871,7 @@ pub fn isSinglePointer(ty: Type, mod: *const Module) bool { |
| 1870 | 1871 | ||
| 1871 | /// Asserts `ty` is a pointer. | 1872 | /// Asserts `ty` is a pointer. |
| 1872 | pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size { | 1873 | pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size { |
| 1873 | return ptrSizeOrNull(ty, mod).?; | 1874 | return ty.ptrSizeOrNull(mod).?; |
| 1874 | } | 1875 | } |
| 1875 | 1876 | ||
| 1876 | /// Returns `null` if `ty` is not a pointer. | 1877 | /// Returns `null` if `ty` is not a pointer. |
| ... | @@ -2105,29 +2106,28 @@ pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { | ... | @@ -2105,29 +2106,28 @@ pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { |
| 2105 | return mod.unionTagFieldIndex(union_obj, enum_tag); | 2106 | return mod.unionTagFieldIndex(union_obj, enum_tag); |
| 2106 | } | 2107 | } |
| 2107 | 2108 | ||
| 2108 | pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *Module) bool { | 2109 | pub fn unionHasAllZeroBitFieldTypes(ty: Type, pt: Zcu.PerThread) bool { |
| 2109 | const ip = &mod.intern_pool; | 2110 | const ip = &pt.zcu.intern_pool; |
| 2110 | const union_obj = mod.typeToUnion(ty).?; | 2111 | const union_obj = pt.zcu.typeToUnion(ty).?; |
| 2111 | for (union_obj.field_types.get(ip)) |field_ty| { | 2112 | for (union_obj.field_types.get(ip)) |field_ty| { |
| 2112 | if (Type.fromInterned(field_ty).hasRuntimeBits(mod)) return false; | 2113 | if (Type.fromInterned(field_ty).hasRuntimeBits(pt)) return false; |
| 2113 | } | 2114 | } |
| 2114 | return true; | 2115 | return true; |
| 2115 | } | 2116 | } |
| 2116 | 2117 | ||
| 2117 | /// Returns the type used for backing storage of this union during comptime operations. | 2118 | /// Returns the type used for backing storage of this union during comptime operations. |
| 2118 | /// Asserts the type is either an extern or packed union. | 2119 | /// Asserts the type is either an extern or packed union. |
| 2119 | pub fn unionBackingType(ty: Type, mod: *Module) !Type { | 2120 | pub fn unionBackingType(ty: Type, pt: Zcu.PerThread) !Type { |
| 2120 | return switch (ty.containerLayout(mod)) { | 2121 | return switch (ty.containerLayout(pt.zcu)) { |
| 2121 | .@"extern" => try mod.arrayType(.{ .len = ty.abiSize(mod), .child = .u8_type }), | 2122 | .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(pt), .child = .u8_type }), |
| 2122 | .@"packed" => try mod.intType(.unsigned, @intCast(ty.bitSize(mod))), | 2123 | .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(pt))), |
| 2123 | .auto => unreachable, | 2124 | .auto => unreachable, |
| 2124 | }; | 2125 | }; |
| 2125 | } | 2126 | } |
| 2126 | 2127 | ||
| 2127 | pub fn unionGetLayout(ty: Type, mod: *Module) Module.UnionLayout { | 2128 | pub fn unionGetLayout(ty: Type, pt: Zcu.PerThread) Module.UnionLayout { |
| 2128 | const ip = &mod.intern_pool; | 2129 | const union_obj = pt.zcu.intern_pool.loadUnionType(ty.toIntern()); |
| 2129 | const union_obj = ip.loadUnionType(ty.toIntern()); | 2130 | return pt.getUnionLayout(union_obj); |
| 2130 | return mod.getUnionLayout(union_obj); | ||
| 2131 | } | 2131 | } |
| 2132 | 2132 | ||
| 2133 | pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout { | 2133 | pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout { |
| ... | @@ -2509,7 +2509,8 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool { | ... | @@ -2509,7 +2509,8 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool { |
| 2509 | 2509 | ||
| 2510 | /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which | 2510 | /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which |
| 2511 | /// resolves field types rather than asserting they are already resolved. | 2511 | /// resolves field types rather than asserting they are already resolved. |
| 2512 | pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | 2512 | pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2513 | const mod = pt.zcu; | ||
| 2513 | var ty = starting_type; | 2514 | var ty = starting_type; |
| 2514 | const ip = &mod.intern_pool; | 2515 | const ip = &mod.intern_pool; |
| 2515 | while (true) switch (ty.toIntern()) { | 2516 | while (true) switch (ty.toIntern()) { |
| ... | @@ -2518,7 +2519,7 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2518,7 +2519,7 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2518 | else => switch (ip.indexToKey(ty.toIntern())) { | 2519 | else => switch (ip.indexToKey(ty.toIntern())) { |
| 2519 | .int_type => |int_type| { | 2520 | .int_type => |int_type| { |
| 2520 | if (int_type.bits == 0) { | 2521 | if (int_type.bits == 0) { |
| 2521 | return try mod.intValue(ty, 0); | 2522 | return try pt.intValue(ty, 0); |
| 2522 | } else { | 2523 | } else { |
| 2523 | return null; | 2524 | return null; |
| 2524 | } | 2525 | } |
| ... | @@ -2534,21 +2535,21 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2534,21 +2535,21 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2534 | 2535 | ||
| 2535 | inline .array_type, .vector_type => |seq_type, seq_tag| { | 2536 | inline .array_type, .vector_type => |seq_type, seq_tag| { |
| 2536 | const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none; | 2537 | const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none; |
| 2537 | if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2538 | if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2538 | .ty = ty.toIntern(), | 2539 | .ty = ty.toIntern(), |
| 2539 | .storage = .{ .elems = &.{} }, | 2540 | .storage = .{ .elems = &.{} }, |
| 2540 | } }))); | 2541 | } })); |
| 2541 | if (try Type.fromInterned(seq_type.child).onePossibleValue(mod)) |opv| { | 2542 | if (try Type.fromInterned(seq_type.child).onePossibleValue(pt)) |opv| { |
| 2542 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2543 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2543 | .ty = ty.toIntern(), | 2544 | .ty = ty.toIntern(), |
| 2544 | .storage = .{ .repeated_elem = opv.toIntern() }, | 2545 | .storage = .{ .repeated_elem = opv.toIntern() }, |
| 2545 | } }))); | 2546 | } })); |
| 2546 | } | 2547 | } |
| 2547 | return null; | 2548 | return null; |
| 2548 | }, | 2549 | }, |
| 2549 | .opt_type => |child| { | 2550 | .opt_type => |child| { |
| 2550 | if (child == .noreturn_type) { | 2551 | if (child == .noreturn_type) { |
| 2551 | return try mod.nullValue(ty); | 2552 | return try pt.nullValue(ty); |
| 2552 | } else { | 2553 | } else { |
| 2553 | return null; | 2554 | return null; |
| 2554 | } | 2555 | } |
| ... | @@ -2615,17 +2616,17 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2615,17 +2616,17 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2615 | continue; | 2616 | continue; |
| 2616 | } | 2617 | } |
| 2617 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 2618 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 2618 | if (try field_ty.onePossibleValue(mod)) |field_opv| { | 2619 | if (try field_ty.onePossibleValue(pt)) |field_opv| { |
| 2619 | field_val.* = field_opv.toIntern(); | 2620 | field_val.* = field_opv.toIntern(); |
| 2620 | } else return null; | 2621 | } else return null; |
| 2621 | } | 2622 | } |
| 2622 | 2623 | ||
| 2623 | // In this case the struct has no runtime-known fields and | 2624 | // In this case the struct has no runtime-known fields and |
| 2624 | // therefore has one possible value. | 2625 | // therefore has one possible value. |
| 2625 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2626 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2626 | .ty = ty.toIntern(), | 2627 | .ty = ty.toIntern(), |
| 2627 | .storage = .{ .elems = field_vals }, | 2628 | .storage = .{ .elems = field_vals }, |
| 2628 | } }))); | 2629 | } })); |
| 2629 | }, | 2630 | }, |
| 2630 | 2631 | ||
| 2631 | .anon_struct_type => |tuple| { | 2632 | .anon_struct_type => |tuple| { |
| ... | @@ -2637,24 +2638,24 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2637,24 +2638,24 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2637 | // TODO: write something like getCoercedInts to avoid needing to dupe | 2638 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 2638 | const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip)); | 2639 | const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip)); |
| 2639 | defer mod.gpa.free(duped_values); | 2640 | defer mod.gpa.free(duped_values); |
| 2640 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2641 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2641 | .ty = ty.toIntern(), | 2642 | .ty = ty.toIntern(), |
| 2642 | .storage = .{ .elems = duped_values }, | 2643 | .storage = .{ .elems = duped_values }, |
| 2643 | } }))); | 2644 | } })); |
| 2644 | }, | 2645 | }, |
| 2645 | 2646 | ||
| 2646 | .union_type => { | 2647 | .union_type => { |
| 2647 | const union_obj = ip.loadUnionType(ty.toIntern()); | 2648 | const union_obj = ip.loadUnionType(ty.toIntern()); |
| 2648 | const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(mod)) orelse | 2649 | const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(pt)) orelse |
| 2649 | return null; | 2650 | return null; |
| 2650 | if (union_obj.field_types.len == 0) { | 2651 | if (union_obj.field_types.len == 0) { |
| 2651 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | 2652 | const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() }); |
| 2652 | return Value.fromInterned(only); | 2653 | return Value.fromInterned(only); |
| 2653 | } | 2654 | } |
| 2654 | const only_field_ty = union_obj.field_types.get(ip)[0]; | 2655 | const only_field_ty = union_obj.field_types.get(ip)[0]; |
| 2655 | const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(mod)) orelse | 2656 | const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(pt)) orelse |
| 2656 | return null; | 2657 | return null; |
| 2657 | const only = try mod.intern(.{ .un = .{ | 2658 | const only = try pt.intern(.{ .un = .{ |
| 2658 | .ty = ty.toIntern(), | 2659 | .ty = ty.toIntern(), |
| 2659 | .tag = tag_val.toIntern(), | 2660 | .tag = tag_val.toIntern(), |
| 2660 | .val = val_val.toIntern(), | 2661 | .val = val_val.toIntern(), |
| ... | @@ -2668,8 +2669,8 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2668,8 +2669,8 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2668 | .nonexhaustive => { | 2669 | .nonexhaustive => { |
| 2669 | if (enum_type.tag_ty == .comptime_int_type) return null; | 2670 | if (enum_type.tag_ty == .comptime_int_type) return null; |
| 2670 | 2671 | ||
| 2671 | if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(mod)) |int_opv| { | 2672 | if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(pt)) |int_opv| { |
| 2672 | const only = try mod.intern(.{ .enum_tag = .{ | 2673 | const only = try pt.intern(.{ .enum_tag = .{ |
| 2673 | .ty = ty.toIntern(), | 2674 | .ty = ty.toIntern(), |
| 2674 | .int = int_opv.toIntern(), | 2675 | .int = int_opv.toIntern(), |
| 2675 | } }); | 2676 | } }); |
| ... | @@ -2679,18 +2680,18 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2679,18 +2680,18 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2679 | return null; | 2680 | return null; |
| 2680 | }, | 2681 | }, |
| 2681 | .auto, .explicit => { | 2682 | .auto, .explicit => { |
| 2682 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(mod)) return null; | 2683 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null; |
| 2683 | 2684 | ||
| 2684 | switch (enum_type.names.len) { | 2685 | switch (enum_type.names.len) { |
| 2685 | 0 => { | 2686 | 0 => { |
| 2686 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | 2687 | const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() }); |
| 2687 | return Value.fromInterned(only); | 2688 | return Value.fromInterned(only); |
| 2688 | }, | 2689 | }, |
| 2689 | 1 => { | 2690 | 1 => { |
| 2690 | if (enum_type.values.len == 0) { | 2691 | if (enum_type.values.len == 0) { |
| 2691 | const only = try mod.intern(.{ .enum_tag = .{ | 2692 | const only = try pt.intern(.{ .enum_tag = .{ |
| 2692 | .ty = ty.toIntern(), | 2693 | .ty = ty.toIntern(), |
| 2693 | .int = try mod.intern(.{ .int = .{ | 2694 | .int = try pt.intern(.{ .int = .{ |
| 2694 | .ty = enum_type.tag_ty, | 2695 | .ty = enum_type.tag_ty, |
| 2695 | .storage = .{ .u64 = 0 }, | 2696 | .storage = .{ .u64 = 0 }, |
| 2696 | } }), | 2697 | } }), |
| ... | @@ -2733,13 +2734,14 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { | ... | @@ -2733,13 +2734,14 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 2733 | 2734 | ||
| 2734 | /// During semantic analysis, instead call `Sema.typeRequiresComptime` which | 2735 | /// During semantic analysis, instead call `Sema.typeRequiresComptime` which |
| 2735 | /// resolves field types rather than asserting they are already resolved. | 2736 | /// resolves field types rather than asserting they are already resolved. |
| 2736 | pub fn comptimeOnly(ty: Type, mod: *Module) bool { | 2737 | pub fn comptimeOnly(ty: Type, pt: Zcu.PerThread) bool { |
| 2737 | return ty.comptimeOnlyAdvanced(mod, .normal) catch unreachable; | 2738 | return ty.comptimeOnlyAdvanced(pt, .normal) catch unreachable; |
| 2738 | } | 2739 | } |
| 2739 | 2740 | ||
| 2740 | /// `generic_poison` will return false. | 2741 | /// `generic_poison` will return false. |
| 2741 | /// May return false negatives when structs and unions are having their field types resolved. | 2742 | /// May return false negatives when structs and unions are having their field types resolved. |
| 2742 | pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool { | 2743 | pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) SemaError!bool { |
| 2744 | const mod = pt.zcu; | ||
| 2743 | const ip = &mod.intern_pool; | 2745 | const ip = &mod.intern_pool; |
| 2744 | return switch (ty.toIntern()) { | 2746 | return switch (ty.toIntern()) { |
| 2745 | .empty_struct_type => false, | 2747 | .empty_struct_type => false, |
| ... | @@ -2749,19 +2751,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr | ... | @@ -2749,19 +2751,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr |
| 2749 | .ptr_type => |ptr_type| { | 2751 | .ptr_type => |ptr_type| { |
| 2750 | const child_ty = Type.fromInterned(ptr_type.child); | 2752 | const child_ty = Type.fromInterned(ptr_type.child); |
| 2751 | switch (child_ty.zigTypeTag(mod)) { | 2753 | switch (child_ty.zigTypeTag(mod)) { |
| 2752 | .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, strat), | 2754 | .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(pt, strat), |
| 2753 | .Opaque => return false, | 2755 | .Opaque => return false, |
| 2754 | else => return child_ty.comptimeOnlyAdvanced(mod, strat), | 2756 | else => return child_ty.comptimeOnlyAdvanced(pt, strat), |
| 2755 | } | 2757 | } |
| 2756 | }, | 2758 | }, |
| 2757 | .anyframe_type => |child| { | 2759 | .anyframe_type => |child| { |
| 2758 | if (child == .none) return false; | 2760 | if (child == .none) return false; |
| 2759 | return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat); | 2761 | return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat); |
| 2760 | }, | 2762 | }, |
| 2761 | .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, strat), | 2763 | .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(pt, strat), |
| 2762 | .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, strat), | 2764 | .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(pt, strat), |
| 2763 | .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat), | 2765 | .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat), |
| 2764 | .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, strat), | 2766 | .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(pt, strat), |
| 2765 | 2767 | ||
| 2766 | .error_set_type, | 2768 | .error_set_type, |
| 2767 | .inferred_error_set_type, | 2769 | .inferred_error_set_type, |
| ... | @@ -2836,13 +2838,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr | ... | @@ -2836,13 +2838,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr |
| 2836 | struct_type.flagsPtr(ip).requires_comptime = .wip; | 2838 | struct_type.flagsPtr(ip).requires_comptime = .wip; |
| 2837 | errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown; | 2839 | errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown; |
| 2838 | 2840 | ||
| 2839 | try ty.resolveFields(mod); | 2841 | try ty.resolveFields(pt); |
| 2840 | 2842 | ||
| 2841 | for (0..struct_type.field_types.len) |i_usize| { | 2843 | for (0..struct_type.field_types.len) |i_usize| { |
| 2842 | const i: u32 = @intCast(i_usize); | 2844 | const i: u32 = @intCast(i_usize); |
| 2843 | if (struct_type.fieldIsComptime(ip, i)) continue; | 2845 | if (struct_type.fieldIsComptime(ip, i)) continue; |
| 2844 | const field_ty = struct_type.field_types.get(ip)[i]; | 2846 | const field_ty = struct_type.field_types.get(ip)[i]; |
| 2845 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) { | 2847 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) { |
| 2846 | // Note that this does not cause the layout to | 2848 | // Note that this does not cause the layout to |
| 2847 | // be considered resolved. Comptime-only types | 2849 | // be considered resolved. Comptime-only types |
| 2848 | // still maintain a layout of their | 2850 | // still maintain a layout of their |
| ... | @@ -2861,7 +2863,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr | ... | @@ -2861,7 +2863,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr |
| 2861 | .anon_struct_type => |tuple| { | 2863 | .anon_struct_type => |tuple| { |
| 2862 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { | 2864 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 2863 | const have_comptime_val = val != .none; | 2865 | const have_comptime_val = val != .none; |
| 2864 | if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) return true; | 2866 | if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) return true; |
| 2865 | } | 2867 | } |
| 2866 | return false; | 2868 | return false; |
| 2867 | }, | 2869 | }, |
| ... | @@ -2880,11 +2882,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr | ... | @@ -2880,11 +2882,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr |
| 2880 | union_type.flagsPtr(ip).requires_comptime = .wip; | 2882 | union_type.flagsPtr(ip).requires_comptime = .wip; |
| 2881 | errdefer union_type.flagsPtr(ip).requires_comptime = .unknown; | 2883 | errdefer union_type.flagsPtr(ip).requires_comptime = .unknown; |
| 2882 | 2884 | ||
| 2883 | try ty.resolveFields(mod); | 2885 | try ty.resolveFields(pt); |
| 2884 | 2886 | ||
| 2885 | for (0..union_type.field_types.len) |field_idx| { | 2887 | for (0..union_type.field_types.len) |field_idx| { |
| 2886 | const field_ty = union_type.field_types.get(ip)[field_idx]; | 2888 | const field_ty = union_type.field_types.get(ip)[field_idx]; |
| 2887 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) { | 2889 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) { |
| 2888 | union_type.flagsPtr(ip).requires_comptime = .yes; | 2890 | union_type.flagsPtr(ip).requires_comptime = .yes; |
| 2889 | return true; | 2891 | return true; |
| 2890 | } | 2892 | } |
| ... | @@ -2898,7 +2900,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr | ... | @@ -2898,7 +2900,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaErr |
| 2898 | 2900 | ||
| 2899 | .opaque_type => false, | 2901 | .opaque_type => false, |
| 2900 | 2902 | ||
| 2901 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(mod, strat), | 2903 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(pt, strat), |
| 2902 | 2904 | ||
| 2903 | // values, not types | 2905 | // values, not types |
| 2904 | .undef, | 2906 | .undef, |
| ... | @@ -2930,10 +2932,10 @@ pub fn isVector(ty: Type, mod: *const Module) bool { | ... | @@ -2930,10 +2932,10 @@ pub fn isVector(ty: Type, mod: *const Module) bool { |
| 2930 | } | 2932 | } |
| 2931 | 2933 | ||
| 2932 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. | 2934 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. |
| 2933 | pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 { | 2935 | pub fn totalVectorBits(ty: Type, pt: Zcu.PerThread) u64 { |
| 2934 | if (!ty.isVector(zcu)) return 0; | 2936 | if (!ty.isVector(pt.zcu)) return 0; |
| 2935 | const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type; | 2937 | const v = pt.zcu.intern_pool.indexToKey(ty.toIntern()).vector_type; |
| 2936 | return v.len * Type.fromInterned(v.child).bitSize(zcu); | 2938 | return v.len * Type.fromInterned(v.child).bitSize(pt); |
| 2937 | } | 2939 | } |
| 2938 | 2940 | ||
| 2939 | pub fn isArrayOrVector(ty: Type, mod: *const Module) bool { | 2941 | pub fn isArrayOrVector(ty: Type, mod: *const Module) bool { |
| ... | @@ -3013,23 +3015,25 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex { | ... | @@ -3013,23 +3015,25 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex { |
| 3013 | } | 3015 | } |
| 3014 | 3016 | ||
| 3015 | // Works for vectors and vectors of integers. | 3017 | // Works for vectors and vectors of integers. |
| 3016 | pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value { | 3018 | pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 3017 | const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod)); | 3019 | const mod = pt.zcu; |
| 3018 | return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3020 | const scalar = try minIntScalar(ty.scalarType(mod), pt, dest_ty.scalarType(mod)); |
| 3021 | return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ | ||
| 3019 | .ty = dest_ty.toIntern(), | 3022 | .ty = dest_ty.toIntern(), |
| 3020 | .storage = .{ .repeated_elem = scalar.toIntern() }, | 3023 | .storage = .{ .repeated_elem = scalar.toIntern() }, |
| 3021 | } }))) else scalar; | 3024 | } })) else scalar; |
| 3022 | } | 3025 | } |
| 3023 | 3026 | ||
| 3024 | /// Asserts that the type is an integer. | 3027 | /// Asserts that the type is an integer. |
| 3025 | pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { | 3028 | pub fn minIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 3029 | const mod = pt.zcu; | ||
| 3026 | const info = ty.intInfo(mod); | 3030 | const info = ty.intInfo(mod); |
| 3027 | if (info.signedness == .unsigned) return mod.intValue(dest_ty, 0); | 3031 | if (info.signedness == .unsigned) return pt.intValue(dest_ty, 0); |
| 3028 | if (info.bits == 0) return mod.intValue(dest_ty, -1); | 3032 | if (info.bits == 0) return pt.intValue(dest_ty, -1); |
| 3029 | 3033 | ||
| 3030 | if (std.math.cast(u6, info.bits - 1)) |shift| { | 3034 | if (std.math.cast(u6, info.bits - 1)) |shift| { |
| 3031 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); | 3035 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); |
| 3032 | return mod.intValue(dest_ty, n); | 3036 | return pt.intValue(dest_ty, n); |
| 3033 | } | 3037 | } |
| 3034 | 3038 | ||
| 3035 | var res = try std.math.big.int.Managed.init(mod.gpa); | 3039 | var res = try std.math.big.int.Managed.init(mod.gpa); |
| ... | @@ -3037,31 +3041,32 @@ pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { | ... | @@ -3037,31 +3041,32 @@ pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { |
| 3037 | 3041 | ||
| 3038 | try res.setTwosCompIntLimit(.min, info.signedness, info.bits); | 3042 | try res.setTwosCompIntLimit(.min, info.signedness, info.bits); |
| 3039 | 3043 | ||
| 3040 | return mod.intValue_big(dest_ty, res.toConst()); | 3044 | return pt.intValue_big(dest_ty, res.toConst()); |
| 3041 | } | 3045 | } |
| 3042 | 3046 | ||
| 3043 | // Works for vectors and vectors of integers. | 3047 | // Works for vectors and vectors of integers. |
| 3044 | /// The returned Value will have type dest_ty. | 3048 | /// The returned Value will have type dest_ty. |
| 3045 | pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value { | 3049 | pub fn maxInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 3046 | const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty.scalarType(mod)); | 3050 | const mod = pt.zcu; |
| 3047 | return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3051 | const scalar = try maxIntScalar(ty.scalarType(mod), pt, dest_ty.scalarType(mod)); |
| 3052 | return if (ty.zigTypeTag(mod) == .Vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ | ||
| 3048 | .ty = dest_ty.toIntern(), | 3053 | .ty = dest_ty.toIntern(), |
| 3049 | .storage = .{ .repeated_elem = scalar.toIntern() }, | 3054 | .storage = .{ .repeated_elem = scalar.toIntern() }, |
| 3050 | } }))) else scalar; | 3055 | } })) else scalar; |
| 3051 | } | 3056 | } |
| 3052 | 3057 | ||
| 3053 | /// The returned Value will have type dest_ty. | 3058 | /// The returned Value will have type dest_ty. |
| 3054 | pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { | 3059 | pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 3055 | const info = ty.intInfo(mod); | 3060 | const info = ty.intInfo(pt.zcu); |
| 3056 | 3061 | ||
| 3057 | switch (info.bits) { | 3062 | switch (info.bits) { |
| 3058 | 0 => return switch (info.signedness) { | 3063 | 0 => return switch (info.signedness) { |
| 3059 | .signed => try mod.intValue(dest_ty, -1), | 3064 | .signed => try pt.intValue(dest_ty, -1), |
| 3060 | .unsigned => try mod.intValue(dest_ty, 0), | 3065 | .unsigned => try pt.intValue(dest_ty, 0), |
| 3061 | }, | 3066 | }, |
| 3062 | 1 => return switch (info.signedness) { | 3067 | 1 => return switch (info.signedness) { |
| 3063 | .signed => try mod.intValue(dest_ty, 0), | 3068 | .signed => try pt.intValue(dest_ty, 0), |
| 3064 | .unsigned => try mod.intValue(dest_ty, 1), | 3069 | .unsigned => try pt.intValue(dest_ty, 1), |
| 3065 | }, | 3070 | }, |
| 3066 | else => {}, | 3071 | else => {}, |
| 3067 | } | 3072 | } |
| ... | @@ -3069,20 +3074,20 @@ pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { | ... | @@ -3069,20 +3074,20 @@ pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { |
| 3069 | if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) { | 3074 | if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) { |
| 3070 | .signed => { | 3075 | .signed => { |
| 3071 | const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift); | 3076 | const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift); |
| 3072 | return mod.intValue(dest_ty, n); | 3077 | return pt.intValue(dest_ty, n); |
| 3073 | }, | 3078 | }, |
| 3074 | .unsigned => { | 3079 | .unsigned => { |
| 3075 | const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift); | 3080 | const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift); |
| 3076 | return mod.intValue(dest_ty, n); | 3081 | return pt.intValue(dest_ty, n); |
| 3077 | }, | 3082 | }, |
| 3078 | }; | 3083 | }; |
| 3079 | 3084 | ||
| 3080 | var res = try std.math.big.int.Managed.init(mod.gpa); | 3085 | var res = try std.math.big.int.Managed.init(pt.zcu.gpa); |
| 3081 | defer res.deinit(); | 3086 | defer res.deinit(); |
| 3082 | 3087 | ||
| 3083 | try res.setTwosCompIntLimit(.max, info.signedness, info.bits); | 3088 | try res.setTwosCompIntLimit(.max, info.signedness, info.bits); |
| 3084 | 3089 | ||
| 3085 | return mod.intValue_big(dest_ty, res.toConst()); | 3090 | return pt.intValue_big(dest_ty, res.toConst()); |
| 3086 | } | 3091 | } |
| 3087 | 3092 | ||
| 3088 | /// Asserts the type is an enum or a union. | 3093 | /// Asserts the type is an enum or a union. |
| ... | @@ -3188,26 +3193,26 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type { | ... | @@ -3188,26 +3193,26 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type { |
| 3188 | }; | 3193 | }; |
| 3189 | } | 3194 | } |
| 3190 | 3195 | ||
| 3191 | pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment { | 3196 | pub fn structFieldAlign(ty: Type, index: usize, pt: Zcu.PerThread) Alignment { |
| 3192 | return ty.structFieldAlignAdvanced(index, zcu, .normal) catch unreachable; | 3197 | return ty.structFieldAlignAdvanced(index, pt, .normal) catch unreachable; |
| 3193 | } | 3198 | } |
| 3194 | 3199 | ||
| 3195 | pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, strat: ResolveStrat) !Alignment { | 3200 | pub fn structFieldAlignAdvanced(ty: Type, index: usize, pt: Zcu.PerThread, strat: ResolveStrat) !Alignment { |
| 3196 | const ip = &zcu.intern_pool; | 3201 | const ip = &pt.zcu.intern_pool; |
| 3197 | switch (ip.indexToKey(ty.toIntern())) { | 3202 | switch (ip.indexToKey(ty.toIntern())) { |
| 3198 | .struct_type => { | 3203 | .struct_type => { |
| 3199 | const struct_type = ip.loadStructType(ty.toIntern()); | 3204 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 3200 | assert(struct_type.layout != .@"packed"); | 3205 | assert(struct_type.layout != .@"packed"); |
| 3201 | const explicit_align = struct_type.fieldAlign(ip, index); | 3206 | const explicit_align = struct_type.fieldAlign(ip, index); |
| 3202 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]); | 3207 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]); |
| 3203 | return zcu.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat); | 3208 | return pt.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat); |
| 3204 | }, | 3209 | }, |
| 3205 | .anon_struct_type => |anon_struct| { | 3210 | .anon_struct_type => |anon_struct| { |
| 3206 | return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(zcu, strat.toLazy())).scalar; | 3211 | return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(pt, strat.toLazy())).scalar; |
| 3207 | }, | 3212 | }, |
| 3208 | .union_type => { | 3213 | .union_type => { |
| 3209 | const union_obj = ip.loadUnionType(ty.toIntern()); | 3214 | const union_obj = ip.loadUnionType(ty.toIntern()); |
| 3210 | return zcu.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat); | 3215 | return pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat); |
| 3211 | }, | 3216 | }, |
| 3212 | else => unreachable, | 3217 | else => unreachable, |
| 3213 | } | 3218 | } |
| ... | @@ -3233,7 +3238,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { | ... | @@ -3233,7 +3238,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { |
| 3233 | } | 3238 | } |
| 3234 | } | 3239 | } |
| 3235 | 3240 | ||
| 3236 | pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { | 3241 | pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Value { |
| 3242 | const mod = pt.zcu; | ||
| 3237 | const ip = &mod.intern_pool; | 3243 | const ip = &mod.intern_pool; |
| 3238 | switch (ip.indexToKey(ty.toIntern())) { | 3244 | switch (ip.indexToKey(ty.toIntern())) { |
| 3239 | .struct_type => { | 3245 | .struct_type => { |
| ... | @@ -3242,13 +3248,13 @@ pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { | ... | @@ -3242,13 +3248,13 @@ pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { |
| 3242 | assert(struct_type.haveFieldInits(ip)); | 3248 | assert(struct_type.haveFieldInits(ip)); |
| 3243 | return Value.fromInterned(struct_type.field_inits.get(ip)[index]); | 3249 | return Value.fromInterned(struct_type.field_inits.get(ip)[index]); |
| 3244 | } else { | 3250 | } else { |
| 3245 | return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(mod); | 3251 | return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt); |
| 3246 | } | 3252 | } |
| 3247 | }, | 3253 | }, |
| 3248 | .anon_struct_type => |tuple| { | 3254 | .anon_struct_type => |tuple| { |
| 3249 | const val = tuple.values.get(ip)[index]; | 3255 | const val = tuple.values.get(ip)[index]; |
| 3250 | if (val == .none) { | 3256 | if (val == .none) { |
| 3251 | return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(mod); | 3257 | return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt); |
| 3252 | } else { | 3258 | } else { |
| 3253 | return Value.fromInterned(val); | 3259 | return Value.fromInterned(val); |
| 3254 | } | 3260 | } |
| ... | @@ -3272,7 +3278,8 @@ pub const FieldOffset = struct { | ... | @@ -3272,7 +3278,8 @@ pub const FieldOffset = struct { |
| 3272 | }; | 3278 | }; |
| 3273 | 3279 | ||
| 3274 | /// Supports structs and unions. | 3280 | /// Supports structs and unions. |
| 3275 | pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { | 3281 | pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { |
| 3282 | const mod = pt.zcu; | ||
| 3276 | const ip = &mod.intern_pool; | 3283 | const ip = &mod.intern_pool; |
| 3277 | switch (ip.indexToKey(ty.toIntern())) { | 3284 | switch (ip.indexToKey(ty.toIntern())) { |
| 3278 | .struct_type => { | 3285 | .struct_type => { |
| ... | @@ -3287,17 +3294,17 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { | ... | @@ -3287,17 +3294,17 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { |
| 3287 | var big_align: Alignment = .none; | 3294 | var big_align: Alignment = .none; |
| 3288 | 3295 | ||
| 3289 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { | 3296 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 3290 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) { | 3297 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) { |
| 3291 | // comptime field | 3298 | // comptime field |
| 3292 | if (i == index) return offset; | 3299 | if (i == index) return offset; |
| 3293 | continue; | 3300 | continue; |
| 3294 | } | 3301 | } |
| 3295 | 3302 | ||
| 3296 | const field_align = Type.fromInterned(field_ty).abiAlignment(mod); | 3303 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); |
| 3297 | big_align = big_align.max(field_align); | 3304 | big_align = big_align.max(field_align); |
| 3298 | offset = field_align.forward(offset); | 3305 | offset = field_align.forward(offset); |
| 3299 | if (i == index) return offset; | 3306 | if (i == index) return offset; |
| 3300 | offset += Type.fromInterned(field_ty).abiSize(mod); | 3307 | offset += Type.fromInterned(field_ty).abiSize(pt); |
| 3301 | } | 3308 | } |
| 3302 | offset = big_align.max(.@"1").forward(offset); | 3309 | offset = big_align.max(.@"1").forward(offset); |
| 3303 | return offset; | 3310 | return offset; |
| ... | @@ -3307,7 +3314,7 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { | ... | @@ -3307,7 +3314,7 @@ pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { |
| 3307 | const union_type = ip.loadUnionType(ty.toIntern()); | 3314 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 3308 | if (!union_type.hasTag(ip)) | 3315 | if (!union_type.hasTag(ip)) |
| 3309 | return 0; | 3316 | return 0; |
| 3310 | const layout = mod.getUnionLayout(union_type); | 3317 | const layout = pt.getUnionLayout(union_type); |
| 3311 | if (layout.tag_align.compare(.gte, layout.payload_align)) { | 3318 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| 3312 | // {Tag, Payload} | 3319 | // {Tag, Payload} |
| 3313 | return layout.payload_align.forward(layout.tag_size); | 3320 | return layout.payload_align.forward(layout.tag_size); |
| ... | @@ -3421,12 +3428,13 @@ pub fn optEuBaseType(ty: Type, mod: *Module) Type { | ... | @@ -3421,12 +3428,13 @@ pub fn optEuBaseType(ty: Type, mod: *Module) Type { |
| 3421 | }; | 3428 | }; |
| 3422 | } | 3429 | } |
| 3423 | 3430 | ||
| 3424 | pub fn toUnsigned(ty: Type, mod: *Module) !Type { | 3431 | pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type { |
| 3432 | const mod = pt.zcu; | ||
| 3425 | return switch (ty.zigTypeTag(mod)) { | 3433 | return switch (ty.zigTypeTag(mod)) { |
| 3426 | .Int => mod.intType(.unsigned, ty.intInfo(mod).bits), | 3434 | .Int => pt.intType(.unsigned, ty.intInfo(mod).bits), |
| 3427 | .Vector => try mod.vectorType(.{ | 3435 | .Vector => try pt.vectorType(.{ |
| 3428 | .len = ty.vectorLen(mod), | 3436 | .len = ty.vectorLen(mod), |
| 3429 | .child = (try ty.childType(mod).toUnsigned(mod)).toIntern(), | 3437 | .child = (try ty.childType(mod).toUnsigned(pt)).toIntern(), |
| 3430 | }), | 3438 | }), |
| 3431 | else => unreachable, | 3439 | else => unreachable, |
| 3432 | }; | 3440 | }; |
| ... | @@ -3492,7 +3500,7 @@ pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } { | ... | @@ -3492,7 +3500,7 @@ pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } { |
| 3492 | return .{ cur_ty, cur_len }; | 3500 | return .{ cur_ty, cur_len }; |
| 3493 | } | 3501 | } |
| 3494 | 3502 | ||
| 3495 | pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: u32, zcu: *Zcu) union(enum) { | 3503 | pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: u32, pt: Zcu.PerThread) union(enum) { |
| 3496 | /// The result is a bit-pointer with the same value and a new packed offset. | 3504 | /// The result is a bit-pointer with the same value and a new packed offset. |
| 3497 | bit_ptr: InternPool.Key.PtrType.PackedOffset, | 3505 | bit_ptr: InternPool.Key.PtrType.PackedOffset, |
| 3498 | /// The result is a standard pointer. | 3506 | /// The result is a standard pointer. |
| ... | @@ -3505,6 +3513,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: | ... | @@ -3505,6 +3513,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3505 | } { | 3513 | } { |
| 3506 | comptime assert(Type.packed_struct_layout_version == 2); | 3514 | comptime assert(Type.packed_struct_layout_version == 2); |
| 3507 | 3515 | ||
| 3516 | const zcu = pt.zcu; | ||
| 3508 | const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); | 3517 | const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); |
| 3509 | const field_ty = struct_ty.structFieldType(field_idx, zcu); | 3518 | const field_ty = struct_ty.structFieldType(field_idx, zcu); |
| 3510 | 3519 | ||
| ... | @@ -3515,7 +3524,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: | ... | @@ -3515,7 +3524,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3515 | if (i == field_idx) { | 3524 | if (i == field_idx) { |
| 3516 | bit_offset = running_bits; | 3525 | bit_offset = running_bits; |
| 3517 | } | 3526 | } |
| 3518 | running_bits += @intCast(f_ty.bitSize(zcu)); | 3527 | running_bits += @intCast(f_ty.bitSize(pt)); |
| 3519 | } | 3528 | } |
| 3520 | 3529 | ||
| 3521 | const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0) | 3530 | const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0) |
| ... | @@ -3532,9 +3541,9 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: | ... | @@ -3532,9 +3541,9 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3532 | // targets before adding the necessary complications to this code. This will not | 3541 | // targets before adding the necessary complications to this code. This will not |
| 3533 | // cause miscompilations; it only means the field pointer uses bit masking when it | 3542 | // cause miscompilations; it only means the field pointer uses bit masking when it |
| 3534 | // might not be strictly necessary. | 3543 | // might not be strictly necessary. |
| 3535 | if (res_bit_offset % 8 == 0 and field_ty.bitSize(zcu) == field_ty.abiSize(zcu) * 8 and zcu.getTarget().cpu.arch.endian() == .little) { | 3544 | if (res_bit_offset % 8 == 0 and field_ty.bitSize(pt) == field_ty.abiSize(pt) * 8 and zcu.getTarget().cpu.arch.endian() == .little) { |
| 3536 | const byte_offset = res_bit_offset / 8; | 3545 | const byte_offset = res_bit_offset / 8; |
| 3537 | const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(zcu).toByteUnits().?)); | 3546 | const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(pt).toByteUnits().?)); |
| 3538 | return .{ .byte_ptr = .{ | 3547 | return .{ .byte_ptr = .{ |
| 3539 | .offset = byte_offset, | 3548 | .offset = byte_offset, |
| 3540 | .alignment = new_align, | 3549 | .alignment = new_align, |
| ... | @@ -3547,34 +3556,35 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: | ... | @@ -3547,34 +3556,35 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3547 | } }; | 3556 | } }; |
| 3548 | } | 3557 | } |
| 3549 | 3558 | ||
| 3550 | pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void { | 3559 | pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3560 | const zcu = pt.zcu; | ||
| 3551 | const ip = &zcu.intern_pool; | 3561 | const ip = &zcu.intern_pool; |
| 3552 | switch (ip.indexToKey(ty.toIntern())) { | 3562 | switch (ip.indexToKey(ty.toIntern())) { |
| 3553 | .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu), | 3563 | .simple_type => |simple_type| return resolveSimpleType(simple_type, pt), |
| 3554 | else => {}, | 3564 | else => {}, |
| 3555 | } | 3565 | } |
| 3556 | switch (ty.zigTypeTag(zcu)) { | 3566 | switch (ty.zigTypeTag(zcu)) { |
| 3557 | .Struct => switch (ip.indexToKey(ty.toIntern())) { | 3567 | .Struct => switch (ip.indexToKey(ty.toIntern())) { |
| 3558 | .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| { | 3568 | .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| { |
| 3559 | const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]); | 3569 | const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]); |
| 3560 | try field_ty.resolveLayout(zcu); | 3570 | try field_ty.resolveLayout(pt); |
| 3561 | }, | 3571 | }, |
| 3562 | .struct_type => return ty.resolveStructInner(zcu, .layout), | 3572 | .struct_type => return ty.resolveStructInner(pt, .layout), |
| 3563 | else => unreachable, | 3573 | else => unreachable, |
| 3564 | }, | 3574 | }, |
| 3565 | .Union => return ty.resolveUnionInner(zcu, .layout), | 3575 | .Union => return ty.resolveUnionInner(pt, .layout), |
| 3566 | .Array => { | 3576 | .Array => { |
| 3567 | if (ty.arrayLenIncludingSentinel(zcu) == 0) return; | 3577 | if (ty.arrayLenIncludingSentinel(zcu) == 0) return; |
| 3568 | const elem_ty = ty.childType(zcu); | 3578 | const elem_ty = ty.childType(zcu); |
| 3569 | return elem_ty.resolveLayout(zcu); | 3579 | return elem_ty.resolveLayout(pt); |
| 3570 | }, | 3580 | }, |
| 3571 | .Optional => { | 3581 | .Optional => { |
| 3572 | const payload_ty = ty.optionalChild(zcu); | 3582 | const payload_ty = ty.optionalChild(zcu); |
| 3573 | return payload_ty.resolveLayout(zcu); | 3583 | return payload_ty.resolveLayout(pt); |
| 3574 | }, | 3584 | }, |
| 3575 | .ErrorUnion => { | 3585 | .ErrorUnion => { |
| 3576 | const payload_ty = ty.errorUnionPayload(zcu); | 3586 | const payload_ty = ty.errorUnionPayload(zcu); |
| 3577 | return payload_ty.resolveLayout(zcu); | 3587 | return payload_ty.resolveLayout(pt); |
| 3578 | }, | 3588 | }, |
| 3579 | .Fn => { | 3589 | .Fn => { |
| 3580 | const info = zcu.typeToFunc(ty).?; | 3590 | const info = zcu.typeToFunc(ty).?; |
| ... | @@ -3585,16 +3595,16 @@ pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void { | ... | @@ -3585,16 +3595,16 @@ pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void { |
| 3585 | } | 3595 | } |
| 3586 | for (0..info.param_types.len) |i| { | 3596 | for (0..info.param_types.len) |i| { |
| 3587 | const param_ty = info.param_types.get(ip)[i]; | 3597 | const param_ty = info.param_types.get(ip)[i]; |
| 3588 | try Type.fromInterned(param_ty).resolveLayout(zcu); | 3598 | try Type.fromInterned(param_ty).resolveLayout(pt); |
| 3589 | } | 3599 | } |
| 3590 | try Type.fromInterned(info.return_type).resolveLayout(zcu); | 3600 | try Type.fromInterned(info.return_type).resolveLayout(pt); |
| 3591 | }, | 3601 | }, |
| 3592 | else => {}, | 3602 | else => {}, |
| 3593 | } | 3603 | } |
| 3594 | } | 3604 | } |
| 3595 | 3605 | ||
| 3596 | pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void { | 3606 | pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3597 | const ip = &zcu.intern_pool; | 3607 | const ip = &pt.zcu.intern_pool; |
| 3598 | const ty_ip = ty.toIntern(); | 3608 | const ty_ip = ty.toIntern(); |
| 3599 | 3609 | ||
| 3600 | switch (ty_ip) { | 3610 | switch (ty_ip) { |
| ... | @@ -3680,22 +3690,23 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void { | ... | @@ -3680,22 +3690,23 @@ pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void { |
| 3680 | .type_struct, | 3690 | .type_struct, |
| 3681 | .type_struct_packed, | 3691 | .type_struct_packed, |
| 3682 | .type_struct_packed_inits, | 3692 | .type_struct_packed_inits, |
| 3683 | => return ty.resolveStructInner(zcu, .fields), | 3693 | => return ty.resolveStructInner(pt, .fields), |
| 3684 | 3694 | ||
| 3685 | .type_union => return ty.resolveUnionInner(zcu, .fields), | 3695 | .type_union => return ty.resolveUnionInner(pt, .fields), |
| 3686 | 3696 | ||
| 3687 | .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, zcu), | 3697 | .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, pt), |
| 3688 | 3698 | ||
| 3689 | else => {}, | 3699 | else => {}, |
| 3690 | }, | 3700 | }, |
| 3691 | } | 3701 | } |
| 3692 | } | 3702 | } |
| 3693 | 3703 | ||
| 3694 | pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void { | 3704 | pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3705 | const zcu = pt.zcu; | ||
| 3695 | const ip = &zcu.intern_pool; | 3706 | const ip = &zcu.intern_pool; |
| 3696 | 3707 | ||
| 3697 | switch (ip.indexToKey(ty.toIntern())) { | 3708 | switch (ip.indexToKey(ty.toIntern())) { |
| 3698 | .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu), | 3709 | .simple_type => |simple_type| return resolveSimpleType(simple_type, pt), |
| 3699 | else => {}, | 3710 | else => {}, |
| 3700 | } | 3711 | } |
| 3701 | 3712 | ||
| ... | @@ -3719,52 +3730,53 @@ pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void { | ... | @@ -3719,52 +3730,53 @@ pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void { |
| 3719 | .EnumLiteral, | 3730 | .EnumLiteral, |
| 3720 | => {}, | 3731 | => {}, |
| 3721 | 3732 | ||
| 3722 | .Pointer => return ty.childType(zcu).resolveFully(zcu), | 3733 | .Pointer => return ty.childType(zcu).resolveFully(pt), |
| 3723 | .Array => return ty.childType(zcu).resolveFully(zcu), | 3734 | .Array => return ty.childType(zcu).resolveFully(pt), |
| 3724 | .Optional => return ty.optionalChild(zcu).resolveFully(zcu), | 3735 | .Optional => return ty.optionalChild(zcu).resolveFully(pt), |
| 3725 | .ErrorUnion => return ty.errorUnionPayload(zcu).resolveFully(zcu), | 3736 | .ErrorUnion => return ty.errorUnionPayload(zcu).resolveFully(pt), |
| 3726 | .Fn => { | 3737 | .Fn => { |
| 3727 | const info = zcu.typeToFunc(ty).?; | 3738 | const info = zcu.typeToFunc(ty).?; |
| 3728 | if (info.is_generic) return; | 3739 | if (info.is_generic) return; |
| 3729 | for (0..info.param_types.len) |i| { | 3740 | for (0..info.param_types.len) |i| { |
| 3730 | const param_ty = info.param_types.get(ip)[i]; | 3741 | const param_ty = info.param_types.get(ip)[i]; |
| 3731 | try Type.fromInterned(param_ty).resolveFully(zcu); | 3742 | try Type.fromInterned(param_ty).resolveFully(pt); |
| 3732 | } | 3743 | } |
| 3733 | try Type.fromInterned(info.return_type).resolveFully(zcu); | 3744 | try Type.fromInterned(info.return_type).resolveFully(pt); |
| 3734 | }, | 3745 | }, |
| 3735 | 3746 | ||
| 3736 | .Struct => switch (ip.indexToKey(ty.toIntern())) { | 3747 | .Struct => switch (ip.indexToKey(ty.toIntern())) { |
| 3737 | .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| { | 3748 | .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| { |
| 3738 | const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]); | 3749 | const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]); |
| 3739 | try field_ty.resolveFully(zcu); | 3750 | try field_ty.resolveFully(pt); |
| 3740 | }, | 3751 | }, |
| 3741 | .struct_type => return ty.resolveStructInner(zcu, .full), | 3752 | .struct_type => return ty.resolveStructInner(pt, .full), |
| 3742 | else => unreachable, | 3753 | else => unreachable, |
| 3743 | }, | 3754 | }, |
| 3744 | .Union => return ty.resolveUnionInner(zcu, .full), | 3755 | .Union => return ty.resolveUnionInner(pt, .full), |
| 3745 | } | 3756 | } |
| 3746 | } | 3757 | } |
| 3747 | 3758 | ||
| 3748 | pub fn resolveStructFieldInits(ty: Type, zcu: *Zcu) SemaError!void { | 3759 | pub fn resolveStructFieldInits(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3749 | // TODO: stop calling this for tuples! | 3760 | // TODO: stop calling this for tuples! |
| 3750 | _ = zcu.typeToStruct(ty) orelse return; | 3761 | _ = pt.zcu.typeToStruct(ty) orelse return; |
| 3751 | return ty.resolveStructInner(zcu, .inits); | 3762 | return ty.resolveStructInner(pt, .inits); |
| 3752 | } | 3763 | } |
| 3753 | 3764 | ||
| 3754 | pub fn resolveStructAlignment(ty: Type, zcu: *Zcu) SemaError!void { | 3765 | pub fn resolveStructAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3755 | return ty.resolveStructInner(zcu, .alignment); | 3766 | return ty.resolveStructInner(pt, .alignment); |
| 3756 | } | 3767 | } |
| 3757 | 3768 | ||
| 3758 | pub fn resolveUnionAlignment(ty: Type, zcu: *Zcu) SemaError!void { | 3769 | pub fn resolveUnionAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void { |
| 3759 | return ty.resolveUnionInner(zcu, .alignment); | 3770 | return ty.resolveUnionInner(pt, .alignment); |
| 3760 | } | 3771 | } |
| 3761 | 3772 | ||
| 3762 | /// `ty` must be a struct. | 3773 | /// `ty` must be a struct. |
| 3763 | fn resolveStructInner( | 3774 | fn resolveStructInner( |
| 3764 | ty: Type, | 3775 | ty: Type, |
| 3765 | zcu: *Zcu, | 3776 | pt: Zcu.PerThread, |
| 3766 | resolution: enum { fields, inits, alignment, layout, full }, | 3777 | resolution: enum { fields, inits, alignment, layout, full }, |
| 3767 | ) SemaError!void { | 3778 | ) SemaError!void { |
| 3779 | const zcu = pt.zcu; | ||
| 3768 | const gpa = zcu.gpa; | 3780 | const gpa = zcu.gpa; |
| 3769 | 3781 | ||
| 3770 | const struct_obj = zcu.typeToStruct(ty).?; | 3782 | const struct_obj = zcu.typeToStruct(ty).?; |
| ... | @@ -3777,7 +3789,7 @@ fn resolveStructInner( | ... | @@ -3777,7 +3789,7 @@ fn resolveStructInner( |
| 3777 | defer comptime_err_ret_trace.deinit(); | 3789 | defer comptime_err_ret_trace.deinit(); |
| 3778 | 3790 | ||
| 3779 | var sema: Sema = .{ | 3791 | var sema: Sema = .{ |
| 3780 | .mod = zcu, | 3792 | .pt = pt, |
| 3781 | .gpa = gpa, | 3793 | .gpa = gpa, |
| 3782 | .arena = analysis_arena.allocator(), | 3794 | .arena = analysis_arena.allocator(), |
| 3783 | .code = undefined, // This ZIR will not be used. | 3795 | .code = undefined, // This ZIR will not be used. |
| ... | @@ -3804,9 +3816,10 @@ fn resolveStructInner( | ... | @@ -3804,9 +3816,10 @@ fn resolveStructInner( |
| 3804 | /// `ty` must be a union. | 3816 | /// `ty` must be a union. |
| 3805 | fn resolveUnionInner( | 3817 | fn resolveUnionInner( |
| 3806 | ty: Type, | 3818 | ty: Type, |
| 3807 | zcu: *Zcu, | 3819 | pt: Zcu.PerThread, |
| 3808 | resolution: enum { fields, alignment, layout, full }, | 3820 | resolution: enum { fields, alignment, layout, full }, |
| 3809 | ) SemaError!void { | 3821 | ) SemaError!void { |
| 3822 | const zcu = pt.zcu; | ||
| 3810 | const gpa = zcu.gpa; | 3823 | const gpa = zcu.gpa; |
| 3811 | 3824 | ||
| 3812 | const union_obj = zcu.typeToUnion(ty).?; | 3825 | const union_obj = zcu.typeToUnion(ty).?; |
| ... | @@ -3819,7 +3832,7 @@ fn resolveUnionInner( | ... | @@ -3819,7 +3832,7 @@ fn resolveUnionInner( |
| 3819 | defer comptime_err_ret_trace.deinit(); | 3832 | defer comptime_err_ret_trace.deinit(); |
| 3820 | 3833 | ||
| 3821 | var sema: Sema = .{ | 3834 | var sema: Sema = .{ |
| 3822 | .mod = zcu, | 3835 | .pt = pt, |
| 3823 | .gpa = gpa, | 3836 | .gpa = gpa, |
| 3824 | .arena = analysis_arena.allocator(), | 3837 | .arena = analysis_arena.allocator(), |
| 3825 | .code = undefined, // This ZIR will not be used. | 3838 | .code = undefined, // This ZIR will not be used. |
| ... | @@ -3845,7 +3858,7 @@ fn resolveUnionInner( | ... | @@ -3845,7 +3858,7 @@ fn resolveUnionInner( |
| 3845 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with | 3858 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with |
| 3846 | /// special InternPool indices (such as std.builtin.Type) it will analyze and fully | 3859 | /// special InternPool indices (such as std.builtin.Type) it will analyze and fully |
| 3847 | /// resolve the type. | 3860 | /// resolve the type. |
| 3848 | fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Error!void { | 3861 | fn resolveSimpleType(simple_type: InternPool.SimpleType, pt: Zcu.PerThread) Allocator.Error!void { |
| 3849 | const builtin_type_name: []const u8 = switch (simple_type) { | 3862 | const builtin_type_name: []const u8 = switch (simple_type) { |
| 3850 | .atomic_order => "AtomicOrder", | 3863 | .atomic_order => "AtomicOrder", |
| 3851 | .atomic_rmw_op => "AtomicRmwOp", | 3864 | .atomic_rmw_op => "AtomicRmwOp", |
| ... | @@ -3861,7 +3874,7 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er | ... | @@ -3861,7 +3874,7 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er |
| 3861 | else => return, | 3874 | else => return, |
| 3862 | }; | 3875 | }; |
| 3863 | // This will fully resolve the type. | 3876 | // This will fully resolve the type. |
| 3864 | _ = try zcu.getBuiltinType(builtin_type_name); | 3877 | _ = try pt.getBuiltinType(builtin_type_name); |
| 3865 | } | 3878 | } |
| 3866 | 3879 | ||
| 3867 | /// Returns the type of a pointer to an element. | 3880 | /// Returns the type of a pointer to an element. |
| ... | @@ -3874,7 +3887,8 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er | ... | @@ -3874,7 +3887,8 @@ fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Er |
| 3874 | /// Handles const-ness and address spaces in particular. | 3887 | /// Handles const-ness and address spaces in particular. |
| 3875 | /// This code is duplicated in `Sema.analyzePtrArithmetic`. | 3888 | /// This code is duplicated in `Sema.analyzePtrArithmetic`. |
| 3876 | /// May perform type resolution and return a transitive `error.AnalysisFail`. | 3889 | /// May perform type resolution and return a transitive `error.AnalysisFail`. |
| 3877 | pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { | 3890 | pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type { |
| 3891 | const zcu = pt.zcu; | ||
| 3878 | const ptr_info = ptr_ty.ptrInfo(zcu); | 3892 | const ptr_info = ptr_ty.ptrInfo(zcu); |
| 3879 | const elem_ty = ptr_ty.elemType2(zcu); | 3893 | const elem_ty = ptr_ty.elemType2(zcu); |
| 3880 | const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0; | 3894 | const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0; |
| ... | @@ -3887,14 +3901,14 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { | ... | @@ -3887,14 +3901,14 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { |
| 3887 | alignment: Alignment = .none, | 3901 | alignment: Alignment = .none, |
| 3888 | vector_index: VI = .none, | 3902 | vector_index: VI = .none, |
| 3889 | } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: { | 3903 | } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: { |
| 3890 | const elem_bits = elem_ty.bitSize(zcu); | 3904 | const elem_bits = elem_ty.bitSize(pt); |
| 3891 | if (elem_bits == 0) break :blk .{}; | 3905 | if (elem_bits == 0) break :blk .{}; |
| 3892 | const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits); | 3906 | const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits); |
| 3893 | if (!is_packed) break :blk .{}; | 3907 | if (!is_packed) break :blk .{}; |
| 3894 | 3908 | ||
| 3895 | break :blk .{ | 3909 | break :blk .{ |
| 3896 | .host_size = @intCast(parent_ty.arrayLen(zcu)), | 3910 | .host_size = @intCast(parent_ty.arrayLen(zcu)), |
| 3897 | .alignment = parent_ty.abiAlignment(zcu), | 3911 | .alignment = parent_ty.abiAlignment(pt), |
| 3898 | .vector_index = if (offset) |some| @enumFromInt(some) else .runtime, | 3912 | .vector_index = if (offset) |some| @enumFromInt(some) else .runtime, |
| 3899 | }; | 3913 | }; |
| 3900 | } else .{}; | 3914 | } else .{}; |
| ... | @@ -3908,7 +3922,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { | ... | @@ -3908,7 +3922,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { |
| 3908 | } | 3922 | } |
| 3909 | // If the addend is not a comptime-known value we can still count on | 3923 | // If the addend is not a comptime-known value we can still count on |
| 3910 | // it being a multiple of the type size. | 3924 | // it being a multiple of the type size. |
| 3911 | const elem_size = (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar; | 3925 | const elem_size = (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar; |
| 3912 | const addend = if (offset) |off| elem_size * off else elem_size; | 3926 | const addend = if (offset) |off| elem_size * off else elem_size; |
| 3913 | 3927 | ||
| 3914 | // The resulting pointer is aligned to the lcd between the offset (an | 3928 | // The resulting pointer is aligned to the lcd between the offset (an |
| ... | @@ -3921,7 +3935,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { | ... | @@ -3921,7 +3935,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type { |
| 3921 | assert(new_align != .none); | 3935 | assert(new_align != .none); |
| 3922 | break :a new_align; | 3936 | break :a new_align; |
| 3923 | }; | 3937 | }; |
| 3924 | return zcu.ptrTypeSema(.{ | 3938 | return pt.ptrTypeSema(.{ |
| 3925 | .child = elem_ty.toIntern(), | 3939 | .child = elem_ty.toIntern(), |
| 3926 | .flags = .{ | 3940 | .flags = .{ |
| 3927 | .alignment = alignment, | 3941 | .alignment = alignment, |
| ... | @@ -3944,6 +3958,7 @@ pub const @"u16": Type = .{ .ip_index = .u16_type }; | ... | @@ -3944,6 +3958,7 @@ pub const @"u16": Type = .{ .ip_index = .u16_type }; |
| 3944 | pub const @"u29": Type = .{ .ip_index = .u29_type }; | 3958 | pub const @"u29": Type = .{ .ip_index = .u29_type }; |
| 3945 | pub const @"u32": Type = .{ .ip_index = .u32_type }; | 3959 | pub const @"u32": Type = .{ .ip_index = .u32_type }; |
| 3946 | pub const @"u64": Type = .{ .ip_index = .u64_type }; | 3960 | pub const @"u64": Type = .{ .ip_index = .u64_type }; |
| 3961 | pub const @"u80": Type = .{ .ip_index = .u80_type }; | ||
| 3947 | pub const @"u128": Type = .{ .ip_index = .u128_type }; | 3962 | pub const @"u128": Type = .{ .ip_index = .u128_type }; |
| 3948 | 3963 | ||
| 3949 | pub const @"i8": Type = .{ .ip_index = .i8_type }; | 3964 | pub const @"i8": Type = .{ .ip_index = .i8_type }; |
src/Value.zig+1163-1084| ... | @@ -40,10 +40,10 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { | ... | @@ -40,10 +40,10 @@ pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { |
| 40 | return .{ .data = val }; | 40 | return .{ .data = val }; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | pub fn fmtValue(val: Value, mod: *Module, opt_sema: ?*Sema) std.fmt.Formatter(print_value.format) { | 43 | pub fn fmtValue(val: Value, pt: Zcu.PerThread, opt_sema: ?*Sema) std.fmt.Formatter(print_value.format) { |
| 44 | return .{ .data = .{ | 44 | return .{ .data = .{ |
| 45 | .val = val, | 45 | .val = val, |
| 46 | .mod = mod, | 46 | .pt = pt, |
| 47 | .opt_sema = opt_sema, | 47 | .opt_sema = opt_sema, |
| 48 | .depth = 3, | 48 | .depth = 3, |
| 49 | } }; | 49 | } }; |
| ... | @@ -55,15 +55,16 @@ pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_valu | ... | @@ -55,15 +55,16 @@ pub fn fmtValueFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_valu |
| 55 | 55 | ||
| 56 | /// Converts `val` to a null-terminated string stored in the InternPool. | 56 | /// Converts `val` to a null-terminated string stored in the InternPool. |
| 57 | /// Asserts `val` is an array of `u8` | 57 | /// Asserts `val` is an array of `u8` |
| 58 | pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString { | 58 | pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTerminatedString { |
| 59 | const mod = pt.zcu; | ||
| 59 | assert(ty.zigTypeTag(mod) == .Array); | 60 | assert(ty.zigTypeTag(mod) == .Array); |
| 60 | assert(ty.childType(mod).toIntern() == .u8_type); | 61 | assert(ty.childType(mod).toIntern() == .u8_type); |
| 61 | const ip = &mod.intern_pool; | 62 | const ip = &mod.intern_pool; |
| 62 | switch (mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage) { | 63 | switch (mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage) { |
| 63 | .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(mod), ip), | 64 | .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(mod), ip), |
| 64 | .elems => return arrayToIpString(val, ty.arrayLen(mod), mod), | 65 | .elems => return arrayToIpString(val, ty.arrayLen(mod), pt), |
| 65 | .repeated_elem => |elem| { | 66 | .repeated_elem => |elem| { |
| 66 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(mod)); | 67 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt)); |
| 67 | const len: usize = @intCast(ty.arrayLen(mod)); | 68 | const len: usize = @intCast(ty.arrayLen(mod)); |
| 68 | try ip.string_bytes.appendNTimes(mod.gpa, byte, len); | 69 | try ip.string_bytes.appendNTimes(mod.gpa, byte, len); |
| 69 | return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls); | 70 | return ip.getOrPutTrailingString(mod.gpa, len, .no_embedded_nulls); |
| ... | @@ -73,16 +74,17 @@ pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminated | ... | @@ -73,16 +74,17 @@ pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminated |
| 73 | 74 | ||
| 74 | /// Asserts that the value is representable as an array of bytes. | 75 | /// Asserts that the value is representable as an array of bytes. |
| 75 | /// Copies the value into a freshly allocated slice of memory, which is owned by the caller. | 76 | /// Copies the value into a freshly allocated slice of memory, which is owned by the caller. |
| 76 | pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 { | 77 | pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) ![]u8 { |
| 78 | const mod = pt.zcu; | ||
| 77 | const ip = &mod.intern_pool; | 79 | const ip = &mod.intern_pool; |
| 78 | return switch (ip.indexToKey(val.toIntern())) { | 80 | return switch (ip.indexToKey(val.toIntern())) { |
| 79 | .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)), | 81 | .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)), |
| 80 | .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(mod), allocator, mod), | 82 | .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(pt), allocator, pt), |
| 81 | .aggregate => |aggregate| switch (aggregate.storage) { | 83 | .aggregate => |aggregate| switch (aggregate.storage) { |
| 82 | .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)), | 84 | .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)), |
| 83 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod), | 85 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, pt), |
| 84 | .repeated_elem => |elem| { | 86 | .repeated_elem => |elem| { |
| 85 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(mod)); | 87 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt)); |
| 86 | const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod))); | 88 | const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod))); |
| 87 | @memset(result, byte); | 89 | @memset(result, byte); |
| 88 | return result; | 90 | return result; |
| ... | @@ -92,16 +94,17 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module | ... | @@ -92,16 +94,17 @@ pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module |
| 92 | }; | 94 | }; |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 { | 97 | fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, pt: Zcu.PerThread) ![]u8 { |
| 96 | const result = try allocator.alloc(u8, @intCast(len)); | 98 | const result = try allocator.alloc(u8, @intCast(len)); |
| 97 | for (result, 0..) |*elem, i| { | 99 | for (result, 0..) |*elem, i| { |
| 98 | const elem_val = try val.elemValue(mod, i); | 100 | const elem_val = try val.elemValue(pt, i); |
| 99 | elem.* = @intCast(elem_val.toUnsignedInt(mod)); | 101 | elem.* = @intCast(elem_val.toUnsignedInt(pt)); |
| 100 | } | 102 | } |
| 101 | return result; | 103 | return result; |
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTerminatedString { | 106 | fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.NullTerminatedString { |
| 107 | const mod = pt.zcu; | ||
| 105 | const gpa = mod.gpa; | 108 | const gpa = mod.gpa; |
| 106 | const ip = &mod.intern_pool; | 109 | const ip = &mod.intern_pool; |
| 107 | const len: usize = @intCast(len_u64); | 110 | const len: usize = @intCast(len_u64); |
| ... | @@ -110,9 +113,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi | ... | @@ -110,9 +113,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi |
| 110 | // I don't think elemValue has the possibility to affect ip.string_bytes. Let's | 113 | // I don't think elemValue has the possibility to affect ip.string_bytes. Let's |
| 111 | // assert just to be sure. | 114 | // assert just to be sure. |
| 112 | const prev = ip.string_bytes.items.len; | 115 | const prev = ip.string_bytes.items.len; |
| 113 | const elem_val = try val.elemValue(mod, i); | 116 | const elem_val = try val.elemValue(pt, i); |
| 114 | assert(ip.string_bytes.items.len == prev); | 117 | assert(ip.string_bytes.items.len == prev); |
| 115 | const byte: u8 = @intCast(elem_val.toUnsignedInt(mod)); | 118 | const byte: u8 = @intCast(elem_val.toUnsignedInt(pt)); |
| 116 | ip.string_bytes.appendAssumeCapacity(byte); | 119 | ip.string_bytes.appendAssumeCapacity(byte); |
| 117 | } | 120 | } |
| 118 | return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls); | 121 | return ip.getOrPutTrailingString(gpa, len, .no_embedded_nulls); |
| ... | @@ -133,14 +136,14 @@ pub fn toType(self: Value) Type { | ... | @@ -133,14 +136,14 @@ pub fn toType(self: Value) Type { |
| 133 | return Type.fromInterned(self.toIntern()); | 136 | return Type.fromInterned(self.toIntern()); |
| 134 | } | 137 | } |
| 135 | 138 | ||
| 136 | pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value { | 139 | pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 137 | const ip = &mod.intern_pool; | 140 | const ip = &pt.zcu.intern_pool; |
| 138 | const enum_ty = ip.typeOf(val.toIntern()); | 141 | const enum_ty = ip.typeOf(val.toIntern()); |
| 139 | return switch (ip.indexToKey(enum_ty)) { | 142 | return switch (ip.indexToKey(enum_ty)) { |
| 140 | // Assume it is already an integer and return it directly. | 143 | // Assume it is already an integer and return it directly. |
| 141 | .simple_type, .int_type => val, | 144 | .simple_type, .int_type => val, |
| 142 | .enum_literal => |enum_literal| { | 145 | .enum_literal => |enum_literal| { |
| 143 | const field_index = ty.enumFieldIndex(enum_literal, mod).?; | 146 | const field_index = ty.enumFieldIndex(enum_literal, pt.zcu).?; |
| 144 | switch (ip.indexToKey(ty.toIntern())) { | 147 | switch (ip.indexToKey(ty.toIntern())) { |
| 145 | // Assume it is already an integer and return it directly. | 148 | // Assume it is already an integer and return it directly. |
| 146 | .simple_type, .int_type => return val, | 149 | .simple_type, .int_type => return val, |
| ... | @@ -150,13 +153,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value { | ... | @@ -150,13 +153,13 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value { |
| 150 | return Value.fromInterned(enum_type.values.get(ip)[field_index]); | 153 | return Value.fromInterned(enum_type.values.get(ip)[field_index]); |
| 151 | } else { | 154 | } else { |
| 152 | // Field index and integer values are the same. | 155 | // Field index and integer values are the same. |
| 153 | return mod.intValue(Type.fromInterned(enum_type.tag_ty), field_index); | 156 | return pt.intValue(Type.fromInterned(enum_type.tag_ty), field_index); |
| 154 | } | 157 | } |
| 155 | }, | 158 | }, |
| 156 | else => unreachable, | 159 | else => unreachable, |
| 157 | } | 160 | } |
| 158 | }, | 161 | }, |
| 159 | .enum_type => try mod.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)), | 162 | .enum_type => try pt.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)), |
| 160 | else => unreachable, | 163 | else => unreachable, |
| 161 | }; | 164 | }; |
| 162 | } | 165 | } |
| ... | @@ -164,38 +167,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value { | ... | @@ -164,38 +167,38 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value { |
| 164 | pub const ResolveStrat = Type.ResolveStrat; | 167 | pub const ResolveStrat = Type.ResolveStrat; |
| 165 | 168 | ||
| 166 | /// Asserts the value is an integer. | 169 | /// Asserts the value is an integer. |
| 167 | pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst { | 170 | pub fn toBigInt(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) BigIntConst { |
| 168 | return val.toBigIntAdvanced(space, mod, .normal) catch unreachable; | 171 | return val.toBigIntAdvanced(space, pt, .normal) catch unreachable; |
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | /// Asserts the value is an integer. | 174 | /// Asserts the value is an integer. |
| 172 | pub fn toBigIntAdvanced( | 175 | pub fn toBigIntAdvanced( |
| 173 | val: Value, | 176 | val: Value, |
| 174 | space: *BigIntSpace, | 177 | space: *BigIntSpace, |
| 175 | mod: *Module, | 178 | pt: Zcu.PerThread, |
| 176 | strat: ResolveStrat, | 179 | strat: ResolveStrat, |
| 177 | ) Module.CompileError!BigIntConst { | 180 | ) Module.CompileError!BigIntConst { |
| 178 | return switch (val.toIntern()) { | 181 | return switch (val.toIntern()) { |
| 179 | .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(), | 182 | .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(), |
| 180 | .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(), | 183 | .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(), |
| 181 | .null_value => BigIntMutable.init(&space.limbs, 0).toConst(), | 184 | .null_value => BigIntMutable.init(&space.limbs, 0).toConst(), |
| 182 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 185 | else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 183 | .int => |int| switch (int.storage) { | 186 | .int => |int| switch (int.storage) { |
| 184 | .u64, .i64, .big_int => int.storage.toBigInt(space), | 187 | .u64, .i64, .big_int => int.storage.toBigInt(space), |
| 185 | .lazy_align, .lazy_size => |ty| { | 188 | .lazy_align, .lazy_size => |ty| { |
| 186 | if (strat == .sema) try Type.fromInterned(ty).resolveLayout(mod); | 189 | if (strat == .sema) try Type.fromInterned(ty).resolveLayout(pt); |
| 187 | const x = switch (int.storage) { | 190 | const x = switch (int.storage) { |
| 188 | else => unreachable, | 191 | else => unreachable, |
| 189 | .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0, | 192 | .lazy_align => Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0, |
| 190 | .lazy_size => Type.fromInterned(ty).abiSize(mod), | 193 | .lazy_size => Type.fromInterned(ty).abiSize(pt), |
| 191 | }; | 194 | }; |
| 192 | return BigIntMutable.init(&space.limbs, x).toConst(); | 195 | return BigIntMutable.init(&space.limbs, x).toConst(); |
| 193 | }, | 196 | }, |
| 194 | }, | 197 | }, |
| 195 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, mod, strat), | 198 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, pt, strat), |
| 196 | .opt, .ptr => BigIntMutable.init( | 199 | .opt, .ptr => BigIntMutable.init( |
| 197 | &space.limbs, | 200 | &space.limbs, |
| 198 | (try val.getUnsignedIntAdvanced(mod, strat)).?, | 201 | (try val.getUnsignedIntAdvanced(pt, strat)).?, |
| 199 | ).toConst(), | 202 | ).toConst(), |
| 200 | else => unreachable, | 203 | else => unreachable, |
| 201 | }, | 204 | }, |
| ... | @@ -229,13 +232,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { | ... | @@ -229,13 +232,14 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { |
| 229 | 232 | ||
| 230 | /// If the value fits in a u64, return it, otherwise null. | 233 | /// If the value fits in a u64, return it, otherwise null. |
| 231 | /// Asserts not undefined. | 234 | /// Asserts not undefined. |
| 232 | pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 { | 235 | pub fn getUnsignedInt(val: Value, pt: Zcu.PerThread) ?u64 { |
| 233 | return getUnsignedIntAdvanced(val, mod, .normal) catch unreachable; | 236 | return getUnsignedIntAdvanced(val, pt, .normal) catch unreachable; |
| 234 | } | 237 | } |
| 235 | 238 | ||
| 236 | /// If the value fits in a u64, return it, otherwise null. | 239 | /// If the value fits in a u64, return it, otherwise null. |
| 237 | /// Asserts not undefined. | 240 | /// Asserts not undefined. |
| 238 | pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u64 { | 241 | pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, strat: ResolveStrat) !?u64 { |
| 242 | const mod = pt.zcu; | ||
| 239 | return switch (val.toIntern()) { | 243 | return switch (val.toIntern()) { |
| 240 | .undef => unreachable, | 244 | .undef => unreachable, |
| 241 | .bool_false => 0, | 245 | .bool_false => 0, |
| ... | @@ -246,22 +250,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u | ... | @@ -246,22 +250,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u |
| 246 | .big_int => |big_int| big_int.to(u64) catch null, | 250 | .big_int => |big_int| big_int.to(u64) catch null, |
| 247 | .u64 => |x| x, | 251 | .u64 => |x| x, |
| 248 | .i64 => |x| std.math.cast(u64, x), | 252 | .i64 => |x| std.math.cast(u64, x), |
| 249 | .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0, | 253 | .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0, |
| 250 | .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar, | 254 | .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, |
| 251 | }, | 255 | }, |
| 252 | .ptr => |ptr| switch (ptr.base_addr) { | 256 | .ptr => |ptr| switch (ptr.base_addr) { |
| 253 | .int => ptr.byte_offset, | 257 | .int => ptr.byte_offset, |
| 254 | .field => |field| { | 258 | .field => |field| { |
| 255 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, strat)) orelse return null; | 259 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(pt, strat)) orelse return null; |
| 256 | const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod); | 260 | const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod); |
| 257 | if (strat == .sema) try struct_ty.resolveLayout(mod); | 261 | if (strat == .sema) try struct_ty.resolveLayout(pt); |
| 258 | return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset; | 262 | return base_addr + struct_ty.structFieldOffset(@intCast(field.index), pt) + ptr.byte_offset; |
| 259 | }, | 263 | }, |
| 260 | else => null, | 264 | else => null, |
| 261 | }, | 265 | }, |
| 262 | .opt => |opt| switch (opt.val) { | 266 | .opt => |opt| switch (opt.val) { |
| 263 | .none => 0, | 267 | .none => 0, |
| 264 | else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, strat), | 268 | else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(pt, strat), |
| 265 | }, | 269 | }, |
| 266 | else => null, | 270 | else => null, |
| 267 | }, | 271 | }, |
| ... | @@ -269,27 +273,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u | ... | @@ -269,27 +273,27 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u |
| 269 | } | 273 | } |
| 270 | 274 | ||
| 271 | /// Asserts the value is an integer and it fits in a u64 | 275 | /// Asserts the value is an integer and it fits in a u64 |
| 272 | pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 { | 276 | pub fn toUnsignedInt(val: Value, pt: Zcu.PerThread) u64 { |
| 273 | return getUnsignedInt(val, zcu).?; | 277 | return getUnsignedInt(val, pt).?; |
| 274 | } | 278 | } |
| 275 | 279 | ||
| 276 | /// Asserts the value is an integer and it fits in a u64 | 280 | /// Asserts the value is an integer and it fits in a u64 |
| 277 | pub fn toUnsignedIntSema(val: Value, zcu: *Zcu) !u64 { | 281 | pub fn toUnsignedIntSema(val: Value, pt: Zcu.PerThread) !u64 { |
| 278 | return (try getUnsignedIntAdvanced(val, zcu, .sema)).?; | 282 | return (try getUnsignedIntAdvanced(val, pt, .sema)).?; |
| 279 | } | 283 | } |
| 280 | 284 | ||
| 281 | /// Asserts the value is an integer and it fits in a i64 | 285 | /// Asserts the value is an integer and it fits in a i64 |
| 282 | pub fn toSignedInt(val: Value, mod: *Module) i64 { | 286 | pub fn toSignedInt(val: Value, pt: Zcu.PerThread) i64 { |
| 283 | return switch (val.toIntern()) { | 287 | return switch (val.toIntern()) { |
| 284 | .bool_false => 0, | 288 | .bool_false => 0, |
| 285 | .bool_true => 1, | 289 | .bool_true => 1, |
| 286 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 290 | else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 287 | .int => |int| switch (int.storage) { | 291 | .int => |int| switch (int.storage) { |
| 288 | .big_int => |big_int| big_int.to(i64) catch unreachable, | 292 | .big_int => |big_int| big_int.to(i64) catch unreachable, |
| 289 | .i64 => |x| x, | 293 | .i64 => |x| x, |
| 290 | .u64 => |x| @intCast(x), | 294 | .u64 => |x| @intCast(x), |
| 291 | .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0), | 295 | .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0), |
| 292 | .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(mod)), | 296 | .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(pt)), |
| 293 | }, | 297 | }, |
| 294 | else => unreachable, | 298 | else => unreachable, |
| 295 | }, | 299 | }, |
| ... | @@ -321,16 +325,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool { | ... | @@ -321,16 +325,17 @@ fn ptrHasIntAddr(val: Value, mod: *Module) bool { |
| 321 | /// | 325 | /// |
| 322 | /// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past | 326 | /// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past |
| 323 | /// the end of the value in memory. | 327 | /// the end of the value in memory. |
| 324 | pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | 328 | pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) error{ |
| 325 | ReinterpretDeclRef, | 329 | ReinterpretDeclRef, |
| 326 | IllDefinedMemoryLayout, | 330 | IllDefinedMemoryLayout, |
| 327 | Unimplemented, | 331 | Unimplemented, |
| 328 | OutOfMemory, | 332 | OutOfMemory, |
| 329 | }!void { | 333 | }!void { |
| 334 | const mod = pt.zcu; | ||
| 330 | const target = mod.getTarget(); | 335 | const target = mod.getTarget(); |
| 331 | const endian = target.cpu.arch.endian(); | 336 | const endian = target.cpu.arch.endian(); |
| 332 | if (val.isUndef(mod)) { | 337 | if (val.isUndef(mod)) { |
| 333 | const size: usize = @intCast(ty.abiSize(mod)); | 338 | const size: usize = @intCast(ty.abiSize(pt)); |
| 334 | @memset(buffer[0..size], 0xaa); | 339 | @memset(buffer[0..size], 0xaa); |
| 335 | return; | 340 | return; |
| 336 | } | 341 | } |
| ... | @@ -346,41 +351,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -346,41 +351,41 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 346 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); | 351 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); |
| 347 | 352 | ||
| 348 | var bigint_buffer: BigIntSpace = undefined; | 353 | var bigint_buffer: BigIntSpace = undefined; |
| 349 | const bigint = val.toBigInt(&bigint_buffer, mod); | 354 | const bigint = val.toBigInt(&bigint_buffer, pt); |
| 350 | bigint.writeTwosComplement(buffer[0..byte_count], endian); | 355 | bigint.writeTwosComplement(buffer[0..byte_count], endian); |
| 351 | }, | 356 | }, |
| 352 | .Float => switch (ty.floatBits(target)) { | 357 | .Float => switch (ty.floatBits(target)) { |
| 353 | 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, mod)), endian), | 358 | 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, pt)), endian), |
| 354 | 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, mod)), endian), | 359 | 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, pt)), endian), |
| 355 | 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, mod)), endian), | 360 | 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, pt)), endian), |
| 356 | 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, mod)), endian), | 361 | 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, pt)), endian), |
| 357 | 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, mod)), endian), | 362 | 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, pt)), endian), |
| 358 | else => unreachable, | 363 | else => unreachable, |
| 359 | }, | 364 | }, |
| 360 | .Array => { | 365 | .Array => { |
| 361 | const len = ty.arrayLen(mod); | 366 | const len = ty.arrayLen(mod); |
| 362 | const elem_ty = ty.childType(mod); | 367 | const elem_ty = ty.childType(mod); |
| 363 | const elem_size: usize = @intCast(elem_ty.abiSize(mod)); | 368 | const elem_size: usize = @intCast(elem_ty.abiSize(pt)); |
| 364 | var elem_i: usize = 0; | 369 | var elem_i: usize = 0; |
| 365 | var buf_off: usize = 0; | 370 | var buf_off: usize = 0; |
| 366 | while (elem_i < len) : (elem_i += 1) { | 371 | while (elem_i < len) : (elem_i += 1) { |
| 367 | const elem_val = try val.elemValue(mod, elem_i); | 372 | const elem_val = try val.elemValue(pt, elem_i); |
| 368 | try elem_val.writeToMemory(elem_ty, mod, buffer[buf_off..]); | 373 | try elem_val.writeToMemory(elem_ty, pt, buffer[buf_off..]); |
| 369 | buf_off += elem_size; | 374 | buf_off += elem_size; |
| 370 | } | 375 | } |
| 371 | }, | 376 | }, |
| 372 | .Vector => { | 377 | .Vector => { |
| 373 | // We use byte_count instead of abi_size here, so that any padding bytes | 378 | // We use byte_count instead of abi_size here, so that any padding bytes |
| 374 | // follow the data bytes, on both big- and little-endian systems. | 379 | // follow the data bytes, on both big- and little-endian systems. |
| 375 | const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8; | 380 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; |
| 376 | return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0); | 381 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 377 | }, | 382 | }, |
| 378 | .Struct => { | 383 | .Struct => { |
| 379 | const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout; | 384 | const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout; |
| 380 | switch (struct_type.layout) { | 385 | switch (struct_type.layout) { |
| 381 | .auto => return error.IllDefinedMemoryLayout, | 386 | .auto => return error.IllDefinedMemoryLayout, |
| 382 | .@"extern" => for (0..struct_type.field_types.len) |field_index| { | 387 | .@"extern" => for (0..struct_type.field_types.len) |field_index| { |
| 383 | const off: usize = @intCast(ty.structFieldOffset(field_index, mod)); | 388 | const off: usize = @intCast(ty.structFieldOffset(field_index, pt)); |
| 384 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 389 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 385 | .bytes => |bytes| { | 390 | .bytes => |bytes| { |
| 386 | buffer[off] = bytes.at(field_index, ip); | 391 | buffer[off] = bytes.at(field_index, ip); |
| ... | @@ -390,11 +395,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -390,11 +395,11 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 390 | .repeated_elem => |elem| elem, | 395 | .repeated_elem => |elem| elem, |
| 391 | }); | 396 | }); |
| 392 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 397 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 393 | try writeToMemory(field_val, field_ty, mod, buffer[off..]); | 398 | try writeToMemory(field_val, field_ty, pt, buffer[off..]); |
| 394 | }, | 399 | }, |
| 395 | .@"packed" => { | 400 | .@"packed" => { |
| 396 | const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8; | 401 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; |
| 397 | return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0); | 402 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 398 | }, | 403 | }, |
| 399 | } | 404 | } |
| 400 | }, | 405 | }, |
| ... | @@ -421,34 +426,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -421,34 +426,34 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 421 | const union_obj = mod.typeToUnion(ty).?; | 426 | const union_obj = mod.typeToUnion(ty).?; |
| 422 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; | 427 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; |
| 423 | const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]); | 428 | const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]); |
| 424 | const field_val = try val.fieldValue(mod, field_index); | 429 | const field_val = try val.fieldValue(pt, field_index); |
| 425 | const byte_count: usize = @intCast(field_type.abiSize(mod)); | 430 | const byte_count: usize = @intCast(field_type.abiSize(pt)); |
| 426 | return writeToMemory(field_val, field_type, mod, buffer[0..byte_count]); | 431 | return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]); |
| 427 | } else { | 432 | } else { |
| 428 | const backing_ty = try ty.unionBackingType(mod); | 433 | const backing_ty = try ty.unionBackingType(pt); |
| 429 | const byte_count: usize = @intCast(backing_ty.abiSize(mod)); | 434 | const byte_count: usize = @intCast(backing_ty.abiSize(pt)); |
| 430 | return writeToMemory(val.unionValue(mod), backing_ty, mod, buffer[0..byte_count]); | 435 | return writeToMemory(val.unionValue(mod), backing_ty, pt, buffer[0..byte_count]); |
| 431 | } | 436 | } |
| 432 | }, | 437 | }, |
| 433 | .@"packed" => { | 438 | .@"packed" => { |
| 434 | const backing_ty = try ty.unionBackingType(mod); | 439 | const backing_ty = try ty.unionBackingType(pt); |
| 435 | const byte_count: usize = @intCast(backing_ty.abiSize(mod)); | 440 | const byte_count: usize = @intCast(backing_ty.abiSize(pt)); |
| 436 | return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0); | 441 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 437 | }, | 442 | }, |
| 438 | }, | 443 | }, |
| 439 | .Pointer => { | 444 | .Pointer => { |
| 440 | if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout; | 445 | if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout; |
| 441 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; | 446 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; |
| 442 | return val.writeToMemory(Type.usize, mod, buffer); | 447 | return val.writeToMemory(Type.usize, pt, buffer); |
| 443 | }, | 448 | }, |
| 444 | .Optional => { | 449 | .Optional => { |
| 445 | if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout; | 450 | if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout; |
| 446 | const child = ty.optionalChild(mod); | 451 | const child = ty.optionalChild(mod); |
| 447 | const opt_val = val.optionalValue(mod); | 452 | const opt_val = val.optionalValue(mod); |
| 448 | if (opt_val) |some| { | 453 | if (opt_val) |some| { |
| 449 | return some.writeToMemory(child, mod, buffer); | 454 | return some.writeToMemory(child, pt, buffer); |
| 450 | } else { | 455 | } else { |
| 451 | return writeToMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer); | 456 | return writeToMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer); |
| 452 | } | 457 | } |
| 453 | }, | 458 | }, |
| 454 | else => return error.Unimplemented, | 459 | else => return error.Unimplemented, |
| ... | @@ -462,15 +467,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -462,15 +467,16 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 462 | pub fn writeToPackedMemory( | 467 | pub fn writeToPackedMemory( |
| 463 | val: Value, | 468 | val: Value, |
| 464 | ty: Type, | 469 | ty: Type, |
| 465 | mod: *Module, | 470 | pt: Zcu.PerThread, |
| 466 | buffer: []u8, | 471 | buffer: []u8, |
| 467 | bit_offset: usize, | 472 | bit_offset: usize, |
| 468 | ) error{ ReinterpretDeclRef, OutOfMemory }!void { | 473 | ) error{ ReinterpretDeclRef, OutOfMemory }!void { |
| 474 | const mod = pt.zcu; | ||
| 469 | const ip = &mod.intern_pool; | 475 | const ip = &mod.intern_pool; |
| 470 | const target = mod.getTarget(); | 476 | const target = mod.getTarget(); |
| 471 | const endian = target.cpu.arch.endian(); | 477 | const endian = target.cpu.arch.endian(); |
| 472 | if (val.isUndef(mod)) { | 478 | if (val.isUndef(mod)) { |
| 473 | const bit_size: usize = @intCast(ty.bitSize(mod)); | 479 | const bit_size: usize = @intCast(ty.bitSize(pt)); |
| 474 | if (bit_size != 0) { | 480 | if (bit_size != 0) { |
| 475 | std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian); | 481 | std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian); |
| 476 | } | 482 | } |
| ... | @@ -494,30 +500,30 @@ pub fn writeToPackedMemory( | ... | @@ -494,30 +500,30 @@ pub fn writeToPackedMemory( |
| 494 | const bits = ty.intInfo(mod).bits; | 500 | const bits = ty.intInfo(mod).bits; |
| 495 | if (bits == 0) return; | 501 | if (bits == 0) return; |
| 496 | 502 | ||
| 497 | switch (ip.indexToKey((try val.intFromEnum(ty, mod)).toIntern()).int.storage) { | 503 | switch (ip.indexToKey((try val.intFromEnum(ty, pt)).toIntern()).int.storage) { |
| 498 | inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian), | 504 | inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian), |
| 499 | .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian), | 505 | .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian), |
| 500 | .lazy_align => |lazy_align| { | 506 | .lazy_align => |lazy_align| { |
| 501 | const num = Type.fromInterned(lazy_align).abiAlignment(mod).toByteUnits() orelse 0; | 507 | const num = Type.fromInterned(lazy_align).abiAlignment(pt).toByteUnits() orelse 0; |
| 502 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); | 508 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); |
| 503 | }, | 509 | }, |
| 504 | .lazy_size => |lazy_size| { | 510 | .lazy_size => |lazy_size| { |
| 505 | const num = Type.fromInterned(lazy_size).abiSize(mod); | 511 | const num = Type.fromInterned(lazy_size).abiSize(pt); |
| 506 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); | 512 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); |
| 507 | }, | 513 | }, |
| 508 | } | 514 | } |
| 509 | }, | 515 | }, |
| 510 | .Float => switch (ty.floatBits(target)) { | 516 | .Float => switch (ty.floatBits(target)) { |
| 511 | 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, mod)), endian), | 517 | 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, pt)), endian), |
| 512 | 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, mod)), endian), | 518 | 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, pt)), endian), |
| 513 | 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, mod)), endian), | 519 | 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, pt)), endian), |
| 514 | 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, mod)), endian), | 520 | 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, pt)), endian), |
| 515 | 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, mod)), endian), | 521 | 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, pt)), endian), |
| 516 | else => unreachable, | 522 | else => unreachable, |
| 517 | }, | 523 | }, |
| 518 | .Vector => { | 524 | .Vector => { |
| 519 | const elem_ty = ty.childType(mod); | 525 | const elem_ty = ty.childType(mod); |
| 520 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod)); | 526 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt)); |
| 521 | const len: usize = @intCast(ty.arrayLen(mod)); | 527 | const len: usize = @intCast(ty.arrayLen(mod)); |
| 522 | 528 | ||
| 523 | var bits: u16 = 0; | 529 | var bits: u16 = 0; |
| ... | @@ -525,8 +531,8 @@ pub fn writeToPackedMemory( | ... | @@ -525,8 +531,8 @@ pub fn writeToPackedMemory( |
| 525 | while (elem_i < len) : (elem_i += 1) { | 531 | while (elem_i < len) : (elem_i += 1) { |
| 526 | // On big-endian systems, LLVM reverses the element order of vectors by default | 532 | // On big-endian systems, LLVM reverses the element order of vectors by default |
| 527 | const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i; | 533 | const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i; |
| 528 | const elem_val = try val.elemValue(mod, tgt_elem_i); | 534 | const elem_val = try val.elemValue(pt, tgt_elem_i); |
| 529 | try elem_val.writeToPackedMemory(elem_ty, mod, buffer, bit_offset + bits); | 535 | try elem_val.writeToPackedMemory(elem_ty, pt, buffer, bit_offset + bits); |
| 530 | bits += elem_bit_size; | 536 | bits += elem_bit_size; |
| 531 | } | 537 | } |
| 532 | }, | 538 | }, |
| ... | @@ -543,8 +549,8 @@ pub fn writeToPackedMemory( | ... | @@ -543,8 +549,8 @@ pub fn writeToPackedMemory( |
| 543 | .repeated_elem => |elem| elem, | 549 | .repeated_elem => |elem| elem, |
| 544 | }); | 550 | }); |
| 545 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 551 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 546 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); | 552 | const field_bits: u16 = @intCast(field_ty.bitSize(pt)); |
| 547 | try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits); | 553 | try field_val.writeToPackedMemory(field_ty, pt, buffer, bit_offset + bits); |
| 548 | bits += field_bits; | 554 | bits += field_bits; |
| 549 | } | 555 | } |
| 550 | }, | 556 | }, |
| ... | @@ -556,11 +562,11 @@ pub fn writeToPackedMemory( | ... | @@ -556,11 +562,11 @@ pub fn writeToPackedMemory( |
| 556 | if (val.unionTag(mod)) |union_tag| { | 562 | if (val.unionTag(mod)) |union_tag| { |
| 557 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; | 563 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; |
| 558 | const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 564 | const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 559 | const field_val = try val.fieldValue(mod, field_index); | 565 | const field_val = try val.fieldValue(pt, field_index); |
| 560 | return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset); | 566 | return field_val.writeToPackedMemory(field_type, pt, buffer, bit_offset); |
| 561 | } else { | 567 | } else { |
| 562 | const backing_ty = try ty.unionBackingType(mod); | 568 | const backing_ty = try ty.unionBackingType(pt); |
| 563 | return val.unionValue(mod).writeToPackedMemory(backing_ty, mod, buffer, bit_offset); | 569 | return val.unionValue(mod).writeToPackedMemory(backing_ty, pt, buffer, bit_offset); |
| 564 | } | 570 | } |
| 565 | }, | 571 | }, |
| 566 | } | 572 | } |
| ... | @@ -568,16 +574,16 @@ pub fn writeToPackedMemory( | ... | @@ -568,16 +574,16 @@ pub fn writeToPackedMemory( |
| 568 | .Pointer => { | 574 | .Pointer => { |
| 569 | assert(!ty.isSlice(mod)); // No well defined layout. | 575 | assert(!ty.isSlice(mod)); // No well defined layout. |
| 570 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; | 576 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; |
| 571 | return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset); | 577 | return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset); |
| 572 | }, | 578 | }, |
| 573 | .Optional => { | 579 | .Optional => { |
| 574 | assert(ty.isPtrLikeOptional(mod)); | 580 | assert(ty.isPtrLikeOptional(mod)); |
| 575 | const child = ty.optionalChild(mod); | 581 | const child = ty.optionalChild(mod); |
| 576 | const opt_val = val.optionalValue(mod); | 582 | const opt_val = val.optionalValue(mod); |
| 577 | if (opt_val) |some| { | 583 | if (opt_val) |some| { |
| 578 | return some.writeToPackedMemory(child, mod, buffer, bit_offset); | 584 | return some.writeToPackedMemory(child, pt, buffer, bit_offset); |
| 579 | } else { | 585 | } else { |
| 580 | return writeToPackedMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer, bit_offset); | 586 | return writeToPackedMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer, bit_offset); |
| 581 | } | 587 | } |
| 582 | }, | 588 | }, |
| 583 | else => @panic("TODO implement writeToPackedMemory for more types"), | 589 | else => @panic("TODO implement writeToPackedMemory for more types"), |
| ... | @@ -590,7 +596,7 @@ pub fn writeToPackedMemory( | ... | @@ -590,7 +596,7 @@ pub fn writeToPackedMemory( |
| 590 | /// the end of the value in memory. | 596 | /// the end of the value in memory. |
| 591 | pub fn readFromMemory( | 597 | pub fn readFromMemory( |
| 592 | ty: Type, | 598 | ty: Type, |
| 593 | mod: *Module, | 599 | pt: Zcu.PerThread, |
| 594 | buffer: []const u8, | 600 | buffer: []const u8, |
| 595 | arena: Allocator, | 601 | arena: Allocator, |
| 596 | ) error{ | 602 | ) error{ |
| ... | @@ -598,6 +604,7 @@ pub fn readFromMemory( | ... | @@ -598,6 +604,7 @@ pub fn readFromMemory( |
| 598 | Unimplemented, | 604 | Unimplemented, |
| 599 | OutOfMemory, | 605 | OutOfMemory, |
| 600 | }!Value { | 606 | }!Value { |
| 607 | const mod = pt.zcu; | ||
| 601 | const ip = &mod.intern_pool; | 608 | const ip = &mod.intern_pool; |
| 602 | const target = mod.getTarget(); | 609 | const target = mod.getTarget(); |
| 603 | const endian = target.cpu.arch.endian(); | 610 | const endian = target.cpu.arch.endian(); |
| ... | @@ -642,7 +649,7 @@ pub fn readFromMemory( | ... | @@ -642,7 +649,7 @@ pub fn readFromMemory( |
| 642 | return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty); | 649 | return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty); |
| 643 | } | 650 | } |
| 644 | }, | 651 | }, |
| 645 | .Float => return Value.fromInterned((try mod.intern(.{ .float = .{ | 652 | .Float => return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 646 | .ty = ty.toIntern(), | 653 | .ty = ty.toIntern(), |
| 647 | .storage = switch (ty.floatBits(target)) { | 654 | .storage = switch (ty.floatBits(target)) { |
| 648 | 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) }, | 655 | 16 => .{ .f16 = @bitCast(std.mem.readInt(u16, buffer[0..2], endian)) }, |
| ... | @@ -652,25 +659,25 @@ pub fn readFromMemory( | ... | @@ -652,25 +659,25 @@ pub fn readFromMemory( |
| 652 | 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) }, | 659 | 128 => .{ .f128 = @bitCast(std.mem.readInt(u128, buffer[0..16], endian)) }, |
| 653 | else => unreachable, | 660 | else => unreachable, |
| 654 | }, | 661 | }, |
| 655 | } }))), | 662 | } })), |
| 656 | .Array => { | 663 | .Array => { |
| 657 | const elem_ty = ty.childType(mod); | 664 | const elem_ty = ty.childType(mod); |
| 658 | const elem_size = elem_ty.abiSize(mod); | 665 | const elem_size = elem_ty.abiSize(pt); |
| 659 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); | 666 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); |
| 660 | var offset: usize = 0; | 667 | var offset: usize = 0; |
| 661 | for (elems) |*elem| { | 668 | for (elems) |*elem| { |
| 662 | elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern(); | 669 | elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern(); |
| 663 | offset += @intCast(elem_size); | 670 | offset += @intCast(elem_size); |
| 664 | } | 671 | } |
| 665 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 672 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 666 | .ty = ty.toIntern(), | 673 | .ty = ty.toIntern(), |
| 667 | .storage = .{ .elems = elems }, | 674 | .storage = .{ .elems = elems }, |
| 668 | } }))); | 675 | } })); |
| 669 | }, | 676 | }, |
| 670 | .Vector => { | 677 | .Vector => { |
| 671 | // We use byte_count instead of abi_size here, so that any padding bytes | 678 | // We use byte_count instead of abi_size here, so that any padding bytes |
| 672 | // follow the data bytes, on both big- and little-endian systems. | 679 | // follow the data bytes, on both big- and little-endian systems. |
| 673 | const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8; | 680 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; |
| 674 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | 681 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); |
| 675 | }, | 682 | }, |
| 676 | .Struct => { | 683 | .Struct => { |
| ... | @@ -683,16 +690,16 @@ pub fn readFromMemory( | ... | @@ -683,16 +690,16 @@ pub fn readFromMemory( |
| 683 | for (field_vals, 0..) |*field_val, i| { | 690 | for (field_vals, 0..) |*field_val, i| { |
| 684 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); | 691 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); |
| 685 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); | 692 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); |
| 686 | const sz: usize = @intCast(field_ty.abiSize(mod)); | 693 | const sz: usize = @intCast(field_ty.abiSize(pt)); |
| 687 | field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern(); | 694 | field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern(); |
| 688 | } | 695 | } |
| 689 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 696 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 690 | .ty = ty.toIntern(), | 697 | .ty = ty.toIntern(), |
| 691 | .storage = .{ .elems = field_vals }, | 698 | .storage = .{ .elems = field_vals }, |
| 692 | } }))); | 699 | } })); |
| 693 | }, | 700 | }, |
| 694 | .@"packed" => { | 701 | .@"packed" => { |
| 695 | const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8; | 702 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; |
| 696 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | 703 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); |
| 697 | }, | 704 | }, |
| 698 | } | 705 | } |
| ... | @@ -704,49 +711,49 @@ pub fn readFromMemory( | ... | @@ -704,49 +711,49 @@ pub fn readFromMemory( |
| 704 | const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits)); | 711 | const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits)); |
| 705 | const name = mod.global_error_set.keys()[@intCast(index)]; | 712 | const name = mod.global_error_set.keys()[@intCast(index)]; |
| 706 | 713 | ||
| 707 | return Value.fromInterned((try mod.intern(.{ .err = .{ | 714 | return Value.fromInterned(try pt.intern(.{ .err = .{ |
| 708 | .ty = ty.toIntern(), | 715 | .ty = ty.toIntern(), |
| 709 | .name = name, | 716 | .name = name, |
| 710 | } }))); | 717 | } })); |
| 711 | }, | 718 | }, |
| 712 | .Union => switch (ty.containerLayout(mod)) { | 719 | .Union => switch (ty.containerLayout(mod)) { |
| 713 | .auto => return error.IllDefinedMemoryLayout, | 720 | .auto => return error.IllDefinedMemoryLayout, |
| 714 | .@"extern" => { | 721 | .@"extern" => { |
| 715 | const union_size = ty.abiSize(mod); | 722 | const union_size = ty.abiSize(pt); |
| 716 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); | 723 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); |
| 717 | const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern(); | 724 | const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern(); |
| 718 | return Value.fromInterned((try mod.intern(.{ .un = .{ | 725 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 719 | .ty = ty.toIntern(), | 726 | .ty = ty.toIntern(), |
| 720 | .tag = .none, | 727 | .tag = .none, |
| 721 | .val = val, | 728 | .val = val, |
| 722 | } }))); | 729 | } })); |
| 723 | }, | 730 | }, |
| 724 | .@"packed" => { | 731 | .@"packed" => { |
| 725 | const byte_count = (@as(usize, @intCast(ty.bitSize(mod))) + 7) / 8; | 732 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; |
| 726 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | 733 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); |
| 727 | }, | 734 | }, |
| 728 | }, | 735 | }, |
| 729 | .Pointer => { | 736 | .Pointer => { |
| 730 | assert(!ty.isSlice(mod)); // No well defined layout. | 737 | assert(!ty.isSlice(mod)); // No well defined layout. |
| 731 | const int_val = try readFromMemory(Type.usize, mod, buffer, arena); | 738 | const int_val = try readFromMemory(Type.usize, mod, buffer, arena); |
| 732 | return Value.fromInterned((try mod.intern(.{ .ptr = .{ | 739 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 733 | .ty = ty.toIntern(), | 740 | .ty = ty.toIntern(), |
| 734 | .base_addr = .int, | 741 | .base_addr = .int, |
| 735 | .byte_offset = int_val.toUnsignedInt(mod), | 742 | .byte_offset = int_val.toUnsignedInt(pt), |
| 736 | } }))); | 743 | } })); |
| 737 | }, | 744 | }, |
| 738 | .Optional => { | 745 | .Optional => { |
| 739 | assert(ty.isPtrLikeOptional(mod)); | 746 | assert(ty.isPtrLikeOptional(mod)); |
| 740 | const child_ty = ty.optionalChild(mod); | 747 | const child_ty = ty.optionalChild(mod); |
| 741 | const child_val = try readFromMemory(child_ty, mod, buffer, arena); | 748 | const child_val = try readFromMemory(child_ty, mod, buffer, arena); |
| 742 | return Value.fromInterned((try mod.intern(.{ .opt = .{ | 749 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 743 | .ty = ty.toIntern(), | 750 | .ty = ty.toIntern(), |
| 744 | .val = switch (child_val.orderAgainstZero(mod)) { | 751 | .val = switch (child_val.orderAgainstZero(pt)) { |
| 745 | .lt => unreachable, | 752 | .lt => unreachable, |
| 746 | .eq => .none, | 753 | .eq => .none, |
| 747 | .gt => child_val.toIntern(), | 754 | .gt => child_val.toIntern(), |
| 748 | }, | 755 | }, |
| 749 | } }))); | 756 | } })); |
| 750 | }, | 757 | }, |
| 751 | else => return error.Unimplemented, | 758 | else => return error.Unimplemented, |
| 752 | } | 759 | } |
| ... | @@ -758,7 +765,7 @@ pub fn readFromMemory( | ... | @@ -758,7 +765,7 @@ pub fn readFromMemory( |
| 758 | /// big-endian packed memory layouts start at the end of the buffer. | 765 | /// big-endian packed memory layouts start at the end of the buffer. |
| 759 | pub fn readFromPackedMemory( | 766 | pub fn readFromPackedMemory( |
| 760 | ty: Type, | 767 | ty: Type, |
| 761 | mod: *Module, | 768 | pt: Zcu.PerThread, |
| 762 | buffer: []const u8, | 769 | buffer: []const u8, |
| 763 | bit_offset: usize, | 770 | bit_offset: usize, |
| 764 | arena: Allocator, | 771 | arena: Allocator, |
| ... | @@ -766,6 +773,7 @@ pub fn readFromPackedMemory( | ... | @@ -766,6 +773,7 @@ pub fn readFromPackedMemory( |
| 766 | IllDefinedMemoryLayout, | 773 | IllDefinedMemoryLayout, |
| 767 | OutOfMemory, | 774 | OutOfMemory, |
| 768 | }!Value { | 775 | }!Value { |
| 776 | const mod = pt.zcu; | ||
| 769 | const ip = &mod.intern_pool; | 777 | const ip = &mod.intern_pool; |
| 770 | const target = mod.getTarget(); | 778 | const target = mod.getTarget(); |
| 771 | const endian = target.cpu.arch.endian(); | 779 | const endian = target.cpu.arch.endian(); |
| ... | @@ -783,35 +791,35 @@ pub fn readFromPackedMemory( | ... | @@ -783,35 +791,35 @@ pub fn readFromPackedMemory( |
| 783 | } | 791 | } |
| 784 | }, | 792 | }, |
| 785 | .Int => { | 793 | .Int => { |
| 786 | if (buffer.len == 0) return mod.intValue(ty, 0); | 794 | if (buffer.len == 0) return pt.intValue(ty, 0); |
| 787 | const int_info = ty.intInfo(mod); | 795 | const int_info = ty.intInfo(mod); |
| 788 | const bits = int_info.bits; | 796 | const bits = int_info.bits; |
| 789 | if (bits == 0) return mod.intValue(ty, 0); | 797 | if (bits == 0) return pt.intValue(ty, 0); |
| 790 | 798 | ||
| 791 | // Fast path for integers <= u64 | 799 | // Fast path for integers <= u64 |
| 792 | if (bits <= 64) switch (int_info.signedness) { | 800 | if (bits <= 64) switch (int_info.signedness) { |
| 793 | // Use different backing types for unsigned vs signed to avoid the need to go via | 801 | // Use different backing types for unsigned vs signed to avoid the need to go via |
| 794 | // a larger type like `i128`. | 802 | // a larger type like `i128`. |
| 795 | .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), | 803 | .unsigned => return pt.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), |
| 796 | .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), | 804 | .signed => return pt.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), |
| 797 | }; | 805 | }; |
| 798 | 806 | ||
| 799 | // Slow path, we have to construct a big-int | 807 | // Slow path, we have to construct a big-int |
| 800 | const abi_size: usize = @intCast(ty.abiSize(mod)); | 808 | const abi_size: usize = @intCast(ty.abiSize(pt)); |
| 801 | const Limb = std.math.big.Limb; | 809 | const Limb = std.math.big.Limb; |
| 802 | const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb); | 810 | const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb); |
| 803 | const limbs_buffer = try arena.alloc(Limb, limb_count); | 811 | const limbs_buffer = try arena.alloc(Limb, limb_count); |
| 804 | 812 | ||
| 805 | var bigint = BigIntMutable.init(limbs_buffer, 0); | 813 | var bigint = BigIntMutable.init(limbs_buffer, 0); |
| 806 | bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness); | 814 | bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness); |
| 807 | return mod.intValue_big(ty, bigint.toConst()); | 815 | return pt.intValue_big(ty, bigint.toConst()); |
| 808 | }, | 816 | }, |
| 809 | .Enum => { | 817 | .Enum => { |
| 810 | const int_ty = ty.intTagType(mod); | 818 | const int_ty = ty.intTagType(mod); |
| 811 | const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena); | 819 | const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, arena); |
| 812 | return mod.getCoerced(int_val, ty); | 820 | return pt.getCoerced(int_val, ty); |
| 813 | }, | 821 | }, |
| 814 | .Float => return Value.fromInterned((try mod.intern(.{ .float = .{ | 822 | .Float => return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 815 | .ty = ty.toIntern(), | 823 | .ty = ty.toIntern(), |
| 816 | .storage = switch (ty.floatBits(target)) { | 824 | .storage = switch (ty.floatBits(target)) { |
| 817 | 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) }, | 825 | 16 => .{ .f16 = @bitCast(std.mem.readPackedInt(u16, buffer, bit_offset, endian)) }, |
| ... | @@ -821,23 +829,23 @@ pub fn readFromPackedMemory( | ... | @@ -821,23 +829,23 @@ pub fn readFromPackedMemory( |
| 821 | 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) }, | 829 | 128 => .{ .f128 = @bitCast(std.mem.readPackedInt(u128, buffer, bit_offset, endian)) }, |
| 822 | else => unreachable, | 830 | else => unreachable, |
| 823 | }, | 831 | }, |
| 824 | } }))), | 832 | } })), |
| 825 | .Vector => { | 833 | .Vector => { |
| 826 | const elem_ty = ty.childType(mod); | 834 | const elem_ty = ty.childType(mod); |
| 827 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); | 835 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); |
| 828 | 836 | ||
| 829 | var bits: u16 = 0; | 837 | var bits: u16 = 0; |
| 830 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(mod)); | 838 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt)); |
| 831 | for (elems, 0..) |_, i| { | 839 | for (elems, 0..) |_, i| { |
| 832 | // On big-endian systems, LLVM reverses the element order of vectors by default | 840 | // On big-endian systems, LLVM reverses the element order of vectors by default |
| 833 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; | 841 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; |
| 834 | elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); | 842 | elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, pt, buffer, bit_offset + bits, arena)).toIntern(); |
| 835 | bits += elem_bit_size; | 843 | bits += elem_bit_size; |
| 836 | } | 844 | } |
| 837 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 845 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 838 | .ty = ty.toIntern(), | 846 | .ty = ty.toIntern(), |
| 839 | .storage = .{ .elems = elems }, | 847 | .storage = .{ .elems = elems }, |
| 840 | } }))); | 848 | } })); |
| 841 | }, | 849 | }, |
| 842 | .Struct => { | 850 | .Struct => { |
| 843 | // Sema is supposed to have emitted a compile error already for Auto layout structs, | 851 | // Sema is supposed to have emitted a compile error already for Auto layout structs, |
| ... | @@ -847,43 +855,43 @@ pub fn readFromPackedMemory( | ... | @@ -847,43 +855,43 @@ pub fn readFromPackedMemory( |
| 847 | const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len); | 855 | const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len); |
| 848 | for (field_vals, 0..) |*field_val, i| { | 856 | for (field_vals, 0..) |*field_val, i| { |
| 849 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 857 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 850 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); | 858 | const field_bits: u16 = @intCast(field_ty.bitSize(pt)); |
| 851 | field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); | 859 | field_val.* = (try readFromPackedMemory(field_ty, pt, buffer, bit_offset + bits, arena)).toIntern(); |
| 852 | bits += field_bits; | 860 | bits += field_bits; |
| 853 | } | 861 | } |
| 854 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 862 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 855 | .ty = ty.toIntern(), | 863 | .ty = ty.toIntern(), |
| 856 | .storage = .{ .elems = field_vals }, | 864 | .storage = .{ .elems = field_vals }, |
| 857 | } }))); | 865 | } })); |
| 858 | }, | 866 | }, |
| 859 | .Union => switch (ty.containerLayout(mod)) { | 867 | .Union => switch (ty.containerLayout(mod)) { |
| 860 | .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory | 868 | .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory |
| 861 | .@"packed" => { | 869 | .@"packed" => { |
| 862 | const backing_ty = try ty.unionBackingType(mod); | 870 | const backing_ty = try ty.unionBackingType(pt); |
| 863 | const val = (try readFromPackedMemory(backing_ty, mod, buffer, bit_offset, arena)).toIntern(); | 871 | const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern(); |
| 864 | return Value.fromInterned((try mod.intern(.{ .un = .{ | 872 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 865 | .ty = ty.toIntern(), | 873 | .ty = ty.toIntern(), |
| 866 | .tag = .none, | 874 | .tag = .none, |
| 867 | .val = val, | 875 | .val = val, |
| 868 | } }))); | 876 | } })); |
| 869 | }, | 877 | }, |
| 870 | }, | 878 | }, |
| 871 | .Pointer => { | 879 | .Pointer => { |
| 872 | assert(!ty.isSlice(mod)); // No well defined layout. | 880 | assert(!ty.isSlice(mod)); // No well defined layout. |
| 873 | const int_val = try readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena); | 881 | const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena); |
| 874 | return Value.fromInterned(try mod.intern(.{ .ptr = .{ | 882 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 875 | .ty = ty.toIntern(), | 883 | .ty = ty.toIntern(), |
| 876 | .base_addr = .int, | 884 | .base_addr = .int, |
| 877 | .byte_offset = int_val.toUnsignedInt(mod), | 885 | .byte_offset = int_val.toUnsignedInt(pt), |
| 878 | } })); | 886 | } })); |
| 879 | }, | 887 | }, |
| 880 | .Optional => { | 888 | .Optional => { |
| 881 | assert(ty.isPtrLikeOptional(mod)); | 889 | assert(ty.isPtrLikeOptional(mod)); |
| 882 | const child_ty = ty.optionalChild(mod); | 890 | const child_ty = ty.optionalChild(mod); |
| 883 | const child_val = try readFromPackedMemory(child_ty, mod, buffer, bit_offset, arena); | 891 | const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena); |
| 884 | return Value.fromInterned(try mod.intern(.{ .opt = .{ | 892 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 885 | .ty = ty.toIntern(), | 893 | .ty = ty.toIntern(), |
| 886 | .val = switch (child_val.orderAgainstZero(mod)) { | 894 | .val = switch (child_val.orderAgainstZero(pt)) { |
| 887 | .lt => unreachable, | 895 | .lt => unreachable, |
| 888 | .eq => .none, | 896 | .eq => .none, |
| 889 | .gt => child_val.toIntern(), | 897 | .gt => child_val.toIntern(), |
| ... | @@ -895,8 +903,8 @@ pub fn readFromPackedMemory( | ... | @@ -895,8 +903,8 @@ pub fn readFromPackedMemory( |
| 895 | } | 903 | } |
| 896 | 904 | ||
| 897 | /// Asserts that the value is a float or an integer. | 905 | /// Asserts that the value is a float or an integer. |
| 898 | pub fn toFloat(val: Value, comptime T: type, mod: *Module) T { | 906 | pub fn toFloat(val: Value, comptime T: type, pt: Zcu.PerThread) T { |
| 899 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 907 | return switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 900 | .int => |int| switch (int.storage) { | 908 | .int => |int| switch (int.storage) { |
| 901 | .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)), | 909 | .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)), |
| 902 | inline .u64, .i64 => |x| { | 910 | inline .u64, .i64 => |x| { |
| ... | @@ -905,8 +913,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T { | ... | @@ -905,8 +913,8 @@ pub fn toFloat(val: Value, comptime T: type, mod: *Module) T { |
| 905 | } | 913 | } |
| 906 | return @floatFromInt(x); | 914 | return @floatFromInt(x); |
| 907 | }, | 915 | }, |
| 908 | .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0), | 916 | .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0), |
| 909 | .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(mod)), | 917 | .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(pt)), |
| 910 | }, | 918 | }, |
| 911 | .float => |float| switch (float.storage) { | 919 | .float => |float| switch (float.storage) { |
| 912 | inline else => |x| @floatCast(x), | 920 | inline else => |x| @floatCast(x), |
| ... | @@ -934,29 +942,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 { | ... | @@ -934,29 +942,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 { |
| 934 | } | 942 | } |
| 935 | } | 943 | } |
| 936 | 944 | ||
| 937 | pub fn clz(val: Value, ty: Type, mod: *Module) u64 { | 945 | pub fn clz(val: Value, ty: Type, pt: Zcu.PerThread) u64 { |
| 938 | var bigint_buf: BigIntSpace = undefined; | 946 | var bigint_buf: BigIntSpace = undefined; |
| 939 | const bigint = val.toBigInt(&bigint_buf, mod); | 947 | const bigint = val.toBigInt(&bigint_buf, pt); |
| 940 | return bigint.clz(ty.intInfo(mod).bits); | 948 | return bigint.clz(ty.intInfo(pt.zcu).bits); |
| 941 | } | 949 | } |
| 942 | 950 | ||
| 943 | pub fn ctz(val: Value, ty: Type, mod: *Module) u64 { | 951 | pub fn ctz(val: Value, ty: Type, pt: Zcu.PerThread) u64 { |
| 944 | var bigint_buf: BigIntSpace = undefined; | 952 | var bigint_buf: BigIntSpace = undefined; |
| 945 | const bigint = val.toBigInt(&bigint_buf, mod); | 953 | const bigint = val.toBigInt(&bigint_buf, pt); |
| 946 | return bigint.ctz(ty.intInfo(mod).bits); | 954 | return bigint.ctz(ty.intInfo(pt.zcu).bits); |
| 947 | } | 955 | } |
| 948 | 956 | ||
| 949 | pub fn popCount(val: Value, ty: Type, mod: *Module) u64 { | 957 | pub fn popCount(val: Value, ty: Type, pt: Zcu.PerThread) u64 { |
| 950 | var bigint_buf: BigIntSpace = undefined; | 958 | var bigint_buf: BigIntSpace = undefined; |
| 951 | const bigint = val.toBigInt(&bigint_buf, mod); | 959 | const bigint = val.toBigInt(&bigint_buf, pt); |
| 952 | return @intCast(bigint.popCount(ty.intInfo(mod).bits)); | 960 | return @intCast(bigint.popCount(ty.intInfo(pt.zcu).bits)); |
| 953 | } | 961 | } |
| 954 | 962 | ||
| 955 | pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { | 963 | pub fn bitReverse(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value { |
| 964 | const mod = pt.zcu; | ||
| 956 | const info = ty.intInfo(mod); | 965 | const info = ty.intInfo(mod); |
| 957 | 966 | ||
| 958 | var buffer: Value.BigIntSpace = undefined; | 967 | var buffer: Value.BigIntSpace = undefined; |
| 959 | const operand_bigint = val.toBigInt(&buffer, mod); | 968 | const operand_bigint = val.toBigInt(&buffer, pt); |
| 960 | 969 | ||
| 961 | const limbs = try arena.alloc( | 970 | const limbs = try arena.alloc( |
| 962 | std.math.big.Limb, | 971 | std.math.big.Limb, |
| ... | @@ -965,17 +974,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { | ... | @@ -965,17 +974,18 @@ pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { |
| 965 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 974 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 966 | result_bigint.bitReverse(operand_bigint, info.signedness, info.bits); | 975 | result_bigint.bitReverse(operand_bigint, info.signedness, info.bits); |
| 967 | 976 | ||
| 968 | return mod.intValue_big(ty, result_bigint.toConst()); | 977 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 969 | } | 978 | } |
| 970 | 979 | ||
| 971 | pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { | 980 | pub fn byteSwap(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value { |
| 981 | const mod = pt.zcu; | ||
| 972 | const info = ty.intInfo(mod); | 982 | const info = ty.intInfo(mod); |
| 973 | 983 | ||
| 974 | // Bit count must be evenly divisible by 8 | 984 | // Bit count must be evenly divisible by 8 |
| 975 | assert(info.bits % 8 == 0); | 985 | assert(info.bits % 8 == 0); |
| 976 | 986 | ||
| 977 | var buffer: Value.BigIntSpace = undefined; | 987 | var buffer: Value.BigIntSpace = undefined; |
| 978 | const operand_bigint = val.toBigInt(&buffer, mod); | 988 | const operand_bigint = val.toBigInt(&buffer, pt); |
| 979 | 989 | ||
| 980 | const limbs = try arena.alloc( | 990 | const limbs = try arena.alloc( |
| 981 | std.math.big.Limb, | 991 | std.math.big.Limb, |
| ... | @@ -984,33 +994,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { | ... | @@ -984,33 +994,33 @@ pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value { |
| 984 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 994 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 985 | result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8); | 995 | result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8); |
| 986 | 996 | ||
| 987 | return mod.intValue_big(ty, result_bigint.toConst()); | 997 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 988 | } | 998 | } |
| 989 | 999 | ||
| 990 | /// Asserts the value is an integer and not undefined. | 1000 | /// Asserts the value is an integer and not undefined. |
| 991 | /// Returns the number of bits the value requires to represent stored in twos complement form. | 1001 | /// Returns the number of bits the value requires to represent stored in twos complement form. |
| 992 | pub fn intBitCountTwosComp(self: Value, mod: *Module) usize { | 1002 | pub fn intBitCountTwosComp(self: Value, pt: Zcu.PerThread) usize { |
| 993 | var buffer: BigIntSpace = undefined; | 1003 | var buffer: BigIntSpace = undefined; |
| 994 | const big_int = self.toBigInt(&buffer, mod); | 1004 | const big_int = self.toBigInt(&buffer, pt); |
| 995 | return big_int.bitCountTwosComp(); | 1005 | return big_int.bitCountTwosComp(); |
| 996 | } | 1006 | } |
| 997 | 1007 | ||
| 998 | /// Converts an integer or a float to a float. May result in a loss of information. | 1008 | /// Converts an integer or a float to a float. May result in a loss of information. |
| 999 | /// Caller can find out by equality checking the result against the operand. | 1009 | /// Caller can find out by equality checking the result against the operand. |
| 1000 | pub fn floatCast(val: Value, dest_ty: Type, zcu: *Zcu) !Value { | 1010 | pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value { |
| 1001 | const target = zcu.getTarget(); | 1011 | const target = pt.zcu.getTarget(); |
| 1002 | if (val.isUndef(zcu)) return zcu.undefValue(dest_ty); | 1012 | if (val.isUndef(pt.zcu)) return pt.undefValue(dest_ty); |
| 1003 | return Value.fromInterned((try zcu.intern(.{ .float = .{ | 1013 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 1004 | .ty = dest_ty.toIntern(), | 1014 | .ty = dest_ty.toIntern(), |
| 1005 | .storage = switch (dest_ty.floatBits(target)) { | 1015 | .storage = switch (dest_ty.floatBits(target)) { |
| 1006 | 16 => .{ .f16 = val.toFloat(f16, zcu) }, | 1016 | 16 => .{ .f16 = val.toFloat(f16, pt) }, |
| 1007 | 32 => .{ .f32 = val.toFloat(f32, zcu) }, | 1017 | 32 => .{ .f32 = val.toFloat(f32, pt) }, |
| 1008 | 64 => .{ .f64 = val.toFloat(f64, zcu) }, | 1018 | 64 => .{ .f64 = val.toFloat(f64, pt) }, |
| 1009 | 80 => .{ .f80 = val.toFloat(f80, zcu) }, | 1019 | 80 => .{ .f80 = val.toFloat(f80, pt) }, |
| 1010 | 128 => .{ .f128 = val.toFloat(f128, zcu) }, | 1020 | 128 => .{ .f128 = val.toFloat(f128, pt) }, |
| 1011 | else => unreachable, | 1021 | else => unreachable, |
| 1012 | }, | 1022 | }, |
| 1013 | } }))); | 1023 | } })); |
| 1014 | } | 1024 | } |
| 1015 | 1025 | ||
| 1016 | /// Asserts the value is a float | 1026 | /// Asserts the value is a float |
| ... | @@ -1023,19 +1033,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool { | ... | @@ -1023,19 +1033,19 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool { |
| 1023 | }; | 1033 | }; |
| 1024 | } | 1034 | } |
| 1025 | 1035 | ||
| 1026 | pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order { | 1036 | pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order { |
| 1027 | return orderAgainstZeroAdvanced(lhs, mod, .normal) catch unreachable; | 1037 | return orderAgainstZeroAdvanced(lhs, pt, .normal) catch unreachable; |
| 1028 | } | 1038 | } |
| 1029 | 1039 | ||
| 1030 | pub fn orderAgainstZeroAdvanced( | 1040 | pub fn orderAgainstZeroAdvanced( |
| 1031 | lhs: Value, | 1041 | lhs: Value, |
| 1032 | mod: *Module, | 1042 | pt: Zcu.PerThread, |
| 1033 | strat: ResolveStrat, | 1043 | strat: ResolveStrat, |
| 1034 | ) Module.CompileError!std.math.Order { | 1044 | ) Module.CompileError!std.math.Order { |
| 1035 | return switch (lhs.toIntern()) { | 1045 | return switch (lhs.toIntern()) { |
| 1036 | .bool_false => .eq, | 1046 | .bool_false => .eq, |
| 1037 | .bool_true => .gt, | 1047 | .bool_true => .gt, |
| 1038 | else => switch (mod.intern_pool.indexToKey(lhs.toIntern())) { | 1048 | else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) { |
| 1039 | .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) { | 1049 | .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) { |
| 1040 | .decl, .comptime_alloc, .comptime_field => .gt, | 1050 | .decl, .comptime_alloc, .comptime_field => .gt, |
| 1041 | .int => .eq, | 1051 | .int => .eq, |
| ... | @@ -1046,7 +1056,7 @@ pub fn orderAgainstZeroAdvanced( | ... | @@ -1046,7 +1056,7 @@ pub fn orderAgainstZeroAdvanced( |
| 1046 | inline .u64, .i64 => |x| std.math.order(x, 0), | 1056 | inline .u64, .i64 => |x| std.math.order(x, 0), |
| 1047 | .lazy_align => .gt, // alignment is never 0 | 1057 | .lazy_align => .gt, // alignment is never 0 |
| 1048 | .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced( | 1058 | .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced( |
| 1049 | mod, | 1059 | pt, |
| 1050 | false, | 1060 | false, |
| 1051 | strat.toLazy(), | 1061 | strat.toLazy(), |
| 1052 | ) catch |err| switch (err) { | 1062 | ) catch |err| switch (err) { |
| ... | @@ -1054,7 +1064,7 @@ pub fn orderAgainstZeroAdvanced( | ... | @@ -1054,7 +1064,7 @@ pub fn orderAgainstZeroAdvanced( |
| 1054 | else => |e| return e, | 1064 | else => |e| return e, |
| 1055 | }) .gt else .eq, | 1065 | }) .gt else .eq, |
| 1056 | }, | 1066 | }, |
| 1057 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(mod, strat), | 1067 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(pt, strat), |
| 1058 | .float => |float| switch (float.storage) { | 1068 | .float => |float| switch (float.storage) { |
| 1059 | inline else => |x| std.math.order(x, 0), | 1069 | inline else => |x| std.math.order(x, 0), |
| 1060 | }, | 1070 | }, |
| ... | @@ -1064,14 +1074,14 @@ pub fn orderAgainstZeroAdvanced( | ... | @@ -1064,14 +1074,14 @@ pub fn orderAgainstZeroAdvanced( |
| 1064 | } | 1074 | } |
| 1065 | 1075 | ||
| 1066 | /// Asserts the value is comparable. | 1076 | /// Asserts the value is comparable. |
| 1067 | pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order { | 1077 | pub fn order(lhs: Value, rhs: Value, pt: Zcu.PerThread) std.math.Order { |
| 1068 | return orderAdvanced(lhs, rhs, mod, .normal) catch unreachable; | 1078 | return orderAdvanced(lhs, rhs, pt, .normal) catch unreachable; |
| 1069 | } | 1079 | } |
| 1070 | 1080 | ||
| 1071 | /// Asserts the value is comparable. | 1081 | /// Asserts the value is comparable. |
| 1072 | pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) !std.math.Order { | 1082 | pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, strat: ResolveStrat) !std.math.Order { |
| 1073 | const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, strat); | 1083 | const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat); |
| 1074 | const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, strat); | 1084 | const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat); |
| 1075 | switch (lhs_against_zero) { | 1085 | switch (lhs_against_zero) { |
| 1076 | .lt => if (rhs_against_zero != .lt) return .lt, | 1086 | .lt => if (rhs_against_zero != .lt) return .lt, |
| 1077 | .eq => return rhs_against_zero.invert(), | 1087 | .eq => return rhs_against_zero.invert(), |
| ... | @@ -1083,34 +1093,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) | ... | @@ -1083,34 +1093,34 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) |
| 1083 | .gt => {}, | 1093 | .gt => {}, |
| 1084 | } | 1094 | } |
| 1085 | 1095 | ||
| 1086 | if (lhs.isFloat(mod) or rhs.isFloat(mod)) { | 1096 | if (lhs.isFloat(pt.zcu) or rhs.isFloat(pt.zcu)) { |
| 1087 | const lhs_f128 = lhs.toFloat(f128, mod); | 1097 | const lhs_f128 = lhs.toFloat(f128, pt); |
| 1088 | const rhs_f128 = rhs.toFloat(f128, mod); | 1098 | const rhs_f128 = rhs.toFloat(f128, pt); |
| 1089 | return std.math.order(lhs_f128, rhs_f128); | 1099 | return std.math.order(lhs_f128, rhs_f128); |
| 1090 | } | 1100 | } |
| 1091 | 1101 | ||
| 1092 | var lhs_bigint_space: BigIntSpace = undefined; | 1102 | var lhs_bigint_space: BigIntSpace = undefined; |
| 1093 | var rhs_bigint_space: BigIntSpace = undefined; | 1103 | var rhs_bigint_space: BigIntSpace = undefined; |
| 1094 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, strat); | 1104 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, pt, strat); |
| 1095 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, strat); | 1105 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, pt, strat); |
| 1096 | return lhs_bigint.order(rhs_bigint); | 1106 | return lhs_bigint.order(rhs_bigint); |
| 1097 | } | 1107 | } |
| 1098 | 1108 | ||
| 1099 | /// Asserts the value is comparable. Does not take a type parameter because it supports | 1109 | /// Asserts the value is comparable. Does not take a type parameter because it supports |
| 1100 | /// comparisons between heterogeneous types. | 1110 | /// comparisons between heterogeneous types. |
| 1101 | pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool { | 1111 | pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) bool { |
| 1102 | return compareHeteroAdvanced(lhs, op, rhs, mod, .normal) catch unreachable; | 1112 | return compareHeteroAdvanced(lhs, op, rhs, pt, .normal) catch unreachable; |
| 1103 | } | 1113 | } |
| 1104 | 1114 | ||
| 1105 | pub fn compareHeteroAdvanced( | 1115 | pub fn compareHeteroAdvanced( |
| 1106 | lhs: Value, | 1116 | lhs: Value, |
| 1107 | op: std.math.CompareOperator, | 1117 | op: std.math.CompareOperator, |
| 1108 | rhs: Value, | 1118 | rhs: Value, |
| 1109 | mod: *Module, | 1119 | pt: Zcu.PerThread, |
| 1110 | strat: ResolveStrat, | 1120 | strat: ResolveStrat, |
| 1111 | ) !bool { | 1121 | ) !bool { |
| 1112 | if (lhs.pointerDecl(mod)) |lhs_decl| { | 1122 | if (lhs.pointerDecl(pt.zcu)) |lhs_decl| { |
| 1113 | if (rhs.pointerDecl(mod)) |rhs_decl| { | 1123 | if (rhs.pointerDecl(pt.zcu)) |rhs_decl| { |
| 1114 | switch (op) { | 1124 | switch (op) { |
| 1115 | .eq => return lhs_decl == rhs_decl, | 1125 | .eq => return lhs_decl == rhs_decl, |
| 1116 | .neq => return lhs_decl != rhs_decl, | 1126 | .neq => return lhs_decl != rhs_decl, |
| ... | @@ -1123,31 +1133,32 @@ pub fn compareHeteroAdvanced( | ... | @@ -1123,31 +1133,32 @@ pub fn compareHeteroAdvanced( |
| 1123 | else => {}, | 1133 | else => {}, |
| 1124 | } | 1134 | } |
| 1125 | } | 1135 | } |
| 1126 | } else if (rhs.pointerDecl(mod)) |_| { | 1136 | } else if (rhs.pointerDecl(pt.zcu)) |_| { |
| 1127 | switch (op) { | 1137 | switch (op) { |
| 1128 | .eq => return false, | 1138 | .eq => return false, |
| 1129 | .neq => return true, | 1139 | .neq => return true, |
| 1130 | else => {}, | 1140 | else => {}, |
| 1131 | } | 1141 | } |
| 1132 | } | 1142 | } |
| 1133 | return (try orderAdvanced(lhs, rhs, mod, strat)).compare(op); | 1143 | return (try orderAdvanced(lhs, rhs, pt, strat)).compare(op); |
| 1134 | } | 1144 | } |
| 1135 | 1145 | ||
| 1136 | /// Asserts the values are comparable. Both operands have type `ty`. | 1146 | /// Asserts the values are comparable. Both operands have type `ty`. |
| 1137 | /// For vectors, returns true if comparison is true for ALL elements. | 1147 | /// For vectors, returns true if comparison is true for ALL elements. |
| 1138 | pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) !bool { | 1148 | pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, pt: Zcu.PerThread) !bool { |
| 1149 | const mod = pt.zcu; | ||
| 1139 | if (ty.zigTypeTag(mod) == .Vector) { | 1150 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1140 | const scalar_ty = ty.scalarType(mod); | 1151 | const scalar_ty = ty.scalarType(mod); |
| 1141 | for (0..ty.vectorLen(mod)) |i| { | 1152 | for (0..ty.vectorLen(mod)) |i| { |
| 1142 | const lhs_elem = try lhs.elemValue(mod, i); | 1153 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1143 | const rhs_elem = try rhs.elemValue(mod, i); | 1154 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1144 | if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, mod)) { | 1155 | if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, pt)) { |
| 1145 | return false; | 1156 | return false; |
| 1146 | } | 1157 | } |
| 1147 | } | 1158 | } |
| 1148 | return true; | 1159 | return true; |
| 1149 | } | 1160 | } |
| 1150 | return compareScalar(lhs, op, rhs, ty, mod); | 1161 | return compareScalar(lhs, op, rhs, ty, pt); |
| 1151 | } | 1162 | } |
| 1152 | 1163 | ||
| 1153 | /// Asserts the values are comparable. Both operands have type `ty`. | 1164 | /// Asserts the values are comparable. Both operands have type `ty`. |
| ... | @@ -1156,12 +1167,12 @@ pub fn compareScalar( | ... | @@ -1156,12 +1167,12 @@ pub fn compareScalar( |
| 1156 | op: std.math.CompareOperator, | 1167 | op: std.math.CompareOperator, |
| 1157 | rhs: Value, | 1168 | rhs: Value, |
| 1158 | ty: Type, | 1169 | ty: Type, |
| 1159 | mod: *Module, | 1170 | pt: Zcu.PerThread, |
| 1160 | ) bool { | 1171 | ) bool { |
| 1161 | return switch (op) { | 1172 | return switch (op) { |
| 1162 | .eq => lhs.eql(rhs, ty, mod), | 1173 | .eq => lhs.eql(rhs, ty, pt.zcu), |
| 1163 | .neq => !lhs.eql(rhs, ty, mod), | 1174 | .neq => !lhs.eql(rhs, ty, pt.zcu), |
| 1164 | else => compareHetero(lhs, op, rhs, mod), | 1175 | else => compareHetero(lhs, op, rhs, pt), |
| 1165 | }; | 1176 | }; |
| 1166 | } | 1177 | } |
| 1167 | 1178 | ||
| ... | @@ -1170,24 +1181,25 @@ pub fn compareScalar( | ... | @@ -1170,24 +1181,25 @@ pub fn compareScalar( |
| 1170 | /// Returns `false` if the value or any vector element is undefined. | 1181 | /// Returns `false` if the value or any vector element is undefined. |
| 1171 | /// | 1182 | /// |
| 1172 | /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)` | 1183 | /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)` |
| 1173 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool { | 1184 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, pt: Zcu.PerThread) bool { |
| 1174 | return compareAllWithZeroAdvancedExtra(lhs, op, mod, .normal) catch unreachable; | 1185 | return compareAllWithZeroAdvancedExtra(lhs, op, pt, .normal) catch unreachable; |
| 1175 | } | 1186 | } |
| 1176 | 1187 | ||
| 1177 | pub fn compareAllWithZeroSema( | 1188 | pub fn compareAllWithZeroSema( |
| 1178 | lhs: Value, | 1189 | lhs: Value, |
| 1179 | op: std.math.CompareOperator, | 1190 | op: std.math.CompareOperator, |
| 1180 | zcu: *Zcu, | 1191 | pt: Zcu.PerThread, |
| 1181 | ) Module.CompileError!bool { | 1192 | ) Module.CompileError!bool { |
| 1182 | return compareAllWithZeroAdvancedExtra(lhs, op, zcu, .sema); | 1193 | return compareAllWithZeroAdvancedExtra(lhs, op, pt, .sema); |
| 1183 | } | 1194 | } |
| 1184 | 1195 | ||
| 1185 | pub fn compareAllWithZeroAdvancedExtra( | 1196 | pub fn compareAllWithZeroAdvancedExtra( |
| 1186 | lhs: Value, | 1197 | lhs: Value, |
| 1187 | op: std.math.CompareOperator, | 1198 | op: std.math.CompareOperator, |
| 1188 | mod: *Module, | 1199 | pt: Zcu.PerThread, |
| 1189 | strat: ResolveStrat, | 1200 | strat: ResolveStrat, |
| 1190 | ) Module.CompileError!bool { | 1201 | ) Module.CompileError!bool { |
| 1202 | const mod = pt.zcu; | ||
| 1191 | if (lhs.isInf(mod)) { | 1203 | if (lhs.isInf(mod)) { |
| 1192 | switch (op) { | 1204 | switch (op) { |
| 1193 | .neq => return true, | 1205 | .neq => return true, |
| ... | @@ -1206,14 +1218,14 @@ pub fn compareAllWithZeroAdvancedExtra( | ... | @@ -1206,14 +1218,14 @@ pub fn compareAllWithZeroAdvancedExtra( |
| 1206 | if (!std.math.order(byte, 0).compare(op)) break false; | 1218 | if (!std.math.order(byte, 0).compare(op)) break false; |
| 1207 | } else true, | 1219 | } else true, |
| 1208 | .elems => |elems| for (elems) |elem| { | 1220 | .elems => |elems| for (elems) |elem| { |
| 1209 | if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat)) break false; | 1221 | if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat)) break false; |
| 1210 | } else true, | 1222 | } else true, |
| 1211 | .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat), | 1223 | .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat), |
| 1212 | }, | 1224 | }, |
| 1213 | .undef => return false, | 1225 | .undef => return false, |
| 1214 | else => {}, | 1226 | else => {}, |
| 1215 | } | 1227 | } |
| 1216 | return (try orderAgainstZeroAdvanced(lhs, mod, strat)).compare(op); | 1228 | return (try orderAgainstZeroAdvanced(lhs, pt, strat)).compare(op); |
| 1217 | } | 1229 | } |
| 1218 | 1230 | ||
| 1219 | pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool { | 1231 | pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool { |
| ... | @@ -1275,21 +1287,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value { | ... | @@ -1275,21 +1287,22 @@ pub fn slicePtr(val: Value, mod: *Module) Value { |
| 1275 | 1287 | ||
| 1276 | /// Gets the `len` field of a slice value as a `u64`. | 1288 | /// Gets the `len` field of a slice value as a `u64`. |
| 1277 | /// Resolves the length using `Sema` if necessary. | 1289 | /// Resolves the length using `Sema` if necessary. |
| 1278 | pub fn sliceLen(val: Value, zcu: *Zcu) !u64 { | 1290 | pub fn sliceLen(val: Value, pt: Zcu.PerThread) !u64 { |
| 1279 | return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(zcu); | 1291 | return Value.fromInterned(pt.zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(pt); |
| 1280 | } | 1292 | } |
| 1281 | 1293 | ||
| 1282 | /// Asserts the value is an aggregate, and returns the element value at the given index. | 1294 | /// Asserts the value is an aggregate, and returns the element value at the given index. |
| 1283 | pub fn elemValue(val: Value, zcu: *Zcu, index: usize) Allocator.Error!Value { | 1295 | pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value { |
| 1296 | const zcu = pt.zcu; | ||
| 1284 | const ip = &zcu.intern_pool; | 1297 | const ip = &zcu.intern_pool; |
| 1285 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 1298 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 1286 | .undef => |ty| { | 1299 | .undef => |ty| { |
| 1287 | return Value.fromInterned(try zcu.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() })); | 1300 | return Value.fromInterned(try pt.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() })); |
| 1288 | }, | 1301 | }, |
| 1289 | .aggregate => |aggregate| { | 1302 | .aggregate => |aggregate| { |
| 1290 | const len = ip.aggregateTypeLen(aggregate.ty); | 1303 | const len = ip.aggregateTypeLen(aggregate.ty); |
| 1291 | if (index < len) return Value.fromInterned(switch (aggregate.storage) { | 1304 | if (index < len) return Value.fromInterned(switch (aggregate.storage) { |
| 1292 | .bytes => |bytes| try zcu.intern(.{ .int = .{ | 1305 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1293 | .ty = .u8_type, | 1306 | .ty = .u8_type, |
| 1294 | .storage = .{ .u64 = bytes.at(index, ip) }, | 1307 | .storage = .{ .u64 = bytes.at(index, ip) }, |
| 1295 | } }), | 1308 | } }), |
| ... | @@ -1330,17 +1343,17 @@ pub fn sliceArray( | ... | @@ -1330,17 +1343,17 @@ pub fn sliceArray( |
| 1330 | start: usize, | 1343 | start: usize, |
| 1331 | end: usize, | 1344 | end: usize, |
| 1332 | ) error{OutOfMemory}!Value { | 1345 | ) error{OutOfMemory}!Value { |
| 1333 | const mod = sema.mod; | 1346 | const pt = sema.pt; |
| 1334 | const ip = &mod.intern_pool; | 1347 | const ip = &pt.zcu.intern_pool; |
| 1335 | return Value.fromInterned(try mod.intern(.{ | 1348 | return Value.fromInterned(try pt.intern(.{ |
| 1336 | .aggregate = .{ | 1349 | .aggregate = .{ |
| 1337 | .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) { | 1350 | .ty = switch (pt.zcu.intern_pool.indexToKey(pt.zcu.intern_pool.typeOf(val.toIntern()))) { |
| 1338 | .array_type => |array_type| try mod.arrayType(.{ | 1351 | .array_type => |array_type| try pt.arrayType(.{ |
| 1339 | .len = @intCast(end - start), | 1352 | .len = @intCast(end - start), |
| 1340 | .child = array_type.child, | 1353 | .child = array_type.child, |
| 1341 | .sentinel = if (end == array_type.len) array_type.sentinel else .none, | 1354 | .sentinel = if (end == array_type.len) array_type.sentinel else .none, |
| 1342 | }), | 1355 | }), |
| 1343 | .vector_type => |vector_type| try mod.vectorType(.{ | 1356 | .vector_type => |vector_type| try pt.vectorType(.{ |
| 1344 | .len = @intCast(end - start), | 1357 | .len = @intCast(end - start), |
| 1345 | .child = vector_type.child, | 1358 | .child = vector_type.child, |
| 1346 | }), | 1359 | }), |
| ... | @@ -1363,13 +1376,14 @@ pub fn sliceArray( | ... | @@ -1363,13 +1376,14 @@ pub fn sliceArray( |
| 1363 | })); | 1376 | })); |
| 1364 | } | 1377 | } |
| 1365 | 1378 | ||
| 1366 | pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value { | 1379 | pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value { |
| 1380 | const mod = pt.zcu; | ||
| 1367 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1381 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1368 | .undef => |ty| Value.fromInterned((try mod.intern(.{ | 1382 | .undef => |ty| Value.fromInterned(try pt.intern(.{ |
| 1369 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), | 1383 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), |
| 1370 | }))), | 1384 | })), |
| 1371 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { | 1385 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { |
| 1372 | .bytes => |bytes| try mod.intern(.{ .int = .{ | 1386 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1373 | .ty = .u8_type, | 1387 | .ty = .u8_type, |
| 1374 | .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) }, | 1388 | .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) }, |
| 1375 | } }), | 1389 | } }), |
| ... | @@ -1483,40 +1497,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, | ... | @@ -1483,40 +1497,49 @@ pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, |
| 1483 | }; | 1497 | }; |
| 1484 | } | 1498 | } |
| 1485 | 1499 | ||
| 1486 | pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value { | 1500 | pub fn floatFromIntAdvanced( |
| 1501 | val: Value, | ||
| 1502 | arena: Allocator, | ||
| 1503 | int_ty: Type, | ||
| 1504 | float_ty: Type, | ||
| 1505 | pt: Zcu.PerThread, | ||
| 1506 | strat: ResolveStrat, | ||
| 1507 | ) !Value { | ||
| 1508 | const mod = pt.zcu; | ||
| 1487 | if (int_ty.zigTypeTag(mod) == .Vector) { | 1509 | if (int_ty.zigTypeTag(mod) == .Vector) { |
| 1488 | const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod)); | 1510 | const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod)); |
| 1489 | const scalar_ty = float_ty.scalarType(mod); | 1511 | const scalar_ty = float_ty.scalarType(mod); |
| 1490 | for (result_data, 0..) |*scalar, i| { | 1512 | for (result_data, 0..) |*scalar, i| { |
| 1491 | const elem_val = try val.elemValue(mod, i); | 1513 | const elem_val = try val.elemValue(pt, i); |
| 1492 | scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, strat)).toIntern(); | 1514 | scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, pt, strat)).toIntern(); |
| 1493 | } | 1515 | } |
| 1494 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1516 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1495 | .ty = float_ty.toIntern(), | 1517 | .ty = float_ty.toIntern(), |
| 1496 | .storage = .{ .elems = result_data }, | 1518 | .storage = .{ .elems = result_data }, |
| 1497 | } }))); | 1519 | } })); |
| 1498 | } | 1520 | } |
| 1499 | return floatFromIntScalar(val, float_ty, mod, strat); | 1521 | return floatFromIntScalar(val, float_ty, pt, strat); |
| 1500 | } | 1522 | } |
| 1501 | 1523 | ||
| 1502 | pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value { | 1524 | pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) !Value { |
| 1525 | const mod = pt.zcu; | ||
| 1503 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1526 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1504 | .undef => try mod.undefValue(float_ty), | 1527 | .undef => try pt.undefValue(float_ty), |
| 1505 | .int => |int| switch (int.storage) { | 1528 | .int => |int| switch (int.storage) { |
| 1506 | .big_int => |big_int| { | 1529 | .big_int => |big_int| { |
| 1507 | const float = bigIntToFloat(big_int.limbs, big_int.positive); | 1530 | const float = bigIntToFloat(big_int.limbs, big_int.positive); |
| 1508 | return mod.floatValue(float_ty, float); | 1531 | return pt.floatValue(float_ty, float); |
| 1509 | }, | 1532 | }, |
| 1510 | inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod), | 1533 | inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, pt), |
| 1511 | .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, mod), | 1534 | .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, pt), |
| 1512 | .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar, float_ty, mod), | 1535 | .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, float_ty, pt), |
| 1513 | }, | 1536 | }, |
| 1514 | else => unreachable, | 1537 | else => unreachable, |
| 1515 | }; | 1538 | }; |
| 1516 | } | 1539 | } |
| 1517 | 1540 | ||
| 1518 | fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value { | 1541 | fn floatFromIntInner(x: anytype, dest_ty: Type, pt: Zcu.PerThread) !Value { |
| 1519 | const target = mod.getTarget(); | 1542 | const target = pt.zcu.getTarget(); |
| 1520 | const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) { | 1543 | const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) { |
| 1521 | 16 => .{ .f16 = @floatFromInt(x) }, | 1544 | 16 => .{ .f16 = @floatFromInt(x) }, |
| 1522 | 32 => .{ .f32 = @floatFromInt(x) }, | 1545 | 32 => .{ .f32 = @floatFromInt(x) }, |
| ... | @@ -1525,10 +1548,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value { | ... | @@ -1525,10 +1548,10 @@ fn floatFromIntInner(x: anytype, dest_ty: Type, mod: *Module) !Value { |
| 1525 | 128 => .{ .f128 = @floatFromInt(x) }, | 1548 | 128 => .{ .f128 = @floatFromInt(x) }, |
| 1526 | else => unreachable, | 1549 | else => unreachable, |
| 1527 | }; | 1550 | }; |
| 1528 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 1551 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 1529 | .ty = dest_ty.toIntern(), | 1552 | .ty = dest_ty.toIntern(), |
| 1530 | .storage = storage, | 1553 | .storage = storage, |
| 1531 | } }))); | 1554 | } })); |
| 1532 | } | 1555 | } |
| 1533 | 1556 | ||
| 1534 | fn calcLimbLenFloat(scalar: anytype) usize { | 1557 | fn calcLimbLenFloat(scalar: anytype) usize { |
| ... | @@ -1551,22 +1574,22 @@ pub fn intAddSat( | ... | @@ -1551,22 +1574,22 @@ pub fn intAddSat( |
| 1551 | rhs: Value, | 1574 | rhs: Value, |
| 1552 | ty: Type, | 1575 | ty: Type, |
| 1553 | arena: Allocator, | 1576 | arena: Allocator, |
| 1554 | mod: *Module, | 1577 | pt: Zcu.PerThread, |
| 1555 | ) !Value { | 1578 | ) !Value { |
| 1556 | if (ty.zigTypeTag(mod) == .Vector) { | 1579 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 1557 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 1580 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 1558 | const scalar_ty = ty.scalarType(mod); | 1581 | const scalar_ty = ty.scalarType(pt.zcu); |
| 1559 | for (result_data, 0..) |*scalar, i| { | 1582 | for (result_data, 0..) |*scalar, i| { |
| 1560 | const lhs_elem = try lhs.elemValue(mod, i); | 1583 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1561 | const rhs_elem = try rhs.elemValue(mod, i); | 1584 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1562 | scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 1585 | scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 1563 | } | 1586 | } |
| 1564 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1587 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1565 | .ty = ty.toIntern(), | 1588 | .ty = ty.toIntern(), |
| 1566 | .storage = .{ .elems = result_data }, | 1589 | .storage = .{ .elems = result_data }, |
| 1567 | } }))); | 1590 | } })); |
| 1568 | } | 1591 | } |
| 1569 | return intAddSatScalar(lhs, rhs, ty, arena, mod); | 1592 | return intAddSatScalar(lhs, rhs, ty, arena, pt); |
| 1570 | } | 1593 | } |
| 1571 | 1594 | ||
| 1572 | /// Supports integers only; asserts neither operand is undefined. | 1595 | /// Supports integers only; asserts neither operand is undefined. |
| ... | @@ -1575,24 +1598,24 @@ pub fn intAddSatScalar( | ... | @@ -1575,24 +1598,24 @@ pub fn intAddSatScalar( |
| 1575 | rhs: Value, | 1598 | rhs: Value, |
| 1576 | ty: Type, | 1599 | ty: Type, |
| 1577 | arena: Allocator, | 1600 | arena: Allocator, |
| 1578 | mod: *Module, | 1601 | pt: Zcu.PerThread, |
| 1579 | ) !Value { | 1602 | ) !Value { |
| 1580 | assert(!lhs.isUndef(mod)); | 1603 | assert(!lhs.isUndef(pt.zcu)); |
| 1581 | assert(!rhs.isUndef(mod)); | 1604 | assert(!rhs.isUndef(pt.zcu)); |
| 1582 | 1605 | ||
| 1583 | const info = ty.intInfo(mod); | 1606 | const info = ty.intInfo(pt.zcu); |
| 1584 | 1607 | ||
| 1585 | var lhs_space: Value.BigIntSpace = undefined; | 1608 | var lhs_space: Value.BigIntSpace = undefined; |
| 1586 | var rhs_space: Value.BigIntSpace = undefined; | 1609 | var rhs_space: Value.BigIntSpace = undefined; |
| 1587 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 1610 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 1588 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 1611 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 1589 | const limbs = try arena.alloc( | 1612 | const limbs = try arena.alloc( |
| 1590 | std.math.big.Limb, | 1613 | std.math.big.Limb, |
| 1591 | std.math.big.int.calcTwosCompLimbCount(info.bits), | 1614 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| 1592 | ); | 1615 | ); |
| 1593 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1616 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1594 | result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 1617 | result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 1595 | return mod.intValue_big(ty, result_bigint.toConst()); | 1618 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1596 | } | 1619 | } |
| 1597 | 1620 | ||
| 1598 | /// Supports (vectors of) integers only; asserts neither operand is undefined. | 1621 | /// Supports (vectors of) integers only; asserts neither operand is undefined. |
| ... | @@ -1601,22 +1624,22 @@ pub fn intSubSat( | ... | @@ -1601,22 +1624,22 @@ pub fn intSubSat( |
| 1601 | rhs: Value, | 1624 | rhs: Value, |
| 1602 | ty: Type, | 1625 | ty: Type, |
| 1603 | arena: Allocator, | 1626 | arena: Allocator, |
| 1604 | mod: *Module, | 1627 | pt: Zcu.PerThread, |
| 1605 | ) !Value { | 1628 | ) !Value { |
| 1606 | if (ty.zigTypeTag(mod) == .Vector) { | 1629 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 1607 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 1630 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 1608 | const scalar_ty = ty.scalarType(mod); | 1631 | const scalar_ty = ty.scalarType(pt.zcu); |
| 1609 | for (result_data, 0..) |*scalar, i| { | 1632 | for (result_data, 0..) |*scalar, i| { |
| 1610 | const lhs_elem = try lhs.elemValue(mod, i); | 1633 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1611 | const rhs_elem = try rhs.elemValue(mod, i); | 1634 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1612 | scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 1635 | scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 1613 | } | 1636 | } |
| 1614 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1637 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1615 | .ty = ty.toIntern(), | 1638 | .ty = ty.toIntern(), |
| 1616 | .storage = .{ .elems = result_data }, | 1639 | .storage = .{ .elems = result_data }, |
| 1617 | } }))); | 1640 | } })); |
| 1618 | } | 1641 | } |
| 1619 | return intSubSatScalar(lhs, rhs, ty, arena, mod); | 1642 | return intSubSatScalar(lhs, rhs, ty, arena, pt); |
| 1620 | } | 1643 | } |
| 1621 | 1644 | ||
| 1622 | /// Supports integers only; asserts neither operand is undefined. | 1645 | /// Supports integers only; asserts neither operand is undefined. |
| ... | @@ -1625,24 +1648,24 @@ pub fn intSubSatScalar( | ... | @@ -1625,24 +1648,24 @@ pub fn intSubSatScalar( |
| 1625 | rhs: Value, | 1648 | rhs: Value, |
| 1626 | ty: Type, | 1649 | ty: Type, |
| 1627 | arena: Allocator, | 1650 | arena: Allocator, |
| 1628 | mod: *Module, | 1651 | pt: Zcu.PerThread, |
| 1629 | ) !Value { | 1652 | ) !Value { |
| 1630 | assert(!lhs.isUndef(mod)); | 1653 | assert(!lhs.isUndef(pt.zcu)); |
| 1631 | assert(!rhs.isUndef(mod)); | 1654 | assert(!rhs.isUndef(pt.zcu)); |
| 1632 | 1655 | ||
| 1633 | const info = ty.intInfo(mod); | 1656 | const info = ty.intInfo(pt.zcu); |
| 1634 | 1657 | ||
| 1635 | var lhs_space: Value.BigIntSpace = undefined; | 1658 | var lhs_space: Value.BigIntSpace = undefined; |
| 1636 | var rhs_space: Value.BigIntSpace = undefined; | 1659 | var rhs_space: Value.BigIntSpace = undefined; |
| 1637 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 1660 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 1638 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 1661 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 1639 | const limbs = try arena.alloc( | 1662 | const limbs = try arena.alloc( |
| 1640 | std.math.big.Limb, | 1663 | std.math.big.Limb, |
| 1641 | std.math.big.int.calcTwosCompLimbCount(info.bits), | 1664 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| 1642 | ); | 1665 | ); |
| 1643 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1666 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1644 | result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 1667 | result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 1645 | return mod.intValue_big(ty, result_bigint.toConst()); | 1668 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1646 | } | 1669 | } |
| 1647 | 1670 | ||
| 1648 | pub fn intMulWithOverflow( | 1671 | pub fn intMulWithOverflow( |
| ... | @@ -1650,32 +1673,33 @@ pub fn intMulWithOverflow( | ... | @@ -1650,32 +1673,33 @@ pub fn intMulWithOverflow( |
| 1650 | rhs: Value, | 1673 | rhs: Value, |
| 1651 | ty: Type, | 1674 | ty: Type, |
| 1652 | arena: Allocator, | 1675 | arena: Allocator, |
| 1653 | mod: *Module, | 1676 | pt: Zcu.PerThread, |
| 1654 | ) !OverflowArithmeticResult { | 1677 | ) !OverflowArithmeticResult { |
| 1678 | const mod = pt.zcu; | ||
| 1655 | if (ty.zigTypeTag(mod) == .Vector) { | 1679 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1656 | const vec_len = ty.vectorLen(mod); | 1680 | const vec_len = ty.vectorLen(mod); |
| 1657 | const overflowed_data = try arena.alloc(InternPool.Index, vec_len); | 1681 | const overflowed_data = try arena.alloc(InternPool.Index, vec_len); |
| 1658 | const result_data = try arena.alloc(InternPool.Index, vec_len); | 1682 | const result_data = try arena.alloc(InternPool.Index, vec_len); |
| 1659 | const scalar_ty = ty.scalarType(mod); | 1683 | const scalar_ty = ty.scalarType(mod); |
| 1660 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { | 1684 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 1661 | const lhs_elem = try lhs.elemValue(mod, i); | 1685 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1662 | const rhs_elem = try rhs.elemValue(mod, i); | 1686 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1663 | const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod); | 1687 | const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt); |
| 1664 | of.* = of_math_result.overflow_bit.toIntern(); | 1688 | of.* = of_math_result.overflow_bit.toIntern(); |
| 1665 | scalar.* = of_math_result.wrapped_result.toIntern(); | 1689 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 1666 | } | 1690 | } |
| 1667 | return OverflowArithmeticResult{ | 1691 | return OverflowArithmeticResult{ |
| 1668 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1692 | .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1669 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 1693 | .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 1670 | .storage = .{ .elems = overflowed_data }, | 1694 | .storage = .{ .elems = overflowed_data }, |
| 1671 | } }))), | 1695 | } })), |
| 1672 | .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1696 | .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1673 | .ty = ty.toIntern(), | 1697 | .ty = ty.toIntern(), |
| 1674 | .storage = .{ .elems = result_data }, | 1698 | .storage = .{ .elems = result_data }, |
| 1675 | } }))), | 1699 | } })), |
| 1676 | }; | 1700 | }; |
| 1677 | } | 1701 | } |
| 1678 | return intMulWithOverflowScalar(lhs, rhs, ty, arena, mod); | 1702 | return intMulWithOverflowScalar(lhs, rhs, ty, arena, pt); |
| 1679 | } | 1703 | } |
| 1680 | 1704 | ||
| 1681 | pub fn intMulWithOverflowScalar( | 1705 | pub fn intMulWithOverflowScalar( |
| ... | @@ -1683,21 +1707,22 @@ pub fn intMulWithOverflowScalar( | ... | @@ -1683,21 +1707,22 @@ pub fn intMulWithOverflowScalar( |
| 1683 | rhs: Value, | 1707 | rhs: Value, |
| 1684 | ty: Type, | 1708 | ty: Type, |
| 1685 | arena: Allocator, | 1709 | arena: Allocator, |
| 1686 | mod: *Module, | 1710 | pt: Zcu.PerThread, |
| 1687 | ) !OverflowArithmeticResult { | 1711 | ) !OverflowArithmeticResult { |
| 1712 | const mod = pt.zcu; | ||
| 1688 | const info = ty.intInfo(mod); | 1713 | const info = ty.intInfo(mod); |
| 1689 | 1714 | ||
| 1690 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | 1715 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { |
| 1691 | return .{ | 1716 | return .{ |
| 1692 | .overflow_bit = try mod.undefValue(Type.u1), | 1717 | .overflow_bit = try pt.undefValue(Type.u1), |
| 1693 | .wrapped_result = try mod.undefValue(ty), | 1718 | .wrapped_result = try pt.undefValue(ty), |
| 1694 | }; | 1719 | }; |
| 1695 | } | 1720 | } |
| 1696 | 1721 | ||
| 1697 | var lhs_space: Value.BigIntSpace = undefined; | 1722 | var lhs_space: Value.BigIntSpace = undefined; |
| 1698 | var rhs_space: Value.BigIntSpace = undefined; | 1723 | var rhs_space: Value.BigIntSpace = undefined; |
| 1699 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 1724 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 1700 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 1725 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 1701 | const limbs = try arena.alloc( | 1726 | const limbs = try arena.alloc( |
| 1702 | std.math.big.Limb, | 1727 | std.math.big.Limb, |
| 1703 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, | 1728 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, |
| ... | @@ -1715,8 +1740,8 @@ pub fn intMulWithOverflowScalar( | ... | @@ -1715,8 +1740,8 @@ pub fn intMulWithOverflowScalar( |
| 1715 | } | 1740 | } |
| 1716 | 1741 | ||
| 1717 | return OverflowArithmeticResult{ | 1742 | return OverflowArithmeticResult{ |
| 1718 | .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)), | 1743 | .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)), |
| 1719 | .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()), | 1744 | .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()), |
| 1720 | }; | 1745 | }; |
| 1721 | } | 1746 | } |
| 1722 | 1747 | ||
| ... | @@ -1726,22 +1751,23 @@ pub fn numberMulWrap( | ... | @@ -1726,22 +1751,23 @@ pub fn numberMulWrap( |
| 1726 | rhs: Value, | 1751 | rhs: Value, |
| 1727 | ty: Type, | 1752 | ty: Type, |
| 1728 | arena: Allocator, | 1753 | arena: Allocator, |
| 1729 | mod: *Module, | 1754 | pt: Zcu.PerThread, |
| 1730 | ) !Value { | 1755 | ) !Value { |
| 1756 | const mod = pt.zcu; | ||
| 1731 | if (ty.zigTypeTag(mod) == .Vector) { | 1757 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1732 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 1758 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 1733 | const scalar_ty = ty.scalarType(mod); | 1759 | const scalar_ty = ty.scalarType(mod); |
| 1734 | for (result_data, 0..) |*scalar, i| { | 1760 | for (result_data, 0..) |*scalar, i| { |
| 1735 | const lhs_elem = try lhs.elemValue(mod, i); | 1761 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1736 | const rhs_elem = try rhs.elemValue(mod, i); | 1762 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1737 | scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 1763 | scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 1738 | } | 1764 | } |
| 1739 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1765 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1740 | .ty = ty.toIntern(), | 1766 | .ty = ty.toIntern(), |
| 1741 | .storage = .{ .elems = result_data }, | 1767 | .storage = .{ .elems = result_data }, |
| 1742 | } }))); | 1768 | } })); |
| 1743 | } | 1769 | } |
| 1744 | return numberMulWrapScalar(lhs, rhs, ty, arena, mod); | 1770 | return numberMulWrapScalar(lhs, rhs, ty, arena, pt); |
| 1745 | } | 1771 | } |
| 1746 | 1772 | ||
| 1747 | /// Supports both floats and ints; handles undefined. | 1773 | /// Supports both floats and ints; handles undefined. |
| ... | @@ -1750,19 +1776,20 @@ pub fn numberMulWrapScalar( | ... | @@ -1750,19 +1776,20 @@ pub fn numberMulWrapScalar( |
| 1750 | rhs: Value, | 1776 | rhs: Value, |
| 1751 | ty: Type, | 1777 | ty: Type, |
| 1752 | arena: Allocator, | 1778 | arena: Allocator, |
| 1753 | mod: *Module, | 1779 | pt: Zcu.PerThread, |
| 1754 | ) !Value { | 1780 | ) !Value { |
| 1781 | const mod = pt.zcu; | ||
| 1755 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef; | 1782 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef; |
| 1756 | 1783 | ||
| 1757 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | 1784 | if (ty.zigTypeTag(mod) == .ComptimeInt) { |
| 1758 | return intMul(lhs, rhs, ty, undefined, arena, mod); | 1785 | return intMul(lhs, rhs, ty, undefined, arena, pt); |
| 1759 | } | 1786 | } |
| 1760 | 1787 | ||
| 1761 | if (ty.isAnyFloat()) { | 1788 | if (ty.isAnyFloat()) { |
| 1762 | return floatMul(lhs, rhs, ty, arena, mod); | 1789 | return floatMul(lhs, rhs, ty, arena, pt); |
| 1763 | } | 1790 | } |
| 1764 | 1791 | ||
| 1765 | const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, mod); | 1792 | const overflow_result = try intMulWithOverflow(lhs, rhs, ty, arena, pt); |
| 1766 | return overflow_result.wrapped_result; | 1793 | return overflow_result.wrapped_result; |
| 1767 | } | 1794 | } |
| 1768 | 1795 | ||
| ... | @@ -1772,22 +1799,22 @@ pub fn intMulSat( | ... | @@ -1772,22 +1799,22 @@ pub fn intMulSat( |
| 1772 | rhs: Value, | 1799 | rhs: Value, |
| 1773 | ty: Type, | 1800 | ty: Type, |
| 1774 | arena: Allocator, | 1801 | arena: Allocator, |
| 1775 | mod: *Module, | 1802 | pt: Zcu.PerThread, |
| 1776 | ) !Value { | 1803 | ) !Value { |
| 1777 | if (ty.zigTypeTag(mod) == .Vector) { | 1804 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 1778 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 1805 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 1779 | const scalar_ty = ty.scalarType(mod); | 1806 | const scalar_ty = ty.scalarType(pt.zcu); |
| 1780 | for (result_data, 0..) |*scalar, i| { | 1807 | for (result_data, 0..) |*scalar, i| { |
| 1781 | const lhs_elem = try lhs.elemValue(mod, i); | 1808 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1782 | const rhs_elem = try rhs.elemValue(mod, i); | 1809 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1783 | scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 1810 | scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 1784 | } | 1811 | } |
| 1785 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1812 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1786 | .ty = ty.toIntern(), | 1813 | .ty = ty.toIntern(), |
| 1787 | .storage = .{ .elems = result_data }, | 1814 | .storage = .{ .elems = result_data }, |
| 1788 | } }))); | 1815 | } })); |
| 1789 | } | 1816 | } |
| 1790 | return intMulSatScalar(lhs, rhs, ty, arena, mod); | 1817 | return intMulSatScalar(lhs, rhs, ty, arena, pt); |
| 1791 | } | 1818 | } |
| 1792 | 1819 | ||
| 1793 | /// Supports (vectors of) integers only; asserts neither operand is undefined. | 1820 | /// Supports (vectors of) integers only; asserts neither operand is undefined. |
| ... | @@ -1796,17 +1823,17 @@ pub fn intMulSatScalar( | ... | @@ -1796,17 +1823,17 @@ pub fn intMulSatScalar( |
| 1796 | rhs: Value, | 1823 | rhs: Value, |
| 1797 | ty: Type, | 1824 | ty: Type, |
| 1798 | arena: Allocator, | 1825 | arena: Allocator, |
| 1799 | mod: *Module, | 1826 | pt: Zcu.PerThread, |
| 1800 | ) !Value { | 1827 | ) !Value { |
| 1801 | assert(!lhs.isUndef(mod)); | 1828 | assert(!lhs.isUndef(pt.zcu)); |
| 1802 | assert(!rhs.isUndef(mod)); | 1829 | assert(!rhs.isUndef(pt.zcu)); |
| 1803 | 1830 | ||
| 1804 | const info = ty.intInfo(mod); | 1831 | const info = ty.intInfo(pt.zcu); |
| 1805 | 1832 | ||
| 1806 | var lhs_space: Value.BigIntSpace = undefined; | 1833 | var lhs_space: Value.BigIntSpace = undefined; |
| 1807 | var rhs_space: Value.BigIntSpace = undefined; | 1834 | var rhs_space: Value.BigIntSpace = undefined; |
| 1808 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 1835 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 1809 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 1836 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 1810 | const limbs = try arena.alloc( | 1837 | const limbs = try arena.alloc( |
| 1811 | std.math.big.Limb, | 1838 | std.math.big.Limb, |
| 1812 | @max( | 1839 | @max( |
| ... | @@ -1822,53 +1849,55 @@ pub fn intMulSatScalar( | ... | @@ -1822,53 +1849,55 @@ pub fn intMulSatScalar( |
| 1822 | ); | 1849 | ); |
| 1823 | result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena); | 1850 | result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena); |
| 1824 | result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits); | 1851 | result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits); |
| 1825 | return mod.intValue_big(ty, result_bigint.toConst()); | 1852 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1826 | } | 1853 | } |
| 1827 | 1854 | ||
| 1828 | /// Supports both floats and ints; handles undefined. | 1855 | /// Supports both floats and ints; handles undefined. |
| 1829 | pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value { | 1856 | pub fn numberMax(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value { |
| 1830 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef; | 1857 | if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef; |
| 1831 | if (lhs.isNan(mod)) return rhs; | 1858 | if (lhs.isNan(pt.zcu)) return rhs; |
| 1832 | if (rhs.isNan(mod)) return lhs; | 1859 | if (rhs.isNan(pt.zcu)) return lhs; |
| 1833 | 1860 | ||
| 1834 | return switch (order(lhs, rhs, mod)) { | 1861 | return switch (order(lhs, rhs, pt)) { |
| 1835 | .lt => rhs, | 1862 | .lt => rhs, |
| 1836 | .gt, .eq => lhs, | 1863 | .gt, .eq => lhs, |
| 1837 | }; | 1864 | }; |
| 1838 | } | 1865 | } |
| 1839 | 1866 | ||
| 1840 | /// Supports both floats and ints; handles undefined. | 1867 | /// Supports both floats and ints; handles undefined. |
| 1841 | pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value { | 1868 | pub fn numberMin(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value { |
| 1842 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return undef; | 1869 | if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef; |
| 1843 | if (lhs.isNan(mod)) return rhs; | 1870 | if (lhs.isNan(pt.zcu)) return rhs; |
| 1844 | if (rhs.isNan(mod)) return lhs; | 1871 | if (rhs.isNan(pt.zcu)) return lhs; |
| 1845 | 1872 | ||
| 1846 | return switch (order(lhs, rhs, mod)) { | 1873 | return switch (order(lhs, rhs, pt)) { |
| 1847 | .lt => lhs, | 1874 | .lt => lhs, |
| 1848 | .gt, .eq => rhs, | 1875 | .gt, .eq => rhs, |
| 1849 | }; | 1876 | }; |
| 1850 | } | 1877 | } |
| 1851 | 1878 | ||
| 1852 | /// operands must be (vectors of) integers; handles undefined scalars. | 1879 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1853 | pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 1880 | pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1881 | const mod = pt.zcu; | ||
| 1854 | if (ty.zigTypeTag(mod) == .Vector) { | 1882 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1855 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 1883 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 1856 | const scalar_ty = ty.scalarType(mod); | 1884 | const scalar_ty = ty.scalarType(mod); |
| 1857 | for (result_data, 0..) |*scalar, i| { | 1885 | for (result_data, 0..) |*scalar, i| { |
| 1858 | const elem_val = try val.elemValue(mod, i); | 1886 | const elem_val = try val.elemValue(pt, i); |
| 1859 | scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern(); | 1887 | scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, pt)).toIntern(); |
| 1860 | } | 1888 | } |
| 1861 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1889 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1862 | .ty = ty.toIntern(), | 1890 | .ty = ty.toIntern(), |
| 1863 | .storage = .{ .elems = result_data }, | 1891 | .storage = .{ .elems = result_data }, |
| 1864 | } }))); | 1892 | } })); |
| 1865 | } | 1893 | } |
| 1866 | return bitwiseNotScalar(val, ty, arena, mod); | 1894 | return bitwiseNotScalar(val, ty, arena, pt); |
| 1867 | } | 1895 | } |
| 1868 | 1896 | ||
| 1869 | /// operands must be integers; handles undefined. | 1897 | /// operands must be integers; handles undefined. |
| 1870 | pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 1898 | pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1871 | if (val.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() }))); | 1899 | const mod = pt.zcu; |
| 1900 | if (val.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | ||
| 1872 | if (ty.toIntern() == .bool_type) return makeBool(!val.toBool()); | 1901 | if (ty.toIntern() == .bool_type) return makeBool(!val.toBool()); |
| 1873 | 1902 | ||
| 1874 | const info = ty.intInfo(mod); | 1903 | const info = ty.intInfo(mod); |
| ... | @@ -1880,7 +1909,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V | ... | @@ -1880,7 +1909,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V |
| 1880 | // TODO is this a performance issue? maybe we should try the operation without | 1909 | // TODO is this a performance issue? maybe we should try the operation without |
| 1881 | // resorting to BigInt first. | 1910 | // resorting to BigInt first. |
| 1882 | var val_space: Value.BigIntSpace = undefined; | 1911 | var val_space: Value.BigIntSpace = undefined; |
| 1883 | const val_bigint = val.toBigInt(&val_space, mod); | 1912 | const val_bigint = val.toBigInt(&val_space, pt); |
| 1884 | const limbs = try arena.alloc( | 1913 | const limbs = try arena.alloc( |
| 1885 | std.math.big.Limb, | 1914 | std.math.big.Limb, |
| 1886 | std.math.big.int.calcTwosCompLimbCount(info.bits), | 1915 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | @@ -1888,29 +1917,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V | ... | @@ -1888,29 +1917,31 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !V |
| 1888 | 1917 | ||
| 1889 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1918 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1890 | result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits); | 1919 | result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits); |
| 1891 | return mod.intValue_big(ty, result_bigint.toConst()); | 1920 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1892 | } | 1921 | } |
| 1893 | 1922 | ||
| 1894 | /// operands must be (vectors of) integers; handles undefined scalars. | 1923 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1895 | pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 1924 | pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 1925 | const mod = pt.zcu; | ||
| 1896 | if (ty.zigTypeTag(mod) == .Vector) { | 1926 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1897 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 1927 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 1898 | const scalar_ty = ty.scalarType(mod); | 1928 | const scalar_ty = ty.scalarType(mod); |
| 1899 | for (result_data, 0..) |*scalar, i| { | 1929 | for (result_data, 0..) |*scalar, i| { |
| 1900 | const lhs_elem = try lhs.elemValue(mod, i); | 1930 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1901 | const rhs_elem = try rhs.elemValue(mod, i); | 1931 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1902 | scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 1932 | scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 1903 | } | 1933 | } |
| 1904 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1934 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1905 | .ty = ty.toIntern(), | 1935 | .ty = ty.toIntern(), |
| 1906 | .storage = .{ .elems = result_data }, | 1936 | .storage = .{ .elems = result_data }, |
| 1907 | } }))); | 1937 | } })); |
| 1908 | } | 1938 | } |
| 1909 | return bitwiseAndScalar(lhs, rhs, ty, allocator, mod); | 1939 | return bitwiseAndScalar(lhs, rhs, ty, allocator, pt); |
| 1910 | } | 1940 | } |
| 1911 | 1941 | ||
| 1912 | /// operands must be integers; handles undefined. | 1942 | /// operands must be integers; handles undefined. |
| 1913 | pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value { | 1943 | pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1944 | const zcu = pt.zcu; | ||
| 1914 | // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can | 1945 | // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can |
| 1915 | // still zero out some bits. | 1946 | // still zero out some bits. |
| 1916 | // TODO: ideally we'd still like tracking for the undef bits. Related: #19634. | 1947 | // TODO: ideally we'd still like tracking for the undef bits. Related: #19634. |
| ... | @@ -1919,9 +1950,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc | ... | @@ -1919,9 +1950,9 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc |
| 1919 | const rhs_undef = orig_rhs.isUndef(zcu); | 1950 | const rhs_undef = orig_rhs.isUndef(zcu); |
| 1920 | break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) { | 1951 | break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) { |
| 1921 | 0b00 => .{ orig_lhs, orig_rhs }, | 1952 | 0b00 => .{ orig_lhs, orig_rhs }, |
| 1922 | 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) }, | 1953 | 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) }, |
| 1923 | 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs }, | 1954 | 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs }, |
| 1924 | 0b11 => return zcu.undefValue(ty), | 1955 | 0b11 => return pt.undefValue(ty), |
| 1925 | }; | 1956 | }; |
| 1926 | }; | 1957 | }; |
| 1927 | 1958 | ||
| ... | @@ -1931,8 +1962,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc | ... | @@ -1931,8 +1962,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc |
| 1931 | // resorting to BigInt first. | 1962 | // resorting to BigInt first. |
| 1932 | var lhs_space: Value.BigIntSpace = undefined; | 1963 | var lhs_space: Value.BigIntSpace = undefined; |
| 1933 | var rhs_space: Value.BigIntSpace = undefined; | 1964 | var rhs_space: Value.BigIntSpace = undefined; |
| 1934 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | 1965 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 1935 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | 1966 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 1936 | const limbs = try arena.alloc( | 1967 | const limbs = try arena.alloc( |
| 1937 | std.math.big.Limb, | 1968 | std.math.big.Limb, |
| 1938 | // + 1 for negatives | 1969 | // + 1 for negatives |
| ... | @@ -1940,12 +1971,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc | ... | @@ -1940,12 +1971,13 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc |
| 1940 | ); | 1971 | ); |
| 1941 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1972 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1942 | result_bigint.bitAnd(lhs_bigint, rhs_bigint); | 1973 | result_bigint.bitAnd(lhs_bigint, rhs_bigint); |
| 1943 | return zcu.intValue_big(ty, result_bigint.toConst()); | 1974 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1944 | } | 1975 | } |
| 1945 | 1976 | ||
| 1946 | /// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA. | 1977 | /// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA. |
| 1947 | /// This is used to convert undef values into 0xAA when performing e.g. bitwise operations. | 1978 | /// This is used to convert undef values into 0xAA when performing e.g. bitwise operations. |
| 1948 | fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value { | 1979 | fn intValueAa(ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1980 | const zcu = pt.zcu; | ||
| 1949 | if (ty.toIntern() == .bool_type) return Value.true; | 1981 | if (ty.toIntern() == .bool_type) return Value.true; |
| 1950 | const info = ty.intInfo(zcu); | 1982 | const info = ty.intInfo(zcu); |
| 1951 | 1983 | ||
| ... | @@ -1958,68 +1990,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value { | ... | @@ -1958,68 +1990,71 @@ fn intValueAa(ty: Type, arena: Allocator, zcu: *Zcu) !Value { |
| 1958 | ); | 1990 | ); |
| 1959 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 1991 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 1960 | result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness); | 1992 | result_bigint.readTwosComplement(buf, info.bits, zcu.getTarget().cpu.arch.endian(), info.signedness); |
| 1961 | return zcu.intValue_big(ty, result_bigint.toConst()); | 1993 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 1962 | } | 1994 | } |
| 1963 | 1995 | ||
| 1964 | /// operands must be (vectors of) integers; handles undefined scalars. | 1996 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1965 | pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 1997 | pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1998 | const mod = pt.zcu; | ||
| 1966 | if (ty.zigTypeTag(mod) == .Vector) { | 1999 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1967 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 2000 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 1968 | const scalar_ty = ty.scalarType(mod); | 2001 | const scalar_ty = ty.scalarType(mod); |
| 1969 | for (result_data, 0..) |*scalar, i| { | 2002 | for (result_data, 0..) |*scalar, i| { |
| 1970 | const lhs_elem = try lhs.elemValue(mod, i); | 2003 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1971 | const rhs_elem = try rhs.elemValue(mod, i); | 2004 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1972 | scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 2005 | scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 1973 | } | 2006 | } |
| 1974 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2007 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 1975 | .ty = ty.toIntern(), | 2008 | .ty = ty.toIntern(), |
| 1976 | .storage = .{ .elems = result_data }, | 2009 | .storage = .{ .elems = result_data }, |
| 1977 | } }))); | 2010 | } })); |
| 1978 | } | 2011 | } |
| 1979 | return bitwiseNandScalar(lhs, rhs, ty, arena, mod); | 2012 | return bitwiseNandScalar(lhs, rhs, ty, arena, pt); |
| 1980 | } | 2013 | } |
| 1981 | 2014 | ||
| 1982 | /// operands must be integers; handles undefined. | 2015 | /// operands must be integers; handles undefined. |
| 1983 | pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 2016 | pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1984 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() }))); | 2017 | const mod = pt.zcu; |
| 2018 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | ||
| 1985 | if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool())); | 2019 | if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool())); |
| 1986 | 2020 | ||
| 1987 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); | 2021 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, pt); |
| 1988 | const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty); | 2022 | const all_ones = if (ty.isSignedInt(mod)) try pt.intValue(ty, -1) else try ty.maxIntScalar(pt, ty); |
| 1989 | return bitwiseXor(anded, all_ones, ty, arena, mod); | 2023 | return bitwiseXor(anded, all_ones, ty, arena, pt); |
| 1990 | } | 2024 | } |
| 1991 | 2025 | ||
| 1992 | /// operands must be (vectors of) integers; handles undefined scalars. | 2026 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1993 | pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2027 | pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2028 | const mod = pt.zcu; | ||
| 1994 | if (ty.zigTypeTag(mod) == .Vector) { | 2029 | if (ty.zigTypeTag(mod) == .Vector) { |
| 1995 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2030 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 1996 | const scalar_ty = ty.scalarType(mod); | 2031 | const scalar_ty = ty.scalarType(mod); |
| 1997 | for (result_data, 0..) |*scalar, i| { | 2032 | for (result_data, 0..) |*scalar, i| { |
| 1998 | const lhs_elem = try lhs.elemValue(mod, i); | 2033 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1999 | const rhs_elem = try rhs.elemValue(mod, i); | 2034 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2000 | scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2035 | scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2001 | } | 2036 | } |
| 2002 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2037 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2003 | .ty = ty.toIntern(), | 2038 | .ty = ty.toIntern(), |
| 2004 | .storage = .{ .elems = result_data }, | 2039 | .storage = .{ .elems = result_data }, |
| 2005 | } }))); | 2040 | } })); |
| 2006 | } | 2041 | } |
| 2007 | return bitwiseOrScalar(lhs, rhs, ty, allocator, mod); | 2042 | return bitwiseOrScalar(lhs, rhs, ty, allocator, pt); |
| 2008 | } | 2043 | } |
| 2009 | 2044 | ||
| 2010 | /// operands must be integers; handles undefined. | 2045 | /// operands must be integers; handles undefined. |
| 2011 | pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, zcu: *Zcu) !Value { | 2046 | pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2012 | // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can | 2047 | // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can |
| 2013 | // still zero out some bits. | 2048 | // still zero out some bits. |
| 2014 | // TODO: ideally we'd still like tracking for the undef bits. Related: #19634. | 2049 | // TODO: ideally we'd still like tracking for the undef bits. Related: #19634. |
| 2015 | const lhs: Value, const rhs: Value = make_defined: { | 2050 | const lhs: Value, const rhs: Value = make_defined: { |
| 2016 | const lhs_undef = orig_lhs.isUndef(zcu); | 2051 | const lhs_undef = orig_lhs.isUndef(pt.zcu); |
| 2017 | const rhs_undef = orig_rhs.isUndef(zcu); | 2052 | const rhs_undef = orig_rhs.isUndef(pt.zcu); |
| 2018 | break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) { | 2053 | break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) { |
| 2019 | 0b00 => .{ orig_lhs, orig_rhs }, | 2054 | 0b00 => .{ orig_lhs, orig_rhs }, |
| 2020 | 0b01 => .{ orig_lhs, try intValueAa(ty, arena, zcu) }, | 2055 | 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) }, |
| 2021 | 0b10 => .{ try intValueAa(ty, arena, zcu), orig_rhs }, | 2056 | 0b10 => .{ try intValueAa(ty, arena, pt), orig_rhs }, |
| 2022 | 0b11 => return zcu.undefValue(ty), | 2057 | 0b11 => return pt.undefValue(ty), |
| 2023 | }; | 2058 | }; |
| 2024 | }; | 2059 | }; |
| 2025 | 2060 | ||
| ... | @@ -2029,46 +2064,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca | ... | @@ -2029,46 +2064,48 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca |
| 2029 | // resorting to BigInt first. | 2064 | // resorting to BigInt first. |
| 2030 | var lhs_space: Value.BigIntSpace = undefined; | 2065 | var lhs_space: Value.BigIntSpace = undefined; |
| 2031 | var rhs_space: Value.BigIntSpace = undefined; | 2066 | var rhs_space: Value.BigIntSpace = undefined; |
| 2032 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | 2067 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2033 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | 2068 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2034 | const limbs = try arena.alloc( | 2069 | const limbs = try arena.alloc( |
| 2035 | std.math.big.Limb, | 2070 | std.math.big.Limb, |
| 2036 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), | 2071 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| 2037 | ); | 2072 | ); |
| 2038 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 2073 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 2039 | result_bigint.bitOr(lhs_bigint, rhs_bigint); | 2074 | result_bigint.bitOr(lhs_bigint, rhs_bigint); |
| 2040 | return zcu.intValue_big(ty, result_bigint.toConst()); | 2075 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2041 | } | 2076 | } |
| 2042 | 2077 | ||
| 2043 | /// operands must be (vectors of) integers; handles undefined scalars. | 2078 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 2044 | pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2079 | pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2080 | const mod = pt.zcu; | ||
| 2045 | if (ty.zigTypeTag(mod) == .Vector) { | 2081 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2046 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2082 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 2047 | const scalar_ty = ty.scalarType(mod); | 2083 | const scalar_ty = ty.scalarType(mod); |
| 2048 | for (result_data, 0..) |*scalar, i| { | 2084 | for (result_data, 0..) |*scalar, i| { |
| 2049 | const lhs_elem = try lhs.elemValue(mod, i); | 2085 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2050 | const rhs_elem = try rhs.elemValue(mod, i); | 2086 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2051 | scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2087 | scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2052 | } | 2088 | } |
| 2053 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2089 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2054 | .ty = ty.toIntern(), | 2090 | .ty = ty.toIntern(), |
| 2055 | .storage = .{ .elems = result_data }, | 2091 | .storage = .{ .elems = result_data }, |
| 2056 | } }))); | 2092 | } })); |
| 2057 | } | 2093 | } |
| 2058 | return bitwiseXorScalar(lhs, rhs, ty, allocator, mod); | 2094 | return bitwiseXorScalar(lhs, rhs, ty, allocator, pt); |
| 2059 | } | 2095 | } |
| 2060 | 2096 | ||
| 2061 | /// operands must be integers; handles undefined. | 2097 | /// operands must be integers; handles undefined. |
| 2062 | pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 2098 | pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2063 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() }))); | 2099 | const mod = pt.zcu; |
| 2100 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | ||
| 2064 | if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool()); | 2101 | if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool()); |
| 2065 | 2102 | ||
| 2066 | // TODO is this a performance issue? maybe we should try the operation without | 2103 | // TODO is this a performance issue? maybe we should try the operation without |
| 2067 | // resorting to BigInt first. | 2104 | // resorting to BigInt first. |
| 2068 | var lhs_space: Value.BigIntSpace = undefined; | 2105 | var lhs_space: Value.BigIntSpace = undefined; |
| 2069 | var rhs_space: Value.BigIntSpace = undefined; | 2106 | var rhs_space: Value.BigIntSpace = undefined; |
| 2070 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2107 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2071 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 2108 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2072 | const limbs = try arena.alloc( | 2109 | const limbs = try arena.alloc( |
| 2073 | std.math.big.Limb, | 2110 | std.math.big.Limb, |
| 2074 | // + 1 for negatives | 2111 | // + 1 for negatives |
| ... | @@ -2076,22 +2113,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: | ... | @@ -2076,22 +2113,22 @@ pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: |
| 2076 | ); | 2113 | ); |
| 2077 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 2114 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 2078 | result_bigint.bitXor(lhs_bigint, rhs_bigint); | 2115 | result_bigint.bitXor(lhs_bigint, rhs_bigint); |
| 2079 | return mod.intValue_big(ty, result_bigint.toConst()); | 2116 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2080 | } | 2117 | } |
| 2081 | 2118 | ||
| 2082 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting | 2119 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting |
| 2083 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). | 2120 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). |
| 2084 | pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, mod: *Module) !Value { | 2121 | pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2085 | var overflow: usize = undefined; | 2122 | var overflow: usize = undefined; |
| 2086 | return intDivInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) { | 2123 | return intDivInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) { |
| 2087 | error.Overflow => { | 2124 | error.Overflow => { |
| 2088 | const is_vec = ty.isVector(mod); | 2125 | const is_vec = ty.isVector(pt.zcu); |
| 2089 | overflow_idx.* = if (is_vec) overflow else 0; | 2126 | overflow_idx.* = if (is_vec) overflow else 0; |
| 2090 | const safe_ty = if (is_vec) try mod.vectorType(.{ | 2127 | const safe_ty = if (is_vec) try pt.vectorType(.{ |
| 2091 | .len = ty.vectorLen(mod), | 2128 | .len = ty.vectorLen(pt.zcu), |
| 2092 | .child = .comptime_int_type, | 2129 | .child = .comptime_int_type, |
| 2093 | }) else Type.comptime_int; | 2130 | }) else Type.comptime_int; |
| 2094 | return intDivInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) { | 2131 | return intDivInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) { |
| 2095 | error.Overflow => unreachable, | 2132 | error.Overflow => unreachable, |
| 2096 | else => |e| return e, | 2133 | else => |e| return e, |
| 2097 | }; | 2134 | }; |
| ... | @@ -2100,14 +2137,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator | ... | @@ -2100,14 +2137,14 @@ pub fn intDiv(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator |
| 2100 | }; | 2137 | }; |
| 2101 | } | 2138 | } |
| 2102 | 2139 | ||
| 2103 | fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value { | 2140 | fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2104 | if (ty.zigTypeTag(mod) == .Vector) { | 2141 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2105 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2142 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2106 | const scalar_ty = ty.scalarType(mod); | 2143 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2107 | for (result_data, 0..) |*scalar, i| { | 2144 | for (result_data, 0..) |*scalar, i| { |
| 2108 | const lhs_elem = try lhs.elemValue(mod, i); | 2145 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2109 | const rhs_elem = try rhs.elemValue(mod, i); | 2146 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2110 | const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) { | 2147 | const val = intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) { |
| 2111 | error.Overflow => { | 2148 | error.Overflow => { |
| 2112 | overflow_idx.* = i; | 2149 | overflow_idx.* = i; |
| 2113 | return error.Overflow; | 2150 | return error.Overflow; |
| ... | @@ -2116,21 +2153,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator | ... | @@ -2116,21 +2153,21 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2116 | }; | 2153 | }; |
| 2117 | scalar.* = val.toIntern(); | 2154 | scalar.* = val.toIntern(); |
| 2118 | } | 2155 | } |
| 2119 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2156 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2120 | .ty = ty.toIntern(), | 2157 | .ty = ty.toIntern(), |
| 2121 | .storage = .{ .elems = result_data }, | 2158 | .storage = .{ .elems = result_data }, |
| 2122 | } }))); | 2159 | } })); |
| 2123 | } | 2160 | } |
| 2124 | return intDivScalar(lhs, rhs, ty, allocator, mod); | 2161 | return intDivScalar(lhs, rhs, ty, allocator, pt); |
| 2125 | } | 2162 | } |
| 2126 | 2163 | ||
| 2127 | pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2164 | pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2128 | // TODO is this a performance issue? maybe we should try the operation without | 2165 | // TODO is this a performance issue? maybe we should try the operation without |
| 2129 | // resorting to BigInt first. | 2166 | // resorting to BigInt first. |
| 2130 | var lhs_space: Value.BigIntSpace = undefined; | 2167 | var lhs_space: Value.BigIntSpace = undefined; |
| 2131 | var rhs_space: Value.BigIntSpace = undefined; | 2168 | var rhs_space: Value.BigIntSpace = undefined; |
| 2132 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2169 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2133 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 2170 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2134 | const limbs_q = try allocator.alloc( | 2171 | const limbs_q = try allocator.alloc( |
| 2135 | std.math.big.Limb, | 2172 | std.math.big.Limb, |
| 2136 | lhs_bigint.limbs.len, | 2173 | lhs_bigint.limbs.len, |
| ... | @@ -2147,38 +2184,38 @@ pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: | ... | @@ -2147,38 +2184,38 @@ pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2147 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; | 2184 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; |
| 2148 | result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); | 2185 | result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); |
| 2149 | if (ty.toIntern() != .comptime_int_type) { | 2186 | if (ty.toIntern() != .comptime_int_type) { |
| 2150 | const info = ty.intInfo(mod); | 2187 | const info = ty.intInfo(pt.zcu); |
| 2151 | if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) { | 2188 | if (!result_q.toConst().fitsInTwosComp(info.signedness, info.bits)) { |
| 2152 | return error.Overflow; | 2189 | return error.Overflow; |
| 2153 | } | 2190 | } |
| 2154 | } | 2191 | } |
| 2155 | return mod.intValue_big(ty, result_q.toConst()); | 2192 | return pt.intValue_big(ty, result_q.toConst()); |
| 2156 | } | 2193 | } |
| 2157 | 2194 | ||
| 2158 | pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2195 | pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2159 | if (ty.zigTypeTag(mod) == .Vector) { | 2196 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2160 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2197 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2161 | const scalar_ty = ty.scalarType(mod); | 2198 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2162 | for (result_data, 0..) |*scalar, i| { | 2199 | for (result_data, 0..) |*scalar, i| { |
| 2163 | const lhs_elem = try lhs.elemValue(mod, i); | 2200 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2164 | const rhs_elem = try rhs.elemValue(mod, i); | 2201 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2165 | scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2202 | scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2166 | } | 2203 | } |
| 2167 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2204 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2168 | .ty = ty.toIntern(), | 2205 | .ty = ty.toIntern(), |
| 2169 | .storage = .{ .elems = result_data }, | 2206 | .storage = .{ .elems = result_data }, |
| 2170 | } }))); | 2207 | } })); |
| 2171 | } | 2208 | } |
| 2172 | return intDivFloorScalar(lhs, rhs, ty, allocator, mod); | 2209 | return intDivFloorScalar(lhs, rhs, ty, allocator, pt); |
| 2173 | } | 2210 | } |
| 2174 | 2211 | ||
| 2175 | pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2212 | pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2176 | // TODO is this a performance issue? maybe we should try the operation without | 2213 | // TODO is this a performance issue? maybe we should try the operation without |
| 2177 | // resorting to BigInt first. | 2214 | // resorting to BigInt first. |
| 2178 | var lhs_space: Value.BigIntSpace = undefined; | 2215 | var lhs_space: Value.BigIntSpace = undefined; |
| 2179 | var rhs_space: Value.BigIntSpace = undefined; | 2216 | var rhs_space: Value.BigIntSpace = undefined; |
| 2180 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2217 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2181 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 2218 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2182 | const limbs_q = try allocator.alloc( | 2219 | const limbs_q = try allocator.alloc( |
| 2183 | std.math.big.Limb, | 2220 | std.math.big.Limb, |
| 2184 | lhs_bigint.limbs.len, | 2221 | lhs_bigint.limbs.len, |
| ... | @@ -2194,33 +2231,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, | ... | @@ -2194,33 +2231,33 @@ pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, |
| 2194 | var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; | 2231 | var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; |
| 2195 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; | 2232 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; |
| 2196 | result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); | 2233 | result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); |
| 2197 | return mod.intValue_big(ty, result_q.toConst()); | 2234 | return pt.intValue_big(ty, result_q.toConst()); |
| 2198 | } | 2235 | } |
| 2199 | 2236 | ||
| 2200 | pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2237 | pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2201 | if (ty.zigTypeTag(mod) == .Vector) { | 2238 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2202 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2239 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2203 | const scalar_ty = ty.scalarType(mod); | 2240 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2204 | for (result_data, 0..) |*scalar, i| { | 2241 | for (result_data, 0..) |*scalar, i| { |
| 2205 | const lhs_elem = try lhs.elemValue(mod, i); | 2242 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2206 | const rhs_elem = try rhs.elemValue(mod, i); | 2243 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2207 | scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2244 | scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2208 | } | 2245 | } |
| 2209 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2246 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2210 | .ty = ty.toIntern(), | 2247 | .ty = ty.toIntern(), |
| 2211 | .storage = .{ .elems = result_data }, | 2248 | .storage = .{ .elems = result_data }, |
| 2212 | } }))); | 2249 | } })); |
| 2213 | } | 2250 | } |
| 2214 | return intModScalar(lhs, rhs, ty, allocator, mod); | 2251 | return intModScalar(lhs, rhs, ty, allocator, pt); |
| 2215 | } | 2252 | } |
| 2216 | 2253 | ||
| 2217 | pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2254 | pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2218 | // TODO is this a performance issue? maybe we should try the operation without | 2255 | // TODO is this a performance issue? maybe we should try the operation without |
| 2219 | // resorting to BigInt first. | 2256 | // resorting to BigInt first. |
| 2220 | var lhs_space: Value.BigIntSpace = undefined; | 2257 | var lhs_space: Value.BigIntSpace = undefined; |
| 2221 | var rhs_space: Value.BigIntSpace = undefined; | 2258 | var rhs_space: Value.BigIntSpace = undefined; |
| 2222 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2259 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2223 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 2260 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2224 | const limbs_q = try allocator.alloc( | 2261 | const limbs_q = try allocator.alloc( |
| 2225 | std.math.big.Limb, | 2262 | std.math.big.Limb, |
| 2226 | lhs_bigint.limbs.len, | 2263 | lhs_bigint.limbs.len, |
| ... | @@ -2236,7 +2273,7 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: | ... | @@ -2236,7 +2273,7 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2236 | var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; | 2273 | var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; |
| 2237 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; | 2274 | var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; |
| 2238 | result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); | 2275 | result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); |
| 2239 | return mod.intValue_big(ty, result_r.toConst()); | 2276 | return pt.intValue_big(ty, result_r.toConst()); |
| 2240 | } | 2277 | } |
| 2241 | 2278 | ||
| 2242 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. | 2279 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. |
| ... | @@ -2268,85 +2305,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool { | ... | @@ -2268,85 +2305,86 @@ pub fn isNegativeInf(val: Value, mod: *const Module) bool { |
| 2268 | }; | 2305 | }; |
| 2269 | } | 2306 | } |
| 2270 | 2307 | ||
| 2271 | pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 2308 | pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2272 | if (float_type.zigTypeTag(mod) == .Vector) { | 2309 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 2273 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2310 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 2274 | const scalar_ty = float_type.scalarType(mod); | 2311 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 2275 | for (result_data, 0..) |*scalar, i| { | 2312 | for (result_data, 0..) |*scalar, i| { |
| 2276 | const lhs_elem = try lhs.elemValue(mod, i); | 2313 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2277 | const rhs_elem = try rhs.elemValue(mod, i); | 2314 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2278 | scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2315 | scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2279 | } | 2316 | } |
| 2280 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2317 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2281 | .ty = float_type.toIntern(), | 2318 | .ty = float_type.toIntern(), |
| 2282 | .storage = .{ .elems = result_data }, | 2319 | .storage = .{ .elems = result_data }, |
| 2283 | } }))); | 2320 | } })); |
| 2284 | } | 2321 | } |
| 2285 | return floatRemScalar(lhs, rhs, float_type, mod); | 2322 | return floatRemScalar(lhs, rhs, float_type, pt); |
| 2286 | } | 2323 | } |
| 2287 | 2324 | ||
| 2288 | pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value { | 2325 | pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2289 | const target = mod.getTarget(); | 2326 | const target = pt.zcu.getTarget(); |
| 2290 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2327 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2291 | 16 => .{ .f16 = @rem(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, | 2328 | 16 => .{ .f16 = @rem(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, |
| 2292 | 32 => .{ .f32 = @rem(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, | 2329 | 32 => .{ .f32 = @rem(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, |
| 2293 | 64 => .{ .f64 = @rem(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, | 2330 | 64 => .{ .f64 = @rem(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, |
| 2294 | 80 => .{ .f80 = @rem(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, | 2331 | 80 => .{ .f80 = @rem(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, |
| 2295 | 128 => .{ .f128 = @rem(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, | 2332 | 128 => .{ .f128 = @rem(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, |
| 2296 | else => unreachable, | 2333 | else => unreachable, |
| 2297 | }; | 2334 | }; |
| 2298 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2335 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2299 | .ty = float_type.toIntern(), | 2336 | .ty = float_type.toIntern(), |
| 2300 | .storage = storage, | 2337 | .storage = storage, |
| 2301 | } }))); | 2338 | } })); |
| 2302 | } | 2339 | } |
| 2303 | 2340 | ||
| 2304 | pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 2341 | pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2305 | if (float_type.zigTypeTag(mod) == .Vector) { | 2342 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 2306 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2343 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 2307 | const scalar_ty = float_type.scalarType(mod); | 2344 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 2308 | for (result_data, 0..) |*scalar, i| { | 2345 | for (result_data, 0..) |*scalar, i| { |
| 2309 | const lhs_elem = try lhs.elemValue(mod, i); | 2346 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2310 | const rhs_elem = try rhs.elemValue(mod, i); | 2347 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2311 | scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2348 | scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2312 | } | 2349 | } |
| 2313 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2350 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2314 | .ty = float_type.toIntern(), | 2351 | .ty = float_type.toIntern(), |
| 2315 | .storage = .{ .elems = result_data }, | 2352 | .storage = .{ .elems = result_data }, |
| 2316 | } }))); | 2353 | } })); |
| 2317 | } | 2354 | } |
| 2318 | return floatModScalar(lhs, rhs, float_type, mod); | 2355 | return floatModScalar(lhs, rhs, float_type, pt); |
| 2319 | } | 2356 | } |
| 2320 | 2357 | ||
| 2321 | pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, mod: *Module) !Value { | 2358 | pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2322 | const target = mod.getTarget(); | 2359 | const target = pt.zcu.getTarget(); |
| 2323 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2360 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2324 | 16 => .{ .f16 = @mod(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, | 2361 | 16 => .{ .f16 = @mod(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, |
| 2325 | 32 => .{ .f32 = @mod(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, | 2362 | 32 => .{ .f32 = @mod(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, |
| 2326 | 64 => .{ .f64 = @mod(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, | 2363 | 64 => .{ .f64 = @mod(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, |
| 2327 | 80 => .{ .f80 = @mod(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, | 2364 | 80 => .{ .f80 = @mod(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, |
| 2328 | 128 => .{ .f128 = @mod(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, | 2365 | 128 => .{ .f128 = @mod(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, |
| 2329 | else => unreachable, | 2366 | else => unreachable, |
| 2330 | }; | 2367 | }; |
| 2331 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2368 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2332 | .ty = float_type.toIntern(), | 2369 | .ty = float_type.toIntern(), |
| 2333 | .storage = storage, | 2370 | .storage = storage, |
| 2334 | } }))); | 2371 | } })); |
| 2335 | } | 2372 | } |
| 2336 | 2373 | ||
| 2337 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting | 2374 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting |
| 2338 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). | 2375 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). |
| 2339 | pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, mod: *Module) !Value { | 2376 | pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2377 | const mod = pt.zcu; | ||
| 2340 | var overflow: usize = undefined; | 2378 | var overflow: usize = undefined; |
| 2341 | return intMulInner(lhs, rhs, ty, &overflow, allocator, mod) catch |err| switch (err) { | 2379 | return intMulInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) { |
| 2342 | error.Overflow => { | 2380 | error.Overflow => { |
| 2343 | const is_vec = ty.isVector(mod); | 2381 | const is_vec = ty.isVector(mod); |
| 2344 | overflow_idx.* = if (is_vec) overflow else 0; | 2382 | overflow_idx.* = if (is_vec) overflow else 0; |
| 2345 | const safe_ty = if (is_vec) try mod.vectorType(.{ | 2383 | const safe_ty = if (is_vec) try pt.vectorType(.{ |
| 2346 | .len = ty.vectorLen(mod), | 2384 | .len = ty.vectorLen(mod), |
| 2347 | .child = .comptime_int_type, | 2385 | .child = .comptime_int_type, |
| 2348 | }) else Type.comptime_int; | 2386 | }) else Type.comptime_int; |
| 2349 | return intMulInner(lhs, rhs, safe_ty, undefined, allocator, mod) catch |err1| switch (err1) { | 2387 | return intMulInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) { |
| 2350 | error.Overflow => unreachable, | 2388 | error.Overflow => unreachable, |
| 2351 | else => |e| return e, | 2389 | else => |e| return e, |
| 2352 | }; | 2390 | }; |
| ... | @@ -2355,14 +2393,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator | ... | @@ -2355,14 +2393,15 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator |
| 2355 | }; | 2393 | }; |
| 2356 | } | 2394 | } |
| 2357 | 2395 | ||
| 2358 | fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, mod: *Module) !Value { | 2396 | fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2397 | const mod = pt.zcu; | ||
| 2359 | if (ty.zigTypeTag(mod) == .Vector) { | 2398 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2360 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2399 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 2361 | const scalar_ty = ty.scalarType(mod); | 2400 | const scalar_ty = ty.scalarType(mod); |
| 2362 | for (result_data, 0..) |*scalar, i| { | 2401 | for (result_data, 0..) |*scalar, i| { |
| 2363 | const lhs_elem = try lhs.elemValue(mod, i); | 2402 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2364 | const rhs_elem = try rhs.elemValue(mod, i); | 2403 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2365 | const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod) catch |err| switch (err) { | 2404 | const val = intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt) catch |err| switch (err) { |
| 2366 | error.Overflow => { | 2405 | error.Overflow => { |
| 2367 | overflow_idx.* = i; | 2406 | overflow_idx.* = i; |
| 2368 | return error.Overflow; | 2407 | return error.Overflow; |
| ... | @@ -2371,26 +2410,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator | ... | @@ -2371,26 +2410,26 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2371 | }; | 2410 | }; |
| 2372 | scalar.* = val.toIntern(); | 2411 | scalar.* = val.toIntern(); |
| 2373 | } | 2412 | } |
| 2374 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2413 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2375 | .ty = ty.toIntern(), | 2414 | .ty = ty.toIntern(), |
| 2376 | .storage = .{ .elems = result_data }, | 2415 | .storage = .{ .elems = result_data }, |
| 2377 | } }))); | 2416 | } })); |
| 2378 | } | 2417 | } |
| 2379 | return intMulScalar(lhs, rhs, ty, allocator, mod); | 2418 | return intMulScalar(lhs, rhs, ty, allocator, pt); |
| 2380 | } | 2419 | } |
| 2381 | 2420 | ||
| 2382 | pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2421 | pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2383 | if (ty.toIntern() != .comptime_int_type) { | 2422 | if (ty.toIntern() != .comptime_int_type) { |
| 2384 | const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, mod); | 2423 | const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, pt); |
| 2385 | if (res.overflow_bit.compareAllWithZero(.neq, mod)) return error.Overflow; | 2424 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; |
| 2386 | return res.wrapped_result; | 2425 | return res.wrapped_result; |
| 2387 | } | 2426 | } |
| 2388 | // TODO is this a performance issue? maybe we should try the operation without | 2427 | // TODO is this a performance issue? maybe we should try the operation without |
| 2389 | // resorting to BigInt first. | 2428 | // resorting to BigInt first. |
| 2390 | var lhs_space: Value.BigIntSpace = undefined; | 2429 | var lhs_space: Value.BigIntSpace = undefined; |
| 2391 | var rhs_space: Value.BigIntSpace = undefined; | 2430 | var rhs_space: Value.BigIntSpace = undefined; |
| 2392 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2431 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2393 | const rhs_bigint = rhs.toBigInt(&rhs_space, mod); | 2432 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); |
| 2394 | const limbs = try allocator.alloc( | 2433 | const limbs = try allocator.alloc( |
| 2395 | std.math.big.Limb, | 2434 | std.math.big.Limb, |
| 2396 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, | 2435 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, |
| ... | @@ -2402,23 +2441,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: | ... | @@ -2402,23 +2441,24 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2402 | ); | 2441 | ); |
| 2403 | defer allocator.free(limbs_buffer); | 2442 | defer allocator.free(limbs_buffer); |
| 2404 | result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator); | 2443 | result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator); |
| 2405 | return mod.intValue_big(ty, result_bigint.toConst()); | 2444 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2406 | } | 2445 | } |
| 2407 | 2446 | ||
| 2408 | pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value { | 2447 | pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, pt: Zcu.PerThread) !Value { |
| 2448 | const mod = pt.zcu; | ||
| 2409 | if (ty.zigTypeTag(mod) == .Vector) { | 2449 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2410 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2450 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 2411 | const scalar_ty = ty.scalarType(mod); | 2451 | const scalar_ty = ty.scalarType(mod); |
| 2412 | for (result_data, 0..) |*scalar, i| { | 2452 | for (result_data, 0..) |*scalar, i| { |
| 2413 | const elem_val = try val.elemValue(mod, i); | 2453 | const elem_val = try val.elemValue(pt, i); |
| 2414 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern(); | 2454 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, pt)).toIntern(); |
| 2415 | } | 2455 | } |
| 2416 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2456 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2417 | .ty = ty.toIntern(), | 2457 | .ty = ty.toIntern(), |
| 2418 | .storage = .{ .elems = result_data }, | 2458 | .storage = .{ .elems = result_data }, |
| 2419 | } }))); | 2459 | } })); |
| 2420 | } | 2460 | } |
| 2421 | return intTruncScalar(val, ty, allocator, signedness, bits, mod); | 2461 | return intTruncScalar(val, ty, allocator, signedness, bits, pt); |
| 2422 | } | 2462 | } |
| 2423 | 2463 | ||
| 2424 | /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`. | 2464 | /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`. |
| ... | @@ -2428,22 +2468,22 @@ pub fn intTruncBitsAsValue( | ... | @@ -2428,22 +2468,22 @@ pub fn intTruncBitsAsValue( |
| 2428 | allocator: Allocator, | 2468 | allocator: Allocator, |
| 2429 | signedness: std.builtin.Signedness, | 2469 | signedness: std.builtin.Signedness, |
| 2430 | bits: Value, | 2470 | bits: Value, |
| 2431 | mod: *Module, | 2471 | pt: Zcu.PerThread, |
| 2432 | ) !Value { | 2472 | ) !Value { |
| 2433 | if (ty.zigTypeTag(mod) == .Vector) { | 2473 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2434 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2474 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2435 | const scalar_ty = ty.scalarType(mod); | 2475 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2436 | for (result_data, 0..) |*scalar, i| { | 2476 | for (result_data, 0..) |*scalar, i| { |
| 2437 | const elem_val = try val.elemValue(mod, i); | 2477 | const elem_val = try val.elemValue(pt, i); |
| 2438 | const bits_elem = try bits.elemValue(mod, i); | 2478 | const bits_elem = try bits.elemValue(pt, i); |
| 2439 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(mod)), mod)).toIntern(); | 2479 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(pt)), pt)).toIntern(); |
| 2440 | } | 2480 | } |
| 2441 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2481 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2442 | .ty = ty.toIntern(), | 2482 | .ty = ty.toIntern(), |
| 2443 | .storage = .{ .elems = result_data }, | 2483 | .storage = .{ .elems = result_data }, |
| 2444 | } }))); | 2484 | } })); |
| 2445 | } | 2485 | } |
| 2446 | return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(mod)), mod); | 2486 | return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(pt)), pt); |
| 2447 | } | 2487 | } |
| 2448 | 2488 | ||
| 2449 | pub fn intTruncScalar( | 2489 | pub fn intTruncScalar( |
| ... | @@ -2452,14 +2492,15 @@ pub fn intTruncScalar( | ... | @@ -2452,14 +2492,15 @@ pub fn intTruncScalar( |
| 2452 | allocator: Allocator, | 2492 | allocator: Allocator, |
| 2453 | signedness: std.builtin.Signedness, | 2493 | signedness: std.builtin.Signedness, |
| 2454 | bits: u16, | 2494 | bits: u16, |
| 2455 | zcu: *Zcu, | 2495 | pt: Zcu.PerThread, |
| 2456 | ) !Value { | 2496 | ) !Value { |
| 2457 | if (bits == 0) return zcu.intValue(ty, 0); | 2497 | const zcu = pt.zcu; |
| 2498 | if (bits == 0) return pt.intValue(ty, 0); | ||
| 2458 | 2499 | ||
| 2459 | if (val.isUndef(zcu)) return zcu.undefValue(ty); | 2500 | if (val.isUndef(zcu)) return pt.undefValue(ty); |
| 2460 | 2501 | ||
| 2461 | var val_space: Value.BigIntSpace = undefined; | 2502 | var val_space: Value.BigIntSpace = undefined; |
| 2462 | const val_bigint = val.toBigInt(&val_space, zcu); | 2503 | const val_bigint = val.toBigInt(&val_space, pt); |
| 2463 | 2504 | ||
| 2464 | const limbs = try allocator.alloc( | 2505 | const limbs = try allocator.alloc( |
| 2465 | std.math.big.Limb, | 2506 | std.math.big.Limb, |
| ... | @@ -2468,32 +2509,33 @@ pub fn intTruncScalar( | ... | @@ -2468,32 +2509,33 @@ pub fn intTruncScalar( |
| 2468 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; | 2509 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 2469 | 2510 | ||
| 2470 | result_bigint.truncate(val_bigint, signedness, bits); | 2511 | result_bigint.truncate(val_bigint, signedness, bits); |
| 2471 | return zcu.intValue_big(ty, result_bigint.toConst()); | 2512 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2472 | } | 2513 | } |
| 2473 | 2514 | ||
| 2474 | pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2515 | pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2516 | const mod = pt.zcu; | ||
| 2475 | if (ty.zigTypeTag(mod) == .Vector) { | 2517 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2476 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2518 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 2477 | const scalar_ty = ty.scalarType(mod); | 2519 | const scalar_ty = ty.scalarType(mod); |
| 2478 | for (result_data, 0..) |*scalar, i| { | 2520 | for (result_data, 0..) |*scalar, i| { |
| 2479 | const lhs_elem = try lhs.elemValue(mod, i); | 2521 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2480 | const rhs_elem = try rhs.elemValue(mod, i); | 2522 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2481 | scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2523 | scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2482 | } | 2524 | } |
| 2483 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2525 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2484 | .ty = ty.toIntern(), | 2526 | .ty = ty.toIntern(), |
| 2485 | .storage = .{ .elems = result_data }, | 2527 | .storage = .{ .elems = result_data }, |
| 2486 | } }))); | 2528 | } })); |
| 2487 | } | 2529 | } |
| 2488 | return shlScalar(lhs, rhs, ty, allocator, mod); | 2530 | return shlScalar(lhs, rhs, ty, allocator, pt); |
| 2489 | } | 2531 | } |
| 2490 | 2532 | ||
| 2491 | pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2533 | pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2492 | // TODO is this a performance issue? maybe we should try the operation without | 2534 | // TODO is this a performance issue? maybe we should try the operation without |
| 2493 | // resorting to BigInt first. | 2535 | // resorting to BigInt first. |
| 2494 | var lhs_space: Value.BigIntSpace = undefined; | 2536 | var lhs_space: Value.BigIntSpace = undefined; |
| 2495 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2537 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2496 | const shift: usize = @intCast(rhs.toUnsignedInt(mod)); | 2538 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); |
| 2497 | const limbs = try allocator.alloc( | 2539 | const limbs = try allocator.alloc( |
| 2498 | std.math.big.Limb, | 2540 | std.math.big.Limb, |
| 2499 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, | 2541 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, |
| ... | @@ -2505,11 +2547,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M | ... | @@ -2505,11 +2547,11 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M |
| 2505 | }; | 2547 | }; |
| 2506 | result_bigint.shiftLeft(lhs_bigint, shift); | 2548 | result_bigint.shiftLeft(lhs_bigint, shift); |
| 2507 | if (ty.toIntern() != .comptime_int_type) { | 2549 | if (ty.toIntern() != .comptime_int_type) { |
| 2508 | const int_info = ty.intInfo(mod); | 2550 | const int_info = ty.intInfo(pt.zcu); |
| 2509 | result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits); | 2551 | result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits); |
| 2510 | } | 2552 | } |
| 2511 | 2553 | ||
| 2512 | return mod.intValue_big(ty, result_bigint.toConst()); | 2554 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2513 | } | 2555 | } |
| 2514 | 2556 | ||
| 2515 | pub fn shlWithOverflow( | 2557 | pub fn shlWithOverflow( |
| ... | @@ -2517,32 +2559,32 @@ pub fn shlWithOverflow( | ... | @@ -2517,32 +2559,32 @@ pub fn shlWithOverflow( |
| 2517 | rhs: Value, | 2559 | rhs: Value, |
| 2518 | ty: Type, | 2560 | ty: Type, |
| 2519 | allocator: Allocator, | 2561 | allocator: Allocator, |
| 2520 | mod: *Module, | 2562 | pt: Zcu.PerThread, |
| 2521 | ) !OverflowArithmeticResult { | 2563 | ) !OverflowArithmeticResult { |
| 2522 | if (ty.zigTypeTag(mod) == .Vector) { | 2564 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2523 | const vec_len = ty.vectorLen(mod); | 2565 | const vec_len = ty.vectorLen(pt.zcu); |
| 2524 | const overflowed_data = try allocator.alloc(InternPool.Index, vec_len); | 2566 | const overflowed_data = try allocator.alloc(InternPool.Index, vec_len); |
| 2525 | const result_data = try allocator.alloc(InternPool.Index, vec_len); | 2567 | const result_data = try allocator.alloc(InternPool.Index, vec_len); |
| 2526 | const scalar_ty = ty.scalarType(mod); | 2568 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2527 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { | 2569 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 2528 | const lhs_elem = try lhs.elemValue(mod, i); | 2570 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2529 | const rhs_elem = try rhs.elemValue(mod, i); | 2571 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2530 | const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod); | 2572 | const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt); |
| 2531 | of.* = of_math_result.overflow_bit.toIntern(); | 2573 | of.* = of_math_result.overflow_bit.toIntern(); |
| 2532 | scalar.* = of_math_result.wrapped_result.toIntern(); | 2574 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 2533 | } | 2575 | } |
| 2534 | return OverflowArithmeticResult{ | 2576 | return OverflowArithmeticResult{ |
| 2535 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2577 | .overflow_bit = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2536 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 2578 | .ty = (try pt.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 2537 | .storage = .{ .elems = overflowed_data }, | 2579 | .storage = .{ .elems = overflowed_data }, |
| 2538 | } }))), | 2580 | } })), |
| 2539 | .wrapped_result = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2581 | .wrapped_result = Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2540 | .ty = ty.toIntern(), | 2582 | .ty = ty.toIntern(), |
| 2541 | .storage = .{ .elems = result_data }, | 2583 | .storage = .{ .elems = result_data }, |
| 2542 | } }))), | 2584 | } })), |
| 2543 | }; | 2585 | }; |
| 2544 | } | 2586 | } |
| 2545 | return shlWithOverflowScalar(lhs, rhs, ty, allocator, mod); | 2587 | return shlWithOverflowScalar(lhs, rhs, ty, allocator, pt); |
| 2546 | } | 2588 | } |
| 2547 | 2589 | ||
| 2548 | pub fn shlWithOverflowScalar( | 2590 | pub fn shlWithOverflowScalar( |
| ... | @@ -2550,12 +2592,12 @@ pub fn shlWithOverflowScalar( | ... | @@ -2550,12 +2592,12 @@ pub fn shlWithOverflowScalar( |
| 2550 | rhs: Value, | 2592 | rhs: Value, |
| 2551 | ty: Type, | 2593 | ty: Type, |
| 2552 | allocator: Allocator, | 2594 | allocator: Allocator, |
| 2553 | mod: *Module, | 2595 | pt: Zcu.PerThread, |
| 2554 | ) !OverflowArithmeticResult { | 2596 | ) !OverflowArithmeticResult { |
| 2555 | const info = ty.intInfo(mod); | 2597 | const info = ty.intInfo(pt.zcu); |
| 2556 | var lhs_space: Value.BigIntSpace = undefined; | 2598 | var lhs_space: Value.BigIntSpace = undefined; |
| 2557 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2599 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2558 | const shift: usize = @intCast(rhs.toUnsignedInt(mod)); | 2600 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); |
| 2559 | const limbs = try allocator.alloc( | 2601 | const limbs = try allocator.alloc( |
| 2560 | std.math.big.Limb, | 2602 | std.math.big.Limb, |
| 2561 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, | 2603 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, |
| ... | @@ -2571,8 +2613,8 @@ pub fn shlWithOverflowScalar( | ... | @@ -2571,8 +2613,8 @@ pub fn shlWithOverflowScalar( |
| 2571 | result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits); | 2613 | result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits); |
| 2572 | } | 2614 | } |
| 2573 | return OverflowArithmeticResult{ | 2615 | return OverflowArithmeticResult{ |
| 2574 | .overflow_bit = try mod.intValue(Type.u1, @intFromBool(overflowed)), | 2616 | .overflow_bit = try pt.intValue(Type.u1, @intFromBool(overflowed)), |
| 2575 | .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()), | 2617 | .wrapped_result = try pt.intValue_big(ty, result_bigint.toConst()), |
| 2576 | }; | 2618 | }; |
| 2577 | } | 2619 | } |
| 2578 | 2620 | ||
| ... | @@ -2581,22 +2623,22 @@ pub fn shlSat( | ... | @@ -2581,22 +2623,22 @@ pub fn shlSat( |
| 2581 | rhs: Value, | 2623 | rhs: Value, |
| 2582 | ty: Type, | 2624 | ty: Type, |
| 2583 | arena: Allocator, | 2625 | arena: Allocator, |
| 2584 | mod: *Module, | 2626 | pt: Zcu.PerThread, |
| 2585 | ) !Value { | 2627 | ) !Value { |
| 2586 | if (ty.zigTypeTag(mod) == .Vector) { | 2628 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2587 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 2629 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2588 | const scalar_ty = ty.scalarType(mod); | 2630 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2589 | for (result_data, 0..) |*scalar, i| { | 2631 | for (result_data, 0..) |*scalar, i| { |
| 2590 | const lhs_elem = try lhs.elemValue(mod, i); | 2632 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2591 | const rhs_elem = try rhs.elemValue(mod, i); | 2633 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2592 | scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 2634 | scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 2593 | } | 2635 | } |
| 2594 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2636 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2595 | .ty = ty.toIntern(), | 2637 | .ty = ty.toIntern(), |
| 2596 | .storage = .{ .elems = result_data }, | 2638 | .storage = .{ .elems = result_data }, |
| 2597 | } }))); | 2639 | } })); |
| 2598 | } | 2640 | } |
| 2599 | return shlSatScalar(lhs, rhs, ty, arena, mod); | 2641 | return shlSatScalar(lhs, rhs, ty, arena, pt); |
| 2600 | } | 2642 | } |
| 2601 | 2643 | ||
| 2602 | pub fn shlSatScalar( | 2644 | pub fn shlSatScalar( |
| ... | @@ -2604,15 +2646,15 @@ pub fn shlSatScalar( | ... | @@ -2604,15 +2646,15 @@ pub fn shlSatScalar( |
| 2604 | rhs: Value, | 2646 | rhs: Value, |
| 2605 | ty: Type, | 2647 | ty: Type, |
| 2606 | arena: Allocator, | 2648 | arena: Allocator, |
| 2607 | mod: *Module, | 2649 | pt: Zcu.PerThread, |
| 2608 | ) !Value { | 2650 | ) !Value { |
| 2609 | // TODO is this a performance issue? maybe we should try the operation without | 2651 | // TODO is this a performance issue? maybe we should try the operation without |
| 2610 | // resorting to BigInt first. | 2652 | // resorting to BigInt first. |
| 2611 | const info = ty.intInfo(mod); | 2653 | const info = ty.intInfo(pt.zcu); |
| 2612 | 2654 | ||
| 2613 | var lhs_space: Value.BigIntSpace = undefined; | 2655 | var lhs_space: Value.BigIntSpace = undefined; |
| 2614 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2656 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2615 | const shift: usize = @intCast(rhs.toUnsignedInt(mod)); | 2657 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); |
| 2616 | const limbs = try arena.alloc( | 2658 | const limbs = try arena.alloc( |
| 2617 | std.math.big.Limb, | 2659 | std.math.big.Limb, |
| 2618 | std.math.big.int.calcTwosCompLimbCount(info.bits) + 1, | 2660 | std.math.big.int.calcTwosCompLimbCount(info.bits) + 1, |
| ... | @@ -2623,7 +2665,7 @@ pub fn shlSatScalar( | ... | @@ -2623,7 +2665,7 @@ pub fn shlSatScalar( |
| 2623 | .len = undefined, | 2665 | .len = undefined, |
| 2624 | }; | 2666 | }; |
| 2625 | result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits); | 2667 | result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits); |
| 2626 | return mod.intValue_big(ty, result_bigint.toConst()); | 2668 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2627 | } | 2669 | } |
| 2628 | 2670 | ||
| 2629 | pub fn shlTrunc( | 2671 | pub fn shlTrunc( |
| ... | @@ -2631,22 +2673,22 @@ pub fn shlTrunc( | ... | @@ -2631,22 +2673,22 @@ pub fn shlTrunc( |
| 2631 | rhs: Value, | 2673 | rhs: Value, |
| 2632 | ty: Type, | 2674 | ty: Type, |
| 2633 | arena: Allocator, | 2675 | arena: Allocator, |
| 2634 | mod: *Module, | 2676 | pt: Zcu.PerThread, |
| 2635 | ) !Value { | 2677 | ) !Value { |
| 2636 | if (ty.zigTypeTag(mod) == .Vector) { | 2678 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2637 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 2679 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2638 | const scalar_ty = ty.scalarType(mod); | 2680 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2639 | for (result_data, 0..) |*scalar, i| { | 2681 | for (result_data, 0..) |*scalar, i| { |
| 2640 | const lhs_elem = try lhs.elemValue(mod, i); | 2682 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2641 | const rhs_elem = try rhs.elemValue(mod, i); | 2683 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2642 | scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); | 2684 | scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, pt)).toIntern(); |
| 2643 | } | 2685 | } |
| 2644 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2686 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2645 | .ty = ty.toIntern(), | 2687 | .ty = ty.toIntern(), |
| 2646 | .storage = .{ .elems = result_data }, | 2688 | .storage = .{ .elems = result_data }, |
| 2647 | } }))); | 2689 | } })); |
| 2648 | } | 2690 | } |
| 2649 | return shlTruncScalar(lhs, rhs, ty, arena, mod); | 2691 | return shlTruncScalar(lhs, rhs, ty, arena, pt); |
| 2650 | } | 2692 | } |
| 2651 | 2693 | ||
| 2652 | pub fn shlTruncScalar( | 2694 | pub fn shlTruncScalar( |
| ... | @@ -2654,46 +2696,46 @@ pub fn shlTruncScalar( | ... | @@ -2654,46 +2696,46 @@ pub fn shlTruncScalar( |
| 2654 | rhs: Value, | 2696 | rhs: Value, |
| 2655 | ty: Type, | 2697 | ty: Type, |
| 2656 | arena: Allocator, | 2698 | arena: Allocator, |
| 2657 | mod: *Module, | 2699 | pt: Zcu.PerThread, |
| 2658 | ) !Value { | 2700 | ) !Value { |
| 2659 | const shifted = try lhs.shl(rhs, ty, arena, mod); | 2701 | const shifted = try lhs.shl(rhs, ty, arena, pt); |
| 2660 | const int_info = ty.intInfo(mod); | 2702 | const int_info = ty.intInfo(pt.zcu); |
| 2661 | const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod); | 2703 | const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, pt); |
| 2662 | return truncated; | 2704 | return truncated; |
| 2663 | } | 2705 | } |
| 2664 | 2706 | ||
| 2665 | pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2707 | pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2666 | if (ty.zigTypeTag(mod) == .Vector) { | 2708 | if (ty.zigTypeTag(pt.zcu) == .Vector) { |
| 2667 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | 2709 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); |
| 2668 | const scalar_ty = ty.scalarType(mod); | 2710 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2669 | for (result_data, 0..) |*scalar, i| { | 2711 | for (result_data, 0..) |*scalar, i| { |
| 2670 | const lhs_elem = try lhs.elemValue(mod, i); | 2712 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2671 | const rhs_elem = try rhs.elemValue(mod, i); | 2713 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2672 | scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); | 2714 | scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, pt)).toIntern(); |
| 2673 | } | 2715 | } |
| 2674 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2716 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2675 | .ty = ty.toIntern(), | 2717 | .ty = ty.toIntern(), |
| 2676 | .storage = .{ .elems = result_data }, | 2718 | .storage = .{ .elems = result_data }, |
| 2677 | } }))); | 2719 | } })); |
| 2678 | } | 2720 | } |
| 2679 | return shrScalar(lhs, rhs, ty, allocator, mod); | 2721 | return shrScalar(lhs, rhs, ty, allocator, pt); |
| 2680 | } | 2722 | } |
| 2681 | 2723 | ||
| 2682 | pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { | 2724 | pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2683 | // TODO is this a performance issue? maybe we should try the operation without | 2725 | // TODO is this a performance issue? maybe we should try the operation without |
| 2684 | // resorting to BigInt first. | 2726 | // resorting to BigInt first. |
| 2685 | var lhs_space: Value.BigIntSpace = undefined; | 2727 | var lhs_space: Value.BigIntSpace = undefined; |
| 2686 | const lhs_bigint = lhs.toBigInt(&lhs_space, mod); | 2728 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); |
| 2687 | const shift: usize = @intCast(rhs.toUnsignedInt(mod)); | 2729 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); |
| 2688 | 2730 | ||
| 2689 | const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8)); | 2731 | const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8)); |
| 2690 | if (result_limbs == 0) { | 2732 | if (result_limbs == 0) { |
| 2691 | // The shift is enough to remove all the bits from the number, which means the | 2733 | // The shift is enough to remove all the bits from the number, which means the |
| 2692 | // result is 0 or -1 depending on the sign. | 2734 | // result is 0 or -1 depending on the sign. |
| 2693 | if (lhs_bigint.positive) { | 2735 | if (lhs_bigint.positive) { |
| 2694 | return mod.intValue(ty, 0); | 2736 | return pt.intValue(ty, 0); |
| 2695 | } else { | 2737 | } else { |
| 2696 | return mod.intValue(ty, -1); | 2738 | return pt.intValue(ty, -1); |
| 2697 | } | 2739 | } |
| 2698 | } | 2740 | } |
| 2699 | 2741 | ||
| ... | @@ -2707,48 +2749,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M | ... | @@ -2707,48 +2749,45 @@ pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M |
| 2707 | .len = undefined, | 2749 | .len = undefined, |
| 2708 | }; | 2750 | }; |
| 2709 | result_bigint.shiftRight(lhs_bigint, shift); | 2751 | result_bigint.shiftRight(lhs_bigint, shift); |
| 2710 | return mod.intValue_big(ty, result_bigint.toConst()); | 2752 | return pt.intValue_big(ty, result_bigint.toConst()); |
| 2711 | } | 2753 | } |
| 2712 | 2754 | ||
| 2713 | pub fn floatNeg( | 2755 | pub fn floatNeg( |
| 2714 | val: Value, | 2756 | val: Value, |
| 2715 | float_type: Type, | 2757 | float_type: Type, |
| 2716 | arena: Allocator, | 2758 | arena: Allocator, |
| 2717 | mod: *Module, | 2759 | pt: Zcu.PerThread, |
| 2718 | ) !Value { | 2760 | ) !Value { |
| 2761 | const mod = pt.zcu; | ||
| 2719 | if (float_type.zigTypeTag(mod) == .Vector) { | 2762 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 2720 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2763 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 2721 | const scalar_ty = float_type.scalarType(mod); | 2764 | const scalar_ty = float_type.scalarType(mod); |
| 2722 | for (result_data, 0..) |*scalar, i| { | 2765 | for (result_data, 0..) |*scalar, i| { |
| 2723 | const elem_val = try val.elemValue(mod, i); | 2766 | const elem_val = try val.elemValue(pt, i); |
| 2724 | scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern(); | 2767 | scalar.* = (try floatNegScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 2725 | } | 2768 | } |
| 2726 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2769 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2727 | .ty = float_type.toIntern(), | 2770 | .ty = float_type.toIntern(), |
| 2728 | .storage = .{ .elems = result_data }, | 2771 | .storage = .{ .elems = result_data }, |
| 2729 | } }))); | 2772 | } })); |
| 2730 | } | 2773 | } |
| 2731 | return floatNegScalar(val, float_type, mod); | 2774 | return floatNegScalar(val, float_type, pt); |
| 2732 | } | 2775 | } |
| 2733 | 2776 | ||
| 2734 | pub fn floatNegScalar( | 2777 | pub fn floatNegScalar(val: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2735 | val: Value, | 2778 | const target = pt.zcu.getTarget(); |
| 2736 | float_type: Type, | ||
| 2737 | mod: *Module, | ||
| 2738 | ) !Value { | ||
| 2739 | const target = mod.getTarget(); | ||
| 2740 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2779 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2741 | 16 => .{ .f16 = -val.toFloat(f16, mod) }, | 2780 | 16 => .{ .f16 = -val.toFloat(f16, pt) }, |
| 2742 | 32 => .{ .f32 = -val.toFloat(f32, mod) }, | 2781 | 32 => .{ .f32 = -val.toFloat(f32, pt) }, |
| 2743 | 64 => .{ .f64 = -val.toFloat(f64, mod) }, | 2782 | 64 => .{ .f64 = -val.toFloat(f64, pt) }, |
| 2744 | 80 => .{ .f80 = -val.toFloat(f80, mod) }, | 2783 | 80 => .{ .f80 = -val.toFloat(f80, pt) }, |
| 2745 | 128 => .{ .f128 = -val.toFloat(f128, mod) }, | 2784 | 128 => .{ .f128 = -val.toFloat(f128, pt) }, |
| 2746 | else => unreachable, | 2785 | else => unreachable, |
| 2747 | }; | 2786 | }; |
| 2748 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2787 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2749 | .ty = float_type.toIntern(), | 2788 | .ty = float_type.toIntern(), |
| 2750 | .storage = storage, | 2789 | .storage = storage, |
| 2751 | } }))); | 2790 | } })); |
| 2752 | } | 2791 | } |
| 2753 | 2792 | ||
| 2754 | pub fn floatAdd( | 2793 | pub fn floatAdd( |
| ... | @@ -2756,43 +2795,45 @@ pub fn floatAdd( | ... | @@ -2756,43 +2795,45 @@ pub fn floatAdd( |
| 2756 | rhs: Value, | 2795 | rhs: Value, |
| 2757 | float_type: Type, | 2796 | float_type: Type, |
| 2758 | arena: Allocator, | 2797 | arena: Allocator, |
| 2759 | mod: *Module, | 2798 | pt: Zcu.PerThread, |
| 2760 | ) !Value { | 2799 | ) !Value { |
| 2800 | const mod = pt.zcu; | ||
| 2761 | if (float_type.zigTypeTag(mod) == .Vector) { | 2801 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 2762 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2802 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 2763 | const scalar_ty = float_type.scalarType(mod); | 2803 | const scalar_ty = float_type.scalarType(mod); |
| 2764 | for (result_data, 0..) |*scalar, i| { | 2804 | for (result_data, 0..) |*scalar, i| { |
| 2765 | const lhs_elem = try lhs.elemValue(mod, i); | 2805 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2766 | const rhs_elem = try rhs.elemValue(mod, i); | 2806 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2767 | scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2807 | scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2768 | } | 2808 | } |
| 2769 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2809 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2770 | .ty = float_type.toIntern(), | 2810 | .ty = float_type.toIntern(), |
| 2771 | .storage = .{ .elems = result_data }, | 2811 | .storage = .{ .elems = result_data }, |
| 2772 | } }))); | 2812 | } })); |
| 2773 | } | 2813 | } |
| 2774 | return floatAddScalar(lhs, rhs, float_type, mod); | 2814 | return floatAddScalar(lhs, rhs, float_type, pt); |
| 2775 | } | 2815 | } |
| 2776 | 2816 | ||
| 2777 | pub fn floatAddScalar( | 2817 | pub fn floatAddScalar( |
| 2778 | lhs: Value, | 2818 | lhs: Value, |
| 2779 | rhs: Value, | 2819 | rhs: Value, |
| 2780 | float_type: Type, | 2820 | float_type: Type, |
| 2781 | mod: *Module, | 2821 | pt: Zcu.PerThread, |
| 2782 | ) !Value { | 2822 | ) !Value { |
| 2823 | const mod = pt.zcu; | ||
| 2783 | const target = mod.getTarget(); | 2824 | const target = mod.getTarget(); |
| 2784 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2825 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2785 | 16 => .{ .f16 = lhs.toFloat(f16, mod) + rhs.toFloat(f16, mod) }, | 2826 | 16 => .{ .f16 = lhs.toFloat(f16, pt) + rhs.toFloat(f16, pt) }, |
| 2786 | 32 => .{ .f32 = lhs.toFloat(f32, mod) + rhs.toFloat(f32, mod) }, | 2827 | 32 => .{ .f32 = lhs.toFloat(f32, pt) + rhs.toFloat(f32, pt) }, |
| 2787 | 64 => .{ .f64 = lhs.toFloat(f64, mod) + rhs.toFloat(f64, mod) }, | 2828 | 64 => .{ .f64 = lhs.toFloat(f64, pt) + rhs.toFloat(f64, pt) }, |
| 2788 | 80 => .{ .f80 = lhs.toFloat(f80, mod) + rhs.toFloat(f80, mod) }, | 2829 | 80 => .{ .f80 = lhs.toFloat(f80, pt) + rhs.toFloat(f80, pt) }, |
| 2789 | 128 => .{ .f128 = lhs.toFloat(f128, mod) + rhs.toFloat(f128, mod) }, | 2830 | 128 => .{ .f128 = lhs.toFloat(f128, pt) + rhs.toFloat(f128, pt) }, |
| 2790 | else => unreachable, | 2831 | else => unreachable, |
| 2791 | }; | 2832 | }; |
| 2792 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2833 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2793 | .ty = float_type.toIntern(), | 2834 | .ty = float_type.toIntern(), |
| 2794 | .storage = storage, | 2835 | .storage = storage, |
| 2795 | } }))); | 2836 | } })); |
| 2796 | } | 2837 | } |
| 2797 | 2838 | ||
| 2798 | pub fn floatSub( | 2839 | pub fn floatSub( |
| ... | @@ -2800,43 +2841,45 @@ pub fn floatSub( | ... | @@ -2800,43 +2841,45 @@ pub fn floatSub( |
| 2800 | rhs: Value, | 2841 | rhs: Value, |
| 2801 | float_type: Type, | 2842 | float_type: Type, |
| 2802 | arena: Allocator, | 2843 | arena: Allocator, |
| 2803 | mod: *Module, | 2844 | pt: Zcu.PerThread, |
| 2804 | ) !Value { | 2845 | ) !Value { |
| 2846 | const mod = pt.zcu; | ||
| 2805 | if (float_type.zigTypeTag(mod) == .Vector) { | 2847 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 2806 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2848 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 2807 | const scalar_ty = float_type.scalarType(mod); | 2849 | const scalar_ty = float_type.scalarType(mod); |
| 2808 | for (result_data, 0..) |*scalar, i| { | 2850 | for (result_data, 0..) |*scalar, i| { |
| 2809 | const lhs_elem = try lhs.elemValue(mod, i); | 2851 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2810 | const rhs_elem = try rhs.elemValue(mod, i); | 2852 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2811 | scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2853 | scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2812 | } | 2854 | } |
| 2813 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2855 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2814 | .ty = float_type.toIntern(), | 2856 | .ty = float_type.toIntern(), |
| 2815 | .storage = .{ .elems = result_data }, | 2857 | .storage = .{ .elems = result_data }, |
| 2816 | } }))); | 2858 | } })); |
| 2817 | } | 2859 | } |
| 2818 | return floatSubScalar(lhs, rhs, float_type, mod); | 2860 | return floatSubScalar(lhs, rhs, float_type, pt); |
| 2819 | } | 2861 | } |
| 2820 | 2862 | ||
| 2821 | pub fn floatSubScalar( | 2863 | pub fn floatSubScalar( |
| 2822 | lhs: Value, | 2864 | lhs: Value, |
| 2823 | rhs: Value, | 2865 | rhs: Value, |
| 2824 | float_type: Type, | 2866 | float_type: Type, |
| 2825 | mod: *Module, | 2867 | pt: Zcu.PerThread, |
| 2826 | ) !Value { | 2868 | ) !Value { |
| 2869 | const mod = pt.zcu; | ||
| 2827 | const target = mod.getTarget(); | 2870 | const target = mod.getTarget(); |
| 2828 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2871 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2829 | 16 => .{ .f16 = lhs.toFloat(f16, mod) - rhs.toFloat(f16, mod) }, | 2872 | 16 => .{ .f16 = lhs.toFloat(f16, pt) - rhs.toFloat(f16, pt) }, |
| 2830 | 32 => .{ .f32 = lhs.toFloat(f32, mod) - rhs.toFloat(f32, mod) }, | 2873 | 32 => .{ .f32 = lhs.toFloat(f32, pt) - rhs.toFloat(f32, pt) }, |
| 2831 | 64 => .{ .f64 = lhs.toFloat(f64, mod) - rhs.toFloat(f64, mod) }, | 2874 | 64 => .{ .f64 = lhs.toFloat(f64, pt) - rhs.toFloat(f64, pt) }, |
| 2832 | 80 => .{ .f80 = lhs.toFloat(f80, mod) - rhs.toFloat(f80, mod) }, | 2875 | 80 => .{ .f80 = lhs.toFloat(f80, pt) - rhs.toFloat(f80, pt) }, |
| 2833 | 128 => .{ .f128 = lhs.toFloat(f128, mod) - rhs.toFloat(f128, mod) }, | 2876 | 128 => .{ .f128 = lhs.toFloat(f128, pt) - rhs.toFloat(f128, pt) }, |
| 2834 | else => unreachable, | 2877 | else => unreachable, |
| 2835 | }; | 2878 | }; |
| 2836 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2879 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2837 | .ty = float_type.toIntern(), | 2880 | .ty = float_type.toIntern(), |
| 2838 | .storage = storage, | 2881 | .storage = storage, |
| 2839 | } }))); | 2882 | } })); |
| 2840 | } | 2883 | } |
| 2841 | 2884 | ||
| 2842 | pub fn floatDiv( | 2885 | pub fn floatDiv( |
| ... | @@ -2844,43 +2887,43 @@ pub fn floatDiv( | ... | @@ -2844,43 +2887,43 @@ pub fn floatDiv( |
| 2844 | rhs: Value, | 2887 | rhs: Value, |
| 2845 | float_type: Type, | 2888 | float_type: Type, |
| 2846 | arena: Allocator, | 2889 | arena: Allocator, |
| 2847 | mod: *Module, | 2890 | pt: Zcu.PerThread, |
| 2848 | ) !Value { | 2891 | ) !Value { |
| 2849 | if (float_type.zigTypeTag(mod) == .Vector) { | 2892 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 2850 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2893 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 2851 | const scalar_ty = float_type.scalarType(mod); | 2894 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 2852 | for (result_data, 0..) |*scalar, i| { | 2895 | for (result_data, 0..) |*scalar, i| { |
| 2853 | const lhs_elem = try lhs.elemValue(mod, i); | 2896 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2854 | const rhs_elem = try rhs.elemValue(mod, i); | 2897 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2855 | scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2898 | scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2856 | } | 2899 | } |
| 2857 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2900 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2858 | .ty = float_type.toIntern(), | 2901 | .ty = float_type.toIntern(), |
| 2859 | .storage = .{ .elems = result_data }, | 2902 | .storage = .{ .elems = result_data }, |
| 2860 | } }))); | 2903 | } })); |
| 2861 | } | 2904 | } |
| 2862 | return floatDivScalar(lhs, rhs, float_type, mod); | 2905 | return floatDivScalar(lhs, rhs, float_type, pt); |
| 2863 | } | 2906 | } |
| 2864 | 2907 | ||
| 2865 | pub fn floatDivScalar( | 2908 | pub fn floatDivScalar( |
| 2866 | lhs: Value, | 2909 | lhs: Value, |
| 2867 | rhs: Value, | 2910 | rhs: Value, |
| 2868 | float_type: Type, | 2911 | float_type: Type, |
| 2869 | mod: *Module, | 2912 | pt: Zcu.PerThread, |
| 2870 | ) !Value { | 2913 | ) !Value { |
| 2871 | const target = mod.getTarget(); | 2914 | const target = pt.zcu.getTarget(); |
| 2872 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2915 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2873 | 16 => .{ .f16 = lhs.toFloat(f16, mod) / rhs.toFloat(f16, mod) }, | 2916 | 16 => .{ .f16 = lhs.toFloat(f16, pt) / rhs.toFloat(f16, pt) }, |
| 2874 | 32 => .{ .f32 = lhs.toFloat(f32, mod) / rhs.toFloat(f32, mod) }, | 2917 | 32 => .{ .f32 = lhs.toFloat(f32, pt) / rhs.toFloat(f32, pt) }, |
| 2875 | 64 => .{ .f64 = lhs.toFloat(f64, mod) / rhs.toFloat(f64, mod) }, | 2918 | 64 => .{ .f64 = lhs.toFloat(f64, pt) / rhs.toFloat(f64, pt) }, |
| 2876 | 80 => .{ .f80 = lhs.toFloat(f80, mod) / rhs.toFloat(f80, mod) }, | 2919 | 80 => .{ .f80 = lhs.toFloat(f80, pt) / rhs.toFloat(f80, pt) }, |
| 2877 | 128 => .{ .f128 = lhs.toFloat(f128, mod) / rhs.toFloat(f128, mod) }, | 2920 | 128 => .{ .f128 = lhs.toFloat(f128, pt) / rhs.toFloat(f128, pt) }, |
| 2878 | else => unreachable, | 2921 | else => unreachable, |
| 2879 | }; | 2922 | }; |
| 2880 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2923 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2881 | .ty = float_type.toIntern(), | 2924 | .ty = float_type.toIntern(), |
| 2882 | .storage = storage, | 2925 | .storage = storage, |
| 2883 | } }))); | 2926 | } })); |
| 2884 | } | 2927 | } |
| 2885 | 2928 | ||
| 2886 | pub fn floatDivFloor( | 2929 | pub fn floatDivFloor( |
| ... | @@ -2888,43 +2931,43 @@ pub fn floatDivFloor( | ... | @@ -2888,43 +2931,43 @@ pub fn floatDivFloor( |
| 2888 | rhs: Value, | 2931 | rhs: Value, |
| 2889 | float_type: Type, | 2932 | float_type: Type, |
| 2890 | arena: Allocator, | 2933 | arena: Allocator, |
| 2891 | mod: *Module, | 2934 | pt: Zcu.PerThread, |
| 2892 | ) !Value { | 2935 | ) !Value { |
| 2893 | if (float_type.zigTypeTag(mod) == .Vector) { | 2936 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 2894 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2937 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 2895 | const scalar_ty = float_type.scalarType(mod); | 2938 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 2896 | for (result_data, 0..) |*scalar, i| { | 2939 | for (result_data, 0..) |*scalar, i| { |
| 2897 | const lhs_elem = try lhs.elemValue(mod, i); | 2940 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2898 | const rhs_elem = try rhs.elemValue(mod, i); | 2941 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2899 | scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2942 | scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2900 | } | 2943 | } |
| 2901 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2944 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2902 | .ty = float_type.toIntern(), | 2945 | .ty = float_type.toIntern(), |
| 2903 | .storage = .{ .elems = result_data }, | 2946 | .storage = .{ .elems = result_data }, |
| 2904 | } }))); | 2947 | } })); |
| 2905 | } | 2948 | } |
| 2906 | return floatDivFloorScalar(lhs, rhs, float_type, mod); | 2949 | return floatDivFloorScalar(lhs, rhs, float_type, pt); |
| 2907 | } | 2950 | } |
| 2908 | 2951 | ||
| 2909 | pub fn floatDivFloorScalar( | 2952 | pub fn floatDivFloorScalar( |
| 2910 | lhs: Value, | 2953 | lhs: Value, |
| 2911 | rhs: Value, | 2954 | rhs: Value, |
| 2912 | float_type: Type, | 2955 | float_type: Type, |
| 2913 | mod: *Module, | 2956 | pt: Zcu.PerThread, |
| 2914 | ) !Value { | 2957 | ) !Value { |
| 2915 | const target = mod.getTarget(); | 2958 | const target = pt.zcu.getTarget(); |
| 2916 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 2959 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2917 | 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, | 2960 | 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, |
| 2918 | 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, | 2961 | 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, |
| 2919 | 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, | 2962 | 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, |
| 2920 | 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, | 2963 | 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, |
| 2921 | 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, | 2964 | 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, |
| 2922 | else => unreachable, | 2965 | else => unreachable, |
| 2923 | }; | 2966 | }; |
| 2924 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 2967 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2925 | .ty = float_type.toIntern(), | 2968 | .ty = float_type.toIntern(), |
| 2926 | .storage = storage, | 2969 | .storage = storage, |
| 2927 | } }))); | 2970 | } })); |
| 2928 | } | 2971 | } |
| 2929 | 2972 | ||
| 2930 | pub fn floatDivTrunc( | 2973 | pub fn floatDivTrunc( |
| ... | @@ -2932,43 +2975,43 @@ pub fn floatDivTrunc( | ... | @@ -2932,43 +2975,43 @@ pub fn floatDivTrunc( |
| 2932 | rhs: Value, | 2975 | rhs: Value, |
| 2933 | float_type: Type, | 2976 | float_type: Type, |
| 2934 | arena: Allocator, | 2977 | arena: Allocator, |
| 2935 | mod: *Module, | 2978 | pt: Zcu.PerThread, |
| 2936 | ) !Value { | 2979 | ) !Value { |
| 2937 | if (float_type.zigTypeTag(mod) == .Vector) { | 2980 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 2938 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 2981 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 2939 | const scalar_ty = float_type.scalarType(mod); | 2982 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 2940 | for (result_data, 0..) |*scalar, i| { | 2983 | for (result_data, 0..) |*scalar, i| { |
| 2941 | const lhs_elem = try lhs.elemValue(mod, i); | 2984 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2942 | const rhs_elem = try rhs.elemValue(mod, i); | 2985 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2943 | scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 2986 | scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2944 | } | 2987 | } |
| 2945 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2988 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2946 | .ty = float_type.toIntern(), | 2989 | .ty = float_type.toIntern(), |
| 2947 | .storage = .{ .elems = result_data }, | 2990 | .storage = .{ .elems = result_data }, |
| 2948 | } }))); | 2991 | } })); |
| 2949 | } | 2992 | } |
| 2950 | return floatDivTruncScalar(lhs, rhs, float_type, mod); | 2993 | return floatDivTruncScalar(lhs, rhs, float_type, pt); |
| 2951 | } | 2994 | } |
| 2952 | 2995 | ||
| 2953 | pub fn floatDivTruncScalar( | 2996 | pub fn floatDivTruncScalar( |
| 2954 | lhs: Value, | 2997 | lhs: Value, |
| 2955 | rhs: Value, | 2998 | rhs: Value, |
| 2956 | float_type: Type, | 2999 | float_type: Type, |
| 2957 | mod: *Module, | 3000 | pt: Zcu.PerThread, |
| 2958 | ) !Value { | 3001 | ) !Value { |
| 2959 | const target = mod.getTarget(); | 3002 | const target = pt.zcu.getTarget(); |
| 2960 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3003 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2961 | 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, mod), rhs.toFloat(f16, mod)) }, | 3004 | 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, |
| 2962 | 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, mod), rhs.toFloat(f32, mod)) }, | 3005 | 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, |
| 2963 | 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, mod), rhs.toFloat(f64, mod)) }, | 3006 | 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, |
| 2964 | 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, mod), rhs.toFloat(f80, mod)) }, | 3007 | 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, |
| 2965 | 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, mod), rhs.toFloat(f128, mod)) }, | 3008 | 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, |
| 2966 | else => unreachable, | 3009 | else => unreachable, |
| 2967 | }; | 3010 | }; |
| 2968 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3011 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 2969 | .ty = float_type.toIntern(), | 3012 | .ty = float_type.toIntern(), |
| 2970 | .storage = storage, | 3013 | .storage = storage, |
| 2971 | } }))); | 3014 | } })); |
| 2972 | } | 3015 | } |
| 2973 | 3016 | ||
| 2974 | pub fn floatMul( | 3017 | pub fn floatMul( |
| ... | @@ -2976,510 +3019,539 @@ pub fn floatMul( | ... | @@ -2976,510 +3019,539 @@ pub fn floatMul( |
| 2976 | rhs: Value, | 3019 | rhs: Value, |
| 2977 | float_type: Type, | 3020 | float_type: Type, |
| 2978 | arena: Allocator, | 3021 | arena: Allocator, |
| 2979 | mod: *Module, | 3022 | pt: Zcu.PerThread, |
| 2980 | ) !Value { | 3023 | ) !Value { |
| 3024 | const mod = pt.zcu; | ||
| 2981 | if (float_type.zigTypeTag(mod) == .Vector) { | 3025 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 2982 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3026 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 2983 | const scalar_ty = float_type.scalarType(mod); | 3027 | const scalar_ty = float_type.scalarType(mod); |
| 2984 | for (result_data, 0..) |*scalar, i| { | 3028 | for (result_data, 0..) |*scalar, i| { |
| 2985 | const lhs_elem = try lhs.elemValue(mod, i); | 3029 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2986 | const rhs_elem = try rhs.elemValue(mod, i); | 3030 | const rhs_elem = try rhs.elemValue(pt, i); |
| 2987 | scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); | 3031 | scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, pt)).toIntern(); |
| 2988 | } | 3032 | } |
| 2989 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3033 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2990 | .ty = float_type.toIntern(), | 3034 | .ty = float_type.toIntern(), |
| 2991 | .storage = .{ .elems = result_data }, | 3035 | .storage = .{ .elems = result_data }, |
| 2992 | } }))); | 3036 | } })); |
| 2993 | } | 3037 | } |
| 2994 | return floatMulScalar(lhs, rhs, float_type, mod); | 3038 | return floatMulScalar(lhs, rhs, float_type, pt); |
| 2995 | } | 3039 | } |
| 2996 | 3040 | ||
| 2997 | pub fn floatMulScalar( | 3041 | pub fn floatMulScalar( |
| 2998 | lhs: Value, | 3042 | lhs: Value, |
| 2999 | rhs: Value, | 3043 | rhs: Value, |
| 3000 | float_type: Type, | 3044 | float_type: Type, |
| 3001 | mod: *Module, | 3045 | pt: Zcu.PerThread, |
| 3002 | ) !Value { | 3046 | ) !Value { |
| 3047 | const mod = pt.zcu; | ||
| 3003 | const target = mod.getTarget(); | 3048 | const target = mod.getTarget(); |
| 3004 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3049 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3005 | 16 => .{ .f16 = lhs.toFloat(f16, mod) * rhs.toFloat(f16, mod) }, | 3050 | 16 => .{ .f16 = lhs.toFloat(f16, pt) * rhs.toFloat(f16, pt) }, |
| 3006 | 32 => .{ .f32 = lhs.toFloat(f32, mod) * rhs.toFloat(f32, mod) }, | 3051 | 32 => .{ .f32 = lhs.toFloat(f32, pt) * rhs.toFloat(f32, pt) }, |
| 3007 | 64 => .{ .f64 = lhs.toFloat(f64, mod) * rhs.toFloat(f64, mod) }, | 3052 | 64 => .{ .f64 = lhs.toFloat(f64, pt) * rhs.toFloat(f64, pt) }, |
| 3008 | 80 => .{ .f80 = lhs.toFloat(f80, mod) * rhs.toFloat(f80, mod) }, | 3053 | 80 => .{ .f80 = lhs.toFloat(f80, pt) * rhs.toFloat(f80, pt) }, |
| 3009 | 128 => .{ .f128 = lhs.toFloat(f128, mod) * rhs.toFloat(f128, mod) }, | 3054 | 128 => .{ .f128 = lhs.toFloat(f128, pt) * rhs.toFloat(f128, pt) }, |
| 3010 | else => unreachable, | 3055 | else => unreachable, |
| 3011 | }; | 3056 | }; |
| 3012 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3057 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3013 | .ty = float_type.toIntern(), | 3058 | .ty = float_type.toIntern(), |
| 3014 | .storage = storage, | 3059 | .storage = storage, |
| 3015 | } }))); | 3060 | } })); |
| 3016 | } | 3061 | } |
| 3017 | 3062 | ||
| 3018 | pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3063 | pub fn sqrt(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3019 | if (float_type.zigTypeTag(mod) == .Vector) { | 3064 | if (float_type.zigTypeTag(pt.zcu) == .Vector) { |
| 3020 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3065 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(pt.zcu)); |
| 3021 | const scalar_ty = float_type.scalarType(mod); | 3066 | const scalar_ty = float_type.scalarType(pt.zcu); |
| 3022 | for (result_data, 0..) |*scalar, i| { | 3067 | for (result_data, 0..) |*scalar, i| { |
| 3023 | const elem_val = try val.elemValue(mod, i); | 3068 | const elem_val = try val.elemValue(pt, i); |
| 3024 | scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern(); | 3069 | scalar.* = (try sqrtScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3025 | } | 3070 | } |
| 3026 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3071 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3027 | .ty = float_type.toIntern(), | 3072 | .ty = float_type.toIntern(), |
| 3028 | .storage = .{ .elems = result_data }, | 3073 | .storage = .{ .elems = result_data }, |
| 3029 | } }))); | 3074 | } })); |
| 3030 | } | 3075 | } |
| 3031 | return sqrtScalar(val, float_type, mod); | 3076 | return sqrtScalar(val, float_type, pt); |
| 3032 | } | 3077 | } |
| 3033 | 3078 | ||
| 3034 | pub fn sqrtScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3079 | pub fn sqrtScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3080 | const mod = pt.zcu; | ||
| 3035 | const target = mod.getTarget(); | 3081 | const target = mod.getTarget(); |
| 3036 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3082 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3037 | 16 => .{ .f16 = @sqrt(val.toFloat(f16, mod)) }, | 3083 | 16 => .{ .f16 = @sqrt(val.toFloat(f16, pt)) }, |
| 3038 | 32 => .{ .f32 = @sqrt(val.toFloat(f32, mod)) }, | 3084 | 32 => .{ .f32 = @sqrt(val.toFloat(f32, pt)) }, |
| 3039 | 64 => .{ .f64 = @sqrt(val.toFloat(f64, mod)) }, | 3085 | 64 => .{ .f64 = @sqrt(val.toFloat(f64, pt)) }, |
| 3040 | 80 => .{ .f80 = @sqrt(val.toFloat(f80, mod)) }, | 3086 | 80 => .{ .f80 = @sqrt(val.toFloat(f80, pt)) }, |
| 3041 | 128 => .{ .f128 = @sqrt(val.toFloat(f128, mod)) }, | 3087 | 128 => .{ .f128 = @sqrt(val.toFloat(f128, pt)) }, |
| 3042 | else => unreachable, | 3088 | else => unreachable, |
| 3043 | }; | 3089 | }; |
| 3044 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3090 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3045 | .ty = float_type.toIntern(), | 3091 | .ty = float_type.toIntern(), |
| 3046 | .storage = storage, | 3092 | .storage = storage, |
| 3047 | } }))); | 3093 | } })); |
| 3048 | } | 3094 | } |
| 3049 | 3095 | ||
| 3050 | pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3096 | pub fn sin(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3097 | const mod = pt.zcu; | ||
| 3051 | if (float_type.zigTypeTag(mod) == .Vector) { | 3098 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3052 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3099 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3053 | const scalar_ty = float_type.scalarType(mod); | 3100 | const scalar_ty = float_type.scalarType(mod); |
| 3054 | for (result_data, 0..) |*scalar, i| { | 3101 | for (result_data, 0..) |*scalar, i| { |
| 3055 | const elem_val = try val.elemValue(mod, i); | 3102 | const elem_val = try val.elemValue(pt, i); |
| 3056 | scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern(); | 3103 | scalar.* = (try sinScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3057 | } | 3104 | } |
| 3058 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3105 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3059 | .ty = float_type.toIntern(), | 3106 | .ty = float_type.toIntern(), |
| 3060 | .storage = .{ .elems = result_data }, | 3107 | .storage = .{ .elems = result_data }, |
| 3061 | } }))); | 3108 | } })); |
| 3062 | } | 3109 | } |
| 3063 | return sinScalar(val, float_type, mod); | 3110 | return sinScalar(val, float_type, pt); |
| 3064 | } | 3111 | } |
| 3065 | 3112 | ||
| 3066 | pub fn sinScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3113 | pub fn sinScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3114 | const mod = pt.zcu; | ||
| 3067 | const target = mod.getTarget(); | 3115 | const target = mod.getTarget(); |
| 3068 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3116 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3069 | 16 => .{ .f16 = @sin(val.toFloat(f16, mod)) }, | 3117 | 16 => .{ .f16 = @sin(val.toFloat(f16, pt)) }, |
| 3070 | 32 => .{ .f32 = @sin(val.toFloat(f32, mod)) }, | 3118 | 32 => .{ .f32 = @sin(val.toFloat(f32, pt)) }, |
| 3071 | 64 => .{ .f64 = @sin(val.toFloat(f64, mod)) }, | 3119 | 64 => .{ .f64 = @sin(val.toFloat(f64, pt)) }, |
| 3072 | 80 => .{ .f80 = @sin(val.toFloat(f80, mod)) }, | 3120 | 80 => .{ .f80 = @sin(val.toFloat(f80, pt)) }, |
| 3073 | 128 => .{ .f128 = @sin(val.toFloat(f128, mod)) }, | 3121 | 128 => .{ .f128 = @sin(val.toFloat(f128, pt)) }, |
| 3074 | else => unreachable, | 3122 | else => unreachable, |
| 3075 | }; | 3123 | }; |
| 3076 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3124 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3077 | .ty = float_type.toIntern(), | 3125 | .ty = float_type.toIntern(), |
| 3078 | .storage = storage, | 3126 | .storage = storage, |
| 3079 | } }))); | 3127 | } })); |
| 3080 | } | 3128 | } |
| 3081 | 3129 | ||
| 3082 | pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3130 | pub fn cos(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3131 | const mod = pt.zcu; | ||
| 3083 | if (float_type.zigTypeTag(mod) == .Vector) { | 3132 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3084 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3133 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3085 | const scalar_ty = float_type.scalarType(mod); | 3134 | const scalar_ty = float_type.scalarType(mod); |
| 3086 | for (result_data, 0..) |*scalar, i| { | 3135 | for (result_data, 0..) |*scalar, i| { |
| 3087 | const elem_val = try val.elemValue(mod, i); | 3136 | const elem_val = try val.elemValue(pt, i); |
| 3088 | scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern(); | 3137 | scalar.* = (try cosScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3089 | } | 3138 | } |
| 3090 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3139 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3091 | .ty = float_type.toIntern(), | 3140 | .ty = float_type.toIntern(), |
| 3092 | .storage = .{ .elems = result_data }, | 3141 | .storage = .{ .elems = result_data }, |
| 3093 | } }))); | 3142 | } })); |
| 3094 | } | 3143 | } |
| 3095 | return cosScalar(val, float_type, mod); | 3144 | return cosScalar(val, float_type, pt); |
| 3096 | } | 3145 | } |
| 3097 | 3146 | ||
| 3098 | pub fn cosScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3147 | pub fn cosScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3148 | const mod = pt.zcu; | ||
| 3099 | const target = mod.getTarget(); | 3149 | const target = mod.getTarget(); |
| 3100 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3150 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3101 | 16 => .{ .f16 = @cos(val.toFloat(f16, mod)) }, | 3151 | 16 => .{ .f16 = @cos(val.toFloat(f16, pt)) }, |
| 3102 | 32 => .{ .f32 = @cos(val.toFloat(f32, mod)) }, | 3152 | 32 => .{ .f32 = @cos(val.toFloat(f32, pt)) }, |
| 3103 | 64 => .{ .f64 = @cos(val.toFloat(f64, mod)) }, | 3153 | 64 => .{ .f64 = @cos(val.toFloat(f64, pt)) }, |
| 3104 | 80 => .{ .f80 = @cos(val.toFloat(f80, mod)) }, | 3154 | 80 => .{ .f80 = @cos(val.toFloat(f80, pt)) }, |
| 3105 | 128 => .{ .f128 = @cos(val.toFloat(f128, mod)) }, | 3155 | 128 => .{ .f128 = @cos(val.toFloat(f128, pt)) }, |
| 3106 | else => unreachable, | 3156 | else => unreachable, |
| 3107 | }; | 3157 | }; |
| 3108 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3158 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3109 | .ty = float_type.toIntern(), | 3159 | .ty = float_type.toIntern(), |
| 3110 | .storage = storage, | 3160 | .storage = storage, |
| 3111 | } }))); | 3161 | } })); |
| 3112 | } | 3162 | } |
| 3113 | 3163 | ||
| 3114 | pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3164 | pub fn tan(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3165 | const mod = pt.zcu; | ||
| 3115 | if (float_type.zigTypeTag(mod) == .Vector) { | 3166 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3116 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3167 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3117 | const scalar_ty = float_type.scalarType(mod); | 3168 | const scalar_ty = float_type.scalarType(mod); |
| 3118 | for (result_data, 0..) |*scalar, i| { | 3169 | for (result_data, 0..) |*scalar, i| { |
| 3119 | const elem_val = try val.elemValue(mod, i); | 3170 | const elem_val = try val.elemValue(pt, i); |
| 3120 | scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern(); | 3171 | scalar.* = (try tanScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3121 | } | 3172 | } |
| 3122 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3173 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3123 | .ty = float_type.toIntern(), | 3174 | .ty = float_type.toIntern(), |
| 3124 | .storage = .{ .elems = result_data }, | 3175 | .storage = .{ .elems = result_data }, |
| 3125 | } }))); | 3176 | } })); |
| 3126 | } | 3177 | } |
| 3127 | return tanScalar(val, float_type, mod); | 3178 | return tanScalar(val, float_type, pt); |
| 3128 | } | 3179 | } |
| 3129 | 3180 | ||
| 3130 | pub fn tanScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3181 | pub fn tanScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3182 | const mod = pt.zcu; | ||
| 3131 | const target = mod.getTarget(); | 3183 | const target = mod.getTarget(); |
| 3132 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3184 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3133 | 16 => .{ .f16 = @tan(val.toFloat(f16, mod)) }, | 3185 | 16 => .{ .f16 = @tan(val.toFloat(f16, pt)) }, |
| 3134 | 32 => .{ .f32 = @tan(val.toFloat(f32, mod)) }, | 3186 | 32 => .{ .f32 = @tan(val.toFloat(f32, pt)) }, |
| 3135 | 64 => .{ .f64 = @tan(val.toFloat(f64, mod)) }, | 3187 | 64 => .{ .f64 = @tan(val.toFloat(f64, pt)) }, |
| 3136 | 80 => .{ .f80 = @tan(val.toFloat(f80, mod)) }, | 3188 | 80 => .{ .f80 = @tan(val.toFloat(f80, pt)) }, |
| 3137 | 128 => .{ .f128 = @tan(val.toFloat(f128, mod)) }, | 3189 | 128 => .{ .f128 = @tan(val.toFloat(f128, pt)) }, |
| 3138 | else => unreachable, | 3190 | else => unreachable, |
| 3139 | }; | 3191 | }; |
| 3140 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3192 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3141 | .ty = float_type.toIntern(), | 3193 | .ty = float_type.toIntern(), |
| 3142 | .storage = storage, | 3194 | .storage = storage, |
| 3143 | } }))); | 3195 | } })); |
| 3144 | } | 3196 | } |
| 3145 | 3197 | ||
| 3146 | pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3198 | pub fn exp(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3199 | const mod = pt.zcu; | ||
| 3147 | if (float_type.zigTypeTag(mod) == .Vector) { | 3200 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3148 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3201 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3149 | const scalar_ty = float_type.scalarType(mod); | 3202 | const scalar_ty = float_type.scalarType(mod); |
| 3150 | for (result_data, 0..) |*scalar, i| { | 3203 | for (result_data, 0..) |*scalar, i| { |
| 3151 | const elem_val = try val.elemValue(mod, i); | 3204 | const elem_val = try val.elemValue(pt, i); |
| 3152 | scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern(); | 3205 | scalar.* = (try expScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3153 | } | 3206 | } |
| 3154 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3207 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3155 | .ty = float_type.toIntern(), | 3208 | .ty = float_type.toIntern(), |
| 3156 | .storage = .{ .elems = result_data }, | 3209 | .storage = .{ .elems = result_data }, |
| 3157 | } }))); | 3210 | } })); |
| 3158 | } | 3211 | } |
| 3159 | return expScalar(val, float_type, mod); | 3212 | return expScalar(val, float_type, pt); |
| 3160 | } | 3213 | } |
| 3161 | 3214 | ||
| 3162 | pub fn expScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3215 | pub fn expScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3216 | const mod = pt.zcu; | ||
| 3163 | const target = mod.getTarget(); | 3217 | const target = mod.getTarget(); |
| 3164 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3218 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3165 | 16 => .{ .f16 = @exp(val.toFloat(f16, mod)) }, | 3219 | 16 => .{ .f16 = @exp(val.toFloat(f16, pt)) }, |
| 3166 | 32 => .{ .f32 = @exp(val.toFloat(f32, mod)) }, | 3220 | 32 => .{ .f32 = @exp(val.toFloat(f32, pt)) }, |
| 3167 | 64 => .{ .f64 = @exp(val.toFloat(f64, mod)) }, | 3221 | 64 => .{ .f64 = @exp(val.toFloat(f64, pt)) }, |
| 3168 | 80 => .{ .f80 = @exp(val.toFloat(f80, mod)) }, | 3222 | 80 => .{ .f80 = @exp(val.toFloat(f80, pt)) }, |
| 3169 | 128 => .{ .f128 = @exp(val.toFloat(f128, mod)) }, | 3223 | 128 => .{ .f128 = @exp(val.toFloat(f128, pt)) }, |
| 3170 | else => unreachable, | 3224 | else => unreachable, |
| 3171 | }; | 3225 | }; |
| 3172 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3226 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3173 | .ty = float_type.toIntern(), | 3227 | .ty = float_type.toIntern(), |
| 3174 | .storage = storage, | 3228 | .storage = storage, |
| 3175 | } }))); | 3229 | } })); |
| 3176 | } | 3230 | } |
| 3177 | 3231 | ||
| 3178 | pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3232 | pub fn exp2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3233 | const mod = pt.zcu; | ||
| 3179 | if (float_type.zigTypeTag(mod) == .Vector) { | 3234 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3180 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3235 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3181 | const scalar_ty = float_type.scalarType(mod); | 3236 | const scalar_ty = float_type.scalarType(mod); |
| 3182 | for (result_data, 0..) |*scalar, i| { | 3237 | for (result_data, 0..) |*scalar, i| { |
| 3183 | const elem_val = try val.elemValue(mod, i); | 3238 | const elem_val = try val.elemValue(pt, i); |
| 3184 | scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern(); | 3239 | scalar.* = (try exp2Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3185 | } | 3240 | } |
| 3186 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3241 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3187 | .ty = float_type.toIntern(), | 3242 | .ty = float_type.toIntern(), |
| 3188 | .storage = .{ .elems = result_data }, | 3243 | .storage = .{ .elems = result_data }, |
| 3189 | } }))); | 3244 | } })); |
| 3190 | } | 3245 | } |
| 3191 | return exp2Scalar(val, float_type, mod); | 3246 | return exp2Scalar(val, float_type, pt); |
| 3192 | } | 3247 | } |
| 3193 | 3248 | ||
| 3194 | pub fn exp2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3249 | pub fn exp2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3250 | const mod = pt.zcu; | ||
| 3195 | const target = mod.getTarget(); | 3251 | const target = mod.getTarget(); |
| 3196 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3252 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3197 | 16 => .{ .f16 = @exp2(val.toFloat(f16, mod)) }, | 3253 | 16 => .{ .f16 = @exp2(val.toFloat(f16, pt)) }, |
| 3198 | 32 => .{ .f32 = @exp2(val.toFloat(f32, mod)) }, | 3254 | 32 => .{ .f32 = @exp2(val.toFloat(f32, pt)) }, |
| 3199 | 64 => .{ .f64 = @exp2(val.toFloat(f64, mod)) }, | 3255 | 64 => .{ .f64 = @exp2(val.toFloat(f64, pt)) }, |
| 3200 | 80 => .{ .f80 = @exp2(val.toFloat(f80, mod)) }, | 3256 | 80 => .{ .f80 = @exp2(val.toFloat(f80, pt)) }, |
| 3201 | 128 => .{ .f128 = @exp2(val.toFloat(f128, mod)) }, | 3257 | 128 => .{ .f128 = @exp2(val.toFloat(f128, pt)) }, |
| 3202 | else => unreachable, | 3258 | else => unreachable, |
| 3203 | }; | 3259 | }; |
| 3204 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3260 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3205 | .ty = float_type.toIntern(), | 3261 | .ty = float_type.toIntern(), |
| 3206 | .storage = storage, | 3262 | .storage = storage, |
| 3207 | } }))); | 3263 | } })); |
| 3208 | } | 3264 | } |
| 3209 | 3265 | ||
| 3210 | pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3266 | pub fn log(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3267 | const mod = pt.zcu; | ||
| 3211 | if (float_type.zigTypeTag(mod) == .Vector) { | 3268 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3212 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3269 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3213 | const scalar_ty = float_type.scalarType(mod); | 3270 | const scalar_ty = float_type.scalarType(mod); |
| 3214 | for (result_data, 0..) |*scalar, i| { | 3271 | for (result_data, 0..) |*scalar, i| { |
| 3215 | const elem_val = try val.elemValue(mod, i); | 3272 | const elem_val = try val.elemValue(pt, i); |
| 3216 | scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern(); | 3273 | scalar.* = (try logScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3217 | } | 3274 | } |
| 3218 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3275 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3219 | .ty = float_type.toIntern(), | 3276 | .ty = float_type.toIntern(), |
| 3220 | .storage = .{ .elems = result_data }, | 3277 | .storage = .{ .elems = result_data }, |
| 3221 | } }))); | 3278 | } })); |
| 3222 | } | 3279 | } |
| 3223 | return logScalar(val, float_type, mod); | 3280 | return logScalar(val, float_type, pt); |
| 3224 | } | 3281 | } |
| 3225 | 3282 | ||
| 3226 | pub fn logScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3283 | pub fn logScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3284 | const mod = pt.zcu; | ||
| 3227 | const target = mod.getTarget(); | 3285 | const target = mod.getTarget(); |
| 3228 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3286 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3229 | 16 => .{ .f16 = @log(val.toFloat(f16, mod)) }, | 3287 | 16 => .{ .f16 = @log(val.toFloat(f16, pt)) }, |
| 3230 | 32 => .{ .f32 = @log(val.toFloat(f32, mod)) }, | 3288 | 32 => .{ .f32 = @log(val.toFloat(f32, pt)) }, |
| 3231 | 64 => .{ .f64 = @log(val.toFloat(f64, mod)) }, | 3289 | 64 => .{ .f64 = @log(val.toFloat(f64, pt)) }, |
| 3232 | 80 => .{ .f80 = @log(val.toFloat(f80, mod)) }, | 3290 | 80 => .{ .f80 = @log(val.toFloat(f80, pt)) }, |
| 3233 | 128 => .{ .f128 = @log(val.toFloat(f128, mod)) }, | 3291 | 128 => .{ .f128 = @log(val.toFloat(f128, pt)) }, |
| 3234 | else => unreachable, | 3292 | else => unreachable, |
| 3235 | }; | 3293 | }; |
| 3236 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3294 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3237 | .ty = float_type.toIntern(), | 3295 | .ty = float_type.toIntern(), |
| 3238 | .storage = storage, | 3296 | .storage = storage, |
| 3239 | } }))); | 3297 | } })); |
| 3240 | } | 3298 | } |
| 3241 | 3299 | ||
| 3242 | pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3300 | pub fn log2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3301 | const mod = pt.zcu; | ||
| 3243 | if (float_type.zigTypeTag(mod) == .Vector) { | 3302 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3244 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3303 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3245 | const scalar_ty = float_type.scalarType(mod); | 3304 | const scalar_ty = float_type.scalarType(mod); |
| 3246 | for (result_data, 0..) |*scalar, i| { | 3305 | for (result_data, 0..) |*scalar, i| { |
| 3247 | const elem_val = try val.elemValue(mod, i); | 3306 | const elem_val = try val.elemValue(pt, i); |
| 3248 | scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern(); | 3307 | scalar.* = (try log2Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3249 | } | 3308 | } |
| 3250 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3309 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3251 | .ty = float_type.toIntern(), | 3310 | .ty = float_type.toIntern(), |
| 3252 | .storage = .{ .elems = result_data }, | 3311 | .storage = .{ .elems = result_data }, |
| 3253 | } }))); | 3312 | } })); |
| 3254 | } | 3313 | } |
| 3255 | return log2Scalar(val, float_type, mod); | 3314 | return log2Scalar(val, float_type, pt); |
| 3256 | } | 3315 | } |
| 3257 | 3316 | ||
| 3258 | pub fn log2Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3317 | pub fn log2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3318 | const mod = pt.zcu; | ||
| 3259 | const target = mod.getTarget(); | 3319 | const target = mod.getTarget(); |
| 3260 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3320 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3261 | 16 => .{ .f16 = @log2(val.toFloat(f16, mod)) }, | 3321 | 16 => .{ .f16 = @log2(val.toFloat(f16, pt)) }, |
| 3262 | 32 => .{ .f32 = @log2(val.toFloat(f32, mod)) }, | 3322 | 32 => .{ .f32 = @log2(val.toFloat(f32, pt)) }, |
| 3263 | 64 => .{ .f64 = @log2(val.toFloat(f64, mod)) }, | 3323 | 64 => .{ .f64 = @log2(val.toFloat(f64, pt)) }, |
| 3264 | 80 => .{ .f80 = @log2(val.toFloat(f80, mod)) }, | 3324 | 80 => .{ .f80 = @log2(val.toFloat(f80, pt)) }, |
| 3265 | 128 => .{ .f128 = @log2(val.toFloat(f128, mod)) }, | 3325 | 128 => .{ .f128 = @log2(val.toFloat(f128, pt)) }, |
| 3266 | else => unreachable, | 3326 | else => unreachable, |
| 3267 | }; | 3327 | }; |
| 3268 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3328 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3269 | .ty = float_type.toIntern(), | 3329 | .ty = float_type.toIntern(), |
| 3270 | .storage = storage, | 3330 | .storage = storage, |
| 3271 | } }))); | 3331 | } })); |
| 3272 | } | 3332 | } |
| 3273 | 3333 | ||
| 3274 | pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3334 | pub fn log10(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3335 | const mod = pt.zcu; | ||
| 3275 | if (float_type.zigTypeTag(mod) == .Vector) { | 3336 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3276 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3337 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3277 | const scalar_ty = float_type.scalarType(mod); | 3338 | const scalar_ty = float_type.scalarType(mod); |
| 3278 | for (result_data, 0..) |*scalar, i| { | 3339 | for (result_data, 0..) |*scalar, i| { |
| 3279 | const elem_val = try val.elemValue(mod, i); | 3340 | const elem_val = try val.elemValue(pt, i); |
| 3280 | scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern(); | 3341 | scalar.* = (try log10Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3281 | } | 3342 | } |
| 3282 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3343 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3283 | .ty = float_type.toIntern(), | 3344 | .ty = float_type.toIntern(), |
| 3284 | .storage = .{ .elems = result_data }, | 3345 | .storage = .{ .elems = result_data }, |
| 3285 | } }))); | 3346 | } })); |
| 3286 | } | 3347 | } |
| 3287 | return log10Scalar(val, float_type, mod); | 3348 | return log10Scalar(val, float_type, pt); |
| 3288 | } | 3349 | } |
| 3289 | 3350 | ||
| 3290 | pub fn log10Scalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3351 | pub fn log10Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3352 | const mod = pt.zcu; | ||
| 3291 | const target = mod.getTarget(); | 3353 | const target = mod.getTarget(); |
| 3292 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3354 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3293 | 16 => .{ .f16 = @log10(val.toFloat(f16, mod)) }, | 3355 | 16 => .{ .f16 = @log10(val.toFloat(f16, pt)) }, |
| 3294 | 32 => .{ .f32 = @log10(val.toFloat(f32, mod)) }, | 3356 | 32 => .{ .f32 = @log10(val.toFloat(f32, pt)) }, |
| 3295 | 64 => .{ .f64 = @log10(val.toFloat(f64, mod)) }, | 3357 | 64 => .{ .f64 = @log10(val.toFloat(f64, pt)) }, |
| 3296 | 80 => .{ .f80 = @log10(val.toFloat(f80, mod)) }, | 3358 | 80 => .{ .f80 = @log10(val.toFloat(f80, pt)) }, |
| 3297 | 128 => .{ .f128 = @log10(val.toFloat(f128, mod)) }, | 3359 | 128 => .{ .f128 = @log10(val.toFloat(f128, pt)) }, |
| 3298 | else => unreachable, | 3360 | else => unreachable, |
| 3299 | }; | 3361 | }; |
| 3300 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3362 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3301 | .ty = float_type.toIntern(), | 3363 | .ty = float_type.toIntern(), |
| 3302 | .storage = storage, | 3364 | .storage = storage, |
| 3303 | } }))); | 3365 | } })); |
| 3304 | } | 3366 | } |
| 3305 | 3367 | ||
| 3306 | pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | 3368 | pub fn abs(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3369 | const mod = pt.zcu; | ||
| 3307 | if (ty.zigTypeTag(mod) == .Vector) { | 3370 | if (ty.zigTypeTag(mod) == .Vector) { |
| 3308 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | 3371 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); |
| 3309 | const scalar_ty = ty.scalarType(mod); | 3372 | const scalar_ty = ty.scalarType(mod); |
| 3310 | for (result_data, 0..) |*scalar, i| { | 3373 | for (result_data, 0..) |*scalar, i| { |
| 3311 | const elem_val = try val.elemValue(mod, i); | 3374 | const elem_val = try val.elemValue(pt, i); |
| 3312 | scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern(); | 3375 | scalar.* = (try absScalar(elem_val, scalar_ty, pt, arena)).toIntern(); |
| 3313 | } | 3376 | } |
| 3314 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3377 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3315 | .ty = ty.toIntern(), | 3378 | .ty = ty.toIntern(), |
| 3316 | .storage = .{ .elems = result_data }, | 3379 | .storage = .{ .elems = result_data }, |
| 3317 | } }))); | 3380 | } })); |
| 3318 | } | 3381 | } |
| 3319 | return absScalar(val, ty, mod, arena); | 3382 | return absScalar(val, ty, pt, arena); |
| 3320 | } | 3383 | } |
| 3321 | 3384 | ||
| 3322 | pub fn absScalar(val: Value, ty: Type, mod: *Module, arena: Allocator) Allocator.Error!Value { | 3385 | pub fn absScalar(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value { |
| 3386 | const mod = pt.zcu; | ||
| 3323 | switch (ty.zigTypeTag(mod)) { | 3387 | switch (ty.zigTypeTag(mod)) { |
| 3324 | .Int => { | 3388 | .Int => { |
| 3325 | var buffer: Value.BigIntSpace = undefined; | 3389 | var buffer: Value.BigIntSpace = undefined; |
| 3326 | var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena); | 3390 | var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena); |
| 3327 | operand_bigint.abs(); | 3391 | operand_bigint.abs(); |
| 3328 | 3392 | ||
| 3329 | return mod.intValue_big(try ty.toUnsigned(mod), operand_bigint.toConst()); | 3393 | return pt.intValue_big(try ty.toUnsigned(pt), operand_bigint.toConst()); |
| 3330 | }, | 3394 | }, |
| 3331 | .ComptimeInt => { | 3395 | .ComptimeInt => { |
| 3332 | var buffer: Value.BigIntSpace = undefined; | 3396 | var buffer: Value.BigIntSpace = undefined; |
| 3333 | var operand_bigint = try val.toBigInt(&buffer, mod).toManaged(arena); | 3397 | var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena); |
| 3334 | operand_bigint.abs(); | 3398 | operand_bigint.abs(); |
| 3335 | 3399 | ||
| 3336 | return mod.intValue_big(ty, operand_bigint.toConst()); | 3400 | return pt.intValue_big(ty, operand_bigint.toConst()); |
| 3337 | }, | 3401 | }, |
| 3338 | .ComptimeFloat, .Float => { | 3402 | .ComptimeFloat, .Float => { |
| 3339 | const target = mod.getTarget(); | 3403 | const target = mod.getTarget(); |
| 3340 | const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) { | 3404 | const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) { |
| 3341 | 16 => .{ .f16 = @abs(val.toFloat(f16, mod)) }, | 3405 | 16 => .{ .f16 = @abs(val.toFloat(f16, pt)) }, |
| 3342 | 32 => .{ .f32 = @abs(val.toFloat(f32, mod)) }, | 3406 | 32 => .{ .f32 = @abs(val.toFloat(f32, pt)) }, |
| 3343 | 64 => .{ .f64 = @abs(val.toFloat(f64, mod)) }, | 3407 | 64 => .{ .f64 = @abs(val.toFloat(f64, pt)) }, |
| 3344 | 80 => .{ .f80 = @abs(val.toFloat(f80, mod)) }, | 3408 | 80 => .{ .f80 = @abs(val.toFloat(f80, pt)) }, |
| 3345 | 128 => .{ .f128 = @abs(val.toFloat(f128, mod)) }, | 3409 | 128 => .{ .f128 = @abs(val.toFloat(f128, pt)) }, |
| 3346 | else => unreachable, | 3410 | else => unreachable, |
| 3347 | }; | 3411 | }; |
| 3348 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3412 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3349 | .ty = ty.toIntern(), | 3413 | .ty = ty.toIntern(), |
| 3350 | .storage = storage, | 3414 | .storage = storage, |
| 3351 | } }))); | 3415 | } })); |
| 3352 | }, | 3416 | }, |
| 3353 | else => unreachable, | 3417 | else => unreachable, |
| 3354 | } | 3418 | } |
| 3355 | } | 3419 | } |
| 3356 | 3420 | ||
| 3357 | pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3421 | pub fn floor(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3422 | const mod = pt.zcu; | ||
| 3358 | if (float_type.zigTypeTag(mod) == .Vector) { | 3423 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3359 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3424 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3360 | const scalar_ty = float_type.scalarType(mod); | 3425 | const scalar_ty = float_type.scalarType(mod); |
| 3361 | for (result_data, 0..) |*scalar, i| { | 3426 | for (result_data, 0..) |*scalar, i| { |
| 3362 | const elem_val = try val.elemValue(mod, i); | 3427 | const elem_val = try val.elemValue(pt, i); |
| 3363 | scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern(); | 3428 | scalar.* = (try floorScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3364 | } | 3429 | } |
| 3365 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3430 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3366 | .ty = float_type.toIntern(), | 3431 | .ty = float_type.toIntern(), |
| 3367 | .storage = .{ .elems = result_data }, | 3432 | .storage = .{ .elems = result_data }, |
| 3368 | } }))); | 3433 | } })); |
| 3369 | } | 3434 | } |
| 3370 | return floorScalar(val, float_type, mod); | 3435 | return floorScalar(val, float_type, pt); |
| 3371 | } | 3436 | } |
| 3372 | 3437 | ||
| 3373 | pub fn floorScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3438 | pub fn floorScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3439 | const mod = pt.zcu; | ||
| 3374 | const target = mod.getTarget(); | 3440 | const target = mod.getTarget(); |
| 3375 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3441 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3376 | 16 => .{ .f16 = @floor(val.toFloat(f16, mod)) }, | 3442 | 16 => .{ .f16 = @floor(val.toFloat(f16, pt)) }, |
| 3377 | 32 => .{ .f32 = @floor(val.toFloat(f32, mod)) }, | 3443 | 32 => .{ .f32 = @floor(val.toFloat(f32, pt)) }, |
| 3378 | 64 => .{ .f64 = @floor(val.toFloat(f64, mod)) }, | 3444 | 64 => .{ .f64 = @floor(val.toFloat(f64, pt)) }, |
| 3379 | 80 => .{ .f80 = @floor(val.toFloat(f80, mod)) }, | 3445 | 80 => .{ .f80 = @floor(val.toFloat(f80, pt)) }, |
| 3380 | 128 => .{ .f128 = @floor(val.toFloat(f128, mod)) }, | 3446 | 128 => .{ .f128 = @floor(val.toFloat(f128, pt)) }, |
| 3381 | else => unreachable, | 3447 | else => unreachable, |
| 3382 | }; | 3448 | }; |
| 3383 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3449 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3384 | .ty = float_type.toIntern(), | 3450 | .ty = float_type.toIntern(), |
| 3385 | .storage = storage, | 3451 | .storage = storage, |
| 3386 | } }))); | 3452 | } })); |
| 3387 | } | 3453 | } |
| 3388 | 3454 | ||
| 3389 | pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3455 | pub fn ceil(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3456 | const mod = pt.zcu; | ||
| 3390 | if (float_type.zigTypeTag(mod) == .Vector) { | 3457 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3391 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3458 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3392 | const scalar_ty = float_type.scalarType(mod); | 3459 | const scalar_ty = float_type.scalarType(mod); |
| 3393 | for (result_data, 0..) |*scalar, i| { | 3460 | for (result_data, 0..) |*scalar, i| { |
| 3394 | const elem_val = try val.elemValue(mod, i); | 3461 | const elem_val = try val.elemValue(pt, i); |
| 3395 | scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern(); | 3462 | scalar.* = (try ceilScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3396 | } | 3463 | } |
| 3397 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3464 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3398 | .ty = float_type.toIntern(), | 3465 | .ty = float_type.toIntern(), |
| 3399 | .storage = .{ .elems = result_data }, | 3466 | .storage = .{ .elems = result_data }, |
| 3400 | } }))); | 3467 | } })); |
| 3401 | } | 3468 | } |
| 3402 | return ceilScalar(val, float_type, mod); | 3469 | return ceilScalar(val, float_type, pt); |
| 3403 | } | 3470 | } |
| 3404 | 3471 | ||
| 3405 | pub fn ceilScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3472 | pub fn ceilScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3473 | const mod = pt.zcu; | ||
| 3406 | const target = mod.getTarget(); | 3474 | const target = mod.getTarget(); |
| 3407 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3475 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3408 | 16 => .{ .f16 = @ceil(val.toFloat(f16, mod)) }, | 3476 | 16 => .{ .f16 = @ceil(val.toFloat(f16, pt)) }, |
| 3409 | 32 => .{ .f32 = @ceil(val.toFloat(f32, mod)) }, | 3477 | 32 => .{ .f32 = @ceil(val.toFloat(f32, pt)) }, |
| 3410 | 64 => .{ .f64 = @ceil(val.toFloat(f64, mod)) }, | 3478 | 64 => .{ .f64 = @ceil(val.toFloat(f64, pt)) }, |
| 3411 | 80 => .{ .f80 = @ceil(val.toFloat(f80, mod)) }, | 3479 | 80 => .{ .f80 = @ceil(val.toFloat(f80, pt)) }, |
| 3412 | 128 => .{ .f128 = @ceil(val.toFloat(f128, mod)) }, | 3480 | 128 => .{ .f128 = @ceil(val.toFloat(f128, pt)) }, |
| 3413 | else => unreachable, | 3481 | else => unreachable, |
| 3414 | }; | 3482 | }; |
| 3415 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3483 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3416 | .ty = float_type.toIntern(), | 3484 | .ty = float_type.toIntern(), |
| 3417 | .storage = storage, | 3485 | .storage = storage, |
| 3418 | } }))); | 3486 | } })); |
| 3419 | } | 3487 | } |
| 3420 | 3488 | ||
| 3421 | pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3489 | pub fn round(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3490 | const mod = pt.zcu; | ||
| 3422 | if (float_type.zigTypeTag(mod) == .Vector) { | 3491 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3423 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3492 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3424 | const scalar_ty = float_type.scalarType(mod); | 3493 | const scalar_ty = float_type.scalarType(mod); |
| 3425 | for (result_data, 0..) |*scalar, i| { | 3494 | for (result_data, 0..) |*scalar, i| { |
| 3426 | const elem_val = try val.elemValue(mod, i); | 3495 | const elem_val = try val.elemValue(pt, i); |
| 3427 | scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern(); | 3496 | scalar.* = (try roundScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3428 | } | 3497 | } |
| 3429 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3498 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3430 | .ty = float_type.toIntern(), | 3499 | .ty = float_type.toIntern(), |
| 3431 | .storage = .{ .elems = result_data }, | 3500 | .storage = .{ .elems = result_data }, |
| 3432 | } }))); | 3501 | } })); |
| 3433 | } | 3502 | } |
| 3434 | return roundScalar(val, float_type, mod); | 3503 | return roundScalar(val, float_type, pt); |
| 3435 | } | 3504 | } |
| 3436 | 3505 | ||
| 3437 | pub fn roundScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3506 | pub fn roundScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3507 | const mod = pt.zcu; | ||
| 3438 | const target = mod.getTarget(); | 3508 | const target = mod.getTarget(); |
| 3439 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3509 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3440 | 16 => .{ .f16 = @round(val.toFloat(f16, mod)) }, | 3510 | 16 => .{ .f16 = @round(val.toFloat(f16, pt)) }, |
| 3441 | 32 => .{ .f32 = @round(val.toFloat(f32, mod)) }, | 3511 | 32 => .{ .f32 = @round(val.toFloat(f32, pt)) }, |
| 3442 | 64 => .{ .f64 = @round(val.toFloat(f64, mod)) }, | 3512 | 64 => .{ .f64 = @round(val.toFloat(f64, pt)) }, |
| 3443 | 80 => .{ .f80 = @round(val.toFloat(f80, mod)) }, | 3513 | 80 => .{ .f80 = @round(val.toFloat(f80, pt)) }, |
| 3444 | 128 => .{ .f128 = @round(val.toFloat(f128, mod)) }, | 3514 | 128 => .{ .f128 = @round(val.toFloat(f128, pt)) }, |
| 3445 | else => unreachable, | 3515 | else => unreachable, |
| 3446 | }; | 3516 | }; |
| 3447 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3517 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3448 | .ty = float_type.toIntern(), | 3518 | .ty = float_type.toIntern(), |
| 3449 | .storage = storage, | 3519 | .storage = storage, |
| 3450 | } }))); | 3520 | } })); |
| 3451 | } | 3521 | } |
| 3452 | 3522 | ||
| 3453 | pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { | 3523 | pub fn trunc(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3524 | const mod = pt.zcu; | ||
| 3454 | if (float_type.zigTypeTag(mod) == .Vector) { | 3525 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3455 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3526 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3456 | const scalar_ty = float_type.scalarType(mod); | 3527 | const scalar_ty = float_type.scalarType(mod); |
| 3457 | for (result_data, 0..) |*scalar, i| { | 3528 | for (result_data, 0..) |*scalar, i| { |
| 3458 | const elem_val = try val.elemValue(mod, i); | 3529 | const elem_val = try val.elemValue(pt, i); |
| 3459 | scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern(); | 3530 | scalar.* = (try truncScalar(elem_val, scalar_ty, pt)).toIntern(); |
| 3460 | } | 3531 | } |
| 3461 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3532 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3462 | .ty = float_type.toIntern(), | 3533 | .ty = float_type.toIntern(), |
| 3463 | .storage = .{ .elems = result_data }, | 3534 | .storage = .{ .elems = result_data }, |
| 3464 | } }))); | 3535 | } })); |
| 3465 | } | 3536 | } |
| 3466 | return truncScalar(val, float_type, mod); | 3537 | return truncScalar(val, float_type, pt); |
| 3467 | } | 3538 | } |
| 3468 | 3539 | ||
| 3469 | pub fn truncScalar(val: Value, float_type: Type, mod: *Module) Allocator.Error!Value { | 3540 | pub fn truncScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3541 | const mod = pt.zcu; | ||
| 3470 | const target = mod.getTarget(); | 3542 | const target = mod.getTarget(); |
| 3471 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3543 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3472 | 16 => .{ .f16 = @trunc(val.toFloat(f16, mod)) }, | 3544 | 16 => .{ .f16 = @trunc(val.toFloat(f16, pt)) }, |
| 3473 | 32 => .{ .f32 = @trunc(val.toFloat(f32, mod)) }, | 3545 | 32 => .{ .f32 = @trunc(val.toFloat(f32, pt)) }, |
| 3474 | 64 => .{ .f64 = @trunc(val.toFloat(f64, mod)) }, | 3546 | 64 => .{ .f64 = @trunc(val.toFloat(f64, pt)) }, |
| 3475 | 80 => .{ .f80 = @trunc(val.toFloat(f80, mod)) }, | 3547 | 80 => .{ .f80 = @trunc(val.toFloat(f80, pt)) }, |
| 3476 | 128 => .{ .f128 = @trunc(val.toFloat(f128, mod)) }, | 3548 | 128 => .{ .f128 = @trunc(val.toFloat(f128, pt)) }, |
| 3477 | else => unreachable, | 3549 | else => unreachable, |
| 3478 | }; | 3550 | }; |
| 3479 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3551 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3480 | .ty = float_type.toIntern(), | 3552 | .ty = float_type.toIntern(), |
| 3481 | .storage = storage, | 3553 | .storage = storage, |
| 3482 | } }))); | 3554 | } })); |
| 3483 | } | 3555 | } |
| 3484 | 3556 | ||
| 3485 | pub fn mulAdd( | 3557 | pub fn mulAdd( |
| ... | @@ -3488,23 +3560,24 @@ pub fn mulAdd( | ... | @@ -3488,23 +3560,24 @@ pub fn mulAdd( |
| 3488 | mulend2: Value, | 3560 | mulend2: Value, |
| 3489 | addend: Value, | 3561 | addend: Value, |
| 3490 | arena: Allocator, | 3562 | arena: Allocator, |
| 3491 | mod: *Module, | 3563 | pt: Zcu.PerThread, |
| 3492 | ) !Value { | 3564 | ) !Value { |
| 3565 | const mod = pt.zcu; | ||
| 3493 | if (float_type.zigTypeTag(mod) == .Vector) { | 3566 | if (float_type.zigTypeTag(mod) == .Vector) { |
| 3494 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | 3567 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); |
| 3495 | const scalar_ty = float_type.scalarType(mod); | 3568 | const scalar_ty = float_type.scalarType(mod); |
| 3496 | for (result_data, 0..) |*scalar, i| { | 3569 | for (result_data, 0..) |*scalar, i| { |
| 3497 | const mulend1_elem = try mulend1.elemValue(mod, i); | 3570 | const mulend1_elem = try mulend1.elemValue(pt, i); |
| 3498 | const mulend2_elem = try mulend2.elemValue(mod, i); | 3571 | const mulend2_elem = try mulend2.elemValue(pt, i); |
| 3499 | const addend_elem = try addend.elemValue(mod, i); | 3572 | const addend_elem = try addend.elemValue(pt, i); |
| 3500 | scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern(); | 3573 | scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, pt)).toIntern(); |
| 3501 | } | 3574 | } |
| 3502 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3575 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 3503 | .ty = float_type.toIntern(), | 3576 | .ty = float_type.toIntern(), |
| 3504 | .storage = .{ .elems = result_data }, | 3577 | .storage = .{ .elems = result_data }, |
| 3505 | } }))); | 3578 | } })); |
| 3506 | } | 3579 | } |
| 3507 | return mulAddScalar(float_type, mulend1, mulend2, addend, mod); | 3580 | return mulAddScalar(float_type, mulend1, mulend2, addend, pt); |
| 3508 | } | 3581 | } |
| 3509 | 3582 | ||
| 3510 | pub fn mulAddScalar( | 3583 | pub fn mulAddScalar( |
| ... | @@ -3512,32 +3585,33 @@ pub fn mulAddScalar( | ... | @@ -3512,32 +3585,33 @@ pub fn mulAddScalar( |
| 3512 | mulend1: Value, | 3585 | mulend1: Value, |
| 3513 | mulend2: Value, | 3586 | mulend2: Value, |
| 3514 | addend: Value, | 3587 | addend: Value, |
| 3515 | mod: *Module, | 3588 | pt: Zcu.PerThread, |
| 3516 | ) Allocator.Error!Value { | 3589 | ) Allocator.Error!Value { |
| 3590 | const mod = pt.zcu; | ||
| 3517 | const target = mod.getTarget(); | 3591 | const target = mod.getTarget(); |
| 3518 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { | 3592 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3519 | 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, mod), mulend2.toFloat(f16, mod), addend.toFloat(f16, mod)) }, | 3593 | 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, pt), mulend2.toFloat(f16, pt), addend.toFloat(f16, pt)) }, |
| 3520 | 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, mod), mulend2.toFloat(f32, mod), addend.toFloat(f32, mod)) }, | 3594 | 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, pt), mulend2.toFloat(f32, pt), addend.toFloat(f32, pt)) }, |
| 3521 | 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, mod), mulend2.toFloat(f64, mod), addend.toFloat(f64, mod)) }, | 3595 | 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, pt), mulend2.toFloat(f64, pt), addend.toFloat(f64, pt)) }, |
| 3522 | 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, mod), mulend2.toFloat(f80, mod), addend.toFloat(f80, mod)) }, | 3596 | 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, pt), mulend2.toFloat(f80, pt), addend.toFloat(f80, pt)) }, |
| 3523 | 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, mod), mulend2.toFloat(f128, mod), addend.toFloat(f128, mod)) }, | 3597 | 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, pt), mulend2.toFloat(f128, pt), addend.toFloat(f128, pt)) }, |
| 3524 | else => unreachable, | 3598 | else => unreachable, |
| 3525 | }; | 3599 | }; |
| 3526 | return Value.fromInterned((try mod.intern(.{ .float = .{ | 3600 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 3527 | .ty = float_type.toIntern(), | 3601 | .ty = float_type.toIntern(), |
| 3528 | .storage = storage, | 3602 | .storage = storage, |
| 3529 | } }))); | 3603 | } })); |
| 3530 | } | 3604 | } |
| 3531 | 3605 | ||
| 3532 | /// If the value is represented in-memory as a series of bytes that all | 3606 | /// If the value is represented in-memory as a series of bytes that all |
| 3533 | /// have the same value, return that byte value, otherwise null. | 3607 | /// have the same value, return that byte value, otherwise null. |
| 3534 | pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?u8 { | 3608 | pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 { |
| 3535 | const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null; | 3609 | const abi_size = std.math.cast(usize, ty.abiSize(pt)) orelse return null; |
| 3536 | assert(abi_size >= 1); | 3610 | assert(abi_size >= 1); |
| 3537 | const byte_buffer = try mod.gpa.alloc(u8, abi_size); | 3611 | const byte_buffer = try pt.zcu.gpa.alloc(u8, abi_size); |
| 3538 | defer mod.gpa.free(byte_buffer); | 3612 | defer pt.zcu.gpa.free(byte_buffer); |
| 3539 | 3613 | ||
| 3540 | writeToMemory(val, ty, mod, byte_buffer) catch |err| switch (err) { | 3614 | writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) { |
| 3541 | error.OutOfMemory => return error.OutOfMemory, | 3615 | error.OutOfMemory => return error.OutOfMemory, |
| 3542 | error.ReinterpretDeclRef => return null, | 3616 | error.ReinterpretDeclRef => return null, |
| 3543 | // TODO: The writeToMemory function was originally created for the purpose | 3617 | // TODO: The writeToMemory function was originally created for the purpose |
| ... | @@ -3567,13 +3641,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type { | ... | @@ -3567,13 +3641,13 @@ pub fn typeOf(val: Value, zcu: *const Zcu) Type { |
| 3567 | /// If `val` is not undef, the bounds are both `val`. | 3641 | /// If `val` is not undef, the bounds are both `val`. |
| 3568 | /// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type. | 3642 | /// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type. |
| 3569 | /// If `val` is undef and is a `comptime_int`, returns null. | 3643 | /// If `val` is undef and is a `comptime_int`, returns null. |
| 3570 | pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value { | 3644 | pub fn intValueBounds(val: Value, pt: Zcu.PerThread) !?[2]Value { |
| 3571 | if (!val.isUndef(mod)) return .{ val, val }; | 3645 | if (!val.isUndef(pt.zcu)) return .{ val, val }; |
| 3572 | const ty = mod.intern_pool.typeOf(val.toIntern()); | 3646 | const ty = pt.zcu.intern_pool.typeOf(val.toIntern()); |
| 3573 | if (ty == .comptime_int_type) return null; | 3647 | if (ty == .comptime_int_type) return null; |
| 3574 | return .{ | 3648 | return .{ |
| 3575 | try Type.fromInterned(ty).minInt(mod, Type.fromInterned(ty)), | 3649 | try Type.fromInterned(ty).minInt(pt, Type.fromInterned(ty)), |
| 3576 | try Type.fromInterned(ty).maxInt(mod, Type.fromInterned(ty)), | 3650 | try Type.fromInterned(ty).maxInt(pt, Type.fromInterned(ty)), |
| 3577 | }; | 3651 | }; |
| 3578 | } | 3652 | } |
| 3579 | 3653 | ||
| ... | @@ -3604,14 +3678,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex; | ... | @@ -3604,14 +3678,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex; |
| 3604 | /// `parent_ptr` must be a single-pointer to some optional. | 3678 | /// `parent_ptr` must be a single-pointer to some optional. |
| 3605 | /// Returns a pointer to the payload of the optional. | 3679 | /// Returns a pointer to the payload of the optional. |
| 3606 | /// May perform type resolution. | 3680 | /// May perform type resolution. |
| 3607 | pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value { | 3681 | pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value { |
| 3682 | const zcu = pt.zcu; | ||
| 3608 | const parent_ptr_ty = parent_ptr.typeOf(zcu); | 3683 | const parent_ptr_ty = parent_ptr.typeOf(zcu); |
| 3609 | const opt_ty = parent_ptr_ty.childType(zcu); | 3684 | const opt_ty = parent_ptr_ty.childType(zcu); |
| 3610 | 3685 | ||
| 3611 | assert(parent_ptr_ty.ptrSize(zcu) == .One); | 3686 | assert(parent_ptr_ty.ptrSize(zcu) == .One); |
| 3612 | assert(opt_ty.zigTypeTag(zcu) == .Optional); | 3687 | assert(opt_ty.zigTypeTag(zcu) == .Optional); |
| 3613 | 3688 | ||
| 3614 | const result_ty = try zcu.ptrTypeSema(info: { | 3689 | const result_ty = try pt.ptrTypeSema(info: { |
| 3615 | var new = parent_ptr_ty.ptrInfo(zcu); | 3690 | var new = parent_ptr_ty.ptrInfo(zcu); |
| 3616 | // We can correctly preserve alignment `.none`, since an optional has the same | 3691 | // We can correctly preserve alignment `.none`, since an optional has the same |
| 3617 | // natural alignment as its child type. | 3692 | // natural alignment as its child type. |
| ... | @@ -3619,15 +3694,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value { | ... | @@ -3619,15 +3694,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value { |
| 3619 | break :info new; | 3694 | break :info new; |
| 3620 | }); | 3695 | }); |
| 3621 | 3696 | ||
| 3622 | if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty); | 3697 | if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty); |
| 3623 | 3698 | ||
| 3624 | if (opt_ty.isPtrLikeOptional(zcu)) { | 3699 | if (opt_ty.isPtrLikeOptional(zcu)) { |
| 3625 | // Just reinterpret the pointer, since the layout is well-defined | 3700 | // Just reinterpret the pointer, since the layout is well-defined |
| 3626 | return zcu.getCoerced(parent_ptr, result_ty); | 3701 | return pt.getCoerced(parent_ptr, result_ty); |
| 3627 | } | 3702 | } |
| 3628 | 3703 | ||
| 3629 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, zcu); | 3704 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, opt_ty, pt); |
| 3630 | return Value.fromInterned(try zcu.intern(.{ .ptr = .{ | 3705 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 3631 | .ty = result_ty.toIntern(), | 3706 | .ty = result_ty.toIntern(), |
| 3632 | .base_addr = .{ .opt_payload = base_ptr.toIntern() }, | 3707 | .base_addr = .{ .opt_payload = base_ptr.toIntern() }, |
| 3633 | .byte_offset = 0, | 3708 | .byte_offset = 0, |
| ... | @@ -3637,14 +3712,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value { | ... | @@ -3637,14 +3712,15 @@ pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value { |
| 3637 | /// `parent_ptr` must be a single-pointer to some error union. | 3712 | /// `parent_ptr` must be a single-pointer to some error union. |
| 3638 | /// Returns a pointer to the payload of the error union. | 3713 | /// Returns a pointer to the payload of the error union. |
| 3639 | /// May perform type resolution. | 3714 | /// May perform type resolution. |
| 3640 | pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value { | 3715 | pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value { |
| 3716 | const zcu = pt.zcu; | ||
| 3641 | const parent_ptr_ty = parent_ptr.typeOf(zcu); | 3717 | const parent_ptr_ty = parent_ptr.typeOf(zcu); |
| 3642 | const eu_ty = parent_ptr_ty.childType(zcu); | 3718 | const eu_ty = parent_ptr_ty.childType(zcu); |
| 3643 | 3719 | ||
| 3644 | assert(parent_ptr_ty.ptrSize(zcu) == .One); | 3720 | assert(parent_ptr_ty.ptrSize(zcu) == .One); |
| 3645 | assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion); | 3721 | assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion); |
| 3646 | 3722 | ||
| 3647 | const result_ty = try zcu.ptrTypeSema(info: { | 3723 | const result_ty = try pt.ptrTypeSema(info: { |
| 3648 | var new = parent_ptr_ty.ptrInfo(zcu); | 3724 | var new = parent_ptr_ty.ptrInfo(zcu); |
| 3649 | // We can correctly preserve alignment `.none`, since an error union has a | 3725 | // We can correctly preserve alignment `.none`, since an error union has a |
| 3650 | // natural alignment greater than or equal to that of its payload type. | 3726 | // natural alignment greater than or equal to that of its payload type. |
| ... | @@ -3652,10 +3728,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value { | ... | @@ -3652,10 +3728,10 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value { |
| 3652 | break :info new; | 3728 | break :info new; |
| 3653 | }); | 3729 | }); |
| 3654 | 3730 | ||
| 3655 | if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty); | 3731 | if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty); |
| 3656 | 3732 | ||
| 3657 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, zcu); | 3733 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, eu_ty, pt); |
| 3658 | return Value.fromInterned(try zcu.intern(.{ .ptr = .{ | 3734 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 3659 | .ty = result_ty.toIntern(), | 3735 | .ty = result_ty.toIntern(), |
| 3660 | .base_addr = .{ .eu_payload = base_ptr.toIntern() }, | 3736 | .base_addr = .{ .eu_payload = base_ptr.toIntern() }, |
| 3661 | .byte_offset = 0, | 3737 | .byte_offset = 0, |
| ... | @@ -3666,7 +3742,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value { | ... | @@ -3666,7 +3742,8 @@ pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value { |
| 3666 | /// Returns a pointer to the aggregate field at the specified index. | 3742 | /// Returns a pointer to the aggregate field at the specified index. |
| 3667 | /// For slices, uses `slice_ptr_index` and `slice_len_index`. | 3743 | /// For slices, uses `slice_ptr_index` and `slice_len_index`. |
| 3668 | /// May perform type resolution. | 3744 | /// May perform type resolution. |
| 3669 | pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | 3745 | pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3746 | const zcu = pt.zcu; | ||
| 3670 | const parent_ptr_ty = parent_ptr.typeOf(zcu); | 3747 | const parent_ptr_ty = parent_ptr.typeOf(zcu); |
| 3671 | const aggregate_ty = parent_ptr_ty.childType(zcu); | 3748 | const aggregate_ty = parent_ptr_ty.childType(zcu); |
| 3672 | 3749 | ||
| ... | @@ -3679,39 +3756,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3679,39 +3756,39 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3679 | .Struct => field: { | 3756 | .Struct => field: { |
| 3680 | const field_ty = aggregate_ty.structFieldType(field_idx, zcu); | 3757 | const field_ty = aggregate_ty.structFieldType(field_idx, zcu); |
| 3681 | switch (aggregate_ty.containerLayout(zcu)) { | 3758 | switch (aggregate_ty.containerLayout(zcu)) { |
| 3682 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) }, | 3759 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) }, |
| 3683 | .@"extern" => { | 3760 | .@"extern" => { |
| 3684 | // Well-defined layout, so just offset the pointer appropriately. | 3761 | // Well-defined layout, so just offset the pointer appropriately. |
| 3685 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); | 3762 | const byte_off = aggregate_ty.structFieldOffset(field_idx, pt); |
| 3686 | const field_align = a: { | 3763 | const field_align = a: { |
| 3687 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { | 3764 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { |
| 3688 | break :pa (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar; | 3765 | break :pa (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar; |
| 3689 | } else parent_ptr_info.flags.alignment; | 3766 | } else parent_ptr_info.flags.alignment; |
| 3690 | break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off))); | 3767 | break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off))); |
| 3691 | }; | 3768 | }; |
| 3692 | const result_ty = try zcu.ptrTypeSema(info: { | 3769 | const result_ty = try pt.ptrTypeSema(info: { |
| 3693 | var new = parent_ptr_info; | 3770 | var new = parent_ptr_info; |
| 3694 | new.child = field_ty.toIntern(); | 3771 | new.child = field_ty.toIntern(); |
| 3695 | new.flags.alignment = field_align; | 3772 | new.flags.alignment = field_align; |
| 3696 | break :info new; | 3773 | break :info new; |
| 3697 | }); | 3774 | }); |
| 3698 | return parent_ptr.getOffsetPtr(byte_off, result_ty, zcu); | 3775 | return parent_ptr.getOffsetPtr(byte_off, result_ty, pt); |
| 3699 | }, | 3776 | }, |
| 3700 | .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, zcu)) { | 3777 | .@"packed" => switch (aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, pt)) { |
| 3701 | .bit_ptr => |packed_offset| { | 3778 | .bit_ptr => |packed_offset| { |
| 3702 | const result_ty = try zcu.ptrType(info: { | 3779 | const result_ty = try pt.ptrType(info: { |
| 3703 | var new = parent_ptr_info; | 3780 | var new = parent_ptr_info; |
| 3704 | new.packed_offset = packed_offset; | 3781 | new.packed_offset = packed_offset; |
| 3705 | new.child = field_ty.toIntern(); | 3782 | new.child = field_ty.toIntern(); |
| 3706 | if (new.flags.alignment == .none) { | 3783 | if (new.flags.alignment == .none) { |
| 3707 | new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar; | 3784 | new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar; |
| 3708 | } | 3785 | } |
| 3709 | break :info new; | 3786 | break :info new; |
| 3710 | }); | 3787 | }); |
| 3711 | return zcu.getCoerced(parent_ptr, result_ty); | 3788 | return pt.getCoerced(parent_ptr, result_ty); |
| 3712 | }, | 3789 | }, |
| 3713 | .byte_ptr => |ptr_info| { | 3790 | .byte_ptr => |ptr_info| { |
| 3714 | const result_ty = try zcu.ptrTypeSema(info: { | 3791 | const result_ty = try pt.ptrTypeSema(info: { |
| 3715 | var new = parent_ptr_info; | 3792 | var new = parent_ptr_info; |
| 3716 | new.child = field_ty.toIntern(); | 3793 | new.child = field_ty.toIntern(); |
| 3717 | new.packed_offset = .{ | 3794 | new.packed_offset = .{ |
| ... | @@ -3721,7 +3798,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3721,7 +3798,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3721 | new.flags.alignment = ptr_info.alignment; | 3798 | new.flags.alignment = ptr_info.alignment; |
| 3722 | break :info new; | 3799 | break :info new; |
| 3723 | }); | 3800 | }); |
| 3724 | return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, zcu); | 3801 | return parent_ptr.getOffsetPtr(ptr_info.offset, result_ty, pt); |
| 3725 | }, | 3802 | }, |
| 3726 | }, | 3803 | }, |
| 3727 | } | 3804 | } |
| ... | @@ -3730,46 +3807,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3730,46 +3807,46 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3730 | const union_obj = zcu.typeToUnion(aggregate_ty).?; | 3807 | const union_obj = zcu.typeToUnion(aggregate_ty).?; |
| 3731 | const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]); | 3808 | const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]); |
| 3732 | switch (aggregate_ty.containerLayout(zcu)) { | 3809 | switch (aggregate_ty.containerLayout(zcu)) { |
| 3733 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) }, | 3810 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) }, |
| 3734 | .@"extern" => { | 3811 | .@"extern" => { |
| 3735 | // Point to the same address. | 3812 | // Point to the same address. |
| 3736 | const result_ty = try zcu.ptrTypeSema(info: { | 3813 | const result_ty = try pt.ptrTypeSema(info: { |
| 3737 | var new = parent_ptr_info; | 3814 | var new = parent_ptr_info; |
| 3738 | new.child = field_ty.toIntern(); | 3815 | new.child = field_ty.toIntern(); |
| 3739 | break :info new; | 3816 | break :info new; |
| 3740 | }); | 3817 | }); |
| 3741 | return zcu.getCoerced(parent_ptr, result_ty); | 3818 | return pt.getCoerced(parent_ptr, result_ty); |
| 3742 | }, | 3819 | }, |
| 3743 | .@"packed" => { | 3820 | .@"packed" => { |
| 3744 | // If the field has an ABI size matching its bit size, then we can continue to use a | 3821 | // If the field has an ABI size matching its bit size, then we can continue to use a |
| 3745 | // non-bit pointer if the parent pointer is also a non-bit pointer. | 3822 | // non-bit pointer if the parent pointer is also a non-bit pointer. |
| 3746 | if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(zcu, .sema)) { | 3823 | if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(pt, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(pt, .sema)) { |
| 3747 | // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely. | 3824 | // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely. |
| 3748 | const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) { | 3825 | const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) { |
| 3749 | .little => 0, | 3826 | .little => 0, |
| 3750 | .big => (try aggregate_ty.abiSizeAdvanced(zcu, .sema)).scalar - (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar, | 3827 | .big => (try aggregate_ty.abiSizeAdvanced(pt, .sema)).scalar - (try field_ty.abiSizeAdvanced(pt, .sema)).scalar, |
| 3751 | }; | 3828 | }; |
| 3752 | const result_ty = try zcu.ptrTypeSema(info: { | 3829 | const result_ty = try pt.ptrTypeSema(info: { |
| 3753 | var new = parent_ptr_info; | 3830 | var new = parent_ptr_info; |
| 3754 | new.child = field_ty.toIntern(); | 3831 | new.child = field_ty.toIntern(); |
| 3755 | new.flags.alignment = InternPool.Alignment.fromLog2Units( | 3832 | new.flags.alignment = InternPool.Alignment.fromLog2Units( |
| 3756 | @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema)).toByteUnits().?), | 3833 | @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema)).toByteUnits().?), |
| 3757 | ); | 3834 | ); |
| 3758 | break :info new; | 3835 | break :info new; |
| 3759 | }); | 3836 | }); |
| 3760 | return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu); | 3837 | return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt); |
| 3761 | } else { | 3838 | } else { |
| 3762 | // The result must be a bit-pointer if it is not already. | 3839 | // The result must be a bit-pointer if it is not already. |
| 3763 | const result_ty = try zcu.ptrTypeSema(info: { | 3840 | const result_ty = try pt.ptrTypeSema(info: { |
| 3764 | var new = parent_ptr_info; | 3841 | var new = parent_ptr_info; |
| 3765 | new.child = field_ty.toIntern(); | 3842 | new.child = field_ty.toIntern(); |
| 3766 | if (new.packed_offset.host_size == 0) { | 3843 | if (new.packed_offset.host_size == 0) { |
| 3767 | new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(zcu, .sema)) + 7) / 8); | 3844 | new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(pt, .sema)) + 7) / 8); |
| 3768 | assert(new.packed_offset.bit_offset == 0); | 3845 | assert(new.packed_offset.bit_offset == 0); |
| 3769 | } | 3846 | } |
| 3770 | break :info new; | 3847 | break :info new; |
| 3771 | }); | 3848 | }); |
| 3772 | return zcu.getCoerced(parent_ptr, result_ty); | 3849 | return pt.getCoerced(parent_ptr, result_ty); |
| 3773 | } | 3850 | } |
| 3774 | }, | 3851 | }, |
| 3775 | } | 3852 | } |
| ... | @@ -3777,8 +3854,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3777,8 +3854,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3777 | .Pointer => field_ty: { | 3854 | .Pointer => field_ty: { |
| 3778 | assert(aggregate_ty.isSlice(zcu)); | 3855 | assert(aggregate_ty.isSlice(zcu)); |
| 3779 | break :field_ty switch (field_idx) { | 3856 | break :field_ty switch (field_idx) { |
| 3780 | Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(zcu) }, | 3857 | Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(pt) }, |
| 3781 | Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(zcu) }, | 3858 | Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(pt) }, |
| 3782 | else => unreachable, | 3859 | else => unreachable, |
| 3783 | }; | 3860 | }; |
| 3784 | }, | 3861 | }, |
| ... | @@ -3786,24 +3863,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3786,24 +3863,24 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3786 | }; | 3863 | }; |
| 3787 | 3864 | ||
| 3788 | const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: { | 3865 | const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: { |
| 3789 | const ty_align = (try field_ty.abiAlignmentAdvanced(zcu, .sema)).scalar; | 3866 | const ty_align = (try field_ty.abiAlignmentAdvanced(pt, .sema)).scalar; |
| 3790 | const true_field_align = if (field_align == .none) ty_align else field_align; | 3867 | const true_field_align = if (field_align == .none) ty_align else field_align; |
| 3791 | const new_align = true_field_align.min(parent_ptr_info.flags.alignment); | 3868 | const new_align = true_field_align.min(parent_ptr_info.flags.alignment); |
| 3792 | if (new_align == ty_align) break :a .none; | 3869 | if (new_align == ty_align) break :a .none; |
| 3793 | break :a new_align; | 3870 | break :a new_align; |
| 3794 | } else field_align; | 3871 | } else field_align; |
| 3795 | 3872 | ||
| 3796 | const result_ty = try zcu.ptrTypeSema(info: { | 3873 | const result_ty = try pt.ptrTypeSema(info: { |
| 3797 | var new = parent_ptr_info; | 3874 | var new = parent_ptr_info; |
| 3798 | new.child = field_ty.toIntern(); | 3875 | new.child = field_ty.toIntern(); |
| 3799 | new.flags.alignment = new_align; | 3876 | new.flags.alignment = new_align; |
| 3800 | break :info new; | 3877 | break :info new; |
| 3801 | }); | 3878 | }); |
| 3802 | 3879 | ||
| 3803 | if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty); | 3880 | if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty); |
| 3804 | 3881 | ||
| 3805 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, zcu); | 3882 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.One, aggregate_ty, pt); |
| 3806 | return Value.fromInterned(try zcu.intern(.{ .ptr = .{ | 3883 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 3807 | .ty = result_ty.toIntern(), | 3884 | .ty = result_ty.toIntern(), |
| 3808 | .base_addr = .{ .field = .{ | 3885 | .base_addr = .{ .field = .{ |
| 3809 | .base = base_ptr.toIntern(), | 3886 | .base = base_ptr.toIntern(), |
| ... | @@ -3816,7 +3893,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { | ... | @@ -3816,7 +3893,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value { |
| 3816 | /// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice. | 3893 | /// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice. |
| 3817 | /// Returns a pointer to the element at the specified index. | 3894 | /// Returns a pointer to the element at the specified index. |
| 3818 | /// May perform type resolution. | 3895 | /// May perform type resolution. |
| 3819 | pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | 3896 | pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value { |
| 3897 | const zcu = pt.zcu; | ||
| 3820 | const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) { | 3898 | const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) { |
| 3821 | .One, .Many, .C => orig_parent_ptr, | 3899 | .One, .Many, .C => orig_parent_ptr, |
| 3822 | .Slice => orig_parent_ptr.slicePtr(zcu), | 3900 | .Slice => orig_parent_ptr.slicePtr(zcu), |
| ... | @@ -3824,14 +3902,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | ... | @@ -3824,14 +3902,14 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { |
| 3824 | 3902 | ||
| 3825 | const parent_ptr_ty = parent_ptr.typeOf(zcu); | 3903 | const parent_ptr_ty = parent_ptr.typeOf(zcu); |
| 3826 | const elem_ty = parent_ptr_ty.childType(zcu); | 3904 | const elem_ty = parent_ptr_ty.childType(zcu); |
| 3827 | const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), zcu); | 3905 | const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), pt); |
| 3828 | 3906 | ||
| 3829 | if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty); | 3907 | if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty); |
| 3830 | 3908 | ||
| 3831 | if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) { | 3909 | if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) { |
| 3832 | // Since we have a bit-pointer, the pointer address should be unchanged. | 3910 | // Since we have a bit-pointer, the pointer address should be unchanged. |
| 3833 | assert(elem_ty.zigTypeTag(zcu) == .Vector); | 3911 | assert(elem_ty.zigTypeTag(zcu) == .Vector); |
| 3834 | return zcu.getCoerced(parent_ptr, result_ty); | 3912 | return pt.getCoerced(parent_ptr, result_ty); |
| 3835 | } | 3913 | } |
| 3836 | 3914 | ||
| 3837 | const PtrStrat = union(enum) { | 3915 | const PtrStrat = union(enum) { |
| ... | @@ -3841,31 +3919,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | ... | @@ -3841,31 +3919,31 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { |
| 3841 | 3919 | ||
| 3842 | const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) { | 3920 | const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) { |
| 3843 | .One => switch (elem_ty.zigTypeTag(zcu)) { | 3921 | .One => switch (elem_ty.zigTypeTag(zcu)) { |
| 3844 | .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(zcu, .sema), 8) }, | 3922 | .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(pt, .sema), 8) }, |
| 3845 | .Array => strat: { | 3923 | .Array => strat: { |
| 3846 | const arr_elem_ty = elem_ty.childType(zcu); | 3924 | const arr_elem_ty = elem_ty.childType(zcu); |
| 3847 | if (try arr_elem_ty.comptimeOnlyAdvanced(zcu, .sema)) { | 3925 | if (try arr_elem_ty.comptimeOnlyAdvanced(pt, .sema)) { |
| 3848 | break :strat .{ .elem_ptr = arr_elem_ty }; | 3926 | break :strat .{ .elem_ptr = arr_elem_ty }; |
| 3849 | } | 3927 | } |
| 3850 | break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(zcu, .sema)).scalar }; | 3928 | break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(pt, .sema)).scalar }; |
| 3851 | }, | 3929 | }, |
| 3852 | else => unreachable, | 3930 | else => unreachable, |
| 3853 | }, | 3931 | }, |
| 3854 | 3932 | ||
| 3855 | .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(zcu, .sema)) | 3933 | .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(pt, .sema)) |
| 3856 | .{ .elem_ptr = elem_ty } | 3934 | .{ .elem_ptr = elem_ty } |
| 3857 | else | 3935 | else |
| 3858 | .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar }, | 3936 | .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar }, |
| 3859 | 3937 | ||
| 3860 | .Slice => unreachable, | 3938 | .Slice => unreachable, |
| 3861 | }; | 3939 | }; |
| 3862 | 3940 | ||
| 3863 | switch (strat) { | 3941 | switch (strat) { |
| 3864 | .offset => |byte_offset| { | 3942 | .offset => |byte_offset| { |
| 3865 | return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu); | 3943 | return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt); |
| 3866 | }, | 3944 | }, |
| 3867 | .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) { | 3945 | .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) { |
| 3868 | return zcu.getCoerced(parent_ptr, result_ty); | 3946 | return pt.getCoerced(parent_ptr, result_ty); |
| 3869 | } else { | 3947 | } else { |
| 3870 | const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu); | 3948 | const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu); |
| 3871 | const base_idx = arr_base_len * field_idx; | 3949 | const base_idx = arr_base_len * field_idx; |
| ... | @@ -3875,7 +3953,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | ... | @@ -3875,7 +3953,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { |
| 3875 | if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) { | 3953 | if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) { |
| 3876 | // We already have a pointer to an element of an array of this type. | 3954 | // We already have a pointer to an element of an array of this type. |
| 3877 | // Just modify the index. | 3955 | // Just modify the index. |
| 3878 | return Value.fromInterned(try zcu.intern(.{ .ptr = ptr: { | 3956 | return Value.fromInterned(try pt.intern(.{ .ptr = ptr: { |
| 3879 | var new = parent_info; | 3957 | var new = parent_info; |
| 3880 | new.base_addr.arr_elem.index += base_idx; | 3958 | new.base_addr.arr_elem.index += base_idx; |
| 3881 | new.ty = result_ty.toIntern(); | 3959 | new.ty = result_ty.toIntern(); |
| ... | @@ -3885,8 +3963,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | ... | @@ -3885,8 +3963,8 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { |
| 3885 | }, | 3963 | }, |
| 3886 | else => {}, | 3964 | else => {}, |
| 3887 | } | 3965 | } |
| 3888 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, zcu); | 3966 | const base_ptr = try parent_ptr.canonicalizeBasePtr(.Many, arr_base_ty, pt); |
| 3889 | return Value.fromInterned(try zcu.intern(.{ .ptr = .{ | 3967 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 3890 | .ty = result_ty.toIntern(), | 3968 | .ty = result_ty.toIntern(), |
| 3891 | .base_addr = .{ .arr_elem = .{ | 3969 | .base_addr = .{ .arr_elem = .{ |
| 3892 | .base = base_ptr.toIntern(), | 3970 | .base = base_ptr.toIntern(), |
| ... | @@ -3898,9 +3976,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { | ... | @@ -3898,9 +3976,9 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value { |
| 3898 | } | 3976 | } |
| 3899 | } | 3977 | } |
| 3900 | 3978 | ||
| 3901 | fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, zcu: *Zcu) !Value { | 3979 | fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, pt: Zcu.PerThread) !Value { |
| 3902 | const ptr_ty = base_ptr.typeOf(zcu); | 3980 | const ptr_ty = base_ptr.typeOf(pt.zcu); |
| 3903 | const ptr_info = ptr_ty.ptrInfo(zcu); | 3981 | const ptr_info = ptr_ty.ptrInfo(pt.zcu); |
| 3904 | 3982 | ||
| 3905 | if (ptr_info.flags.size == want_size and | 3983 | if (ptr_info.flags.size == want_size and |
| 3906 | ptr_info.child == want_child.toIntern() and | 3984 | ptr_info.child == want_child.toIntern() and |
| ... | @@ -3914,7 +3992,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size | ... | @@ -3914,7 +3992,7 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size |
| 3914 | return base_ptr; | 3992 | return base_ptr; |
| 3915 | } | 3993 | } |
| 3916 | 3994 | ||
| 3917 | const new_ty = try zcu.ptrType(.{ | 3995 | const new_ty = try pt.ptrType(.{ |
| 3918 | .child = want_child.toIntern(), | 3996 | .child = want_child.toIntern(), |
| 3919 | .sentinel = .none, | 3997 | .sentinel = .none, |
| 3920 | .flags = .{ | 3998 | .flags = .{ |
| ... | @@ -3926,15 +4004,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size | ... | @@ -3926,15 +4004,15 @@ fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size |
| 3926 | .address_space = ptr_info.flags.address_space, | 4004 | .address_space = ptr_info.flags.address_space, |
| 3927 | }, | 4005 | }, |
| 3928 | }); | 4006 | }); |
| 3929 | return zcu.getCoerced(base_ptr, new_ty); | 4007 | return pt.getCoerced(base_ptr, new_ty); |
| 3930 | } | 4008 | } |
| 3931 | 4009 | ||
| 3932 | pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, zcu: *Zcu) !Value { | 4010 | pub fn getOffsetPtr(ptr_val: Value, byte_off: u64, new_ty: Type, pt: Zcu.PerThread) !Value { |
| 3933 | if (ptr_val.isUndef(zcu)) return ptr_val; | 4011 | if (ptr_val.isUndef(pt.zcu)) return ptr_val; |
| 3934 | var ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | 4012 | var ptr = pt.zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; |
| 3935 | ptr.ty = new_ty.toIntern(); | 4013 | ptr.ty = new_ty.toIntern(); |
| 3936 | ptr.byte_offset += byte_off; | 4014 | ptr.byte_offset += byte_off; |
| 3937 | return Value.fromInterned(try zcu.intern(.{ .ptr = ptr })); | 4015 | return Value.fromInterned(try pt.intern(.{ .ptr = ptr })); |
| 3938 | } | 4016 | } |
| 3939 | 4017 | ||
| 3940 | pub const PointerDeriveStep = union(enum) { | 4018 | pub const PointerDeriveStep = union(enum) { |
| ... | @@ -3977,21 +4055,21 @@ pub const PointerDeriveStep = union(enum) { | ... | @@ -3977,21 +4055,21 @@ pub const PointerDeriveStep = union(enum) { |
| 3977 | new_ptr_ty: Type, | 4055 | new_ptr_ty: Type, |
| 3978 | }, | 4056 | }, |
| 3979 | 4057 | ||
| 3980 | pub fn ptrType(step: PointerDeriveStep, zcu: *Zcu) !Type { | 4058 | pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type { |
| 3981 | return switch (step) { | 4059 | return switch (step) { |
| 3982 | .int => |int| int.ptr_ty, | 4060 | .int => |int| int.ptr_ty, |
| 3983 | .decl_ptr => |decl| try zcu.declPtr(decl).declPtrType(zcu), | 4061 | .decl_ptr => |decl| try pt.zcu.declPtr(decl).declPtrType(pt), |
| 3984 | .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty), | 4062 | .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty), |
| 3985 | .comptime_alloc_ptr => |info| info.ptr_ty, | 4063 | .comptime_alloc_ptr => |info| info.ptr_ty, |
| 3986 | .comptime_field_ptr => |val| try zcu.singleConstPtrType(val.typeOf(zcu)), | 4064 | .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)), |
| 3987 | .offset_and_cast => |oac| oac.new_ptr_ty, | 4065 | .offset_and_cast => |oac| oac.new_ptr_ty, |
| 3988 | inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty, | 4066 | inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty, |
| 3989 | }; | 4067 | }; |
| 3990 | } | 4068 | } |
| 3991 | }; | 4069 | }; |
| 3992 | 4070 | ||
| 3993 | pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep { | 4071 | pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread) Allocator.Error!PointerDeriveStep { |
| 3994 | return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) { | 4072 | return ptr_val.pointerDerivationAdvanced(arena, pt, null) catch |err| switch (err) { |
| 3995 | error.OutOfMemory => |e| return e, | 4073 | error.OutOfMemory => |e| return e, |
| 3996 | error.AnalysisFail => unreachable, | 4074 | error.AnalysisFail => unreachable, |
| 3997 | }; | 4075 | }; |
| ... | @@ -4001,7 +4079,8 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator. | ... | @@ -4001,7 +4079,8 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator. |
| 4001 | /// only field and element pointers with no casts. This can be used by codegen backends | 4079 | /// only field and element pointers with no casts. This can be used by codegen backends |
| 4002 | /// which prefer field/elem accesses when lowering constant pointer values. | 4080 | /// which prefer field/elem accesses when lowering constant pointer values. |
| 4003 | /// It is also used by the Value printing logic for pointers. | 4081 | /// It is also used by the Value printing logic for pointers. |
| 4004 | pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, opt_sema: ?*Sema) !PointerDeriveStep { | 4082 | pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) !PointerDeriveStep { |
| 4083 | const zcu = pt.zcu; | ||
| 4005 | const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | 4084 | const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; |
| 4006 | const base_derive: PointerDeriveStep = switch (ptr.base_addr) { | 4085 | const base_derive: PointerDeriveStep = switch (ptr.base_addr) { |
| 4007 | .int => return .{ .int = .{ | 4086 | .int => return .{ .int = .{ |
| ... | @@ -4012,7 +4091,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4012,7 +4091,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4012 | .anon_decl => |ad| base: { | 4091 | .anon_decl => |ad| base: { |
| 4013 | // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be. | 4092 | // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be. |
| 4014 | // TODO: fix this in the sites interning anon decls! | 4093 | // TODO: fix this in the sites interning anon decls! |
| 4015 | const const_ty = try zcu.ptrType(info: { | 4094 | const const_ty = try pt.ptrType(info: { |
| 4016 | var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu); | 4095 | var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu); |
| 4017 | info.flags.is_const = true; | 4096 | info.flags.is_const = true; |
| 4018 | break :info info; | 4097 | break :info info; |
| ... | @@ -4024,11 +4103,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4024,11 +4103,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4024 | }, | 4103 | }, |
| 4025 | .comptime_alloc => |idx| base: { | 4104 | .comptime_alloc => |idx| base: { |
| 4026 | const alloc = opt_sema.?.getComptimeAlloc(idx); | 4105 | const alloc = opt_sema.?.getComptimeAlloc(idx); |
| 4027 | const val = try alloc.val.intern(zcu, opt_sema.?.arena); | 4106 | const val = try alloc.val.intern(pt, opt_sema.?.arena); |
| 4028 | const ty = val.typeOf(zcu); | 4107 | const ty = val.typeOf(zcu); |
| 4029 | break :base .{ .comptime_alloc_ptr = .{ | 4108 | break :base .{ .comptime_alloc_ptr = .{ |
| 4030 | .val = val, | 4109 | .val = val, |
| 4031 | .ptr_ty = try zcu.ptrType(.{ | 4110 | .ptr_ty = try pt.ptrType(.{ |
| 4032 | .child = ty.toIntern(), | 4111 | .child = ty.toIntern(), |
| 4033 | .flags = .{ | 4112 | .flags = .{ |
| 4034 | .alignment = alloc.alignment, | 4113 | .alignment = alloc.alignment, |
| ... | @@ -4041,20 +4120,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4041,20 +4120,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4041 | const base_ptr = Value.fromInterned(eu_ptr); | 4120 | const base_ptr = Value.fromInterned(eu_ptr); |
| 4042 | const base_ptr_ty = base_ptr.typeOf(zcu); | 4121 | const base_ptr_ty = base_ptr.typeOf(zcu); |
| 4043 | const parent_step = try arena.create(PointerDeriveStep); | 4122 | const parent_step = try arena.create(PointerDeriveStep); |
| 4044 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, zcu, opt_sema); | 4123 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, opt_sema); |
| 4045 | break :base .{ .eu_payload_ptr = .{ | 4124 | break :base .{ .eu_payload_ptr = .{ |
| 4046 | .parent = parent_step, | 4125 | .parent = parent_step, |
| 4047 | .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)), | 4126 | .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)), |
| 4048 | } }; | 4127 | } }; |
| 4049 | }, | 4128 | }, |
| 4050 | .opt_payload => |opt_ptr| base: { | 4129 | .opt_payload => |opt_ptr| base: { |
| 4051 | const base_ptr = Value.fromInterned(opt_ptr); | 4130 | const base_ptr = Value.fromInterned(opt_ptr); |
| 4052 | const base_ptr_ty = base_ptr.typeOf(zcu); | 4131 | const base_ptr_ty = base_ptr.typeOf(zcu); |
| 4053 | const parent_step = try arena.create(PointerDeriveStep); | 4132 | const parent_step = try arena.create(PointerDeriveStep); |
| 4054 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, zcu, opt_sema); | 4133 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, opt_sema); |
| 4055 | break :base .{ .opt_payload_ptr = .{ | 4134 | break :base .{ .opt_payload_ptr = .{ |
| 4056 | .parent = parent_step, | 4135 | .parent = parent_step, |
| 4057 | .result_ptr_ty = try zcu.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)), | 4136 | .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)), |
| 4058 | } }; | 4137 | } }; |
| 4059 | }, | 4138 | }, |
| 4060 | .field => |field| base: { | 4139 | .field => |field| base: { |
| ... | @@ -4062,22 +4141,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4062,22 +4141,22 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4062 | const base_ptr_ty = base_ptr.typeOf(zcu); | 4141 | const base_ptr_ty = base_ptr.typeOf(zcu); |
| 4063 | const agg_ty = base_ptr_ty.childType(zcu); | 4142 | const agg_ty = base_ptr_ty.childType(zcu); |
| 4064 | const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) { | 4143 | const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) { |
| 4065 | .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) }, | 4144 | .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) }, |
| 4066 | .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) }, | 4145 | .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, .sema) }, |
| 4067 | .Pointer => .{ switch (field.index) { | 4146 | .Pointer => .{ switch (field.index) { |
| 4068 | Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu), | 4147 | Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu), |
| 4069 | Value.slice_len_index => Type.usize, | 4148 | Value.slice_len_index => Type.usize, |
| 4070 | else => unreachable, | 4149 | else => unreachable, |
| 4071 | }, Type.usize.abiAlignment(zcu) }, | 4150 | }, Type.usize.abiAlignment(pt) }, |
| 4072 | else => unreachable, | 4151 | else => unreachable, |
| 4073 | }; | 4152 | }; |
| 4074 | const base_align = base_ptr_ty.ptrAlignment(zcu); | 4153 | const base_align = base_ptr_ty.ptrAlignment(pt); |
| 4075 | const result_align = field_align.minStrict(base_align); | 4154 | const result_align = field_align.minStrict(base_align); |
| 4076 | const result_ty = try zcu.ptrType(.{ | 4155 | const result_ty = try pt.ptrType(.{ |
| 4077 | .child = field_ty.toIntern(), | 4156 | .child = field_ty.toIntern(), |
| 4078 | .flags = flags: { | 4157 | .flags = flags: { |
| 4079 | var flags = base_ptr_ty.ptrInfo(zcu).flags; | 4158 | var flags = base_ptr_ty.ptrInfo(zcu).flags; |
| 4080 | if (result_align == field_ty.abiAlignment(zcu)) { | 4159 | if (result_align == field_ty.abiAlignment(pt)) { |
| 4081 | flags.alignment = .none; | 4160 | flags.alignment = .none; |
| 4082 | } else { | 4161 | } else { |
| 4083 | flags.alignment = result_align; | 4162 | flags.alignment = result_align; |
| ... | @@ -4086,7 +4165,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4086,7 +4165,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4086 | }, | 4165 | }, |
| 4087 | }); | 4166 | }); |
| 4088 | const parent_step = try arena.create(PointerDeriveStep); | 4167 | const parent_step = try arena.create(PointerDeriveStep); |
| 4089 | parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, zcu, opt_sema); | 4168 | parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, opt_sema); |
| 4090 | break :base .{ .field_ptr = .{ | 4169 | break :base .{ .field_ptr = .{ |
| 4091 | .parent = parent_step, | 4170 | .parent = parent_step, |
| 4092 | .field_idx = @intCast(field.index), | 4171 | .field_idx = @intCast(field.index), |
| ... | @@ -4095,9 +4174,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4095,9 +4174,9 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4095 | }, | 4174 | }, |
| 4096 | .arr_elem => |arr_elem| base: { | 4175 | .arr_elem => |arr_elem| base: { |
| 4097 | const parent_step = try arena.create(PointerDeriveStep); | 4176 | const parent_step = try arena.create(PointerDeriveStep); |
| 4098 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, zcu, opt_sema); | 4177 | parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, pt, opt_sema); |
| 4099 | const parent_ptr_info = (try parent_step.ptrType(zcu)).ptrInfo(zcu); | 4178 | const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu); |
| 4100 | const result_ptr_ty = try zcu.ptrType(.{ | 4179 | const result_ptr_ty = try pt.ptrType(.{ |
| 4101 | .child = parent_ptr_info.child, | 4180 | .child = parent_ptr_info.child, |
| 4102 | .flags = flags: { | 4181 | .flags = flags: { |
| 4103 | var flags = parent_ptr_info.flags; | 4182 | var flags = parent_ptr_info.flags; |
| ... | @@ -4113,12 +4192,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4113,12 +4192,12 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4113 | }, | 4192 | }, |
| 4114 | }; | 4193 | }; |
| 4115 | 4194 | ||
| 4116 | if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(zcu)).toIntern()) { | 4195 | if (ptr.byte_offset == 0 and ptr.ty == (try base_derive.ptrType(pt)).toIntern()) { |
| 4117 | return base_derive; | 4196 | return base_derive; |
| 4118 | } | 4197 | } |
| 4119 | 4198 | ||
| 4120 | const need_child = Type.fromInterned(ptr.ty).childType(zcu); | 4199 | const need_child = Type.fromInterned(ptr.ty).childType(zcu); |
| 4121 | if (need_child.comptimeOnly(zcu)) { | 4200 | if (need_child.comptimeOnly(pt)) { |
| 4122 | // No refinement can happen - this pointer is presumably invalid. | 4201 | // No refinement can happen - this pointer is presumably invalid. |
| 4123 | // Just offset it. | 4202 | // Just offset it. |
| 4124 | const parent = try arena.create(PointerDeriveStep); | 4203 | const parent = try arena.create(PointerDeriveStep); |
| ... | @@ -4129,7 +4208,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4129,7 +4208,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4129 | .new_ptr_ty = Type.fromInterned(ptr.ty), | 4208 | .new_ptr_ty = Type.fromInterned(ptr.ty), |
| 4130 | } }; | 4209 | } }; |
| 4131 | } | 4210 | } |
| 4132 | const need_bytes = need_child.abiSize(zcu); | 4211 | const need_bytes = need_child.abiSize(pt); |
| 4133 | 4212 | ||
| 4134 | var cur_derive = base_derive; | 4213 | var cur_derive = base_derive; |
| 4135 | var cur_offset = ptr.byte_offset; | 4214 | var cur_offset = ptr.byte_offset; |
| ... | @@ -4137,7 +4216,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4137,7 +4216,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4137 | // Refine through fields and array elements as much as possible. | 4216 | // Refine through fields and array elements as much as possible. |
| 4138 | 4217 | ||
| 4139 | if (need_bytes > 0) while (true) { | 4218 | if (need_bytes > 0) while (true) { |
| 4140 | const cur_ty = (try cur_derive.ptrType(zcu)).childType(zcu); | 4219 | const cur_ty = (try cur_derive.ptrType(pt)).childType(zcu); |
| 4141 | if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) { | 4220 | if (cur_ty.toIntern() == need_child.toIntern() and cur_offset == 0) { |
| 4142 | break; | 4221 | break; |
| 4143 | } | 4222 | } |
| ... | @@ -4168,7 +4247,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4168,7 +4247,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4168 | 4247 | ||
| 4169 | .Array => { | 4248 | .Array => { |
| 4170 | const elem_ty = cur_ty.childType(zcu); | 4249 | const elem_ty = cur_ty.childType(zcu); |
| 4171 | const elem_size = elem_ty.abiSize(zcu); | 4250 | const elem_size = elem_ty.abiSize(pt); |
| 4172 | const start_idx = cur_offset / elem_size; | 4251 | const start_idx = cur_offset / elem_size; |
| 4173 | const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size; | 4252 | const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size; |
| 4174 | if (end_idx == start_idx + 1) { | 4253 | if (end_idx == start_idx + 1) { |
| ... | @@ -4177,7 +4256,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4177,7 +4256,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4177 | cur_derive = .{ .elem_ptr = .{ | 4256 | cur_derive = .{ .elem_ptr = .{ |
| 4178 | .parent = parent, | 4257 | .parent = parent, |
| 4179 | .elem_idx = start_idx, | 4258 | .elem_idx = start_idx, |
| 4180 | .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty), | 4259 | .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty), |
| 4181 | } }; | 4260 | } }; |
| 4182 | cur_offset -= start_idx * elem_size; | 4261 | cur_offset -= start_idx * elem_size; |
| 4183 | } else { | 4262 | } else { |
| ... | @@ -4188,7 +4267,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4188,7 +4267,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4188 | cur_derive = .{ .elem_ptr = .{ | 4267 | cur_derive = .{ .elem_ptr = .{ |
| 4189 | .parent = parent, | 4268 | .parent = parent, |
| 4190 | .elem_idx = start_idx, | 4269 | .elem_idx = start_idx, |
| 4191 | .result_ptr_ty = try zcu.adjustPtrTypeChild(try parent.ptrType(zcu), elem_ty), | 4270 | .result_ptr_ty = try pt.adjustPtrTypeChild(try parent.ptrType(pt), elem_ty), |
| 4192 | } }; | 4271 | } }; |
| 4193 | cur_offset -= start_idx * elem_size; | 4272 | cur_offset -= start_idx * elem_size; |
| 4194 | } | 4273 | } |
| ... | @@ -4199,19 +4278,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4199,19 +4278,19 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4199 | .auto, .@"packed" => break, | 4278 | .auto, .@"packed" => break, |
| 4200 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { | 4279 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 4201 | const field_ty = cur_ty.structFieldType(field_idx, zcu); | 4280 | const field_ty = cur_ty.structFieldType(field_idx, zcu); |
| 4202 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | 4281 | const start_off = cur_ty.structFieldOffset(field_idx, pt); |
| 4203 | const end_off = start_off + field_ty.abiSize(zcu); | 4282 | const end_off = start_off + field_ty.abiSize(pt); |
| 4204 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { | 4283 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 4205 | const old_ptr_ty = try cur_derive.ptrType(zcu); | 4284 | const old_ptr_ty = try cur_derive.ptrType(pt); |
| 4206 | const parent_align = old_ptr_ty.ptrAlignment(zcu); | 4285 | const parent_align = old_ptr_ty.ptrAlignment(pt); |
| 4207 | const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off))); | 4286 | const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off))); |
| 4208 | const parent = try arena.create(PointerDeriveStep); | 4287 | const parent = try arena.create(PointerDeriveStep); |
| 4209 | parent.* = cur_derive; | 4288 | parent.* = cur_derive; |
| 4210 | const new_ptr_ty = try zcu.ptrType(.{ | 4289 | const new_ptr_ty = try pt.ptrType(.{ |
| 4211 | .child = field_ty.toIntern(), | 4290 | .child = field_ty.toIntern(), |
| 4212 | .flags = flags: { | 4291 | .flags = flags: { |
| 4213 | var flags = old_ptr_ty.ptrInfo(zcu).flags; | 4292 | var flags = old_ptr_ty.ptrInfo(zcu).flags; |
| 4214 | if (field_align == field_ty.abiAlignment(zcu)) { | 4293 | if (field_align == field_ty.abiAlignment(pt)) { |
| 4215 | flags.alignment = .none; | 4294 | flags.alignment = .none; |
| 4216 | } else { | 4295 | } else { |
| 4217 | flags.alignment = field_align; | 4296 | flags.alignment = field_align; |
| ... | @@ -4232,7 +4311,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4232,7 +4311,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4232 | } | 4311 | } |
| 4233 | }; | 4312 | }; |
| 4234 | 4313 | ||
| 4235 | if (cur_offset == 0 and (try cur_derive.ptrType(zcu)).toIntern() == ptr.ty) { | 4314 | if (cur_offset == 0 and (try cur_derive.ptrType(pt)).toIntern() == ptr.ty) { |
| 4236 | return cur_derive; | 4315 | return cur_derive; |
| 4237 | } | 4316 | } |
| 4238 | 4317 | ||
| ... | @@ -4245,20 +4324,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op | ... | @@ -4245,20 +4324,20 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op |
| 4245 | } }; | 4324 | } }; |
| 4246 | } | 4325 | } |
| 4247 | 4326 | ||
| 4248 | pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value { | 4327 | pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaError!Value { |
| 4249 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 4328 | switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 4250 | .int => |int| switch (int.storage) { | 4329 | .int => |int| switch (int.storage) { |
| 4251 | .u64, .i64, .big_int => return val, | 4330 | .u64, .i64, .big_int => return val, |
| 4252 | .lazy_align, .lazy_size => return zcu.intValue( | 4331 | .lazy_align, .lazy_size => return pt.intValue( |
| 4253 | Type.fromInterned(int.ty), | 4332 | Type.fromInterned(int.ty), |
| 4254 | (try val.getUnsignedIntAdvanced(zcu, .sema)).?, | 4333 | (try val.getUnsignedIntAdvanced(pt, .sema)).?, |
| 4255 | ), | 4334 | ), |
| 4256 | }, | 4335 | }, |
| 4257 | .slice => |slice| { | 4336 | .slice => |slice| { |
| 4258 | const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, zcu); | 4337 | const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, pt); |
| 4259 | const len = try Value.fromInterned(slice.len).resolveLazy(arena, zcu); | 4338 | const len = try Value.fromInterned(slice.len).resolveLazy(arena, pt); |
| 4260 | if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val; | 4339 | if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val; |
| 4261 | return Value.fromInterned(try zcu.intern(.{ .slice = .{ | 4340 | return Value.fromInterned(try pt.intern(.{ .slice = .{ |
| 4262 | .ty = slice.ty, | 4341 | .ty = slice.ty, |
| 4263 | .ptr = ptr.toIntern(), | 4342 | .ptr = ptr.toIntern(), |
| 4264 | .len = len.toIntern(), | 4343 | .len = len.toIntern(), |
| ... | @@ -4268,22 +4347,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value | ... | @@ -4268,22 +4347,22 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value |
| 4268 | switch (ptr.base_addr) { | 4347 | switch (ptr.base_addr) { |
| 4269 | .decl, .comptime_alloc, .anon_decl, .int => return val, | 4348 | .decl, .comptime_alloc, .anon_decl, .int => return val, |
| 4270 | .comptime_field => |field_val| { | 4349 | .comptime_field => |field_val| { |
| 4271 | const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, zcu)).toIntern(); | 4350 | const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern(); |
| 4272 | return if (resolved_field_val == field_val) | 4351 | return if (resolved_field_val == field_val) |
| 4273 | val | 4352 | val |
| 4274 | else | 4353 | else |
| 4275 | Value.fromInterned((try zcu.intern(.{ .ptr = .{ | 4354 | Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 4276 | .ty = ptr.ty, | 4355 | .ty = ptr.ty, |
| 4277 | .base_addr = .{ .comptime_field = resolved_field_val }, | 4356 | .base_addr = .{ .comptime_field = resolved_field_val }, |
| 4278 | .byte_offset = ptr.byte_offset, | 4357 | .byte_offset = ptr.byte_offset, |
| 4279 | } }))); | 4358 | } })); |
| 4280 | }, | 4359 | }, |
| 4281 | .eu_payload, .opt_payload => |base| { | 4360 | .eu_payload, .opt_payload => |base| { |
| 4282 | const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, zcu)).toIntern(); | 4361 | const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, pt)).toIntern(); |
| 4283 | return if (resolved_base == base) | 4362 | return if (resolved_base == base) |
| 4284 | val | 4363 | val |
| 4285 | else | 4364 | else |
| 4286 | Value.fromInterned((try zcu.intern(.{ .ptr = .{ | 4365 | Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 4287 | .ty = ptr.ty, | 4366 | .ty = ptr.ty, |
| 4288 | .base_addr = switch (ptr.base_addr) { | 4367 | .base_addr = switch (ptr.base_addr) { |
| 4289 | .eu_payload => .{ .eu_payload = resolved_base }, | 4368 | .eu_payload => .{ .eu_payload = resolved_base }, |
| ... | @@ -4291,14 +4370,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value | ... | @@ -4291,14 +4370,14 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value |
| 4291 | else => unreachable, | 4370 | else => unreachable, |
| 4292 | }, | 4371 | }, |
| 4293 | .byte_offset = ptr.byte_offset, | 4372 | .byte_offset = ptr.byte_offset, |
| 4294 | } }))); | 4373 | } })); |
| 4295 | }, | 4374 | }, |
| 4296 | .arr_elem, .field => |base_index| { | 4375 | .arr_elem, .field => |base_index| { |
| 4297 | const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, zcu)).toIntern(); | 4376 | const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, pt)).toIntern(); |
| 4298 | return if (resolved_base == base_index.base) | 4377 | return if (resolved_base == base_index.base) |
| 4299 | val | 4378 | val |
| 4300 | else | 4379 | else |
| 4301 | Value.fromInterned((try zcu.intern(.{ .ptr = .{ | 4380 | Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 4302 | .ty = ptr.ty, | 4381 | .ty = ptr.ty, |
| 4303 | .base_addr = switch (ptr.base_addr) { | 4382 | .base_addr = switch (ptr.base_addr) { |
| 4304 | .arr_elem => .{ .arr_elem = .{ | 4383 | .arr_elem => .{ .arr_elem = .{ |
| ... | @@ -4312,7 +4391,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value | ... | @@ -4312,7 +4391,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value |
| 4312 | else => unreachable, | 4391 | else => unreachable, |
| 4313 | }, | 4392 | }, |
| 4314 | .byte_offset = ptr.byte_offset, | 4393 | .byte_offset = ptr.byte_offset, |
| 4315 | } }))); | 4394 | } })); |
| 4316 | }, | 4395 | }, |
| 4317 | } | 4396 | } |
| 4318 | }, | 4397 | }, |
| ... | @@ -4321,40 +4400,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value | ... | @@ -4321,40 +4400,40 @@ pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value |
| 4321 | .elems => |elems| { | 4400 | .elems => |elems| { |
| 4322 | var resolved_elems: []InternPool.Index = &.{}; | 4401 | var resolved_elems: []InternPool.Index = &.{}; |
| 4323 | for (elems, 0..) |elem, i| { | 4402 | for (elems, 0..) |elem, i| { |
| 4324 | const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern(); | 4403 | const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern(); |
| 4325 | if (resolved_elems.len == 0 and resolved_elem != elem) { | 4404 | if (resolved_elems.len == 0 and resolved_elem != elem) { |
| 4326 | resolved_elems = try arena.alloc(InternPool.Index, elems.len); | 4405 | resolved_elems = try arena.alloc(InternPool.Index, elems.len); |
| 4327 | @memcpy(resolved_elems[0..i], elems[0..i]); | 4406 | @memcpy(resolved_elems[0..i], elems[0..i]); |
| 4328 | } | 4407 | } |
| 4329 | if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem; | 4408 | if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem; |
| 4330 | } | 4409 | } |
| 4331 | return if (resolved_elems.len == 0) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 4410 | return if (resolved_elems.len == 0) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 4332 | .ty = aggregate.ty, | 4411 | .ty = aggregate.ty, |
| 4333 | .storage = .{ .elems = resolved_elems }, | 4412 | .storage = .{ .elems = resolved_elems }, |
| 4334 | } }))); | 4413 | } })); |
| 4335 | }, | 4414 | }, |
| 4336 | .repeated_elem => |elem| { | 4415 | .repeated_elem => |elem| { |
| 4337 | const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern(); | 4416 | const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern(); |
| 4338 | return if (resolved_elem == elem) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{ | 4417 | return if (resolved_elem == elem) val else Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 4339 | .ty = aggregate.ty, | 4418 | .ty = aggregate.ty, |
| 4340 | .storage = .{ .repeated_elem = resolved_elem }, | 4419 | .storage = .{ .repeated_elem = resolved_elem }, |
| 4341 | } }))); | 4420 | } })); |
| 4342 | }, | 4421 | }, |
| 4343 | }, | 4422 | }, |
| 4344 | .un => |un| { | 4423 | .un => |un| { |
| 4345 | const resolved_tag = if (un.tag == .none) | 4424 | const resolved_tag = if (un.tag == .none) |
| 4346 | .none | 4425 | .none |
| 4347 | else | 4426 | else |
| 4348 | (try Value.fromInterned(un.tag).resolveLazy(arena, zcu)).toIntern(); | 4427 | (try Value.fromInterned(un.tag).resolveLazy(arena, pt)).toIntern(); |
| 4349 | const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, zcu)).toIntern(); | 4428 | const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, pt)).toIntern(); |
| 4350 | return if (resolved_tag == un.tag and resolved_val == un.val) | 4429 | return if (resolved_tag == un.tag and resolved_val == un.val) |
| 4351 | val | 4430 | val |
| 4352 | else | 4431 | else |
| 4353 | Value.fromInterned((try zcu.intern(.{ .un = .{ | 4432 | Value.fromInterned(try pt.intern(.{ .un = .{ |
| 4354 | .ty = un.ty, | 4433 | .ty = un.ty, |
| 4355 | .tag = resolved_tag, | 4434 | .tag = resolved_tag, |
| 4356 | .val = resolved_val, | 4435 | .val = resolved_val, |
| 4357 | } }))); | 4436 | } })); |
| 4358 | }, | 4437 | }, |
| 4359 | else => return val, | 4438 | else => return val, |
| 4360 | } | 4439 | } |
src/Zcu.zig+103-2161| ... | @@ -6,7 +6,6 @@ const std = @import("std"); | ... | @@ -6,7 +6,6 @@ const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | const mem = std.mem; | 7 | const mem = std.mem; |
| 8 | const Allocator = std.mem.Allocator; | 8 | const Allocator = std.mem.Allocator; |
| 9 | const ArrayListUnmanaged = std.ArrayListUnmanaged; | ||
| 10 | const assert = std.debug.assert; | 9 | const assert = std.debug.assert; |
| 11 | const log = std.log.scoped(.module); | 10 | const log = std.log.scoped(.module); |
| 12 | const BigIntConst = std.math.big.int.Const; | 11 | const BigIntConst = std.math.big.int.Const; |
| ... | @@ -75,10 +74,10 @@ local_zir_cache: Compilation.Directory, | ... | @@ -75,10 +74,10 @@ local_zir_cache: Compilation.Directory, |
| 75 | 74 | ||
| 76 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; | 75 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; |
| 77 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. | 76 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. |
| 78 | all_exports: ArrayListUnmanaged(Export) = .{}, | 77 | all_exports: std.ArrayListUnmanaged(Export) = .{}, |
| 79 | /// This is a list of free indices in `all_exports`. These indices may be reused by exports from | 78 | /// This is a list of free indices in `all_exports`. These indices may be reused by exports from |
| 80 | /// future semantic analysis. | 79 | /// future semantic analysis. |
| 81 | free_exports: ArrayListUnmanaged(u32) = .{}, | 80 | free_exports: std.ArrayListUnmanaged(u32) = .{}, |
| 82 | /// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of | 81 | /// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of |
| 83 | /// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit` | 82 | /// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit` |
| 84 | /// whose analysis triggered the export. | 83 | /// whose analysis triggered the export. |
| ... | @@ -179,7 +178,7 @@ stage1_flags: packed struct { | ... | @@ -179,7 +178,7 @@ stage1_flags: packed struct { |
| 179 | reserved: u2 = 0, | 178 | reserved: u2 = 0, |
| 180 | } = .{}, | 179 | } = .{}, |
| 181 | 180 | ||
| 182 | compile_log_text: ArrayListUnmanaged(u8) = .{}, | 181 | compile_log_text: std.ArrayListUnmanaged(u8) = .{}, |
| 183 | 182 | ||
| 184 | emit_h: ?*GlobalEmitH, | 183 | emit_h: ?*GlobalEmitH, |
| 185 | 184 | ||
| ... | @@ -203,6 +202,8 @@ panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len, | ... | @@ -203,6 +202,8 @@ panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len, |
| 203 | panic_func_index: InternPool.Index = .none, | 202 | panic_func_index: InternPool.Index = .none, |
| 204 | null_stack_trace: InternPool.Index = .none, | 203 | null_stack_trace: InternPool.Index = .none, |
| 205 | 204 | ||
| 205 | pub const PerThread = @import("Zcu/PerThread.zig"); | ||
| 206 | |||
| 206 | pub const PanicId = enum { | 207 | pub const PanicId = enum { |
| 207 | unreach, | 208 | unreach, |
| 208 | unwrap_null, | 209 | unwrap_null, |
| ... | @@ -519,24 +520,24 @@ pub const Decl = struct { | ... | @@ -519,24 +520,24 @@ pub const Decl = struct { |
| 519 | return decl.getExternDecl(zcu) != .none; | 520 | return decl.getExternDecl(zcu) != .none; |
| 520 | } | 521 | } |
| 521 | 522 | ||
| 522 | pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment { | 523 | pub fn getAlignment(decl: Decl, pt: Zcu.PerThread) Alignment { |
| 523 | assert(decl.has_tv); | 524 | assert(decl.has_tv); |
| 524 | if (decl.alignment != .none) return decl.alignment; | 525 | if (decl.alignment != .none) return decl.alignment; |
| 525 | return decl.typeOf(zcu).abiAlignment(zcu); | 526 | return decl.typeOf(pt.zcu).abiAlignment(pt); |
| 526 | } | 527 | } |
| 527 | 528 | ||
| 528 | pub fn declPtrType(decl: Decl, zcu: *Zcu) !Type { | 529 | pub fn declPtrType(decl: Decl, pt: Zcu.PerThread) !Type { |
| 529 | assert(decl.has_tv); | 530 | assert(decl.has_tv); |
| 530 | const decl_ty = decl.typeOf(zcu); | 531 | const decl_ty = decl.typeOf(pt.zcu); |
| 531 | return zcu.ptrType(.{ | 532 | return pt.ptrType(.{ |
| 532 | .child = decl_ty.toIntern(), | 533 | .child = decl_ty.toIntern(), |
| 533 | .flags = .{ | 534 | .flags = .{ |
| 534 | .alignment = if (decl.alignment == decl_ty.abiAlignment(zcu)) | 535 | .alignment = if (decl.alignment == decl_ty.abiAlignment(pt)) |
| 535 | .none | 536 | .none |
| 536 | else | 537 | else |
| 537 | decl.alignment, | 538 | decl.alignment, |
| 538 | .address_space = decl.@"addrspace", | 539 | .address_space = decl.@"addrspace", |
| 539 | .is_const = decl.getOwnedVariable(zcu) == null, | 540 | .is_const = decl.getOwnedVariable(pt.zcu) == null, |
| 540 | }, | 541 | }, |
| 541 | }); | 542 | }); |
| 542 | } | 543 | } |
| ... | @@ -589,7 +590,7 @@ pub const Decl = struct { | ... | @@ -589,7 +590,7 @@ pub const Decl = struct { |
| 589 | 590 | ||
| 590 | /// This state is attached to every Decl when Module emit_h is non-null. | 591 | /// This state is attached to every Decl when Module emit_h is non-null. |
| 591 | pub const EmitH = struct { | 592 | pub const EmitH = struct { |
| 592 | fwd_decl: ArrayListUnmanaged(u8) = .{}, | 593 | fwd_decl: std.ArrayListUnmanaged(u8) = .{}, |
| 593 | }; | 594 | }; |
| 594 | 595 | ||
| 595 | pub const DeclAdapter = struct { | 596 | pub const DeclAdapter = struct { |
| ... | @@ -622,8 +623,8 @@ pub const Namespace = struct { | ... | @@ -622,8 +623,8 @@ pub const Namespace = struct { |
| 622 | /// Value is whether the usingnamespace decl is marked `pub`. | 623 | /// Value is whether the usingnamespace decl is marked `pub`. |
| 623 | usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{}, | 624 | usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{}, |
| 624 | 625 | ||
| 625 | const Index = InternPool.NamespaceIndex; | 626 | pub const Index = InternPool.NamespaceIndex; |
| 626 | const OptionalIndex = InternPool.OptionalNamespaceIndex; | 627 | pub const OptionalIndex = InternPool.OptionalNamespaceIndex; |
| 627 | 628 | ||
| 628 | const DeclContext = struct { | 629 | const DeclContext = struct { |
| 629 | zcu: *Zcu, | 630 | zcu: *Zcu, |
| ... | @@ -3079,7 +3080,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void { | ... | @@ -3079,7 +3080,7 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 3079 | } | 3080 | } |
| 3080 | } | 3081 | } |
| 3081 | 3082 | ||
| 3082 | fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { | 3083 | pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 3083 | var it = zcu.intern_pool.dependencyIterator(dependee); | 3084 | var it = zcu.intern_pool.dependencyIterator(dependee); |
| 3084 | while (it.next()) |depender| { | 3085 | while (it.next()) |depender| { |
| 3085 | if (zcu.outdated.getPtr(depender)) |po_dep_count| { | 3086 | if (zcu.outdated.getPtr(depender)) |po_dep_count| { |
| ... | @@ -3279,7 +3280,7 @@ pub fn mapOldZirToNew( | ... | @@ -3279,7 +3280,7 @@ pub fn mapOldZirToNew( |
| 3279 | old_inst: Zir.Inst.Index, | 3280 | old_inst: Zir.Inst.Index, |
| 3280 | new_inst: Zir.Inst.Index, | 3281 | new_inst: Zir.Inst.Index, |
| 3281 | }; | 3282 | }; |
| 3282 | var match_stack: ArrayListUnmanaged(MatchedZirDecl) = .{}; | 3283 | var match_stack: std.ArrayListUnmanaged(MatchedZirDecl) = .{}; |
| 3283 | defer match_stack.deinit(gpa); | 3284 | defer match_stack.deinit(gpa); |
| 3284 | 3285 | ||
| 3285 | // Main struct inst is always matched | 3286 | // Main struct inst is always matched |
| ... | @@ -3394,357 +3395,6 @@ pub fn mapOldZirToNew( | ... | @@ -3394,357 +3395,6 @@ pub fn mapOldZirToNew( |
| 3394 | } | 3395 | } |
| 3395 | } | 3396 | } |
| 3396 | 3397 | ||
| 3397 | /// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl. | ||
| 3398 | pub fn ensureFileAnalyzed(zcu: *Zcu, file_index: File.Index) SemaError!void { | ||
| 3399 | if (zcu.fileRootDecl(file_index).unwrap()) |existing_root| { | ||
| 3400 | return zcu.ensureDeclAnalyzed(existing_root); | ||
| 3401 | } else { | ||
| 3402 | return zcu.semaFile(file_index); | ||
| 3403 | } | ||
| 3404 | } | ||
| 3405 | |||
| 3406 | /// This ensures that the Decl will have an up-to-date Type and Value populated. | ||
| 3407 | /// However the resolution status of the Type may not be fully resolved. | ||
| 3408 | /// For example an inferred error set is not resolved until after `analyzeFnBody`. | ||
| 3409 | /// is called. | ||
| 3410 | pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { | ||
| 3411 | const tracy = trace(@src()); | ||
| 3412 | defer tracy.end(); | ||
| 3413 | |||
| 3414 | const ip = &mod.intern_pool; | ||
| 3415 | const decl = mod.declPtr(decl_index); | ||
| 3416 | |||
| 3417 | log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{ | ||
| 3418 | @intFromEnum(decl_index), | ||
| 3419 | decl.name.fmt(ip), | ||
| 3420 | }); | ||
| 3421 | |||
| 3422 | // Determine whether or not this Decl is outdated, i.e. requires re-analysis | ||
| 3423 | // even if `complete`. If a Decl is PO, we pessismistically assume that it | ||
| 3424 | // *does* require re-analysis, to ensure that the Decl is definitely | ||
| 3425 | // up-to-date when this function returns. | ||
| 3426 | |||
| 3427 | // If analysis occurs in a poor order, this could result in over-analysis. | ||
| 3428 | // We do our best to avoid this by the other dependency logic in this file | ||
| 3429 | // which tries to limit re-analysis to Decls whose previously listed | ||
| 3430 | // dependencies are all up-to-date. | ||
| 3431 | |||
| 3432 | const decl_as_depender = AnalUnit.wrap(.{ .decl = decl_index }); | ||
| 3433 | const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or | ||
| 3434 | mod.potentially_outdated.swapRemove(decl_as_depender); | ||
| 3435 | |||
| 3436 | if (decl_was_outdated) { | ||
| 3437 | _ = mod.outdated_ready.swapRemove(decl_as_depender); | ||
| 3438 | } | ||
| 3439 | |||
| 3440 | const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated; | ||
| 3441 | |||
| 3442 | switch (decl.analysis) { | ||
| 3443 | .in_progress => unreachable, | ||
| 3444 | |||
| 3445 | .file_failure => return error.AnalysisFail, | ||
| 3446 | |||
| 3447 | .sema_failure, | ||
| 3448 | .dependency_failure, | ||
| 3449 | .codegen_failure, | ||
| 3450 | => if (!was_outdated) return error.AnalysisFail, | ||
| 3451 | |||
| 3452 | .complete => if (!was_outdated) return, | ||
| 3453 | |||
| 3454 | .unreferenced => {}, | ||
| 3455 | } | ||
| 3456 | |||
| 3457 | if (was_outdated) { | ||
| 3458 | // The exports this Decl performs will be re-discovered, so we remove them here | ||
| 3459 | // prior to re-analysis. | ||
| 3460 | if (build_options.only_c) unreachable; | ||
| 3461 | mod.deleteUnitExports(decl_as_depender); | ||
| 3462 | mod.deleteUnitReferences(decl_as_depender); | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | const sema_result: SemaDeclResult = blk: { | ||
| 3466 | if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) { | ||
| 3467 | // Anonymous decl. We don't semantically analyze these. | ||
| 3468 | break :blk .{ | ||
| 3469 | .invalidate_decl_val = false, | ||
| 3470 | .invalidate_decl_ref = false, | ||
| 3471 | }; | ||
| 3472 | } | ||
| 3473 | |||
| 3474 | if (mod.declIsRoot(decl_index)) { | ||
| 3475 | const changed = try mod.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated); | ||
| 3476 | break :blk .{ | ||
| 3477 | .invalidate_decl_val = changed, | ||
| 3478 | .invalidate_decl_ref = changed, | ||
| 3479 | }; | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0); | ||
| 3483 | defer decl_prog_node.end(); | ||
| 3484 | |||
| 3485 | break :blk mod.semaDecl(decl_index) catch |err| switch (err) { | ||
| 3486 | error.AnalysisFail => { | ||
| 3487 | if (decl.analysis == .in_progress) { | ||
| 3488 | // If this decl caused the compile error, the analysis field would | ||
| 3489 | // be changed to indicate it was this Decl's fault. Because this | ||
| 3490 | // did not happen, we infer here that it was a dependency failure. | ||
| 3491 | decl.analysis = .dependency_failure; | ||
| 3492 | } | ||
| 3493 | return error.AnalysisFail; | ||
| 3494 | }, | ||
| 3495 | error.GenericPoison => unreachable, | ||
| 3496 | else => |e| { | ||
| 3497 | decl.analysis = .sema_failure; | ||
| 3498 | try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1); | ||
| 3499 | try mod.retryable_failures.append(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 3500 | mod.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .decl = decl_index }), try ErrorMsg.create( | ||
| 3501 | mod.gpa, | ||
| 3502 | decl.navSrcLoc(mod), | ||
| 3503 | "unable to analyze: {s}", | ||
| 3504 | .{@errorName(e)}, | ||
| 3505 | )); | ||
| 3506 | return error.AnalysisFail; | ||
| 3507 | }, | ||
| 3508 | }; | ||
| 3509 | }; | ||
| 3510 | |||
| 3511 | // TODO: we do not yet have separate dependencies for decl values vs types. | ||
| 3512 | if (decl_was_outdated) { | ||
| 3513 | if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) { | ||
| 3514 | log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)}); | ||
| 3515 | // This dependency was marked as PO, meaning dependees were waiting | ||
| 3516 | // on its analysis result, and it has turned out to be outdated. | ||
| 3517 | // Update dependees accordingly. | ||
| 3518 | try mod.markDependeeOutdated(.{ .decl_val = decl_index }); | ||
| 3519 | } else { | ||
| 3520 | log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)}); | ||
| 3521 | // This dependency was previously PO, but turned out to be up-to-date. | ||
| 3522 | // We do not need to queue successive analysis. | ||
| 3523 | try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index }); | ||
| 3524 | } | ||
| 3525 | } | ||
| 3526 | } | ||
| 3527 | |||
| 3528 | pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.Index) SemaError!void { | ||
| 3529 | const tracy = trace(@src()); | ||
| 3530 | defer tracy.end(); | ||
| 3531 | |||
| 3532 | const gpa = zcu.gpa; | ||
| 3533 | const ip = &zcu.intern_pool; | ||
| 3534 | |||
| 3535 | // We only care about the uncoerced function. | ||
| 3536 | // We need to do this for the "orphaned function" check below to be valid. | ||
| 3537 | const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index); | ||
| 3538 | |||
| 3539 | const func = zcu.funcInfo(maybe_coerced_func_index); | ||
| 3540 | const decl_index = func.owner_decl; | ||
| 3541 | const decl = zcu.declPtr(decl_index); | ||
| 3542 | |||
| 3543 | log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{ | ||
| 3544 | @intFromEnum(func_index), | ||
| 3545 | decl.name.fmt(ip), | ||
| 3546 | }); | ||
| 3547 | |||
| 3548 | // First, our owner decl must be up-to-date. This will always be the case | ||
| 3549 | // during the first update, but may not on successive updates if we happen | ||
| 3550 | // to get analyzed before our parent decl. | ||
| 3551 | try zcu.ensureDeclAnalyzed(decl_index); | ||
| 3552 | |||
| 3553 | // On an update, it's possible this function changed such that our owner | ||
| 3554 | // decl now refers to a different function, making this one orphaned. If | ||
| 3555 | // that's the case, we should remove this function from the binary. | ||
| 3556 | if (decl.val.ip_index != func_index) { | ||
| 3557 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); | ||
| 3558 | ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .func = func_index })); | ||
| 3559 | ip.remove(func_index); | ||
| 3560 | @panic("TODO: remove orphaned function from binary"); | ||
| 3561 | } | ||
| 3562 | |||
| 3563 | // We'll want to remember what the IES used to be before the update for | ||
| 3564 | // dependency invalidation purposes. | ||
| 3565 | const old_resolved_ies = if (func.analysis(ip).inferred_error_set) | ||
| 3566 | func.resolvedErrorSet(ip).* | ||
| 3567 | else | ||
| 3568 | .none; | ||
| 3569 | |||
| 3570 | switch (decl.analysis) { | ||
| 3571 | .unreferenced => unreachable, | ||
| 3572 | .in_progress => unreachable, | ||
| 3573 | |||
| 3574 | .codegen_failure => unreachable, // functions do not perform constant value generation | ||
| 3575 | |||
| 3576 | .file_failure, | ||
| 3577 | .sema_failure, | ||
| 3578 | .dependency_failure, | ||
| 3579 | => return error.AnalysisFail, | ||
| 3580 | |||
| 3581 | .complete => {}, | ||
| 3582 | } | ||
| 3583 | |||
| 3584 | const func_as_depender = AnalUnit.wrap(.{ .func = func_index }); | ||
| 3585 | const was_outdated = zcu.outdated.swapRemove(func_as_depender) or | ||
| 3586 | zcu.potentially_outdated.swapRemove(func_as_depender); | ||
| 3587 | |||
| 3588 | if (was_outdated) { | ||
| 3589 | if (build_options.only_c) unreachable; | ||
| 3590 | _ = zcu.outdated_ready.swapRemove(func_as_depender); | ||
| 3591 | zcu.deleteUnitExports(func_as_depender); | ||
| 3592 | zcu.deleteUnitReferences(func_as_depender); | ||
| 3593 | } | ||
| 3594 | |||
| 3595 | switch (func.analysis(ip).state) { | ||
| 3596 | .success => if (!was_outdated) return, | ||
| 3597 | .sema_failure, | ||
| 3598 | .dependency_failure, | ||
| 3599 | .codegen_failure, | ||
| 3600 | => if (!was_outdated) return error.AnalysisFail, | ||
| 3601 | .none, .queued => {}, | ||
| 3602 | .in_progress => unreachable, | ||
| 3603 | .inline_only => unreachable, // don't queue work for this | ||
| 3604 | } | ||
| 3605 | |||
| 3606 | log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{ | ||
| 3607 | @intFromEnum(func_index), | ||
| 3608 | if (was_outdated) "outdated" else "never analyzed", | ||
| 3609 | }); | ||
| 3610 | |||
| 3611 | var tmp_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 3612 | defer tmp_arena.deinit(); | ||
| 3613 | const sema_arena = tmp_arena.allocator(); | ||
| 3614 | |||
| 3615 | var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) { | ||
| 3616 | error.AnalysisFail => { | ||
| 3617 | if (func.analysis(ip).state == .in_progress) { | ||
| 3618 | // If this decl caused the compile error, the analysis field would | ||
| 3619 | // be changed to indicate it was this Decl's fault. Because this | ||
| 3620 | // did not happen, we infer here that it was a dependency failure. | ||
| 3621 | func.analysis(ip).state = .dependency_failure; | ||
| 3622 | } | ||
| 3623 | return error.AnalysisFail; | ||
| 3624 | }, | ||
| 3625 | error.OutOfMemory => return error.OutOfMemory, | ||
| 3626 | }; | ||
| 3627 | errdefer air.deinit(gpa); | ||
| 3628 | |||
| 3629 | const invalidate_ies_deps = i: { | ||
| 3630 | if (!was_outdated) break :i false; | ||
| 3631 | if (!func.analysis(ip).inferred_error_set) break :i true; | ||
| 3632 | const new_resolved_ies = func.resolvedErrorSet(ip).*; | ||
| 3633 | break :i new_resolved_ies != old_resolved_ies; | ||
| 3634 | }; | ||
| 3635 | if (invalidate_ies_deps) { | ||
| 3636 | log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)}); | ||
| 3637 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); | ||
| 3638 | } else if (was_outdated) { | ||
| 3639 | log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)}); | ||
| 3640 | try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }); | ||
| 3641 | } | ||
| 3642 | |||
| 3643 | const comp = zcu.comp; | ||
| 3644 | |||
| 3645 | const dump_air = build_options.enable_debug_extensions and comp.verbose_air; | ||
| 3646 | const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null); | ||
| 3647 | |||
| 3648 | if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) { | ||
| 3649 | air.deinit(gpa); | ||
| 3650 | return; | ||
| 3651 | } | ||
| 3652 | |||
| 3653 | try comp.work_queue.writeItem(.{ .codegen_func = .{ | ||
| 3654 | .func = func_index, | ||
| 3655 | .air = air, | ||
| 3656 | } }); | ||
| 3657 | } | ||
| 3658 | |||
| 3659 | /// Takes ownership of `air`, even on error. | ||
| 3660 | /// If any types referenced by `air` are unresolved, marks the codegen as failed. | ||
| 3661 | pub fn linkerUpdateFunc(zcu: *Zcu, func_index: InternPool.Index, air: Air) Allocator.Error!void { | ||
| 3662 | const gpa = zcu.gpa; | ||
| 3663 | const ip = &zcu.intern_pool; | ||
| 3664 | const comp = zcu.comp; | ||
| 3665 | |||
| 3666 | defer { | ||
| 3667 | var air_mut = air; | ||
| 3668 | air_mut.deinit(gpa); | ||
| 3669 | } | ||
| 3670 | |||
| 3671 | const func = zcu.funcInfo(func_index); | ||
| 3672 | const decl_index = func.owner_decl; | ||
| 3673 | const decl = zcu.declPtr(decl_index); | ||
| 3674 | |||
| 3675 | var liveness = try Liveness.analyze(gpa, air, ip); | ||
| 3676 | defer liveness.deinit(gpa); | ||
| 3677 | |||
| 3678 | if (build_options.enable_debug_extensions and comp.verbose_air) { | ||
| 3679 | const fqn = try decl.fullyQualifiedName(zcu); | ||
| 3680 | std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)}); | ||
| 3681 | @import("print_air.zig").dump(zcu, air, liveness); | ||
| 3682 | std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)}); | ||
| 3683 | } | ||
| 3684 | |||
| 3685 | if (std.debug.runtime_safety) { | ||
| 3686 | var verify: Liveness.Verify = .{ | ||
| 3687 | .gpa = gpa, | ||
| 3688 | .air = air, | ||
| 3689 | .liveness = liveness, | ||
| 3690 | .intern_pool = ip, | ||
| 3691 | }; | ||
| 3692 | defer verify.deinit(); | ||
| 3693 | |||
| 3694 | verify.verify() catch |err| switch (err) { | ||
| 3695 | error.OutOfMemory => return error.OutOfMemory, | ||
| 3696 | else => { | ||
| 3697 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 3698 | zcu.failed_analysis.putAssumeCapacityNoClobber( | ||
| 3699 | AnalUnit.wrap(.{ .func = func_index }), | ||
| 3700 | try Module.ErrorMsg.create( | ||
| 3701 | gpa, | ||
| 3702 | decl.navSrcLoc(zcu), | ||
| 3703 | "invalid liveness: {s}", | ||
| 3704 | .{@errorName(err)}, | ||
| 3705 | ), | ||
| 3706 | ); | ||
| 3707 | func.analysis(ip).state = .codegen_failure; | ||
| 3708 | return; | ||
| 3709 | }, | ||
| 3710 | }; | ||
| 3711 | } | ||
| 3712 | |||
| 3713 | const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0); | ||
| 3714 | defer codegen_prog_node.end(); | ||
| 3715 | |||
| 3716 | if (!air.typesFullyResolved(zcu)) { | ||
| 3717 | // A type we depend on failed to resolve. This is a transitive failure. | ||
| 3718 | // Correcting this failure will involve changing a type this function | ||
| 3719 | // depends on, hence triggering re-analysis of this function, so this | ||
| 3720 | // interacts correctly with incremental compilation. | ||
| 3721 | func.analysis(ip).state = .codegen_failure; | ||
| 3722 | } else if (comp.bin_file) |lf| { | ||
| 3723 | lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) { | ||
| 3724 | error.OutOfMemory => return error.OutOfMemory, | ||
| 3725 | error.AnalysisFail => { | ||
| 3726 | func.analysis(ip).state = .codegen_failure; | ||
| 3727 | }, | ||
| 3728 | else => { | ||
| 3729 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 3730 | zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .func = func_index }), try Module.ErrorMsg.create( | ||
| 3731 | gpa, | ||
| 3732 | decl.navSrcLoc(zcu), | ||
| 3733 | "unable to codegen: {s}", | ||
| 3734 | .{@errorName(err)}, | ||
| 3735 | )); | ||
| 3736 | func.analysis(ip).state = .codegen_failure; | ||
| 3737 | try zcu.retryable_failures.append(zcu.gpa, AnalUnit.wrap(.{ .func = func_index })); | ||
| 3738 | }, | ||
| 3739 | }; | ||
| 3740 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 3741 | if (build_options.only_c) unreachable; | ||
| 3742 | llvm_object.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) { | ||
| 3743 | error.OutOfMemory => return error.OutOfMemory, | ||
| 3744 | }; | ||
| 3745 | } | ||
| 3746 | } | ||
| 3747 | |||
| 3748 | /// Ensure this function's body is or will be analyzed and emitted. This should | 3398 | /// Ensure this function's body is or will be analyzed and emitted. This should |
| 3749 | /// be called whenever a potential runtime call of a function is seen. | 3399 | /// be called whenever a potential runtime call of a function is seen. |
| 3750 | /// | 3400 | /// |
| ... | @@ -3804,608 +3454,105 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) | ... | @@ -3804,608 +3454,105 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) |
| 3804 | func.analysis(ip).state = .queued; | 3454 | func.analysis(ip).state = .queued; |
| 3805 | } | 3455 | } |
| 3806 | 3456 | ||
| 3807 | pub fn semaPkg(zcu: *Zcu, pkg: *Package.Module) !void { | 3457 | pub const SemaDeclResult = packed struct { |
| 3808 | const import_file_result = try zcu.importPkg(pkg); | 3458 | /// Whether the value of a `decl_val` of this Decl changed. |
| 3809 | const root_decl_index = zcu.fileRootDecl(import_file_result.file_index); | 3459 | invalidate_decl_val: bool, |
| 3810 | if (root_decl_index == .none) { | 3460 | /// Whether the type of a `decl_ref` of this Decl changed. |
| 3811 | return zcu.semaFile(import_file_result.file_index); | 3461 | invalidate_decl_ref: bool, |
| 3812 | } | 3462 | }; |
| 3813 | } | ||
| 3814 | |||
| 3815 | fn getFileRootStruct( | ||
| 3816 | zcu: *Zcu, | ||
| 3817 | decl_index: Decl.Index, | ||
| 3818 | namespace_index: Namespace.Index, | ||
| 3819 | file_index: File.Index, | ||
| 3820 | ) Allocator.Error!InternPool.Index { | ||
| 3821 | const gpa = zcu.gpa; | ||
| 3822 | const ip = &zcu.intern_pool; | ||
| 3823 | const file = zcu.fileByIndex(file_index); | ||
| 3824 | const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended; | ||
| 3825 | assert(extended.opcode == .struct_decl); | ||
| 3826 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | ||
| 3827 | assert(!small.has_captures_len); | ||
| 3828 | assert(!small.has_backing_int); | ||
| 3829 | assert(small.layout == .auto); | ||
| 3830 | var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len; | ||
| 3831 | const fields_len = if (small.has_fields_len) blk: { | ||
| 3832 | const fields_len = file.zir.extra[extra_index]; | ||
| 3833 | extra_index += 1; | ||
| 3834 | break :blk fields_len; | ||
| 3835 | } else 0; | ||
| 3836 | const decls_len = if (small.has_decls_len) blk: { | ||
| 3837 | const decls_len = file.zir.extra[extra_index]; | ||
| 3838 | extra_index += 1; | ||
| 3839 | break :blk decls_len; | ||
| 3840 | } else 0; | ||
| 3841 | const decls = file.zir.bodySlice(extra_index, decls_len); | ||
| 3842 | extra_index += decls_len; | ||
| 3843 | |||
| 3844 | const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst); | ||
| 3845 | const wip_ty = switch (try ip.getStructType(gpa, .{ | ||
| 3846 | .layout = .auto, | ||
| 3847 | .fields_len = fields_len, | ||
| 3848 | .known_non_opv = small.known_non_opv, | ||
| 3849 | .requires_comptime = if (small.known_comptime_only) .yes else .unknown, | ||
| 3850 | .is_tuple = small.is_tuple, | ||
| 3851 | .any_comptime_fields = small.any_comptime_fields, | ||
| 3852 | .any_default_inits = small.any_default_inits, | ||
| 3853 | .inits_resolved = false, | ||
| 3854 | .any_aligned_fields = small.any_aligned_fields, | ||
| 3855 | .has_namespace = true, | ||
| 3856 | .key = .{ .declared = .{ | ||
| 3857 | .zir_index = tracked_inst, | ||
| 3858 | .captures = &.{}, | ||
| 3859 | } }, | ||
| 3860 | })) { | ||
| 3861 | .existing => unreachable, // we wouldn't be analysing the file root if this type existed | ||
| 3862 | .wip => |wip| wip, | ||
| 3863 | }; | ||
| 3864 | errdefer wip_ty.cancel(ip); | ||
| 3865 | |||
| 3866 | if (zcu.comp.debug_incremental) { | ||
| 3867 | try ip.addDependency( | ||
| 3868 | gpa, | ||
| 3869 | AnalUnit.wrap(.{ .decl = decl_index }), | ||
| 3870 | .{ .src_hash = tracked_inst }, | ||
| 3871 | ); | ||
| 3872 | } | ||
| 3873 | 3463 | ||
| 3464 | pub fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { | ||
| 3874 | const decl = zcu.declPtr(decl_index); | 3465 | const decl = zcu.declPtr(decl_index); |
| 3875 | decl.val = Value.fromInterned(wip_ty.index); | ||
| 3876 | decl.has_tv = true; | ||
| 3877 | decl.owns_tv = true; | ||
| 3878 | decl.analysis = .complete; | ||
| 3879 | |||
| 3880 | try zcu.scanNamespace(namespace_index, decls, decl); | ||
| 3881 | try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | ||
| 3882 | return wip_ty.finish(ip, decl_index, namespace_index.toOptional()); | ||
| 3883 | } | ||
| 3884 | |||
| 3885 | /// Re-analyze the root Decl of a file on an incremental update. | ||
| 3886 | /// If `type_outdated`, the struct type itself is considered outdated and is | ||
| 3887 | /// reconstructed at a new InternPool index. Otherwise, the namespace is just | ||
| 3888 | /// re-analyzed. Returns whether the decl's tyval was invalidated. | ||
| 3889 | fn semaFileUpdate(zcu: *Zcu, file_index: File.Index, type_outdated: bool) SemaError!bool { | ||
| 3890 | const file = zcu.fileByIndex(file_index); | ||
| 3891 | const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?); | ||
| 3892 | |||
| 3893 | log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{ | ||
| 3894 | file.mod.fully_qualified_name, | ||
| 3895 | file.sub_file_path, | ||
| 3896 | type_outdated, | ||
| 3897 | }); | ||
| 3898 | |||
| 3899 | if (file.status != .success_zir) { | ||
| 3900 | if (decl.analysis == .file_failure) { | ||
| 3901 | return false; | ||
| 3902 | } else { | ||
| 3903 | decl.analysis = .file_failure; | ||
| 3904 | return true; | ||
| 3905 | } | ||
| 3906 | } | ||
| 3907 | |||
| 3908 | if (decl.analysis == .file_failure) { | ||
| 3909 | // No struct type currently exists. Create one! | ||
| 3910 | const root_decl = zcu.fileRootDecl(file_index); | ||
| 3911 | _ = try zcu.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index); | ||
| 3912 | return true; | ||
| 3913 | } | ||
| 3914 | 3466 | ||
| 3915 | assert(decl.has_tv); | 3467 | assert(decl.has_tv); |
| 3916 | assert(decl.owns_tv); | 3468 | assert(decl.owns_tv); |
| 3917 | 3469 | ||
| 3918 | if (type_outdated) { | 3470 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); |
| 3919 | // Invalidate the existing type, reusing the decl and namespace. | ||
| 3920 | const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?; | ||
| 3921 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ | ||
| 3922 | .decl = file_root_decl, | ||
| 3923 | })); | ||
| 3924 | zcu.intern_pool.remove(decl.val.toIntern()); | ||
| 3925 | decl.val = undefined; | ||
| 3926 | _ = try zcu.getFileRootStruct(file_root_decl, decl.src_namespace, file_index); | ||
| 3927 | return true; | ||
| 3928 | } | ||
| 3929 | |||
| 3930 | // Only the struct's namespace is outdated. | ||
| 3931 | // Preserve the type - just scan the namespace again. | ||
| 3932 | |||
| 3933 | const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended; | ||
| 3934 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | ||
| 3935 | |||
| 3936 | var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len; | ||
| 3937 | extra_index += @intFromBool(small.has_fields_len); | ||
| 3938 | const decls_len = if (small.has_decls_len) blk: { | ||
| 3939 | const decls_len = file.zir.extra[extra_index]; | ||
| 3940 | extra_index += 1; | ||
| 3941 | break :blk decls_len; | ||
| 3942 | } else 0; | ||
| 3943 | const decls = file.zir.bodySlice(extra_index, decls_len); | ||
| 3944 | 3471 | ||
| 3945 | if (!type_outdated) { | 3472 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { |
| 3946 | try zcu.scanNamespace(decl.src_namespace, decls, decl); | 3473 | .Fn => @panic("TODO: update fn instance"), |
| 3474 | .Type => {}, | ||
| 3475 | else => unreachable, | ||
| 3947 | } | 3476 | } |
| 3948 | 3477 | ||
| 3949 | return false; | 3478 | // We are the owner Decl of a type, and we were marked as outdated. That means the *structure* |
| 3479 | // of this type changed; not just its namespace. Therefore, we need a new InternPool index. | ||
| 3480 | // | ||
| 3481 | // However, as soon as we make that, the context that created us will require re-analysis anyway | ||
| 3482 | // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction | ||
| 3483 | // will be analyzed again. Since Sema already needs to be able to reconstruct types like this, | ||
| 3484 | // why should we bother implementing it here too when the Sema logic will be hit right after? | ||
| 3485 | // | ||
| 3486 | // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely | ||
| 3487 | // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type | ||
| 3488 | // with a new Decl. | ||
| 3489 | // | ||
| 3490 | // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime. | ||
| 3491 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 3492 | zcu.intern_pool.remove(decl.val.toIntern()); | ||
| 3493 | decl.analysis = .dependency_failure; | ||
| 3494 | return .{ | ||
| 3495 | .invalidate_decl_val = true, | ||
| 3496 | .invalidate_decl_ref = true, | ||
| 3497 | }; | ||
| 3950 | } | 3498 | } |
| 3951 | 3499 | ||
| 3952 | /// Regardless of the file status, will create a `Decl` if none exists so that we can track | 3500 | pub const ImportFileResult = struct { |
| 3953 | /// dependencies and re-analyze when the file becomes outdated. | 3501 | file: *File, |
| 3954 | fn semaFile(zcu: *Zcu, file_index: File.Index) SemaError!void { | 3502 | file_index: File.Index, |
| 3955 | const tracy = trace(@src()); | 3503 | is_new: bool, |
| 3956 | defer tracy.end(); | 3504 | is_pkg: bool, |
| 3957 | 3505 | }; | |
| 3958 | const file = zcu.fileByIndex(file_index); | ||
| 3959 | assert(zcu.fileRootDecl(file_index) == .none); | ||
| 3960 | 3506 | ||
| 3507 | pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { | ||
| 3961 | const gpa = zcu.gpa; | 3508 | const gpa = zcu.gpa; |
| 3962 | log.debug("semaFile zcu={s} sub_file_path={s}", .{ | ||
| 3963 | file.mod.fully_qualified_name, file.sub_file_path, | ||
| 3964 | }); | ||
| 3965 | 3509 | ||
| 3966 | // Because these three things each reference each other, `undefined` | 3510 | // The resolved path is used as the key in the import table, to detect if |
| 3967 | // placeholders are used before being set after the struct type gains an | 3511 | // an import refers to the same as another, despite different relative paths |
| 3968 | // InternPool index. | 3512 | // or differently mapped package names. |
| 3969 | const new_namespace_index = try zcu.createNamespace(.{ | 3513 | const resolved_path = try std.fs.path.resolve(gpa, &.{ |
| 3970 | .parent = .none, | 3514 | mod.root.root_dir.path orelse ".", |
| 3971 | .decl_index = undefined, | 3515 | mod.root.sub_path, |
| 3972 | .file_scope = file_index, | 3516 | mod.root_src_path, |
| 3973 | }); | 3517 | }); |
| 3974 | errdefer zcu.destroyNamespace(new_namespace_index); | 3518 | var keep_resolved_path = false; |
| 3519 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 3975 | 3520 | ||
| 3976 | const new_decl_index = try zcu.allocateNewDecl(new_namespace_index); | 3521 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); |
| 3977 | const new_decl = zcu.declPtr(new_decl_index); | 3522 | errdefer _ = zcu.import_table.pop(); |
| 3978 | errdefer @panic("TODO error handling"); | 3523 | if (gop.found_existing) { |
| 3524 | try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod }); | ||
| 3525 | return .{ | ||
| 3526 | .file = gop.value_ptr.*, | ||
| 3527 | .file_index = @enumFromInt(gop.index), | ||
| 3528 | .is_new = false, | ||
| 3529 | .is_pkg = true, | ||
| 3530 | }; | ||
| 3531 | } | ||
| 3979 | 3532 | ||
| 3980 | zcu.setFileRootDecl(file_index, new_decl_index.toOptional()); | 3533 | const ip = &zcu.intern_pool; |
| 3981 | zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index; | ||
| 3982 | 3534 | ||
| 3983 | new_decl.name = try file.fullyQualifiedName(zcu); | 3535 | try ip.files.ensureUnusedCapacity(gpa, 1); |
| 3984 | new_decl.name_fully_qualified = true; | ||
| 3985 | new_decl.is_pub = true; | ||
| 3986 | new_decl.is_exported = false; | ||
| 3987 | new_decl.alignment = .none; | ||
| 3988 | new_decl.@"linksection" = .none; | ||
| 3989 | new_decl.analysis = .in_progress; | ||
| 3990 | 3536 | ||
| 3991 | if (file.status != .success_zir) { | 3537 | if (mod.builtin_file) |builtin_file| { |
| 3992 | new_decl.analysis = .file_failure; | 3538 | keep_resolved_path = true; // It's now owned by import_table. |
| 3993 | return; | 3539 | gop.value_ptr.* = builtin_file; |
| 3540 | try builtin_file.addReference(zcu.*, .{ .root = mod }); | ||
| 3541 | const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path); | ||
| 3542 | ip.files.putAssumeCapacityNoClobber(path_digest, .none); | ||
| 3543 | return .{ | ||
| 3544 | .file = builtin_file, | ||
| 3545 | .file_index = @enumFromInt(ip.files.entries.len - 1), | ||
| 3546 | .is_new = false, | ||
| 3547 | .is_pkg = true, | ||
| 3548 | }; | ||
| 3994 | } | 3549 | } |
| 3995 | assert(file.zir_loaded); | ||
| 3996 | 3550 | ||
| 3997 | const struct_ty = try zcu.getFileRootStruct(new_decl_index, new_namespace_index, file_index); | 3551 | const sub_file_path = try gpa.dupe(u8, mod.root_src_path); |
| 3998 | errdefer zcu.intern_pool.remove(struct_ty); | 3552 | errdefer gpa.free(sub_file_path); |
| 3999 | 3553 | ||
| 4000 | switch (zcu.comp.cache_use) { | 3554 | const new_file = try gpa.create(File); |
| 4001 | .whole => |whole| if (whole.cache_manifest) |man| { | 3555 | errdefer gpa.destroy(new_file); |
| 4002 | const source = file.getSource(gpa) catch |err| { | ||
| 4003 | try reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)}); | ||
| 4004 | return error.AnalysisFail; | ||
| 4005 | }; | ||
| 4006 | |||
| 4007 | const resolved_path = std.fs.path.resolve(gpa, &.{ | ||
| 4008 | file.mod.root.root_dir.path orelse ".", | ||
| 4009 | file.mod.root.sub_path, | ||
| 4010 | file.sub_file_path, | ||
| 4011 | }) catch |err| { | ||
| 4012 | try reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)}); | ||
| 4013 | return error.AnalysisFail; | ||
| 4014 | }; | ||
| 4015 | errdefer gpa.free(resolved_path); | ||
| 4016 | |||
| 4017 | whole.cache_manifest_mutex.lock(); | ||
| 4018 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4019 | try man.addFilePostContents(resolved_path, source.bytes, source.stat); | ||
| 4020 | }, | ||
| 4021 | .incremental => {}, | ||
| 4022 | } | ||
| 4023 | } | ||
| 4024 | |||
| 4025 | const SemaDeclResult = packed struct { | ||
| 4026 | /// Whether the value of a `decl_val` of this Decl changed. | ||
| 4027 | invalidate_decl_val: bool, | ||
| 4028 | /// Whether the type of a `decl_ref` of this Decl changed. | ||
| 4029 | invalidate_decl_ref: bool, | ||
| 4030 | }; | ||
| 4031 | |||
| 4032 | fn semaDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { | ||
| 4033 | const tracy = trace(@src()); | ||
| 4034 | defer tracy.end(); | ||
| 4035 | |||
| 4036 | const decl = zcu.declPtr(decl_index); | ||
| 4037 | const ip = &zcu.intern_pool; | ||
| 4038 | |||
| 4039 | if (decl.getFileScope(zcu).status != .success_zir) { | ||
| 4040 | return error.AnalysisFail; | ||
| 4041 | } | ||
| 4042 | |||
| 4043 | assert(!zcu.declIsRoot(decl_index)); | ||
| 4044 | |||
| 4045 | if (decl.zir_decl_index == .none and decl.owns_tv) { | ||
| 4046 | // We are re-analyzing an anonymous owner Decl (for a function or a namespace type). | ||
| 4047 | return zcu.semaAnonOwnerDecl(decl_index); | ||
| 4048 | } | ||
| 4049 | |||
| 4050 | log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)}); | ||
| 4051 | log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)}); | ||
| 4052 | defer blk: { | ||
| 4053 | log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)}); | ||
| 4054 | } | ||
| 4055 | |||
| 4056 | const old_has_tv = decl.has_tv; | ||
| 4057 | // The following values are ignored if `!old_has_tv` | ||
| 4058 | const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined; | ||
| 4059 | const old_val = decl.val; | ||
| 4060 | const old_align = decl.alignment; | ||
| 4061 | const old_linksection = decl.@"linksection"; | ||
| 4062 | const old_addrspace = decl.@"addrspace"; | ||
| 4063 | const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func| | ||
| 4064 | prev_func.analysis(ip).state == .inline_only | ||
| 4065 | else | ||
| 4066 | false; | ||
| 4067 | |||
| 4068 | const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip); | ||
| 4069 | |||
| 4070 | const gpa = zcu.gpa; | ||
| 4071 | const zir = decl.getFileScope(zcu).zir; | ||
| 4072 | |||
| 4073 | const builtin_type_target_index: InternPool.Index = ip_index: { | ||
| 4074 | const std_mod = zcu.std_mod; | ||
| 4075 | if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none; | ||
| 4076 | // We're in the std module. | ||
| 4077 | const std_file_imported = try zcu.importPkg(std_mod); | ||
| 4078 | const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index); | ||
| 4079 | const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?); | ||
| 4080 | const std_namespace = std_decl.getInnerNamespace(zcu).?; | ||
| 4081 | const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); | ||
| 4082 | const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none); | ||
| 4083 | const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none; | ||
| 4084 | if (decl.src_namespace != builtin_namespace) break :ip_index .none; | ||
| 4085 | // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. | ||
| 4086 | for ([_][]const u8{ | ||
| 4087 | "AtomicOrder", | ||
| 4088 | "AtomicRmwOp", | ||
| 4089 | "CallingConvention", | ||
| 4090 | "AddressSpace", | ||
| 4091 | "FloatMode", | ||
| 4092 | "ReduceOp", | ||
| 4093 | "CallModifier", | ||
| 4094 | "PrefetchOptions", | ||
| 4095 | "ExportOptions", | ||
| 4096 | "ExternOptions", | ||
| 4097 | "Type", | ||
| 4098 | }, [_]InternPool.Index{ | ||
| 4099 | .atomic_order_type, | ||
| 4100 | .atomic_rmw_op_type, | ||
| 4101 | .calling_convention_type, | ||
| 4102 | .address_space_type, | ||
| 4103 | .float_mode_type, | ||
| 4104 | .reduce_op_type, | ||
| 4105 | .call_modifier_type, | ||
| 4106 | .prefetch_options_type, | ||
| 4107 | .export_options_type, | ||
| 4108 | .extern_options_type, | ||
| 4109 | .type_info_type, | ||
| 4110 | }) |type_name, type_ip| { | ||
| 4111 | if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip; | ||
| 4112 | } | ||
| 4113 | break :ip_index .none; | ||
| 4114 | }; | ||
| 4115 | |||
| 4116 | zcu.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 4117 | |||
| 4118 | decl.analysis = .in_progress; | ||
| 4119 | |||
| 4120 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 4121 | defer analysis_arena.deinit(); | ||
| 4122 | |||
| 4123 | var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa); | ||
| 4124 | defer comptime_err_ret_trace.deinit(); | ||
| 4125 | |||
| 4126 | var sema: Sema = .{ | ||
| 4127 | .mod = zcu, | ||
| 4128 | .gpa = gpa, | ||
| 4129 | .arena = analysis_arena.allocator(), | ||
| 4130 | .code = zir, | ||
| 4131 | .owner_decl = decl, | ||
| 4132 | .owner_decl_index = decl_index, | ||
| 4133 | .func_index = .none, | ||
| 4134 | .func_is_naked = false, | ||
| 4135 | .fn_ret_ty = Type.void, | ||
| 4136 | .fn_ret_ty_ies = null, | ||
| 4137 | .owner_func_index = .none, | ||
| 4138 | .comptime_err_ret_trace = &comptime_err_ret_trace, | ||
| 4139 | .builtin_type_target_index = builtin_type_target_index, | ||
| 4140 | }; | ||
| 4141 | defer sema.deinit(); | ||
| 4142 | |||
| 4143 | // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source. | ||
| 4144 | try sema.declareDependency(.{ .src_hash = try ip.trackZir( | ||
| 4145 | gpa, | ||
| 4146 | decl.getFileScopeIndex(zcu), | ||
| 4147 | decl_inst, | ||
| 4148 | ) }); | ||
| 4149 | |||
| 4150 | var block_scope: Sema.Block = .{ | ||
| 4151 | .parent = null, | ||
| 4152 | .sema = &sema, | ||
| 4153 | .namespace = decl.src_namespace, | ||
| 4154 | .instructions = .{}, | ||
| 4155 | .inlining = null, | ||
| 4156 | .is_comptime = true, | ||
| 4157 | .src_base_inst = decl.zir_decl_index.unwrap().?, | ||
| 4158 | .type_name_ctx = decl.name, | ||
| 4159 | }; | ||
| 4160 | defer block_scope.instructions.deinit(gpa); | ||
| 4161 | |||
| 4162 | const decl_bodies = decl.zirBodies(zcu); | ||
| 4163 | |||
| 4164 | const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst); | ||
| 4165 | // We'll do some other bits with the Sema. Clear the type target index just | ||
| 4166 | // in case they analyze any type. | ||
| 4167 | sema.builtin_type_target_index = .none; | ||
| 4168 | const align_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_align = 0 }); | ||
| 4169 | const section_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_section = 0 }); | ||
| 4170 | const address_space_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 }); | ||
| 4171 | const ty_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_ty = 0 }); | ||
| 4172 | const init_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_init = 0 }); | ||
| 4173 | const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); | ||
| 4174 | const decl_ty = decl_val.typeOf(zcu); | ||
| 4175 | |||
| 4176 | // Note this resolves the type of the Decl, not the value; if this Decl | ||
| 4177 | // is a struct, for example, this resolves `type` (which needs no resolution), | ||
| 4178 | // not the struct itself. | ||
| 4179 | try decl_ty.resolveLayout(zcu); | ||
| 4180 | |||
| 4181 | if (decl.kind == .@"usingnamespace") { | ||
| 4182 | if (!decl_ty.eql(Type.type, zcu)) { | ||
| 4183 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{ | ||
| 4184 | decl_ty.fmt(zcu), | ||
| 4185 | }); | ||
| 4186 | } | ||
| 4187 | const ty = decl_val.toType(); | ||
| 4188 | if (ty.getNamespace(zcu) == null) { | ||
| 4189 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(zcu)}); | ||
| 4190 | } | ||
| 4191 | |||
| 4192 | decl.val = ty.toValue(); | ||
| 4193 | decl.alignment = .none; | ||
| 4194 | decl.@"linksection" = .none; | ||
| 4195 | decl.has_tv = true; | ||
| 4196 | decl.owns_tv = false; | ||
| 4197 | decl.analysis = .complete; | ||
| 4198 | |||
| 4199 | // TODO: usingnamespace cannot currently participate in incremental compilation | ||
| 4200 | return .{ | ||
| 4201 | .invalidate_decl_val = true, | ||
| 4202 | .invalidate_decl_ref = true, | ||
| 4203 | }; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | var queue_linker_work = true; | ||
| 4207 | var is_func = false; | ||
| 4208 | var is_inline = false; | ||
| 4209 | switch (decl_val.toIntern()) { | ||
| 4210 | .generic_poison => unreachable, | ||
| 4211 | .unreachable_value => unreachable, | ||
| 4212 | else => switch (ip.indexToKey(decl_val.toIntern())) { | ||
| 4213 | .variable => |variable| { | ||
| 4214 | decl.owns_tv = variable.decl == decl_index; | ||
| 4215 | queue_linker_work = decl.owns_tv; | ||
| 4216 | }, | ||
| 4217 | |||
| 4218 | .extern_func => |extern_func| { | ||
| 4219 | decl.owns_tv = extern_func.decl == decl_index; | ||
| 4220 | queue_linker_work = decl.owns_tv; | ||
| 4221 | is_func = decl.owns_tv; | ||
| 4222 | }, | ||
| 4223 | |||
| 4224 | .func => |func| { | ||
| 4225 | decl.owns_tv = func.owner_decl == decl_index; | ||
| 4226 | queue_linker_work = false; | ||
| 4227 | is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline; | ||
| 4228 | is_func = decl.owns_tv; | ||
| 4229 | }, | ||
| 4230 | |||
| 4231 | else => {}, | ||
| 4232 | }, | ||
| 4233 | } | ||
| 4234 | |||
| 4235 | decl.val = decl_val; | ||
| 4236 | // Function linksection, align, and addrspace were already set by Sema | ||
| 4237 | if (!is_func) { | ||
| 4238 | decl.alignment = blk: { | ||
| 4239 | const align_body = decl_bodies.align_body orelse break :blk .none; | ||
| 4240 | const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst); | ||
| 4241 | break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref); | ||
| 4242 | }; | ||
| 4243 | decl.@"linksection" = blk: { | ||
| 4244 | const linksection_body = decl_bodies.linksection_body orelse break :blk .none; | ||
| 4245 | const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst); | ||
| 4246 | const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{ | ||
| 4247 | .needed_comptime_reason = "linksection must be comptime-known", | ||
| 4248 | }); | ||
| 4249 | if (mem.indexOfScalar(u8, bytes, 0) != null) { | ||
| 4250 | return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{}); | ||
| 4251 | } else if (bytes.len == 0) { | ||
| 4252 | return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{}); | ||
| 4253 | } | ||
| 4254 | break :blk try ip.getOrPutStringOpt(gpa, bytes, .no_embedded_nulls); | ||
| 4255 | }; | ||
| 4256 | decl.@"addrspace" = blk: { | ||
| 4257 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { | ||
| 4258 | .variable => .variable, | ||
| 4259 | .extern_func, .func => .function, | ||
| 4260 | else => .constant, | ||
| 4261 | }; | ||
| 4262 | |||
| 4263 | const target = sema.mod.getTarget(); | ||
| 4264 | |||
| 4265 | const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) { | ||
| 4266 | .function => target_util.defaultAddressSpace(target, .function), | ||
| 4267 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | ||
| 4268 | .constant => target_util.defaultAddressSpace(target, .global_constant), | ||
| 4269 | else => unreachable, | ||
| 4270 | }; | ||
| 4271 | const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst); | ||
| 4272 | break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx); | ||
| 4273 | }; | ||
| 4274 | } | ||
| 4275 | decl.has_tv = true; | ||
| 4276 | decl.analysis = .complete; | ||
| 4277 | |||
| 4278 | const result: SemaDeclResult = if (old_has_tv) .{ | ||
| 4279 | .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or | ||
| 4280 | !decl.val.eql(old_val, decl_ty, zcu) or | ||
| 4281 | is_inline != old_is_inline, | ||
| 4282 | .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or | ||
| 4283 | decl.alignment != old_align or | ||
| 4284 | decl.@"linksection" != old_linksection or | ||
| 4285 | decl.@"addrspace" != old_addrspace or | ||
| 4286 | is_inline != old_is_inline, | ||
| 4287 | } else .{ | ||
| 4288 | .invalidate_decl_val = true, | ||
| 4289 | .invalidate_decl_ref = true, | ||
| 4290 | }; | ||
| 4291 | |||
| 4292 | const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty)); | ||
| 4293 | if (has_runtime_bits) { | ||
| 4294 | // Needed for codegen_decl which will call updateDecl and then the | ||
| 4295 | // codegen backend wants full access to the Decl Type. | ||
| 4296 | try decl_ty.resolveFully(zcu); | ||
| 4297 | |||
| 4298 | try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | ||
| 4299 | |||
| 4300 | if (result.invalidate_decl_ref and zcu.emit_h != null) { | ||
| 4301 | try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); | ||
| 4302 | } | ||
| 4303 | } | ||
| 4304 | |||
| 4305 | if (decl.is_exported) { | ||
| 4306 | const export_src: LazySrcLoc = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) }); | ||
| 4307 | if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{}); | ||
| 4308 | // The scope needs to have the decl in it. | ||
| 4309 | try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index); | ||
| 4310 | } | ||
| 4311 | |||
| 4312 | try sema.flushExports(); | ||
| 4313 | |||
| 4314 | return result; | ||
| 4315 | } | ||
| 4316 | |||
| 4317 | fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { | ||
| 4318 | const decl = zcu.declPtr(decl_index); | ||
| 4319 | |||
| 4320 | assert(decl.has_tv); | ||
| 4321 | assert(decl.owns_tv); | ||
| 4322 | |||
| 4323 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); | ||
| 4324 | |||
| 4325 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { | ||
| 4326 | .Fn => @panic("TODO: update fn instance"), | ||
| 4327 | .Type => {}, | ||
| 4328 | else => unreachable, | ||
| 4329 | } | ||
| 4330 | |||
| 4331 | // We are the owner Decl of a type, and we were marked as outdated. That means the *structure* | ||
| 4332 | // of this type changed; not just its namespace. Therefore, we need a new InternPool index. | ||
| 4333 | // | ||
| 4334 | // However, as soon as we make that, the context that created us will require re-analysis anyway | ||
| 4335 | // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction | ||
| 4336 | // will be analyzed again. Since Sema already needs to be able to reconstruct types like this, | ||
| 4337 | // why should we bother implementing it here too when the Sema logic will be hit right after? | ||
| 4338 | // | ||
| 4339 | // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely | ||
| 4340 | // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type | ||
| 4341 | // with a new Decl. | ||
| 4342 | // | ||
| 4343 | // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime. | ||
| 4344 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 4345 | zcu.intern_pool.remove(decl.val.toIntern()); | ||
| 4346 | decl.analysis = .dependency_failure; | ||
| 4347 | return .{ | ||
| 4348 | .invalidate_decl_val = true, | ||
| 4349 | .invalidate_decl_ref = true, | ||
| 4350 | }; | ||
| 4351 | } | ||
| 4352 | |||
| 4353 | pub const ImportFileResult = struct { | ||
| 4354 | file: *File, | ||
| 4355 | file_index: File.Index, | ||
| 4356 | is_new: bool, | ||
| 4357 | is_pkg: bool, | ||
| 4358 | }; | ||
| 4359 | |||
| 4360 | pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { | ||
| 4361 | const gpa = zcu.gpa; | ||
| 4362 | |||
| 4363 | // The resolved path is used as the key in the import table, to detect if | ||
| 4364 | // an import refers to the same as another, despite different relative paths | ||
| 4365 | // or differently mapped package names. | ||
| 4366 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 4367 | mod.root.root_dir.path orelse ".", | ||
| 4368 | mod.root.sub_path, | ||
| 4369 | mod.root_src_path, | ||
| 4370 | }); | ||
| 4371 | var keep_resolved_path = false; | ||
| 4372 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 4373 | |||
| 4374 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); | ||
| 4375 | errdefer _ = zcu.import_table.pop(); | ||
| 4376 | if (gop.found_existing) { | ||
| 4377 | try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod }); | ||
| 4378 | return .{ | ||
| 4379 | .file = gop.value_ptr.*, | ||
| 4380 | .file_index = @enumFromInt(gop.index), | ||
| 4381 | .is_new = false, | ||
| 4382 | .is_pkg = true, | ||
| 4383 | }; | ||
| 4384 | } | ||
| 4385 | |||
| 4386 | const ip = &zcu.intern_pool; | ||
| 4387 | |||
| 4388 | try ip.files.ensureUnusedCapacity(gpa, 1); | ||
| 4389 | |||
| 4390 | if (mod.builtin_file) |builtin_file| { | ||
| 4391 | keep_resolved_path = true; // It's now owned by import_table. | ||
| 4392 | gop.value_ptr.* = builtin_file; | ||
| 4393 | try builtin_file.addReference(zcu.*, .{ .root = mod }); | ||
| 4394 | const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path); | ||
| 4395 | ip.files.putAssumeCapacityNoClobber(path_digest, .none); | ||
| 4396 | return .{ | ||
| 4397 | .file = builtin_file, | ||
| 4398 | .file_index = @enumFromInt(ip.files.entries.len - 1), | ||
| 4399 | .is_new = false, | ||
| 4400 | .is_pkg = true, | ||
| 4401 | }; | ||
| 4402 | } | ||
| 4403 | |||
| 4404 | const sub_file_path = try gpa.dupe(u8, mod.root_src_path); | ||
| 4405 | errdefer gpa.free(sub_file_path); | ||
| 4406 | |||
| 4407 | const new_file = try gpa.create(File); | ||
| 4408 | errdefer gpa.destroy(new_file); | ||
| 4409 | 3556 | ||
| 4410 | keep_resolved_path = true; // It's now owned by import_table. | 3557 | keep_resolved_path = true; // It's now owned by import_table. |
| 4411 | gop.value_ptr.* = new_file; | 3558 | gop.value_ptr.* = new_file; |
| ... | @@ -4533,78 +3680,6 @@ pub fn importFile( | ... | @@ -4533,78 +3680,6 @@ pub fn importFile( |
| 4533 | }; | 3680 | }; |
| 4534 | } | 3681 | } |
| 4535 | 3682 | ||
| 4536 | pub fn embedFile( | ||
| 4537 | mod: *Module, | ||
| 4538 | cur_file: *File, | ||
| 4539 | import_string: []const u8, | ||
| 4540 | src_loc: LazySrcLoc, | ||
| 4541 | ) !InternPool.Index { | ||
| 4542 | const gpa = mod.gpa; | ||
| 4543 | |||
| 4544 | if (cur_file.mod.deps.get(import_string)) |pkg| { | ||
| 4545 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 4546 | pkg.root.root_dir.path orelse ".", | ||
| 4547 | pkg.root.sub_path, | ||
| 4548 | pkg.root_src_path, | ||
| 4549 | }); | ||
| 4550 | var keep_resolved_path = false; | ||
| 4551 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 4552 | |||
| 4553 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); | ||
| 4554 | errdefer { | ||
| 4555 | assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path)); | ||
| 4556 | keep_resolved_path = false; | ||
| 4557 | } | ||
| 4558 | if (gop.found_existing) return gop.value_ptr.*.val; | ||
| 4559 | keep_resolved_path = true; | ||
| 4560 | |||
| 4561 | const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); | ||
| 4562 | errdefer gpa.free(sub_file_path); | ||
| 4563 | |||
| 4564 | return newEmbedFile(mod, pkg, sub_file_path, resolved_path, gop.value_ptr, src_loc); | ||
| 4565 | } | ||
| 4566 | |||
| 4567 | // The resolved path is used as the key in the table, to detect if a file | ||
| 4568 | // refers to the same as another, despite different relative paths. | ||
| 4569 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 4570 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 4571 | cur_file.mod.root.sub_path, | ||
| 4572 | cur_file.sub_file_path, | ||
| 4573 | "..", | ||
| 4574 | import_string, | ||
| 4575 | }); | ||
| 4576 | |||
| 4577 | var keep_resolved_path = false; | ||
| 4578 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 4579 | |||
| 4580 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); | ||
| 4581 | errdefer { | ||
| 4582 | assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path)); | ||
| 4583 | keep_resolved_path = false; | ||
| 4584 | } | ||
| 4585 | if (gop.found_existing) return gop.value_ptr.*.val; | ||
| 4586 | keep_resolved_path = true; | ||
| 4587 | |||
| 4588 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | ||
| 4589 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 4590 | cur_file.mod.root.sub_path, | ||
| 4591 | }); | ||
| 4592 | defer gpa.free(resolved_root_path); | ||
| 4593 | |||
| 4594 | const sub_file_path = p: { | ||
| 4595 | const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path); | ||
| 4596 | errdefer gpa.free(relative); | ||
| 4597 | |||
| 4598 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { | ||
| 4599 | break :p relative; | ||
| 4600 | } | ||
| 4601 | return error.ImportOutsideModulePath; | ||
| 4602 | }; | ||
| 4603 | defer gpa.free(sub_file_path); | ||
| 4604 | |||
| 4605 | return newEmbedFile(mod, cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); | ||
| 4606 | } | ||
| 4607 | |||
| 4608 | fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { | 3683 | fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { |
| 4609 | const want_local_cache = mod == zcu.main_mod; | 3684 | const want_local_cache = mod == zcu.main_mod; |
| 4610 | var path_hash: Cache.HashHelper = .{}; | 3685 | var path_hash: Cache.HashHelper = .{}; |
| ... | @@ -4620,87 +3695,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) | ... | @@ -4620,87 +3695,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) |
| 4620 | return bin; | 3695 | return bin; |
| 4621 | } | 3696 | } |
| 4622 | 3697 | ||
| 4623 | /// https://github.com/ziglang/zig/issues/14307 | ||
| 4624 | fn newEmbedFile( | ||
| 4625 | mod: *Module, | ||
| 4626 | pkg: *Package.Module, | ||
| 4627 | sub_file_path: []const u8, | ||
| 4628 | resolved_path: []const u8, | ||
| 4629 | result: **EmbedFile, | ||
| 4630 | src_loc: LazySrcLoc, | ||
| 4631 | ) !InternPool.Index { | ||
| 4632 | const gpa = mod.gpa; | ||
| 4633 | const ip = &mod.intern_pool; | ||
| 4634 | |||
| 4635 | const new_file = try gpa.create(EmbedFile); | ||
| 4636 | errdefer gpa.destroy(new_file); | ||
| 4637 | |||
| 4638 | var file = try pkg.root.openFile(sub_file_path, .{}); | ||
| 4639 | defer file.close(); | ||
| 4640 | |||
| 4641 | const actual_stat = try file.stat(); | ||
| 4642 | const stat: Cache.File.Stat = .{ | ||
| 4643 | .size = actual_stat.size, | ||
| 4644 | .inode = actual_stat.inode, | ||
| 4645 | .mtime = actual_stat.mtime, | ||
| 4646 | }; | ||
| 4647 | const size = std.math.cast(usize, actual_stat.size) orelse return error.Overflow; | ||
| 4648 | |||
| 4649 | const bytes = try ip.string_bytes.addManyAsSlice(gpa, try std.math.add(usize, size, 1)); | ||
| 4650 | const actual_read = try file.readAll(bytes[0..size]); | ||
| 4651 | if (actual_read != size) return error.UnexpectedEndOfFile; | ||
| 4652 | bytes[size] = 0; | ||
| 4653 | |||
| 4654 | const comp = mod.comp; | ||
| 4655 | switch (comp.cache_use) { | ||
| 4656 | .whole => |whole| if (whole.cache_manifest) |man| { | ||
| 4657 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); | ||
| 4658 | errdefer gpa.free(copied_resolved_path); | ||
| 4659 | whole.cache_manifest_mutex.lock(); | ||
| 4660 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4661 | try man.addFilePostContents(copied_resolved_path, bytes[0..size], stat); | ||
| 4662 | }, | ||
| 4663 | .incremental => {}, | ||
| 4664 | } | ||
| 4665 | |||
| 4666 | const array_ty = try ip.get(gpa, .{ .array_type = .{ | ||
| 4667 | .len = size, | ||
| 4668 | .sentinel = .zero_u8, | ||
| 4669 | .child = .u8_type, | ||
| 4670 | } }); | ||
| 4671 | const array_val = try ip.get(gpa, .{ .aggregate = .{ | ||
| 4672 | .ty = array_ty, | ||
| 4673 | .storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, bytes.len, .maybe_embedded_nulls) }, | ||
| 4674 | } }); | ||
| 4675 | |||
| 4676 | const ptr_ty = (try mod.ptrType(.{ | ||
| 4677 | .child = array_ty, | ||
| 4678 | .flags = .{ | ||
| 4679 | .alignment = .none, | ||
| 4680 | .is_const = true, | ||
| 4681 | .address_space = .generic, | ||
| 4682 | }, | ||
| 4683 | })).toIntern(); | ||
| 4684 | const ptr_val = try ip.get(gpa, .{ .ptr = .{ | ||
| 4685 | .ty = ptr_ty, | ||
| 4686 | .base_addr = .{ .anon_decl = .{ | ||
| 4687 | .val = array_val, | ||
| 4688 | .orig_ty = ptr_ty, | ||
| 4689 | } }, | ||
| 4690 | .byte_offset = 0, | ||
| 4691 | } }); | ||
| 4692 | |||
| 4693 | result.* = new_file; | ||
| 4694 | new_file.* = .{ | ||
| 4695 | .sub_file_path = try ip.getOrPutString(gpa, sub_file_path, .no_embedded_nulls), | ||
| 4696 | .owner = pkg, | ||
| 4697 | .stat = stat, | ||
| 4698 | .val = ptr_val, | ||
| 4699 | .src_loc = src_loc, | ||
| 4700 | }; | ||
| 4701 | return ptr_val; | ||
| 4702 | } | ||
| 4703 | |||
| 4704 | pub fn scanNamespace( | 3698 | pub fn scanNamespace( |
| 4705 | zcu: *Zcu, | 3699 | zcu: *Zcu, |
| 4706 | namespace_index: Namespace.Index, | 3700 | namespace_index: Namespace.Index, |
| ... | @@ -4970,13 +3964,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { | ... | @@ -4970,13 +3964,6 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { |
| 4970 | mod.destroyDecl(decl_index); | 3964 | mod.destroyDecl(decl_index); |
| 4971 | } | 3965 | } |
| 4972 | 3966 | ||
| 4973 | /// Finalize the creation of an anon decl. | ||
| 4974 | pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void { | ||
| 4975 | if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) { | ||
| 4976 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | ||
| 4977 | } | ||
| 4978 | } | ||
| 4979 | |||
| 4980 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of | 3967 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of |
| 4981 | /// this `AnalUnit` will cause them to be re-created (or not). | 3968 | /// this `AnalUnit` will cause them to be re-created (or not). |
| 4982 | pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { | 3969 | pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| ... | @@ -5019,7 +4006,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { | ... | @@ -5019,7 +4006,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 5019 | 4006 | ||
| 5020 | /// Delete all references in `reference_table` which are caused by this `AnalUnit`. | 4007 | /// Delete all references in `reference_table` which are caused by this `AnalUnit`. |
| 5021 | /// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated. | 4008 | /// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated. |
| 5022 | fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void { | 4009 | pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 5023 | const gpa = zcu.gpa; | 4010 | const gpa = zcu.gpa; |
| 5024 | 4011 | ||
| 5025 | const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return; | 4012 | const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse return; |
| ... | @@ -5058,258 +4045,13 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit | ... | @@ -5058,258 +4045,13 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit |
| 5058 | gop.value_ptr.* = @intCast(ref_idx); | 4045 | gop.value_ptr.* = @intCast(ref_idx); |
| 5059 | } | 4046 | } |
| 5060 | 4047 | ||
| 5061 | pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocator) SemaError!Air { | 4048 | pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index { |
| 5062 | const tracy = trace(@src()); | 4049 | return mod.intern_pool.createNamespace(mod.gpa, initialization); |
| 5063 | defer tracy.end(); | 4050 | } |
| 5064 | |||
| 5065 | const gpa = mod.gpa; | ||
| 5066 | const ip = &mod.intern_pool; | ||
| 5067 | const func = mod.funcInfo(func_index); | ||
| 5068 | const decl_index = func.owner_decl; | ||
| 5069 | const decl = mod.declPtr(decl_index); | ||
| 5070 | |||
| 5071 | log.debug("func name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)}); | ||
| 5072 | defer blk: { | ||
| 5073 | log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)}); | ||
| 5074 | } | ||
| 5075 | |||
| 5076 | const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0); | ||
| 5077 | defer decl_prog_node.end(); | ||
| 5078 | |||
| 5079 | mod.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .func = func_index })); | ||
| 5080 | |||
| 5081 | var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa); | ||
| 5082 | defer comptime_err_ret_trace.deinit(); | ||
| 5083 | 4051 | ||
| 5084 | // In the case of a generic function instance, this is the type of the | 4052 | pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void { |
| 5085 | // instance, which has comptime parameters elided. In other words, it is | 4053 | return mod.intern_pool.destroyNamespace(mod.gpa, index); |
| 5086 | // the runtime-known parameters only, not to be confused with the | 4054 | } |
| 5087 | // generic_owner function type, which potentially has more parameters, | ||
| 5088 | // including comptime parameters. | ||
| 5089 | const fn_ty = decl.typeOf(mod); | ||
| 5090 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | ||
| 5091 | |||
| 5092 | var sema: Sema = .{ | ||
| 5093 | .mod = mod, | ||
| 5094 | .gpa = gpa, | ||
| 5095 | .arena = arena, | ||
| 5096 | .code = decl.getFileScope(mod).zir, | ||
| 5097 | .owner_decl = decl, | ||
| 5098 | .owner_decl_index = decl_index, | ||
| 5099 | .func_index = func_index, | ||
| 5100 | .func_is_naked = fn_ty_info.cc == .Naked, | ||
| 5101 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), | ||
| 5102 | .fn_ret_ty_ies = null, | ||
| 5103 | .owner_func_index = func_index, | ||
| 5104 | .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota), | ||
| 5105 | .comptime_err_ret_trace = &comptime_err_ret_trace, | ||
| 5106 | }; | ||
| 5107 | defer sema.deinit(); | ||
| 5108 | |||
| 5109 | // Every runtime function has a dependency on the source of the Decl it originates from. | ||
| 5110 | // It also depends on the value of its owner Decl. | ||
| 5111 | try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? }); | ||
| 5112 | try sema.declareDependency(.{ .decl_val = decl_index }); | ||
| 5113 | |||
| 5114 | if (func.analysis(ip).inferred_error_set) { | ||
| 5115 | const ies = try arena.create(Sema.InferredErrorSet); | ||
| 5116 | ies.* = .{ .func = func_index }; | ||
| 5117 | sema.fn_ret_ty_ies = ies; | ||
| 5118 | } | ||
| 5119 | |||
| 5120 | // reset in case calls to errorable functions are removed. | ||
| 5121 | func.analysis(ip).calls_or_awaits_errorable_fn = false; | ||
| 5122 | |||
| 5123 | // First few indexes of extra are reserved and set at the end. | ||
| 5124 | const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len; | ||
| 5125 | try sema.air_extra.ensureTotalCapacity(gpa, reserved_count); | ||
| 5126 | sema.air_extra.items.len += reserved_count; | ||
| 5127 | |||
| 5128 | var inner_block: Sema.Block = .{ | ||
| 5129 | .parent = null, | ||
| 5130 | .sema = &sema, | ||
| 5131 | .namespace = decl.src_namespace, | ||
| 5132 | .instructions = .{}, | ||
| 5133 | .inlining = null, | ||
| 5134 | .is_comptime = false, | ||
| 5135 | .src_base_inst = inst: { | ||
| 5136 | const owner_info = if (func.generic_owner == .none) | ||
| 5137 | func | ||
| 5138 | else | ||
| 5139 | mod.funcInfo(func.generic_owner); | ||
| 5140 | const orig_decl = mod.declPtr(owner_info.owner_decl); | ||
| 5141 | break :inst orig_decl.zir_decl_index.unwrap().?; | ||
| 5142 | }, | ||
| 5143 | .type_name_ctx = decl.name, | ||
| 5144 | }; | ||
| 5145 | defer inner_block.instructions.deinit(gpa); | ||
| 5146 | |||
| 5147 | const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip)); | ||
| 5148 | |||
| 5149 | // Here we are performing "runtime semantic analysis" for a function body, which means | ||
| 5150 | // we must map the parameter ZIR instructions to `arg` AIR instructions. | ||
| 5151 | // AIR requires the `arg` parameters to be the first N instructions. | ||
| 5152 | // This could be a generic function instantiation, however, in which case we need to | ||
| 5153 | // map the comptime parameters to constant values and only emit arg AIR instructions | ||
| 5154 | // for the runtime ones. | ||
| 5155 | const runtime_params_len = fn_ty_info.param_types.len; | ||
| 5156 | try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len); | ||
| 5157 | try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len); | ||
| 5158 | try sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); | ||
| 5159 | |||
| 5160 | // In the case of a generic function instance, pre-populate all the comptime args. | ||
| 5161 | if (func.comptime_args.len != 0) { | ||
| 5162 | for ( | ||
| 5163 | fn_info.param_body[0..func.comptime_args.len], | ||
| 5164 | func.comptime_args.get(ip), | ||
| 5165 | ) |inst, comptime_arg| { | ||
| 5166 | if (comptime_arg == .none) continue; | ||
| 5167 | sema.inst_map.putAssumeCapacityNoClobber(inst, Air.internedToRef(comptime_arg)); | ||
| 5168 | } | ||
| 5169 | } | ||
| 5170 | |||
| 5171 | const src_params_len = if (func.comptime_args.len != 0) | ||
| 5172 | func.comptime_args.len | ||
| 5173 | else | ||
| 5174 | runtime_params_len; | ||
| 5175 | |||
| 5176 | var runtime_param_index: usize = 0; | ||
| 5177 | for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| { | ||
| 5178 | const gop = sema.inst_map.getOrPutAssumeCapacity(inst); | ||
| 5179 | if (gop.found_existing) continue; // provided above by comptime arg | ||
| 5180 | |||
| 5181 | const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index]; | ||
| 5182 | runtime_param_index += 1; | ||
| 5183 | |||
| 5184 | const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) { | ||
| 5185 | error.GenericPoison => unreachable, | ||
| 5186 | error.ComptimeReturn => unreachable, | ||
| 5187 | error.ComptimeBreak => unreachable, | ||
| 5188 | else => |e| return e, | ||
| 5189 | }; | ||
| 5190 | if (opt_opv) |opv| { | ||
| 5191 | gop.value_ptr.* = Air.internedToRef(opv.toIntern()); | ||
| 5192 | continue; | ||
| 5193 | } | ||
| 5194 | const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); | ||
| 5195 | gop.value_ptr.* = arg_index.toRef(); | ||
| 5196 | inner_block.instructions.appendAssumeCapacity(arg_index); | ||
| 5197 | sema.air_instructions.appendAssumeCapacity(.{ | ||
| 5198 | .tag = .arg, | ||
| 5199 | .data = .{ .arg = .{ | ||
| 5200 | .ty = Air.internedToRef(param_ty), | ||
| 5201 | .src_index = @intCast(src_param_index), | ||
| 5202 | } }, | ||
| 5203 | }); | ||
| 5204 | } | ||
| 5205 | |||
| 5206 | func.analysis(ip).state = .in_progress; | ||
| 5207 | |||
| 5208 | const last_arg_index = inner_block.instructions.items.len; | ||
| 5209 | |||
| 5210 | // Save the error trace as our first action in the function. | ||
| 5211 | // If this is unnecessary after all, Liveness will clean it up for us. | ||
| 5212 | const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&inner_block); | ||
| 5213 | sema.error_return_trace_index_on_fn_entry = error_return_trace_index; | ||
| 5214 | inner_block.error_return_trace_index = error_return_trace_index; | ||
| 5215 | |||
| 5216 | sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) { | ||
| 5217 | // TODO make these unreachable instead of @panic | ||
| 5218 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | ||
| 5219 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | ||
| 5220 | else => |e| return e, | ||
| 5221 | }; | ||
| 5222 | |||
| 5223 | for (sema.unresolved_inferred_allocs.keys()) |ptr_inst| { | ||
| 5224 | // The lack of a resolve_inferred_alloc means that this instruction | ||
| 5225 | // is unused so it just has to be a no-op. | ||
| 5226 | sema.air_instructions.set(@intFromEnum(ptr_inst), .{ | ||
| 5227 | .tag = .alloc, | ||
| 5228 | .data = .{ .ty = Type.single_const_pointer_to_comptime_int }, | ||
| 5229 | }); | ||
| 5230 | } | ||
| 5231 | |||
| 5232 | // If we don't get an error return trace from a caller, create our own. | ||
| 5233 | if (func.analysis(ip).calls_or_awaits_errorable_fn and | ||
| 5234 | mod.comp.config.any_error_tracing and | ||
| 5235 | !sema.fn_ret_ty.isError(mod)) | ||
| 5236 | { | ||
| 5237 | sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) { | ||
| 5238 | // TODO make these unreachable instead of @panic | ||
| 5239 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | ||
| 5240 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | ||
| 5241 | error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"), | ||
| 5242 | else => |e| return e, | ||
| 5243 | }; | ||
| 5244 | } | ||
| 5245 | |||
| 5246 | // Copy the block into place and mark that as the main block. | ||
| 5247 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | ||
| 5248 | inner_block.instructions.items.len); | ||
| 5249 | const main_block_index = sema.addExtraAssumeCapacity(Air.Block{ | ||
| 5250 | .body_len = @intCast(inner_block.instructions.items.len), | ||
| 5251 | }); | ||
| 5252 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items)); | ||
| 5253 | sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index; | ||
| 5254 | |||
| 5255 | // Resolving inferred error sets is done *before* setting the function | ||
| 5256 | // state to success, so that "unable to resolve inferred error set" errors | ||
| 5257 | // can be emitted here. | ||
| 5258 | if (sema.fn_ret_ty_ies) |ies| { | ||
| 5259 | sema.resolveInferredErrorSetPtr(&inner_block, .{ | ||
| 5260 | .base_node_inst = inner_block.src_base_inst, | ||
| 5261 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 5262 | }, ies) catch |err| switch (err) { | ||
| 5263 | error.GenericPoison => unreachable, | ||
| 5264 | error.ComptimeReturn => unreachable, | ||
| 5265 | error.ComptimeBreak => unreachable, | ||
| 5266 | error.AnalysisFail => { | ||
| 5267 | // In this case our function depends on a type that had a compile error. | ||
| 5268 | // We should not try to lower this function. | ||
| 5269 | decl.analysis = .dependency_failure; | ||
| 5270 | return error.AnalysisFail; | ||
| 5271 | }, | ||
| 5272 | else => |e| return e, | ||
| 5273 | }; | ||
| 5274 | assert(ies.resolved != .none); | ||
| 5275 | ip.funcIesResolved(func_index).* = ies.resolved; | ||
| 5276 | } | ||
| 5277 | |||
| 5278 | func.analysis(ip).state = .success; | ||
| 5279 | |||
| 5280 | // Finally we must resolve the return type and parameter types so that backends | ||
| 5281 | // have full access to type information. | ||
| 5282 | // Crucially, this happens *after* we set the function state to success above, | ||
| 5283 | // so that dependencies on the function body will now be satisfied rather than | ||
| 5284 | // result in circular dependency errors. | ||
| 5285 | sema.resolveFnTypes(fn_ty) catch |err| switch (err) { | ||
| 5286 | error.GenericPoison => unreachable, | ||
| 5287 | error.ComptimeReturn => unreachable, | ||
| 5288 | error.ComptimeBreak => unreachable, | ||
| 5289 | error.AnalysisFail => { | ||
| 5290 | // In this case our function depends on a type that had a compile error. | ||
| 5291 | // We should not try to lower this function. | ||
| 5292 | decl.analysis = .dependency_failure; | ||
| 5293 | return error.AnalysisFail; | ||
| 5294 | }, | ||
| 5295 | else => |e| return e, | ||
| 5296 | }; | ||
| 5297 | |||
| 5298 | try sema.flushExports(); | ||
| 5299 | |||
| 5300 | return .{ | ||
| 5301 | .instructions = sema.air_instructions.toOwnedSlice(), | ||
| 5302 | .extra = try sema.air_extra.toOwnedSlice(gpa), | ||
| 5303 | }; | ||
| 5304 | } | ||
| 5305 | |||
| 5306 | pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index { | ||
| 5307 | return mod.intern_pool.createNamespace(mod.gpa, initialization); | ||
| 5308 | } | ||
| 5309 | |||
| 5310 | pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void { | ||
| 5311 | return mod.intern_pool.destroyNamespace(mod.gpa, index); | ||
| 5312 | } | ||
| 5313 | 4055 | ||
| 5314 | pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index { | 4056 | pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index { |
| 5315 | const gpa = zcu.gpa; | 4057 | const gpa = zcu.gpa; |
| ... | @@ -5420,117 +4162,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void { | ... | @@ -5420,117 +4162,7 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void { |
| 5420 | } | 4162 | } |
| 5421 | } | 4163 | } |
| 5422 | 4164 | ||
| 5423 | /// Called from `Compilation.update`, after everything is done, just before | 4165 | pub fn handleUpdateExports( |
| 5424 | /// reporting compile errors. In this function we emit exported symbol collision | ||
| 5425 | /// errors and communicate exported symbols to the linker backend. | ||
| 5426 | pub fn processExports(zcu: *Zcu) !void { | ||
| 5427 | const gpa = zcu.gpa; | ||
| 5428 | |||
| 5429 | // First, construct a mapping of every exported value and Decl to the indices of all its different exports. | ||
| 5430 | var decl_exports: std.AutoArrayHashMapUnmanaged(Decl.Index, ArrayListUnmanaged(u32)) = .{}; | ||
| 5431 | var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, ArrayListUnmanaged(u32)) = .{}; | ||
| 5432 | defer { | ||
| 5433 | for (decl_exports.values()) |*exports| { | ||
| 5434 | exports.deinit(gpa); | ||
| 5435 | } | ||
| 5436 | decl_exports.deinit(gpa); | ||
| 5437 | for (value_exports.values()) |*exports| { | ||
| 5438 | exports.deinit(gpa); | ||
| 5439 | } | ||
| 5440 | value_exports.deinit(gpa); | ||
| 5441 | } | ||
| 5442 | |||
| 5443 | // We note as a heuristic: | ||
| 5444 | // * It is rare to export a value. | ||
| 5445 | // * It is rare for one Decl to be exported multiple times. | ||
| 5446 | // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization. | ||
| 5447 | try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count()); | ||
| 5448 | |||
| 5449 | for (zcu.single_exports.values()) |export_idx| { | ||
| 5450 | const exp = zcu.all_exports.items[export_idx]; | ||
| 5451 | const value_ptr, const found_existing = switch (exp.exported) { | ||
| 5452 | .decl_index => |i| gop: { | ||
| 5453 | const gop = try decl_exports.getOrPut(gpa, i); | ||
| 5454 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 5455 | }, | ||
| 5456 | .value => |i| gop: { | ||
| 5457 | const gop = try value_exports.getOrPut(gpa, i); | ||
| 5458 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 5459 | }, | ||
| 5460 | }; | ||
| 5461 | if (!found_existing) value_ptr.* = .{}; | ||
| 5462 | try value_ptr.append(gpa, export_idx); | ||
| 5463 | } | ||
| 5464 | |||
| 5465 | for (zcu.multi_exports.values()) |info| { | ||
| 5466 | for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| { | ||
| 5467 | const value_ptr, const found_existing = switch (exp.exported) { | ||
| 5468 | .decl_index => |i| gop: { | ||
| 5469 | const gop = try decl_exports.getOrPut(gpa, i); | ||
| 5470 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 5471 | }, | ||
| 5472 | .value => |i| gop: { | ||
| 5473 | const gop = try value_exports.getOrPut(gpa, i); | ||
| 5474 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 5475 | }, | ||
| 5476 | }; | ||
| 5477 | if (!found_existing) value_ptr.* = .{}; | ||
| 5478 | try value_ptr.append(gpa, @intCast(export_idx)); | ||
| 5479 | } | ||
| 5480 | } | ||
| 5481 | |||
| 5482 | // Map symbol names to `Export` for name collision detection. | ||
| 5483 | var symbol_exports: SymbolExports = .{}; | ||
| 5484 | defer symbol_exports.deinit(gpa); | ||
| 5485 | |||
| 5486 | for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| { | ||
| 5487 | const exported: Exported = .{ .decl_index = exported_decl }; | ||
| 5488 | try processExportsInner(zcu, &symbol_exports, exported, exports_list.items); | ||
| 5489 | } | ||
| 5490 | |||
| 5491 | for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| { | ||
| 5492 | const exported: Exported = .{ .value = exported_value }; | ||
| 5493 | try processExportsInner(zcu, &symbol_exports, exported, exports_list.items); | ||
| 5494 | } | ||
| 5495 | } | ||
| 5496 | |||
| 5497 | const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32); | ||
| 5498 | |||
| 5499 | fn processExportsInner( | ||
| 5500 | zcu: *Zcu, | ||
| 5501 | symbol_exports: *SymbolExports, | ||
| 5502 | exported: Exported, | ||
| 5503 | export_indices: []const u32, | ||
| 5504 | ) error{OutOfMemory}!void { | ||
| 5505 | const gpa = zcu.gpa; | ||
| 5506 | |||
| 5507 | for (export_indices) |export_idx| { | ||
| 5508 | const new_export = &zcu.all_exports.items[export_idx]; | ||
| 5509 | const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name); | ||
| 5510 | if (gop.found_existing) { | ||
| 5511 | new_export.status = .failed_retryable; | ||
| 5512 | try zcu.failed_exports.ensureUnusedCapacity(gpa, 1); | ||
| 5513 | const msg = try ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{ | ||
| 5514 | new_export.opts.name.fmt(&zcu.intern_pool), | ||
| 5515 | }); | ||
| 5516 | errdefer msg.destroy(gpa); | ||
| 5517 | const other_export = zcu.all_exports.items[gop.value_ptr.*]; | ||
| 5518 | try zcu.errNote(other_export.src, msg, "other symbol here", .{}); | ||
| 5519 | zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg); | ||
| 5520 | new_export.status = .failed; | ||
| 5521 | } else { | ||
| 5522 | gop.value_ptr.* = export_idx; | ||
| 5523 | } | ||
| 5524 | } | ||
| 5525 | if (zcu.comp.bin_file) |lf| { | ||
| 5526 | try handleUpdateExports(zcu, export_indices, lf.updateExports(zcu, exported, export_indices)); | ||
| 5527 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 5528 | if (build_options.only_c) unreachable; | ||
| 5529 | try handleUpdateExports(zcu, export_indices, llvm_object.updateExports(zcu, exported, export_indices)); | ||
| 5530 | } | ||
| 5531 | } | ||
| 5532 | |||
| 5533 | fn handleUpdateExports( | ||
| 5534 | zcu: *Zcu, | 4166 | zcu: *Zcu, |
| 5535 | export_indices: []const u32, | 4167 | export_indices: []const u32, |
| 5536 | result: link.File.UpdateExportsError!void, | 4168 | result: link.File.UpdateExportsError!void, |
| ... | @@ -5551,180 +4183,7 @@ fn handleUpdateExports( | ... | @@ -5551,180 +4183,7 @@ fn handleUpdateExports( |
| 5551 | }; | 4183 | }; |
| 5552 | } | 4184 | } |
| 5553 | 4185 | ||
| 5554 | pub fn populateTestFunctions( | 4186 | pub fn reportRetryableFileError( |
| 5555 | zcu: *Zcu, | ||
| 5556 | main_progress_node: std.Progress.Node, | ||
| 5557 | ) !void { | ||
| 5558 | const gpa = zcu.gpa; | ||
| 5559 | const ip = &zcu.intern_pool; | ||
| 5560 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); | ||
| 5561 | const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index; | ||
| 5562 | const root_decl_index = zcu.fileRootDecl(builtin_file_index); | ||
| 5563 | const root_decl = zcu.declPtr(root_decl_index.unwrap().?); | ||
| 5564 | const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace); | ||
| 5565 | const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls); | ||
| 5566 | const decl_index = builtin_namespace.decls.getKeyAdapted( | ||
| 5567 | test_functions_str, | ||
| 5568 | DeclAdapter{ .zcu = zcu }, | ||
| 5569 | ).?; | ||
| 5570 | { | ||
| 5571 | // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` | ||
| 5572 | // was not referenced by start code. | ||
| 5573 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | ||
| 5574 | defer { | ||
| 5575 | zcu.sema_prog_node.end(); | ||
| 5576 | zcu.sema_prog_node = undefined; | ||
| 5577 | } | ||
| 5578 | try zcu.ensureDeclAnalyzed(decl_index); | ||
| 5579 | } | ||
| 5580 | |||
| 5581 | const decl = zcu.declPtr(decl_index); | ||
| 5582 | const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); | ||
| 5583 | |||
| 5584 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: { | ||
| 5585 | // Add zcu.test_functions to an array decl then make the test_functions | ||
| 5586 | // decl reference it as a slice. | ||
| 5587 | const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count()); | ||
| 5588 | defer gpa.free(test_fn_vals); | ||
| 5589 | |||
| 5590 | for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| { | ||
| 5591 | const test_decl = zcu.declPtr(test_decl_index); | ||
| 5592 | const test_decl_name = try test_decl.fullyQualifiedName(zcu); | ||
| 5593 | const test_decl_name_len = test_decl_name.length(ip); | ||
| 5594 | const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: { | ||
| 5595 | const test_name_ty = try zcu.arrayType(.{ | ||
| 5596 | .len = test_decl_name_len, | ||
| 5597 | .child = .u8_type, | ||
| 5598 | }); | ||
| 5599 | const test_name_val = try zcu.intern(.{ .aggregate = .{ | ||
| 5600 | .ty = test_name_ty.toIntern(), | ||
| 5601 | .storage = .{ .bytes = test_decl_name.toString() }, | ||
| 5602 | } }); | ||
| 5603 | break :n .{ | ||
| 5604 | .orig_ty = (try zcu.singleConstPtrType(test_name_ty)).toIntern(), | ||
| 5605 | .val = test_name_val, | ||
| 5606 | }; | ||
| 5607 | }; | ||
| 5608 | |||
| 5609 | const test_fn_fields = .{ | ||
| 5610 | // name | ||
| 5611 | try zcu.intern(.{ .slice = .{ | ||
| 5612 | .ty = .slice_const_u8_type, | ||
| 5613 | .ptr = try zcu.intern(.{ .ptr = .{ | ||
| 5614 | .ty = .manyptr_const_u8_type, | ||
| 5615 | .base_addr = .{ .anon_decl = test_name_anon_decl }, | ||
| 5616 | .byte_offset = 0, | ||
| 5617 | } }), | ||
| 5618 | .len = try zcu.intern(.{ .int = .{ | ||
| 5619 | .ty = .usize_type, | ||
| 5620 | .storage = .{ .u64 = test_decl_name_len }, | ||
| 5621 | } }), | ||
| 5622 | } }), | ||
| 5623 | // func | ||
| 5624 | try zcu.intern(.{ .ptr = .{ | ||
| 5625 | .ty = try zcu.intern(.{ .ptr_type = .{ | ||
| 5626 | .child = test_decl.typeOf(zcu).toIntern(), | ||
| 5627 | .flags = .{ | ||
| 5628 | .is_const = true, | ||
| 5629 | }, | ||
| 5630 | } }), | ||
| 5631 | .base_addr = .{ .decl = test_decl_index }, | ||
| 5632 | .byte_offset = 0, | ||
| 5633 | } }), | ||
| 5634 | }; | ||
| 5635 | test_fn_val.* = try zcu.intern(.{ .aggregate = .{ | ||
| 5636 | .ty = test_fn_ty.toIntern(), | ||
| 5637 | .storage = .{ .elems = &test_fn_fields }, | ||
| 5638 | } }); | ||
| 5639 | } | ||
| 5640 | |||
| 5641 | const array_ty = try zcu.arrayType(.{ | ||
| 5642 | .len = test_fn_vals.len, | ||
| 5643 | .child = test_fn_ty.toIntern(), | ||
| 5644 | .sentinel = .none, | ||
| 5645 | }); | ||
| 5646 | const array_val = try zcu.intern(.{ .aggregate = .{ | ||
| 5647 | .ty = array_ty.toIntern(), | ||
| 5648 | .storage = .{ .elems = test_fn_vals }, | ||
| 5649 | } }); | ||
| 5650 | break :array .{ | ||
| 5651 | .orig_ty = (try zcu.singleConstPtrType(array_ty)).toIntern(), | ||
| 5652 | .val = array_val, | ||
| 5653 | }; | ||
| 5654 | }; | ||
| 5655 | |||
| 5656 | { | ||
| 5657 | const new_ty = try zcu.ptrType(.{ | ||
| 5658 | .child = test_fn_ty.toIntern(), | ||
| 5659 | .flags = .{ | ||
| 5660 | .is_const = true, | ||
| 5661 | .size = .Slice, | ||
| 5662 | }, | ||
| 5663 | }); | ||
| 5664 | const new_val = decl.val; | ||
| 5665 | const new_init = try zcu.intern(.{ .slice = .{ | ||
| 5666 | .ty = new_ty.toIntern(), | ||
| 5667 | .ptr = try zcu.intern(.{ .ptr = .{ | ||
| 5668 | .ty = new_ty.slicePtrFieldType(zcu).toIntern(), | ||
| 5669 | .base_addr = .{ .anon_decl = array_anon_decl }, | ||
| 5670 | .byte_offset = 0, | ||
| 5671 | } }), | ||
| 5672 | .len = (try zcu.intValue(Type.usize, zcu.test_functions.count())).toIntern(), | ||
| 5673 | } }); | ||
| 5674 | ip.mutateVarInit(decl.val.toIntern(), new_init); | ||
| 5675 | |||
| 5676 | // Since we are replacing the Decl's value we must perform cleanup on the | ||
| 5677 | // previous value. | ||
| 5678 | decl.val = new_val; | ||
| 5679 | decl.has_tv = true; | ||
| 5680 | } | ||
| 5681 | { | ||
| 5682 | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); | ||
| 5683 | defer { | ||
| 5684 | zcu.codegen_prog_node.end(); | ||
| 5685 | zcu.codegen_prog_node = undefined; | ||
| 5686 | } | ||
| 5687 | |||
| 5688 | try zcu.linkerUpdateDecl(decl_index); | ||
| 5689 | } | ||
| 5690 | } | ||
| 5691 | |||
| 5692 | pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void { | ||
| 5693 | const comp = zcu.comp; | ||
| 5694 | |||
| 5695 | const decl = zcu.declPtr(decl_index); | ||
| 5696 | |||
| 5697 | const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool), 0); | ||
| 5698 | defer codegen_prog_node.end(); | ||
| 5699 | |||
| 5700 | if (comp.bin_file) |lf| { | ||
| 5701 | lf.updateDecl(zcu, decl_index) catch |err| switch (err) { | ||
| 5702 | error.OutOfMemory => return error.OutOfMemory, | ||
| 5703 | error.AnalysisFail => { | ||
| 5704 | decl.analysis = .codegen_failure; | ||
| 5705 | }, | ||
| 5706 | else => { | ||
| 5707 | const gpa = zcu.gpa; | ||
| 5708 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 5709 | zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .decl = decl_index }), try ErrorMsg.create( | ||
| 5710 | gpa, | ||
| 5711 | decl.navSrcLoc(zcu), | ||
| 5712 | "unable to codegen: {s}", | ||
| 5713 | .{@errorName(err)}, | ||
| 5714 | )); | ||
| 5715 | decl.analysis = .codegen_failure; | ||
| 5716 | try zcu.retryable_failures.append(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 5717 | }, | ||
| 5718 | }; | ||
| 5719 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 5720 | if (build_options.only_c) unreachable; | ||
| 5721 | llvm_object.updateDecl(zcu, decl_index) catch |err| switch (err) { | ||
| 5722 | error.OutOfMemory => return error.OutOfMemory, | ||
| 5723 | }; | ||
| 5724 | } | ||
| 5725 | } | ||
| 5726 | |||
| 5727 | fn reportRetryableFileError( | ||
| 5728 | zcu: *Zcu, | 4187 | zcu: *Zcu, |
| 5729 | file_index: File.Index, | 4188 | file_index: File.Index, |
| 5730 | comptime format: []const u8, | 4189 | comptime format: []const u8, |
| ... | @@ -5795,344 +4254,6 @@ pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool { | ... | @@ -5795,344 +4254,6 @@ pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool { |
| 5795 | return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature); | 4254 | return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature); |
| 5796 | } | 4255 | } |
| 5797 | 4256 | ||
| 5798 | /// Shortcut for calling `intern_pool.get`. | ||
| 5799 | pub fn intern(mod: *Module, key: InternPool.Key) Allocator.Error!InternPool.Index { | ||
| 5800 | return mod.intern_pool.get(mod.gpa, key); | ||
| 5801 | } | ||
| 5802 | |||
| 5803 | /// Shortcut for calling `intern_pool.getCoerced`. | ||
| 5804 | pub fn getCoerced(mod: *Module, val: Value, new_ty: Type) Allocator.Error!Value { | ||
| 5805 | return Value.fromInterned((try mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), new_ty.toIntern()))); | ||
| 5806 | } | ||
| 5807 | |||
| 5808 | pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type { | ||
| 5809 | return Type.fromInterned((try intern(mod, .{ .int_type = .{ | ||
| 5810 | .signedness = signedness, | ||
| 5811 | .bits = bits, | ||
| 5812 | } }))); | ||
| 5813 | } | ||
| 5814 | |||
| 5815 | pub fn errorIntType(mod: *Module) std.mem.Allocator.Error!Type { | ||
| 5816 | return mod.intType(.unsigned, mod.errorSetBits()); | ||
| 5817 | } | ||
| 5818 | |||
| 5819 | pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type { | ||
| 5820 | const i = try intern(mod, .{ .array_type = info }); | ||
| 5821 | return Type.fromInterned(i); | ||
| 5822 | } | ||
| 5823 | |||
| 5824 | pub fn vectorType(mod: *Module, info: InternPool.Key.VectorType) Allocator.Error!Type { | ||
| 5825 | const i = try intern(mod, .{ .vector_type = info }); | ||
| 5826 | return Type.fromInterned(i); | ||
| 5827 | } | ||
| 5828 | |||
| 5829 | pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error!Type { | ||
| 5830 | const i = try intern(mod, .{ .opt_type = child_type }); | ||
| 5831 | return Type.fromInterned(i); | ||
| 5832 | } | ||
| 5833 | |||
| 5834 | pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type { | ||
| 5835 | var canon_info = info; | ||
| 5836 | |||
| 5837 | if (info.flags.size == .C) canon_info.flags.is_allowzero = true; | ||
| 5838 | |||
| 5839 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee | ||
| 5840 | // type, we change it to 0 here. If this causes an assertion trip because the | ||
| 5841 | // pointee type needs to be resolved more, that needs to be done before calling | ||
| 5842 | // this ptr() function. | ||
| 5843 | if (info.flags.alignment != .none and | ||
| 5844 | info.flags.alignment == Type.fromInterned(info.child).abiAlignment(mod)) | ||
| 5845 | { | ||
| 5846 | canon_info.flags.alignment = .none; | ||
| 5847 | } | ||
| 5848 | |||
| 5849 | switch (info.flags.vector_index) { | ||
| 5850 | // Canonicalize host_size. If it matches the bit size of the pointee type, | ||
| 5851 | // we change it to 0 here. If this causes an assertion trip, the pointee type | ||
| 5852 | // needs to be resolved before calling this ptr() function. | ||
| 5853 | .none => if (info.packed_offset.host_size != 0) { | ||
| 5854 | const elem_bit_size = Type.fromInterned(info.child).bitSize(mod); | ||
| 5855 | assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8); | ||
| 5856 | if (info.packed_offset.host_size * 8 == elem_bit_size) { | ||
| 5857 | canon_info.packed_offset.host_size = 0; | ||
| 5858 | } | ||
| 5859 | }, | ||
| 5860 | .runtime => {}, | ||
| 5861 | _ => assert(@intFromEnum(info.flags.vector_index) < info.packed_offset.host_size), | ||
| 5862 | } | ||
| 5863 | |||
| 5864 | return Type.fromInterned((try intern(mod, .{ .ptr_type = canon_info }))); | ||
| 5865 | } | ||
| 5866 | |||
| 5867 | /// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer | ||
| 5868 | /// child type's alignment is resolved so that an invalid alignment is not used. | ||
| 5869 | /// In general, prefer this function during semantic analysis. | ||
| 5870 | pub fn ptrTypeSema(zcu: *Zcu, info: InternPool.Key.PtrType) SemaError!Type { | ||
| 5871 | if (info.flags.alignment != .none) { | ||
| 5872 | _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(zcu, .sema); | ||
| 5873 | } | ||
| 5874 | return zcu.ptrType(info); | ||
| 5875 | } | ||
| 5876 | |||
| 5877 | pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | ||
| 5878 | return ptrType(mod, .{ .child = child_type.toIntern() }); | ||
| 5879 | } | ||
| 5880 | |||
| 5881 | pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | ||
| 5882 | return ptrType(mod, .{ | ||
| 5883 | .child = child_type.toIntern(), | ||
| 5884 | .flags = .{ | ||
| 5885 | .is_const = true, | ||
| 5886 | }, | ||
| 5887 | }); | ||
| 5888 | } | ||
| 5889 | |||
| 5890 | pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | ||
| 5891 | return ptrType(mod, .{ | ||
| 5892 | .child = child_type.toIntern(), | ||
| 5893 | .flags = .{ | ||
| 5894 | .size = .Many, | ||
| 5895 | .is_const = true, | ||
| 5896 | }, | ||
| 5897 | }); | ||
| 5898 | } | ||
| 5899 | |||
| 5900 | pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type { | ||
| 5901 | var info = ptr_ty.ptrInfo(mod); | ||
| 5902 | info.child = new_child.toIntern(); | ||
| 5903 | return mod.ptrType(info); | ||
| 5904 | } | ||
| 5905 | |||
| 5906 | pub fn funcType(mod: *Module, key: InternPool.GetFuncTypeKey) Allocator.Error!Type { | ||
| 5907 | return Type.fromInterned((try mod.intern_pool.getFuncType(mod.gpa, key))); | ||
| 5908 | } | ||
| 5909 | |||
| 5910 | /// Use this for `anyframe->T` only. | ||
| 5911 | /// For `anyframe`, use the `InternPool.Index.anyframe` tag directly. | ||
| 5912 | pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type { | ||
| 5913 | return Type.fromInterned((try intern(mod, .{ .anyframe_type = payload_ty.toIntern() }))); | ||
| 5914 | } | ||
| 5915 | |||
| 5916 | pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type { | ||
| 5917 | return Type.fromInterned((try intern(mod, .{ .error_union_type = .{ | ||
| 5918 | .error_set_type = error_set_ty.toIntern(), | ||
| 5919 | .payload_type = payload_ty.toIntern(), | ||
| 5920 | } }))); | ||
| 5921 | } | ||
| 5922 | |||
| 5923 | pub fn singleErrorSetType(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type { | ||
| 5924 | const names: *const [1]InternPool.NullTerminatedString = &name; | ||
| 5925 | const new_ty = try mod.intern_pool.getErrorSetType(mod.gpa, names); | ||
| 5926 | return Type.fromInterned(new_ty); | ||
| 5927 | } | ||
| 5928 | |||
| 5929 | /// Sorts `names` in place. | ||
| 5930 | pub fn errorSetFromUnsortedNames( | ||
| 5931 | mod: *Module, | ||
| 5932 | names: []InternPool.NullTerminatedString, | ||
| 5933 | ) Allocator.Error!Type { | ||
| 5934 | std.mem.sort( | ||
| 5935 | InternPool.NullTerminatedString, | ||
| 5936 | names, | ||
| 5937 | {}, | ||
| 5938 | InternPool.NullTerminatedString.indexLessThan, | ||
| 5939 | ); | ||
| 5940 | const new_ty = try mod.intern_pool.getErrorSetType(mod.gpa, names); | ||
| 5941 | return Type.fromInterned(new_ty); | ||
| 5942 | } | ||
| 5943 | |||
| 5944 | /// Supports only pointers, not pointer-like optionals. | ||
| 5945 | pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value { | ||
| 5946 | assert(ty.zigTypeTag(mod) == .Pointer and !ty.isSlice(mod)); | ||
| 5947 | assert(x != 0 or ty.isAllowzeroPtr(mod)); | ||
| 5948 | const i = try intern(mod, .{ .ptr = .{ | ||
| 5949 | .ty = ty.toIntern(), | ||
| 5950 | .base_addr = .int, | ||
| 5951 | .byte_offset = x, | ||
| 5952 | } }); | ||
| 5953 | return Value.fromInterned(i); | ||
| 5954 | } | ||
| 5955 | |||
| 5956 | /// Creates an enum tag value based on the integer tag value. | ||
| 5957 | pub fn enumValue(mod: *Module, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value { | ||
| 5958 | if (std.debug.runtime_safety) { | ||
| 5959 | const tag = ty.zigTypeTag(mod); | ||
| 5960 | assert(tag == .Enum); | ||
| 5961 | } | ||
| 5962 | const i = try intern(mod, .{ .enum_tag = .{ | ||
| 5963 | .ty = ty.toIntern(), | ||
| 5964 | .int = tag_int, | ||
| 5965 | } }); | ||
| 5966 | return Value.fromInterned(i); | ||
| 5967 | } | ||
| 5968 | |||
| 5969 | /// Creates an enum tag value based on the field index according to source code | ||
| 5970 | /// declaration order. | ||
| 5971 | pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.Error!Value { | ||
| 5972 | const ip = &mod.intern_pool; | ||
| 5973 | const gpa = mod.gpa; | ||
| 5974 | const enum_type = ip.loadEnumType(ty.toIntern()); | ||
| 5975 | |||
| 5976 | if (enum_type.values.len == 0) { | ||
| 5977 | // Auto-numbered fields. | ||
| 5978 | return Value.fromInterned((try ip.get(gpa, .{ .enum_tag = .{ | ||
| 5979 | .ty = ty.toIntern(), | ||
| 5980 | .int = try ip.get(gpa, .{ .int = .{ | ||
| 5981 | .ty = enum_type.tag_ty, | ||
| 5982 | .storage = .{ .u64 = field_index }, | ||
| 5983 | } }), | ||
| 5984 | } }))); | ||
| 5985 | } | ||
| 5986 | |||
| 5987 | return Value.fromInterned((try ip.get(gpa, .{ .enum_tag = .{ | ||
| 5988 | .ty = ty.toIntern(), | ||
| 5989 | .int = enum_type.values.get(ip)[field_index], | ||
| 5990 | } }))); | ||
| 5991 | } | ||
| 5992 | |||
| 5993 | pub fn undefValue(mod: *Module, ty: Type) Allocator.Error!Value { | ||
| 5994 | return Value.fromInterned((try mod.intern(.{ .undef = ty.toIntern() }))); | ||
| 5995 | } | ||
| 5996 | |||
| 5997 | pub fn undefRef(mod: *Module, ty: Type) Allocator.Error!Air.Inst.Ref { | ||
| 5998 | return Air.internedToRef((try mod.undefValue(ty)).toIntern()); | ||
| 5999 | } | ||
| 6000 | |||
| 6001 | pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { | ||
| 6002 | if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); | ||
| 6003 | if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); | ||
| 6004 | var limbs_buffer: [4]usize = undefined; | ||
| 6005 | var big_int = BigIntMutable.init(&limbs_buffer, x); | ||
| 6006 | return intValue_big(mod, ty, big_int.toConst()); | ||
| 6007 | } | ||
| 6008 | |||
| 6009 | pub fn intRef(mod: *Module, ty: Type, x: anytype) Allocator.Error!Air.Inst.Ref { | ||
| 6010 | return Air.internedToRef((try mod.intValue(ty, x)).toIntern()); | ||
| 6011 | } | ||
| 6012 | |||
| 6013 | pub fn intValue_big(mod: *Module, ty: Type, x: BigIntConst) Allocator.Error!Value { | ||
| 6014 | const i = try intern(mod, .{ .int = .{ | ||
| 6015 | .ty = ty.toIntern(), | ||
| 6016 | .storage = .{ .big_int = x }, | ||
| 6017 | } }); | ||
| 6018 | return Value.fromInterned(i); | ||
| 6019 | } | ||
| 6020 | |||
| 6021 | pub fn intValue_u64(mod: *Module, ty: Type, x: u64) Allocator.Error!Value { | ||
| 6022 | const i = try intern(mod, .{ .int = .{ | ||
| 6023 | .ty = ty.toIntern(), | ||
| 6024 | .storage = .{ .u64 = x }, | ||
| 6025 | } }); | ||
| 6026 | return Value.fromInterned(i); | ||
| 6027 | } | ||
| 6028 | |||
| 6029 | pub fn intValue_i64(mod: *Module, ty: Type, x: i64) Allocator.Error!Value { | ||
| 6030 | const i = try intern(mod, .{ .int = .{ | ||
| 6031 | .ty = ty.toIntern(), | ||
| 6032 | .storage = .{ .i64 = x }, | ||
| 6033 | } }); | ||
| 6034 | return Value.fromInterned(i); | ||
| 6035 | } | ||
| 6036 | |||
| 6037 | pub fn unionValue(mod: *Module, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value { | ||
| 6038 | const i = try intern(mod, .{ .un = .{ | ||
| 6039 | .ty = union_ty.toIntern(), | ||
| 6040 | .tag = tag.toIntern(), | ||
| 6041 | .val = val.toIntern(), | ||
| 6042 | } }); | ||
| 6043 | return Value.fromInterned(i); | ||
| 6044 | } | ||
| 6045 | |||
| 6046 | /// This function casts the float representation down to the representation of the type, potentially | ||
| 6047 | /// losing data if the representation wasn't correct. | ||
| 6048 | pub fn floatValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { | ||
| 6049 | const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(mod.getTarget())) { | ||
| 6050 | 16 => .{ .f16 = @as(f16, @floatCast(x)) }, | ||
| 6051 | 32 => .{ .f32 = @as(f32, @floatCast(x)) }, | ||
| 6052 | 64 => .{ .f64 = @as(f64, @floatCast(x)) }, | ||
| 6053 | 80 => .{ .f80 = @as(f80, @floatCast(x)) }, | ||
| 6054 | 128 => .{ .f128 = @as(f128, @floatCast(x)) }, | ||
| 6055 | else => unreachable, | ||
| 6056 | }; | ||
| 6057 | const i = try intern(mod, .{ .float = .{ | ||
| 6058 | .ty = ty.toIntern(), | ||
| 6059 | .storage = storage, | ||
| 6060 | } }); | ||
| 6061 | return Value.fromInterned(i); | ||
| 6062 | } | ||
| 6063 | |||
| 6064 | pub fn nullValue(mod: *Module, opt_ty: Type) Allocator.Error!Value { | ||
| 6065 | const ip = &mod.intern_pool; | ||
| 6066 | assert(ip.isOptionalType(opt_ty.toIntern())); | ||
| 6067 | const result = try ip.get(mod.gpa, .{ .opt = .{ | ||
| 6068 | .ty = opt_ty.toIntern(), | ||
| 6069 | .val = .none, | ||
| 6070 | } }); | ||
| 6071 | return Value.fromInterned(result); | ||
| 6072 | } | ||
| 6073 | |||
| 6074 | pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type { | ||
| 6075 | return intType(mod, .unsigned, Type.smallestUnsignedBits(max)); | ||
| 6076 | } | ||
| 6077 | |||
| 6078 | /// Returns the smallest possible integer type containing both `min` and | ||
| 6079 | /// `max`. Asserts that neither value is undef. | ||
| 6080 | /// TODO: if #3806 is implemented, this becomes trivial | ||
| 6081 | pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type { | ||
| 6082 | assert(!min.isUndef(mod)); | ||
| 6083 | assert(!max.isUndef(mod)); | ||
| 6084 | |||
| 6085 | if (std.debug.runtime_safety) { | ||
| 6086 | assert(Value.order(min, max, mod).compare(.lte)); | ||
| 6087 | } | ||
| 6088 | |||
| 6089 | const sign = min.orderAgainstZero(mod) == .lt; | ||
| 6090 | |||
| 6091 | const min_val_bits = intBitsForValue(mod, min, sign); | ||
| 6092 | const max_val_bits = intBitsForValue(mod, max, sign); | ||
| 6093 | |||
| 6094 | return mod.intType( | ||
| 6095 | if (sign) .signed else .unsigned, | ||
| 6096 | @max(min_val_bits, max_val_bits), | ||
| 6097 | ); | ||
| 6098 | } | ||
| 6099 | |||
| 6100 | /// Given a value representing an integer, returns the number of bits necessary to represent | ||
| 6101 | /// this value in an integer. If `sign` is true, returns the number of bits necessary in a | ||
| 6102 | /// twos-complement integer; otherwise in an unsigned integer. | ||
| 6103 | /// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true. | ||
| 6104 | pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 { | ||
| 6105 | assert(!val.isUndef(mod)); | ||
| 6106 | |||
| 6107 | const key = mod.intern_pool.indexToKey(val.toIntern()); | ||
| 6108 | switch (key.int.storage) { | ||
| 6109 | .i64 => |x| { | ||
| 6110 | if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted) + @intFromBool(sign); | ||
| 6111 | assert(sign); | ||
| 6112 | // Protect against overflow in the following negation. | ||
| 6113 | if (x == std.math.minInt(i64)) return 64; | ||
| 6114 | return Type.smallestUnsignedBits(@as(u64, @intCast(-(x + 1)))) + 1; | ||
| 6115 | }, | ||
| 6116 | .u64 => |x| { | ||
| 6117 | return Type.smallestUnsignedBits(x) + @intFromBool(sign); | ||
| 6118 | }, | ||
| 6119 | .big_int => |big| { | ||
| 6120 | if (big.positive) return @as(u16, @intCast(big.bitCountAbs() + @intFromBool(sign))); | ||
| 6121 | |||
| 6122 | // Zero is still a possibility, in which case unsigned is fine | ||
| 6123 | if (big.eqlZero()) return 0; | ||
| 6124 | |||
| 6125 | return @as(u16, @intCast(big.bitCountTwosComp())); | ||
| 6126 | }, | ||
| 6127 | .lazy_align => |lazy_ty| { | ||
| 6128 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(mod).toByteUnits() orelse 0) + @intFromBool(sign); | ||
| 6129 | }, | ||
| 6130 | .lazy_size => |lazy_ty| { | ||
| 6131 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(mod)) + @intFromBool(sign); | ||
| 6132 | }, | ||
| 6133 | } | ||
| 6134 | } | ||
| 6135 | |||
| 6136 | pub const AtomicPtrAlignmentError = error{ | 4257 | pub const AtomicPtrAlignmentError = error{ |
| 6137 | FloatTooBig, | 4258 | FloatTooBig, |
| 6138 | IntTooBig, | 4259 | IntTooBig, |
| ... | @@ -6371,101 +4492,6 @@ pub const UnionLayout = struct { | ... | @@ -6371,101 +4492,6 @@ pub const UnionLayout = struct { |
| 6371 | padding: u32, | 4492 | padding: u32, |
| 6372 | }; | 4493 | }; |
| 6373 | 4494 | ||
| 6374 | pub fn getUnionLayout(mod: *Module, loaded_union: InternPool.LoadedUnionType) UnionLayout { | ||
| 6375 | const ip = &mod.intern_pool; | ||
| 6376 | assert(loaded_union.haveLayout(ip)); | ||
| 6377 | var most_aligned_field: u32 = undefined; | ||
| 6378 | var most_aligned_field_size: u64 = undefined; | ||
| 6379 | var biggest_field: u32 = undefined; | ||
| 6380 | var payload_size: u64 = 0; | ||
| 6381 | var payload_align: Alignment = .@"1"; | ||
| 6382 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { | ||
| 6383 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue; | ||
| 6384 | |||
| 6385 | const explicit_align = loaded_union.fieldAlign(ip, field_index); | ||
| 6386 | const field_align = if (explicit_align != .none) | ||
| 6387 | explicit_align | ||
| 6388 | else | ||
| 6389 | Type.fromInterned(field_ty).abiAlignment(mod); | ||
| 6390 | const field_size = Type.fromInterned(field_ty).abiSize(mod); | ||
| 6391 | if (field_size > payload_size) { | ||
| 6392 | payload_size = field_size; | ||
| 6393 | biggest_field = @intCast(field_index); | ||
| 6394 | } | ||
| 6395 | if (field_align.compare(.gte, payload_align)) { | ||
| 6396 | payload_align = field_align; | ||
| 6397 | most_aligned_field = @intCast(field_index); | ||
| 6398 | most_aligned_field_size = field_size; | ||
| 6399 | } | ||
| 6400 | } | ||
| 6401 | const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); | ||
| 6402 | if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(mod)) { | ||
| 6403 | return .{ | ||
| 6404 | .abi_size = payload_align.forward(payload_size), | ||
| 6405 | .abi_align = payload_align, | ||
| 6406 | .most_aligned_field = most_aligned_field, | ||
| 6407 | .most_aligned_field_size = most_aligned_field_size, | ||
| 6408 | .biggest_field = biggest_field, | ||
| 6409 | .payload_size = payload_size, | ||
| 6410 | .payload_align = payload_align, | ||
| 6411 | .tag_align = .none, | ||
| 6412 | .tag_size = 0, | ||
| 6413 | .padding = 0, | ||
| 6414 | }; | ||
| 6415 | } | ||
| 6416 | |||
| 6417 | const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(mod); | ||
| 6418 | const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(mod).max(.@"1"); | ||
| 6419 | return .{ | ||
| 6420 | .abi_size = loaded_union.size(ip).*, | ||
| 6421 | .abi_align = tag_align.max(payload_align), | ||
| 6422 | .most_aligned_field = most_aligned_field, | ||
| 6423 | .most_aligned_field_size = most_aligned_field_size, | ||
| 6424 | .biggest_field = biggest_field, | ||
| 6425 | .payload_size = payload_size, | ||
| 6426 | .payload_align = payload_align, | ||
| 6427 | .tag_align = tag_align, | ||
| 6428 | .tag_size = tag_size, | ||
| 6429 | .padding = loaded_union.padding(ip).*, | ||
| 6430 | }; | ||
| 6431 | } | ||
| 6432 | |||
| 6433 | pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 { | ||
| 6434 | return mod.getUnionLayout(loaded_union).abi_size; | ||
| 6435 | } | ||
| 6436 | |||
| 6437 | /// Returns 0 if the union is represented with 0 bits at runtime. | ||
| 6438 | pub fn unionAbiAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType) Alignment { | ||
| 6439 | const ip = &mod.intern_pool; | ||
| 6440 | const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); | ||
| 6441 | var max_align: Alignment = .none; | ||
| 6442 | if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(mod); | ||
| 6443 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { | ||
| 6444 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | ||
| 6445 | |||
| 6446 | const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); | ||
| 6447 | max_align = max_align.max(field_align); | ||
| 6448 | } | ||
| 6449 | return max_align; | ||
| 6450 | } | ||
| 6451 | |||
| 6452 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | ||
| 6453 | pub fn unionFieldNormalAlignment(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment { | ||
| 6454 | return zcu.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable; | ||
| 6455 | } | ||
| 6456 | |||
| 6457 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | ||
| 6458 | /// If `strat` is `.sema`, may perform type resolution. | ||
| 6459 | pub fn unionFieldNormalAlignmentAdvanced(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32, strat: Type.ResolveStrat) SemaError!Alignment { | ||
| 6460 | const ip = &zcu.intern_pool; | ||
| 6461 | assert(loaded_union.flagsPtr(ip).layout != .@"packed"); | ||
| 6462 | const field_align = loaded_union.fieldAlign(ip, field_index); | ||
| 6463 | if (field_align != .none) return field_align; | ||
| 6464 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | ||
| 6465 | if (field_ty.isNoReturn(zcu)) return .none; | ||
| 6466 | return (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar; | ||
| 6467 | } | ||
| 6468 | |||
| 6469 | /// Returns the index of the active field, given the current tag value | 4495 | /// Returns the index of the active field, given the current tag value |
| 6470 | pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { | 4496 | pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { |
| 6471 | const ip = &mod.intern_pool; | 4497 | const ip = &mod.intern_pool; |
| ... | @@ -6474,63 +4500,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType | ... | @@ -6474,63 +4500,6 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType |
| 6474 | return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern()); | 4500 | return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern()); |
| 6475 | } | 4501 | } |
| 6476 | 4502 | ||
| 6477 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | ||
| 6478 | pub fn structFieldAlignment( | ||
| 6479 | zcu: *Zcu, | ||
| 6480 | explicit_alignment: InternPool.Alignment, | ||
| 6481 | field_ty: Type, | ||
| 6482 | layout: std.builtin.Type.ContainerLayout, | ||
| 6483 | ) Alignment { | ||
| 6484 | return zcu.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable; | ||
| 6485 | } | ||
| 6486 | |||
| 6487 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | ||
| 6488 | /// If `strat` is `.sema`, may perform type resolution. | ||
| 6489 | pub fn structFieldAlignmentAdvanced( | ||
| 6490 | zcu: *Zcu, | ||
| 6491 | explicit_alignment: InternPool.Alignment, | ||
| 6492 | field_ty: Type, | ||
| 6493 | layout: std.builtin.Type.ContainerLayout, | ||
| 6494 | strat: Type.ResolveStrat, | ||
| 6495 | ) SemaError!Alignment { | ||
| 6496 | assert(layout != .@"packed"); | ||
| 6497 | if (explicit_alignment != .none) return explicit_alignment; | ||
| 6498 | const ty_abi_align = (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar; | ||
| 6499 | switch (layout) { | ||
| 6500 | .@"packed" => unreachable, | ||
| 6501 | .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align, | ||
| 6502 | .@"extern" => {}, | ||
| 6503 | } | ||
| 6504 | // extern | ||
| 6505 | if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) { | ||
| 6506 | return ty_abi_align.maxStrict(.@"16"); | ||
| 6507 | } | ||
| 6508 | return ty_abi_align; | ||
| 6509 | } | ||
| 6510 | |||
| 6511 | /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets | ||
| 6512 | /// into the packed struct InternPool data rather than computing this on the | ||
| 6513 | /// fly, however it was found to perform worse when measured on real world | ||
| 6514 | /// projects. | ||
| 6515 | pub fn structPackedFieldBitOffset( | ||
| 6516 | mod: *Module, | ||
| 6517 | struct_type: InternPool.LoadedStructType, | ||
| 6518 | field_index: u32, | ||
| 6519 | ) u16 { | ||
| 6520 | const ip = &mod.intern_pool; | ||
| 6521 | assert(struct_type.layout == .@"packed"); | ||
| 6522 | assert(struct_type.haveLayout(ip)); | ||
| 6523 | var bit_sum: u64 = 0; | ||
| 6524 | for (0..struct_type.field_types.len) |i| { | ||
| 6525 | if (i == field_index) { | ||
| 6526 | return @intCast(bit_sum); | ||
| 6527 | } | ||
| 6528 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | ||
| 6529 | bit_sum += field_ty.bitSize(mod); | ||
| 6530 | } | ||
| 6531 | unreachable; // index out of bounds | ||
| 6532 | } | ||
| 6533 | |||
| 6534 | pub const ResolvedReference = struct { | 4503 | pub const ResolvedReference = struct { |
| 6535 | referencer: AnalUnit, | 4504 | referencer: AnalUnit, |
| 6536 | src: LazySrcLoc, | 4505 | src: LazySrcLoc, |
| ... | @@ -6564,33 +4533,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved | ... | @@ -6564,33 +4533,6 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved |
| 6564 | return result; | 4533 | return result; |
| 6565 | } | 4534 | } |
| 6566 | 4535 | ||
| 6567 | pub fn getBuiltin(zcu: *Zcu, name: []const u8) Allocator.Error!Air.Inst.Ref { | ||
| 6568 | const decl_index = try zcu.getBuiltinDecl(name); | ||
| 6569 | zcu.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt"); | ||
| 6570 | return Air.internedToRef(zcu.declPtr(decl_index).val.toIntern()); | ||
| 6571 | } | ||
| 6572 | |||
| 6573 | pub fn getBuiltinDecl(zcu: *Zcu, name: []const u8) Allocator.Error!InternPool.DeclIndex { | ||
| 6574 | const gpa = zcu.gpa; | ||
| 6575 | const ip = &zcu.intern_pool; | ||
| 6576 | const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig"); | ||
| 6577 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?; | ||
| 6578 | const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?; | ||
| 6579 | const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); | ||
| 6580 | const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'"); | ||
| 6581 | zcu.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt"); | ||
| 6582 | const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt"); | ||
| 6583 | const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls); | ||
| 6584 | return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt"); | ||
| 6585 | } | ||
| 6586 | |||
| 6587 | pub fn getBuiltinType(zcu: *Zcu, name: []const u8) Allocator.Error!Type { | ||
| 6588 | const ty_inst = try zcu.getBuiltin(name); | ||
| 6589 | const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt")); | ||
| 6590 | ty.resolveFully(zcu) catch @panic("std.builtin is corrupt"); | ||
| 6591 | return ty; | ||
| 6592 | } | ||
| 6593 | |||
| 6594 | pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File { | 4536 | pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File { |
| 6595 | return zcu.import_table.values()[@intFromEnum(i)]; | 4537 | return zcu.import_table.values()[@intFromEnum(i)]; |
| 6596 | } | 4538 | } |
src/Zcu/PerThread.zig created+2102| ... | @@ -0,0 +1,2102 @@ | ||
| 1 | zcu: *Zcu, | ||
| 2 | |||
| 3 | /// Dense, per-thread unique index. | ||
| 4 | tid: Id, | ||
| 5 | |||
| 6 | pub const Id = if (builtin.single_threaded) enum { main } else enum(usize) { main, _ }; | ||
| 7 | |||
| 8 | /// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl. | ||
| 9 | pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ||
| 10 | if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| { | ||
| 11 | return pt.ensureDeclAnalyzed(existing_root); | ||
| 12 | } else { | ||
| 13 | return pt.semaFile(file_index); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | /// This ensures that the Decl will have an up-to-date Type and Value populated. | ||
| 18 | /// However the resolution status of the Type may not be fully resolved. | ||
| 19 | /// For example an inferred error set is not resolved until after `analyzeFnBody`. | ||
| 20 | /// is called. | ||
| 21 | pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.SemaError!void { | ||
| 22 | const tracy = trace(@src()); | ||
| 23 | defer tracy.end(); | ||
| 24 | |||
| 25 | const mod = pt.zcu; | ||
| 26 | const ip = &mod.intern_pool; | ||
| 27 | const decl = mod.declPtr(decl_index); | ||
| 28 | |||
| 29 | log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{ | ||
| 30 | @intFromEnum(decl_index), | ||
| 31 | decl.name.fmt(ip), | ||
| 32 | }); | ||
| 33 | |||
| 34 | // Determine whether or not this Decl is outdated, i.e. requires re-analysis | ||
| 35 | // even if `complete`. If a Decl is PO, we pessismistically assume that it | ||
| 36 | // *does* require re-analysis, to ensure that the Decl is definitely | ||
| 37 | // up-to-date when this function returns. | ||
| 38 | |||
| 39 | // If analysis occurs in a poor order, this could result in over-analysis. | ||
| 40 | // We do our best to avoid this by the other dependency logic in this file | ||
| 41 | // which tries to limit re-analysis to Decls whose previously listed | ||
| 42 | // dependencies are all up-to-date. | ||
| 43 | |||
| 44 | const decl_as_depender = InternPool.AnalUnit.wrap(.{ .decl = decl_index }); | ||
| 45 | const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or | ||
| 46 | mod.potentially_outdated.swapRemove(decl_as_depender); | ||
| 47 | |||
| 48 | if (decl_was_outdated) { | ||
| 49 | _ = mod.outdated_ready.swapRemove(decl_as_depender); | ||
| 50 | } | ||
| 51 | |||
| 52 | const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated; | ||
| 53 | |||
| 54 | switch (decl.analysis) { | ||
| 55 | .in_progress => unreachable, | ||
| 56 | |||
| 57 | .file_failure => return error.AnalysisFail, | ||
| 58 | |||
| 59 | .sema_failure, | ||
| 60 | .dependency_failure, | ||
| 61 | .codegen_failure, | ||
| 62 | => if (!was_outdated) return error.AnalysisFail, | ||
| 63 | |||
| 64 | .complete => if (!was_outdated) return, | ||
| 65 | |||
| 66 | .unreferenced => {}, | ||
| 67 | } | ||
| 68 | |||
| 69 | if (was_outdated) { | ||
| 70 | // The exports this Decl performs will be re-discovered, so we remove them here | ||
| 71 | // prior to re-analysis. | ||
| 72 | if (build_options.only_c) unreachable; | ||
| 73 | mod.deleteUnitExports(decl_as_depender); | ||
| 74 | mod.deleteUnitReferences(decl_as_depender); | ||
| 75 | } | ||
| 76 | |||
| 77 | const sema_result: Zcu.SemaDeclResult = blk: { | ||
| 78 | if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) { | ||
| 79 | // Anonymous decl. We don't semantically analyze these. | ||
| 80 | break :blk .{ | ||
| 81 | .invalidate_decl_val = false, | ||
| 82 | .invalidate_decl_ref = false, | ||
| 83 | }; | ||
| 84 | } | ||
| 85 | |||
| 86 | if (mod.declIsRoot(decl_index)) { | ||
| 87 | const changed = try pt.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated); | ||
| 88 | break :blk .{ | ||
| 89 | .invalidate_decl_val = changed, | ||
| 90 | .invalidate_decl_ref = changed, | ||
| 91 | }; | ||
| 92 | } | ||
| 93 | |||
| 94 | const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0); | ||
| 95 | defer decl_prog_node.end(); | ||
| 96 | |||
| 97 | break :blk pt.semaDecl(decl_index) catch |err| switch (err) { | ||
| 98 | error.AnalysisFail => { | ||
| 99 | if (decl.analysis == .in_progress) { | ||
| 100 | // If this decl caused the compile error, the analysis field would | ||
| 101 | // be changed to indicate it was this Decl's fault. Because this | ||
| 102 | // did not happen, we infer here that it was a dependency failure. | ||
| 103 | decl.analysis = .dependency_failure; | ||
| 104 | } | ||
| 105 | return error.AnalysisFail; | ||
| 106 | }, | ||
| 107 | error.GenericPoison => unreachable, | ||
| 108 | else => |e| { | ||
| 109 | decl.analysis = .sema_failure; | ||
| 110 | try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1); | ||
| 111 | try mod.retryable_failures.append(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 112 | mod.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create( | ||
| 113 | mod.gpa, | ||
| 114 | decl.navSrcLoc(mod), | ||
| 115 | "unable to analyze: {s}", | ||
| 116 | .{@errorName(e)}, | ||
| 117 | )); | ||
| 118 | return error.AnalysisFail; | ||
| 119 | }, | ||
| 120 | }; | ||
| 121 | }; | ||
| 122 | |||
| 123 | // TODO: we do not yet have separate dependencies for decl values vs types. | ||
| 124 | if (decl_was_outdated) { | ||
| 125 | if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) { | ||
| 126 | log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)}); | ||
| 127 | // This dependency was marked as PO, meaning dependees were waiting | ||
| 128 | // on its analysis result, and it has turned out to be outdated. | ||
| 129 | // Update dependees accordingly. | ||
| 130 | try mod.markDependeeOutdated(.{ .decl_val = decl_index }); | ||
| 131 | } else { | ||
| 132 | log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)}); | ||
| 133 | // This dependency was previously PO, but turned out to be up-to-date. | ||
| 134 | // We do not need to queue successive analysis. | ||
| 135 | try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index }); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: InternPool.Index) Zcu.SemaError!void { | ||
| 141 | const tracy = trace(@src()); | ||
| 142 | defer tracy.end(); | ||
| 143 | |||
| 144 | const zcu = pt.zcu; | ||
| 145 | const gpa = zcu.gpa; | ||
| 146 | const ip = &zcu.intern_pool; | ||
| 147 | |||
| 148 | // We only care about the uncoerced function. | ||
| 149 | // We need to do this for the "orphaned function" check below to be valid. | ||
| 150 | const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index); | ||
| 151 | |||
| 152 | const func = zcu.funcInfo(maybe_coerced_func_index); | ||
| 153 | const decl_index = func.owner_decl; | ||
| 154 | const decl = zcu.declPtr(decl_index); | ||
| 155 | |||
| 156 | log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{ | ||
| 157 | @intFromEnum(func_index), | ||
| 158 | decl.name.fmt(ip), | ||
| 159 | }); | ||
| 160 | |||
| 161 | // First, our owner decl must be up-to-date. This will always be the case | ||
| 162 | // during the first update, but may not on successive updates if we happen | ||
| 163 | // to get analyzed before our parent decl. | ||
| 164 | try pt.ensureDeclAnalyzed(decl_index); | ||
| 165 | |||
| 166 | // On an update, it's possible this function changed such that our owner | ||
| 167 | // decl now refers to a different function, making this one orphaned. If | ||
| 168 | // that's the case, we should remove this function from the binary. | ||
| 169 | if (decl.val.ip_index != func_index) { | ||
| 170 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); | ||
| 171 | ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index })); | ||
| 172 | ip.remove(func_index); | ||
| 173 | @panic("TODO: remove orphaned function from binary"); | ||
| 174 | } | ||
| 175 | |||
| 176 | // We'll want to remember what the IES used to be before the update for | ||
| 177 | // dependency invalidation purposes. | ||
| 178 | const old_resolved_ies = if (func.analysis(ip).inferred_error_set) | ||
| 179 | func.resolvedErrorSet(ip).* | ||
| 180 | else | ||
| 181 | .none; | ||
| 182 | |||
| 183 | switch (decl.analysis) { | ||
| 184 | .unreferenced => unreachable, | ||
| 185 | .in_progress => unreachable, | ||
| 186 | |||
| 187 | .codegen_failure => unreachable, // functions do not perform constant value generation | ||
| 188 | |||
| 189 | .file_failure, | ||
| 190 | .sema_failure, | ||
| 191 | .dependency_failure, | ||
| 192 | => return error.AnalysisFail, | ||
| 193 | |||
| 194 | .complete => {}, | ||
| 195 | } | ||
| 196 | |||
| 197 | const func_as_depender = InternPool.AnalUnit.wrap(.{ .func = func_index }); | ||
| 198 | const was_outdated = zcu.outdated.swapRemove(func_as_depender) or | ||
| 199 | zcu.potentially_outdated.swapRemove(func_as_depender); | ||
| 200 | |||
| 201 | if (was_outdated) { | ||
| 202 | if (build_options.only_c) unreachable; | ||
| 203 | _ = zcu.outdated_ready.swapRemove(func_as_depender); | ||
| 204 | zcu.deleteUnitExports(func_as_depender); | ||
| 205 | zcu.deleteUnitReferences(func_as_depender); | ||
| 206 | } | ||
| 207 | |||
| 208 | switch (func.analysis(ip).state) { | ||
| 209 | .success => if (!was_outdated) return, | ||
| 210 | .sema_failure, | ||
| 211 | .dependency_failure, | ||
| 212 | .codegen_failure, | ||
| 213 | => if (!was_outdated) return error.AnalysisFail, | ||
| 214 | .none, .queued => {}, | ||
| 215 | .in_progress => unreachable, | ||
| 216 | .inline_only => unreachable, // don't queue work for this | ||
| 217 | } | ||
| 218 | |||
| 219 | log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{ | ||
| 220 | @intFromEnum(func_index), | ||
| 221 | if (was_outdated) "outdated" else "never analyzed", | ||
| 222 | }); | ||
| 223 | |||
| 224 | var tmp_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 225 | defer tmp_arena.deinit(); | ||
| 226 | const sema_arena = tmp_arena.allocator(); | ||
| 227 | |||
| 228 | var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) { | ||
| 229 | error.AnalysisFail => { | ||
| 230 | if (func.analysis(ip).state == .in_progress) { | ||
| 231 | // If this decl caused the compile error, the analysis field would | ||
| 232 | // be changed to indicate it was this Decl's fault. Because this | ||
| 233 | // did not happen, we infer here that it was a dependency failure. | ||
| 234 | func.analysis(ip).state = .dependency_failure; | ||
| 235 | } | ||
| 236 | return error.AnalysisFail; | ||
| 237 | }, | ||
| 238 | error.OutOfMemory => return error.OutOfMemory, | ||
| 239 | }; | ||
| 240 | errdefer air.deinit(gpa); | ||
| 241 | |||
| 242 | const invalidate_ies_deps = i: { | ||
| 243 | if (!was_outdated) break :i false; | ||
| 244 | if (!func.analysis(ip).inferred_error_set) break :i true; | ||
| 245 | const new_resolved_ies = func.resolvedErrorSet(ip).*; | ||
| 246 | break :i new_resolved_ies != old_resolved_ies; | ||
| 247 | }; | ||
| 248 | if (invalidate_ies_deps) { | ||
| 249 | log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)}); | ||
| 250 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); | ||
| 251 | } else if (was_outdated) { | ||
| 252 | log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)}); | ||
| 253 | try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }); | ||
| 254 | } | ||
| 255 | |||
| 256 | const comp = zcu.comp; | ||
| 257 | |||
| 258 | const dump_air = build_options.enable_debug_extensions and comp.verbose_air; | ||
| 259 | const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null); | ||
| 260 | |||
| 261 | if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) { | ||
| 262 | air.deinit(gpa); | ||
| 263 | return; | ||
| 264 | } | ||
| 265 | |||
| 266 | try comp.work_queue.writeItem(.{ .codegen_func = .{ | ||
| 267 | .func = func_index, | ||
| 268 | .air = air, | ||
| 269 | } }); | ||
| 270 | } | ||
| 271 | |||
| 272 | /// Takes ownership of `air`, even on error. | ||
| 273 | /// If any types referenced by `air` are unresolved, marks the codegen as failed. | ||
| 274 | pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Air) Allocator.Error!void { | ||
| 275 | const zcu = pt.zcu; | ||
| 276 | const gpa = zcu.gpa; | ||
| 277 | const ip = &zcu.intern_pool; | ||
| 278 | const comp = zcu.comp; | ||
| 279 | |||
| 280 | defer { | ||
| 281 | var air_mut = air; | ||
| 282 | air_mut.deinit(gpa); | ||
| 283 | } | ||
| 284 | |||
| 285 | const func = zcu.funcInfo(func_index); | ||
| 286 | const decl_index = func.owner_decl; | ||
| 287 | const decl = zcu.declPtr(decl_index); | ||
| 288 | |||
| 289 | var liveness = try Liveness.analyze(gpa, air, ip); | ||
| 290 | defer liveness.deinit(gpa); | ||
| 291 | |||
| 292 | if (build_options.enable_debug_extensions and comp.verbose_air) { | ||
| 293 | const fqn = try decl.fullyQualifiedName(zcu); | ||
| 294 | std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)}); | ||
| 295 | @import("../print_air.zig").dump(pt, air, liveness); | ||
| 296 | std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)}); | ||
| 297 | } | ||
| 298 | |||
| 299 | if (std.debug.runtime_safety) { | ||
| 300 | var verify: Liveness.Verify = .{ | ||
| 301 | .gpa = gpa, | ||
| 302 | .air = air, | ||
| 303 | .liveness = liveness, | ||
| 304 | .intern_pool = ip, | ||
| 305 | }; | ||
| 306 | defer verify.deinit(); | ||
| 307 | |||
| 308 | verify.verify() catch |err| switch (err) { | ||
| 309 | error.OutOfMemory => return error.OutOfMemory, | ||
| 310 | else => { | ||
| 311 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 312 | zcu.failed_analysis.putAssumeCapacityNoClobber( | ||
| 313 | InternPool.AnalUnit.wrap(.{ .func = func_index }), | ||
| 314 | try Zcu.ErrorMsg.create( | ||
| 315 | gpa, | ||
| 316 | decl.navSrcLoc(zcu), | ||
| 317 | "invalid liveness: {s}", | ||
| 318 | .{@errorName(err)}, | ||
| 319 | ), | ||
| 320 | ); | ||
| 321 | func.analysis(ip).state = .codegen_failure; | ||
| 322 | return; | ||
| 323 | }, | ||
| 324 | }; | ||
| 325 | } | ||
| 326 | |||
| 327 | const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0); | ||
| 328 | defer codegen_prog_node.end(); | ||
| 329 | |||
| 330 | if (!air.typesFullyResolved(zcu)) { | ||
| 331 | // A type we depend on failed to resolve. This is a transitive failure. | ||
| 332 | // Correcting this failure will involve changing a type this function | ||
| 333 | // depends on, hence triggering re-analysis of this function, so this | ||
| 334 | // interacts correctly with incremental compilation. | ||
| 335 | func.analysis(ip).state = .codegen_failure; | ||
| 336 | } else if (comp.bin_file) |lf| { | ||
| 337 | lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) { | ||
| 338 | error.OutOfMemory => return error.OutOfMemory, | ||
| 339 | error.AnalysisFail => { | ||
| 340 | func.analysis(ip).state = .codegen_failure; | ||
| 341 | }, | ||
| 342 | else => { | ||
| 343 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 344 | zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .func = func_index }), try Zcu.ErrorMsg.create( | ||
| 345 | gpa, | ||
| 346 | decl.navSrcLoc(zcu), | ||
| 347 | "unable to codegen: {s}", | ||
| 348 | .{@errorName(err)}, | ||
| 349 | )); | ||
| 350 | func.analysis(ip).state = .codegen_failure; | ||
| 351 | try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index })); | ||
| 352 | }, | ||
| 353 | }; | ||
| 354 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 355 | if (build_options.only_c) unreachable; | ||
| 356 | llvm_object.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) { | ||
| 357 | error.OutOfMemory => return error.OutOfMemory, | ||
| 358 | }; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | /// https://github.com/ziglang/zig/issues/14307 | ||
| 363 | pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void { | ||
| 364 | const import_file_result = try pt.zcu.importPkg(pkg); | ||
| 365 | const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index); | ||
| 366 | if (root_decl_index == .none) { | ||
| 367 | return pt.semaFile(import_file_result.file_index); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | fn getFileRootStruct( | ||
| 372 | pt: Zcu.PerThread, | ||
| 373 | decl_index: Zcu.Decl.Index, | ||
| 374 | namespace_index: Zcu.Namespace.Index, | ||
| 375 | file_index: Zcu.File.Index, | ||
| 376 | ) Allocator.Error!InternPool.Index { | ||
| 377 | const zcu = pt.zcu; | ||
| 378 | const gpa = zcu.gpa; | ||
| 379 | const ip = &zcu.intern_pool; | ||
| 380 | const file = zcu.fileByIndex(file_index); | ||
| 381 | const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended; | ||
| 382 | assert(extended.opcode == .struct_decl); | ||
| 383 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | ||
| 384 | assert(!small.has_captures_len); | ||
| 385 | assert(!small.has_backing_int); | ||
| 386 | assert(small.layout == .auto); | ||
| 387 | var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len; | ||
| 388 | const fields_len = if (small.has_fields_len) blk: { | ||
| 389 | const fields_len = file.zir.extra[extra_index]; | ||
| 390 | extra_index += 1; | ||
| 391 | break :blk fields_len; | ||
| 392 | } else 0; | ||
| 393 | const decls_len = if (small.has_decls_len) blk: { | ||
| 394 | const decls_len = file.zir.extra[extra_index]; | ||
| 395 | extra_index += 1; | ||
| 396 | break :blk decls_len; | ||
| 397 | } else 0; | ||
| 398 | const decls = file.zir.bodySlice(extra_index, decls_len); | ||
| 399 | extra_index += decls_len; | ||
| 400 | |||
| 401 | const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst); | ||
| 402 | const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{ | ||
| 403 | .layout = .auto, | ||
| 404 | .fields_len = fields_len, | ||
| 405 | .known_non_opv = small.known_non_opv, | ||
| 406 | .requires_comptime = if (small.known_comptime_only) .yes else .unknown, | ||
| 407 | .is_tuple = small.is_tuple, | ||
| 408 | .any_comptime_fields = small.any_comptime_fields, | ||
| 409 | .any_default_inits = small.any_default_inits, | ||
| 410 | .inits_resolved = false, | ||
| 411 | .any_aligned_fields = small.any_aligned_fields, | ||
| 412 | .has_namespace = true, | ||
| 413 | .key = .{ .declared = .{ | ||
| 414 | .zir_index = tracked_inst, | ||
| 415 | .captures = &.{}, | ||
| 416 | } }, | ||
| 417 | })) { | ||
| 418 | .existing => unreachable, // we wouldn't be analysing the file root if this type existed | ||
| 419 | .wip => |wip| wip, | ||
| 420 | }; | ||
| 421 | errdefer wip_ty.cancel(ip); | ||
| 422 | |||
| 423 | if (zcu.comp.debug_incremental) { | ||
| 424 | try ip.addDependency( | ||
| 425 | gpa, | ||
| 426 | InternPool.AnalUnit.wrap(.{ .decl = decl_index }), | ||
| 427 | .{ .src_hash = tracked_inst }, | ||
| 428 | ); | ||
| 429 | } | ||
| 430 | |||
| 431 | const decl = zcu.declPtr(decl_index); | ||
| 432 | decl.val = Value.fromInterned(wip_ty.index); | ||
| 433 | decl.has_tv = true; | ||
| 434 | decl.owns_tv = true; | ||
| 435 | decl.analysis = .complete; | ||
| 436 | |||
| 437 | try zcu.scanNamespace(namespace_index, decls, decl); | ||
| 438 | try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index }); | ||
| 439 | return wip_ty.finish(ip, decl_index, namespace_index.toOptional()); | ||
| 440 | } | ||
| 441 | |||
| 442 | /// Re-analyze the root Decl of a file on an incremental update. | ||
| 443 | /// If `type_outdated`, the struct type itself is considered outdated and is | ||
| 444 | /// reconstructed at a new InternPool index. Otherwise, the namespace is just | ||
| 445 | /// re-analyzed. Returns whether the decl's tyval was invalidated. | ||
| 446 | fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool { | ||
| 447 | const zcu = pt.zcu; | ||
| 448 | const ip = &zcu.intern_pool; | ||
| 449 | const file = zcu.fileByIndex(file_index); | ||
| 450 | const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?); | ||
| 451 | |||
| 452 | log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{ | ||
| 453 | file.mod.fully_qualified_name, | ||
| 454 | file.sub_file_path, | ||
| 455 | type_outdated, | ||
| 456 | }); | ||
| 457 | |||
| 458 | if (file.status != .success_zir) { | ||
| 459 | if (decl.analysis == .file_failure) { | ||
| 460 | return false; | ||
| 461 | } else { | ||
| 462 | decl.analysis = .file_failure; | ||
| 463 | return true; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | if (decl.analysis == .file_failure) { | ||
| 468 | // No struct type currently exists. Create one! | ||
| 469 | const root_decl = zcu.fileRootDecl(file_index); | ||
| 470 | _ = try pt.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index); | ||
| 471 | return true; | ||
| 472 | } | ||
| 473 | |||
| 474 | assert(decl.has_tv); | ||
| 475 | assert(decl.owns_tv); | ||
| 476 | |||
| 477 | if (type_outdated) { | ||
| 478 | // Invalidate the existing type, reusing the decl and namespace. | ||
| 479 | const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?; | ||
| 480 | ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ | ||
| 481 | .decl = file_root_decl, | ||
| 482 | })); | ||
| 483 | ip.remove(decl.val.toIntern()); | ||
| 484 | decl.val = undefined; | ||
| 485 | _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index); | ||
| 486 | return true; | ||
| 487 | } | ||
| 488 | |||
| 489 | // Only the struct's namespace is outdated. | ||
| 490 | // Preserve the type - just scan the namespace again. | ||
| 491 | |||
| 492 | const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended; | ||
| 493 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | ||
| 494 | |||
| 495 | var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len; | ||
| 496 | extra_index += @intFromBool(small.has_fields_len); | ||
| 497 | const decls_len = if (small.has_decls_len) blk: { | ||
| 498 | const decls_len = file.zir.extra[extra_index]; | ||
| 499 | extra_index += 1; | ||
| 500 | break :blk decls_len; | ||
| 501 | } else 0; | ||
| 502 | const decls = file.zir.bodySlice(extra_index, decls_len); | ||
| 503 | |||
| 504 | if (!type_outdated) { | ||
| 505 | try zcu.scanNamespace(decl.src_namespace, decls, decl); | ||
| 506 | } | ||
| 507 | |||
| 508 | return false; | ||
| 509 | } | ||
| 510 | |||
| 511 | /// Regardless of the file status, will create a `Decl` if none exists so that we can track | ||
| 512 | /// dependencies and re-analyze when the file becomes outdated. | ||
| 513 | fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ||
| 514 | const tracy = trace(@src()); | ||
| 515 | defer tracy.end(); | ||
| 516 | |||
| 517 | const zcu = pt.zcu; | ||
| 518 | const gpa = zcu.gpa; | ||
| 519 | const file = zcu.fileByIndex(file_index); | ||
| 520 | assert(zcu.fileRootDecl(file_index) == .none); | ||
| 521 | log.debug("semaFile zcu={s} sub_file_path={s}", .{ | ||
| 522 | file.mod.fully_qualified_name, file.sub_file_path, | ||
| 523 | }); | ||
| 524 | |||
| 525 | // Because these three things each reference each other, `undefined` | ||
| 526 | // placeholders are used before being set after the struct type gains an | ||
| 527 | // InternPool index. | ||
| 528 | const new_namespace_index = try zcu.createNamespace(.{ | ||
| 529 | .parent = .none, | ||
| 530 | .decl_index = undefined, | ||
| 531 | .file_scope = file_index, | ||
| 532 | }); | ||
| 533 | errdefer zcu.destroyNamespace(new_namespace_index); | ||
| 534 | |||
| 535 | const new_decl_index = try zcu.allocateNewDecl(new_namespace_index); | ||
| 536 | const new_decl = zcu.declPtr(new_decl_index); | ||
| 537 | errdefer @panic("TODO error handling"); | ||
| 538 | |||
| 539 | zcu.setFileRootDecl(file_index, new_decl_index.toOptional()); | ||
| 540 | zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index; | ||
| 541 | |||
| 542 | new_decl.name = try file.fullyQualifiedName(zcu); | ||
| 543 | new_decl.name_fully_qualified = true; | ||
| 544 | new_decl.is_pub = true; | ||
| 545 | new_decl.is_exported = false; | ||
| 546 | new_decl.alignment = .none; | ||
| 547 | new_decl.@"linksection" = .none; | ||
| 548 | new_decl.analysis = .in_progress; | ||
| 549 | |||
| 550 | if (file.status != .success_zir) { | ||
| 551 | new_decl.analysis = .file_failure; | ||
| 552 | return; | ||
| 553 | } | ||
| 554 | assert(file.zir_loaded); | ||
| 555 | |||
| 556 | const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index); | ||
| 557 | errdefer zcu.intern_pool.remove(struct_ty); | ||
| 558 | |||
| 559 | switch (zcu.comp.cache_use) { | ||
| 560 | .whole => |whole| if (whole.cache_manifest) |man| { | ||
| 561 | const source = file.getSource(gpa) catch |err| { | ||
| 562 | try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)}); | ||
| 563 | return error.AnalysisFail; | ||
| 564 | }; | ||
| 565 | |||
| 566 | const resolved_path = std.fs.path.resolve(gpa, &.{ | ||
| 567 | file.mod.root.root_dir.path orelse ".", | ||
| 568 | file.mod.root.sub_path, | ||
| 569 | file.sub_file_path, | ||
| 570 | }) catch |err| { | ||
| 571 | try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)}); | ||
| 572 | return error.AnalysisFail; | ||
| 573 | }; | ||
| 574 | errdefer gpa.free(resolved_path); | ||
| 575 | |||
| 576 | whole.cache_manifest_mutex.lock(); | ||
| 577 | defer whole.cache_manifest_mutex.unlock(); | ||
| 578 | try man.addFilePostContents(resolved_path, source.bytes, source.stat); | ||
| 579 | }, | ||
| 580 | .incremental => {}, | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { | ||
| 585 | const tracy = trace(@src()); | ||
| 586 | defer tracy.end(); | ||
| 587 | |||
| 588 | const zcu = pt.zcu; | ||
| 589 | const decl = zcu.declPtr(decl_index); | ||
| 590 | const ip = &zcu.intern_pool; | ||
| 591 | |||
| 592 | if (decl.getFileScope(zcu).status != .success_zir) { | ||
| 593 | return error.AnalysisFail; | ||
| 594 | } | ||
| 595 | |||
| 596 | assert(!zcu.declIsRoot(decl_index)); | ||
| 597 | |||
| 598 | if (decl.zir_decl_index == .none and decl.owns_tv) { | ||
| 599 | // We are re-analyzing an anonymous owner Decl (for a function or a namespace type). | ||
| 600 | return zcu.semaAnonOwnerDecl(decl_index); | ||
| 601 | } | ||
| 602 | |||
| 603 | log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)}); | ||
| 604 | log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)}); | ||
| 605 | defer blk: { | ||
| 606 | log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)}); | ||
| 607 | } | ||
| 608 | |||
| 609 | const old_has_tv = decl.has_tv; | ||
| 610 | // The following values are ignored if `!old_has_tv` | ||
| 611 | const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined; | ||
| 612 | const old_val = decl.val; | ||
| 613 | const old_align = decl.alignment; | ||
| 614 | const old_linksection = decl.@"linksection"; | ||
| 615 | const old_addrspace = decl.@"addrspace"; | ||
| 616 | const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func| | ||
| 617 | prev_func.analysis(ip).state == .inline_only | ||
| 618 | else | ||
| 619 | false; | ||
| 620 | |||
| 621 | const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip); | ||
| 622 | |||
| 623 | const gpa = zcu.gpa; | ||
| 624 | const zir = decl.getFileScope(zcu).zir; | ||
| 625 | |||
| 626 | const builtin_type_target_index: InternPool.Index = ip_index: { | ||
| 627 | const std_mod = zcu.std_mod; | ||
| 628 | if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none; | ||
| 629 | // We're in the std module. | ||
| 630 | const std_file_imported = try zcu.importPkg(std_mod); | ||
| 631 | const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index); | ||
| 632 | const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?); | ||
| 633 | const std_namespace = std_decl.getInnerNamespace(zcu).?; | ||
| 634 | const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); | ||
| 635 | const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none); | ||
| 636 | const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none; | ||
| 637 | if (decl.src_namespace != builtin_namespace) break :ip_index .none; | ||
| 638 | // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. | ||
| 639 | for ([_][]const u8{ | ||
| 640 | "AtomicOrder", | ||
| 641 | "AtomicRmwOp", | ||
| 642 | "CallingConvention", | ||
| 643 | "AddressSpace", | ||
| 644 | "FloatMode", | ||
| 645 | "ReduceOp", | ||
| 646 | "CallModifier", | ||
| 647 | "PrefetchOptions", | ||
| 648 | "ExportOptions", | ||
| 649 | "ExternOptions", | ||
| 650 | "Type", | ||
| 651 | }, [_]InternPool.Index{ | ||
| 652 | .atomic_order_type, | ||
| 653 | .atomic_rmw_op_type, | ||
| 654 | .calling_convention_type, | ||
| 655 | .address_space_type, | ||
| 656 | .float_mode_type, | ||
| 657 | .reduce_op_type, | ||
| 658 | .call_modifier_type, | ||
| 659 | .prefetch_options_type, | ||
| 660 | .export_options_type, | ||
| 661 | .extern_options_type, | ||
| 662 | .type_info_type, | ||
| 663 | }) |type_name, type_ip| { | ||
| 664 | if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip; | ||
| 665 | } | ||
| 666 | break :ip_index .none; | ||
| 667 | }; | ||
| 668 | |||
| 669 | zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 670 | |||
| 671 | decl.analysis = .in_progress; | ||
| 672 | |||
| 673 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 674 | defer analysis_arena.deinit(); | ||
| 675 | |||
| 676 | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); | ||
| 677 | defer comptime_err_ret_trace.deinit(); | ||
| 678 | |||
| 679 | var sema: Sema = .{ | ||
| 680 | .pt = pt, | ||
| 681 | .gpa = gpa, | ||
| 682 | .arena = analysis_arena.allocator(), | ||
| 683 | .code = zir, | ||
| 684 | .owner_decl = decl, | ||
| 685 | .owner_decl_index = decl_index, | ||
| 686 | .func_index = .none, | ||
| 687 | .func_is_naked = false, | ||
| 688 | .fn_ret_ty = Type.void, | ||
| 689 | .fn_ret_ty_ies = null, | ||
| 690 | .owner_func_index = .none, | ||
| 691 | .comptime_err_ret_trace = &comptime_err_ret_trace, | ||
| 692 | .builtin_type_target_index = builtin_type_target_index, | ||
| 693 | }; | ||
| 694 | defer sema.deinit(); | ||
| 695 | |||
| 696 | // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source. | ||
| 697 | try sema.declareDependency(.{ .src_hash = try ip.trackZir( | ||
| 698 | gpa, | ||
| 699 | decl.getFileScopeIndex(zcu), | ||
| 700 | decl_inst, | ||
| 701 | ) }); | ||
| 702 | |||
| 703 | var block_scope: Sema.Block = .{ | ||
| 704 | .parent = null, | ||
| 705 | .sema = &sema, | ||
| 706 | .namespace = decl.src_namespace, | ||
| 707 | .instructions = .{}, | ||
| 708 | .inlining = null, | ||
| 709 | .is_comptime = true, | ||
| 710 | .src_base_inst = decl.zir_decl_index.unwrap().?, | ||
| 711 | .type_name_ctx = decl.name, | ||
| 712 | }; | ||
| 713 | defer block_scope.instructions.deinit(gpa); | ||
| 714 | |||
| 715 | const decl_bodies = decl.zirBodies(zcu); | ||
| 716 | |||
| 717 | const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst); | ||
| 718 | // We'll do some other bits with the Sema. Clear the type target index just | ||
| 719 | // in case they analyze any type. | ||
| 720 | sema.builtin_type_target_index = .none; | ||
| 721 | const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 }); | ||
| 722 | const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 }); | ||
| 723 | const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 }); | ||
| 724 | const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 }); | ||
| 725 | const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 }); | ||
| 726 | const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); | ||
| 727 | const decl_ty = decl_val.typeOf(zcu); | ||
| 728 | |||
| 729 | // Note this resolves the type of the Decl, not the value; if this Decl | ||
| 730 | // is a struct, for example, this resolves `type` (which needs no resolution), | ||
| 731 | // not the struct itself. | ||
| 732 | try decl_ty.resolveLayout(pt); | ||
| 733 | |||
| 734 | if (decl.kind == .@"usingnamespace") { | ||
| 735 | if (!decl_ty.eql(Type.type, zcu)) { | ||
| 736 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)}); | ||
| 737 | } | ||
| 738 | const ty = decl_val.toType(); | ||
| 739 | if (ty.getNamespace(zcu) == null) { | ||
| 740 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)}); | ||
| 741 | } | ||
| 742 | |||
| 743 | decl.val = ty.toValue(); | ||
| 744 | decl.alignment = .none; | ||
| 745 | decl.@"linksection" = .none; | ||
| 746 | decl.has_tv = true; | ||
| 747 | decl.owns_tv = false; | ||
| 748 | decl.analysis = .complete; | ||
| 749 | |||
| 750 | // TODO: usingnamespace cannot currently participate in incremental compilation | ||
| 751 | return .{ | ||
| 752 | .invalidate_decl_val = true, | ||
| 753 | .invalidate_decl_ref = true, | ||
| 754 | }; | ||
| 755 | } | ||
| 756 | |||
| 757 | var queue_linker_work = true; | ||
| 758 | var is_func = false; | ||
| 759 | var is_inline = false; | ||
| 760 | switch (decl_val.toIntern()) { | ||
| 761 | .generic_poison => unreachable, | ||
| 762 | .unreachable_value => unreachable, | ||
| 763 | else => switch (ip.indexToKey(decl_val.toIntern())) { | ||
| 764 | .variable => |variable| { | ||
| 765 | decl.owns_tv = variable.decl == decl_index; | ||
| 766 | queue_linker_work = decl.owns_tv; | ||
| 767 | }, | ||
| 768 | |||
| 769 | .extern_func => |extern_func| { | ||
| 770 | decl.owns_tv = extern_func.decl == decl_index; | ||
| 771 | queue_linker_work = decl.owns_tv; | ||
| 772 | is_func = decl.owns_tv; | ||
| 773 | }, | ||
| 774 | |||
| 775 | .func => |func| { | ||
| 776 | decl.owns_tv = func.owner_decl == decl_index; | ||
| 777 | queue_linker_work = false; | ||
| 778 | is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline; | ||
| 779 | is_func = decl.owns_tv; | ||
| 780 | }, | ||
| 781 | |||
| 782 | else => {}, | ||
| 783 | }, | ||
| 784 | } | ||
| 785 | |||
| 786 | decl.val = decl_val; | ||
| 787 | // Function linksection, align, and addrspace were already set by Sema | ||
| 788 | if (!is_func) { | ||
| 789 | decl.alignment = blk: { | ||
| 790 | const align_body = decl_bodies.align_body orelse break :blk .none; | ||
| 791 | const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst); | ||
| 792 | break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref); | ||
| 793 | }; | ||
| 794 | decl.@"linksection" = blk: { | ||
| 795 | const linksection_body = decl_bodies.linksection_body orelse break :blk .none; | ||
| 796 | const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst); | ||
| 797 | const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{ | ||
| 798 | .needed_comptime_reason = "linksection must be comptime-known", | ||
| 799 | }); | ||
| 800 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { | ||
| 801 | return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{}); | ||
| 802 | } else if (bytes.len == 0) { | ||
| 803 | return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{}); | ||
| 804 | } | ||
| 805 | break :blk try ip.getOrPutStringOpt(gpa, bytes, .no_embedded_nulls); | ||
| 806 | }; | ||
| 807 | decl.@"addrspace" = blk: { | ||
| 808 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { | ||
| 809 | .variable => .variable, | ||
| 810 | .extern_func, .func => .function, | ||
| 811 | else => .constant, | ||
| 812 | }; | ||
| 813 | |||
| 814 | const target = zcu.getTarget(); | ||
| 815 | |||
| 816 | const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) { | ||
| 817 | .function => target_util.defaultAddressSpace(target, .function), | ||
| 818 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | ||
| 819 | .constant => target_util.defaultAddressSpace(target, .global_constant), | ||
| 820 | else => unreachable, | ||
| 821 | }; | ||
| 822 | const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst); | ||
| 823 | break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx); | ||
| 824 | }; | ||
| 825 | } | ||
| 826 | decl.has_tv = true; | ||
| 827 | decl.analysis = .complete; | ||
| 828 | |||
| 829 | const result: Zcu.SemaDeclResult = if (old_has_tv) .{ | ||
| 830 | .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or | ||
| 831 | !decl.val.eql(old_val, decl_ty, zcu) or | ||
| 832 | is_inline != old_is_inline, | ||
| 833 | .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or | ||
| 834 | decl.alignment != old_align or | ||
| 835 | decl.@"linksection" != old_linksection or | ||
| 836 | decl.@"addrspace" != old_addrspace or | ||
| 837 | is_inline != old_is_inline, | ||
| 838 | } else .{ | ||
| 839 | .invalidate_decl_val = true, | ||
| 840 | .invalidate_decl_ref = true, | ||
| 841 | }; | ||
| 842 | |||
| 843 | const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty)); | ||
| 844 | if (has_runtime_bits) { | ||
| 845 | // Needed for codegen_decl which will call updateDecl and then the | ||
| 846 | // codegen backend wants full access to the Decl Type. | ||
| 847 | try decl_ty.resolveFully(pt); | ||
| 848 | |||
| 849 | try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | ||
| 850 | |||
| 851 | if (result.invalidate_decl_ref and zcu.emit_h != null) { | ||
| 852 | try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); | ||
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 856 | if (decl.is_exported) { | ||
| 857 | const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) }); | ||
| 858 | if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{}); | ||
| 859 | // The scope needs to have the decl in it. | ||
| 860 | try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index); | ||
| 861 | } | ||
| 862 | |||
| 863 | try sema.flushExports(); | ||
| 864 | |||
| 865 | return result; | ||
| 866 | } | ||
| 867 | |||
| 868 | pub fn embedFile( | ||
| 869 | pt: Zcu.PerThread, | ||
| 870 | cur_file: *Zcu.File, | ||
| 871 | import_string: []const u8, | ||
| 872 | src_loc: Zcu.LazySrcLoc, | ||
| 873 | ) !InternPool.Index { | ||
| 874 | const mod = pt.zcu; | ||
| 875 | const gpa = mod.gpa; | ||
| 876 | |||
| 877 | if (cur_file.mod.deps.get(import_string)) |pkg| { | ||
| 878 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 879 | pkg.root.root_dir.path orelse ".", | ||
| 880 | pkg.root.sub_path, | ||
| 881 | pkg.root_src_path, | ||
| 882 | }); | ||
| 883 | var keep_resolved_path = false; | ||
| 884 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 885 | |||
| 886 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); | ||
| 887 | errdefer { | ||
| 888 | assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path)); | ||
| 889 | keep_resolved_path = false; | ||
| 890 | } | ||
| 891 | if (gop.found_existing) return gop.value_ptr.*.val; | ||
| 892 | keep_resolved_path = true; | ||
| 893 | |||
| 894 | const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); | ||
| 895 | errdefer gpa.free(sub_file_path); | ||
| 896 | |||
| 897 | return pt.newEmbedFile(pkg, sub_file_path, resolved_path, gop.value_ptr, src_loc); | ||
| 898 | } | ||
| 899 | |||
| 900 | // The resolved path is used as the key in the table, to detect if a file | ||
| 901 | // refers to the same as another, despite different relative paths. | ||
| 902 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 903 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 904 | cur_file.mod.root.sub_path, | ||
| 905 | cur_file.sub_file_path, | ||
| 906 | "..", | ||
| 907 | import_string, | ||
| 908 | }); | ||
| 909 | |||
| 910 | var keep_resolved_path = false; | ||
| 911 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 912 | |||
| 913 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); | ||
| 914 | errdefer { | ||
| 915 | assert(std.mem.eql(u8, mod.embed_table.pop().key, resolved_path)); | ||
| 916 | keep_resolved_path = false; | ||
| 917 | } | ||
| 918 | if (gop.found_existing) return gop.value_ptr.*.val; | ||
| 919 | keep_resolved_path = true; | ||
| 920 | |||
| 921 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | ||
| 922 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 923 | cur_file.mod.root.sub_path, | ||
| 924 | }); | ||
| 925 | defer gpa.free(resolved_root_path); | ||
| 926 | |||
| 927 | const sub_file_path = p: { | ||
| 928 | const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path); | ||
| 929 | errdefer gpa.free(relative); | ||
| 930 | |||
| 931 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { | ||
| 932 | break :p relative; | ||
| 933 | } | ||
| 934 | return error.ImportOutsideModulePath; | ||
| 935 | }; | ||
| 936 | defer gpa.free(sub_file_path); | ||
| 937 | |||
| 938 | return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); | ||
| 939 | } | ||
| 940 | |||
| 941 | /// Finalize the creation of an anon decl. | ||
| 942 | pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void { | ||
| 943 | if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) { | ||
| 944 | try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | |||
| 948 | /// https://github.com/ziglang/zig/issues/14307 | ||
| 949 | fn newEmbedFile( | ||
| 950 | pt: Zcu.PerThread, | ||
| 951 | pkg: *Module, | ||
| 952 | sub_file_path: []const u8, | ||
| 953 | resolved_path: []const u8, | ||
| 954 | result: **Zcu.EmbedFile, | ||
| 955 | src_loc: Zcu.LazySrcLoc, | ||
| 956 | ) !InternPool.Index { | ||
| 957 | const mod = pt.zcu; | ||
| 958 | const gpa = mod.gpa; | ||
| 959 | const ip = &mod.intern_pool; | ||
| 960 | |||
| 961 | const new_file = try gpa.create(Zcu.EmbedFile); | ||
| 962 | errdefer gpa.destroy(new_file); | ||
| 963 | |||
| 964 | var file = try pkg.root.openFile(sub_file_path, .{}); | ||
| 965 | defer file.close(); | ||
| 966 | |||
| 967 | const actual_stat = try file.stat(); | ||
| 968 | const stat: Cache.File.Stat = .{ | ||
| 969 | .size = actual_stat.size, | ||
| 970 | .inode = actual_stat.inode, | ||
| 971 | .mtime = actual_stat.mtime, | ||
| 972 | }; | ||
| 973 | const size = std.math.cast(usize, actual_stat.size) orelse return error.Overflow; | ||
| 974 | |||
| 975 | const bytes = try ip.string_bytes.addManyAsSlice(gpa, try std.math.add(usize, size, 1)); | ||
| 976 | const actual_read = try file.readAll(bytes[0..size]); | ||
| 977 | if (actual_read != size) return error.UnexpectedEndOfFile; | ||
| 978 | bytes[size] = 0; | ||
| 979 | |||
| 980 | const comp = mod.comp; | ||
| 981 | switch (comp.cache_use) { | ||
| 982 | .whole => |whole| if (whole.cache_manifest) |man| { | ||
| 983 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); | ||
| 984 | errdefer gpa.free(copied_resolved_path); | ||
| 985 | whole.cache_manifest_mutex.lock(); | ||
| 986 | defer whole.cache_manifest_mutex.unlock(); | ||
| 987 | try man.addFilePostContents(copied_resolved_path, bytes[0..size], stat); | ||
| 988 | }, | ||
| 989 | .incremental => {}, | ||
| 990 | } | ||
| 991 | |||
| 992 | const array_ty = try pt.intern(.{ .array_type = .{ | ||
| 993 | .len = size, | ||
| 994 | .sentinel = .zero_u8, | ||
| 995 | .child = .u8_type, | ||
| 996 | } }); | ||
| 997 | const array_val = try pt.intern(.{ .aggregate = .{ | ||
| 998 | .ty = array_ty, | ||
| 999 | .storage = .{ .bytes = try ip.getOrPutTrailingString(gpa, bytes.len, .maybe_embedded_nulls) }, | ||
| 1000 | } }); | ||
| 1001 | |||
| 1002 | const ptr_ty = (try pt.ptrType(.{ | ||
| 1003 | .child = array_ty, | ||
| 1004 | .flags = .{ | ||
| 1005 | .alignment = .none, | ||
| 1006 | .is_const = true, | ||
| 1007 | .address_space = .generic, | ||
| 1008 | }, | ||
| 1009 | })).toIntern(); | ||
| 1010 | const ptr_val = try pt.intern(.{ .ptr = .{ | ||
| 1011 | .ty = ptr_ty, | ||
| 1012 | .base_addr = .{ .anon_decl = .{ | ||
| 1013 | .val = array_val, | ||
| 1014 | .orig_ty = ptr_ty, | ||
| 1015 | } }, | ||
| 1016 | .byte_offset = 0, | ||
| 1017 | } }); | ||
| 1018 | |||
| 1019 | result.* = new_file; | ||
| 1020 | new_file.* = .{ | ||
| 1021 | .sub_file_path = try ip.getOrPutString(gpa, sub_file_path, .no_embedded_nulls), | ||
| 1022 | .owner = pkg, | ||
| 1023 | .stat = stat, | ||
| 1024 | .val = ptr_val, | ||
| 1025 | .src_loc = src_loc, | ||
| 1026 | }; | ||
| 1027 | return ptr_val; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air { | ||
| 1031 | const tracy = trace(@src()); | ||
| 1032 | defer tracy.end(); | ||
| 1033 | |||
| 1034 | const mod = pt.zcu; | ||
| 1035 | const gpa = mod.gpa; | ||
| 1036 | const ip = &mod.intern_pool; | ||
| 1037 | const func = mod.funcInfo(func_index); | ||
| 1038 | const decl_index = func.owner_decl; | ||
| 1039 | const decl = mod.declPtr(decl_index); | ||
| 1040 | |||
| 1041 | log.debug("func name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)}); | ||
| 1042 | defer blk: { | ||
| 1043 | log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)}); | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0); | ||
| 1047 | defer decl_prog_node.end(); | ||
| 1048 | |||
| 1049 | mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index })); | ||
| 1050 | |||
| 1051 | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); | ||
| 1052 | defer comptime_err_ret_trace.deinit(); | ||
| 1053 | |||
| 1054 | // In the case of a generic function instance, this is the type of the | ||
| 1055 | // instance, which has comptime parameters elided. In other words, it is | ||
| 1056 | // the runtime-known parameters only, not to be confused with the | ||
| 1057 | // generic_owner function type, which potentially has more parameters, | ||
| 1058 | // including comptime parameters. | ||
| 1059 | const fn_ty = decl.typeOf(mod); | ||
| 1060 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | ||
| 1061 | |||
| 1062 | var sema: Sema = .{ | ||
| 1063 | .pt = pt, | ||
| 1064 | .gpa = gpa, | ||
| 1065 | .arena = arena, | ||
| 1066 | .code = decl.getFileScope(mod).zir, | ||
| 1067 | .owner_decl = decl, | ||
| 1068 | .owner_decl_index = decl_index, | ||
| 1069 | .func_index = func_index, | ||
| 1070 | .func_is_naked = fn_ty_info.cc == .Naked, | ||
| 1071 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), | ||
| 1072 | .fn_ret_ty_ies = null, | ||
| 1073 | .owner_func_index = func_index, | ||
| 1074 | .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota), | ||
| 1075 | .comptime_err_ret_trace = &comptime_err_ret_trace, | ||
| 1076 | }; | ||
| 1077 | defer sema.deinit(); | ||
| 1078 | |||
| 1079 | // Every runtime function has a dependency on the source of the Decl it originates from. | ||
| 1080 | // It also depends on the value of its owner Decl. | ||
| 1081 | try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? }); | ||
| 1082 | try sema.declareDependency(.{ .decl_val = decl_index }); | ||
| 1083 | |||
| 1084 | if (func.analysis(ip).inferred_error_set) { | ||
| 1085 | const ies = try arena.create(Sema.InferredErrorSet); | ||
| 1086 | ies.* = .{ .func = func_index }; | ||
| 1087 | sema.fn_ret_ty_ies = ies; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | // reset in case calls to errorable functions are removed. | ||
| 1091 | func.analysis(ip).calls_or_awaits_errorable_fn = false; | ||
| 1092 | |||
| 1093 | // First few indexes of extra are reserved and set at the end. | ||
| 1094 | const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len; | ||
| 1095 | try sema.air_extra.ensureTotalCapacity(gpa, reserved_count); | ||
| 1096 | sema.air_extra.items.len += reserved_count; | ||
| 1097 | |||
| 1098 | var inner_block: Sema.Block = .{ | ||
| 1099 | .parent = null, | ||
| 1100 | .sema = &sema, | ||
| 1101 | .namespace = decl.src_namespace, | ||
| 1102 | .instructions = .{}, | ||
| 1103 | .inlining = null, | ||
| 1104 | .is_comptime = false, | ||
| 1105 | .src_base_inst = inst: { | ||
| 1106 | const owner_info = if (func.generic_owner == .none) | ||
| 1107 | func | ||
| 1108 | else | ||
| 1109 | mod.funcInfo(func.generic_owner); | ||
| 1110 | const orig_decl = mod.declPtr(owner_info.owner_decl); | ||
| 1111 | break :inst orig_decl.zir_decl_index.unwrap().?; | ||
| 1112 | }, | ||
| 1113 | .type_name_ctx = decl.name, | ||
| 1114 | }; | ||
| 1115 | defer inner_block.instructions.deinit(gpa); | ||
| 1116 | |||
| 1117 | const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip)); | ||
| 1118 | |||
| 1119 | // Here we are performing "runtime semantic analysis" for a function body, which means | ||
| 1120 | // we must map the parameter ZIR instructions to `arg` AIR instructions. | ||
| 1121 | // AIR requires the `arg` parameters to be the first N instructions. | ||
| 1122 | // This could be a generic function instantiation, however, in which case we need to | ||
| 1123 | // map the comptime parameters to constant values and only emit arg AIR instructions | ||
| 1124 | // for the runtime ones. | ||
| 1125 | const runtime_params_len = fn_ty_info.param_types.len; | ||
| 1126 | try inner_block.instructions.ensureTotalCapacityPrecise(gpa, runtime_params_len); | ||
| 1127 | try sema.air_instructions.ensureUnusedCapacity(gpa, fn_info.total_params_len); | ||
| 1128 | try sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); | ||
| 1129 | |||
| 1130 | // In the case of a generic function instance, pre-populate all the comptime args. | ||
| 1131 | if (func.comptime_args.len != 0) { | ||
| 1132 | for ( | ||
| 1133 | fn_info.param_body[0..func.comptime_args.len], | ||
| 1134 | func.comptime_args.get(ip), | ||
| 1135 | ) |inst, comptime_arg| { | ||
| 1136 | if (comptime_arg == .none) continue; | ||
| 1137 | sema.inst_map.putAssumeCapacityNoClobber(inst, Air.internedToRef(comptime_arg)); | ||
| 1138 | } | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | const src_params_len = if (func.comptime_args.len != 0) | ||
| 1142 | func.comptime_args.len | ||
| 1143 | else | ||
| 1144 | runtime_params_len; | ||
| 1145 | |||
| 1146 | var runtime_param_index: usize = 0; | ||
| 1147 | for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| { | ||
| 1148 | const gop = sema.inst_map.getOrPutAssumeCapacity(inst); | ||
| 1149 | if (gop.found_existing) continue; // provided above by comptime arg | ||
| 1150 | |||
| 1151 | const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index]; | ||
| 1152 | runtime_param_index += 1; | ||
| 1153 | |||
| 1154 | const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) { | ||
| 1155 | error.GenericPoison => unreachable, | ||
| 1156 | error.ComptimeReturn => unreachable, | ||
| 1157 | error.ComptimeBreak => unreachable, | ||
| 1158 | else => |e| return e, | ||
| 1159 | }; | ||
| 1160 | if (opt_opv) |opv| { | ||
| 1161 | gop.value_ptr.* = Air.internedToRef(opv.toIntern()); | ||
| 1162 | continue; | ||
| 1163 | } | ||
| 1164 | const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); | ||
| 1165 | gop.value_ptr.* = arg_index.toRef(); | ||
| 1166 | inner_block.instructions.appendAssumeCapacity(arg_index); | ||
| 1167 | sema.air_instructions.appendAssumeCapacity(.{ | ||
| 1168 | .tag = .arg, | ||
| 1169 | .data = .{ .arg = .{ | ||
| 1170 | .ty = Air.internedToRef(param_ty), | ||
| 1171 | .src_index = @intCast(src_param_index), | ||
| 1172 | } }, | ||
| 1173 | }); | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | func.analysis(ip).state = .in_progress; | ||
| 1177 | |||
| 1178 | const last_arg_index = inner_block.instructions.items.len; | ||
| 1179 | |||
| 1180 | // Save the error trace as our first action in the function. | ||
| 1181 | // If this is unnecessary after all, Liveness will clean it up for us. | ||
| 1182 | const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&inner_block); | ||
| 1183 | sema.error_return_trace_index_on_fn_entry = error_return_trace_index; | ||
| 1184 | inner_block.error_return_trace_index = error_return_trace_index; | ||
| 1185 | |||
| 1186 | sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) { | ||
| 1187 | // TODO make these unreachable instead of @panic | ||
| 1188 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | ||
| 1189 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | ||
| 1190 | else => |e| return e, | ||
| 1191 | }; | ||
| 1192 | |||
| 1193 | for (sema.unresolved_inferred_allocs.keys()) |ptr_inst| { | ||
| 1194 | // The lack of a resolve_inferred_alloc means that this instruction | ||
| 1195 | // is unused so it just has to be a no-op. | ||
| 1196 | sema.air_instructions.set(@intFromEnum(ptr_inst), .{ | ||
| 1197 | .tag = .alloc, | ||
| 1198 | .data = .{ .ty = Type.single_const_pointer_to_comptime_int }, | ||
| 1199 | }); | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | // If we don't get an error return trace from a caller, create our own. | ||
| 1203 | if (func.analysis(ip).calls_or_awaits_errorable_fn and | ||
| 1204 | mod.comp.config.any_error_tracing and | ||
| 1205 | !sema.fn_ret_ty.isError(mod)) | ||
| 1206 | { | ||
| 1207 | sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) { | ||
| 1208 | // TODO make these unreachable instead of @panic | ||
| 1209 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | ||
| 1210 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | ||
| 1211 | error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"), | ||
| 1212 | else => |e| return e, | ||
| 1213 | }; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | // Copy the block into place and mark that as the main block. | ||
| 1217 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | ||
| 1218 | inner_block.instructions.items.len); | ||
| 1219 | const main_block_index = sema.addExtraAssumeCapacity(Air.Block{ | ||
| 1220 | .body_len = @intCast(inner_block.instructions.items.len), | ||
| 1221 | }); | ||
| 1222 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items)); | ||
| 1223 | sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index; | ||
| 1224 | |||
| 1225 | // Resolving inferred error sets is done *before* setting the function | ||
| 1226 | // state to success, so that "unable to resolve inferred error set" errors | ||
| 1227 | // can be emitted here. | ||
| 1228 | if (sema.fn_ret_ty_ies) |ies| { | ||
| 1229 | sema.resolveInferredErrorSetPtr(&inner_block, .{ | ||
| 1230 | .base_node_inst = inner_block.src_base_inst, | ||
| 1231 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0), | ||
| 1232 | }, ies) catch |err| switch (err) { | ||
| 1233 | error.GenericPoison => unreachable, | ||
| 1234 | error.ComptimeReturn => unreachable, | ||
| 1235 | error.ComptimeBreak => unreachable, | ||
| 1236 | error.AnalysisFail => { | ||
| 1237 | // In this case our function depends on a type that had a compile error. | ||
| 1238 | // We should not try to lower this function. | ||
| 1239 | decl.analysis = .dependency_failure; | ||
| 1240 | return error.AnalysisFail; | ||
| 1241 | }, | ||
| 1242 | else => |e| return e, | ||
| 1243 | }; | ||
| 1244 | assert(ies.resolved != .none); | ||
| 1245 | ip.funcIesResolved(func_index).* = ies.resolved; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | func.analysis(ip).state = .success; | ||
| 1249 | |||
| 1250 | // Finally we must resolve the return type and parameter types so that backends | ||
| 1251 | // have full access to type information. | ||
| 1252 | // Crucially, this happens *after* we set the function state to success above, | ||
| 1253 | // so that dependencies on the function body will now be satisfied rather than | ||
| 1254 | // result in circular dependency errors. | ||
| 1255 | sema.resolveFnTypes(fn_ty) catch |err| switch (err) { | ||
| 1256 | error.GenericPoison => unreachable, | ||
| 1257 | error.ComptimeReturn => unreachable, | ||
| 1258 | error.ComptimeBreak => unreachable, | ||
| 1259 | error.AnalysisFail => { | ||
| 1260 | // In this case our function depends on a type that had a compile error. | ||
| 1261 | // We should not try to lower this function. | ||
| 1262 | decl.analysis = .dependency_failure; | ||
| 1263 | return error.AnalysisFail; | ||
| 1264 | }, | ||
| 1265 | else => |e| return e, | ||
| 1266 | }; | ||
| 1267 | |||
| 1268 | try sema.flushExports(); | ||
| 1269 | |||
| 1270 | return .{ | ||
| 1271 | .instructions = sema.air_instructions.toOwnedSlice(), | ||
| 1272 | .extra = try sema.air_extra.toOwnedSlice(gpa), | ||
| 1273 | }; | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | /// Called from `Compilation.update`, after everything is done, just before | ||
| 1277 | /// reporting compile errors. In this function we emit exported symbol collision | ||
| 1278 | /// errors and communicate exported symbols to the linker backend. | ||
| 1279 | pub fn processExports(pt: Zcu.PerThread) !void { | ||
| 1280 | const zcu = pt.zcu; | ||
| 1281 | const gpa = zcu.gpa; | ||
| 1282 | |||
| 1283 | // First, construct a mapping of every exported value and Decl to the indices of all its different exports. | ||
| 1284 | var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{}; | ||
| 1285 | var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{}; | ||
| 1286 | defer { | ||
| 1287 | for (decl_exports.values()) |*exports| { | ||
| 1288 | exports.deinit(gpa); | ||
| 1289 | } | ||
| 1290 | decl_exports.deinit(gpa); | ||
| 1291 | for (value_exports.values()) |*exports| { | ||
| 1292 | exports.deinit(gpa); | ||
| 1293 | } | ||
| 1294 | value_exports.deinit(gpa); | ||
| 1295 | } | ||
| 1296 | |||
| 1297 | // We note as a heuristic: | ||
| 1298 | // * It is rare to export a value. | ||
| 1299 | // * It is rare for one Decl to be exported multiple times. | ||
| 1300 | // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization. | ||
| 1301 | try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count()); | ||
| 1302 | |||
| 1303 | for (zcu.single_exports.values()) |export_idx| { | ||
| 1304 | const exp = zcu.all_exports.items[export_idx]; | ||
| 1305 | const value_ptr, const found_existing = switch (exp.exported) { | ||
| 1306 | .decl_index => |i| gop: { | ||
| 1307 | const gop = try decl_exports.getOrPut(gpa, i); | ||
| 1308 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 1309 | }, | ||
| 1310 | .value => |i| gop: { | ||
| 1311 | const gop = try value_exports.getOrPut(gpa, i); | ||
| 1312 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 1313 | }, | ||
| 1314 | }; | ||
| 1315 | if (!found_existing) value_ptr.* = .{}; | ||
| 1316 | try value_ptr.append(gpa, export_idx); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | for (zcu.multi_exports.values()) |info| { | ||
| 1320 | for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| { | ||
| 1321 | const value_ptr, const found_existing = switch (exp.exported) { | ||
| 1322 | .decl_index => |i| gop: { | ||
| 1323 | const gop = try decl_exports.getOrPut(gpa, i); | ||
| 1324 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 1325 | }, | ||
| 1326 | .value => |i| gop: { | ||
| 1327 | const gop = try value_exports.getOrPut(gpa, i); | ||
| 1328 | break :gop .{ gop.value_ptr, gop.found_existing }; | ||
| 1329 | }, | ||
| 1330 | }; | ||
| 1331 | if (!found_existing) value_ptr.* = .{}; | ||
| 1332 | try value_ptr.append(gpa, @intCast(export_idx)); | ||
| 1333 | } | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | // Map symbol names to `Export` for name collision detection. | ||
| 1337 | var symbol_exports: SymbolExports = .{}; | ||
| 1338 | defer symbol_exports.deinit(gpa); | ||
| 1339 | |||
| 1340 | for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| { | ||
| 1341 | const exported: Zcu.Exported = .{ .decl_index = exported_decl }; | ||
| 1342 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| { | ||
| 1346 | const exported: Zcu.Exported = .{ .value = exported_value }; | ||
| 1347 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | ||
| 1348 | } | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32); | ||
| 1352 | |||
| 1353 | fn processExportsInner( | ||
| 1354 | pt: Zcu.PerThread, | ||
| 1355 | symbol_exports: *SymbolExports, | ||
| 1356 | exported: Zcu.Exported, | ||
| 1357 | export_indices: []const u32, | ||
| 1358 | ) error{OutOfMemory}!void { | ||
| 1359 | const zcu = pt.zcu; | ||
| 1360 | const gpa = zcu.gpa; | ||
| 1361 | |||
| 1362 | for (export_indices) |export_idx| { | ||
| 1363 | const new_export = &zcu.all_exports.items[export_idx]; | ||
| 1364 | const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name); | ||
| 1365 | if (gop.found_existing) { | ||
| 1366 | new_export.status = .failed_retryable; | ||
| 1367 | try zcu.failed_exports.ensureUnusedCapacity(gpa, 1); | ||
| 1368 | const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{ | ||
| 1369 | new_export.opts.name.fmt(&zcu.intern_pool), | ||
| 1370 | }); | ||
| 1371 | errdefer msg.destroy(gpa); | ||
| 1372 | const other_export = zcu.all_exports.items[gop.value_ptr.*]; | ||
| 1373 | try zcu.errNote(other_export.src, msg, "other symbol here", .{}); | ||
| 1374 | zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg); | ||
| 1375 | new_export.status = .failed; | ||
| 1376 | } else { | ||
| 1377 | gop.value_ptr.* = export_idx; | ||
| 1378 | } | ||
| 1379 | } | ||
| 1380 | if (zcu.comp.bin_file) |lf| { | ||
| 1381 | try zcu.handleUpdateExports(export_indices, lf.updateExports(pt, exported, export_indices)); | ||
| 1382 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 1383 | if (build_options.only_c) unreachable; | ||
| 1384 | try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices)); | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | pub fn populateTestFunctions( | ||
| 1389 | pt: Zcu.PerThread, | ||
| 1390 | main_progress_node: std.Progress.Node, | ||
| 1391 | ) !void { | ||
| 1392 | const zcu = pt.zcu; | ||
| 1393 | const gpa = zcu.gpa; | ||
| 1394 | const ip = &zcu.intern_pool; | ||
| 1395 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); | ||
| 1396 | const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index; | ||
| 1397 | const root_decl_index = zcu.fileRootDecl(builtin_file_index); | ||
| 1398 | const root_decl = zcu.declPtr(root_decl_index.unwrap().?); | ||
| 1399 | const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace); | ||
| 1400 | const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls); | ||
| 1401 | const decl_index = builtin_namespace.decls.getKeyAdapted( | ||
| 1402 | test_functions_str, | ||
| 1403 | Zcu.DeclAdapter{ .zcu = zcu }, | ||
| 1404 | ).?; | ||
| 1405 | { | ||
| 1406 | // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` | ||
| 1407 | // was not referenced by start code. | ||
| 1408 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | ||
| 1409 | defer { | ||
| 1410 | zcu.sema_prog_node.end(); | ||
| 1411 | zcu.sema_prog_node = undefined; | ||
| 1412 | } | ||
| 1413 | try pt.ensureDeclAnalyzed(decl_index); | ||
| 1414 | } | ||
| 1415 | |||
| 1416 | const decl = zcu.declPtr(decl_index); | ||
| 1417 | const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); | ||
| 1418 | |||
| 1419 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: { | ||
| 1420 | // Add zcu.test_functions to an array decl then make the test_functions | ||
| 1421 | // decl reference it as a slice. | ||
| 1422 | const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count()); | ||
| 1423 | defer gpa.free(test_fn_vals); | ||
| 1424 | |||
| 1425 | for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| { | ||
| 1426 | const test_decl = zcu.declPtr(test_decl_index); | ||
| 1427 | const test_decl_name = try test_decl.fullyQualifiedName(zcu); | ||
| 1428 | const test_decl_name_len = test_decl_name.length(ip); | ||
| 1429 | const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: { | ||
| 1430 | const test_name_ty = try pt.arrayType(.{ | ||
| 1431 | .len = test_decl_name_len, | ||
| 1432 | .child = .u8_type, | ||
| 1433 | }); | ||
| 1434 | const test_name_val = try pt.intern(.{ .aggregate = .{ | ||
| 1435 | .ty = test_name_ty.toIntern(), | ||
| 1436 | .storage = .{ .bytes = test_decl_name.toString() }, | ||
| 1437 | } }); | ||
| 1438 | break :n .{ | ||
| 1439 | .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(), | ||
| 1440 | .val = test_name_val, | ||
| 1441 | }; | ||
| 1442 | }; | ||
| 1443 | |||
| 1444 | const test_fn_fields = .{ | ||
| 1445 | // name | ||
| 1446 | try pt.intern(.{ .slice = .{ | ||
| 1447 | .ty = .slice_const_u8_type, | ||
| 1448 | .ptr = try pt.intern(.{ .ptr = .{ | ||
| 1449 | .ty = .manyptr_const_u8_type, | ||
| 1450 | .base_addr = .{ .anon_decl = test_name_anon_decl }, | ||
| 1451 | .byte_offset = 0, | ||
| 1452 | } }), | ||
| 1453 | .len = try pt.intern(.{ .int = .{ | ||
| 1454 | .ty = .usize_type, | ||
| 1455 | .storage = .{ .u64 = test_decl_name_len }, | ||
| 1456 | } }), | ||
| 1457 | } }), | ||
| 1458 | // func | ||
| 1459 | try pt.intern(.{ .ptr = .{ | ||
| 1460 | .ty = try pt.intern(.{ .ptr_type = .{ | ||
| 1461 | .child = test_decl.typeOf(zcu).toIntern(), | ||
| 1462 | .flags = .{ | ||
| 1463 | .is_const = true, | ||
| 1464 | }, | ||
| 1465 | } }), | ||
| 1466 | .base_addr = .{ .decl = test_decl_index }, | ||
| 1467 | .byte_offset = 0, | ||
| 1468 | } }), | ||
| 1469 | }; | ||
| 1470 | test_fn_val.* = try pt.intern(.{ .aggregate = .{ | ||
| 1471 | .ty = test_fn_ty.toIntern(), | ||
| 1472 | .storage = .{ .elems = &test_fn_fields }, | ||
| 1473 | } }); | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | const array_ty = try pt.arrayType(.{ | ||
| 1477 | .len = test_fn_vals.len, | ||
| 1478 | .child = test_fn_ty.toIntern(), | ||
| 1479 | .sentinel = .none, | ||
| 1480 | }); | ||
| 1481 | const array_val = try pt.intern(.{ .aggregate = .{ | ||
| 1482 | .ty = array_ty.toIntern(), | ||
| 1483 | .storage = .{ .elems = test_fn_vals }, | ||
| 1484 | } }); | ||
| 1485 | break :array .{ | ||
| 1486 | .orig_ty = (try pt.singleConstPtrType(array_ty)).toIntern(), | ||
| 1487 | .val = array_val, | ||
| 1488 | }; | ||
| 1489 | }; | ||
| 1490 | |||
| 1491 | { | ||
| 1492 | const new_ty = try pt.ptrType(.{ | ||
| 1493 | .child = test_fn_ty.toIntern(), | ||
| 1494 | .flags = .{ | ||
| 1495 | .is_const = true, | ||
| 1496 | .size = .Slice, | ||
| 1497 | }, | ||
| 1498 | }); | ||
| 1499 | const new_val = decl.val; | ||
| 1500 | const new_init = try pt.intern(.{ .slice = .{ | ||
| 1501 | .ty = new_ty.toIntern(), | ||
| 1502 | .ptr = try pt.intern(.{ .ptr = .{ | ||
| 1503 | .ty = new_ty.slicePtrFieldType(zcu).toIntern(), | ||
| 1504 | .base_addr = .{ .anon_decl = array_anon_decl }, | ||
| 1505 | .byte_offset = 0, | ||
| 1506 | } }), | ||
| 1507 | .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(), | ||
| 1508 | } }); | ||
| 1509 | ip.mutateVarInit(decl.val.toIntern(), new_init); | ||
| 1510 | |||
| 1511 | // Since we are replacing the Decl's value we must perform cleanup on the | ||
| 1512 | // previous value. | ||
| 1513 | decl.val = new_val; | ||
| 1514 | decl.has_tv = true; | ||
| 1515 | } | ||
| 1516 | { | ||
| 1517 | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); | ||
| 1518 | defer { | ||
| 1519 | zcu.codegen_prog_node.end(); | ||
| 1520 | zcu.codegen_prog_node = undefined; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | try pt.linkerUpdateDecl(decl_index); | ||
| 1524 | } | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void { | ||
| 1528 | const zcu = pt.zcu; | ||
| 1529 | const comp = zcu.comp; | ||
| 1530 | |||
| 1531 | const decl = zcu.declPtr(decl_index); | ||
| 1532 | |||
| 1533 | const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool), 0); | ||
| 1534 | defer codegen_prog_node.end(); | ||
| 1535 | |||
| 1536 | if (comp.bin_file) |lf| { | ||
| 1537 | lf.updateDecl(pt, decl_index) catch |err| switch (err) { | ||
| 1538 | error.OutOfMemory => return error.OutOfMemory, | ||
| 1539 | error.AnalysisFail => { | ||
| 1540 | decl.analysis = .codegen_failure; | ||
| 1541 | }, | ||
| 1542 | else => { | ||
| 1543 | const gpa = zcu.gpa; | ||
| 1544 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | ||
| 1545 | zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create( | ||
| 1546 | gpa, | ||
| 1547 | decl.navSrcLoc(zcu), | ||
| 1548 | "unable to codegen: {s}", | ||
| 1549 | .{@errorName(err)}, | ||
| 1550 | )); | ||
| 1551 | decl.analysis = .codegen_failure; | ||
| 1552 | try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | ||
| 1553 | }, | ||
| 1554 | }; | ||
| 1555 | } else if (zcu.llvm_object) |llvm_object| { | ||
| 1556 | if (build_options.only_c) unreachable; | ||
| 1557 | llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) { | ||
| 1558 | error.OutOfMemory => return error.OutOfMemory, | ||
| 1559 | }; | ||
| 1560 | } | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | /// Shortcut for calling `intern_pool.get`. | ||
| 1564 | pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index { | ||
| 1565 | return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key); | ||
| 1566 | } | ||
| 1567 | |||
| 1568 | /// Shortcut for calling `intern_pool.getCoerced`. | ||
| 1569 | pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value { | ||
| 1570 | return Value.fromInterned(try pt.zcu.intern_pool.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern())); | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type { | ||
| 1574 | return Type.fromInterned(try pt.intern(.{ .int_type = .{ | ||
| 1575 | .signedness = signedness, | ||
| 1576 | .bits = bits, | ||
| 1577 | } })); | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | pub fn errorIntType(pt: Zcu.PerThread) std.mem.Allocator.Error!Type { | ||
| 1581 | return pt.intType(.unsigned, pt.zcu.errorSetBits()); | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | pub fn arrayType(pt: Zcu.PerThread, info: InternPool.Key.ArrayType) Allocator.Error!Type { | ||
| 1585 | return Type.fromInterned(try pt.intern(.{ .array_type = info })); | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | pub fn vectorType(pt: Zcu.PerThread, info: InternPool.Key.VectorType) Allocator.Error!Type { | ||
| 1589 | return Type.fromInterned(try pt.intern(.{ .vector_type = info })); | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | pub fn optionalType(pt: Zcu.PerThread, child_type: InternPool.Index) Allocator.Error!Type { | ||
| 1593 | return Type.fromInterned(try pt.intern(.{ .opt_type = child_type })); | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!Type { | ||
| 1597 | var canon_info = info; | ||
| 1598 | |||
| 1599 | if (info.flags.size == .C) canon_info.flags.is_allowzero = true; | ||
| 1600 | |||
| 1601 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee | ||
| 1602 | // type, we change it to 0 here. If this causes an assertion trip because the | ||
| 1603 | // pointee type needs to be resolved more, that needs to be done before calling | ||
| 1604 | // this ptr() function. | ||
| 1605 | if (info.flags.alignment != .none and | ||
| 1606 | info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt)) | ||
| 1607 | { | ||
| 1608 | canon_info.flags.alignment = .none; | ||
| 1609 | } | ||
| 1610 | |||
| 1611 | switch (info.flags.vector_index) { | ||
| 1612 | // Canonicalize host_size. If it matches the bit size of the pointee type, | ||
| 1613 | // we change it to 0 here. If this causes an assertion trip, the pointee type | ||
| 1614 | // needs to be resolved before calling this ptr() function. | ||
| 1615 | .none => if (info.packed_offset.host_size != 0) { | ||
| 1616 | const elem_bit_size = Type.fromInterned(info.child).bitSize(pt); | ||
| 1617 | assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8); | ||
| 1618 | if (info.packed_offset.host_size * 8 == elem_bit_size) { | ||
| 1619 | canon_info.packed_offset.host_size = 0; | ||
| 1620 | } | ||
| 1621 | }, | ||
| 1622 | .runtime => {}, | ||
| 1623 | _ => assert(@intFromEnum(info.flags.vector_index) < info.packed_offset.host_size), | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info })); | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | /// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer | ||
| 1630 | /// child type's alignment is resolved so that an invalid alignment is not used. | ||
| 1631 | /// In general, prefer this function during semantic analysis. | ||
| 1632 | pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type { | ||
| 1633 | if (info.flags.alignment != .none) { | ||
| 1634 | _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(pt, .sema); | ||
| 1635 | } | ||
| 1636 | return pt.ptrType(info); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type { | ||
| 1640 | return pt.ptrType(.{ .child = child_type.toIntern() }); | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | pub fn singleConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type { | ||
| 1644 | return pt.ptrType(.{ | ||
| 1645 | .child = child_type.toIntern(), | ||
| 1646 | .flags = .{ | ||
| 1647 | .is_const = true, | ||
| 1648 | }, | ||
| 1649 | }); | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | pub fn manyConstPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type { | ||
| 1653 | return pt.ptrType(.{ | ||
| 1654 | .child = child_type.toIntern(), | ||
| 1655 | .flags = .{ | ||
| 1656 | .size = .Many, | ||
| 1657 | .is_const = true, | ||
| 1658 | }, | ||
| 1659 | }); | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | pub fn adjustPtrTypeChild(pt: Zcu.PerThread, ptr_ty: Type, new_child: Type) Allocator.Error!Type { | ||
| 1663 | var info = ptr_ty.ptrInfo(pt.zcu); | ||
| 1664 | info.child = new_child.toIntern(); | ||
| 1665 | return pt.ptrType(info); | ||
| 1666 | } | ||
| 1667 | |||
| 1668 | pub fn funcType(pt: Zcu.PerThread, key: InternPool.GetFuncTypeKey) Allocator.Error!Type { | ||
| 1669 | return Type.fromInterned(try pt.zcu.intern_pool.getFuncType(pt.zcu.gpa, pt.tid, key)); | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | /// Use this for `anyframe->T` only. | ||
| 1673 | /// For `anyframe`, use the `InternPool.Index.anyframe` tag directly. | ||
| 1674 | pub fn anyframeType(pt: Zcu.PerThread, payload_ty: Type) Allocator.Error!Type { | ||
| 1675 | return Type.fromInterned(try pt.intern(.{ .anyframe_type = payload_ty.toIntern() })); | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | pub fn errorUnionType(pt: Zcu.PerThread, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type { | ||
| 1679 | return Type.fromInterned(try pt.intern(.{ .error_union_type = .{ | ||
| 1680 | .error_set_type = error_set_ty.toIntern(), | ||
| 1681 | .payload_type = payload_ty.toIntern(), | ||
| 1682 | } })); | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | pub fn singleErrorSetType(pt: Zcu.PerThread, name: InternPool.NullTerminatedString) Allocator.Error!Type { | ||
| 1686 | const names: *const [1]InternPool.NullTerminatedString = &name; | ||
| 1687 | return Type.fromInterned(try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names)); | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | /// Sorts `names` in place. | ||
| 1691 | pub fn errorSetFromUnsortedNames( | ||
| 1692 | pt: Zcu.PerThread, | ||
| 1693 | names: []InternPool.NullTerminatedString, | ||
| 1694 | ) Allocator.Error!Type { | ||
| 1695 | std.mem.sort( | ||
| 1696 | InternPool.NullTerminatedString, | ||
| 1697 | names, | ||
| 1698 | {}, | ||
| 1699 | InternPool.NullTerminatedString.indexLessThan, | ||
| 1700 | ); | ||
| 1701 | const new_ty = try pt.zcu.intern_pool.getErrorSetType(pt.zcu.gpa, pt.tid, names); | ||
| 1702 | return Type.fromInterned(new_ty); | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | /// Supports only pointers, not pointer-like optionals. | ||
| 1706 | pub fn ptrIntValue(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value { | ||
| 1707 | const mod = pt.zcu; | ||
| 1708 | assert(ty.zigTypeTag(mod) == .Pointer and !ty.isSlice(mod)); | ||
| 1709 | assert(x != 0 or ty.isAllowzeroPtr(mod)); | ||
| 1710 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ | ||
| 1711 | .ty = ty.toIntern(), | ||
| 1712 | .base_addr = .int, | ||
| 1713 | .byte_offset = x, | ||
| 1714 | } })); | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | /// Creates an enum tag value based on the integer tag value. | ||
| 1718 | pub fn enumValue(pt: Zcu.PerThread, ty: Type, tag_int: InternPool.Index) Allocator.Error!Value { | ||
| 1719 | if (std.debug.runtime_safety) { | ||
| 1720 | const tag = ty.zigTypeTag(pt.zcu); | ||
| 1721 | assert(tag == .Enum); | ||
| 1722 | } | ||
| 1723 | return Value.fromInterned(try pt.intern(.{ .enum_tag = .{ | ||
| 1724 | .ty = ty.toIntern(), | ||
| 1725 | .int = tag_int, | ||
| 1726 | } })); | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | /// Creates an enum tag value based on the field index according to source code | ||
| 1730 | /// declaration order. | ||
| 1731 | pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Allocator.Error!Value { | ||
| 1732 | const ip = &pt.zcu.intern_pool; | ||
| 1733 | const enum_type = ip.loadEnumType(ty.toIntern()); | ||
| 1734 | |||
| 1735 | if (enum_type.values.len == 0) { | ||
| 1736 | // Auto-numbered fields. | ||
| 1737 | return Value.fromInterned(try pt.intern(.{ .enum_tag = .{ | ||
| 1738 | .ty = ty.toIntern(), | ||
| 1739 | .int = try pt.intern(.{ .int = .{ | ||
| 1740 | .ty = enum_type.tag_ty, | ||
| 1741 | .storage = .{ .u64 = field_index }, | ||
| 1742 | } }), | ||
| 1743 | } })); | ||
| 1744 | } | ||
| 1745 | |||
| 1746 | return Value.fromInterned(try pt.intern(.{ .enum_tag = .{ | ||
| 1747 | .ty = ty.toIntern(), | ||
| 1748 | .int = enum_type.values.get(ip)[field_index], | ||
| 1749 | } })); | ||
| 1750 | } | ||
| 1751 | |||
| 1752 | pub fn undefValue(pt: Zcu.PerThread, ty: Type) Allocator.Error!Value { | ||
| 1753 | return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | pub fn undefRef(pt: Zcu.PerThread, ty: Type) Allocator.Error!Air.Inst.Ref { | ||
| 1757 | return Air.internedToRef((try pt.undefValue(ty)).toIntern()); | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | pub fn intValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value { | ||
| 1761 | if (std.math.cast(u64, x)) |casted| return pt.intValue_u64(ty, casted); | ||
| 1762 | if (std.math.cast(i64, x)) |casted| return pt.intValue_i64(ty, casted); | ||
| 1763 | var limbs_buffer: [4]usize = undefined; | ||
| 1764 | var big_int = BigIntMutable.init(&limbs_buffer, x); | ||
| 1765 | return pt.intValue_big(ty, big_int.toConst()); | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | pub fn intRef(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Air.Inst.Ref { | ||
| 1769 | return Air.internedToRef((try pt.intValue(ty, x)).toIntern()); | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | pub fn intValue_big(pt: Zcu.PerThread, ty: Type, x: BigIntConst) Allocator.Error!Value { | ||
| 1773 | return Value.fromInterned(try pt.intern(.{ .int = .{ | ||
| 1774 | .ty = ty.toIntern(), | ||
| 1775 | .storage = .{ .big_int = x }, | ||
| 1776 | } })); | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | pub fn intValue_u64(pt: Zcu.PerThread, ty: Type, x: u64) Allocator.Error!Value { | ||
| 1780 | return Value.fromInterned(try pt.intern(.{ .int = .{ | ||
| 1781 | .ty = ty.toIntern(), | ||
| 1782 | .storage = .{ .u64 = x }, | ||
| 1783 | } })); | ||
| 1784 | } | ||
| 1785 | |||
| 1786 | pub fn intValue_i64(pt: Zcu.PerThread, ty: Type, x: i64) Allocator.Error!Value { | ||
| 1787 | return Value.fromInterned(try pt.intern(.{ .int = .{ | ||
| 1788 | .ty = ty.toIntern(), | ||
| 1789 | .storage = .{ .i64 = x }, | ||
| 1790 | } })); | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value { | ||
| 1794 | return Value.fromInterned(try pt.intern(.{ .un = .{ | ||
| 1795 | .ty = union_ty.toIntern(), | ||
| 1796 | .tag = tag.toIntern(), | ||
| 1797 | .val = val.toIntern(), | ||
| 1798 | } })); | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | /// This function casts the float representation down to the representation of the type, potentially | ||
| 1802 | /// losing data if the representation wasn't correct. | ||
| 1803 | pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value { | ||
| 1804 | const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(pt.zcu.getTarget())) { | ||
| 1805 | 16 => .{ .f16 = @as(f16, @floatCast(x)) }, | ||
| 1806 | 32 => .{ .f32 = @as(f32, @floatCast(x)) }, | ||
| 1807 | 64 => .{ .f64 = @as(f64, @floatCast(x)) }, | ||
| 1808 | 80 => .{ .f80 = @as(f80, @floatCast(x)) }, | ||
| 1809 | 128 => .{ .f128 = @as(f128, @floatCast(x)) }, | ||
| 1810 | else => unreachable, | ||
| 1811 | }; | ||
| 1812 | return Value.fromInterned(try pt.intern(.{ .float = .{ | ||
| 1813 | .ty = ty.toIntern(), | ||
| 1814 | .storage = storage, | ||
| 1815 | } })); | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value { | ||
| 1819 | assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern())); | ||
| 1820 | return Value.fromInterned(try pt.intern(.{ .opt = .{ | ||
| 1821 | .ty = opt_ty.toIntern(), | ||
| 1822 | .val = .none, | ||
| 1823 | } })); | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type { | ||
| 1827 | return pt.intType(.unsigned, Type.smallestUnsignedBits(max)); | ||
| 1828 | } | ||
| 1829 | |||
| 1830 | /// Returns the smallest possible integer type containing both `min` and | ||
| 1831 | /// `max`. Asserts that neither value is undef. | ||
| 1832 | /// TODO: if #3806 is implemented, this becomes trivial | ||
| 1833 | pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type { | ||
| 1834 | const mod = pt.zcu; | ||
| 1835 | assert(!min.isUndef(mod)); | ||
| 1836 | assert(!max.isUndef(mod)); | ||
| 1837 | |||
| 1838 | if (std.debug.runtime_safety) { | ||
| 1839 | assert(Value.order(min, max, pt).compare(.lte)); | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | const sign = min.orderAgainstZero(pt) == .lt; | ||
| 1843 | |||
| 1844 | const min_val_bits = pt.intBitsForValue(min, sign); | ||
| 1845 | const max_val_bits = pt.intBitsForValue(max, sign); | ||
| 1846 | |||
| 1847 | return pt.intType( | ||
| 1848 | if (sign) .signed else .unsigned, | ||
| 1849 | @max(min_val_bits, max_val_bits), | ||
| 1850 | ); | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | /// Given a value representing an integer, returns the number of bits necessary to represent | ||
| 1854 | /// this value in an integer. If `sign` is true, returns the number of bits necessary in a | ||
| 1855 | /// twos-complement integer; otherwise in an unsigned integer. | ||
| 1856 | /// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true. | ||
| 1857 | pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 { | ||
| 1858 | const mod = pt.zcu; | ||
| 1859 | assert(!val.isUndef(mod)); | ||
| 1860 | |||
| 1861 | const key = mod.intern_pool.indexToKey(val.toIntern()); | ||
| 1862 | switch (key.int.storage) { | ||
| 1863 | .i64 => |x| { | ||
| 1864 | if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted) + @intFromBool(sign); | ||
| 1865 | assert(sign); | ||
| 1866 | // Protect against overflow in the following negation. | ||
| 1867 | if (x == std.math.minInt(i64)) return 64; | ||
| 1868 | return Type.smallestUnsignedBits(@as(u64, @intCast(-(x + 1)))) + 1; | ||
| 1869 | }, | ||
| 1870 | .u64 => |x| { | ||
| 1871 | return Type.smallestUnsignedBits(x) + @intFromBool(sign); | ||
| 1872 | }, | ||
| 1873 | .big_int => |big| { | ||
| 1874 | if (big.positive) return @as(u16, @intCast(big.bitCountAbs() + @intFromBool(sign))); | ||
| 1875 | |||
| 1876 | // Zero is still a possibility, in which case unsigned is fine | ||
| 1877 | if (big.eqlZero()) return 0; | ||
| 1878 | |||
| 1879 | return @as(u16, @intCast(big.bitCountTwosComp())); | ||
| 1880 | }, | ||
| 1881 | .lazy_align => |lazy_ty| { | ||
| 1882 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt).toByteUnits() orelse 0) + @intFromBool(sign); | ||
| 1883 | }, | ||
| 1884 | .lazy_size => |lazy_ty| { | ||
| 1885 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt)) + @intFromBool(sign); | ||
| 1886 | }, | ||
| 1887 | } | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) Zcu.UnionLayout { | ||
| 1891 | const mod = pt.zcu; | ||
| 1892 | const ip = &mod.intern_pool; | ||
| 1893 | assert(loaded_union.haveLayout(ip)); | ||
| 1894 | var most_aligned_field: u32 = undefined; | ||
| 1895 | var most_aligned_field_size: u64 = undefined; | ||
| 1896 | var biggest_field: u32 = undefined; | ||
| 1897 | var payload_size: u64 = 0; | ||
| 1898 | var payload_align: InternPool.Alignment = .@"1"; | ||
| 1899 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { | ||
| 1900 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | ||
| 1901 | |||
| 1902 | const explicit_align = loaded_union.fieldAlign(ip, field_index); | ||
| 1903 | const field_align = if (explicit_align != .none) | ||
| 1904 | explicit_align | ||
| 1905 | else | ||
| 1906 | Type.fromInterned(field_ty).abiAlignment(pt); | ||
| 1907 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | ||
| 1908 | if (field_size > payload_size) { | ||
| 1909 | payload_size = field_size; | ||
| 1910 | biggest_field = @intCast(field_index); | ||
| 1911 | } | ||
| 1912 | if (field_align.compare(.gte, payload_align)) { | ||
| 1913 | payload_align = field_align; | ||
| 1914 | most_aligned_field = @intCast(field_index); | ||
| 1915 | most_aligned_field_size = field_size; | ||
| 1916 | } | ||
| 1917 | } | ||
| 1918 | const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); | ||
| 1919 | if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) { | ||
| 1920 | return .{ | ||
| 1921 | .abi_size = payload_align.forward(payload_size), | ||
| 1922 | .abi_align = payload_align, | ||
| 1923 | .most_aligned_field = most_aligned_field, | ||
| 1924 | .most_aligned_field_size = most_aligned_field_size, | ||
| 1925 | .biggest_field = biggest_field, | ||
| 1926 | .payload_size = payload_size, | ||
| 1927 | .payload_align = payload_align, | ||
| 1928 | .tag_align = .none, | ||
| 1929 | .tag_size = 0, | ||
| 1930 | .padding = 0, | ||
| 1931 | }; | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt); | ||
| 1935 | const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1"); | ||
| 1936 | return .{ | ||
| 1937 | .abi_size = loaded_union.size(ip).*, | ||
| 1938 | .abi_align = tag_align.max(payload_align), | ||
| 1939 | .most_aligned_field = most_aligned_field, | ||
| 1940 | .most_aligned_field_size = most_aligned_field_size, | ||
| 1941 | .biggest_field = biggest_field, | ||
| 1942 | .payload_size = payload_size, | ||
| 1943 | .payload_align = payload_align, | ||
| 1944 | .tag_align = tag_align, | ||
| 1945 | .tag_size = tag_size, | ||
| 1946 | .padding = loaded_union.padding(ip).*, | ||
| 1947 | }; | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 { | ||
| 1951 | return mod.getUnionLayout(loaded_union).abi_size; | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | /// Returns 0 if the union is represented with 0 bits at runtime. | ||
| 1955 | pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment { | ||
| 1956 | const mod = pt.zcu; | ||
| 1957 | const ip = &mod.intern_pool; | ||
| 1958 | const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); | ||
| 1959 | var max_align: InternPool.Alignment = .none; | ||
| 1960 | if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt); | ||
| 1961 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { | ||
| 1962 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | ||
| 1963 | |||
| 1964 | const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); | ||
| 1965 | max_align = max_align.max(field_align); | ||
| 1966 | } | ||
| 1967 | return max_align; | ||
| 1968 | } | ||
| 1969 | |||
| 1970 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | ||
| 1971 | pub fn unionFieldNormalAlignment( | ||
| 1972 | pt: Zcu.PerThread, | ||
| 1973 | loaded_union: InternPool.LoadedUnionType, | ||
| 1974 | field_index: u32, | ||
| 1975 | ) InternPool.Alignment { | ||
| 1976 | return pt.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable; | ||
| 1977 | } | ||
| 1978 | |||
| 1979 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | ||
| 1980 | /// If `strat` is `.sema`, may perform type resolution. | ||
| 1981 | pub fn unionFieldNormalAlignmentAdvanced( | ||
| 1982 | pt: Zcu.PerThread, | ||
| 1983 | loaded_union: InternPool.LoadedUnionType, | ||
| 1984 | field_index: u32, | ||
| 1985 | strat: Type.ResolveStrat, | ||
| 1986 | ) Zcu.SemaError!InternPool.Alignment { | ||
| 1987 | const ip = &pt.zcu.intern_pool; | ||
| 1988 | assert(loaded_union.flagsPtr(ip).layout != .@"packed"); | ||
| 1989 | const field_align = loaded_union.fieldAlign(ip, field_index); | ||
| 1990 | if (field_align != .none) return field_align; | ||
| 1991 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | ||
| 1992 | if (field_ty.isNoReturn(pt.zcu)) return .none; | ||
| 1993 | return (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; | ||
| 1994 | } | ||
| 1995 | |||
| 1996 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | ||
| 1997 | pub fn structFieldAlignment( | ||
| 1998 | pt: Zcu.PerThread, | ||
| 1999 | explicit_alignment: InternPool.Alignment, | ||
| 2000 | field_ty: Type, | ||
| 2001 | layout: std.builtin.Type.ContainerLayout, | ||
| 2002 | ) InternPool.Alignment { | ||
| 2003 | return pt.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable; | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | ||
| 2007 | /// If `strat` is `.sema`, may perform type resolution. | ||
| 2008 | pub fn structFieldAlignmentAdvanced( | ||
| 2009 | pt: Zcu.PerThread, | ||
| 2010 | explicit_alignment: InternPool.Alignment, | ||
| 2011 | field_ty: Type, | ||
| 2012 | layout: std.builtin.Type.ContainerLayout, | ||
| 2013 | strat: Type.ResolveStrat, | ||
| 2014 | ) Zcu.SemaError!InternPool.Alignment { | ||
| 2015 | assert(layout != .@"packed"); | ||
| 2016 | if (explicit_alignment != .none) return explicit_alignment; | ||
| 2017 | const ty_abi_align = (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; | ||
| 2018 | switch (layout) { | ||
| 2019 | .@"packed" => unreachable, | ||
| 2020 | .auto => if (pt.zcu.getTarget().ofmt != .c) return ty_abi_align, | ||
| 2021 | .@"extern" => {}, | ||
| 2022 | } | ||
| 2023 | // extern | ||
| 2024 | if (field_ty.isAbiInt(pt.zcu) and field_ty.intInfo(pt.zcu).bits >= 128) { | ||
| 2025 | return ty_abi_align.maxStrict(.@"16"); | ||
| 2026 | } | ||
| 2027 | return ty_abi_align; | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets | ||
| 2031 | /// into the packed struct InternPool data rather than computing this on the | ||
| 2032 | /// fly, however it was found to perform worse when measured on real world | ||
| 2033 | /// projects. | ||
| 2034 | pub fn structPackedFieldBitOffset( | ||
| 2035 | pt: Zcu.PerThread, | ||
| 2036 | struct_type: InternPool.LoadedStructType, | ||
| 2037 | field_index: u32, | ||
| 2038 | ) u16 { | ||
| 2039 | const mod = pt.zcu; | ||
| 2040 | const ip = &mod.intern_pool; | ||
| 2041 | assert(struct_type.layout == .@"packed"); | ||
| 2042 | assert(struct_type.haveLayout(ip)); | ||
| 2043 | var bit_sum: u64 = 0; | ||
| 2044 | for (0..struct_type.field_types.len) |i| { | ||
| 2045 | if (i == field_index) { | ||
| 2046 | return @intCast(bit_sum); | ||
| 2047 | } | ||
| 2048 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | ||
| 2049 | bit_sum += field_ty.bitSize(pt); | ||
| 2050 | } | ||
| 2051 | unreachable; // index out of bounds | ||
| 2052 | } | ||
| 2053 | |||
| 2054 | pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref { | ||
| 2055 | const decl_index = try pt.getBuiltinDecl(name); | ||
| 2056 | pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt"); | ||
| 2057 | return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern()); | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex { | ||
| 2061 | const zcu = pt.zcu; | ||
| 2062 | const gpa = zcu.gpa; | ||
| 2063 | const ip = &zcu.intern_pool; | ||
| 2064 | const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig"); | ||
| 2065 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?; | ||
| 2066 | const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?; | ||
| 2067 | const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); | ||
| 2068 | const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'"); | ||
| 2069 | pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt"); | ||
| 2070 | const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt"); | ||
| 2071 | const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls); | ||
| 2072 | return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt"); | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type { | ||
| 2076 | const ty_inst = try pt.getBuiltin(name); | ||
| 2077 | const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt")); | ||
| 2078 | ty.resolveFully(pt) catch @panic("std.builtin is corrupt"); | ||
| 2079 | return ty; | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | const Air = @import("../Air.zig"); | ||
| 2083 | const Allocator = std.mem.Allocator; | ||
| 2084 | const assert = std.debug.assert; | ||
| 2085 | const BigIntConst = std.math.big.int.Const; | ||
| 2086 | const BigIntMutable = std.math.big.int.Mutable; | ||
| 2087 | const build_options = @import("build_options"); | ||
| 2088 | const builtin = @import("builtin"); | ||
| 2089 | const Cache = std.Build.Cache; | ||
| 2090 | const InternPool = @import("../InternPool.zig"); | ||
| 2091 | const isUpDir = @import("../introspect.zig").isUpDir; | ||
| 2092 | const Liveness = @import("../Liveness.zig"); | ||
| 2093 | const log = std.log.scoped(.zcu); | ||
| 2094 | const Module = @import("../Package.zig").Module; | ||
| 2095 | const Sema = @import("../Sema.zig"); | ||
| 2096 | const std = @import("std"); | ||
| 2097 | const target_util = @import("../target.zig"); | ||
| 2098 | const trace = @import("../tracy.zig").trace; | ||
| 2099 | const Type = @import("../Type.zig"); | ||
| 2100 | const Value = @import("../Value.zig"); | ||
| 2101 | const Zcu = @import("../Zcu.zig"); | ||
| 2102 | const Zir = std.zig.Zir; | ||
src/arch/aarch64/CodeGen.zig+220-163| ... | @@ -12,11 +12,9 @@ const Type = @import("../../Type.zig"); | ... | @@ -12,11 +12,9 @@ const Type = @import("../../Type.zig"); |
| 12 | const Value = @import("../../Value.zig"); | 12 | const Value = @import("../../Value.zig"); |
| 13 | const link = @import("../../link.zig"); | 13 | const link = @import("../../link.zig"); |
| 14 | const Zcu = @import("../../Zcu.zig"); | 14 | const Zcu = @import("../../Zcu.zig"); |
| 15 | /// Deprecated. | ||
| 16 | const Module = Zcu; | ||
| 17 | const InternPool = @import("../../InternPool.zig"); | 15 | const InternPool = @import("../../InternPool.zig"); |
| 18 | const Compilation = @import("../../Compilation.zig"); | 16 | const Compilation = @import("../../Compilation.zig"); |
| 19 | const ErrorMsg = Module.ErrorMsg; | 17 | const ErrorMsg = Zcu.ErrorMsg; |
| 20 | const Target = std.Target; | 18 | const Target = std.Target; |
| 21 | const Allocator = mem.Allocator; | 19 | const Allocator = mem.Allocator; |
| 22 | const trace = @import("../../tracy.zig").trace; | 20 | const trace = @import("../../tracy.zig").trace; |
| ... | @@ -47,6 +45,7 @@ const gp = abi.RegisterClass.gp; | ... | @@ -47,6 +45,7 @@ const gp = abi.RegisterClass.gp; |
| 47 | const InnerError = CodeGenError || error{OutOfRegisters}; | 45 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 48 | 46 | ||
| 49 | gpa: Allocator, | 47 | gpa: Allocator, |
| 48 | pt: Zcu.PerThread, | ||
| 50 | air: Air, | 49 | air: Air, |
| 51 | liveness: Liveness, | 50 | liveness: Liveness, |
| 52 | bin_file: *link.File, | 51 | bin_file: *link.File, |
| ... | @@ -59,7 +58,7 @@ args: []MCValue, | ... | @@ -59,7 +58,7 @@ args: []MCValue, |
| 59 | ret_mcv: MCValue, | 58 | ret_mcv: MCValue, |
| 60 | fn_type: Type, | 59 | fn_type: Type, |
| 61 | arg_index: u32, | 60 | arg_index: u32, |
| 62 | src_loc: Module.LazySrcLoc, | 61 | src_loc: Zcu.LazySrcLoc, |
| 63 | stack_align: u32, | 62 | stack_align: u32, |
| 64 | 63 | ||
| 65 | /// MIR Instructions | 64 | /// MIR Instructions |
| ... | @@ -331,15 +330,16 @@ const Self = @This(); | ... | @@ -331,15 +330,16 @@ const Self = @This(); |
| 331 | 330 | ||
| 332 | pub fn generate( | 331 | pub fn generate( |
| 333 | lf: *link.File, | 332 | lf: *link.File, |
| 334 | src_loc: Module.LazySrcLoc, | 333 | pt: Zcu.PerThread, |
| 334 | src_loc: Zcu.LazySrcLoc, | ||
| 335 | func_index: InternPool.Index, | 335 | func_index: InternPool.Index, |
| 336 | air: Air, | 336 | air: Air, |
| 337 | liveness: Liveness, | 337 | liveness: Liveness, |
| 338 | code: *std.ArrayList(u8), | 338 | code: *std.ArrayList(u8), |
| 339 | debug_output: DebugInfoOutput, | 339 | debug_output: DebugInfoOutput, |
| 340 | ) CodeGenError!Result { | 340 | ) CodeGenError!Result { |
| 341 | const gpa = lf.comp.gpa; | 341 | const zcu = pt.zcu; |
| 342 | const zcu = lf.comp.module.?; | 342 | const gpa = zcu.gpa; |
| 343 | const func = zcu.funcInfo(func_index); | 343 | const func = zcu.funcInfo(func_index); |
| 344 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 344 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 345 | assert(fn_owner_decl.has_tv); | 345 | assert(fn_owner_decl.has_tv); |
| ... | @@ -355,8 +355,9 @@ pub fn generate( | ... | @@ -355,8 +355,9 @@ pub fn generate( |
| 355 | } | 355 | } |
| 356 | try branch_stack.append(.{}); | 356 | try branch_stack.append(.{}); |
| 357 | 357 | ||
| 358 | var function = Self{ | 358 | var function: Self = .{ |
| 359 | .gpa = gpa, | 359 | .gpa = gpa, |
| 360 | .pt = pt, | ||
| 360 | .air = air, | 361 | .air = air, |
| 361 | .liveness = liveness, | 362 | .liveness = liveness, |
| 362 | .debug_output = debug_output, | 363 | .debug_output = debug_output, |
| ... | @@ -476,7 +477,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -476,7 +477,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 476 | } | 477 | } |
| 477 | 478 | ||
| 478 | fn gen(self: *Self) !void { | 479 | fn gen(self: *Self) !void { |
| 479 | const mod = self.bin_file.comp.module.?; | 480 | const pt = self.pt; |
| 481 | const mod = pt.zcu; | ||
| 480 | const cc = self.fn_type.fnCallingConvention(mod); | 482 | const cc = self.fn_type.fnCallingConvention(mod); |
| 481 | if (cc != .Naked) { | 483 | if (cc != .Naked) { |
| 482 | // stp fp, lr, [sp, #-16]! | 484 | // stp fp, lr, [sp, #-16]! |
| ... | @@ -526,8 +528,8 @@ fn gen(self: *Self) !void { | ... | @@ -526,8 +528,8 @@ fn gen(self: *Self) !void { |
| 526 | 528 | ||
| 527 | const ty = self.typeOfIndex(inst); | 529 | const ty = self.typeOfIndex(inst); |
| 528 | 530 | ||
| 529 | const abi_size = @as(u32, @intCast(ty.abiSize(mod))); | 531 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); |
| 530 | const abi_align = ty.abiAlignment(mod); | 532 | const abi_align = ty.abiAlignment(pt); |
| 531 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | 533 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 532 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 534 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 533 | 535 | ||
| ... | @@ -656,7 +658,8 @@ fn gen(self: *Self) !void { | ... | @@ -656,7 +658,8 @@ fn gen(self: *Self) !void { |
| 656 | } | 658 | } |
| 657 | 659 | ||
| 658 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | 660 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 659 | const mod = self.bin_file.comp.module.?; | 661 | const pt = self.pt; |
| 662 | const mod = pt.zcu; | ||
| 660 | const ip = &mod.intern_pool; | 663 | const ip = &mod.intern_pool; |
| 661 | const air_tags = self.air.instructions.items(.tag); | 664 | const air_tags = self.air.instructions.items(.tag); |
| 662 | 665 | ||
| ... | @@ -1022,31 +1025,32 @@ fn allocMem( | ... | @@ -1022,31 +1025,32 @@ fn allocMem( |
| 1022 | 1025 | ||
| 1023 | /// Use a pointer instruction as the basis for allocating stack memory. | 1026 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1024 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | 1027 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1025 | const mod = self.bin_file.comp.module.?; | 1028 | const pt = self.pt; |
| 1029 | const mod = pt.zcu; | ||
| 1026 | const elem_ty = self.typeOfIndex(inst).childType(mod); | 1030 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 1027 | 1031 | ||
| 1028 | if (!elem_ty.hasRuntimeBits(mod)) { | 1032 | if (!elem_ty.hasRuntimeBits(pt)) { |
| 1029 | // return the stack offset 0. Stack offset 0 will be where all | 1033 | // return the stack offset 0. Stack offset 0 will be where all |
| 1030 | // zero-sized stack allocations live as non-zero-sized | 1034 | // zero-sized stack allocations live as non-zero-sized |
| 1031 | // allocations will always have an offset > 0. | 1035 | // allocations will always have an offset > 0. |
| 1032 | return @as(u32, 0); | 1036 | return @as(u32, 0); |
| 1033 | } | 1037 | } |
| 1034 | 1038 | ||
| 1035 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 1039 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 1036 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 1040 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1037 | }; | 1041 | }; |
| 1038 | // TODO swap this for inst.ty.ptrAlign | 1042 | // TODO swap this for inst.ty.ptrAlign |
| 1039 | const abi_align = elem_ty.abiAlignment(mod); | 1043 | const abi_align = elem_ty.abiAlignment(pt); |
| 1040 | 1044 | ||
| 1041 | return self.allocMem(abi_size, abi_align, inst); | 1045 | return self.allocMem(abi_size, abi_align, inst); |
| 1042 | } | 1046 | } |
| 1043 | 1047 | ||
| 1044 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { | 1048 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1045 | const mod = self.bin_file.comp.module.?; | 1049 | const pt = self.pt; |
| 1046 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 1050 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 1047 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 1051 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1048 | }; | 1052 | }; |
| 1049 | const abi_align = elem_ty.abiAlignment(mod); | 1053 | const abi_align = elem_ty.abiAlignment(pt); |
| 1050 | 1054 | ||
| 1051 | if (reg_ok) { | 1055 | if (reg_ok) { |
| 1052 | // Make sure the type can fit in a register before we try to allocate one. | 1056 | // Make sure the type can fit in a register before we try to allocate one. |
| ... | @@ -1133,14 +1137,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1133,14 +1137,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1133 | } | 1137 | } |
| 1134 | 1138 | ||
| 1135 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { | 1139 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1136 | const mod = self.bin_file.comp.module.?; | 1140 | const pt = self.pt; |
| 1141 | const mod = pt.zcu; | ||
| 1137 | const result: MCValue = switch (self.ret_mcv) { | 1142 | const result: MCValue = switch (self.ret_mcv) { |
| 1138 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, | 1143 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1139 | .stack_offset => blk: { | 1144 | .stack_offset => blk: { |
| 1140 | // self.ret_mcv is an address to where this function | 1145 | // self.ret_mcv is an address to where this function |
| 1141 | // should store its result into | 1146 | // should store its result into |
| 1142 | const ret_ty = self.fn_type.fnReturnType(mod); | 1147 | const ret_ty = self.fn_type.fnReturnType(mod); |
| 1143 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 1148 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 1144 | 1149 | ||
| 1145 | // addr_reg will contain the address of where to store the | 1150 | // addr_reg will contain the address of where to store the |
| 1146 | // result into | 1151 | // result into |
| ... | @@ -1170,7 +1175,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1170,7 +1175,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1170 | if (self.liveness.isUnused(inst)) | 1175 | if (self.liveness.isUnused(inst)) |
| 1171 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); | 1176 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 1172 | 1177 | ||
| 1173 | const mod = self.bin_file.comp.module.?; | 1178 | const pt = self.pt; |
| 1179 | const mod = pt.zcu; | ||
| 1174 | const operand = ty_op.operand; | 1180 | const operand = ty_op.operand; |
| 1175 | const operand_mcv = try self.resolveInst(operand); | 1181 | const operand_mcv = try self.resolveInst(operand); |
| 1176 | const operand_ty = self.typeOf(operand); | 1182 | const operand_ty = self.typeOf(operand); |
| ... | @@ -1251,7 +1257,8 @@ fn trunc( | ... | @@ -1251,7 +1257,8 @@ fn trunc( |
| 1251 | operand_ty: Type, | 1257 | operand_ty: Type, |
| 1252 | dest_ty: Type, | 1258 | dest_ty: Type, |
| 1253 | ) !MCValue { | 1259 | ) !MCValue { |
| 1254 | const mod = self.bin_file.comp.module.?; | 1260 | const pt = self.pt; |
| 1261 | const mod = pt.zcu; | ||
| 1255 | const info_a = operand_ty.intInfo(mod); | 1262 | const info_a = operand_ty.intInfo(mod); |
| 1256 | const info_b = dest_ty.intInfo(mod); | 1263 | const info_b = dest_ty.intInfo(mod); |
| 1257 | 1264 | ||
| ... | @@ -1314,7 +1321,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1314,7 +1321,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1314 | 1321 | ||
| 1315 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { | 1322 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1316 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1323 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1317 | const mod = self.bin_file.comp.module.?; | 1324 | const pt = self.pt; |
| 1325 | const mod = pt.zcu; | ||
| 1318 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1326 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1319 | const operand = try self.resolveInst(ty_op.operand); | 1327 | const operand = try self.resolveInst(ty_op.operand); |
| 1320 | const operand_ty = self.typeOf(ty_op.operand); | 1328 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -1409,7 +1417,8 @@ fn minMax( | ... | @@ -1409,7 +1417,8 @@ fn minMax( |
| 1409 | rhs_ty: Type, | 1417 | rhs_ty: Type, |
| 1410 | maybe_inst: ?Air.Inst.Index, | 1418 | maybe_inst: ?Air.Inst.Index, |
| 1411 | ) !MCValue { | 1419 | ) !MCValue { |
| 1412 | const mod = self.bin_file.comp.module.?; | 1420 | const pt = self.pt; |
| 1421 | const mod = pt.zcu; | ||
| 1413 | switch (lhs_ty.zigTypeTag(mod)) { | 1422 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1414 | .Float => return self.fail("TODO ARM min/max on floats", .{}), | 1423 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1415 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), | 1424 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| ... | @@ -1899,7 +1908,8 @@ fn addSub( | ... | @@ -1899,7 +1908,8 @@ fn addSub( |
| 1899 | rhs_ty: Type, | 1908 | rhs_ty: Type, |
| 1900 | maybe_inst: ?Air.Inst.Index, | 1909 | maybe_inst: ?Air.Inst.Index, |
| 1901 | ) InnerError!MCValue { | 1910 | ) InnerError!MCValue { |
| 1902 | const mod = self.bin_file.comp.module.?; | 1911 | const pt = self.pt; |
| 1912 | const mod = pt.zcu; | ||
| 1903 | switch (lhs_ty.zigTypeTag(mod)) { | 1913 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1904 | .Float => return self.fail("TODO binary operations on floats", .{}), | 1914 | .Float => return self.fail("TODO binary operations on floats", .{}), |
| 1905 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 1915 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| ... | @@ -1960,7 +1970,8 @@ fn mul( | ... | @@ -1960,7 +1970,8 @@ fn mul( |
| 1960 | rhs_ty: Type, | 1970 | rhs_ty: Type, |
| 1961 | maybe_inst: ?Air.Inst.Index, | 1971 | maybe_inst: ?Air.Inst.Index, |
| 1962 | ) InnerError!MCValue { | 1972 | ) InnerError!MCValue { |
| 1963 | const mod = self.bin_file.comp.module.?; | 1973 | const pt = self.pt; |
| 1974 | const mod = pt.zcu; | ||
| 1964 | switch (lhs_ty.zigTypeTag(mod)) { | 1975 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1965 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 1976 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 1966 | .Int => { | 1977 | .Int => { |
| ... | @@ -1992,7 +2003,8 @@ fn divFloat( | ... | @@ -1992,7 +2003,8 @@ fn divFloat( |
| 1992 | _ = rhs_ty; | 2003 | _ = rhs_ty; |
| 1993 | _ = maybe_inst; | 2004 | _ = maybe_inst; |
| 1994 | 2005 | ||
| 1995 | const mod = self.bin_file.comp.module.?; | 2006 | const pt = self.pt; |
| 2007 | const mod = pt.zcu; | ||
| 1996 | switch (lhs_ty.zigTypeTag(mod)) { | 2008 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1997 | .Float => return self.fail("TODO div_float", .{}), | 2009 | .Float => return self.fail("TODO div_float", .{}), |
| 1998 | .Vector => return self.fail("TODO div_float on vectors", .{}), | 2010 | .Vector => return self.fail("TODO div_float on vectors", .{}), |
| ... | @@ -2008,7 +2020,8 @@ fn divTrunc( | ... | @@ -2008,7 +2020,8 @@ fn divTrunc( |
| 2008 | rhs_ty: Type, | 2020 | rhs_ty: Type, |
| 2009 | maybe_inst: ?Air.Inst.Index, | 2021 | maybe_inst: ?Air.Inst.Index, |
| 2010 | ) InnerError!MCValue { | 2022 | ) InnerError!MCValue { |
| 2011 | const mod = self.bin_file.comp.module.?; | 2023 | const pt = self.pt; |
| 2024 | const mod = pt.zcu; | ||
| 2012 | switch (lhs_ty.zigTypeTag(mod)) { | 2025 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2013 | .Float => return self.fail("TODO div on floats", .{}), | 2026 | .Float => return self.fail("TODO div on floats", .{}), |
| 2014 | .Vector => return self.fail("TODO div on vectors", .{}), | 2027 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | @@ -2042,7 +2055,8 @@ fn divFloor( | ... | @@ -2042,7 +2055,8 @@ fn divFloor( |
| 2042 | rhs_ty: Type, | 2055 | rhs_ty: Type, |
| 2043 | maybe_inst: ?Air.Inst.Index, | 2056 | maybe_inst: ?Air.Inst.Index, |
| 2044 | ) InnerError!MCValue { | 2057 | ) InnerError!MCValue { |
| 2045 | const mod = self.bin_file.comp.module.?; | 2058 | const pt = self.pt; |
| 2059 | const mod = pt.zcu; | ||
| 2046 | switch (lhs_ty.zigTypeTag(mod)) { | 2060 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2047 | .Float => return self.fail("TODO div on floats", .{}), | 2061 | .Float => return self.fail("TODO div on floats", .{}), |
| 2048 | .Vector => return self.fail("TODO div on vectors", .{}), | 2062 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | @@ -2075,7 +2089,8 @@ fn divExact( | ... | @@ -2075,7 +2089,8 @@ fn divExact( |
| 2075 | rhs_ty: Type, | 2089 | rhs_ty: Type, |
| 2076 | maybe_inst: ?Air.Inst.Index, | 2090 | maybe_inst: ?Air.Inst.Index, |
| 2077 | ) InnerError!MCValue { | 2091 | ) InnerError!MCValue { |
| 2078 | const mod = self.bin_file.comp.module.?; | 2092 | const pt = self.pt; |
| 2093 | const mod = pt.zcu; | ||
| 2079 | switch (lhs_ty.zigTypeTag(mod)) { | 2094 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2080 | .Float => return self.fail("TODO div on floats", .{}), | 2095 | .Float => return self.fail("TODO div on floats", .{}), |
| 2081 | .Vector => return self.fail("TODO div on vectors", .{}), | 2096 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | @@ -2111,7 +2126,8 @@ fn rem( | ... | @@ -2111,7 +2126,8 @@ fn rem( |
| 2111 | ) InnerError!MCValue { | 2126 | ) InnerError!MCValue { |
| 2112 | _ = maybe_inst; | 2127 | _ = maybe_inst; |
| 2113 | 2128 | ||
| 2114 | const mod = self.bin_file.comp.module.?; | 2129 | const pt = self.pt; |
| 2130 | const mod = pt.zcu; | ||
| 2115 | switch (lhs_ty.zigTypeTag(mod)) { | 2131 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2116 | .Float => return self.fail("TODO rem/mod on floats", .{}), | 2132 | .Float => return self.fail("TODO rem/mod on floats", .{}), |
| 2117 | .Vector => return self.fail("TODO rem/mod on vectors", .{}), | 2133 | .Vector => return self.fail("TODO rem/mod on vectors", .{}), |
| ... | @@ -2182,7 +2198,8 @@ fn modulo( | ... | @@ -2182,7 +2198,8 @@ fn modulo( |
| 2182 | _ = rhs_ty; | 2198 | _ = rhs_ty; |
| 2183 | _ = maybe_inst; | 2199 | _ = maybe_inst; |
| 2184 | 2200 | ||
| 2185 | const mod = self.bin_file.comp.module.?; | 2201 | const pt = self.pt; |
| 2202 | const mod = pt.zcu; | ||
| 2186 | switch (lhs_ty.zigTypeTag(mod)) { | 2203 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2187 | .Float => return self.fail("TODO mod on floats", .{}), | 2204 | .Float => return self.fail("TODO mod on floats", .{}), |
| 2188 | .Vector => return self.fail("TODO mod on vectors", .{}), | 2205 | .Vector => return self.fail("TODO mod on vectors", .{}), |
| ... | @@ -2200,7 +2217,8 @@ fn wrappingArithmetic( | ... | @@ -2200,7 +2217,8 @@ fn wrappingArithmetic( |
| 2200 | rhs_ty: Type, | 2217 | rhs_ty: Type, |
| 2201 | maybe_inst: ?Air.Inst.Index, | 2218 | maybe_inst: ?Air.Inst.Index, |
| 2202 | ) InnerError!MCValue { | 2219 | ) InnerError!MCValue { |
| 2203 | const mod = self.bin_file.comp.module.?; | 2220 | const pt = self.pt; |
| 2221 | const mod = pt.zcu; | ||
| 2204 | switch (lhs_ty.zigTypeTag(mod)) { | 2222 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2205 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 2223 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2206 | .Int => { | 2224 | .Int => { |
| ... | @@ -2235,7 +2253,8 @@ fn bitwise( | ... | @@ -2235,7 +2253,8 @@ fn bitwise( |
| 2235 | rhs_ty: Type, | 2253 | rhs_ty: Type, |
| 2236 | maybe_inst: ?Air.Inst.Index, | 2254 | maybe_inst: ?Air.Inst.Index, |
| 2237 | ) InnerError!MCValue { | 2255 | ) InnerError!MCValue { |
| 2238 | const mod = self.bin_file.comp.module.?; | 2256 | const pt = self.pt; |
| 2257 | const mod = pt.zcu; | ||
| 2239 | switch (lhs_ty.zigTypeTag(mod)) { | 2258 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2240 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 2259 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2241 | .Int => { | 2260 | .Int => { |
| ... | @@ -2270,7 +2289,8 @@ fn shiftExact( | ... | @@ -2270,7 +2289,8 @@ fn shiftExact( |
| 2270 | ) InnerError!MCValue { | 2289 | ) InnerError!MCValue { |
| 2271 | _ = rhs_ty; | 2290 | _ = rhs_ty; |
| 2272 | 2291 | ||
| 2273 | const mod = self.bin_file.comp.module.?; | 2292 | const pt = self.pt; |
| 2293 | const mod = pt.zcu; | ||
| 2274 | switch (lhs_ty.zigTypeTag(mod)) { | 2294 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2275 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 2295 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2276 | .Int => { | 2296 | .Int => { |
| ... | @@ -2320,7 +2340,8 @@ fn shiftNormal( | ... | @@ -2320,7 +2340,8 @@ fn shiftNormal( |
| 2320 | rhs_ty: Type, | 2340 | rhs_ty: Type, |
| 2321 | maybe_inst: ?Air.Inst.Index, | 2341 | maybe_inst: ?Air.Inst.Index, |
| 2322 | ) InnerError!MCValue { | 2342 | ) InnerError!MCValue { |
| 2323 | const mod = self.bin_file.comp.module.?; | 2343 | const pt = self.pt; |
| 2344 | const mod = pt.zcu; | ||
| 2324 | switch (lhs_ty.zigTypeTag(mod)) { | 2345 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2325 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 2346 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2326 | .Int => { | 2347 | .Int => { |
| ... | @@ -2360,7 +2381,8 @@ fn booleanOp( | ... | @@ -2360,7 +2381,8 @@ fn booleanOp( |
| 2360 | rhs_ty: Type, | 2381 | rhs_ty: Type, |
| 2361 | maybe_inst: ?Air.Inst.Index, | 2382 | maybe_inst: ?Air.Inst.Index, |
| 2362 | ) InnerError!MCValue { | 2383 | ) InnerError!MCValue { |
| 2363 | const mod = self.bin_file.comp.module.?; | 2384 | const pt = self.pt; |
| 2385 | const mod = pt.zcu; | ||
| 2364 | switch (lhs_ty.zigTypeTag(mod)) { | 2386 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2365 | .Bool => { | 2387 | .Bool => { |
| 2366 | assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema | 2388 | assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema |
| ... | @@ -2387,7 +2409,8 @@ fn ptrArithmetic( | ... | @@ -2387,7 +2409,8 @@ fn ptrArithmetic( |
| 2387 | rhs_ty: Type, | 2409 | rhs_ty: Type, |
| 2388 | maybe_inst: ?Air.Inst.Index, | 2410 | maybe_inst: ?Air.Inst.Index, |
| 2389 | ) InnerError!MCValue { | 2411 | ) InnerError!MCValue { |
| 2390 | const mod = self.bin_file.comp.module.?; | 2412 | const pt = self.pt; |
| 2413 | const mod = pt.zcu; | ||
| 2391 | switch (lhs_ty.zigTypeTag(mod)) { | 2414 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2392 | .Pointer => { | 2415 | .Pointer => { |
| 2393 | assert(rhs_ty.eql(Type.usize, mod)); | 2416 | assert(rhs_ty.eql(Type.usize, mod)); |
| ... | @@ -2397,7 +2420,7 @@ fn ptrArithmetic( | ... | @@ -2397,7 +2420,7 @@ fn ptrArithmetic( |
| 2397 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | 2420 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type |
| 2398 | else => ptr_ty.childType(mod), | 2421 | else => ptr_ty.childType(mod), |
| 2399 | }; | 2422 | }; |
| 2400 | const elem_size = elem_ty.abiSize(mod); | 2423 | const elem_size = elem_ty.abiSize(pt); |
| 2401 | 2424 | ||
| 2402 | const base_tag: Air.Inst.Tag = switch (tag) { | 2425 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 2403 | .ptr_add => .add, | 2426 | .ptr_add => .add, |
| ... | @@ -2510,7 +2533,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2510,7 +2533,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2510 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 2533 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 2511 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2534 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2512 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2535 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2513 | const mod = self.bin_file.comp.module.?; | 2536 | const pt = self.pt; |
| 2537 | const mod = pt.zcu; | ||
| 2514 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2538 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2515 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; | 2539 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2516 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; | 2540 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | @@ -2518,9 +2542,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2518,9 +2542,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2518 | const rhs_ty = self.typeOf(extra.rhs); | 2542 | const rhs_ty = self.typeOf(extra.rhs); |
| 2519 | 2543 | ||
| 2520 | const tuple_ty = self.typeOfIndex(inst); | 2544 | const tuple_ty = self.typeOfIndex(inst); |
| 2521 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod))); | 2545 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); |
| 2522 | const tuple_align = tuple_ty.abiAlignment(mod); | 2546 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 2523 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod))); | 2547 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); |
| 2524 | 2548 | ||
| 2525 | switch (lhs_ty.zigTypeTag(mod)) { | 2549 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2526 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), | 2550 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), |
| ... | @@ -2638,7 +2662,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2638,7 +2662,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2638 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2662 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2639 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2663 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2640 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); | 2664 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 2641 | const mod = self.bin_file.comp.module.?; | 2665 | const pt = self.pt; |
| 2666 | const mod = pt.zcu; | ||
| 2642 | const result: MCValue = result: { | 2667 | const result: MCValue = result: { |
| 2643 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; | 2668 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2644 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; | 2669 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | @@ -2646,9 +2671,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2646,9 +2671,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2646 | const rhs_ty = self.typeOf(extra.rhs); | 2671 | const rhs_ty = self.typeOf(extra.rhs); |
| 2647 | 2672 | ||
| 2648 | const tuple_ty = self.typeOfIndex(inst); | 2673 | const tuple_ty = self.typeOfIndex(inst); |
| 2649 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod))); | 2674 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); |
| 2650 | const tuple_align = tuple_ty.abiAlignment(mod); | 2675 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 2651 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod))); | 2676 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); |
| 2652 | 2677 | ||
| 2653 | switch (lhs_ty.zigTypeTag(mod)) { | 2678 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2654 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), | 2679 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), |
| ... | @@ -2862,7 +2887,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2862,7 +2887,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2862 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2887 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2863 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2888 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2864 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); | 2889 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 2865 | const mod = self.bin_file.comp.module.?; | 2890 | const pt = self.pt; |
| 2891 | const mod = pt.zcu; | ||
| 2866 | const result: MCValue = result: { | 2892 | const result: MCValue = result: { |
| 2867 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; | 2893 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2868 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; | 2894 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | @@ -2870,9 +2896,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2870,9 +2896,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2870 | const rhs_ty = self.typeOf(extra.rhs); | 2896 | const rhs_ty = self.typeOf(extra.rhs); |
| 2871 | 2897 | ||
| 2872 | const tuple_ty = self.typeOfIndex(inst); | 2898 | const tuple_ty = self.typeOfIndex(inst); |
| 2873 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(mod))); | 2899 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); |
| 2874 | const tuple_align = tuple_ty.abiAlignment(mod); | 2900 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 2875 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, mod))); | 2901 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); |
| 2876 | 2902 | ||
| 2877 | switch (lhs_ty.zigTypeTag(mod)) { | 2903 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2878 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), | 2904 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), |
| ... | @@ -3010,9 +3036,10 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3010,9 +3036,10 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3010 | } | 3036 | } |
| 3011 | 3037 | ||
| 3012 | fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue { | 3038 | fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue { |
| 3013 | const mod = self.bin_file.comp.module.?; | 3039 | const pt = self.pt; |
| 3040 | const mod = pt.zcu; | ||
| 3014 | const payload_ty = optional_ty.optionalChild(mod); | 3041 | const payload_ty = optional_ty.optionalChild(mod); |
| 3015 | if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none; | 3042 | if (!payload_ty.hasRuntimeBits(pt)) return MCValue.none; |
| 3016 | if (optional_ty.isPtrLikeOptional(mod)) { | 3043 | if (optional_ty.isPtrLikeOptional(mod)) { |
| 3017 | // TODO should we reuse the operand here? | 3044 | // TODO should we reuse the operand here? |
| 3018 | const raw_reg = try self.register_manager.allocReg(inst, gp); | 3045 | const raw_reg = try self.register_manager.allocReg(inst, gp); |
| ... | @@ -3054,17 +3081,18 @@ fn errUnionErr( | ... | @@ -3054,17 +3081,18 @@ fn errUnionErr( |
| 3054 | error_union_ty: Type, | 3081 | error_union_ty: Type, |
| 3055 | maybe_inst: ?Air.Inst.Index, | 3082 | maybe_inst: ?Air.Inst.Index, |
| 3056 | ) !MCValue { | 3083 | ) !MCValue { |
| 3057 | const mod = self.bin_file.comp.module.?; | 3084 | const pt = self.pt; |
| 3085 | const mod = pt.zcu; | ||
| 3058 | const err_ty = error_union_ty.errorUnionSet(mod); | 3086 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3059 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 3087 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3060 | if (err_ty.errorSetIsEmpty(mod)) { | 3088 | if (err_ty.errorSetIsEmpty(mod)) { |
| 3061 | return MCValue{ .immediate = 0 }; | 3089 | return MCValue{ .immediate = 0 }; |
| 3062 | } | 3090 | } |
| 3063 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3091 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3064 | return try error_union_bind.resolveToMcv(self); | 3092 | return try error_union_bind.resolveToMcv(self); |
| 3065 | } | 3093 | } |
| 3066 | 3094 | ||
| 3067 | const err_offset = @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod))); | 3095 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); |
| 3068 | switch (try error_union_bind.resolveToMcv(self)) { | 3096 | switch (try error_union_bind.resolveToMcv(self)) { |
| 3069 | .register => { | 3097 | .register => { |
| 3070 | var operand_reg: Register = undefined; | 3098 | var operand_reg: Register = undefined; |
| ... | @@ -3086,7 +3114,7 @@ fn errUnionErr( | ... | @@ -3086,7 +3114,7 @@ fn errUnionErr( |
| 3086 | ); | 3114 | ); |
| 3087 | 3115 | ||
| 3088 | const err_bit_offset = err_offset * 8; | 3116 | const err_bit_offset = err_offset * 8; |
| 3089 | const err_bit_size = @as(u32, @intCast(err_ty.abiSize(mod))) * 8; | 3117 | const err_bit_size = @as(u32, @intCast(err_ty.abiSize(pt))) * 8; |
| 3090 | 3118 | ||
| 3091 | _ = try self.addInst(.{ | 3119 | _ = try self.addInst(.{ |
| 3092 | .tag = .ubfx, // errors are unsigned integers | 3120 | .tag = .ubfx, // errors are unsigned integers |
| ... | @@ -3134,17 +3162,18 @@ fn errUnionPayload( | ... | @@ -3134,17 +3162,18 @@ fn errUnionPayload( |
| 3134 | error_union_ty: Type, | 3162 | error_union_ty: Type, |
| 3135 | maybe_inst: ?Air.Inst.Index, | 3163 | maybe_inst: ?Air.Inst.Index, |
| 3136 | ) !MCValue { | 3164 | ) !MCValue { |
| 3137 | const mod = self.bin_file.comp.module.?; | 3165 | const pt = self.pt; |
| 3166 | const mod = pt.zcu; | ||
| 3138 | const err_ty = error_union_ty.errorUnionSet(mod); | 3167 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3139 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 3168 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3140 | if (err_ty.errorSetIsEmpty(mod)) { | 3169 | if (err_ty.errorSetIsEmpty(mod)) { |
| 3141 | return try error_union_bind.resolveToMcv(self); | 3170 | return try error_union_bind.resolveToMcv(self); |
| 3142 | } | 3171 | } |
| 3143 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3172 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3144 | return MCValue.none; | 3173 | return MCValue.none; |
| 3145 | } | 3174 | } |
| 3146 | 3175 | ||
| 3147 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod))); | 3176 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); |
| 3148 | switch (try error_union_bind.resolveToMcv(self)) { | 3177 | switch (try error_union_bind.resolveToMcv(self)) { |
| 3149 | .register => { | 3178 | .register => { |
| 3150 | var operand_reg: Register = undefined; | 3179 | var operand_reg: Register = undefined; |
| ... | @@ -3166,7 +3195,7 @@ fn errUnionPayload( | ... | @@ -3166,7 +3195,7 @@ fn errUnionPayload( |
| 3166 | ); | 3195 | ); |
| 3167 | 3196 | ||
| 3168 | const payload_bit_offset = payload_offset * 8; | 3197 | const payload_bit_offset = payload_offset * 8; |
| 3169 | const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(mod))) * 8; | 3198 | const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(pt))) * 8; |
| 3170 | 3199 | ||
| 3171 | _ = try self.addInst(.{ | 3200 | _ = try self.addInst(.{ |
| 3172 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | 3201 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, |
| ... | @@ -3246,7 +3275,8 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3246,7 +3275,8 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 3246 | } | 3275 | } |
| 3247 | 3276 | ||
| 3248 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | 3277 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3249 | const mod = self.bin_file.comp.module.?; | 3278 | const pt = self.pt; |
| 3279 | const mod = pt.zcu; | ||
| 3250 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3280 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3251 | 3281 | ||
| 3252 | if (self.liveness.isUnused(inst)) { | 3282 | if (self.liveness.isUnused(inst)) { |
| ... | @@ -3255,7 +3285,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3255,7 +3285,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3255 | 3285 | ||
| 3256 | const result: MCValue = result: { | 3286 | const result: MCValue = result: { |
| 3257 | const payload_ty = self.typeOf(ty_op.operand); | 3287 | const payload_ty = self.typeOf(ty_op.operand); |
| 3258 | if (!payload_ty.hasRuntimeBits(mod)) { | 3288 | if (!payload_ty.hasRuntimeBits(pt)) { |
| 3259 | break :result MCValue{ .immediate = 1 }; | 3289 | break :result MCValue{ .immediate = 1 }; |
| 3260 | } | 3290 | } |
| 3261 | 3291 | ||
| ... | @@ -3275,9 +3305,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3275,9 +3305,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3275 | break :result MCValue{ .register = reg }; | 3305 | break :result MCValue{ .register = reg }; |
| 3276 | } | 3306 | } |
| 3277 | 3307 | ||
| 3278 | const optional_abi_size: u32 = @intCast(optional_ty.abiSize(mod)); | 3308 | const optional_abi_size: u32 = @intCast(optional_ty.abiSize(pt)); |
| 3279 | const optional_abi_align = optional_ty.abiAlignment(mod); | 3309 | const optional_abi_align = optional_ty.abiAlignment(pt); |
| 3280 | const offset: u32 = @intCast(payload_ty.abiSize(mod)); | 3310 | const offset: u32 = @intCast(payload_ty.abiSize(pt)); |
| 3281 | 3311 | ||
| 3282 | const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst); | 3312 | const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst); |
| 3283 | try self.genSetStack(payload_ty, stack_offset, operand); | 3313 | try self.genSetStack(payload_ty, stack_offset, operand); |
| ... | @@ -3291,20 +3321,21 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3291,20 +3321,21 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3291 | 3321 | ||
| 3292 | /// T to E!T | 3322 | /// T to E!T |
| 3293 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | 3323 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3294 | const mod = self.bin_file.comp.module.?; | 3324 | const pt = self.pt; |
| 3325 | const mod = pt.zcu; | ||
| 3295 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3326 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3296 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 3327 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3297 | const error_union_ty = ty_op.ty.toType(); | 3328 | const error_union_ty = ty_op.ty.toType(); |
| 3298 | const error_ty = error_union_ty.errorUnionSet(mod); | 3329 | const error_ty = error_union_ty.errorUnionSet(mod); |
| 3299 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 3330 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3300 | const operand = try self.resolveInst(ty_op.operand); | 3331 | const operand = try self.resolveInst(ty_op.operand); |
| 3301 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand; | 3332 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; |
| 3302 | 3333 | ||
| 3303 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(mod))); | 3334 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); |
| 3304 | const abi_align = error_union_ty.abiAlignment(mod); | 3335 | const abi_align = error_union_ty.abiAlignment(pt); |
| 3305 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | 3336 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3306 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | 3337 | const payload_off = errUnionPayloadOffset(payload_ty, pt); |
| 3307 | const err_off = errUnionErrorOffset(payload_ty, mod); | 3338 | const err_off = errUnionErrorOffset(payload_ty, pt); |
| 3308 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); | 3339 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); |
| 3309 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); | 3340 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); |
| 3310 | 3341 | ||
| ... | @@ -3317,18 +3348,19 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3317,18 +3348,19 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3317 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 3348 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3318 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3349 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3319 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 3350 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3320 | const mod = self.bin_file.comp.module.?; | 3351 | const pt = self.pt; |
| 3352 | const mod = pt.zcu; | ||
| 3321 | const error_union_ty = ty_op.ty.toType(); | 3353 | const error_union_ty = ty_op.ty.toType(); |
| 3322 | const error_ty = error_union_ty.errorUnionSet(mod); | 3354 | const error_ty = error_union_ty.errorUnionSet(mod); |
| 3323 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 3355 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3324 | const operand = try self.resolveInst(ty_op.operand); | 3356 | const operand = try self.resolveInst(ty_op.operand); |
| 3325 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand; | 3357 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; |
| 3326 | 3358 | ||
| 3327 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(mod))); | 3359 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); |
| 3328 | const abi_align = error_union_ty.abiAlignment(mod); | 3360 | const abi_align = error_union_ty.abiAlignment(pt); |
| 3329 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | 3361 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3330 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | 3362 | const payload_off = errUnionPayloadOffset(payload_ty, pt); |
| 3331 | const err_off = errUnionErrorOffset(payload_ty, mod); | 3363 | const err_off = errUnionErrorOffset(payload_ty, pt); |
| 3332 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); | 3364 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); |
| 3333 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); | 3365 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); |
| 3334 | 3366 | ||
| ... | @@ -3420,7 +3452,8 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3420,7 +3452,8 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3420 | } | 3452 | } |
| 3421 | 3453 | ||
| 3422 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | 3454 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3423 | const mod = self.bin_file.comp.module.?; | 3455 | const pt = self.pt; |
| 3456 | const mod = pt.zcu; | ||
| 3424 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3457 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3425 | const slice_ty = self.typeOf(bin_op.lhs); | 3458 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3426 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 3459 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | @@ -3444,9 +3477,10 @@ fn ptrElemVal( | ... | @@ -3444,9 +3477,10 @@ fn ptrElemVal( |
| 3444 | ptr_ty: Type, | 3477 | ptr_ty: Type, |
| 3445 | maybe_inst: ?Air.Inst.Index, | 3478 | maybe_inst: ?Air.Inst.Index, |
| 3446 | ) !MCValue { | 3479 | ) !MCValue { |
| 3447 | const mod = self.bin_file.comp.module.?; | 3480 | const pt = self.pt; |
| 3481 | const mod = pt.zcu; | ||
| 3448 | const elem_ty = ptr_ty.childType(mod); | 3482 | const elem_ty = ptr_ty.childType(mod); |
| 3449 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod))); | 3483 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt))); |
| 3450 | 3484 | ||
| 3451 | // TODO optimize for elem_sizes of 1, 2, 4, 8 | 3485 | // TODO optimize for elem_sizes of 1, 2, 4, 8 |
| 3452 | switch (elem_size) { | 3486 | switch (elem_size) { |
| ... | @@ -3486,7 +3520,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3486,7 +3520,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3486 | } | 3520 | } |
| 3487 | 3521 | ||
| 3488 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | 3522 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3489 | const mod = self.bin_file.comp.module.?; | 3523 | const pt = self.pt; |
| 3524 | const mod = pt.zcu; | ||
| 3490 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3525 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3491 | const ptr_ty = self.typeOf(bin_op.lhs); | 3526 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3492 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 3527 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | @@ -3609,9 +3644,10 @@ fn reuseOperand( | ... | @@ -3609,9 +3644,10 @@ fn reuseOperand( |
| 3609 | } | 3644 | } |
| 3610 | 3645 | ||
| 3611 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { | 3646 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 3612 | const mod = self.bin_file.comp.module.?; | 3647 | const pt = self.pt; |
| 3648 | const mod = pt.zcu; | ||
| 3613 | const elem_ty = ptr_ty.childType(mod); | 3649 | const elem_ty = ptr_ty.childType(mod); |
| 3614 | const elem_size = elem_ty.abiSize(mod); | 3650 | const elem_size = elem_ty.abiSize(pt); |
| 3615 | 3651 | ||
| 3616 | switch (ptr) { | 3652 | switch (ptr) { |
| 3617 | .none => unreachable, | 3653 | .none => unreachable, |
| ... | @@ -3857,12 +3893,13 @@ fn genInlineMemsetCode( | ... | @@ -3857,12 +3893,13 @@ fn genInlineMemsetCode( |
| 3857 | } | 3893 | } |
| 3858 | 3894 | ||
| 3859 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | 3895 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3860 | const mod = self.bin_file.comp.module.?; | 3896 | const pt = self.pt; |
| 3897 | const mod = pt.zcu; | ||
| 3861 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3898 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3862 | const elem_ty = self.typeOfIndex(inst); | 3899 | const elem_ty = self.typeOfIndex(inst); |
| 3863 | const elem_size = elem_ty.abiSize(mod); | 3900 | const elem_size = elem_ty.abiSize(pt); |
| 3864 | const result: MCValue = result: { | 3901 | const result: MCValue = result: { |
| 3865 | if (!elem_ty.hasRuntimeBits(mod)) | 3902 | if (!elem_ty.hasRuntimeBits(pt)) |
| 3866 | break :result MCValue.none; | 3903 | break :result MCValue.none; |
| 3867 | 3904 | ||
| 3868 | const ptr = try self.resolveInst(ty_op.operand); | 3905 | const ptr = try self.resolveInst(ty_op.operand); |
| ... | @@ -3888,8 +3925,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3888,8 +3925,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3888 | } | 3925 | } |
| 3889 | 3926 | ||
| 3890 | fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { | 3927 | fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3891 | const mod = self.bin_file.comp.module.?; | 3928 | const pt = self.pt; |
| 3892 | const abi_size = ty.abiSize(mod); | 3929 | const mod = pt.zcu; |
| 3930 | const abi_size = ty.abiSize(pt); | ||
| 3893 | 3931 | ||
| 3894 | const tag: Mir.Inst.Tag = switch (abi_size) { | 3932 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3895 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate, | 3933 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate, |
| ... | @@ -3911,8 +3949,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type | ... | @@ -3911,8 +3949,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3911 | } | 3949 | } |
| 3912 | 3950 | ||
| 3913 | fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { | 3951 | fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3914 | const mod = self.bin_file.comp.module.?; | 3952 | const pt = self.pt; |
| 3915 | const abi_size = ty.abiSize(mod); | 3953 | const abi_size = ty.abiSize(pt); |
| 3916 | 3954 | ||
| 3917 | const tag: Mir.Inst.Tag = switch (abi_size) { | 3955 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3918 | 1 => .strb_immediate, | 3956 | 1 => .strb_immediate, |
| ... | @@ -3933,9 +3971,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type | ... | @@ -3933,9 +3971,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3933 | } | 3971 | } |
| 3934 | 3972 | ||
| 3935 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 3973 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 3936 | const mod = self.bin_file.comp.module.?; | 3974 | const pt = self.pt; |
| 3937 | log.debug("store: storing {} to {}", .{ value, ptr }); | 3975 | log.debug("store: storing {} to {}", .{ value, ptr }); |
| 3938 | const abi_size = value_ty.abiSize(mod); | 3976 | const abi_size = value_ty.abiSize(pt); |
| 3939 | 3977 | ||
| 3940 | switch (ptr) { | 3978 | switch (ptr) { |
| 3941 | .none => unreachable, | 3979 | .none => unreachable, |
| ... | @@ -4087,11 +4125,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -4087,11 +4125,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 4087 | 4125 | ||
| 4088 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 4126 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4089 | return if (self.liveness.isUnused(inst)) .dead else result: { | 4127 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 4090 | const mod = self.bin_file.comp.module.?; | 4128 | const pt = self.pt; |
| 4129 | const mod = pt.zcu; | ||
| 4091 | const mcv = try self.resolveInst(operand); | 4130 | const mcv = try self.resolveInst(operand); |
| 4092 | const ptr_ty = self.typeOf(operand); | 4131 | const ptr_ty = self.typeOf(operand); |
| 4093 | const struct_ty = ptr_ty.childType(mod); | 4132 | const struct_ty = ptr_ty.childType(mod); |
| 4094 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod))); | 4133 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); |
| 4095 | switch (mcv) { | 4134 | switch (mcv) { |
| 4096 | .ptr_stack_offset => |off| { | 4135 | .ptr_stack_offset => |off| { |
| 4097 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; | 4136 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| ... | @@ -4112,11 +4151,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4112,11 +4151,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4112 | const operand = extra.struct_operand; | 4151 | const operand = extra.struct_operand; |
| 4113 | const index = extra.field_index; | 4152 | const index = extra.field_index; |
| 4114 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4153 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4115 | const mod = self.bin_file.comp.module.?; | 4154 | const pt = self.pt; |
| 4155 | const mod = pt.zcu; | ||
| 4116 | const mcv = try self.resolveInst(operand); | 4156 | const mcv = try self.resolveInst(operand); |
| 4117 | const struct_ty = self.typeOf(operand); | 4157 | const struct_ty = self.typeOf(operand); |
| 4118 | const struct_field_ty = struct_ty.structFieldType(index, mod); | 4158 | const struct_field_ty = struct_ty.structFieldType(index, mod); |
| 4119 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod))); | 4159 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); |
| 4120 | 4160 | ||
| 4121 | switch (mcv) { | 4161 | switch (mcv) { |
| 4122 | .dead, .unreach => unreachable, | 4162 | .dead, .unreach => unreachable, |
| ... | @@ -4162,13 +4202,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4162,13 +4202,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4162 | } | 4202 | } |
| 4163 | 4203 | ||
| 4164 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | 4204 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4165 | const mod = self.bin_file.comp.module.?; | 4205 | const pt = self.pt; |
| 4206 | const mod = pt.zcu; | ||
| 4166 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4207 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4167 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 4208 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 4168 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4209 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4169 | const field_ptr = try self.resolveInst(extra.field_ptr); | 4210 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 4170 | const struct_ty = ty_pl.ty.toType().childType(mod); | 4211 | const struct_ty = ty_pl.ty.toType().childType(mod); |
| 4171 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, mod))); | 4212 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, pt))); |
| 4172 | switch (field_ptr) { | 4213 | switch (field_ptr) { |
| 4173 | .ptr_stack_offset => |off| { | 4214 | .ptr_stack_offset => |off| { |
| 4174 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; | 4215 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; |
| ... | @@ -4190,7 +4231,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4190,7 +4231,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4190 | while (self.args[arg_index] == .none) arg_index += 1; | 4231 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4191 | self.arg_index = arg_index + 1; | 4232 | self.arg_index = arg_index + 1; |
| 4192 | 4233 | ||
| 4193 | const mod = self.bin_file.comp.module.?; | 4234 | const pt = self.pt; |
| 4235 | const mod = pt.zcu; | ||
| 4194 | const ty = self.typeOfIndex(inst); | 4236 | const ty = self.typeOfIndex(inst); |
| 4195 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4237 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4196 | const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; | 4238 | const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; |
| ... | @@ -4245,7 +4287,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4245,7 +4287,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4245 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 4287 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 4246 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); | 4288 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); |
| 4247 | const ty = self.typeOf(callee); | 4289 | const ty = self.typeOf(callee); |
| 4248 | const mod = self.bin_file.comp.module.?; | 4290 | const pt = self.pt; |
| 4291 | const mod = pt.zcu; | ||
| 4249 | 4292 | ||
| 4250 | const fn_ty = switch (ty.zigTypeTag(mod)) { | 4293 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 4251 | .Fn => ty, | 4294 | .Fn => ty, |
| ... | @@ -4269,13 +4312,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4269,13 +4312,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4269 | if (info.return_value == .stack_offset) { | 4312 | if (info.return_value == .stack_offset) { |
| 4270 | log.debug("airCall: return by reference", .{}); | 4313 | log.debug("airCall: return by reference", .{}); |
| 4271 | const ret_ty = fn_ty.fnReturnType(mod); | 4314 | const ret_ty = fn_ty.fnReturnType(mod); |
| 4272 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(mod)); | 4315 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 4273 | const ret_abi_align = ret_ty.abiAlignment(mod); | 4316 | const ret_abi_align = ret_ty.abiAlignment(pt); |
| 4274 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); | 4317 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); |
| 4275 | 4318 | ||
| 4276 | const ret_ptr_reg = self.registerAlias(.x0, Type.usize); | 4319 | const ret_ptr_reg = self.registerAlias(.x0, Type.usize); |
| 4277 | 4320 | ||
| 4278 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 4321 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 4279 | try self.register_manager.getReg(ret_ptr_reg, null); | 4322 | try self.register_manager.getReg(ret_ptr_reg, null); |
| 4280 | try self.genSetReg(ptr_ty, ret_ptr_reg, .{ .ptr_stack_offset = stack_offset }); | 4323 | try self.genSetReg(ptr_ty, ret_ptr_reg, .{ .ptr_stack_offset = stack_offset }); |
| 4281 | 4324 | ||
| ... | @@ -4308,7 +4351,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4308,7 +4351,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4308 | 4351 | ||
| 4309 | // Due to incremental compilation, how function calls are generated depends | 4352 | // Due to incremental compilation, how function calls are generated depends |
| 4310 | // on linking. | 4353 | // on linking. |
| 4311 | if (try self.air.value(callee, mod)) |func_value| { | 4354 | if (try self.air.value(callee, pt)) |func_value| { |
| 4312 | if (func_value.getFunction(mod)) |func| { | 4355 | if (func_value.getFunction(mod)) |func| { |
| 4313 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 4356 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 4314 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); | 4357 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); |
| ... | @@ -4421,7 +4464,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4421,7 +4464,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4421 | } | 4464 | } |
| 4422 | 4465 | ||
| 4423 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { | 4466 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4424 | const mod = self.bin_file.comp.module.?; | 4467 | const pt = self.pt; |
| 4468 | const mod = pt.zcu; | ||
| 4425 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4469 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4426 | const operand = try self.resolveInst(un_op); | 4470 | const operand = try self.resolveInst(un_op); |
| 4427 | const ret_ty = self.fn_type.fnReturnType(mod); | 4471 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | @@ -4440,7 +4484,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4440,7 +4484,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4440 | // | 4484 | // |
| 4441 | // self.ret_mcv is an address to where this function | 4485 | // self.ret_mcv is an address to where this function |
| 4442 | // should store its result into | 4486 | // should store its result into |
| 4443 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 4487 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 4444 | try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); | 4488 | try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); |
| 4445 | }, | 4489 | }, |
| 4446 | else => unreachable, | 4490 | else => unreachable, |
| ... | @@ -4453,7 +4497,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4453,7 +4497,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4453 | } | 4497 | } |
| 4454 | 4498 | ||
| 4455 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | 4499 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4456 | const mod = self.bin_file.comp.module.?; | 4500 | const pt = self.pt; |
| 4501 | const mod = pt.zcu; | ||
| 4457 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4502 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4458 | const ptr = try self.resolveInst(un_op); | 4503 | const ptr = try self.resolveInst(un_op); |
| 4459 | const ptr_ty = self.typeOf(un_op); | 4504 | const ptr_ty = self.typeOf(un_op); |
| ... | @@ -4477,8 +4522,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4477,8 +4522,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4477 | // location. | 4522 | // location. |
| 4478 | const op_inst = un_op.toIndex().?; | 4523 | const op_inst = un_op.toIndex().?; |
| 4479 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { | 4524 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { |
| 4480 | const abi_size = @as(u32, @intCast(ret_ty.abiSize(mod))); | 4525 | const abi_size = @as(u32, @intCast(ret_ty.abiSize(pt))); |
| 4481 | const abi_align = ret_ty.abiAlignment(mod); | 4526 | const abi_align = ret_ty.abiAlignment(pt); |
| 4482 | 4527 | ||
| 4483 | const offset = try self.allocMem(abi_size, abi_align, null); | 4528 | const offset = try self.allocMem(abi_size, abi_align, null); |
| 4484 | 4529 | ||
| ... | @@ -4513,11 +4558,12 @@ fn cmp( | ... | @@ -4513,11 +4558,12 @@ fn cmp( |
| 4513 | lhs_ty: Type, | 4558 | lhs_ty: Type, |
| 4514 | op: math.CompareOperator, | 4559 | op: math.CompareOperator, |
| 4515 | ) !MCValue { | 4560 | ) !MCValue { |
| 4516 | const mod = self.bin_file.comp.module.?; | 4561 | const pt = self.pt; |
| 4562 | const mod = pt.zcu; | ||
| 4517 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { | 4563 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { |
| 4518 | .Optional => blk: { | 4564 | .Optional => blk: { |
| 4519 | const payload_ty = lhs_ty.optionalChild(mod); | 4565 | const payload_ty = lhs_ty.optionalChild(mod); |
| 4520 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4566 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4521 | break :blk Type.u1; | 4567 | break :blk Type.u1; |
| 4522 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | 4568 | } else if (lhs_ty.isPtrLikeOptional(mod)) { |
| 4523 | break :blk Type.usize; | 4569 | break :blk Type.usize; |
| ... | @@ -4620,7 +4666,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4620,7 +4666,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4620 | } | 4666 | } |
| 4621 | 4667 | ||
| 4622 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | 4668 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4623 | const mod = self.bin_file.comp.module.?; | 4669 | const pt = self.pt; |
| 4670 | const mod = pt.zcu; | ||
| 4624 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4671 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4625 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 4672 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4626 | const func = mod.funcInfo(extra.data.func); | 4673 | const func = mod.funcInfo(extra.data.func); |
| ... | @@ -4825,13 +4872,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4825,13 +4872,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4825 | } | 4872 | } |
| 4826 | 4873 | ||
| 4827 | fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { | 4874 | fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { |
| 4828 | const mod = self.bin_file.comp.module.?; | 4875 | const pt = self.pt; |
| 4876 | const mod = pt.zcu; | ||
| 4829 | const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: { | 4877 | const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: { |
| 4830 | const payload_ty = operand_ty.optionalChild(mod); | 4878 | const payload_ty = operand_ty.optionalChild(mod); |
| 4831 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 4879 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 4832 | break :blk .{ .ty = operand_ty, .bind = operand_bind }; | 4880 | break :blk .{ .ty = operand_ty, .bind = operand_bind }; |
| 4833 | 4881 | ||
| 4834 | const offset = @as(u32, @intCast(payload_ty.abiSize(mod))); | 4882 | const offset = @as(u32, @intCast(payload_ty.abiSize(pt))); |
| 4835 | const operand_mcv = try operand_bind.resolveToMcv(self); | 4883 | const operand_mcv = try operand_bind.resolveToMcv(self); |
| 4836 | const new_mcv: MCValue = switch (operand_mcv) { | 4884 | const new_mcv: MCValue = switch (operand_mcv) { |
| 4837 | .register => |source_reg| new: { | 4885 | .register => |source_reg| new: { |
| ... | @@ -4881,7 +4929,8 @@ fn isErr( | ... | @@ -4881,7 +4929,8 @@ fn isErr( |
| 4881 | error_union_bind: ReadArg.Bind, | 4929 | error_union_bind: ReadArg.Bind, |
| 4882 | error_union_ty: Type, | 4930 | error_union_ty: Type, |
| 4883 | ) !MCValue { | 4931 | ) !MCValue { |
| 4884 | const mod = self.bin_file.comp.module.?; | 4932 | const pt = self.pt; |
| 4933 | const mod = pt.zcu; | ||
| 4885 | const error_type = error_union_ty.errorUnionSet(mod); | 4934 | const error_type = error_union_ty.errorUnionSet(mod); |
| 4886 | 4935 | ||
| 4887 | if (error_type.errorSetIsEmpty(mod)) { | 4936 | if (error_type.errorSetIsEmpty(mod)) { |
| ... | @@ -4923,7 +4972,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4923,7 +4972,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4923 | } | 4972 | } |
| 4924 | 4973 | ||
| 4925 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { | 4974 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4926 | const mod = self.bin_file.comp.module.?; | 4975 | const pt = self.pt; |
| 4976 | const mod = pt.zcu; | ||
| 4927 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4977 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4928 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4978 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4929 | const operand_ptr = try self.resolveInst(un_op); | 4979 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -4950,7 +5000,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4950,7 +5000,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4950 | } | 5000 | } |
| 4951 | 5001 | ||
| 4952 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { | 5002 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4953 | const mod = self.bin_file.comp.module.?; | 5003 | const pt = self.pt; |
| 5004 | const mod = pt.zcu; | ||
| 4954 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5005 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4955 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 5006 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4956 | const operand_ptr = try self.resolveInst(un_op); | 5007 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -4977,7 +5028,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4977,7 +5028,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4977 | } | 5028 | } |
| 4978 | 5029 | ||
| 4979 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 5030 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4980 | const mod = self.bin_file.comp.module.?; | 5031 | const pt = self.pt; |
| 5032 | const mod = pt.zcu; | ||
| 4981 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5033 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4982 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 5034 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4983 | const operand_ptr = try self.resolveInst(un_op); | 5035 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -5004,7 +5056,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5004,7 +5056,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5004 | } | 5056 | } |
| 5005 | 5057 | ||
| 5006 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 5058 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5007 | const mod = self.bin_file.comp.module.?; | 5059 | const pt = self.pt; |
| 5060 | const mod = pt.zcu; | ||
| 5008 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5061 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5009 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 5062 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5010 | const operand_ptr = try self.resolveInst(un_op); | 5063 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -5225,10 +5278,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5225,10 +5278,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5225 | } | 5278 | } |
| 5226 | 5279 | ||
| 5227 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { | 5280 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 5228 | const mod = self.bin_file.comp.module.?; | 5281 | const pt = self.pt; |
| 5229 | const block_data = self.blocks.getPtr(block).?; | 5282 | const block_data = self.blocks.getPtr(block).?; |
| 5230 | 5283 | ||
| 5231 | if (self.typeOf(operand).hasRuntimeBits(mod)) { | 5284 | if (self.typeOf(operand).hasRuntimeBits(pt)) { |
| 5232 | const operand_mcv = try self.resolveInst(operand); | 5285 | const operand_mcv = try self.resolveInst(operand); |
| 5233 | const block_mcv = block_data.mcv; | 5286 | const block_mcv = block_data.mcv; |
| 5234 | if (block_mcv == .none) { | 5287 | if (block_mcv == .none) { |
| ... | @@ -5402,8 +5455,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { | ... | @@ -5402,8 +5455,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5402 | } | 5455 | } |
| 5403 | 5456 | ||
| 5404 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { | 5457 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5405 | const mod = self.bin_file.comp.module.?; | 5458 | const pt = self.pt; |
| 5406 | const abi_size = @as(u32, @intCast(ty.abiSize(mod))); | 5459 | const mod = pt.zcu; |
| 5460 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); | ||
| 5407 | switch (mcv) { | 5461 | switch (mcv) { |
| 5408 | .dead => unreachable, | 5462 | .dead => unreachable, |
| 5409 | .unreach, .none => return, // Nothing to do. | 5463 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -5462,7 +5516,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5462,7 +5516,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5462 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); | 5516 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); |
| 5463 | 5517 | ||
| 5464 | const overflow_bit_ty = ty.structFieldType(1, mod); | 5518 | const overflow_bit_ty = ty.structFieldType(1, mod); |
| 5465 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, mod))); | 5519 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt))); |
| 5466 | const raw_cond_reg = try self.register_manager.allocReg(null, gp); | 5520 | const raw_cond_reg = try self.register_manager.allocReg(null, gp); |
| 5467 | const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty); | 5521 | const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty); |
| 5468 | 5522 | ||
| ... | @@ -5495,7 +5549,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5495,7 +5549,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5495 | const reg = try self.copyToTmpRegister(ty, mcv); | 5549 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 5496 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 5550 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 5497 | } else { | 5551 | } else { |
| 5498 | const ptr_ty = try mod.singleMutPtrType(ty); | 5552 | const ptr_ty = try pt.singleMutPtrType(ty); |
| 5499 | 5553 | ||
| 5500 | // TODO call extern memcpy | 5554 | // TODO call extern memcpy |
| 5501 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); | 5555 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); |
| ... | @@ -5573,7 +5627,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5573,7 +5627,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5573 | } | 5627 | } |
| 5574 | 5628 | ||
| 5575 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 5629 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 5576 | const mod = self.bin_file.comp.module.?; | 5630 | const pt = self.pt; |
| 5631 | const mod = pt.zcu; | ||
| 5577 | switch (mcv) { | 5632 | switch (mcv) { |
| 5578 | .dead => unreachable, | 5633 | .dead => unreachable, |
| 5579 | .unreach, .none => return, // Nothing to do. | 5634 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -5685,7 +5740,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5685,7 +5740,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5685 | try self.genLdrRegister(reg, reg.toX(), ty); | 5740 | try self.genLdrRegister(reg, reg.toX(), ty); |
| 5686 | }, | 5741 | }, |
| 5687 | .stack_offset => |off| { | 5742 | .stack_offset => |off| { |
| 5688 | const abi_size = ty.abiSize(mod); | 5743 | const abi_size = ty.abiSize(pt); |
| 5689 | 5744 | ||
| 5690 | switch (abi_size) { | 5745 | switch (abi_size) { |
| 5691 | 1, 2, 4, 8 => { | 5746 | 1, 2, 4, 8 => { |
| ... | @@ -5709,7 +5764,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5709,7 +5764,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5709 | } | 5764 | } |
| 5710 | }, | 5765 | }, |
| 5711 | .stack_argument_offset => |off| { | 5766 | .stack_argument_offset => |off| { |
| 5712 | const abi_size = ty.abiSize(mod); | 5767 | const abi_size = ty.abiSize(pt); |
| 5713 | 5768 | ||
| 5714 | switch (abi_size) { | 5769 | switch (abi_size) { |
| 5715 | 1, 2, 4, 8 => { | 5770 | 1, 2, 4, 8 => { |
| ... | @@ -5736,8 +5791,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5736,8 +5791,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5736 | } | 5791 | } |
| 5737 | 5792 | ||
| 5738 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { | 5793 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5739 | const mod = self.bin_file.comp.module.?; | 5794 | const pt = self.pt; |
| 5740 | const abi_size = @as(u32, @intCast(ty.abiSize(mod))); | 5795 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); |
| 5741 | switch (mcv) { | 5796 | switch (mcv) { |
| 5742 | .dead => unreachable, | 5797 | .dead => unreachable, |
| 5743 | .none, .unreach => return, | 5798 | .none, .unreach => return, |
| ... | @@ -5745,7 +5800,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -5745,7 +5800,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 5745 | if (!self.wantSafety()) | 5800 | if (!self.wantSafety()) |
| 5746 | return; // The already existing value will do just fine. | 5801 | return; // The already existing value will do just fine. |
| 5747 | // TODO Upgrade this to a memset call when we have that available. | 5802 | // TODO Upgrade this to a memset call when we have that available. |
| 5748 | switch (ty.abiSize(mod)) { | 5803 | switch (ty.abiSize(pt)) { |
| 5749 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), | 5804 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), |
| 5750 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), | 5805 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 5751 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), | 5806 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| ... | @@ -5815,7 +5870,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -5815,7 +5870,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 5815 | const reg = try self.copyToTmpRegister(ty, mcv); | 5870 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 5816 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); | 5871 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); |
| 5817 | } else { | 5872 | } else { |
| 5818 | const ptr_ty = try mod.singleMutPtrType(ty); | 5873 | const ptr_ty = try pt.singleMutPtrType(ty); |
| 5819 | 5874 | ||
| 5820 | // TODO call extern memcpy | 5875 | // TODO call extern memcpy |
| 5821 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); | 5876 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); |
| ... | @@ -5936,7 +5991,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5936,7 +5991,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5936 | } | 5991 | } |
| 5937 | 5992 | ||
| 5938 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | 5993 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5939 | const mod = self.bin_file.comp.module.?; | 5994 | const pt = self.pt; |
| 5995 | const mod = pt.zcu; | ||
| 5940 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5996 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5941 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 5997 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5942 | const ptr_ty = self.typeOf(ty_op.operand); | 5998 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -6056,7 +6112,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6056,7 +6112,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6056 | } | 6112 | } |
| 6057 | 6113 | ||
| 6058 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 6114 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6059 | const mod = self.bin_file.comp.module.?; | 6115 | const pt = self.pt; |
| 6116 | const mod = pt.zcu; | ||
| 6060 | const vector_ty = self.typeOfIndex(inst); | 6117 | const vector_ty = self.typeOfIndex(inst); |
| 6061 | const len = vector_ty.vectorLen(mod); | 6118 | const len = vector_ty.vectorLen(mod); |
| 6062 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6119 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -6100,15 +6157,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6100,15 +6157,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 6100 | } | 6157 | } |
| 6101 | 6158 | ||
| 6102 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { | 6159 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 6103 | const mod = self.bin_file.comp.module.?; | 6160 | const pt = self.pt; |
| 6104 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6161 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6105 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 6162 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| 6106 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 6163 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 6107 | const result: MCValue = result: { | 6164 | const result: MCValue = result: { |
| 6108 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; | 6165 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; |
| 6109 | const error_union_ty = self.typeOf(pl_op.operand); | 6166 | const error_union_ty = self.typeOf(pl_op.operand); |
| 6110 | const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(mod))); | 6167 | const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); |
| 6111 | const error_union_align = error_union_ty.abiAlignment(mod); | 6168 | const error_union_align = error_union_ty.abiAlignment(pt); |
| 6112 | 6169 | ||
| 6113 | // The error union will die in the body. However, we need the | 6170 | // The error union will die in the body. However, we need the |
| 6114 | // error union after the body in order to extract the payload | 6171 | // error union after the body in order to extract the payload |
| ... | @@ -6137,14 +6194,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6137,14 +6194,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6137 | } | 6194 | } |
| 6138 | 6195 | ||
| 6139 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | 6196 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6140 | const mod = self.bin_file.comp.module.?; | 6197 | const pt = self.pt; |
| 6198 | const mod = pt.zcu; | ||
| 6141 | 6199 | ||
| 6142 | // If the type has no codegen bits, no need to store it. | 6200 | // If the type has no codegen bits, no need to store it. |
| 6143 | const inst_ty = self.typeOf(inst); | 6201 | const inst_ty = self.typeOf(inst); |
| 6144 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) | 6202 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod)) |
| 6145 | return MCValue{ .none = {} }; | 6203 | return MCValue{ .none = {} }; |
| 6146 | 6204 | ||
| 6147 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?); | 6205 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?); |
| 6148 | 6206 | ||
| 6149 | return self.getResolvedInstValue(inst_index); | 6207 | return self.getResolvedInstValue(inst_index); |
| 6150 | } | 6208 | } |
| ... | @@ -6164,6 +6222,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -6164,6 +6222,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 6164 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | 6222 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 6165 | const mcv: MCValue = switch (try codegen.genTypedValue( | 6223 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 6166 | self.bin_file, | 6224 | self.bin_file, |
| 6225 | self.pt, | ||
| 6167 | self.src_loc, | 6226 | self.src_loc, |
| 6168 | val, | 6227 | val, |
| 6169 | self.owner_decl, | 6228 | self.owner_decl, |
| ... | @@ -6199,7 +6258,8 @@ const CallMCValues = struct { | ... | @@ -6199,7 +6258,8 @@ const CallMCValues = struct { |
| 6199 | 6258 | ||
| 6200 | /// Caller must call `CallMCValues.deinit`. | 6259 | /// Caller must call `CallMCValues.deinit`. |
| 6201 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | 6260 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6202 | const mod = self.bin_file.comp.module.?; | 6261 | const pt = self.pt; |
| 6262 | const mod = pt.zcu; | ||
| 6203 | const ip = &mod.intern_pool; | 6263 | const ip = &mod.intern_pool; |
| 6204 | const fn_info = mod.typeToFunc(fn_ty).?; | 6264 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 6205 | const cc = fn_info.cc; | 6265 | const cc = fn_info.cc; |
| ... | @@ -6229,10 +6289,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6229,10 +6289,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6229 | 6289 | ||
| 6230 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 6290 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 6231 | result.return_value = .{ .unreach = {} }; | 6291 | result.return_value = .{ .unreach = {} }; |
| 6232 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) { | 6292 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { |
| 6233 | result.return_value = .{ .none = {} }; | 6293 | result.return_value = .{ .none = {} }; |
| 6234 | } else { | 6294 | } else { |
| 6235 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod))); | 6295 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 6236 | if (ret_ty_size == 0) { | 6296 | if (ret_ty_size == 0) { |
| 6237 | assert(ret_ty.isError(mod)); | 6297 | assert(ret_ty.isError(mod)); |
| 6238 | result.return_value = .{ .immediate = 0 }; | 6298 | result.return_value = .{ .immediate = 0 }; |
| ... | @@ -6244,7 +6304,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6244,7 +6304,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6244 | } | 6304 | } |
| 6245 | 6305 | ||
| 6246 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { | 6306 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6247 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(mod))); | 6307 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))); |
| 6248 | if (param_size == 0) { | 6308 | if (param_size == 0) { |
| 6249 | result_arg.* = .{ .none = {} }; | 6309 | result_arg.* = .{ .none = {} }; |
| 6250 | continue; | 6310 | continue; |
| ... | @@ -6252,7 +6312,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6252,7 +6312,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6252 | 6312 | ||
| 6253 | // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned | 6313 | // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned |
| 6254 | // values to spread across odd-numbered registers. | 6314 | // values to spread across odd-numbered registers. |
| 6255 | if (Type.fromInterned(ty).abiAlignment(mod) == .@"16" and !self.target.isDarwin()) { | 6315 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"16" and !self.target.isDarwin()) { |
| 6256 | // Round up NCRN to the next even number | 6316 | // Round up NCRN to the next even number |
| 6257 | ncrn += ncrn % 2; | 6317 | ncrn += ncrn % 2; |
| 6258 | } | 6318 | } |
| ... | @@ -6270,7 +6330,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6270,7 +6330,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6270 | ncrn = 8; | 6330 | ncrn = 8; |
| 6271 | // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided | 6331 | // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided |
| 6272 | // that the entire stack space consumed by the arguments is 8-byte aligned. | 6332 | // that the entire stack space consumed by the arguments is 8-byte aligned. |
| 6273 | if (Type.fromInterned(ty).abiAlignment(mod) == .@"8") { | 6333 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") { |
| 6274 | if (nsaa % 8 != 0) { | 6334 | if (nsaa % 8 != 0) { |
| 6275 | nsaa += 8 - (nsaa % 8); | 6335 | nsaa += 8 - (nsaa % 8); |
| 6276 | } | 6336 | } |
| ... | @@ -6287,10 +6347,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6287,10 +6347,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6287 | .Unspecified => { | 6347 | .Unspecified => { |
| 6288 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 6348 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 6289 | result.return_value = .{ .unreach = {} }; | 6349 | result.return_value = .{ .unreach = {} }; |
| 6290 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) { | 6350 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { |
| 6291 | result.return_value = .{ .none = {} }; | 6351 | result.return_value = .{ .none = {} }; |
| 6292 | } else { | 6352 | } else { |
| 6293 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod))); | 6353 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(pt))); |
| 6294 | if (ret_ty_size == 0) { | 6354 | if (ret_ty_size == 0) { |
| 6295 | assert(ret_ty.isError(mod)); | 6355 | assert(ret_ty.isError(mod)); |
| 6296 | result.return_value = .{ .immediate = 0 }; | 6356 | result.return_value = .{ .immediate = 0 }; |
| ... | @@ -6309,9 +6369,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6309,9 +6369,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6309 | var stack_offset: u32 = 0; | 6369 | var stack_offset: u32 = 0; |
| 6310 | 6370 | ||
| 6311 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { | 6371 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6312 | if (Type.fromInterned(ty).abiSize(mod) > 0) { | 6372 | if (Type.fromInterned(ty).abiSize(pt) > 0) { |
| 6313 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod)); | 6373 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); |
| 6314 | const param_alignment = Type.fromInterned(ty).abiAlignment(mod); | 6374 | const param_alignment = Type.fromInterned(ty).abiAlignment(pt); |
| 6315 | 6375 | ||
| 6316 | stack_offset = @intCast(param_alignment.forward(stack_offset)); | 6376 | stack_offset = @intCast(param_alignment.forward(stack_offset)); |
| 6317 | result_arg.* = .{ .stack_argument_offset = stack_offset }; | 6377 | result_arg.* = .{ .stack_argument_offset = stack_offset }; |
| ... | @@ -6330,7 +6390,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6330,7 +6390,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6330 | return result; | 6390 | return result; |
| 6331 | } | 6391 | } |
| 6332 | 6392 | ||
| 6333 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. | 6393 | /// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`. |
| 6334 | fn wantSafety(self: *Self) bool { | 6394 | fn wantSafety(self: *Self) bool { |
| 6335 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | 6395 | return switch (self.bin_file.comp.root_mod.optimize_mode) { |
| 6336 | .Debug => true, | 6396 | .Debug => true, |
| ... | @@ -6362,8 +6422,7 @@ fn parseRegName(name: []const u8) ?Register { | ... | @@ -6362,8 +6422,7 @@ fn parseRegName(name: []const u8) ?Register { |
| 6362 | } | 6422 | } |
| 6363 | 6423 | ||
| 6364 | fn registerAlias(self: *Self, reg: Register, ty: Type) Register { | 6424 | fn registerAlias(self: *Self, reg: Register, ty: Type) Register { |
| 6365 | const mod = self.bin_file.comp.module.?; | 6425 | const abi_size = ty.abiSize(self.pt); |
| 6366 | const abi_size = ty.abiSize(mod); | ||
| 6367 | 6426 | ||
| 6368 | switch (reg.class()) { | 6427 | switch (reg.class()) { |
| 6369 | .general_purpose => { | 6428 | .general_purpose => { |
| ... | @@ -6391,11 +6450,9 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register { | ... | @@ -6391,11 +6450,9 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register { |
| 6391 | } | 6450 | } |
| 6392 | 6451 | ||
| 6393 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { | 6452 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 6394 | const mod = self.bin_file.comp.module.?; | 6453 | return self.air.typeOf(inst, &self.pt.zcu.intern_pool); |
| 6395 | return self.air.typeOf(inst, &mod.intern_pool); | ||
| 6396 | } | 6454 | } |
| 6397 | 6455 | ||
| 6398 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { | 6456 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 6399 | const mod = self.bin_file.comp.module.?; | 6457 | return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool); |
| 6400 | return self.air.typeOfIndex(inst, &mod.intern_pool); | ||
| 6401 | } | 6458 | } |
src/arch/aarch64/Emit.zig+2-4| ... | @@ -8,9 +8,7 @@ const Mir = @import("Mir.zig"); | ... | @@ -8,9 +8,7 @@ const Mir = @import("Mir.zig"); |
| 8 | const bits = @import("bits.zig"); | 8 | const bits = @import("bits.zig"); |
| 9 | const link = @import("../../link.zig"); | 9 | const link = @import("../../link.zig"); |
| 10 | const Zcu = @import("../../Zcu.zig"); | 10 | const Zcu = @import("../../Zcu.zig"); |
| 11 | /// Deprecated. | 11 | const ErrorMsg = Zcu.ErrorMsg; |
| 12 | const Module = Zcu; | ||
| 13 | const ErrorMsg = Module.ErrorMsg; | ||
| 14 | const assert = std.debug.assert; | 12 | const assert = std.debug.assert; |
| 15 | const Instruction = bits.Instruction; | 13 | const Instruction = bits.Instruction; |
| 16 | const Register = bits.Register; | 14 | const Register = bits.Register; |
| ... | @@ -22,7 +20,7 @@ bin_file: *link.File, | ... | @@ -22,7 +20,7 @@ bin_file: *link.File, |
| 22 | debug_output: DebugInfoOutput, | 20 | debug_output: DebugInfoOutput, |
| 23 | target: *const std.Target, | 21 | target: *const std.Target, |
| 24 | err_msg: ?*ErrorMsg = null, | 22 | err_msg: ?*ErrorMsg = null, |
| 25 | src_loc: Module.LazySrcLoc, | 23 | src_loc: Zcu.LazySrcLoc, |
| 26 | code: *std.ArrayList(u8), | 24 | code: *std.ArrayList(u8), |
| 27 | 25 | ||
| 28 | prev_di_line: u32, | 26 | prev_di_line: u32, |
src/arch/aarch64/abi.zig+29-31| ... | @@ -5,8 +5,6 @@ const Register = bits.Register; | ... | @@ -5,8 +5,6 @@ const Register = bits.Register; |
| 5 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; | 5 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 6 | const Type = @import("../../Type.zig"); | 6 | const Type = @import("../../Type.zig"); |
| 7 | const Zcu = @import("../../Zcu.zig"); | 7 | const Zcu = @import("../../Zcu.zig"); |
| 8 | /// Deprecated. | ||
| 9 | const Module = Zcu; | ||
| 10 | 8 | ||
| 11 | pub const Class = union(enum) { | 9 | pub const Class = union(enum) { |
| 12 | memory, | 10 | memory, |
| ... | @@ -17,44 +15,44 @@ pub const Class = union(enum) { | ... | @@ -17,44 +15,44 @@ pub const Class = union(enum) { |
| 17 | }; | 15 | }; |
| 18 | 16 | ||
| 19 | /// For `float_array` the second element will be the amount of floats. | 17 | /// For `float_array` the second element will be the amount of floats. |
| 20 | pub fn classifyType(ty: Type, mod: *Module) Class { | 18 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { |
| 21 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 19 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 22 | 20 | ||
| 23 | var maybe_float_bits: ?u16 = null; | 21 | var maybe_float_bits: ?u16 = null; |
| 24 | switch (ty.zigTypeTag(mod)) { | 22 | switch (ty.zigTypeTag(pt.zcu)) { |
| 25 | .Struct => { | 23 | .Struct => { |
| 26 | if (ty.containerLayout(mod) == .@"packed") return .byval; | 24 | if (ty.containerLayout(pt.zcu) == .@"packed") return .byval; |
| 27 | const float_count = countFloats(ty, mod, &maybe_float_bits); | 25 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); |
| 28 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; | 26 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; |
| 29 | 27 | ||
| 30 | const bit_size = ty.bitSize(mod); | 28 | const bit_size = ty.bitSize(pt); |
| 31 | if (bit_size > 128) return .memory; | 29 | if (bit_size > 128) return .memory; |
| 32 | if (bit_size > 64) return .double_integer; | 30 | if (bit_size > 64) return .double_integer; |
| 33 | return .integer; | 31 | return .integer; |
| 34 | }, | 32 | }, |
| 35 | .Union => { | 33 | .Union => { |
| 36 | if (ty.containerLayout(mod) == .@"packed") return .byval; | 34 | if (ty.containerLayout(pt.zcu) == .@"packed") return .byval; |
| 37 | const float_count = countFloats(ty, mod, &maybe_float_bits); | 35 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); |
| 38 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; | 36 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; |
| 39 | 37 | ||
| 40 | const bit_size = ty.bitSize(mod); | 38 | const bit_size = ty.bitSize(pt); |
| 41 | if (bit_size > 128) return .memory; | 39 | if (bit_size > 128) return .memory; |
| 42 | if (bit_size > 64) return .double_integer; | 40 | if (bit_size > 64) return .double_integer; |
| 43 | return .integer; | 41 | return .integer; |
| 44 | }, | 42 | }, |
| 45 | .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval, | 43 | .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval, |
| 46 | .Vector => { | 44 | .Vector => { |
| 47 | const bit_size = ty.bitSize(mod); | 45 | const bit_size = ty.bitSize(pt); |
| 48 | // TODO is this controlled by a cpu feature? | 46 | // TODO is this controlled by a cpu feature? |
| 49 | if (bit_size > 128) return .memory; | 47 | if (bit_size > 128) return .memory; |
| 50 | return .byval; | 48 | return .byval; |
| 51 | }, | 49 | }, |
| 52 | .Optional => { | 50 | .Optional => { |
| 53 | std.debug.assert(ty.isPtrLikeOptional(mod)); | 51 | std.debug.assert(ty.isPtrLikeOptional(pt.zcu)); |
| 54 | return .byval; | 52 | return .byval; |
| 55 | }, | 53 | }, |
| 56 | .Pointer => { | 54 | .Pointer => { |
| 57 | std.debug.assert(!ty.isSlice(mod)); | 55 | std.debug.assert(!ty.isSlice(pt.zcu)); |
| 58 | return .byval; | 56 | return .byval; |
| 59 | }, | 57 | }, |
| 60 | .ErrorUnion, | 58 | .ErrorUnion, |
| ... | @@ -76,16 +74,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class { | ... | @@ -76,16 +74,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class { |
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | const sret_float_count = 4; | 76 | const sret_float_count = 4; |
| 79 | fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 { | 77 | fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u8 { |
| 80 | const ip = &mod.intern_pool; | 78 | const ip = &zcu.intern_pool; |
| 81 | const target = mod.getTarget(); | 79 | const target = zcu.getTarget(); |
| 82 | const invalid = std.math.maxInt(u8); | 80 | const invalid = std.math.maxInt(u8); |
| 83 | switch (ty.zigTypeTag(mod)) { | 81 | switch (ty.zigTypeTag(zcu)) { |
| 84 | .Union => { | 82 | .Union => { |
| 85 | const union_obj = mod.typeToUnion(ty).?; | 83 | const union_obj = zcu.typeToUnion(ty).?; |
| 86 | var max_count: u8 = 0; | 84 | var max_count: u8 = 0; |
| 87 | for (union_obj.field_types.get(ip)) |field_ty| { | 85 | for (union_obj.field_types.get(ip)) |field_ty| { |
| 88 | const field_count = countFloats(Type.fromInterned(field_ty), mod, maybe_float_bits); | 86 | const field_count = countFloats(Type.fromInterned(field_ty), zcu, maybe_float_bits); |
| 89 | if (field_count == invalid) return invalid; | 87 | if (field_count == invalid) return invalid; |
| 90 | if (field_count > max_count) max_count = field_count; | 88 | if (field_count > max_count) max_count = field_count; |
| 91 | if (max_count > sret_float_count) return invalid; | 89 | if (max_count > sret_float_count) return invalid; |
| ... | @@ -93,12 +91,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 { | ... | @@ -93,12 +91,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 { |
| 93 | return max_count; | 91 | return max_count; |
| 94 | }, | 92 | }, |
| 95 | .Struct => { | 93 | .Struct => { |
| 96 | const fields_len = ty.structFieldCount(mod); | 94 | const fields_len = ty.structFieldCount(zcu); |
| 97 | var count: u8 = 0; | 95 | var count: u8 = 0; |
| 98 | var i: u32 = 0; | 96 | var i: u32 = 0; |
| 99 | while (i < fields_len) : (i += 1) { | 97 | while (i < fields_len) : (i += 1) { |
| 100 | const field_ty = ty.structFieldType(i, mod); | 98 | const field_ty = ty.structFieldType(i, zcu); |
| 101 | const field_count = countFloats(field_ty, mod, maybe_float_bits); | 99 | const field_count = countFloats(field_ty, zcu, maybe_float_bits); |
| 102 | if (field_count == invalid) return invalid; | 100 | if (field_count == invalid) return invalid; |
| 103 | count += field_count; | 101 | count += field_count; |
| 104 | if (count > sret_float_count) return invalid; | 102 | if (count > sret_float_count) return invalid; |
| ... | @@ -118,22 +116,22 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 { | ... | @@ -118,22 +116,22 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u8 { |
| 118 | } | 116 | } |
| 119 | } | 117 | } |
| 120 | 118 | ||
| 121 | pub fn getFloatArrayType(ty: Type, mod: *Module) ?Type { | 119 | pub fn getFloatArrayType(ty: Type, zcu: *Zcu) ?Type { |
| 122 | const ip = &mod.intern_pool; | 120 | const ip = &zcu.intern_pool; |
| 123 | switch (ty.zigTypeTag(mod)) { | 121 | switch (ty.zigTypeTag(zcu)) { |
| 124 | .Union => { | 122 | .Union => { |
| 125 | const union_obj = mod.typeToUnion(ty).?; | 123 | const union_obj = zcu.typeToUnion(ty).?; |
| 126 | for (union_obj.field_types.get(ip)) |field_ty| { | 124 | for (union_obj.field_types.get(ip)) |field_ty| { |
| 127 | if (getFloatArrayType(Type.fromInterned(field_ty), mod)) |some| return some; | 125 | if (getFloatArrayType(Type.fromInterned(field_ty), zcu)) |some| return some; |
| 128 | } | 126 | } |
| 129 | return null; | 127 | return null; |
| 130 | }, | 128 | }, |
| 131 | .Struct => { | 129 | .Struct => { |
| 132 | const fields_len = ty.structFieldCount(mod); | 130 | const fields_len = ty.structFieldCount(zcu); |
| 133 | var i: u32 = 0; | 131 | var i: u32 = 0; |
| 134 | while (i < fields_len) : (i += 1) { | 132 | while (i < fields_len) : (i += 1) { |
| 135 | const field_ty = ty.structFieldType(i, mod); | 133 | const field_ty = ty.structFieldType(i, zcu); |
| 136 | if (getFloatArrayType(field_ty, mod)) |some| return some; | 134 | if (getFloatArrayType(field_ty, zcu)) |some| return some; |
| 137 | } | 135 | } |
| 138 | return null; | 136 | return null; |
| 139 | }, | 137 | }, |
src/arch/arm/CodeGen.zig+219-164| ... | @@ -12,11 +12,9 @@ const Type = @import("../../Type.zig"); | ... | @@ -12,11 +12,9 @@ const Type = @import("../../Type.zig"); |
| 12 | const Value = @import("../../Value.zig"); | 12 | const Value = @import("../../Value.zig"); |
| 13 | const link = @import("../../link.zig"); | 13 | const link = @import("../../link.zig"); |
| 14 | const Zcu = @import("../../Zcu.zig"); | 14 | const Zcu = @import("../../Zcu.zig"); |
| 15 | /// Deprecated. | ||
| 16 | const Module = Zcu; | ||
| 17 | const InternPool = @import("../../InternPool.zig"); | 15 | const InternPool = @import("../../InternPool.zig"); |
| 18 | const Compilation = @import("../../Compilation.zig"); | 16 | const Compilation = @import("../../Compilation.zig"); |
| 19 | const ErrorMsg = Module.ErrorMsg; | 17 | const ErrorMsg = Zcu.ErrorMsg; |
| 20 | const Target = std.Target; | 18 | const Target = std.Target; |
| 21 | const Allocator = mem.Allocator; | 19 | const Allocator = mem.Allocator; |
| 22 | const trace = @import("../../tracy.zig").trace; | 20 | const trace = @import("../../tracy.zig").trace; |
| ... | @@ -48,6 +46,7 @@ const gp = abi.RegisterClass.gp; | ... | @@ -48,6 +46,7 @@ const gp = abi.RegisterClass.gp; |
| 48 | const InnerError = CodeGenError || error{OutOfRegisters}; | 46 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 49 | 47 | ||
| 50 | gpa: Allocator, | 48 | gpa: Allocator, |
| 49 | pt: Zcu.PerThread, | ||
| 51 | air: Air, | 50 | air: Air, |
| 52 | liveness: Liveness, | 51 | liveness: Liveness, |
| 53 | bin_file: *link.File, | 52 | bin_file: *link.File, |
| ... | @@ -59,7 +58,7 @@ args: []MCValue, | ... | @@ -59,7 +58,7 @@ args: []MCValue, |
| 59 | ret_mcv: MCValue, | 58 | ret_mcv: MCValue, |
| 60 | fn_type: Type, | 59 | fn_type: Type, |
| 61 | arg_index: u32, | 60 | arg_index: u32, |
| 62 | src_loc: Module.LazySrcLoc, | 61 | src_loc: Zcu.LazySrcLoc, |
| 63 | stack_align: u32, | 62 | stack_align: u32, |
| 64 | 63 | ||
| 65 | /// MIR Instructions | 64 | /// MIR Instructions |
| ... | @@ -261,7 +260,6 @@ const DbgInfoReloc = struct { | ... | @@ -261,7 +260,6 @@ const DbgInfoReloc = struct { |
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { | 262 | fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { |
| 264 | const mod = function.bin_file.comp.module.?; | ||
| 265 | switch (function.debug_output) { | 263 | switch (function.debug_output) { |
| 266 | .dwarf => |dw| { | 264 | .dwarf => |dw| { |
| 267 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) { | 265 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) { |
| ... | @@ -282,7 +280,7 @@ const DbgInfoReloc = struct { | ... | @@ -282,7 +280,7 @@ const DbgInfoReloc = struct { |
| 282 | else => unreachable, // not a possible argument | 280 | else => unreachable, // not a possible argument |
| 283 | }; | 281 | }; |
| 284 | 282 | ||
| 285 | try dw.genArgDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), loc); | 283 | try dw.genArgDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), loc); |
| 286 | }, | 284 | }, |
| 287 | .plan9 => {}, | 285 | .plan9 => {}, |
| 288 | .none => {}, | 286 | .none => {}, |
| ... | @@ -290,7 +288,6 @@ const DbgInfoReloc = struct { | ... | @@ -290,7 +288,6 @@ const DbgInfoReloc = struct { |
| 290 | } | 288 | } |
| 291 | 289 | ||
| 292 | fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void { | 290 | fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void { |
| 293 | const mod = function.bin_file.comp.module.?; | ||
| 294 | const is_ptr = switch (reloc.tag) { | 291 | const is_ptr = switch (reloc.tag) { |
| 295 | .dbg_var_ptr => true, | 292 | .dbg_var_ptr => true, |
| 296 | .dbg_var_val => false, | 293 | .dbg_var_val => false, |
| ... | @@ -326,7 +323,7 @@ const DbgInfoReloc = struct { | ... | @@ -326,7 +323,7 @@ const DbgInfoReloc = struct { |
| 326 | break :blk .nop; | 323 | break :blk .nop; |
| 327 | }, | 324 | }, |
| 328 | }; | 325 | }; |
| 329 | try dw.genVarDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), is_ptr, loc); | 326 | try dw.genVarDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), is_ptr, loc); |
| 330 | }, | 327 | }, |
| 331 | .plan9 => {}, | 328 | .plan9 => {}, |
| 332 | .none => {}, | 329 | .none => {}, |
| ... | @@ -338,15 +335,16 @@ const Self = @This(); | ... | @@ -338,15 +335,16 @@ const Self = @This(); |
| 338 | 335 | ||
| 339 | pub fn generate( | 336 | pub fn generate( |
| 340 | lf: *link.File, | 337 | lf: *link.File, |
| 341 | src_loc: Module.LazySrcLoc, | 338 | pt: Zcu.PerThread, |
| 339 | src_loc: Zcu.LazySrcLoc, | ||
| 342 | func_index: InternPool.Index, | 340 | func_index: InternPool.Index, |
| 343 | air: Air, | 341 | air: Air, |
| 344 | liveness: Liveness, | 342 | liveness: Liveness, |
| 345 | code: *std.ArrayList(u8), | 343 | code: *std.ArrayList(u8), |
| 346 | debug_output: DebugInfoOutput, | 344 | debug_output: DebugInfoOutput, |
| 347 | ) CodeGenError!Result { | 345 | ) CodeGenError!Result { |
| 348 | const gpa = lf.comp.gpa; | 346 | const zcu = pt.zcu; |
| 349 | const zcu = lf.comp.module.?; | 347 | const gpa = zcu.gpa; |
| 350 | const func = zcu.funcInfo(func_index); | 348 | const func = zcu.funcInfo(func_index); |
| 351 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 349 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 352 | assert(fn_owner_decl.has_tv); | 350 | assert(fn_owner_decl.has_tv); |
| ... | @@ -364,6 +362,7 @@ pub fn generate( | ... | @@ -364,6 +362,7 @@ pub fn generate( |
| 364 | 362 | ||
| 365 | var function: Self = .{ | 363 | var function: Self = .{ |
| 366 | .gpa = gpa, | 364 | .gpa = gpa, |
| 365 | .pt = pt, | ||
| 367 | .air = air, | 366 | .air = air, |
| 368 | .liveness = liveness, | 367 | .liveness = liveness, |
| 369 | .target = target, | 368 | .target = target, |
| ... | @@ -482,7 +481,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -482,7 +481,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 482 | } | 481 | } |
| 483 | 482 | ||
| 484 | fn gen(self: *Self) !void { | 483 | fn gen(self: *Self) !void { |
| 485 | const mod = self.bin_file.comp.module.?; | 484 | const pt = self.pt; |
| 485 | const mod = pt.zcu; | ||
| 486 | const cc = self.fn_type.fnCallingConvention(mod); | 486 | const cc = self.fn_type.fnCallingConvention(mod); |
| 487 | if (cc != .Naked) { | 487 | if (cc != .Naked) { |
| 488 | // push {fp, lr} | 488 | // push {fp, lr} |
| ... | @@ -526,8 +526,8 @@ fn gen(self: *Self) !void { | ... | @@ -526,8 +526,8 @@ fn gen(self: *Self) !void { |
| 526 | 526 | ||
| 527 | const ty = self.typeOfIndex(inst); | 527 | const ty = self.typeOfIndex(inst); |
| 528 | 528 | ||
| 529 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 529 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 530 | const abi_align = ty.abiAlignment(mod); | 530 | const abi_align = ty.abiAlignment(pt); |
| 531 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | 531 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 532 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 532 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 533 | 533 | ||
| ... | @@ -642,7 +642,8 @@ fn gen(self: *Self) !void { | ... | @@ -642,7 +642,8 @@ fn gen(self: *Self) !void { |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | 644 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 645 | const mod = self.bin_file.comp.module.?; | 645 | const pt = self.pt; |
| 646 | const mod = pt.zcu; | ||
| 646 | const ip = &mod.intern_pool; | 647 | const ip = &mod.intern_pool; |
| 647 | const air_tags = self.air.instructions.items(.tag); | 648 | const air_tags = self.air.instructions.items(.tag); |
| 648 | 649 | ||
| ... | @@ -1004,10 +1005,11 @@ fn allocMem( | ... | @@ -1004,10 +1005,11 @@ fn allocMem( |
| 1004 | 1005 | ||
| 1005 | /// Use a pointer instruction as the basis for allocating stack memory. | 1006 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1006 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | 1007 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1007 | const mod = self.bin_file.comp.module.?; | 1008 | const pt = self.pt; |
| 1009 | const mod = pt.zcu; | ||
| 1008 | const elem_ty = self.typeOfIndex(inst).childType(mod); | 1010 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 1009 | 1011 | ||
| 1010 | if (!elem_ty.hasRuntimeBits(mod)) { | 1012 | if (!elem_ty.hasRuntimeBits(pt)) { |
| 1011 | // As this stack item will never be dereferenced at runtime, | 1013 | // As this stack item will never be dereferenced at runtime, |
| 1012 | // return the stack offset 0. Stack offset 0 will be where all | 1014 | // return the stack offset 0. Stack offset 0 will be where all |
| 1013 | // zero-sized stack allocations live as non-zero-sized | 1015 | // zero-sized stack allocations live as non-zero-sized |
| ... | @@ -1015,21 +1017,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | ... | @@ -1015,21 +1017,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1015 | return 0; | 1017 | return 0; |
| 1016 | } | 1018 | } |
| 1017 | 1019 | ||
| 1018 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 1020 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 1019 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 1021 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1020 | }; | 1022 | }; |
| 1021 | // TODO swap this for inst.ty.ptrAlign | 1023 | // TODO swap this for inst.ty.ptrAlign |
| 1022 | const abi_align = elem_ty.abiAlignment(mod); | 1024 | const abi_align = elem_ty.abiAlignment(pt); |
| 1023 | 1025 | ||
| 1024 | return self.allocMem(abi_size, abi_align, inst); | 1026 | return self.allocMem(abi_size, abi_align, inst); |
| 1025 | } | 1027 | } |
| 1026 | 1028 | ||
| 1027 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { | 1029 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1028 | const mod = self.bin_file.comp.module.?; | 1030 | const pt = self.pt; |
| 1029 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 1031 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 1030 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 1032 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1031 | }; | 1033 | }; |
| 1032 | const abi_align = elem_ty.abiAlignment(mod); | 1034 | const abi_align = elem_ty.abiAlignment(pt); |
| 1033 | 1035 | ||
| 1034 | if (reg_ok) { | 1036 | if (reg_ok) { |
| 1035 | // Make sure the type can fit in a register before we try to allocate one. | 1037 | // Make sure the type can fit in a register before we try to allocate one. |
| ... | @@ -1112,14 +1114,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1112,14 +1114,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1112 | } | 1114 | } |
| 1113 | 1115 | ||
| 1114 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { | 1116 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1115 | const mod = self.bin_file.comp.module.?; | 1117 | const pt = self.pt; |
| 1118 | const mod = pt.zcu; | ||
| 1116 | const result: MCValue = switch (self.ret_mcv) { | 1119 | const result: MCValue = switch (self.ret_mcv) { |
| 1117 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, | 1120 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1118 | .stack_offset => blk: { | 1121 | .stack_offset => blk: { |
| 1119 | // self.ret_mcv is an address to where this function | 1122 | // self.ret_mcv is an address to where this function |
| 1120 | // should store its result into | 1123 | // should store its result into |
| 1121 | const ret_ty = self.fn_type.fnReturnType(mod); | 1124 | const ret_ty = self.fn_type.fnReturnType(mod); |
| 1122 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 1125 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 1123 | 1126 | ||
| 1124 | // addr_reg will contain the address of where to store the | 1127 | // addr_reg will contain the address of where to store the |
| 1125 | // result into | 1128 | // result into |
| ... | @@ -1145,7 +1148,8 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1145,7 +1148,8 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 1145 | } | 1148 | } |
| 1146 | 1149 | ||
| 1147 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | 1150 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1148 | const mod = self.bin_file.comp.module.?; | 1151 | const pt = self.pt; |
| 1152 | const mod = pt.zcu; | ||
| 1149 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1153 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1150 | if (self.liveness.isUnused(inst)) | 1154 | if (self.liveness.isUnused(inst)) |
| 1151 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); | 1155 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| ... | @@ -1154,8 +1158,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1154,8 +1158,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1154 | const operand_ty = self.typeOf(ty_op.operand); | 1158 | const operand_ty = self.typeOf(ty_op.operand); |
| 1155 | const dest_ty = self.typeOfIndex(inst); | 1159 | const dest_ty = self.typeOfIndex(inst); |
| 1156 | 1160 | ||
| 1157 | const operand_abi_size = operand_ty.abiSize(mod); | 1161 | const operand_abi_size = operand_ty.abiSize(pt); |
| 1158 | const dest_abi_size = dest_ty.abiSize(mod); | 1162 | const dest_abi_size = dest_ty.abiSize(pt); |
| 1159 | const info_a = operand_ty.intInfo(mod); | 1163 | const info_a = operand_ty.intInfo(mod); |
| 1160 | const info_b = dest_ty.intInfo(mod); | 1164 | const info_b = dest_ty.intInfo(mod); |
| 1161 | 1165 | ||
| ... | @@ -1211,7 +1215,8 @@ fn trunc( | ... | @@ -1211,7 +1215,8 @@ fn trunc( |
| 1211 | operand_ty: Type, | 1215 | operand_ty: Type, |
| 1212 | dest_ty: Type, | 1216 | dest_ty: Type, |
| 1213 | ) !MCValue { | 1217 | ) !MCValue { |
| 1214 | const mod = self.bin_file.comp.module.?; | 1218 | const pt = self.pt; |
| 1219 | const mod = pt.zcu; | ||
| 1215 | const info_a = operand_ty.intInfo(mod); | 1220 | const info_a = operand_ty.intInfo(mod); |
| 1216 | const info_b = dest_ty.intInfo(mod); | 1221 | const info_b = dest_ty.intInfo(mod); |
| 1217 | 1222 | ||
| ... | @@ -1275,7 +1280,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1275,7 +1280,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1275 | 1280 | ||
| 1276 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { | 1281 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1277 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1282 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1278 | const mod = self.bin_file.comp.module.?; | 1283 | const pt = self.pt; |
| 1284 | const mod = pt.zcu; | ||
| 1279 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1285 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1280 | const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand }; | 1286 | const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand }; |
| 1281 | const operand_ty = self.typeOf(ty_op.operand); | 1287 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -1371,7 +1377,8 @@ fn minMax( | ... | @@ -1371,7 +1377,8 @@ fn minMax( |
| 1371 | rhs_ty: Type, | 1377 | rhs_ty: Type, |
| 1372 | maybe_inst: ?Air.Inst.Index, | 1378 | maybe_inst: ?Air.Inst.Index, |
| 1373 | ) !MCValue { | 1379 | ) !MCValue { |
| 1374 | const mod = self.bin_file.comp.module.?; | 1380 | const pt = self.pt; |
| 1381 | const mod = pt.zcu; | ||
| 1375 | switch (lhs_ty.zigTypeTag(mod)) { | 1382 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1376 | .Float => return self.fail("TODO ARM min/max on floats", .{}), | 1383 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1377 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), | 1384 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| ... | @@ -1580,7 +1587,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1580,7 +1587,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1580 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 1587 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 1581 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1588 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1582 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 1589 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1583 | const mod = self.bin_file.comp.module.?; | 1590 | const pt = self.pt; |
| 1591 | const mod = pt.zcu; | ||
| 1584 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1592 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1585 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; | 1593 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1586 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; | 1594 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | @@ -1588,9 +1596,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1588,9 +1596,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1588 | const rhs_ty = self.typeOf(extra.rhs); | 1596 | const rhs_ty = self.typeOf(extra.rhs); |
| 1589 | 1597 | ||
| 1590 | const tuple_ty = self.typeOfIndex(inst); | 1598 | const tuple_ty = self.typeOfIndex(inst); |
| 1591 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod)); | 1599 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); |
| 1592 | const tuple_align = tuple_ty.abiAlignment(mod); | 1600 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 1593 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod)); | 1601 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); |
| 1594 | 1602 | ||
| 1595 | switch (lhs_ty.zigTypeTag(mod)) { | 1603 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1596 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), | 1604 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), |
| ... | @@ -1693,7 +1701,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1693,7 +1701,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1693 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1701 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1694 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 1702 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1695 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); | 1703 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 1696 | const mod = self.bin_file.comp.module.?; | 1704 | const pt = self.pt; |
| 1705 | const mod = pt.zcu; | ||
| 1697 | const result: MCValue = result: { | 1706 | const result: MCValue = result: { |
| 1698 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; | 1707 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1699 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; | 1708 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | @@ -1701,9 +1710,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1701,9 +1710,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1701 | const rhs_ty = self.typeOf(extra.rhs); | 1710 | const rhs_ty = self.typeOf(extra.rhs); |
| 1702 | 1711 | ||
| 1703 | const tuple_ty = self.typeOfIndex(inst); | 1712 | const tuple_ty = self.typeOfIndex(inst); |
| 1704 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod)); | 1713 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); |
| 1705 | const tuple_align = tuple_ty.abiAlignment(mod); | 1714 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 1706 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod)); | 1715 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); |
| 1707 | 1716 | ||
| 1708 | switch (lhs_ty.zigTypeTag(mod)) { | 1717 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1709 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), | 1718 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), |
| ... | @@ -1857,15 +1866,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1857,15 +1866,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1857 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1866 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1858 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 1867 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1859 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); | 1868 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 1860 | const mod = self.bin_file.comp.module.?; | 1869 | const pt = self.pt; |
| 1870 | const mod = pt.zcu; | ||
| 1861 | const result: MCValue = result: { | 1871 | const result: MCValue = result: { |
| 1862 | const lhs_ty = self.typeOf(extra.lhs); | 1872 | const lhs_ty = self.typeOf(extra.lhs); |
| 1863 | const rhs_ty = self.typeOf(extra.rhs); | 1873 | const rhs_ty = self.typeOf(extra.rhs); |
| 1864 | 1874 | ||
| 1865 | const tuple_ty = self.typeOfIndex(inst); | 1875 | const tuple_ty = self.typeOfIndex(inst); |
| 1866 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod)); | 1876 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); |
| 1867 | const tuple_align = tuple_ty.abiAlignment(mod); | 1877 | const tuple_align = tuple_ty.abiAlignment(pt); |
| 1868 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod)); | 1878 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); |
| 1869 | 1879 | ||
| 1870 | switch (lhs_ty.zigTypeTag(mod)) { | 1880 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1871 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), | 1881 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), |
| ... | @@ -2013,11 +2023,11 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2013,11 +2023,11 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 2013 | } | 2023 | } |
| 2014 | 2024 | ||
| 2015 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | 2025 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2016 | const mod = self.bin_file.comp.module.?; | 2026 | const pt = self.pt; |
| 2017 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2027 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2018 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2028 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2019 | const optional_ty = self.typeOfIndex(inst); | 2029 | const optional_ty = self.typeOfIndex(inst); |
| 2020 | const abi_size: u32 = @intCast(optional_ty.abiSize(mod)); | 2030 | const abi_size: u32 = @intCast(optional_ty.abiSize(pt)); |
| 2021 | 2031 | ||
| 2022 | // Optional with a zero-bit payload type is just a boolean true | 2032 | // Optional with a zero-bit payload type is just a boolean true |
| 2023 | if (abi_size == 1) { | 2033 | if (abi_size == 1) { |
| ... | @@ -2036,17 +2046,18 @@ fn errUnionErr( | ... | @@ -2036,17 +2046,18 @@ fn errUnionErr( |
| 2036 | error_union_ty: Type, | 2046 | error_union_ty: Type, |
| 2037 | maybe_inst: ?Air.Inst.Index, | 2047 | maybe_inst: ?Air.Inst.Index, |
| 2038 | ) !MCValue { | 2048 | ) !MCValue { |
| 2039 | const mod = self.bin_file.comp.module.?; | 2049 | const pt = self.pt; |
| 2050 | const mod = pt.zcu; | ||
| 2040 | const err_ty = error_union_ty.errorUnionSet(mod); | 2051 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 2041 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2052 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2042 | if (err_ty.errorSetIsEmpty(mod)) { | 2053 | if (err_ty.errorSetIsEmpty(mod)) { |
| 2043 | return MCValue{ .immediate = 0 }; | 2054 | return MCValue{ .immediate = 0 }; |
| 2044 | } | 2055 | } |
| 2045 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2056 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2046 | return try error_union_bind.resolveToMcv(self); | 2057 | return try error_union_bind.resolveToMcv(self); |
| 2047 | } | 2058 | } |
| 2048 | 2059 | ||
| 2049 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, mod)); | 2060 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); |
| 2050 | switch (try error_union_bind.resolveToMcv(self)) { | 2061 | switch (try error_union_bind.resolveToMcv(self)) { |
| 2051 | .register => { | 2062 | .register => { |
| 2052 | var operand_reg: Register = undefined; | 2063 | var operand_reg: Register = undefined; |
| ... | @@ -2068,7 +2079,7 @@ fn errUnionErr( | ... | @@ -2068,7 +2079,7 @@ fn errUnionErr( |
| 2068 | ); | 2079 | ); |
| 2069 | 2080 | ||
| 2070 | const err_bit_offset = err_offset * 8; | 2081 | const err_bit_offset = err_offset * 8; |
| 2071 | const err_bit_size: u32 = @intCast(err_ty.abiSize(mod) * 8); | 2082 | const err_bit_size: u32 = @intCast(err_ty.abiSize(pt) * 8); |
| 2072 | 2083 | ||
| 2073 | _ = try self.addInst(.{ | 2084 | _ = try self.addInst(.{ |
| 2074 | .tag = .ubfx, // errors are unsigned integers | 2085 | .tag = .ubfx, // errors are unsigned integers |
| ... | @@ -2113,17 +2124,18 @@ fn errUnionPayload( | ... | @@ -2113,17 +2124,18 @@ fn errUnionPayload( |
| 2113 | error_union_ty: Type, | 2124 | error_union_ty: Type, |
| 2114 | maybe_inst: ?Air.Inst.Index, | 2125 | maybe_inst: ?Air.Inst.Index, |
| 2115 | ) !MCValue { | 2126 | ) !MCValue { |
| 2116 | const mod = self.bin_file.comp.module.?; | 2127 | const pt = self.pt; |
| 2128 | const mod = pt.zcu; | ||
| 2117 | const err_ty = error_union_ty.errorUnionSet(mod); | 2129 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 2118 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2130 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2119 | if (err_ty.errorSetIsEmpty(mod)) { | 2131 | if (err_ty.errorSetIsEmpty(mod)) { |
| 2120 | return try error_union_bind.resolveToMcv(self); | 2132 | return try error_union_bind.resolveToMcv(self); |
| 2121 | } | 2133 | } |
| 2122 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2134 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2123 | return MCValue.none; | 2135 | return MCValue.none; |
| 2124 | } | 2136 | } |
| 2125 | 2137 | ||
| 2126 | const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, mod)); | 2138 | const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, pt)); |
| 2127 | switch (try error_union_bind.resolveToMcv(self)) { | 2139 | switch (try error_union_bind.resolveToMcv(self)) { |
| 2128 | .register => { | 2140 | .register => { |
| 2129 | var operand_reg: Register = undefined; | 2141 | var operand_reg: Register = undefined; |
| ... | @@ -2145,7 +2157,7 @@ fn errUnionPayload( | ... | @@ -2145,7 +2157,7 @@ fn errUnionPayload( |
| 2145 | ); | 2157 | ); |
| 2146 | 2158 | ||
| 2147 | const payload_bit_offset = payload_offset * 8; | 2159 | const payload_bit_offset = payload_offset * 8; |
| 2148 | const payload_bit_size: u32 = @intCast(payload_ty.abiSize(mod) * 8); | 2160 | const payload_bit_size: u32 = @intCast(payload_ty.abiSize(pt) * 8); |
| 2149 | 2161 | ||
| 2150 | _ = try self.addInst(.{ | 2162 | _ = try self.addInst(.{ |
| 2151 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | 2163 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, |
| ... | @@ -2223,20 +2235,21 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2223,20 +2235,21 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 2223 | 2235 | ||
| 2224 | /// T to E!T | 2236 | /// T to E!T |
| 2225 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | 2237 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2226 | const mod = self.bin_file.comp.module.?; | 2238 | const pt = self.pt; |
| 2239 | const mod = pt.zcu; | ||
| 2227 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2240 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2228 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2241 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2229 | const error_union_ty = ty_op.ty.toType(); | 2242 | const error_union_ty = ty_op.ty.toType(); |
| 2230 | const error_ty = error_union_ty.errorUnionSet(mod); | 2243 | const error_ty = error_union_ty.errorUnionSet(mod); |
| 2231 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2244 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2232 | const operand = try self.resolveInst(ty_op.operand); | 2245 | const operand = try self.resolveInst(ty_op.operand); |
| 2233 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand; | 2246 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; |
| 2234 | 2247 | ||
| 2235 | const abi_size: u32 = @intCast(error_union_ty.abiSize(mod)); | 2248 | const abi_size: u32 = @intCast(error_union_ty.abiSize(pt)); |
| 2236 | const abi_align = error_union_ty.abiAlignment(mod); | 2249 | const abi_align = error_union_ty.abiAlignment(pt); |
| 2237 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); | 2250 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); |
| 2238 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | 2251 | const payload_off = errUnionPayloadOffset(payload_ty, pt); |
| 2239 | const err_off = errUnionErrorOffset(payload_ty, mod); | 2252 | const err_off = errUnionErrorOffset(payload_ty, pt); |
| 2240 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); | 2253 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); |
| 2241 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); | 2254 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); |
| 2242 | 2255 | ||
| ... | @@ -2247,20 +2260,21 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2247,20 +2260,21 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2247 | 2260 | ||
| 2248 | /// E to E!T | 2261 | /// E to E!T |
| 2249 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 2262 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2250 | const mod = self.bin_file.comp.module.?; | 2263 | const pt = self.pt; |
| 2264 | const mod = pt.zcu; | ||
| 2251 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2265 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2252 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2266 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2253 | const error_union_ty = ty_op.ty.toType(); | 2267 | const error_union_ty = ty_op.ty.toType(); |
| 2254 | const error_ty = error_union_ty.errorUnionSet(mod); | 2268 | const error_ty = error_union_ty.errorUnionSet(mod); |
| 2255 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2269 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2256 | const operand = try self.resolveInst(ty_op.operand); | 2270 | const operand = try self.resolveInst(ty_op.operand); |
| 2257 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand; | 2271 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; |
| 2258 | 2272 | ||
| 2259 | const abi_size: u32 = @intCast(error_union_ty.abiSize(mod)); | 2273 | const abi_size: u32 = @intCast(error_union_ty.abiSize(pt)); |
| 2260 | const abi_align = error_union_ty.abiAlignment(mod); | 2274 | const abi_align = error_union_ty.abiAlignment(pt); |
| 2261 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); | 2275 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); |
| 2262 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | 2276 | const payload_off = errUnionPayloadOffset(payload_ty, pt); |
| 2263 | const err_off = errUnionErrorOffset(payload_ty, mod); | 2277 | const err_off = errUnionErrorOffset(payload_ty, pt); |
| 2264 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); | 2278 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); |
| 2265 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); | 2279 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); |
| 2266 | 2280 | ||
| ... | @@ -2364,9 +2378,10 @@ fn ptrElemVal( | ... | @@ -2364,9 +2378,10 @@ fn ptrElemVal( |
| 2364 | ptr_ty: Type, | 2378 | ptr_ty: Type, |
| 2365 | maybe_inst: ?Air.Inst.Index, | 2379 | maybe_inst: ?Air.Inst.Index, |
| 2366 | ) !MCValue { | 2380 | ) !MCValue { |
| 2367 | const mod = self.bin_file.comp.module.?; | 2381 | const pt = self.pt; |
| 2382 | const mod = pt.zcu; | ||
| 2368 | const elem_ty = ptr_ty.childType(mod); | 2383 | const elem_ty = ptr_ty.childType(mod); |
| 2369 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); | 2384 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 2370 | 2385 | ||
| 2371 | switch (elem_size) { | 2386 | switch (elem_size) { |
| 2372 | 1, 4 => { | 2387 | 1, 4 => { |
| ... | @@ -2423,7 +2438,8 @@ fn ptrElemVal( | ... | @@ -2423,7 +2438,8 @@ fn ptrElemVal( |
| 2423 | } | 2438 | } |
| 2424 | 2439 | ||
| 2425 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | 2440 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2426 | const mod = self.bin_file.comp.module.?; | 2441 | const pt = self.pt; |
| 2442 | const mod = pt.zcu; | ||
| 2427 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2443 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2428 | const slice_ty = self.typeOf(bin_op.lhs); | 2444 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2429 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 2445 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | @@ -2466,7 +2482,8 @@ fn arrayElemVal( | ... | @@ -2466,7 +2482,8 @@ fn arrayElemVal( |
| 2466 | array_ty: Type, | 2482 | array_ty: Type, |
| 2467 | maybe_inst: ?Air.Inst.Index, | 2483 | maybe_inst: ?Air.Inst.Index, |
| 2468 | ) InnerError!MCValue { | 2484 | ) InnerError!MCValue { |
| 2469 | const mod = self.bin_file.comp.module.?; | 2485 | const pt = self.pt; |
| 2486 | const mod = pt.zcu; | ||
| 2470 | const elem_ty = array_ty.childType(mod); | 2487 | const elem_ty = array_ty.childType(mod); |
| 2471 | 2488 | ||
| 2472 | const mcv = try array_bind.resolveToMcv(self); | 2489 | const mcv = try array_bind.resolveToMcv(self); |
| ... | @@ -2501,7 +2518,7 @@ fn arrayElemVal( | ... | @@ -2501,7 +2518,7 @@ fn arrayElemVal( |
| 2501 | 2518 | ||
| 2502 | const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv }; | 2519 | const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv }; |
| 2503 | 2520 | ||
| 2504 | const ptr_ty = try mod.singleMutPtrType(elem_ty); | 2521 | const ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 2505 | 2522 | ||
| 2506 | return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst); | 2523 | return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst); |
| 2507 | }, | 2524 | }, |
| ... | @@ -2522,7 +2539,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2522,7 +2539,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2522 | } | 2539 | } |
| 2523 | 2540 | ||
| 2524 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | 2541 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2525 | const mod = self.bin_file.comp.module.?; | 2542 | const pt = self.pt; |
| 2543 | const mod = pt.zcu; | ||
| 2526 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2544 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2527 | const ptr_ty = self.typeOf(bin_op.lhs); | 2545 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 2528 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 2546 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | @@ -2656,9 +2674,10 @@ fn reuseOperand( | ... | @@ -2656,9 +2674,10 @@ fn reuseOperand( |
| 2656 | } | 2674 | } |
| 2657 | 2675 | ||
| 2658 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { | 2676 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 2659 | const mod = self.bin_file.comp.module.?; | 2677 | const pt = self.pt; |
| 2678 | const mod = pt.zcu; | ||
| 2660 | const elem_ty = ptr_ty.childType(mod); | 2679 | const elem_ty = ptr_ty.childType(mod); |
| 2661 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); | 2680 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 2662 | 2681 | ||
| 2663 | switch (ptr) { | 2682 | switch (ptr) { |
| 2664 | .none => unreachable, | 2683 | .none => unreachable, |
| ... | @@ -2733,11 +2752,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2733,11 +2752,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2733 | } | 2752 | } |
| 2734 | 2753 | ||
| 2735 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | 2754 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2736 | const mod = self.bin_file.comp.module.?; | 2755 | const pt = self.pt; |
| 2756 | const mod = pt.zcu; | ||
| 2737 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2757 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2738 | const elem_ty = self.typeOfIndex(inst); | 2758 | const elem_ty = self.typeOfIndex(inst); |
| 2739 | const result: MCValue = result: { | 2759 | const result: MCValue = result: { |
| 2740 | if (!elem_ty.hasRuntimeBits(mod)) | 2760 | if (!elem_ty.hasRuntimeBits(pt)) |
| 2741 | break :result MCValue.none; | 2761 | break :result MCValue.none; |
| 2742 | 2762 | ||
| 2743 | const ptr = try self.resolveInst(ty_op.operand); | 2763 | const ptr = try self.resolveInst(ty_op.operand); |
| ... | @@ -2746,7 +2766,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2746,7 +2766,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2746 | break :result MCValue.dead; | 2766 | break :result MCValue.dead; |
| 2747 | 2767 | ||
| 2748 | const dest_mcv: MCValue = blk: { | 2768 | const dest_mcv: MCValue = blk: { |
| 2749 | const ptr_fits_dest = elem_ty.abiSize(mod) <= 4; | 2769 | const ptr_fits_dest = elem_ty.abiSize(pt) <= 4; |
| 2750 | if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) { | 2770 | if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) { |
| 2751 | // The MCValue that holds the pointer can be re-used as the value. | 2771 | // The MCValue that holds the pointer can be re-used as the value. |
| 2752 | break :blk ptr; | 2772 | break :blk ptr; |
| ... | @@ -2762,8 +2782,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2762,8 +2782,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2762 | } | 2782 | } |
| 2763 | 2783 | ||
| 2764 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 2784 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 2765 | const mod = self.bin_file.comp.module.?; | 2785 | const pt = self.pt; |
| 2766 | const elem_size: u32 = @intCast(value_ty.abiSize(mod)); | 2786 | const elem_size: u32 = @intCast(value_ty.abiSize(pt)); |
| 2767 | 2787 | ||
| 2768 | switch (ptr) { | 2788 | switch (ptr) { |
| 2769 | .none => unreachable, | 2789 | .none => unreachable, |
| ... | @@ -2882,11 +2902,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -2882,11 +2902,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 2882 | 2902 | ||
| 2883 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 2903 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 2884 | return if (self.liveness.isUnused(inst)) .dead else result: { | 2904 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 2885 | const mod = self.bin_file.comp.module.?; | 2905 | const pt = self.pt; |
| 2906 | const mod = pt.zcu; | ||
| 2886 | const mcv = try self.resolveInst(operand); | 2907 | const mcv = try self.resolveInst(operand); |
| 2887 | const ptr_ty = self.typeOf(operand); | 2908 | const ptr_ty = self.typeOf(operand); |
| 2888 | const struct_ty = ptr_ty.childType(mod); | 2909 | const struct_ty = ptr_ty.childType(mod); |
| 2889 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod)); | 2910 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt)); |
| 2890 | switch (mcv) { | 2911 | switch (mcv) { |
| 2891 | .ptr_stack_offset => |off| { | 2912 | .ptr_stack_offset => |off| { |
| 2892 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; | 2913 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| ... | @@ -2906,11 +2927,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2906,11 +2927,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2906 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 2927 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 2907 | const operand = extra.struct_operand; | 2928 | const operand = extra.struct_operand; |
| 2908 | const index = extra.field_index; | 2929 | const index = extra.field_index; |
| 2909 | const mod = self.bin_file.comp.module.?; | 2930 | const pt = self.pt; |
| 2931 | const mod = pt.zcu; | ||
| 2910 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2932 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2911 | const mcv = try self.resolveInst(operand); | 2933 | const mcv = try self.resolveInst(operand); |
| 2912 | const struct_ty = self.typeOf(operand); | 2934 | const struct_ty = self.typeOf(operand); |
| 2913 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod)); | 2935 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt)); |
| 2914 | const struct_field_ty = struct_ty.structFieldType(index, mod); | 2936 | const struct_field_ty = struct_ty.structFieldType(index, mod); |
| 2915 | 2937 | ||
| 2916 | switch (mcv) { | 2938 | switch (mcv) { |
| ... | @@ -2974,7 +2996,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2974,7 +2996,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2974 | ); | 2996 | ); |
| 2975 | 2997 | ||
| 2976 | const field_bit_offset = struct_field_offset * 8; | 2998 | const field_bit_offset = struct_field_offset * 8; |
| 2977 | const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(mod) * 8); | 2999 | const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(pt) * 8); |
| 2978 | 3000 | ||
| 2979 | _ = try self.addInst(.{ | 3001 | _ = try self.addInst(.{ |
| 2980 | .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | 3002 | .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, |
| ... | @@ -2996,7 +3018,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2996,7 +3018,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2996 | } | 3018 | } |
| 2997 | 3019 | ||
| 2998 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | 3020 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2999 | const mod = self.bin_file.comp.module.?; | 3021 | const pt = self.pt; |
| 3022 | const mod = pt.zcu; | ||
| 3000 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3023 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3001 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 3024 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 3002 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 3025 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| ... | @@ -3007,7 +3030,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3007,7 +3030,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3007 | return self.fail("TODO implement @fieldParentPtr codegen for unions", .{}); | 3030 | return self.fail("TODO implement @fieldParentPtr codegen for unions", .{}); |
| 3008 | } | 3031 | } |
| 3009 | 3032 | ||
| 3010 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, mod)); | 3033 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, pt)); |
| 3011 | switch (field_ptr) { | 3034 | switch (field_ptr) { |
| 3012 | .ptr_stack_offset => |off| { | 3035 | .ptr_stack_offset => |off| { |
| 3013 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; | 3036 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; |
| ... | @@ -3390,7 +3413,8 @@ fn addSub( | ... | @@ -3390,7 +3413,8 @@ fn addSub( |
| 3390 | rhs_ty: Type, | 3413 | rhs_ty: Type, |
| 3391 | maybe_inst: ?Air.Inst.Index, | 3414 | maybe_inst: ?Air.Inst.Index, |
| 3392 | ) InnerError!MCValue { | 3415 | ) InnerError!MCValue { |
| 3393 | const mod = self.bin_file.comp.module.?; | 3416 | const pt = self.pt; |
| 3417 | const mod = pt.zcu; | ||
| 3394 | switch (lhs_ty.zigTypeTag(mod)) { | 3418 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3395 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3419 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3396 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3420 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3446,7 +3470,8 @@ fn mul( | ... | @@ -3446,7 +3470,8 @@ fn mul( |
| 3446 | rhs_ty: Type, | 3470 | rhs_ty: Type, |
| 3447 | maybe_inst: ?Air.Inst.Index, | 3471 | maybe_inst: ?Air.Inst.Index, |
| 3448 | ) InnerError!MCValue { | 3472 | ) InnerError!MCValue { |
| 3449 | const mod = self.bin_file.comp.module.?; | 3473 | const pt = self.pt; |
| 3474 | const mod = pt.zcu; | ||
| 3450 | switch (lhs_ty.zigTypeTag(mod)) { | 3475 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3451 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3476 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3452 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3477 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3479,7 +3504,8 @@ fn divFloat( | ... | @@ -3479,7 +3504,8 @@ fn divFloat( |
| 3479 | _ = rhs_ty; | 3504 | _ = rhs_ty; |
| 3480 | _ = maybe_inst; | 3505 | _ = maybe_inst; |
| 3481 | 3506 | ||
| 3482 | const mod = self.bin_file.comp.module.?; | 3507 | const pt = self.pt; |
| 3508 | const mod = pt.zcu; | ||
| 3483 | switch (lhs_ty.zigTypeTag(mod)) { | 3509 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3484 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3510 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3485 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3511 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3495,7 +3521,8 @@ fn divTrunc( | ... | @@ -3495,7 +3521,8 @@ fn divTrunc( |
| 3495 | rhs_ty: Type, | 3521 | rhs_ty: Type, |
| 3496 | maybe_inst: ?Air.Inst.Index, | 3522 | maybe_inst: ?Air.Inst.Index, |
| 3497 | ) InnerError!MCValue { | 3523 | ) InnerError!MCValue { |
| 3498 | const mod = self.bin_file.comp.module.?; | 3524 | const pt = self.pt; |
| 3525 | const mod = pt.zcu; | ||
| 3499 | switch (lhs_ty.zigTypeTag(mod)) { | 3526 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3500 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3527 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3501 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3528 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3538,7 +3565,8 @@ fn divFloor( | ... | @@ -3538,7 +3565,8 @@ fn divFloor( |
| 3538 | rhs_ty: Type, | 3565 | rhs_ty: Type, |
| 3539 | maybe_inst: ?Air.Inst.Index, | 3566 | maybe_inst: ?Air.Inst.Index, |
| 3540 | ) InnerError!MCValue { | 3567 | ) InnerError!MCValue { |
| 3541 | const mod = self.bin_file.comp.module.?; | 3568 | const pt = self.pt; |
| 3569 | const mod = pt.zcu; | ||
| 3542 | switch (lhs_ty.zigTypeTag(mod)) { | 3570 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3543 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3571 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3544 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3572 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3586,7 +3614,8 @@ fn divExact( | ... | @@ -3586,7 +3614,8 @@ fn divExact( |
| 3586 | _ = rhs_ty; | 3614 | _ = rhs_ty; |
| 3587 | _ = maybe_inst; | 3615 | _ = maybe_inst; |
| 3588 | 3616 | ||
| 3589 | const mod = self.bin_file.comp.module.?; | 3617 | const pt = self.pt; |
| 3618 | const mod = pt.zcu; | ||
| 3590 | switch (lhs_ty.zigTypeTag(mod)) { | 3619 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3591 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3620 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3592 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3621 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3603,7 +3632,8 @@ fn rem( | ... | @@ -3603,7 +3632,8 @@ fn rem( |
| 3603 | rhs_ty: Type, | 3632 | rhs_ty: Type, |
| 3604 | maybe_inst: ?Air.Inst.Index, | 3633 | maybe_inst: ?Air.Inst.Index, |
| 3605 | ) InnerError!MCValue { | 3634 | ) InnerError!MCValue { |
| 3606 | const mod = self.bin_file.comp.module.?; | 3635 | const pt = self.pt; |
| 3636 | const mod = pt.zcu; | ||
| 3607 | switch (lhs_ty.zigTypeTag(mod)) { | 3637 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3608 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3638 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3609 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3639 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3672,7 +3702,8 @@ fn modulo( | ... | @@ -3672,7 +3702,8 @@ fn modulo( |
| 3672 | _ = rhs_ty; | 3702 | _ = rhs_ty; |
| 3673 | _ = maybe_inst; | 3703 | _ = maybe_inst; |
| 3674 | 3704 | ||
| 3675 | const mod = self.bin_file.comp.module.?; | 3705 | const pt = self.pt; |
| 3706 | const mod = pt.zcu; | ||
| 3676 | switch (lhs_ty.zigTypeTag(mod)) { | 3707 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3677 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), | 3708 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3678 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3709 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | @@ -3690,7 +3721,8 @@ fn wrappingArithmetic( | ... | @@ -3690,7 +3721,8 @@ fn wrappingArithmetic( |
| 3690 | rhs_ty: Type, | 3721 | rhs_ty: Type, |
| 3691 | maybe_inst: ?Air.Inst.Index, | 3722 | maybe_inst: ?Air.Inst.Index, |
| 3692 | ) InnerError!MCValue { | 3723 | ) InnerError!MCValue { |
| 3693 | const mod = self.bin_file.comp.module.?; | 3724 | const pt = self.pt; |
| 3725 | const mod = pt.zcu; | ||
| 3694 | switch (lhs_ty.zigTypeTag(mod)) { | 3726 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3695 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3727 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3696 | .Int => { | 3728 | .Int => { |
| ... | @@ -3728,7 +3760,8 @@ fn bitwise( | ... | @@ -3728,7 +3760,8 @@ fn bitwise( |
| 3728 | rhs_ty: Type, | 3760 | rhs_ty: Type, |
| 3729 | maybe_inst: ?Air.Inst.Index, | 3761 | maybe_inst: ?Air.Inst.Index, |
| 3730 | ) InnerError!MCValue { | 3762 | ) InnerError!MCValue { |
| 3731 | const mod = self.bin_file.comp.module.?; | 3763 | const pt = self.pt; |
| 3764 | const mod = pt.zcu; | ||
| 3732 | switch (lhs_ty.zigTypeTag(mod)) { | 3765 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3733 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3766 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3734 | .Int => { | 3767 | .Int => { |
| ... | @@ -3773,7 +3806,8 @@ fn shiftExact( | ... | @@ -3773,7 +3806,8 @@ fn shiftExact( |
| 3773 | rhs_ty: Type, | 3806 | rhs_ty: Type, |
| 3774 | maybe_inst: ?Air.Inst.Index, | 3807 | maybe_inst: ?Air.Inst.Index, |
| 3775 | ) InnerError!MCValue { | 3808 | ) InnerError!MCValue { |
| 3776 | const mod = self.bin_file.comp.module.?; | 3809 | const pt = self.pt; |
| 3810 | const mod = pt.zcu; | ||
| 3777 | switch (lhs_ty.zigTypeTag(mod)) { | 3811 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3778 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3812 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3779 | .Int => { | 3813 | .Int => { |
| ... | @@ -3812,7 +3846,8 @@ fn shiftNormal( | ... | @@ -3812,7 +3846,8 @@ fn shiftNormal( |
| 3812 | rhs_ty: Type, | 3846 | rhs_ty: Type, |
| 3813 | maybe_inst: ?Air.Inst.Index, | 3847 | maybe_inst: ?Air.Inst.Index, |
| 3814 | ) InnerError!MCValue { | 3848 | ) InnerError!MCValue { |
| 3815 | const mod = self.bin_file.comp.module.?; | 3849 | const pt = self.pt; |
| 3850 | const mod = pt.zcu; | ||
| 3816 | switch (lhs_ty.zigTypeTag(mod)) { | 3851 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3817 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), | 3852 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3818 | .Int => { | 3853 | .Int => { |
| ... | @@ -3855,7 +3890,8 @@ fn booleanOp( | ... | @@ -3855,7 +3890,8 @@ fn booleanOp( |
| 3855 | rhs_ty: Type, | 3890 | rhs_ty: Type, |
| 3856 | maybe_inst: ?Air.Inst.Index, | 3891 | maybe_inst: ?Air.Inst.Index, |
| 3857 | ) InnerError!MCValue { | 3892 | ) InnerError!MCValue { |
| 3858 | const mod = self.bin_file.comp.module.?; | 3893 | const pt = self.pt; |
| 3894 | const mod = pt.zcu; | ||
| 3859 | switch (lhs_ty.zigTypeTag(mod)) { | 3895 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3860 | .Bool => { | 3896 | .Bool => { |
| 3861 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); | 3897 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| ... | @@ -3889,7 +3925,8 @@ fn ptrArithmetic( | ... | @@ -3889,7 +3925,8 @@ fn ptrArithmetic( |
| 3889 | rhs_ty: Type, | 3925 | rhs_ty: Type, |
| 3890 | maybe_inst: ?Air.Inst.Index, | 3926 | maybe_inst: ?Air.Inst.Index, |
| 3891 | ) InnerError!MCValue { | 3927 | ) InnerError!MCValue { |
| 3892 | const mod = self.bin_file.comp.module.?; | 3928 | const pt = self.pt; |
| 3929 | const mod = pt.zcu; | ||
| 3893 | switch (lhs_ty.zigTypeTag(mod)) { | 3930 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3894 | .Pointer => { | 3931 | .Pointer => { |
| 3895 | assert(rhs_ty.eql(Type.usize, mod)); | 3932 | assert(rhs_ty.eql(Type.usize, mod)); |
| ... | @@ -3899,7 +3936,7 @@ fn ptrArithmetic( | ... | @@ -3899,7 +3936,7 @@ fn ptrArithmetic( |
| 3899 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | 3936 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type |
| 3900 | else => ptr_ty.childType(mod), | 3937 | else => ptr_ty.childType(mod), |
| 3901 | }; | 3938 | }; |
| 3902 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); | 3939 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 3903 | 3940 | ||
| 3904 | const base_tag: Air.Inst.Tag = switch (tag) { | 3941 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 3905 | .ptr_add => .add, | 3942 | .ptr_add => .add, |
| ... | @@ -3926,8 +3963,9 @@ fn ptrArithmetic( | ... | @@ -3926,8 +3963,9 @@ fn ptrArithmetic( |
| 3926 | } | 3963 | } |
| 3927 | 3964 | ||
| 3928 | fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void { | 3965 | fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3929 | const mod = self.bin_file.comp.module.?; | 3966 | const pt = self.pt; |
| 3930 | const abi_size = ty.abiSize(mod); | 3967 | const mod = pt.zcu; |
| 3968 | const abi_size = ty.abiSize(pt); | ||
| 3931 | 3969 | ||
| 3932 | const tag: Mir.Inst.Tag = switch (abi_size) { | 3970 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3933 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, | 3971 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, |
| ... | @@ -3961,8 +3999,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) | ... | @@ -3961,8 +3999,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) |
| 3961 | } | 3999 | } |
| 3962 | 4000 | ||
| 3963 | fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void { | 4001 | fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3964 | const mod = self.bin_file.comp.module.?; | 4002 | const pt = self.pt; |
| 3965 | const abi_size = ty.abiSize(mod); | 4003 | const abi_size = ty.abiSize(pt); |
| 3966 | 4004 | ||
| 3967 | const tag: Mir.Inst.Tag = switch (abi_size) { | 4005 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3968 | 1 => .strb, | 4006 | 1 => .strb, |
| ... | @@ -4168,7 +4206,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4168,7 +4206,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4168 | while (self.args[arg_index] == .none) arg_index += 1; | 4206 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4169 | self.arg_index = arg_index + 1; | 4207 | self.arg_index = arg_index + 1; |
| 4170 | 4208 | ||
| 4171 | const mod = self.bin_file.comp.module.?; | 4209 | const pt = self.pt; |
| 4210 | const mod = pt.zcu; | ||
| 4172 | const ty = self.typeOfIndex(inst); | 4211 | const ty = self.typeOfIndex(inst); |
| 4173 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 4212 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4174 | const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; | 4213 | const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; |
| ... | @@ -4223,7 +4262,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4223,7 +4262,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4223 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 4262 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 4224 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); | 4263 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 4225 | const ty = self.typeOf(callee); | 4264 | const ty = self.typeOf(callee); |
| 4226 | const mod = self.bin_file.comp.module.?; | 4265 | const pt = self.pt; |
| 4266 | const mod = pt.zcu; | ||
| 4227 | 4267 | ||
| 4228 | const fn_ty = switch (ty.zigTypeTag(mod)) { | 4268 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 4229 | .Fn => ty, | 4269 | .Fn => ty, |
| ... | @@ -4253,11 +4293,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4253,11 +4293,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4253 | const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: { | 4293 | const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: { |
| 4254 | log.debug("airCall: return by reference", .{}); | 4294 | log.debug("airCall: return by reference", .{}); |
| 4255 | const ret_ty = fn_ty.fnReturnType(mod); | 4295 | const ret_ty = fn_ty.fnReturnType(mod); |
| 4256 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(mod)); | 4296 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 4257 | const ret_abi_align = ret_ty.abiAlignment(mod); | 4297 | const ret_abi_align = ret_ty.abiAlignment(pt); |
| 4258 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); | 4298 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); |
| 4259 | 4299 | ||
| 4260 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 4300 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 4261 | try self.register_manager.getReg(.r0, null); | 4301 | try self.register_manager.getReg(.r0, null); |
| 4262 | try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset }); | 4302 | try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset }); |
| 4263 | 4303 | ||
| ... | @@ -4293,7 +4333,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4293,7 +4333,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4293 | 4333 | ||
| 4294 | // Due to incremental compilation, how function calls are generated depends | 4334 | // Due to incremental compilation, how function calls are generated depends |
| 4295 | // on linking. | 4335 | // on linking. |
| 4296 | if (try self.air.value(callee, mod)) |func_value| { | 4336 | if (try self.air.value(callee, pt)) |func_value| { |
| 4297 | if (func_value.getFunction(mod)) |func| { | 4337 | if (func_value.getFunction(mod)) |func| { |
| 4298 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 4338 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 4299 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); | 4339 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); |
| ... | @@ -4374,7 +4414,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4374,7 +4414,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4374 | } | 4414 | } |
| 4375 | 4415 | ||
| 4376 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { | 4416 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4377 | const mod = self.bin_file.comp.module.?; | 4417 | const pt = self.pt; |
| 4418 | const mod = pt.zcu; | ||
| 4378 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4419 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4379 | const operand = try self.resolveInst(un_op); | 4420 | const operand = try self.resolveInst(un_op); |
| 4380 | const ret_ty = self.fn_type.fnReturnType(mod); | 4421 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | @@ -4393,7 +4434,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4393,7 +4434,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4393 | // | 4434 | // |
| 4394 | // self.ret_mcv is an address to where this function | 4435 | // self.ret_mcv is an address to where this function |
| 4395 | // should store its result into | 4436 | // should store its result into |
| 4396 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 4437 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 4397 | try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); | 4438 | try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); |
| 4398 | }, | 4439 | }, |
| 4399 | else => unreachable, // invalid return result | 4440 | else => unreachable, // invalid return result |
| ... | @@ -4406,7 +4447,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4406,7 +4447,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4406 | } | 4447 | } |
| 4407 | 4448 | ||
| 4408 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | 4449 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4409 | const mod = self.bin_file.comp.module.?; | 4450 | const pt = self.pt; |
| 4451 | const mod = pt.zcu; | ||
| 4410 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4452 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4411 | const ptr = try self.resolveInst(un_op); | 4453 | const ptr = try self.resolveInst(un_op); |
| 4412 | const ptr_ty = self.typeOf(un_op); | 4454 | const ptr_ty = self.typeOf(un_op); |
| ... | @@ -4430,8 +4472,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4430,8 +4472,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4430 | // location. | 4472 | // location. |
| 4431 | const op_inst = un_op.toIndex().?; | 4473 | const op_inst = un_op.toIndex().?; |
| 4432 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { | 4474 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { |
| 4433 | const abi_size: u32 = @intCast(ret_ty.abiSize(mod)); | 4475 | const abi_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 4434 | const abi_align = ret_ty.abiAlignment(mod); | 4476 | const abi_align = ret_ty.abiAlignment(pt); |
| 4435 | 4477 | ||
| 4436 | const offset = try self.allocMem(abi_size, abi_align, null); | 4478 | const offset = try self.allocMem(abi_size, abi_align, null); |
| 4437 | 4479 | ||
| ... | @@ -4467,11 +4509,12 @@ fn cmp( | ... | @@ -4467,11 +4509,12 @@ fn cmp( |
| 4467 | lhs_ty: Type, | 4509 | lhs_ty: Type, |
| 4468 | op: math.CompareOperator, | 4510 | op: math.CompareOperator, |
| 4469 | ) !MCValue { | 4511 | ) !MCValue { |
| 4470 | const mod = self.bin_file.comp.module.?; | 4512 | const pt = self.pt; |
| 4513 | const mod = pt.zcu; | ||
| 4471 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { | 4514 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { |
| 4472 | .Optional => blk: { | 4515 | .Optional => blk: { |
| 4473 | const payload_ty = lhs_ty.optionalChild(mod); | 4516 | const payload_ty = lhs_ty.optionalChild(mod); |
| 4474 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4517 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4475 | break :blk Type.u1; | 4518 | break :blk Type.u1; |
| 4476 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | 4519 | } else if (lhs_ty.isPtrLikeOptional(mod)) { |
| 4477 | break :blk Type.usize; | 4520 | break :blk Type.usize; |
| ... | @@ -4573,7 +4616,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4573,7 +4616,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4573 | } | 4616 | } |
| 4574 | 4617 | ||
| 4575 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | 4618 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4576 | const mod = self.bin_file.comp.module.?; | 4619 | const pt = self.pt; |
| 4620 | const mod = pt.zcu; | ||
| 4577 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4621 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4578 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 4622 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4579 | const func = mod.funcInfo(extra.data.func); | 4623 | const func = mod.funcInfo(extra.data.func); |
| ... | @@ -4785,9 +4829,10 @@ fn isNull( | ... | @@ -4785,9 +4829,10 @@ fn isNull( |
| 4785 | operand_bind: ReadArg.Bind, | 4829 | operand_bind: ReadArg.Bind, |
| 4786 | operand_ty: Type, | 4830 | operand_ty: Type, |
| 4787 | ) !MCValue { | 4831 | ) !MCValue { |
| 4788 | const mod = self.bin_file.comp.module.?; | 4832 | const pt = self.pt; |
| 4833 | const mod = pt.zcu; | ||
| 4789 | if (operand_ty.isPtrLikeOptional(mod)) { | 4834 | if (operand_ty.isPtrLikeOptional(mod)) { |
| 4790 | assert(operand_ty.abiSize(mod) == 4); | 4835 | assert(operand_ty.abiSize(pt) == 4); |
| 4791 | 4836 | ||
| 4792 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; | 4837 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; |
| 4793 | return self.cmp(operand_bind, imm_bind, Type.usize, .eq); | 4838 | return self.cmp(operand_bind, imm_bind, Type.usize, .eq); |
| ... | @@ -4819,7 +4864,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4819,7 +4864,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4819 | } | 4864 | } |
| 4820 | 4865 | ||
| 4821 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { | 4866 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4822 | const mod = self.bin_file.comp.module.?; | 4867 | const pt = self.pt; |
| 4868 | const mod = pt.zcu; | ||
| 4823 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4869 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4824 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4870 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4825 | const operand_ptr = try self.resolveInst(un_op); | 4871 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -4846,7 +4892,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4846,7 +4892,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4846 | } | 4892 | } |
| 4847 | 4893 | ||
| 4848 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { | 4894 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4849 | const mod = self.bin_file.comp.module.?; | 4895 | const pt = self.pt; |
| 4896 | const mod = pt.zcu; | ||
| 4850 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4897 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4851 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4898 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4852 | const operand_ptr = try self.resolveInst(un_op); | 4899 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -4866,7 +4913,8 @@ fn isErr( | ... | @@ -4866,7 +4913,8 @@ fn isErr( |
| 4866 | error_union_bind: ReadArg.Bind, | 4913 | error_union_bind: ReadArg.Bind, |
| 4867 | error_union_ty: Type, | 4914 | error_union_ty: Type, |
| 4868 | ) !MCValue { | 4915 | ) !MCValue { |
| 4869 | const mod = self.bin_file.comp.module.?; | 4916 | const pt = self.pt; |
| 4917 | const mod = pt.zcu; | ||
| 4870 | const error_type = error_union_ty.errorUnionSet(mod); | 4918 | const error_type = error_union_ty.errorUnionSet(mod); |
| 4871 | 4919 | ||
| 4872 | if (error_type.errorSetIsEmpty(mod)) { | 4920 | if (error_type.errorSetIsEmpty(mod)) { |
| ... | @@ -4908,7 +4956,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4908,7 +4956,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4908 | } | 4956 | } |
| 4909 | 4957 | ||
| 4910 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 4958 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4911 | const mod = self.bin_file.comp.module.?; | 4959 | const pt = self.pt; |
| 4960 | const mod = pt.zcu; | ||
| 4912 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4961 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4913 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4962 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4914 | const operand_ptr = try self.resolveInst(un_op); | 4963 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -4935,7 +4984,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4935,7 +4984,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4935 | } | 4984 | } |
| 4936 | 4985 | ||
| 4937 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 4986 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4938 | const mod = self.bin_file.comp.module.?; | 4987 | const pt = self.pt; |
| 4988 | const mod = pt.zcu; | ||
| 4939 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4989 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4940 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 4990 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4941 | const operand_ptr = try self.resolveInst(un_op); | 4991 | const operand_ptr = try self.resolveInst(un_op); |
| ... | @@ -5154,10 +5204,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5154,10 +5204,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5154 | } | 5204 | } |
| 5155 | 5205 | ||
| 5156 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { | 5206 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 5157 | const mod = self.bin_file.comp.module.?; | 5207 | const pt = self.pt; |
| 5158 | const block_data = self.blocks.getPtr(block).?; | 5208 | const block_data = self.blocks.getPtr(block).?; |
| 5159 | 5209 | ||
| 5160 | if (self.typeOf(operand).hasRuntimeBits(mod)) { | 5210 | if (self.typeOf(operand).hasRuntimeBits(pt)) { |
| 5161 | const operand_mcv = try self.resolveInst(operand); | 5211 | const operand_mcv = try self.resolveInst(operand); |
| 5162 | const block_mcv = block_data.mcv; | 5212 | const block_mcv = block_data.mcv; |
| 5163 | if (block_mcv == .none) { | 5213 | if (block_mcv == .none) { |
| ... | @@ -5325,8 +5375,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { | ... | @@ -5325,8 +5375,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5325 | } | 5375 | } |
| 5326 | 5376 | ||
| 5327 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { | 5377 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5328 | const mod = self.bin_file.comp.module.?; | 5378 | const pt = self.pt; |
| 5329 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 5379 | const mod = pt.zcu; |
| 5380 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | ||
| 5330 | switch (mcv) { | 5381 | switch (mcv) { |
| 5331 | .dead => unreachable, | 5382 | .dead => unreachable, |
| 5332 | .unreach, .none => return, // Nothing to do. | 5383 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -5407,7 +5458,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5407,7 +5458,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5407 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg }); | 5458 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg }); |
| 5408 | 5459 | ||
| 5409 | const overflow_bit_ty = ty.structFieldType(1, mod); | 5460 | const overflow_bit_ty = ty.structFieldType(1, mod); |
| 5410 | const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, mod)); | 5461 | const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, pt)); |
| 5411 | const cond_reg = try self.register_manager.allocReg(null, gp); | 5462 | const cond_reg = try self.register_manager.allocReg(null, gp); |
| 5412 | 5463 | ||
| 5413 | // C flag: movcs reg, #1 | 5464 | // C flag: movcs reg, #1 |
| ... | @@ -5445,7 +5496,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5445,7 +5496,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5445 | const reg = try self.copyToTmpRegister(ty, mcv); | 5496 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 5446 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 5497 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 5447 | } else { | 5498 | } else { |
| 5448 | const ptr_ty = try mod.singleMutPtrType(ty); | 5499 | const ptr_ty = try pt.singleMutPtrType(ty); |
| 5449 | 5500 | ||
| 5450 | // TODO call extern memcpy | 5501 | // TODO call extern memcpy |
| 5451 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); | 5502 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); |
| ... | @@ -5487,7 +5538,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -5487,7 +5538,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5487 | } | 5538 | } |
| 5488 | 5539 | ||
| 5489 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 5540 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 5490 | const mod = self.bin_file.comp.module.?; | 5541 | const pt = self.pt; |
| 5542 | const mod = pt.zcu; | ||
| 5491 | switch (mcv) { | 5543 | switch (mcv) { |
| 5492 | .dead => unreachable, | 5544 | .dead => unreachable, |
| 5493 | .unreach, .none => return, // Nothing to do. | 5545 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -5662,7 +5714,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5662,7 +5714,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5662 | }, | 5714 | }, |
| 5663 | .stack_offset => |off| { | 5715 | .stack_offset => |off| { |
| 5664 | // TODO: maybe addressing from sp instead of fp | 5716 | // TODO: maybe addressing from sp instead of fp |
| 5665 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 5717 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 5666 | 5718 | ||
| 5667 | const tag: Mir.Inst.Tag = switch (abi_size) { | 5719 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5668 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, | 5720 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, |
| ... | @@ -5713,7 +5765,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5713,7 +5765,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5713 | } | 5765 | } |
| 5714 | }, | 5766 | }, |
| 5715 | .stack_argument_offset => |off| { | 5767 | .stack_argument_offset => |off| { |
| 5716 | const abi_size = ty.abiSize(mod); | 5768 | const abi_size = ty.abiSize(pt); |
| 5717 | 5769 | ||
| 5718 | const tag: Mir.Inst.Tag = switch (abi_size) { | 5770 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5719 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, | 5771 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, |
| ... | @@ -5734,8 +5786,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5734,8 +5786,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5734 | } | 5786 | } |
| 5735 | 5787 | ||
| 5736 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { | 5788 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5737 | const mod = self.bin_file.comp.module.?; | 5789 | const pt = self.pt; |
| 5738 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 5790 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 5739 | switch (mcv) { | 5791 | switch (mcv) { |
| 5740 | .dead => unreachable, | 5792 | .dead => unreachable, |
| 5741 | .none, .unreach => return, | 5793 | .none, .unreach => return, |
| ... | @@ -5802,7 +5854,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -5802,7 +5854,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 5802 | const reg = try self.copyToTmpRegister(ty, mcv); | 5854 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 5803 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); | 5855 | return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); |
| 5804 | } else { | 5856 | } else { |
| 5805 | const ptr_ty = try mod.singleMutPtrType(ty); | 5857 | const ptr_ty = try pt.singleMutPtrType(ty); |
| 5806 | 5858 | ||
| 5807 | // TODO call extern memcpy | 5859 | // TODO call extern memcpy |
| 5808 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); | 5860 | const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); |
| ... | @@ -5890,7 +5942,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5890,7 +5942,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5890 | } | 5942 | } |
| 5891 | 5943 | ||
| 5892 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | 5944 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5893 | const mod = self.bin_file.comp.module.?; | 5945 | const pt = self.pt; |
| 5946 | const mod = pt.zcu; | ||
| 5894 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5947 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5895 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 5948 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5896 | const ptr_ty = self.typeOf(ty_op.operand); | 5949 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -6009,7 +6062,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6009,7 +6062,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6009 | } | 6062 | } |
| 6010 | 6063 | ||
| 6011 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 6064 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6012 | const mod = self.bin_file.comp.module.?; | 6065 | const pt = self.pt; |
| 6066 | const mod = pt.zcu; | ||
| 6013 | const vector_ty = self.typeOfIndex(inst); | 6067 | const vector_ty = self.typeOfIndex(inst); |
| 6014 | const len = vector_ty.vectorLen(mod); | 6068 | const len = vector_ty.vectorLen(mod); |
| 6015 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6069 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -6054,15 +6108,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6054,15 +6108,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 6054 | } | 6108 | } |
| 6055 | 6109 | ||
| 6056 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { | 6110 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 6111 | const pt = self.pt; | ||
| 6057 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6112 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6058 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 6113 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| 6059 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 6114 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 6060 | const result: MCValue = result: { | 6115 | const result: MCValue = result: { |
| 6061 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; | 6116 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; |
| 6062 | const error_union_ty = self.typeOf(pl_op.operand); | 6117 | const error_union_ty = self.typeOf(pl_op.operand); |
| 6063 | const mod = self.bin_file.comp.module.?; | 6118 | const error_union_size: u32 = @intCast(error_union_ty.abiSize(pt)); |
| 6064 | const error_union_size: u32 = @intCast(error_union_ty.abiSize(mod)); | 6119 | const error_union_align = error_union_ty.abiAlignment(pt); |
| 6065 | const error_union_align = error_union_ty.abiAlignment(mod); | ||
| 6066 | 6120 | ||
| 6067 | // The error union will die in the body. However, we need the | 6121 | // The error union will die in the body. However, we need the |
| 6068 | // error union after the body in order to extract the payload | 6122 | // error union after the body in order to extract the payload |
| ... | @@ -6091,14 +6145,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6091,14 +6145,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6091 | } | 6145 | } |
| 6092 | 6146 | ||
| 6093 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | 6147 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6094 | const mod = self.bin_file.comp.module.?; | 6148 | const pt = self.pt; |
| 6149 | const mod = pt.zcu; | ||
| 6095 | 6150 | ||
| 6096 | // If the type has no codegen bits, no need to store it. | 6151 | // If the type has no codegen bits, no need to store it. |
| 6097 | const inst_ty = self.typeOf(inst); | 6152 | const inst_ty = self.typeOf(inst); |
| 6098 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) | 6153 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod)) |
| 6099 | return MCValue{ .none = {} }; | 6154 | return MCValue{ .none = {} }; |
| 6100 | 6155 | ||
| 6101 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?); | 6156 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?); |
| 6102 | 6157 | ||
| 6103 | return self.getResolvedInstValue(inst_index); | 6158 | return self.getResolvedInstValue(inst_index); |
| 6104 | } | 6159 | } |
| ... | @@ -6116,12 +6171,13 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -6116,12 +6171,13 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 6116 | } | 6171 | } |
| 6117 | 6172 | ||
| 6118 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | 6173 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 6119 | const mod = self.bin_file.comp.module.?; | 6174 | const pt = self.pt; |
| 6120 | const mcv: MCValue = switch (try codegen.genTypedValue( | 6175 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 6121 | self.bin_file, | 6176 | self.bin_file, |
| 6177 | pt, | ||
| 6122 | self.src_loc, | 6178 | self.src_loc, |
| 6123 | val, | 6179 | val, |
| 6124 | mod.funcOwnerDeclIndex(self.func_index), | 6180 | pt.zcu.funcOwnerDeclIndex(self.func_index), |
| 6125 | )) { | 6181 | )) { |
| 6126 | .mcv => |mcv| switch (mcv) { | 6182 | .mcv => |mcv| switch (mcv) { |
| 6127 | .none => .none, | 6183 | .none => .none, |
| ... | @@ -6152,7 +6208,8 @@ const CallMCValues = struct { | ... | @@ -6152,7 +6208,8 @@ const CallMCValues = struct { |
| 6152 | 6208 | ||
| 6153 | /// Caller must call `CallMCValues.deinit`. | 6209 | /// Caller must call `CallMCValues.deinit`. |
| 6154 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | 6210 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6155 | const mod = self.bin_file.comp.module.?; | 6211 | const pt = self.pt; |
| 6212 | const mod = pt.zcu; | ||
| 6156 | const ip = &mod.intern_pool; | 6213 | const ip = &mod.intern_pool; |
| 6157 | const fn_info = mod.typeToFunc(fn_ty).?; | 6214 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 6158 | const cc = fn_info.cc; | 6215 | const cc = fn_info.cc; |
| ... | @@ -6182,10 +6239,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6182,10 +6239,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6182 | 6239 | ||
| 6183 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 6240 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 6184 | result.return_value = .{ .unreach = {} }; | 6241 | result.return_value = .{ .unreach = {} }; |
| 6185 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6242 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6186 | result.return_value = .{ .none = {} }; | 6243 | result.return_value = .{ .none = {} }; |
| 6187 | } else { | 6244 | } else { |
| 6188 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod)); | 6245 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 6189 | // TODO handle cases where multiple registers are used | 6246 | // TODO handle cases where multiple registers are used |
| 6190 | if (ret_ty_size <= 4) { | 6247 | if (ret_ty_size <= 4) { |
| 6191 | result.return_value = .{ .register = c_abi_int_return_regs[0] }; | 6248 | result.return_value = .{ .register = c_abi_int_return_regs[0] }; |
| ... | @@ -6200,10 +6257,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6200,10 +6257,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6200 | } | 6257 | } |
| 6201 | 6258 | ||
| 6202 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { | 6259 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6203 | if (Type.fromInterned(ty).abiAlignment(mod) == .@"8") | 6260 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") |
| 6204 | ncrn = std.mem.alignForward(usize, ncrn, 2); | 6261 | ncrn = std.mem.alignForward(usize, ncrn, 2); |
| 6205 | 6262 | ||
| 6206 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod)); | 6263 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); |
| 6207 | if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) { | 6264 | if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) { |
| 6208 | if (param_size <= 4) { | 6265 | if (param_size <= 4) { |
| 6209 | result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] }; | 6266 | result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] }; |
| ... | @@ -6215,7 +6272,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6215,7 +6272,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6215 | return self.fail("TODO MCValues split between registers and stack", .{}); | 6272 | return self.fail("TODO MCValues split between registers and stack", .{}); |
| 6216 | } else { | 6273 | } else { |
| 6217 | ncrn = 4; | 6274 | ncrn = 4; |
| 6218 | if (Type.fromInterned(ty).abiAlignment(mod) == .@"8") | 6275 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") |
| 6219 | nsaa = std.mem.alignForward(u32, nsaa, 8); | 6276 | nsaa = std.mem.alignForward(u32, nsaa, 8); |
| 6220 | 6277 | ||
| 6221 | result_arg.* = .{ .stack_argument_offset = nsaa }; | 6278 | result_arg.* = .{ .stack_argument_offset = nsaa }; |
| ... | @@ -6229,10 +6286,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6229,10 +6286,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6229 | .Unspecified => { | 6286 | .Unspecified => { |
| 6230 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 6287 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 6231 | result.return_value = .{ .unreach = {} }; | 6288 | result.return_value = .{ .unreach = {} }; |
| 6232 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) { | 6289 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { |
| 6233 | result.return_value = .{ .none = {} }; | 6290 | result.return_value = .{ .none = {} }; |
| 6234 | } else { | 6291 | } else { |
| 6235 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod)); | 6292 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 6236 | if (ret_ty_size == 0) { | 6293 | if (ret_ty_size == 0) { |
| 6237 | assert(ret_ty.isError(mod)); | 6294 | assert(ret_ty.isError(mod)); |
| 6238 | result.return_value = .{ .immediate = 0 }; | 6295 | result.return_value = .{ .immediate = 0 }; |
| ... | @@ -6250,9 +6307,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6250,9 +6307,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6250 | var stack_offset: u32 = 0; | 6307 | var stack_offset: u32 = 0; |
| 6251 | 6308 | ||
| 6252 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { | 6309 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6253 | if (Type.fromInterned(ty).abiSize(mod) > 0) { | 6310 | if (Type.fromInterned(ty).abiSize(pt) > 0) { |
| 6254 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod)); | 6311 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); |
| 6255 | const param_alignment = Type.fromInterned(ty).abiAlignment(mod); | 6312 | const param_alignment = Type.fromInterned(ty).abiAlignment(pt); |
| 6256 | 6313 | ||
| 6257 | stack_offset = @intCast(param_alignment.forward(stack_offset)); | 6314 | stack_offset = @intCast(param_alignment.forward(stack_offset)); |
| 6258 | result_arg.* = .{ .stack_argument_offset = stack_offset }; | 6315 | result_arg.* = .{ .stack_argument_offset = stack_offset }; |
| ... | @@ -6271,7 +6328,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6271,7 +6328,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6271 | return result; | 6328 | return result; |
| 6272 | } | 6329 | } |
| 6273 | 6330 | ||
| 6274 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. | 6331 | /// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`. |
| 6275 | fn wantSafety(self: *Self) bool { | 6332 | fn wantSafety(self: *Self) bool { |
| 6276 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | 6333 | return switch (self.bin_file.comp.root_mod.optimize_mode) { |
| 6277 | .Debug => true, | 6334 | .Debug => true, |
| ... | @@ -6305,11 +6362,9 @@ fn parseRegName(name: []const u8) ?Register { | ... | @@ -6305,11 +6362,9 @@ fn parseRegName(name: []const u8) ?Register { |
| 6305 | } | 6362 | } |
| 6306 | 6363 | ||
| 6307 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { | 6364 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 6308 | const mod = self.bin_file.comp.module.?; | 6365 | return self.air.typeOf(inst, &self.pt.zcu.intern_pool); |
| 6309 | return self.air.typeOf(inst, &mod.intern_pool); | ||
| 6310 | } | 6366 | } |
| 6311 | 6367 | ||
| 6312 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { | 6368 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 6313 | const mod = self.bin_file.comp.module.?; | 6369 | return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool); |
| 6314 | return self.air.typeOfIndex(inst, &mod.intern_pool); | ||
| 6315 | } | 6370 | } |
src/arch/arm/Emit.zig+2-4| ... | @@ -9,10 +9,8 @@ const Mir = @import("Mir.zig"); | ... | @@ -9,10 +9,8 @@ const Mir = @import("Mir.zig"); |
| 9 | const bits = @import("bits.zig"); | 9 | const bits = @import("bits.zig"); |
| 10 | const link = @import("../../link.zig"); | 10 | const link = @import("../../link.zig"); |
| 11 | const Zcu = @import("../../Zcu.zig"); | 11 | const Zcu = @import("../../Zcu.zig"); |
| 12 | /// Deprecated. | ||
| 13 | const Module = Zcu; | ||
| 14 | const Type = @import("../../Type.zig"); | 12 | const Type = @import("../../Type.zig"); |
| 15 | const ErrorMsg = Module.ErrorMsg; | 13 | const ErrorMsg = Zcu.ErrorMsg; |
| 16 | const Target = std.Target; | 14 | const Target = std.Target; |
| 17 | const assert = std.debug.assert; | 15 | const assert = std.debug.assert; |
| 18 | const Instruction = bits.Instruction; | 16 | const Instruction = bits.Instruction; |
| ... | @@ -26,7 +24,7 @@ bin_file: *link.File, | ... | @@ -26,7 +24,7 @@ bin_file: *link.File, |
| 26 | debug_output: DebugInfoOutput, | 24 | debug_output: DebugInfoOutput, |
| 27 | target: *const std.Target, | 25 | target: *const std.Target, |
| 28 | err_msg: ?*ErrorMsg = null, | 26 | err_msg: ?*ErrorMsg = null, |
| 29 | src_loc: Module.LazySrcLoc, | 27 | src_loc: Zcu.LazySrcLoc, |
| 30 | code: *std.ArrayList(u8), | 28 | code: *std.ArrayList(u8), |
| 31 | 29 | ||
| 32 | prev_di_line: u32, | 30 | prev_di_line: u32, |
src/arch/arm/abi.zig+30-32| ... | @@ -5,8 +5,6 @@ const Register = bits.Register; | ... | @@ -5,8 +5,6 @@ const Register = bits.Register; |
| 5 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; | 5 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 6 | const Type = @import("../../Type.zig"); | 6 | const Type = @import("../../Type.zig"); |
| 7 | const Zcu = @import("../../Zcu.zig"); | 7 | const Zcu = @import("../../Zcu.zig"); |
| 8 | /// Deprecated. | ||
| 9 | const Module = Zcu; | ||
| 10 | 8 | ||
| 11 | pub const Class = union(enum) { | 9 | pub const Class = union(enum) { |
| 12 | memory, | 10 | memory, |
| ... | @@ -26,29 +24,29 @@ pub const Class = union(enum) { | ... | @@ -26,29 +24,29 @@ pub const Class = union(enum) { |
| 26 | 24 | ||
| 27 | pub const Context = enum { ret, arg }; | 25 | pub const Context = enum { ret, arg }; |
| 28 | 26 | ||
| 29 | pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { | 27 | pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class { |
| 30 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 28 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 31 | 29 | ||
| 32 | var maybe_float_bits: ?u16 = null; | 30 | var maybe_float_bits: ?u16 = null; |
| 33 | const max_byval_size = 512; | 31 | const max_byval_size = 512; |
| 34 | const ip = &mod.intern_pool; | 32 | const ip = &pt.zcu.intern_pool; |
| 35 | switch (ty.zigTypeTag(mod)) { | 33 | switch (ty.zigTypeTag(pt.zcu)) { |
| 36 | .Struct => { | 34 | .Struct => { |
| 37 | const bit_size = ty.bitSize(mod); | 35 | const bit_size = ty.bitSize(pt); |
| 38 | if (ty.containerLayout(mod) == .@"packed") { | 36 | if (ty.containerLayout(pt.zcu) == .@"packed") { |
| 39 | if (bit_size > 64) return .memory; | 37 | if (bit_size > 64) return .memory; |
| 40 | return .byval; | 38 | return .byval; |
| 41 | } | 39 | } |
| 42 | if (bit_size > max_byval_size) return .memory; | 40 | if (bit_size > max_byval_size) return .memory; |
| 43 | const float_count = countFloats(ty, mod, &maybe_float_bits); | 41 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); |
| 44 | if (float_count <= byval_float_count) return .byval; | 42 | if (float_count <= byval_float_count) return .byval; |
| 45 | 43 | ||
| 46 | const fields = ty.structFieldCount(mod); | 44 | const fields = ty.structFieldCount(pt.zcu); |
| 47 | var i: u32 = 0; | 45 | var i: u32 = 0; |
| 48 | while (i < fields) : (i += 1) { | 46 | while (i < fields) : (i += 1) { |
| 49 | const field_ty = ty.structFieldType(i, mod); | 47 | const field_ty = ty.structFieldType(i, pt.zcu); |
| 50 | const field_alignment = ty.structFieldAlign(i, mod); | 48 | const field_alignment = ty.structFieldAlign(i, pt); |
| 51 | const field_size = field_ty.bitSize(mod); | 49 | const field_size = field_ty.bitSize(pt); |
| 52 | if (field_size > 32 or field_alignment.compare(.gt, .@"32")) { | 50 | if (field_size > 32 or field_alignment.compare(.gt, .@"32")) { |
| 53 | return Class.arrSize(bit_size, 64); | 51 | return Class.arrSize(bit_size, 64); |
| 54 | } | 52 | } |
| ... | @@ -56,19 +54,19 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { | ... | @@ -56,19 +54,19 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { |
| 56 | return Class.arrSize(bit_size, 32); | 54 | return Class.arrSize(bit_size, 32); |
| 57 | }, | 55 | }, |
| 58 | .Union => { | 56 | .Union => { |
| 59 | const bit_size = ty.bitSize(mod); | 57 | const bit_size = ty.bitSize(pt); |
| 60 | const union_obj = mod.typeToUnion(ty).?; | 58 | const union_obj = pt.zcu.typeToUnion(ty).?; |
| 61 | if (union_obj.getLayout(ip) == .@"packed") { | 59 | if (union_obj.getLayout(ip) == .@"packed") { |
| 62 | if (bit_size > 64) return .memory; | 60 | if (bit_size > 64) return .memory; |
| 63 | return .byval; | 61 | return .byval; |
| 64 | } | 62 | } |
| 65 | if (bit_size > max_byval_size) return .memory; | 63 | if (bit_size > max_byval_size) return .memory; |
| 66 | const float_count = countFloats(ty, mod, &maybe_float_bits); | 64 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); |
| 67 | if (float_count <= byval_float_count) return .byval; | 65 | if (float_count <= byval_float_count) return .byval; |
| 68 | 66 | ||
| 69 | for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| { | 67 | for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| { |
| 70 | if (Type.fromInterned(field_ty).bitSize(mod) > 32 or | 68 | if (Type.fromInterned(field_ty).bitSize(pt) > 32 or |
| 71 | mod.unionFieldNormalAlignment(union_obj, @intCast(field_index)).compare(.gt, .@"32")) | 69 | pt.unionFieldNormalAlignment(union_obj, @intCast(field_index)).compare(.gt, .@"32")) |
| 72 | { | 70 | { |
| 73 | return Class.arrSize(bit_size, 64); | 71 | return Class.arrSize(bit_size, 64); |
| 74 | } | 72 | } |
| ... | @@ -79,28 +77,28 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { | ... | @@ -79,28 +77,28 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { |
| 79 | .Int => { | 77 | .Int => { |
| 80 | // TODO this is incorrect for _BitInt(128) but implementing | 78 | // TODO this is incorrect for _BitInt(128) but implementing |
| 81 | // this correctly makes implementing compiler-rt impossible. | 79 | // this correctly makes implementing compiler-rt impossible. |
| 82 | // const bit_size = ty.bitSize(mod); | 80 | // const bit_size = ty.bitSize(pt); |
| 83 | // if (bit_size > 64) return .memory; | 81 | // if (bit_size > 64) return .memory; |
| 84 | return .byval; | 82 | return .byval; |
| 85 | }, | 83 | }, |
| 86 | .Enum, .ErrorSet => { | 84 | .Enum, .ErrorSet => { |
| 87 | const bit_size = ty.bitSize(mod); | 85 | const bit_size = ty.bitSize(pt); |
| 88 | if (bit_size > 64) return .memory; | 86 | if (bit_size > 64) return .memory; |
| 89 | return .byval; | 87 | return .byval; |
| 90 | }, | 88 | }, |
| 91 | .Vector => { | 89 | .Vector => { |
| 92 | const bit_size = ty.bitSize(mod); | 90 | const bit_size = ty.bitSize(pt); |
| 93 | // TODO is this controlled by a cpu feature? | 91 | // TODO is this controlled by a cpu feature? |
| 94 | if (ctx == .ret and bit_size > 128) return .memory; | 92 | if (ctx == .ret and bit_size > 128) return .memory; |
| 95 | if (bit_size > 512) return .memory; | 93 | if (bit_size > 512) return .memory; |
| 96 | return .byval; | 94 | return .byval; |
| 97 | }, | 95 | }, |
| 98 | .Optional => { | 96 | .Optional => { |
| 99 | assert(ty.isPtrLikeOptional(mod)); | 97 | assert(ty.isPtrLikeOptional(pt.zcu)); |
| 100 | return .byval; | 98 | return .byval; |
| 101 | }, | 99 | }, |
| 102 | .Pointer => { | 100 | .Pointer => { |
| 103 | assert(!ty.isSlice(mod)); | 101 | assert(!ty.isSlice(pt.zcu)); |
| 104 | return .byval; | 102 | return .byval; |
| 105 | }, | 103 | }, |
| 106 | .ErrorUnion, | 104 | .ErrorUnion, |
| ... | @@ -122,16 +120,16 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { | ... | @@ -122,16 +120,16 @@ pub fn classifyType(ty: Type, mod: *Module, ctx: Context) Class { |
| 122 | } | 120 | } |
| 123 | 121 | ||
| 124 | const byval_float_count = 4; | 122 | const byval_float_count = 4; |
| 125 | fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 { | 123 | fn countFloats(ty: Type, zcu: *Zcu, maybe_float_bits: *?u16) u32 { |
| 126 | const ip = &mod.intern_pool; | 124 | const ip = &zcu.intern_pool; |
| 127 | const target = mod.getTarget(); | 125 | const target = zcu.getTarget(); |
| 128 | const invalid = std.math.maxInt(u32); | 126 | const invalid = std.math.maxInt(u32); |
| 129 | switch (ty.zigTypeTag(mod)) { | 127 | switch (ty.zigTypeTag(zcu)) { |
| 130 | .Union => { | 128 | .Union => { |
| 131 | const union_obj = mod.typeToUnion(ty).?; | 129 | const union_obj = zcu.typeToUnion(ty).?; |
| 132 | var max_count: u32 = 0; | 130 | var max_count: u32 = 0; |
| 133 | for (union_obj.field_types.get(ip)) |field_ty| { | 131 | for (union_obj.field_types.get(ip)) |field_ty| { |
| 134 | const field_count = countFloats(Type.fromInterned(field_ty), mod, maybe_float_bits); | 132 | const field_count = countFloats(Type.fromInterned(field_ty), zcu, maybe_float_bits); |
| 135 | if (field_count == invalid) return invalid; | 133 | if (field_count == invalid) return invalid; |
| 136 | if (field_count > max_count) max_count = field_count; | 134 | if (field_count > max_count) max_count = field_count; |
| 137 | if (max_count > byval_float_count) return invalid; | 135 | if (max_count > byval_float_count) return invalid; |
| ... | @@ -139,12 +137,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 { | ... | @@ -139,12 +137,12 @@ fn countFloats(ty: Type, mod: *Module, maybe_float_bits: *?u16) u32 { |
| 139 | return max_count; | 137 | return max_count; |
| 140 | }, | 138 | }, |
| 141 | .Struct => { | 139 | .Struct => { |
| 142 | const fields_len = ty.structFieldCount(mod); | 140 | const fields_len = ty.structFieldCount(zcu); |
| 143 | var count: u32 = 0; | 141 | var count: u32 = 0; |
| 144 | var i: u32 = 0; | 142 | var i: u32 = 0; |
| 145 | while (i < fields_len) : (i += 1) { | 143 | while (i < fields_len) : (i += 1) { |
| 146 | const field_ty = ty.structFieldType(i, mod); | 144 | const field_ty = ty.structFieldType(i, zcu); |
| 147 | const field_count = countFloats(field_ty, mod, maybe_float_bits); | 145 | const field_count = countFloats(field_ty, zcu, maybe_float_bits); |
| 148 | if (field_count == invalid) return invalid; | 146 | if (field_count == invalid) return invalid; |
| 149 | count += field_count; | 147 | count += field_count; |
| 150 | if (count > byval_float_count) return invalid; | 148 | if (count > byval_float_count) return invalid; |
src/arch/riscv64/CodeGen.zig+267-216| ... | @@ -46,6 +46,7 @@ const RegisterLock = RegisterManager.RegisterLock; | ... | @@ -46,6 +46,7 @@ const RegisterLock = RegisterManager.RegisterLock; |
| 46 | const InnerError = CodeGenError || error{OutOfRegisters}; | 46 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 47 | 47 | ||
| 48 | gpa: Allocator, | 48 | gpa: Allocator, |
| 49 | pt: Zcu.PerThread, | ||
| 49 | air: Air, | 50 | air: Air, |
| 50 | mod: *Package.Module, | 51 | mod: *Package.Module, |
| 51 | liveness: Liveness, | 52 | liveness: Liveness, |
| ... | @@ -541,14 +542,14 @@ const FrameAlloc = struct { | ... | @@ -541,14 +542,14 @@ const FrameAlloc = struct { |
| 541 | .ref_count = 0, | 542 | .ref_count = 0, |
| 542 | }; | 543 | }; |
| 543 | } | 544 | } |
| 544 | fn initType(ty: Type, zcu: *Zcu) FrameAlloc { | 545 | fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc { |
| 545 | return init(.{ | 546 | return init(.{ |
| 546 | .size = ty.abiSize(zcu), | 547 | .size = ty.abiSize(pt), |
| 547 | .alignment = ty.abiAlignment(zcu), | 548 | .alignment = ty.abiAlignment(pt), |
| 548 | }); | 549 | }); |
| 549 | } | 550 | } |
| 550 | fn initSpill(ty: Type, zcu: *Zcu) FrameAlloc { | 551 | fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc { |
| 551 | const abi_size = ty.abiSize(zcu); | 552 | const abi_size = ty.abiSize(pt); |
| 552 | const spill_size = if (abi_size < 8) | 553 | const spill_size = if (abi_size < 8) |
| 553 | math.ceilPowerOfTwoAssert(u64, abi_size) | 554 | math.ceilPowerOfTwoAssert(u64, abi_size) |
| 554 | else | 555 | else |
| ... | @@ -556,7 +557,7 @@ const FrameAlloc = struct { | ... | @@ -556,7 +557,7 @@ const FrameAlloc = struct { |
| 556 | return init(.{ | 557 | return init(.{ |
| 557 | .size = spill_size, | 558 | .size = spill_size, |
| 558 | .pad = @intCast(spill_size - abi_size), | 559 | .pad = @intCast(spill_size - abi_size), |
| 559 | .alignment = ty.abiAlignment(zcu).maxStrict( | 560 | .alignment = ty.abiAlignment(pt).maxStrict( |
| 560 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), | 561 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), |
| 561 | ), | 562 | ), |
| 562 | }); | 563 | }); |
| ... | @@ -696,6 +697,7 @@ const CallView = enum(u1) { | ... | @@ -696,6 +697,7 @@ const CallView = enum(u1) { |
| 696 | 697 | ||
| 697 | pub fn generate( | 698 | pub fn generate( |
| 698 | bin_file: *link.File, | 699 | bin_file: *link.File, |
| 700 | pt: Zcu.PerThread, | ||
| 699 | src_loc: Zcu.LazySrcLoc, | 701 | src_loc: Zcu.LazySrcLoc, |
| 700 | func_index: InternPool.Index, | 702 | func_index: InternPool.Index, |
| 701 | air: Air, | 703 | air: Air, |
| ... | @@ -703,9 +705,9 @@ pub fn generate( | ... | @@ -703,9 +705,9 @@ pub fn generate( |
| 703 | code: *std.ArrayList(u8), | 705 | code: *std.ArrayList(u8), |
| 704 | debug_output: DebugInfoOutput, | 706 | debug_output: DebugInfoOutput, |
| 705 | ) CodeGenError!Result { | 707 | ) CodeGenError!Result { |
| 706 | const comp = bin_file.comp; | 708 | const zcu = pt.zcu; |
| 707 | const gpa = comp.gpa; | 709 | const comp = zcu.comp; |
| 708 | const zcu = comp.module.?; | 710 | const gpa = zcu.gpa; |
| 709 | const ip = &zcu.intern_pool; | 711 | const ip = &zcu.intern_pool; |
| 710 | const func = zcu.funcInfo(func_index); | 712 | const func = zcu.funcInfo(func_index); |
| 711 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 713 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| ... | @@ -726,6 +728,7 @@ pub fn generate( | ... | @@ -726,6 +728,7 @@ pub fn generate( |
| 726 | var function = Func{ | 728 | var function = Func{ |
| 727 | .gpa = gpa, | 729 | .gpa = gpa, |
| 728 | .air = air, | 730 | .air = air, |
| 731 | .pt = pt, | ||
| 729 | .mod = mod, | 732 | .mod = mod, |
| 730 | .liveness = liveness, | 733 | .liveness = liveness, |
| 731 | .target = target, | 734 | .target = target, |
| ... | @@ -787,11 +790,11 @@ pub fn generate( | ... | @@ -787,11 +790,11 @@ pub fn generate( |
| 787 | function.args = call_info.args; | 790 | function.args = call_info.args; |
| 788 | function.ret_mcv = call_info.return_value; | 791 | function.ret_mcv = call_info.return_value; |
| 789 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ | 792 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ |
| 790 | .size = Type.usize.abiSize(zcu), | 793 | .size = Type.usize.abiSize(pt), |
| 791 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), | 794 | .alignment = Type.usize.abiAlignment(pt).min(call_info.stack_align), |
| 792 | })); | 795 | })); |
| 793 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ | 796 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 794 | .size = Type.usize.abiSize(zcu), | 797 | .size = Type.usize.abiSize(pt), |
| 795 | .alignment = Alignment.min( | 798 | .alignment = Alignment.min( |
| 796 | call_info.stack_align, | 799 | call_info.stack_align, |
| 797 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), | 800 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), |
| ... | @@ -803,7 +806,7 @@ pub fn generate( | ... | @@ -803,7 +806,7 @@ pub fn generate( |
| 803 | })); | 806 | })); |
| 804 | function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{ | 807 | function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{ |
| 805 | .size = 0, | 808 | .size = 0, |
| 806 | .alignment = Type.usize.abiAlignment(zcu), | 809 | .alignment = Type.usize.abiAlignment(pt), |
| 807 | })); | 810 | })); |
| 808 | 811 | ||
| 809 | function.gen() catch |err| switch (err) { | 812 | function.gen() catch |err| switch (err) { |
| ... | @@ -821,9 +824,10 @@ pub fn generate( | ... | @@ -821,9 +824,10 @@ pub fn generate( |
| 821 | }; | 824 | }; |
| 822 | defer mir.deinit(gpa); | 825 | defer mir.deinit(gpa); |
| 823 | 826 | ||
| 824 | var emit = Emit{ | 827 | var emit: Emit = .{ |
| 828 | .bin_file = bin_file, | ||
| 825 | .lower = .{ | 829 | .lower = .{ |
| 826 | .bin_file = bin_file, | 830 | .pt = pt, |
| 827 | .allocator = gpa, | 831 | .allocator = gpa, |
| 828 | .mir = mir, | 832 | .mir = mir, |
| 829 | .cc = fn_info.cc, | 833 | .cc = fn_info.cc, |
| ... | @@ -875,10 +879,10 @@ fn formatWipMir( | ... | @@ -875,10 +879,10 @@ fn formatWipMir( |
| 875 | _: std.fmt.FormatOptions, | 879 | _: std.fmt.FormatOptions, |
| 876 | writer: anytype, | 880 | writer: anytype, |
| 877 | ) @TypeOf(writer).Error!void { | 881 | ) @TypeOf(writer).Error!void { |
| 878 | const comp = data.func.bin_file.comp; | 882 | const pt = data.func.pt; |
| 879 | const mod = comp.root_mod; | 883 | const comp = pt.zcu.comp; |
| 880 | var lower = Lower{ | 884 | var lower: Lower = .{ |
| 881 | .bin_file = data.func.bin_file, | 885 | .pt = pt, |
| 882 | .allocator = data.func.gpa, | 886 | .allocator = data.func.gpa, |
| 883 | .mir = .{ | 887 | .mir = .{ |
| 884 | .instructions = data.func.mir_instructions.slice(), | 888 | .instructions = data.func.mir_instructions.slice(), |
| ... | @@ -889,7 +893,7 @@ fn formatWipMir( | ... | @@ -889,7 +893,7 @@ fn formatWipMir( |
| 889 | .src_loc = data.func.src_loc, | 893 | .src_loc = data.func.src_loc, |
| 890 | .output_mode = comp.config.output_mode, | 894 | .output_mode = comp.config.output_mode, |
| 891 | .link_mode = comp.config.link_mode, | 895 | .link_mode = comp.config.link_mode, |
| 892 | .pic = mod.pic, | 896 | .pic = comp.root_mod.pic, |
| 893 | }; | 897 | }; |
| 894 | var first = true; | 898 | var first = true; |
| 895 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { | 899 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
| ... | @@ -933,7 +937,7 @@ fn formatDecl( | ... | @@ -933,7 +937,7 @@ fn formatDecl( |
| 933 | } | 937 | } |
| 934 | fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { | 938 | fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { |
| 935 | return .{ .data = .{ | 939 | return .{ .data = .{ |
| 936 | .mod = func.bin_file.comp.module.?, | 940 | .mod = func.pt.zcu, |
| 937 | .decl_index = decl_index, | 941 | .decl_index = decl_index, |
| 938 | } }; | 942 | } }; |
| 939 | } | 943 | } |
| ... | @@ -950,7 +954,7 @@ fn formatAir( | ... | @@ -950,7 +954,7 @@ fn formatAir( |
| 950 | ) @TypeOf(writer).Error!void { | 954 | ) @TypeOf(writer).Error!void { |
| 951 | @import("../../print_air.zig").dumpInst( | 955 | @import("../../print_air.zig").dumpInst( |
| 952 | data.inst, | 956 | data.inst, |
| 953 | data.func.bin_file.comp.module.?, | 957 | data.func.pt, |
| 954 | data.func.air, | 958 | data.func.air, |
| 955 | data.func.liveness, | 959 | data.func.liveness, |
| 956 | ); | 960 | ); |
| ... | @@ -1044,8 +1048,9 @@ const required_features = [_]Target.riscv.Feature{ | ... | @@ -1044,8 +1048,9 @@ const required_features = [_]Target.riscv.Feature{ |
| 1044 | }; | 1048 | }; |
| 1045 | 1049 | ||
| 1046 | fn gen(func: *Func) !void { | 1050 | fn gen(func: *Func) !void { |
| 1047 | const mod = func.bin_file.comp.module.?; | 1051 | const pt = func.pt; |
| 1048 | const fn_info = mod.typeToFunc(func.fn_type).?; | 1052 | const zcu = pt.zcu; |
| 1053 | const fn_info = zcu.typeToFunc(func.fn_type).?; | ||
| 1049 | 1054 | ||
| 1050 | inline for (required_features) |feature| { | 1055 | inline for (required_features) |feature| { |
| 1051 | if (!func.hasFeature(feature)) { | 1056 | if (!func.hasFeature(feature)) { |
| ... | @@ -1071,7 +1076,7 @@ fn gen(func: *Func) !void { | ... | @@ -1071,7 +1076,7 @@ fn gen(func: *Func) !void { |
| 1071 | // The address where to store the return value for the caller is in a | 1076 | // The address where to store the return value for the caller is in a |
| 1072 | // register which the callee is free to clobber. Therefore, we purposely | 1077 | // register which the callee is free to clobber. Therefore, we purposely |
| 1073 | // spill it to stack immediately. | 1078 | // spill it to stack immediately. |
| 1074 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.usize, mod)); | 1079 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.usize, pt)); |
| 1075 | try func.genSetMem( | 1080 | try func.genSetMem( |
| 1076 | .{ .frame = frame_index }, | 1081 | .{ .frame = frame_index }, |
| 1077 | 0, | 1082 | 0, |
| ... | @@ -1205,7 +1210,8 @@ fn gen(func: *Func) !void { | ... | @@ -1205,7 +1210,8 @@ fn gen(func: *Func) !void { |
| 1205 | } | 1210 | } |
| 1206 | 1211 | ||
| 1207 | fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | 1212 | fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1208 | const zcu = func.bin_file.comp.module.?; | 1213 | const pt = func.pt; |
| 1214 | const zcu = pt.zcu; | ||
| 1209 | const ip = &zcu.intern_pool; | 1215 | const ip = &zcu.intern_pool; |
| 1210 | const air_tags = func.air.instructions.items(.tag); | 1216 | const air_tags = func.air.instructions.items(.tag); |
| 1211 | 1217 | ||
| ... | @@ -1672,44 +1678,46 @@ fn ensureProcessDeathCapacity(func: *Func, additional_count: usize) !void { | ... | @@ -1672,44 +1678,46 @@ fn ensureProcessDeathCapacity(func: *Func, additional_count: usize) !void { |
| 1672 | } | 1678 | } |
| 1673 | 1679 | ||
| 1674 | fn memSize(func: *Func, ty: Type) Memory.Size { | 1680 | fn memSize(func: *Func, ty: Type) Memory.Size { |
| 1675 | const mod = func.bin_file.comp.module.?; | 1681 | const pt = func.pt; |
| 1676 | return switch (ty.zigTypeTag(mod)) { | 1682 | const zcu = pt.zcu; |
| 1683 | return switch (ty.zigTypeTag(zcu)) { | ||
| 1677 | .Float => Memory.Size.fromBitSize(ty.floatBits(func.target.*)), | 1684 | .Float => Memory.Size.fromBitSize(ty.floatBits(func.target.*)), |
| 1678 | else => Memory.Size.fromByteSize(ty.abiSize(mod)), | 1685 | else => Memory.Size.fromByteSize(ty.abiSize(pt)), |
| 1679 | }; | 1686 | }; |
| 1680 | } | 1687 | } |
| 1681 | 1688 | ||
| 1682 | fn splitType(func: *Func, ty: Type) ![2]Type { | 1689 | fn splitType(func: *Func, ty: Type) ![2]Type { |
| 1683 | const zcu = func.bin_file.comp.module.?; | 1690 | const pt = func.pt; |
| 1684 | const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none); | 1691 | const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none); |
| 1685 | var parts: [2]Type = undefined; | 1692 | var parts: [2]Type = undefined; |
| 1686 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { | 1693 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { |
| 1687 | part.* = switch (class) { | 1694 | part.* = switch (class) { |
| 1688 | .integer => switch (part_i) { | 1695 | .integer => switch (part_i) { |
| 1689 | 0 => Type.u64, | 1696 | 0 => Type.u64, |
| 1690 | 1 => part: { | 1697 | 1 => part: { |
| 1691 | const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?; | 1698 | const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?; |
| 1692 | const elem_ty = try zcu.intType(.unsigned, @intCast(elem_size * 8)); | 1699 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); |
| 1693 | break :part switch (@divExact(ty.abiSize(zcu) - 8, elem_size)) { | 1700 | break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) { |
| 1694 | 1 => elem_ty, | 1701 | 1 => elem_ty, |
| 1695 | else => |len| try zcu.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), | 1702 | else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), |
| 1696 | }; | 1703 | }; |
| 1697 | }, | 1704 | }, |
| 1698 | else => unreachable, | 1705 | else => unreachable, |
| 1699 | }, | 1706 | }, |
| 1700 | else => return func.fail("TODO: splitType class {}", .{class}), | 1707 | else => return func.fail("TODO: splitType class {}", .{class}), |
| 1701 | }; | 1708 | }; |
| 1702 | } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts; | 1709 | } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts; |
| 1703 | return func.fail("TODO implement splitType for {}", .{ty.fmt(zcu)}); | 1710 | return func.fail("TODO implement splitType for {}", .{ty.fmt(pt)}); |
| 1704 | } | 1711 | } |
| 1705 | 1712 | ||
| 1706 | /// Truncates the value in the register in place. | 1713 | /// Truncates the value in the register in place. |
| 1707 | /// Clobbers any remaining bits. | 1714 | /// Clobbers any remaining bits. |
| 1708 | fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { | 1715 | fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { |
| 1709 | const mod = func.bin_file.comp.module.?; | 1716 | const pt = func.pt; |
| 1710 | const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ | 1717 | const zcu = pt.zcu; |
| 1718 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ | ||
| 1711 | .signedness = .unsigned, | 1719 | .signedness = .unsigned, |
| 1712 | .bits = @intCast(ty.bitSize(mod)), | 1720 | .bits = @intCast(ty.bitSize(pt)), |
| 1713 | }; | 1721 | }; |
| 1714 | const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; | 1722 | const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; |
| 1715 | switch (int_info.signedness) { | 1723 | switch (int_info.signedness) { |
| ... | @@ -1780,7 +1788,8 @@ fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { | ... | @@ -1780,7 +1788,8 @@ fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { |
| 1780 | } | 1788 | } |
| 1781 | 1789 | ||
| 1782 | fn symbolIndex(func: *Func) !u32 { | 1790 | fn symbolIndex(func: *Func) !u32 { |
| 1783 | const zcu = func.bin_file.comp.module.?; | 1791 | const pt = func.pt; |
| 1792 | const zcu = pt.zcu; | ||
| 1784 | const decl_index = zcu.funcOwnerDeclIndex(func.func_index); | 1793 | const decl_index = zcu.funcOwnerDeclIndex(func.func_index); |
| 1785 | return switch (func.bin_file.tag) { | 1794 | return switch (func.bin_file.tag) { |
| 1786 | .elf => blk: { | 1795 | .elf => blk: { |
| ... | @@ -1817,19 +1826,21 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex { | ... | @@ -1817,19 +1826,21 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex { |
| 1817 | 1826 | ||
| 1818 | /// Use a pointer instruction as the basis for allocating stack memory. | 1827 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1819 | fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex { | 1828 | fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex { |
| 1820 | const zcu = func.bin_file.comp.module.?; | 1829 | const pt = func.pt; |
| 1830 | const zcu = pt.zcu; | ||
| 1821 | const ptr_ty = func.typeOfIndex(inst); | 1831 | const ptr_ty = func.typeOfIndex(inst); |
| 1822 | const val_ty = ptr_ty.childType(zcu); | 1832 | const val_ty = ptr_ty.childType(zcu); |
| 1823 | return func.allocFrameIndex(FrameAlloc.init(.{ | 1833 | return func.allocFrameIndex(FrameAlloc.init(.{ |
| 1824 | .size = math.cast(u32, val_ty.abiSize(zcu)) orelse { | 1834 | .size = math.cast(u32, val_ty.abiSize(pt)) orelse { |
| 1825 | return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(zcu)}); | 1835 | return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); |
| 1826 | }, | 1836 | }, |
| 1827 | .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"), | 1837 | .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"), |
| 1828 | })); | 1838 | })); |
| 1829 | } | 1839 | } |
| 1830 | 1840 | ||
| 1831 | fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass { | 1841 | fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass { |
| 1832 | const zcu = func.bin_file.comp.module.?; | 1842 | const pt = func.pt; |
| 1843 | const zcu = pt.zcu; | ||
| 1833 | return switch (ty.zigTypeTag(zcu)) { | 1844 | return switch (ty.zigTypeTag(zcu)) { |
| 1834 | .Float => .float, | 1845 | .Float => .float, |
| 1835 | .Vector => @panic("TODO: typeRegClass for Vectors"), | 1846 | .Vector => @panic("TODO: typeRegClass for Vectors"), |
| ... | @@ -1838,7 +1849,8 @@ fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass { | ... | @@ -1838,7 +1849,8 @@ fn typeRegClass(func: *Func, ty: Type) abi.RegisterClass { |
| 1838 | } | 1849 | } |
| 1839 | 1850 | ||
| 1840 | fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { | 1851 | fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { |
| 1841 | const zcu = func.bin_file.comp.module.?; | 1852 | const pt = func.pt; |
| 1853 | const zcu = pt.zcu; | ||
| 1842 | return switch (ty.zigTypeTag(zcu)) { | 1854 | return switch (ty.zigTypeTag(zcu)) { |
| 1843 | .Float => abi.Registers.Float.general_purpose, | 1855 | .Float => abi.Registers.Float.general_purpose, |
| 1844 | .Vector => @panic("TODO: regGeneralClassForType for Vectors"), | 1856 | .Vector => @panic("TODO: regGeneralClassForType for Vectors"), |
| ... | @@ -1847,7 +1859,8 @@ fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet | ... | @@ -1847,7 +1859,8 @@ fn regGeneralClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet |
| 1847 | } | 1859 | } |
| 1848 | 1860 | ||
| 1849 | fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { | 1861 | fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { |
| 1850 | const zcu = func.bin_file.comp.module.?; | 1862 | const pt = func.pt; |
| 1863 | const zcu = pt.zcu; | ||
| 1851 | return switch (ty.zigTypeTag(zcu)) { | 1864 | return switch (ty.zigTypeTag(zcu)) { |
| 1852 | .Float => abi.Registers.Float.temporary, | 1865 | .Float => abi.Registers.Float.temporary, |
| 1853 | .Vector => @panic("TODO: regTempClassForType for Vectors"), | 1866 | .Vector => @panic("TODO: regTempClassForType for Vectors"), |
| ... | @@ -1856,13 +1869,13 @@ fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { | ... | @@ -1856,13 +1869,13 @@ fn regTempClassForType(func: *Func, ty: Type) RegisterManager.RegisterBitSet { |
| 1856 | } | 1869 | } |
| 1857 | 1870 | ||
| 1858 | fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue { | 1871 | fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue { |
| 1859 | const zcu = func.bin_file.comp.module.?; | 1872 | const pt = func.pt; |
| 1860 | 1873 | ||
| 1861 | const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse { | 1874 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 1862 | return func.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(zcu)}); | 1875 | return func.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1863 | }; | 1876 | }; |
| 1864 | 1877 | ||
| 1865 | const min_size: u32 = switch (elem_ty.zigTypeTag(zcu)) { | 1878 | const min_size: u32 = switch (elem_ty.zigTypeTag(pt.zcu)) { |
| 1866 | .Float => 4, | 1879 | .Float => 4, |
| 1867 | .Vector => @panic("allocRegOrMem Vector"), | 1880 | .Vector => @panic("allocRegOrMem Vector"), |
| 1868 | else => 8, | 1881 | else => 8, |
| ... | @@ -1874,7 +1887,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool | ... | @@ -1874,7 +1887,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool |
| 1874 | } | 1887 | } |
| 1875 | } | 1888 | } |
| 1876 | 1889 | ||
| 1877 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, zcu)); | 1890 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, pt)); |
| 1878 | return .{ .load_frame = .{ .index = frame_index } }; | 1891 | return .{ .load_frame = .{ .index = frame_index } }; |
| 1879 | } | 1892 | } |
| 1880 | 1893 | ||
| ... | @@ -1955,7 +1968,7 @@ pub fn spillInstruction(func: *Func, reg: Register, inst: Air.Inst.Index) !void | ... | @@ -1955,7 +1968,7 @@ pub fn spillInstruction(func: *Func, reg: Register, inst: Air.Inst.Index) !void |
| 1955 | /// allocated. A second call to `copyToTmpRegister` may return the same register. | 1968 | /// allocated. A second call to `copyToTmpRegister` may return the same register. |
| 1956 | /// This can have a side effect of spilling instructions to the stack to free up a register. | 1969 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 1957 | fn copyToTmpRegister(func: *Func, ty: Type, mcv: MCValue) !Register { | 1970 | fn copyToTmpRegister(func: *Func, ty: Type, mcv: MCValue) !Register { |
| 1958 | log.debug("copyToTmpRegister ty: {}", .{ty.fmt(func.bin_file.comp.module.?)}); | 1971 | log.debug("copyToTmpRegister ty: {}", .{ty.fmt(func.pt)}); |
| 1959 | const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty)); | 1972 | const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty)); |
| 1960 | try func.genSetReg(ty, reg, mcv); | 1973 | try func.genSetReg(ty, reg, mcv); |
| 1961 | return reg; | 1974 | return reg; |
| ... | @@ -2004,7 +2017,8 @@ fn airFpext(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2004,7 +2017,8 @@ fn airFpext(func: *Func, inst: Air.Inst.Index) !void { |
| 2004 | } | 2017 | } |
| 2005 | 2018 | ||
| 2006 | fn airIntCast(func: *Func, inst: Air.Inst.Index) !void { | 2019 | fn airIntCast(func: *Func, inst: Air.Inst.Index) !void { |
| 2007 | const zcu = func.bin_file.comp.module.?; | 2020 | const pt = func.pt; |
| 2021 | const zcu = pt.zcu; | ||
| 2008 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2022 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2009 | const src_ty = func.typeOf(ty_op.operand); | 2023 | const src_ty = func.typeOf(ty_op.operand); |
| 2010 | const dst_ty = func.typeOfIndex(inst); | 2024 | const dst_ty = func.typeOfIndex(inst); |
| ... | @@ -2040,7 +2054,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2040,7 +2054,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void { |
| 2040 | 2054 | ||
| 2041 | break :result dst_mcv; | 2055 | break :result dst_mcv; |
| 2042 | } orelse return func.fail("TODO: implement airIntCast from {} to {}", .{ | 2056 | } orelse return func.fail("TODO: implement airIntCast from {} to {}", .{ |
| 2043 | src_ty.fmt(zcu), dst_ty.fmt(zcu), | 2057 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 2044 | }); | 2058 | }); |
| 2045 | 2059 | ||
| 2046 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2060 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -2067,7 +2081,8 @@ fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2067,7 +2081,8 @@ fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void { |
| 2067 | fn airNot(func: *Func, inst: Air.Inst.Index) !void { | 2081 | fn airNot(func: *Func, inst: Air.Inst.Index) !void { |
| 2068 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2082 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2069 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 2083 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 2070 | const zcu = func.bin_file.comp.module.?; | 2084 | const pt = func.pt; |
| 2085 | const zcu = pt.zcu; | ||
| 2071 | 2086 | ||
| 2072 | const operand = try func.resolveInst(ty_op.operand); | 2087 | const operand = try func.resolveInst(ty_op.operand); |
| 2073 | const ty = func.typeOf(ty_op.operand); | 2088 | const ty = func.typeOf(ty_op.operand); |
| ... | @@ -2106,12 +2121,12 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2106,12 +2121,12 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void { |
| 2106 | } | 2121 | } |
| 2107 | 2122 | ||
| 2108 | fn airSlice(func: *Func, inst: Air.Inst.Index) !void { | 2123 | fn airSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 2109 | const zcu = func.bin_file.comp.module.?; | 2124 | const pt = func.pt; |
| 2110 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2125 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2111 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; | 2126 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2112 | 2127 | ||
| 2113 | const slice_ty = func.typeOfIndex(inst); | 2128 | const slice_ty = func.typeOfIndex(inst); |
| 2114 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | 2129 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); |
| 2115 | 2130 | ||
| 2116 | const ptr_ty = func.typeOf(bin_op.lhs); | 2131 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 2117 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }); | 2132 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }); |
| ... | @@ -2119,7 +2134,7 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2119,7 +2134,7 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 2119 | const len_ty = func.typeOf(bin_op.rhs); | 2134 | const len_ty = func.typeOf(bin_op.rhs); |
| 2120 | try func.genSetMem( | 2135 | try func.genSetMem( |
| 2121 | .{ .frame = frame_index }, | 2136 | .{ .frame = frame_index }, |
| 2122 | @intCast(ptr_ty.abiSize(zcu)), | 2137 | @intCast(ptr_ty.abiSize(pt)), |
| 2123 | len_ty, | 2138 | len_ty, |
| 2124 | .{ .air_ref = bin_op.rhs }, | 2139 | .{ .air_ref = bin_op.rhs }, |
| 2125 | ); | 2140 | ); |
| ... | @@ -2129,14 +2144,15 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2129,14 +2144,15 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 2129 | } | 2144 | } |
| 2130 | 2145 | ||
| 2131 | fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | 2146 | fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 2132 | const zcu = func.bin_file.comp.module.?; | 2147 | const pt = func.pt; |
| 2148 | const zcu = pt.zcu; | ||
| 2133 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2149 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2134 | const dst_mcv = try func.binOp(inst, tag, bin_op.lhs, bin_op.rhs); | 2150 | const dst_mcv = try func.binOp(inst, tag, bin_op.lhs, bin_op.rhs); |
| 2135 | 2151 | ||
| 2136 | const dst_ty = func.typeOfIndex(inst); | 2152 | const dst_ty = func.typeOfIndex(inst); |
| 2137 | if (dst_ty.isAbiInt(zcu)) { | 2153 | if (dst_ty.isAbiInt(zcu)) { |
| 2138 | const abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | 2154 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 2139 | const bit_size: u32 = @intCast(dst_ty.bitSize(zcu)); | 2155 | const bit_size: u32 = @intCast(dst_ty.bitSize(pt)); |
| 2140 | if (abi_size * 8 > bit_size) { | 2156 | if (abi_size * 8 > bit_size) { |
| 2141 | const dst_lock = switch (dst_mcv) { | 2157 | const dst_lock = switch (dst_mcv) { |
| 2142 | .register => |dst_reg| func.register_manager.lockRegAssumeUnused(dst_reg), | 2158 | .register => |dst_reg| func.register_manager.lockRegAssumeUnused(dst_reg), |
| ... | @@ -2150,7 +2166,7 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | ... | @@ -2150,7 +2166,7 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 2150 | const tmp_reg, const tmp_lock = try func.allocReg(.int); | 2166 | const tmp_reg, const tmp_lock = try func.allocReg(.int); |
| 2151 | defer func.register_manager.unlockReg(tmp_lock); | 2167 | defer func.register_manager.unlockReg(tmp_lock); |
| 2152 | 2168 | ||
| 2153 | const hi_ty = try zcu.intType(.unsigned, @intCast((dst_ty.bitSize(zcu) - 1) % 64 + 1)); | 2169 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1)); |
| 2154 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); | 2170 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 2155 | try func.genSetReg(hi_ty, tmp_reg, hi_mcv); | 2171 | try func.genSetReg(hi_ty, tmp_reg, hi_mcv); |
| 2156 | try func.truncateRegister(dst_ty, tmp_reg); | 2172 | try func.truncateRegister(dst_ty, tmp_reg); |
| ... | @@ -2170,7 +2186,7 @@ fn binOp( | ... | @@ -2170,7 +2186,7 @@ fn binOp( |
| 2170 | rhs_air: Air.Inst.Ref, | 2186 | rhs_air: Air.Inst.Ref, |
| 2171 | ) !MCValue { | 2187 | ) !MCValue { |
| 2172 | _ = maybe_inst; | 2188 | _ = maybe_inst; |
| 2173 | const zcu = func.bin_file.comp.module.?; | 2189 | const pt = func.pt; |
| 2174 | const lhs_ty = func.typeOf(lhs_air); | 2190 | const lhs_ty = func.typeOf(lhs_air); |
| 2175 | const rhs_ty = func.typeOf(rhs_air); | 2191 | const rhs_ty = func.typeOf(rhs_air); |
| 2176 | 2192 | ||
| ... | @@ -2189,7 +2205,7 @@ fn binOp( | ... | @@ -2189,7 +2205,7 @@ fn binOp( |
| 2189 | return func.fail("binOp libcall runtime-float ops", .{}); | 2205 | return func.fail("binOp libcall runtime-float ops", .{}); |
| 2190 | } | 2206 | } |
| 2191 | 2207 | ||
| 2192 | if (lhs_ty.bitSize(zcu) > 64) return func.fail("TODO: binOp >= 64 bits", .{}); | 2208 | if (lhs_ty.bitSize(pt) > 64) return func.fail("TODO: binOp >= 64 bits", .{}); |
| 2193 | 2209 | ||
| 2194 | const lhs_mcv = try func.resolveInst(lhs_air); | 2210 | const lhs_mcv = try func.resolveInst(lhs_air); |
| 2195 | const rhs_mcv = try func.resolveInst(rhs_air); | 2211 | const rhs_mcv = try func.resolveInst(rhs_air); |
| ... | @@ -2237,8 +2253,9 @@ fn genBinOp( | ... | @@ -2237,8 +2253,9 @@ fn genBinOp( |
| 2237 | rhs_ty: Type, | 2253 | rhs_ty: Type, |
| 2238 | dst_reg: Register, | 2254 | dst_reg: Register, |
| 2239 | ) !void { | 2255 | ) !void { |
| 2240 | const zcu = func.bin_file.comp.module.?; | 2256 | const pt = func.pt; |
| 2241 | const bit_size = lhs_ty.bitSize(zcu); | 2257 | const zcu = pt.zcu; |
| 2258 | const bit_size = lhs_ty.bitSize(pt); | ||
| 2242 | assert(bit_size <= 64); | 2259 | assert(bit_size <= 64); |
| 2243 | 2260 | ||
| 2244 | const is_unsigned = lhs_ty.isUnsignedInt(zcu); | 2261 | const is_unsigned = lhs_ty.isUnsignedInt(zcu); |
| ... | @@ -2349,7 +2366,7 @@ fn genBinOp( | ... | @@ -2349,7 +2366,7 @@ fn genBinOp( |
| 2349 | defer func.register_manager.unlockReg(tmp_lock); | 2366 | defer func.register_manager.unlockReg(tmp_lock); |
| 2350 | 2367 | ||
| 2351 | // RISC-V has no immediate mul, so we copy the size to a temporary register | 2368 | // RISC-V has no immediate mul, so we copy the size to a temporary register |
| 2352 | const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu); | 2369 | const elem_size = lhs_ty.elemType2(zcu).abiSize(pt); |
| 2353 | const elem_size_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = elem_size }); | 2370 | const elem_size_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = elem_size }); |
| 2354 | 2371 | ||
| 2355 | try func.genBinOp( | 2372 | try func.genBinOp( |
| ... | @@ -2613,7 +2630,8 @@ fn airPtrArithmetic(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void | ... | @@ -2613,7 +2630,8 @@ fn airPtrArithmetic(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void |
| 2613 | } | 2630 | } |
| 2614 | 2631 | ||
| 2615 | fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | 2632 | fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2616 | const zcu = func.bin_file.comp.module.?; | 2633 | const pt = func.pt; |
| 2634 | const zcu = pt.zcu; | ||
| 2617 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2635 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2618 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; | 2636 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2619 | 2637 | ||
| ... | @@ -2632,7 +2650,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2632,7 +2650,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2632 | const add_result_reg_lock = func.register_manager.lockRegAssumeUnused(add_result_reg); | 2650 | const add_result_reg_lock = func.register_manager.lockRegAssumeUnused(add_result_reg); |
| 2633 | defer func.register_manager.unlockReg(add_result_reg_lock); | 2651 | defer func.register_manager.unlockReg(add_result_reg_lock); |
| 2634 | 2652 | ||
| 2635 | const shift_amount: u6 = @intCast(Type.usize.bitSize(zcu) - int_info.bits); | 2653 | const shift_amount: u6 = @intCast(Type.usize.bitSize(pt) - int_info.bits); |
| 2636 | 2654 | ||
| 2637 | const shift_reg, const shift_lock = try func.allocReg(.int); | 2655 | const shift_reg, const shift_lock = try func.allocReg(.int); |
| 2638 | defer func.register_manager.unlockReg(shift_lock); | 2656 | defer func.register_manager.unlockReg(shift_lock); |
| ... | @@ -2663,7 +2681,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2663,7 +2681,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2663 | 2681 | ||
| 2664 | try func.genSetMem( | 2682 | try func.genSetMem( |
| 2665 | .{ .frame = offset.index }, | 2683 | .{ .frame = offset.index }, |
| 2666 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | 2684 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), |
| 2667 | lhs_ty, | 2685 | lhs_ty, |
| 2668 | add_result, | 2686 | add_result, |
| 2669 | ); | 2687 | ); |
| ... | @@ -2682,7 +2700,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2682,7 +2700,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2682 | 2700 | ||
| 2683 | try func.genSetMem( | 2701 | try func.genSetMem( |
| 2684 | .{ .frame = offset.index }, | 2702 | .{ .frame = offset.index }, |
| 2685 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | 2703 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), |
| 2686 | Type.u1, | 2704 | Type.u1, |
| 2687 | .{ .register = overflow_reg }, | 2705 | .{ .register = overflow_reg }, |
| 2688 | ); | 2706 | ); |
| ... | @@ -2697,7 +2715,8 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2697,7 +2715,8 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2697 | } | 2715 | } |
| 2698 | 2716 | ||
| 2699 | fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | 2717 | fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2700 | const zcu = func.bin_file.comp.module.?; | 2718 | const pt = func.pt; |
| 2719 | const zcu = pt.zcu; | ||
| 2701 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2720 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2702 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; | 2721 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2703 | 2722 | ||
| ... | @@ -2727,7 +2746,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2727,7 +2746,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2727 | 2746 | ||
| 2728 | try func.genSetMem( | 2747 | try func.genSetMem( |
| 2729 | .{ .frame = offset.index }, | 2748 | .{ .frame = offset.index }, |
| 2730 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | 2749 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), |
| 2731 | lhs_ty, | 2750 | lhs_ty, |
| 2732 | .{ .register = dest_reg }, | 2751 | .{ .register = dest_reg }, |
| 2733 | ); | 2752 | ); |
| ... | @@ -2757,7 +2776,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2757,7 +2776,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2757 | 2776 | ||
| 2758 | try func.genSetMem( | 2777 | try func.genSetMem( |
| 2759 | .{ .frame = offset.index }, | 2778 | .{ .frame = offset.index }, |
| 2760 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | 2779 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), |
| 2761 | Type.u1, | 2780 | Type.u1, |
| 2762 | .{ .register = overflow_reg }, | 2781 | .{ .register = overflow_reg }, |
| 2763 | ); | 2782 | ); |
| ... | @@ -2808,7 +2827,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2808,7 +2827,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2808 | 2827 | ||
| 2809 | try func.genSetMem( | 2828 | try func.genSetMem( |
| 2810 | .{ .frame = offset.index }, | 2829 | .{ .frame = offset.index }, |
| 2811 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | 2830 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), |
| 2812 | Type.u1, | 2831 | Type.u1, |
| 2813 | .{ .register = overflow_reg }, | 2832 | .{ .register = overflow_reg }, |
| 2814 | ); | 2833 | ); |
| ... | @@ -2825,7 +2844,8 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2825,7 +2844,8 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2825 | } | 2844 | } |
| 2826 | 2845 | ||
| 2827 | fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | 2846 | fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2828 | const zcu = func.bin_file.comp.module.?; | 2847 | const pt = func.pt; |
| 2848 | const zcu = pt.zcu; | ||
| 2829 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2849 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2830 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; | 2850 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2831 | 2851 | ||
| ... | @@ -2840,8 +2860,8 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2840,8 +2860,8 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2840 | // genSetReg needs to support register_offset src_mcv for this to be true. | 2860 | // genSetReg needs to support register_offset src_mcv for this to be true. |
| 2841 | const result_mcv = try func.allocRegOrMem(tuple_ty, inst, false); | 2861 | const result_mcv = try func.allocRegOrMem(tuple_ty, inst, false); |
| 2842 | 2862 | ||
| 2843 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); | 2863 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt)); |
| 2844 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | 2864 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, pt)); |
| 2845 | 2865 | ||
| 2846 | const dest_reg, const dest_lock = try func.allocReg(.int); | 2866 | const dest_reg, const dest_lock = try func.allocReg(.int); |
| 2847 | defer func.register_manager.unlockReg(dest_lock); | 2867 | defer func.register_manager.unlockReg(dest_lock); |
| ... | @@ -2957,11 +2977,11 @@ fn airShlSat(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2957,11 +2977,11 @@ fn airShlSat(func: *Func, inst: Air.Inst.Index) !void { |
| 2957 | } | 2977 | } |
| 2958 | 2978 | ||
| 2959 | fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void { | 2979 | fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 2960 | const zcu = func.bin_file.comp.module.?; | 2980 | const pt = func.pt; |
| 2961 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2981 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2962 | const result: MCValue = result: { | 2982 | const result: MCValue = result: { |
| 2963 | const pl_ty = func.typeOfIndex(inst); | 2983 | const pl_ty = func.typeOfIndex(inst); |
| 2964 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | 2984 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 2965 | 2985 | ||
| 2966 | const opt_mcv = try func.resolveInst(ty_op.operand); | 2986 | const opt_mcv = try func.resolveInst(ty_op.operand); |
| 2967 | if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { | 2987 | if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { |
| ... | @@ -2993,7 +3013,8 @@ fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -2993,7 +3013,8 @@ fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { |
| 2993 | 3013 | ||
| 2994 | fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void { | 3014 | fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void { |
| 2995 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3015 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2996 | const zcu = func.bin_file.comp.module.?; | 3016 | const pt = func.pt; |
| 3017 | const zcu = pt.zcu; | ||
| 2997 | const err_union_ty = func.typeOf(ty_op.operand); | 3018 | const err_union_ty = func.typeOf(ty_op.operand); |
| 2998 | const err_ty = err_union_ty.errorUnionSet(zcu); | 3019 | const err_ty = err_union_ty.errorUnionSet(zcu); |
| 2999 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 3020 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| ... | @@ -3004,11 +3025,11 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3004,11 +3025,11 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void { |
| 3004 | break :result .{ .immediate = 0 }; | 3025 | break :result .{ .immediate = 0 }; |
| 3005 | } | 3026 | } |
| 3006 | 3027 | ||
| 3007 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 3028 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3008 | break :result operand; | 3029 | break :result operand; |
| 3009 | } | 3030 | } |
| 3010 | 3031 | ||
| 3011 | const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu)); | 3032 | const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); |
| 3012 | 3033 | ||
| 3013 | switch (operand) { | 3034 | switch (operand) { |
| 3014 | .register => |reg| { | 3035 | .register => |reg| { |
| ... | @@ -3052,13 +3073,14 @@ fn genUnwrapErrUnionPayloadMir( | ... | @@ -3052,13 +3073,14 @@ fn genUnwrapErrUnionPayloadMir( |
| 3052 | err_union_ty: Type, | 3073 | err_union_ty: Type, |
| 3053 | err_union: MCValue, | 3074 | err_union: MCValue, |
| 3054 | ) !MCValue { | 3075 | ) !MCValue { |
| 3055 | const zcu = func.bin_file.comp.module.?; | 3076 | const pt = func.pt; |
| 3077 | const zcu = pt.zcu; | ||
| 3056 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 3078 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 3057 | 3079 | ||
| 3058 | const result: MCValue = result: { | 3080 | const result: MCValue = result: { |
| 3059 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | 3081 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 3060 | 3082 | ||
| 3061 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu)); | 3083 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt)); |
| 3062 | switch (err_union) { | 3084 | switch (err_union) { |
| 3063 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ | 3085 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ |
| 3064 | .index = frame_addr.index, | 3086 | .index = frame_addr.index, |
| ... | @@ -3127,11 +3149,12 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3127,11 +3149,12 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void { |
| 3127 | } | 3149 | } |
| 3128 | 3150 | ||
| 3129 | fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { | 3151 | fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { |
| 3130 | const zcu = func.bin_file.comp.module.?; | 3152 | const pt = func.pt; |
| 3153 | const zcu = pt.zcu; | ||
| 3131 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3154 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3132 | const result: MCValue = result: { | 3155 | const result: MCValue = result: { |
| 3133 | const pl_ty = func.typeOf(ty_op.operand); | 3156 | const pl_ty = func.typeOf(ty_op.operand); |
| 3134 | if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 }; | 3157 | if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 }; |
| 3135 | 3158 | ||
| 3136 | const opt_ty = func.typeOfIndex(inst); | 3159 | const opt_ty = func.typeOfIndex(inst); |
| 3137 | const pl_mcv = try func.resolveInst(ty_op.operand); | 3160 | const pl_mcv = try func.resolveInst(ty_op.operand); |
| ... | @@ -3148,7 +3171,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3148,7 +3171,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { |
| 3148 | try func.genCopy(pl_ty, opt_mcv, pl_mcv); | 3171 | try func.genCopy(pl_ty, opt_mcv, pl_mcv); |
| 3149 | 3172 | ||
| 3150 | if (!same_repr) { | 3173 | if (!same_repr) { |
| 3151 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); | 3174 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); |
| 3152 | switch (opt_mcv) { | 3175 | switch (opt_mcv) { |
| 3153 | .load_frame => |frame_addr| try func.genSetMem( | 3176 | .load_frame => |frame_addr| try func.genSetMem( |
| 3154 | .{ .frame = frame_addr.index }, | 3177 | .{ .frame = frame_addr.index }, |
| ... | @@ -3167,7 +3190,8 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3167,7 +3190,8 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { |
| 3167 | 3190 | ||
| 3168 | /// T to E!T | 3191 | /// T to E!T |
| 3169 | fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { | 3192 | fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 3170 | const zcu = func.bin_file.comp.module.?; | 3193 | const pt = func.pt; |
| 3194 | const zcu = pt.zcu; | ||
| 3171 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3195 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3172 | 3196 | ||
| 3173 | const eu_ty = ty_op.ty.toType(); | 3197 | const eu_ty = ty_op.ty.toType(); |
| ... | @@ -3176,11 +3200,11 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3176,11 +3200,11 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 3176 | const operand = try func.resolveInst(ty_op.operand); | 3200 | const operand = try func.resolveInst(ty_op.operand); |
| 3177 | 3201 | ||
| 3178 | const result: MCValue = result: { | 3202 | const result: MCValue = result: { |
| 3179 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 }; | 3203 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 }; |
| 3180 | 3204 | ||
| 3181 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | 3205 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); |
| 3182 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | 3206 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 3183 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | 3207 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 3184 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand); | 3208 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand); |
| 3185 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }); | 3209 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }); |
| 3186 | break :result .{ .load_frame = .{ .index = frame_index } }; | 3210 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -3191,7 +3215,8 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3191,7 +3215,8 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 3191 | 3215 | ||
| 3192 | /// E to E!T | 3216 | /// E to E!T |
| 3193 | fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void { | 3217 | fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void { |
| 3194 | const zcu = func.bin_file.comp.module.?; | 3218 | const pt = func.pt; |
| 3219 | const zcu = pt.zcu; | ||
| 3195 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3220 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3196 | 3221 | ||
| 3197 | const eu_ty = ty_op.ty.toType(); | 3222 | const eu_ty = ty_op.ty.toType(); |
| ... | @@ -3199,11 +3224,11 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3199,11 +3224,11 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void { |
| 3199 | const err_ty = eu_ty.errorUnionSet(zcu); | 3224 | const err_ty = eu_ty.errorUnionSet(zcu); |
| 3200 | 3225 | ||
| 3201 | const result: MCValue = result: { | 3226 | const result: MCValue = result: { |
| 3202 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try func.resolveInst(ty_op.operand); | 3227 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try func.resolveInst(ty_op.operand); |
| 3203 | 3228 | ||
| 3204 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | 3229 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); |
| 3205 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | 3230 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 3206 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | 3231 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 3207 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef); | 3232 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef); |
| 3208 | const operand = try func.resolveInst(ty_op.operand); | 3233 | const operand = try func.resolveInst(ty_op.operand); |
| 3209 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); | 3234 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); |
| ... | @@ -3327,15 +3352,16 @@ fn airPtrSlicePtrPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3327,15 +3352,16 @@ fn airPtrSlicePtrPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 3327 | } | 3352 | } |
| 3328 | 3353 | ||
| 3329 | fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void { | 3354 | fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3330 | const mod = func.bin_file.comp.module.?; | 3355 | const pt = func.pt; |
| 3356 | const zcu = pt.zcu; | ||
| 3331 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3357 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3332 | 3358 | ||
| 3333 | const result: MCValue = result: { | 3359 | const result: MCValue = result: { |
| 3334 | const elem_ty = func.typeOfIndex(inst); | 3360 | const elem_ty = func.typeOfIndex(inst); |
| 3335 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 3361 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 3336 | 3362 | ||
| 3337 | const slice_ty = func.typeOf(bin_op.lhs); | 3363 | const slice_ty = func.typeOf(bin_op.lhs); |
| 3338 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | 3364 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu); |
| 3339 | const elem_ptr = try func.genSliceElemPtr(bin_op.lhs, bin_op.rhs); | 3365 | const elem_ptr = try func.genSliceElemPtr(bin_op.lhs, bin_op.rhs); |
| 3340 | const dst_mcv = try func.allocRegOrMem(elem_ty, inst, false); | 3366 | const dst_mcv = try func.allocRegOrMem(elem_ty, inst, false); |
| 3341 | try func.load(dst_mcv, elem_ptr, slice_ptr_field_type); | 3367 | try func.load(dst_mcv, elem_ptr, slice_ptr_field_type); |
| ... | @@ -3352,7 +3378,8 @@ fn airSliceElemPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3352,7 +3378,8 @@ fn airSliceElemPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 3352 | } | 3378 | } |
| 3353 | 3379 | ||
| 3354 | fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | 3380 | fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 3355 | const zcu = func.bin_file.comp.module.?; | 3381 | const pt = func.pt; |
| 3382 | const zcu = pt.zcu; | ||
| 3356 | const slice_ty = func.typeOf(lhs); | 3383 | const slice_ty = func.typeOf(lhs); |
| 3357 | const slice_mcv = try func.resolveInst(lhs); | 3384 | const slice_mcv = try func.resolveInst(lhs); |
| 3358 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { | 3385 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { |
| ... | @@ -3362,7 +3389,7 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -3362,7 +3389,7 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 3362 | defer if (slice_mcv_lock) |lock| func.register_manager.unlockReg(lock); | 3389 | defer if (slice_mcv_lock) |lock| func.register_manager.unlockReg(lock); |
| 3363 | 3390 | ||
| 3364 | const elem_ty = slice_ty.childType(zcu); | 3391 | const elem_ty = slice_ty.childType(zcu); |
| 3365 | const elem_size = elem_ty.abiSize(zcu); | 3392 | const elem_size = elem_ty.abiSize(pt); |
| 3366 | 3393 | ||
| 3367 | const index_ty = func.typeOf(rhs); | 3394 | const index_ty = func.typeOf(rhs); |
| 3368 | const index_mcv = try func.resolveInst(rhs); | 3395 | const index_mcv = try func.resolveInst(rhs); |
| ... | @@ -3394,7 +3421,8 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -3394,7 +3421,8 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 3394 | } | 3421 | } |
| 3395 | 3422 | ||
| 3396 | fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { | 3423 | fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3397 | const zcu = func.bin_file.comp.module.?; | 3424 | const pt = func.pt; |
| 3425 | const zcu = pt.zcu; | ||
| 3398 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3426 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3399 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 3427 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 3400 | const result_ty = func.typeOfIndex(inst); | 3428 | const result_ty = func.typeOfIndex(inst); |
| ... | @@ -3406,14 +3434,14 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3406,14 +3434,14 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3406 | const index_ty = func.typeOf(bin_op.rhs); | 3434 | const index_ty = func.typeOf(bin_op.rhs); |
| 3407 | 3435 | ||
| 3408 | const elem_ty = array_ty.childType(zcu); | 3436 | const elem_ty = array_ty.childType(zcu); |
| 3409 | const elem_abi_size = elem_ty.abiSize(zcu); | 3437 | const elem_abi_size = elem_ty.abiSize(pt); |
| 3410 | 3438 | ||
| 3411 | const addr_reg, const addr_reg_lock = try func.allocReg(.int); | 3439 | const addr_reg, const addr_reg_lock = try func.allocReg(.int); |
| 3412 | defer func.register_manager.unlockReg(addr_reg_lock); | 3440 | defer func.register_manager.unlockReg(addr_reg_lock); |
| 3413 | 3441 | ||
| 3414 | switch (array_mcv) { | 3442 | switch (array_mcv) { |
| 3415 | .register => { | 3443 | .register => { |
| 3416 | const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | 3444 | const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); |
| 3417 | try func.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); | 3445 | try func.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); |
| 3418 | try func.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } }); | 3446 | try func.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } }); |
| 3419 | }, | 3447 | }, |
| ... | @@ -3451,7 +3479,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3451,7 +3479,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3451 | } | 3479 | } |
| 3452 | 3480 | ||
| 3453 | fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void { | 3481 | fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 3454 | const zcu = func.bin_file.comp.module.?; | 3482 | const pt = func.pt; |
| 3483 | const zcu = pt.zcu; | ||
| 3455 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3484 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3456 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; | 3485 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3457 | 3486 | ||
| ... | @@ -3474,7 +3503,7 @@ fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3474,7 +3503,7 @@ fn airPtrElemPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 3474 | } | 3503 | } |
| 3475 | 3504 | ||
| 3476 | const elem_ty = base_ptr_ty.elemType2(zcu); | 3505 | const elem_ty = base_ptr_ty.elemType2(zcu); |
| 3477 | const elem_abi_size = elem_ty.abiSize(zcu); | 3506 | const elem_abi_size = elem_ty.abiSize(pt); |
| 3478 | const index_ty = func.typeOf(extra.rhs); | 3507 | const index_ty = func.typeOf(extra.rhs); |
| 3479 | const index_mcv = try func.resolveInst(extra.rhs); | 3508 | const index_mcv = try func.resolveInst(extra.rhs); |
| 3480 | const index_lock: ?RegisterLock = switch (index_mcv) { | 3509 | const index_lock: ?RegisterLock = switch (index_mcv) { |
| ... | @@ -3536,7 +3565,8 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3536,7 +3565,8 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void { |
| 3536 | } | 3565 | } |
| 3537 | 3566 | ||
| 3538 | fn airAbs(func: *Func, inst: Air.Inst.Index) !void { | 3567 | fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3539 | const zcu = func.bin_file.comp.module.?; | 3568 | const pt = func.pt; |
| 3569 | const zcu = pt.zcu; | ||
| 3540 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3570 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3541 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 3571 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 3542 | const ty = func.typeOf(ty_op.operand); | 3572 | const ty = func.typeOf(ty_op.operand); |
| ... | @@ -3545,7 +3575,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3545,7 +3575,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3545 | 3575 | ||
| 3546 | switch (scalar_ty.zigTypeTag(zcu)) { | 3576 | switch (scalar_ty.zigTypeTag(zcu)) { |
| 3547 | .Int => if (ty.zigTypeTag(zcu) == .Vector) { | 3577 | .Int => if (ty.zigTypeTag(zcu) == .Vector) { |
| 3548 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(zcu)}); | 3578 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 3549 | } else { | 3579 | } else { |
| 3550 | const return_mcv = try func.copyToNewRegister(inst, operand); | 3580 | const return_mcv = try func.copyToNewRegister(inst, operand); |
| 3551 | const operand_reg = return_mcv.register; | 3581 | const operand_reg = return_mcv.register; |
| ... | @@ -3615,7 +3645,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3615,7 +3645,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3615 | 3645 | ||
| 3616 | break :result return_mcv; | 3646 | break :result return_mcv; |
| 3617 | }, | 3647 | }, |
| 3618 | else => return func.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(zcu)}), | 3648 | else => return func.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(pt)}), |
| 3619 | } | 3649 | } |
| 3620 | 3650 | ||
| 3621 | break :result .unreach; | 3651 | break :result .unreach; |
| ... | @@ -3626,7 +3656,8 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3626,7 +3656,8 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3626 | fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void { | 3656 | fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void { |
| 3627 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3657 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3628 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 3658 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 3629 | const zcu = func.bin_file.comp.module.?; | 3659 | const pt = func.pt; |
| 3660 | const zcu = pt.zcu; | ||
| 3630 | const ty = func.typeOf(ty_op.operand); | 3661 | const ty = func.typeOf(ty_op.operand); |
| 3631 | const operand = try func.resolveInst(ty_op.operand); | 3662 | const operand = try func.resolveInst(ty_op.operand); |
| 3632 | 3663 | ||
| ... | @@ -3746,12 +3777,13 @@ fn reuseOperandAdvanced( | ... | @@ -3746,12 +3777,13 @@ fn reuseOperandAdvanced( |
| 3746 | } | 3777 | } |
| 3747 | 3778 | ||
| 3748 | fn airLoad(func: *Func, inst: Air.Inst.Index) !void { | 3779 | fn airLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 3749 | const zcu = func.bin_file.comp.module.?; | 3780 | const pt = func.pt; |
| 3781 | const zcu = pt.zcu; | ||
| 3750 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3782 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3751 | const elem_ty = func.typeOfIndex(inst); | 3783 | const elem_ty = func.typeOfIndex(inst); |
| 3752 | 3784 | ||
| 3753 | const result: MCValue = result: { | 3785 | const result: MCValue = result: { |
| 3754 | if (!elem_ty.hasRuntimeBits(zcu)) | 3786 | if (!elem_ty.hasRuntimeBits(pt)) |
| 3755 | break :result .none; | 3787 | break :result .none; |
| 3756 | 3788 | ||
| 3757 | const ptr = try func.resolveInst(ty_op.operand); | 3789 | const ptr = try func.resolveInst(ty_op.operand); |
| ... | @@ -3759,7 +3791,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3759,7 +3791,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 3759 | if (func.liveness.isUnused(inst) and !is_volatile) | 3791 | if (func.liveness.isUnused(inst) and !is_volatile) |
| 3760 | break :result .unreach; | 3792 | break :result .unreach; |
| 3761 | 3793 | ||
| 3762 | const elem_size = elem_ty.abiSize(zcu); | 3794 | const elem_size = elem_ty.abiSize(pt); |
| 3763 | 3795 | ||
| 3764 | const dst_mcv: MCValue = blk: { | 3796 | const dst_mcv: MCValue = blk: { |
| 3765 | // Pointer is 8 bytes, and if the element is more than that, we cannot reuse it. | 3797 | // Pointer is 8 bytes, and if the element is more than that, we cannot reuse it. |
| ... | @@ -3778,10 +3810,11 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3778,10 +3810,11 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 3778 | } | 3810 | } |
| 3779 | 3811 | ||
| 3780 | fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerError!void { | 3812 | fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerError!void { |
| 3781 | const zcu = func.bin_file.comp.module.?; | 3813 | const pt = func.pt; |
| 3814 | const zcu = pt.zcu; | ||
| 3782 | const dst_ty = ptr_ty.childType(zcu); | 3815 | const dst_ty = ptr_ty.childType(zcu); |
| 3783 | 3816 | ||
| 3784 | log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(zcu), dst_mcv }); | 3817 | log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(pt), dst_mcv }); |
| 3785 | 3818 | ||
| 3786 | switch (ptr_mcv) { | 3819 | switch (ptr_mcv) { |
| 3787 | .none, | 3820 | .none, |
| ... | @@ -3833,9 +3866,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -3833,9 +3866,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 3833 | 3866 | ||
| 3834 | /// Loads `value` into the "payload" of `pointer`. | 3867 | /// Loads `value` into the "payload" of `pointer`. |
| 3835 | fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type, src_ty: Type) !void { | 3868 | fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type, src_ty: Type) !void { |
| 3836 | const zcu = func.bin_file.comp.module.?; | 3869 | log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(func.pt), ptr_mcv, ptr_ty.fmt(func.pt) }); |
| 3837 | |||
| 3838 | log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(zcu), ptr_mcv, ptr_ty.fmt(zcu) }); | ||
| 3839 | 3870 | ||
| 3840 | switch (ptr_mcv) { | 3871 | switch (ptr_mcv) { |
| 3841 | .none => unreachable, | 3872 | .none => unreachable, |
| ... | @@ -3881,7 +3912,8 @@ fn airStructFieldPtrIndex(func: *Func, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -3881,7 +3912,8 @@ fn airStructFieldPtrIndex(func: *Func, inst: Air.Inst.Index, index: u8) !void { |
| 3881 | } | 3912 | } |
| 3882 | 3913 | ||
| 3883 | fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 3914 | fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 3884 | const zcu = func.bin_file.comp.module.?; | 3915 | const pt = func.pt; |
| 3916 | const zcu = pt.zcu; | ||
| 3885 | const ptr_field_ty = func.typeOfIndex(inst); | 3917 | const ptr_field_ty = func.typeOfIndex(inst); |
| 3886 | const ptr_container_ty = func.typeOf(operand); | 3918 | const ptr_container_ty = func.typeOf(operand); |
| 3887 | const ptr_container_ty_info = ptr_container_ty.ptrInfo(zcu); | 3919 | const ptr_container_ty_info = ptr_container_ty.ptrInfo(zcu); |
| ... | @@ -3889,12 +3921,12 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -3889,12 +3921,12 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 3889 | 3921 | ||
| 3890 | const field_offset: i32 = if (zcu.typeToPackedStruct(container_ty)) |struct_obj| | 3922 | const field_offset: i32 = if (zcu.typeToPackedStruct(container_ty)) |struct_obj| |
| 3891 | if (ptr_field_ty.ptrInfo(zcu).packed_offset.host_size == 0) | 3923 | if (ptr_field_ty.ptrInfo(zcu).packed_offset.host_size == 0) |
| 3892 | @divExact(zcu.structPackedFieldBitOffset(struct_obj, index) + | 3924 | @divExact(pt.structPackedFieldBitOffset(struct_obj, index) + |
| 3893 | ptr_container_ty_info.packed_offset.bit_offset, 8) | 3925 | ptr_container_ty_info.packed_offset.bit_offset, 8) |
| 3894 | else | 3926 | else |
| 3895 | 0 | 3927 | 0 |
| 3896 | else | 3928 | else |
| 3897 | @intCast(container_ty.structFieldOffset(index, zcu)); | 3929 | @intCast(container_ty.structFieldOffset(index, pt)); |
| 3898 | 3930 | ||
| 3899 | const src_mcv = try func.resolveInst(operand); | 3931 | const src_mcv = try func.resolveInst(operand); |
| 3900 | const dst_mcv = if (switch (src_mcv) { | 3932 | const dst_mcv = if (switch (src_mcv) { |
| ... | @@ -3906,7 +3938,8 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -3906,7 +3938,8 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 3906 | } | 3938 | } |
| 3907 | 3939 | ||
| 3908 | fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { | 3940 | fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3909 | const mod = func.bin_file.comp.module.?; | 3941 | const pt = func.pt; |
| 3942 | const zcu = pt.zcu; | ||
| 3910 | 3943 | ||
| 3911 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3944 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3912 | const extra = func.air.extraData(Air.StructField, ty_pl.payload).data; | 3945 | const extra = func.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -3914,16 +3947,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3914,16 +3947,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3914 | const index = extra.field_index; | 3947 | const index = extra.field_index; |
| 3915 | 3948 | ||
| 3916 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 3949 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 3917 | const zcu = func.bin_file.comp.module.?; | ||
| 3918 | const src_mcv = try func.resolveInst(operand); | 3950 | const src_mcv = try func.resolveInst(operand); |
| 3919 | const struct_ty = func.typeOf(operand); | 3951 | const struct_ty = func.typeOf(operand); |
| 3920 | const field_ty = struct_ty.structFieldType(index, zcu); | 3952 | const field_ty = struct_ty.structFieldType(index, zcu); |
| 3921 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | 3953 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 3922 | 3954 | ||
| 3923 | const field_off: u32 = switch (struct_ty.containerLayout(zcu)) { | 3955 | const field_off: u32 = switch (struct_ty.containerLayout(zcu)) { |
| 3924 | .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8), | 3956 | .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, pt) * 8), |
| 3925 | .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type| | 3957 | .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type| |
| 3926 | zcu.structPackedFieldBitOffset(struct_type, index) | 3958 | pt.structPackedFieldBitOffset(struct_type, index) |
| 3927 | else | 3959 | else |
| 3928 | 0, | 3960 | 0, |
| 3929 | }; | 3961 | }; |
| ... | @@ -3958,15 +3990,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3958,15 +3990,15 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3958 | break :result if (field_off == 0) dst_mcv else try func.copyToNewRegister(inst, dst_mcv); | 3990 | break :result if (field_off == 0) dst_mcv else try func.copyToNewRegister(inst, dst_mcv); |
| 3959 | }, | 3991 | }, |
| 3960 | .load_frame => { | 3992 | .load_frame => { |
| 3961 | const field_abi_size: u32 = @intCast(field_ty.abiSize(mod)); | 3993 | const field_abi_size: u32 = @intCast(field_ty.abiSize(pt)); |
| 3962 | if (field_off % 8 == 0) { | 3994 | if (field_off % 8 == 0) { |
| 3963 | const field_byte_off = @divExact(field_off, 8); | 3995 | const field_byte_off = @divExact(field_off, 8); |
| 3964 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); | 3996 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); |
| 3965 | const field_bit_size = field_ty.bitSize(mod); | 3997 | const field_bit_size = field_ty.bitSize(pt); |
| 3966 | 3998 | ||
| 3967 | if (field_abi_size <= 8) { | 3999 | if (field_abi_size <= 8) { |
| 3968 | const int_ty = try mod.intType( | 4000 | const int_ty = try pt.intType( |
| 3969 | if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, | 4001 | if (field_ty.isAbiInt(zcu)) field_ty.intInfo(zcu).signedness else .unsigned, |
| 3970 | @intCast(field_bit_size), | 4002 | @intCast(field_bit_size), |
| 3971 | ); | 4003 | ); |
| 3972 | 4004 | ||
| ... | @@ -3978,7 +4010,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -3978,7 +4010,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3978 | break :result try func.copyToNewRegister(inst, dst_mcv); | 4010 | break :result try func.copyToNewRegister(inst, dst_mcv); |
| 3979 | } | 4011 | } |
| 3980 | 4012 | ||
| 3981 | const container_abi_size: u32 = @intCast(struct_ty.abiSize(mod)); | 4013 | const container_abi_size: u32 = @intCast(struct_ty.abiSize(pt)); |
| 3982 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and | 4014 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and |
| 3983 | func.reuseOperand(inst, operand, 0, src_mcv)) | 4015 | func.reuseOperand(inst, operand, 0, src_mcv)) |
| 3984 | off_mcv | 4016 | off_mcv |
| ... | @@ -4014,7 +4046,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -4014,7 +4046,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 4014 | } | 4046 | } |
| 4015 | 4047 | ||
| 4016 | fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { | 4048 | fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 4017 | const zcu = func.bin_file.comp.module.?; | 4049 | const pt = func.pt; |
| 4050 | const zcu = pt.zcu; | ||
| 4018 | const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; | 4051 | const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 4019 | const ty = arg.ty.toType(); | 4052 | const ty = arg.ty.toType(); |
| 4020 | const owner_decl = zcu.funcOwnerDeclIndex(func.func_index); | 4053 | const owner_decl = zcu.funcOwnerDeclIndex(func.func_index); |
| ... | @@ -4139,7 +4172,8 @@ fn genCall( | ... | @@ -4139,7 +4172,8 @@ fn genCall( |
| 4139 | arg_tys: []const Type, | 4172 | arg_tys: []const Type, |
| 4140 | args: []const MCValue, | 4173 | args: []const MCValue, |
| 4141 | ) !MCValue { | 4174 | ) !MCValue { |
| 4142 | const zcu = func.bin_file.comp.module.?; | 4175 | const pt = func.pt; |
| 4176 | const zcu = pt.zcu; | ||
| 4143 | 4177 | ||
| 4144 | const fn_ty = switch (info) { | 4178 | const fn_ty = switch (info) { |
| 4145 | .air => |callee| fn_info: { | 4179 | .air => |callee| fn_info: { |
| ... | @@ -4150,7 +4184,7 @@ fn genCall( | ... | @@ -4150,7 +4184,7 @@ fn genCall( |
| 4150 | else => unreachable, | 4184 | else => unreachable, |
| 4151 | }; | 4185 | }; |
| 4152 | }, | 4186 | }, |
| 4153 | .lib => |lib| try zcu.funcType(.{ | 4187 | .lib => |lib| try pt.funcType(.{ |
| 4154 | .param_types = lib.param_types, | 4188 | .param_types = lib.param_types, |
| 4155 | .return_type = lib.return_type, | 4189 | .return_type = lib.return_type, |
| 4156 | .cc = .C, | 4190 | .cc = .C, |
| ... | @@ -4208,7 +4242,7 @@ fn genCall( | ... | @@ -4208,7 +4242,7 @@ fn genCall( |
| 4208 | try reg_locks.appendSlice(&func.register_manager.lockRegs(2, regs)); | 4242 | try reg_locks.appendSlice(&func.register_manager.lockRegs(2, regs)); |
| 4209 | }, | 4243 | }, |
| 4210 | .indirect => |reg_off| { | 4244 | .indirect => |reg_off| { |
| 4211 | frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, zcu)); | 4245 | frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, pt)); |
| 4212 | try func.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg); | 4246 | try func.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg); |
| 4213 | try func.register_manager.getReg(reg_off.reg, null); | 4247 | try func.register_manager.getReg(reg_off.reg, null); |
| 4214 | try reg_locks.append(func.register_manager.lockReg(reg_off.reg)); | 4248 | try reg_locks.append(func.register_manager.lockReg(reg_off.reg)); |
| ... | @@ -4221,7 +4255,7 @@ fn genCall( | ... | @@ -4221,7 +4255,7 @@ fn genCall( |
| 4221 | .none, .unreach => {}, | 4255 | .none, .unreach => {}, |
| 4222 | .indirect => |reg_off| { | 4256 | .indirect => |reg_off| { |
| 4223 | const ret_ty = Type.fromInterned(fn_info.return_type); | 4257 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 4224 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, zcu)); | 4258 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt)); |
| 4225 | try func.genSetReg(Type.usize, reg_off.reg, .{ | 4259 | try func.genSetReg(Type.usize, reg_off.reg, .{ |
| 4226 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 4260 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 4227 | }); | 4261 | }); |
| ... | @@ -4251,7 +4285,7 @@ fn genCall( | ... | @@ -4251,7 +4285,7 @@ fn genCall( |
| 4251 | // on linking. | 4285 | // on linking. |
| 4252 | switch (info) { | 4286 | switch (info) { |
| 4253 | .air => |callee| { | 4287 | .air => |callee| { |
| 4254 | if (try func.air.value(callee, zcu)) |func_value| { | 4288 | if (try func.air.value(callee, pt)) |func_value| { |
| 4255 | const func_key = zcu.intern_pool.indexToKey(func_value.ip_index); | 4289 | const func_key = zcu.intern_pool.indexToKey(func_value.ip_index); |
| 4256 | switch (switch (func_key) { | 4290 | switch (switch (func_key) { |
| 4257 | else => func_key, | 4291 | else => func_key, |
| ... | @@ -4324,7 +4358,8 @@ fn genCall( | ... | @@ -4324,7 +4358,8 @@ fn genCall( |
| 4324 | } | 4358 | } |
| 4325 | 4359 | ||
| 4326 | fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | 4360 | fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 4327 | const zcu = func.bin_file.comp.module.?; | 4361 | const pt = func.pt; |
| 4362 | const zcu = pt.zcu; | ||
| 4328 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4363 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4329 | 4364 | ||
| 4330 | if (safety) { | 4365 | if (safety) { |
| ... | @@ -4394,7 +4429,8 @@ fn airRetLoad(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -4394,7 +4429,8 @@ fn airRetLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 4394 | 4429 | ||
| 4395 | fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | 4430 | fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 4396 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4431 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4397 | const zcu = func.bin_file.comp.module.?; | 4432 | const pt = func.pt; |
| 4433 | const zcu = pt.zcu; | ||
| 4398 | 4434 | ||
| 4399 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 4435 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 4400 | const lhs_ty = func.typeOf(bin_op.lhs); | 4436 | const lhs_ty = func.typeOf(bin_op.lhs); |
| ... | @@ -4415,7 +4451,7 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | ... | @@ -4415,7 +4451,7 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 4415 | .ErrorSet => Type.anyerror, | 4451 | .ErrorSet => Type.anyerror, |
| 4416 | .Optional => blk: { | 4452 | .Optional => blk: { |
| 4417 | const payload_ty = lhs_ty.optionalChild(zcu); | 4453 | const payload_ty = lhs_ty.optionalChild(zcu); |
| 4418 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 4454 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4419 | break :blk Type.u1; | 4455 | break :blk Type.u1; |
| 4420 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { | 4456 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { |
| 4421 | break :blk Type.usize; | 4457 | break :blk Type.usize; |
| ... | @@ -4503,7 +4539,8 @@ fn genVarDbgInfo( | ... | @@ -4503,7 +4539,8 @@ fn genVarDbgInfo( |
| 4503 | mcv: MCValue, | 4539 | mcv: MCValue, |
| 4504 | name: [:0]const u8, | 4540 | name: [:0]const u8, |
| 4505 | ) !void { | 4541 | ) !void { |
| 4506 | const zcu = func.bin_file.comp.module.?; | 4542 | const pt = func.pt; |
| 4543 | const zcu = pt.zcu; | ||
| 4507 | const is_ptr = switch (tag) { | 4544 | const is_ptr = switch (tag) { |
| 4508 | .dbg_var_ptr => true, | 4545 | .dbg_var_ptr => true, |
| 4509 | .dbg_var_val => false, | 4546 | .dbg_var_val => false, |
| ... | @@ -4595,13 +4632,14 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { | ... | @@ -4595,13 +4632,14 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { |
| 4595 | } | 4632 | } |
| 4596 | 4633 | ||
| 4597 | fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { | 4634 | fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { |
| 4598 | const zcu = func.bin_file.comp.module.?; | 4635 | const pt = func.pt; |
| 4636 | const zcu = pt.zcu; | ||
| 4599 | const pl_ty = opt_ty.optionalChild(zcu); | 4637 | const pl_ty = opt_ty.optionalChild(zcu); |
| 4600 | 4638 | ||
| 4601 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) | 4639 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) |
| 4602 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } | 4640 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } |
| 4603 | else | 4641 | else |
| 4604 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | 4642 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; |
| 4605 | 4643 | ||
| 4606 | const return_mcv = try func.allocRegOrMem(func.typeOfIndex(inst), inst, true); | 4644 | const return_mcv = try func.allocRegOrMem(func.typeOfIndex(inst), inst, true); |
| 4607 | assert(return_mcv == .register); // should not be larger 8 bytes | 4645 | assert(return_mcv == .register); // should not be larger 8 bytes |
| ... | @@ -4642,7 +4680,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -4642,7 +4680,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 4642 | return return_mcv; | 4680 | return return_mcv; |
| 4643 | } | 4681 | } |
| 4644 | assert(some_info.ty.ip_index == .bool_type); | 4682 | assert(some_info.ty.ip_index == .bool_type); |
| 4645 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(zcu)); | 4683 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt)); |
| 4646 | _ = opt_abi_size; | 4684 | _ = opt_abi_size; |
| 4647 | return func.fail("TODO: isNull some_info.off != 0 register", .{}); | 4685 | return func.fail("TODO: isNull some_info.off != 0 register", .{}); |
| 4648 | }, | 4686 | }, |
| ... | @@ -4742,7 +4780,8 @@ fn airIsErr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -4742,7 +4780,8 @@ fn airIsErr(func: *Func, inst: Air.Inst.Index) !void { |
| 4742 | } | 4780 | } |
| 4743 | 4781 | ||
| 4744 | fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void { | 4782 | fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 4745 | const zcu = func.bin_file.comp.module.?; | 4783 | const pt = func.pt; |
| 4784 | const zcu = pt.zcu; | ||
| 4746 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4785 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4747 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 4786 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 4748 | const operand_ptr = try func.resolveInst(un_op); | 4787 | const operand_ptr = try func.resolveInst(un_op); |
| ... | @@ -4768,10 +4807,11 @@ fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -4768,10 +4807,11 @@ fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 4768 | /// Result is in the return register. | 4807 | /// Result is in the return register. |
| 4769 | fn isErr(func: *Func, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { | 4808 | fn isErr(func: *Func, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { |
| 4770 | _ = maybe_inst; | 4809 | _ = maybe_inst; |
| 4771 | const zcu = func.bin_file.comp.module.?; | 4810 | const pt = func.pt; |
| 4811 | const zcu = pt.zcu; | ||
| 4772 | const err_ty = eu_ty.errorUnionSet(zcu); | 4812 | const err_ty = eu_ty.errorUnionSet(zcu); |
| 4773 | if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false | 4813 | if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false |
| 4774 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu)); | 4814 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), pt)); |
| 4775 | 4815 | ||
| 4776 | const return_reg, const return_lock = try func.allocReg(.int); | 4816 | const return_reg, const return_lock = try func.allocReg(.int); |
| 4777 | defer func.register_manager.unlockReg(return_lock); | 4817 | defer func.register_manager.unlockReg(return_lock); |
| ... | @@ -4858,7 +4898,8 @@ fn isNonErr(func: *Func, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MC | ... | @@ -4858,7 +4898,8 @@ fn isNonErr(func: *Func, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MC |
| 4858 | } | 4898 | } |
| 4859 | 4899 | ||
| 4860 | fn airIsNonErrPtr(func: *Func, inst: Air.Inst.Index) !void { | 4900 | fn airIsNonErrPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 4861 | const zcu = func.bin_file.comp.module.?; | 4901 | const pt = func.pt; |
| 4902 | const zcu = pt.zcu; | ||
| 4862 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4903 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4863 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { | 4904 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 4864 | const operand_ptr = try func.resolveInst(un_op); | 4905 | const operand_ptr = try func.resolveInst(un_op); |
| ... | @@ -5063,12 +5104,12 @@ fn performReloc(func: *Func, inst: Mir.Inst.Index) void { | ... | @@ -5063,12 +5104,12 @@ fn performReloc(func: *Func, inst: Mir.Inst.Index) void { |
| 5063 | } | 5104 | } |
| 5064 | 5105 | ||
| 5065 | fn airBr(func: *Func, inst: Air.Inst.Index) !void { | 5106 | fn airBr(func: *Func, inst: Air.Inst.Index) !void { |
| 5066 | const mod = func.bin_file.comp.module.?; | 5107 | const pt = func.pt; |
| 5067 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; | 5108 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5068 | 5109 | ||
| 5069 | const block_ty = func.typeOfIndex(br.block_inst); | 5110 | const block_ty = func.typeOfIndex(br.block_inst); |
| 5070 | const block_unused = | 5111 | const block_unused = |
| 5071 | !block_ty.hasRuntimeBitsIgnoreComptime(mod) or func.liveness.isUnused(br.block_inst); | 5112 | !block_ty.hasRuntimeBitsIgnoreComptime(pt) or func.liveness.isUnused(br.block_inst); |
| 5072 | const block_tracking = func.inst_tracking.getPtr(br.block_inst).?; | 5113 | const block_tracking = func.inst_tracking.getPtr(br.block_inst).?; |
| 5073 | const block_data = func.blocks.getPtr(br.block_inst).?; | 5114 | const block_data = func.blocks.getPtr(br.block_inst).?; |
| 5074 | const first_br = block_data.relocs.items.len == 0; | 5115 | const first_br = block_data.relocs.items.len == 0; |
| ... | @@ -5288,8 +5329,6 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5288,8 +5329,6 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { |
| 5288 | 5329 | ||
| 5289 | /// Sets the value of `dst_mcv` to the value of `src_mcv`. | 5330 | /// Sets the value of `dst_mcv` to the value of `src_mcv`. |
| 5290 | fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { | 5331 | fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 5291 | const zcu = func.bin_file.comp.module.?; | ||
| 5292 | |||
| 5293 | // There isn't anything to store | 5332 | // There isn't anything to store |
| 5294 | if (dst_mcv == .none) return; | 5333 | if (dst_mcv == .none) return; |
| 5295 | 5334 | ||
| ... | @@ -5362,7 +5401,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { | ... | @@ -5362,7 +5401,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 5362 | } }, | 5401 | } }, |
| 5363 | else => unreachable, | 5402 | else => unreachable, |
| 5364 | }); | 5403 | }); |
| 5365 | part_disp += @intCast(dst_ty.abiSize(zcu)); | 5404 | part_disp += @intCast(dst_ty.abiSize(func.pt)); |
| 5366 | } | 5405 | } |
| 5367 | }, | 5406 | }, |
| 5368 | else => return func.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }), | 5407 | else => return func.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }), |
| ... | @@ -5555,8 +5594,9 @@ fn genInlineMemset( | ... | @@ -5555,8 +5594,9 @@ fn genInlineMemset( |
| 5555 | 5594 | ||
| 5556 | /// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it. | 5595 | /// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it. |
| 5557 | fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void { | 5596 | fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void { |
| 5558 | const zcu = func.bin_file.comp.module.?; | 5597 | const pt = func.pt; |
| 5559 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | 5598 | const zcu = pt.zcu; |
| 5599 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | ||
| 5560 | 5600 | ||
| 5561 | if (abi_size > 8) return std.debug.panic("tried to set reg with size {}", .{abi_size}); | 5601 | if (abi_size > 8) return std.debug.panic("tried to set reg with size {}", .{abi_size}); |
| 5562 | 5602 | ||
| ... | @@ -5784,8 +5824,8 @@ fn genSetMem( | ... | @@ -5784,8 +5824,8 @@ fn genSetMem( |
| 5784 | ty: Type, | 5824 | ty: Type, |
| 5785 | src_mcv: MCValue, | 5825 | src_mcv: MCValue, |
| 5786 | ) InnerError!void { | 5826 | ) InnerError!void { |
| 5787 | const mod = func.bin_file.comp.module.?; | 5827 | const pt = func.pt; |
| 5788 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 5828 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 5789 | const dst_ptr_mcv: MCValue = switch (base) { | 5829 | const dst_ptr_mcv: MCValue = switch (base) { |
| 5790 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | 5830 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 5791 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, | 5831 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| ... | @@ -5883,7 +5923,7 @@ fn genSetMem( | ... | @@ -5883,7 +5923,7 @@ fn genSetMem( |
| 5883 | var part_disp: i32 = disp; | 5923 | var part_disp: i32 = disp; |
| 5884 | for (try func.splitType(ty), src_regs) |src_ty, src_reg| { | 5924 | for (try func.splitType(ty), src_regs) |src_ty, src_reg| { |
| 5885 | try func.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); | 5925 | try func.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); |
| 5886 | part_disp += @intCast(src_ty.abiSize(mod)); | 5926 | part_disp += @intCast(src_ty.abiSize(pt)); |
| 5887 | } | 5927 | } |
| 5888 | }, | 5928 | }, |
| 5889 | .immediate => { | 5929 | .immediate => { |
| ... | @@ -5914,7 +5954,8 @@ fn airIntFromPtr(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5914,7 +5954,8 @@ fn airIntFromPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 5914 | } | 5954 | } |
| 5915 | 5955 | ||
| 5916 | fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { | 5956 | fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 5917 | const zcu = func.bin_file.comp.module.?; | 5957 | const pt = func.pt; |
| 5958 | const zcu = pt.zcu; | ||
| 5918 | 5959 | ||
| 5919 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5960 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5920 | const result = if (func.liveness.isUnused(inst)) .unreach else result: { | 5961 | const result = if (func.liveness.isUnused(inst)) .unreach else result: { |
| ... | @@ -5926,10 +5967,10 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5926,10 +5967,10 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 5926 | const src_lock = if (src_mcv.getReg()) |reg| func.register_manager.lockReg(reg) else null; | 5967 | const src_lock = if (src_mcv.getReg()) |reg| func.register_manager.lockReg(reg) else null; |
| 5927 | defer if (src_lock) |lock| func.register_manager.unlockReg(lock); | 5968 | defer if (src_lock) |lock| func.register_manager.unlockReg(lock); |
| 5928 | 5969 | ||
| 5929 | const dst_mcv = if (dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and | 5970 | const dst_mcv = if (dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and |
| 5930 | func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { | 5971 | func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 5931 | const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true); | 5972 | const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true); |
| 5932 | try func.genCopy(switch (math.order(dst_ty.abiSize(zcu), src_ty.abiSize(zcu))) { | 5973 | try func.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) { |
| 5933 | .lt => dst_ty, | 5974 | .lt => dst_ty, |
| 5934 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, | 5975 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, |
| 5935 | .gt => src_ty, | 5976 | .gt => src_ty, |
| ... | @@ -5940,17 +5981,18 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5940,17 +5981,18 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 5940 | if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and | 5981 | if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and |
| 5941 | dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv; | 5982 | dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv; |
| 5942 | 5983 | ||
| 5943 | const abi_size = dst_ty.abiSize(zcu); | 5984 | const abi_size = dst_ty.abiSize(pt); |
| 5944 | const bit_size = dst_ty.bitSize(zcu); | 5985 | const bit_size = dst_ty.bitSize(pt); |
| 5945 | if (abi_size * 8 <= bit_size) break :result dst_mcv; | 5986 | if (abi_size * 8 <= bit_size) break :result dst_mcv; |
| 5946 | 5987 | ||
| 5947 | return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(zcu), dst_ty.fmt(zcu) }); | 5988 | return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(pt), dst_ty.fmt(pt) }); |
| 5948 | }; | 5989 | }; |
| 5949 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 5990 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 5950 | } | 5991 | } |
| 5951 | 5992 | ||
| 5952 | fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void { | 5993 | fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 5953 | const zcu = func.bin_file.comp.module.?; | 5994 | const pt = func.pt; |
| 5995 | const zcu = pt.zcu; | ||
| 5954 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5996 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5955 | 5997 | ||
| 5956 | const slice_ty = func.typeOfIndex(inst); | 5998 | const slice_ty = func.typeOfIndex(inst); |
| ... | @@ -5959,11 +6001,11 @@ fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -5959,11 +6001,11 @@ fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 5959 | const array_ty = ptr_ty.childType(zcu); | 6001 | const array_ty = ptr_ty.childType(zcu); |
| 5960 | const array_len = array_ty.arrayLen(zcu); | 6002 | const array_len = array_ty.arrayLen(zcu); |
| 5961 | 6003 | ||
| 5962 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | 6004 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); |
| 5963 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); | 6005 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); |
| 5964 | try func.genSetMem( | 6006 | try func.genSetMem( |
| 5965 | .{ .frame = frame_index }, | 6007 | .{ .frame = frame_index }, |
| 5966 | @intCast(ptr_ty.abiSize(zcu)), | 6008 | @intCast(ptr_ty.abiSize(pt)), |
| 5967 | Type.usize, | 6009 | Type.usize, |
| 5968 | .{ .immediate = array_len }, | 6010 | .{ .immediate = array_len }, |
| 5969 | ); | 6011 | ); |
| ... | @@ -6015,7 +6057,8 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr | ... | @@ -6015,7 +6057,8 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 6015 | } | 6057 | } |
| 6016 | 6058 | ||
| 6017 | fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | 6059 | fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 6018 | const zcu = func.bin_file.comp.module.?; | 6060 | const pt = func.pt; |
| 6061 | const zcu = pt.zcu; | ||
| 6019 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6062 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6020 | 6063 | ||
| 6021 | result: { | 6064 | result: { |
| ... | @@ -6037,7 +6080,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -6037,7 +6080,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 6037 | }; | 6080 | }; |
| 6038 | defer if (src_val_lock) |lock| func.register_manager.unlockReg(lock); | 6081 | defer if (src_val_lock) |lock| func.register_manager.unlockReg(lock); |
| 6039 | 6082 | ||
| 6040 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); | 6083 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt)); |
| 6041 | 6084 | ||
| 6042 | if (elem_abi_size == 1) { | 6085 | if (elem_abi_size == 1) { |
| 6043 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | 6086 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { |
| ... | @@ -6068,7 +6111,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -6068,7 +6111,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 6068 | switch (dst_ptr_ty.ptrSize(zcu)) { | 6111 | switch (dst_ptr_ty.ptrSize(zcu)) { |
| 6069 | .Slice => return func.fail("TODO: airMemset Slices", .{}), | 6112 | .Slice => return func.fail("TODO: airMemset Slices", .{}), |
| 6070 | .One => { | 6113 | .One => { |
| 6071 | const elem_ptr_ty = try zcu.singleMutPtrType(elem_ty); | 6114 | const elem_ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 6072 | 6115 | ||
| 6073 | const len = dst_ptr_ty.childType(zcu).arrayLen(zcu); | 6116 | const len = dst_ptr_ty.childType(zcu).arrayLen(zcu); |
| 6074 | 6117 | ||
| ... | @@ -6110,7 +6153,8 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6110,7 +6153,8 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void { |
| 6110 | } | 6153 | } |
| 6111 | 6154 | ||
| 6112 | fn airErrorName(func: *Func, inst: Air.Inst.Index) !void { | 6155 | fn airErrorName(func: *Func, inst: Air.Inst.Index) !void { |
| 6113 | const zcu = func.bin_file.comp.module.?; | 6156 | const pt = func.pt; |
| 6157 | const zcu = pt.zcu; | ||
| 6114 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6158 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6115 | 6159 | ||
| 6116 | const err_ty = func.typeOf(un_op); | 6160 | const err_ty = func.typeOf(un_op); |
| ... | @@ -6126,7 +6170,7 @@ fn airErrorName(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6126,7 +6170,7 @@ fn airErrorName(func: *Func, inst: Air.Inst.Index) !void { |
| 6126 | // this is now the base address of the error name table | 6170 | // this is now the base address of the error name table |
| 6127 | const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, zcu); | 6171 | const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, zcu); |
| 6128 | if (func.bin_file.cast(link.File.Elf)) |elf_file| { | 6172 | if (func.bin_file.cast(link.File.Elf)) |elf_file| { |
| 6129 | const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err| | 6173 | const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err| |
| 6130 | return func.fail("{s} creating lazy symbol", .{@errorName(err)}); | 6174 | return func.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 6131 | const sym = elf_file.symbol(sym_index); | 6175 | const sym = elf_file.symbol(sym_index); |
| 6132 | try func.genSetReg(Type.usize, addr_reg, .{ .load_symbol = .{ .sym = sym.esym_index } }); | 6176 | try func.genSetReg(Type.usize, addr_reg, .{ .load_symbol = .{ .sym = sym.esym_index } }); |
| ... | @@ -6239,7 +6283,8 @@ fn airReduce(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6239,7 +6283,8 @@ fn airReduce(func: *Func, inst: Air.Inst.Index) !void { |
| 6239 | } | 6283 | } |
| 6240 | 6284 | ||
| 6241 | fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | 6285 | fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6242 | const zcu = func.bin_file.comp.module.?; | 6286 | const pt = func.pt; |
| 6287 | const zcu = pt.zcu; | ||
| 6243 | const result_ty = func.typeOfIndex(inst); | 6288 | const result_ty = func.typeOfIndex(inst); |
| 6244 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | 6289 | const len: usize = @intCast(result_ty.arrayLen(zcu)); |
| 6245 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6290 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -6248,21 +6293,21 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6248,21 +6293,21 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6248 | const result: MCValue = result: { | 6293 | const result: MCValue = result: { |
| 6249 | switch (result_ty.zigTypeTag(zcu)) { | 6294 | switch (result_ty.zigTypeTag(zcu)) { |
| 6250 | .Struct => { | 6295 | .Struct => { |
| 6251 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | 6296 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); |
| 6252 | if (result_ty.containerLayout(zcu) == .@"packed") { | 6297 | if (result_ty.containerLayout(zcu) == .@"packed") { |
| 6253 | const struct_obj = zcu.typeToStruct(result_ty).?; | 6298 | const struct_obj = zcu.typeToStruct(result_ty).?; |
| 6254 | try func.genInlineMemset( | 6299 | try func.genInlineMemset( |
| 6255 | .{ .lea_frame = .{ .index = frame_index } }, | 6300 | .{ .lea_frame = .{ .index = frame_index } }, |
| 6256 | .{ .immediate = 0 }, | 6301 | .{ .immediate = 0 }, |
| 6257 | .{ .immediate = result_ty.abiSize(zcu) }, | 6302 | .{ .immediate = result_ty.abiSize(pt) }, |
| 6258 | ); | 6303 | ); |
| 6259 | 6304 | ||
| 6260 | for (elements, 0..) |elem, elem_i_usize| { | 6305 | for (elements, 0..) |elem, elem_i_usize| { |
| 6261 | const elem_i: u32 = @intCast(elem_i_usize); | 6306 | const elem_i: u32 = @intCast(elem_i_usize); |
| 6262 | if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue; | 6307 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 6263 | 6308 | ||
| 6264 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | 6309 | const elem_ty = result_ty.structFieldType(elem_i, zcu); |
| 6265 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu)); | 6310 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt)); |
| 6266 | if (elem_bit_size > 64) { | 6311 | if (elem_bit_size > 64) { |
| 6267 | return func.fail( | 6312 | return func.fail( |
| 6268 | "TODO airAggregateInit implement packed structs with large fields", | 6313 | "TODO airAggregateInit implement packed structs with large fields", |
| ... | @@ -6270,9 +6315,9 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6270,9 +6315,9 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6270 | ); | 6315 | ); |
| 6271 | } | 6316 | } |
| 6272 | 6317 | ||
| 6273 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | 6318 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 6274 | const elem_abi_bits = elem_abi_size * 8; | 6319 | const elem_abi_bits = elem_abi_size * 8; |
| 6275 | const elem_off = zcu.structPackedFieldBitOffset(struct_obj, elem_i); | 6320 | const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i); |
| 6276 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); | 6321 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| 6277 | const elem_bit_off = elem_off % elem_abi_bits; | 6322 | const elem_bit_off = elem_off % elem_abi_bits; |
| 6278 | const elem_mcv = try func.resolveInst(elem); | 6323 | const elem_mcv = try func.resolveInst(elem); |
| ... | @@ -6293,10 +6338,10 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6293,10 +6338,10 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6293 | return func.fail("TODO: airAggregateInit packed structs", .{}); | 6338 | return func.fail("TODO: airAggregateInit packed structs", .{}); |
| 6294 | } | 6339 | } |
| 6295 | } else for (elements, 0..) |elem, elem_i| { | 6340 | } else for (elements, 0..) |elem, elem_i| { |
| 6296 | if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue; | 6341 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 6297 | 6342 | ||
| 6298 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | 6343 | const elem_ty = result_ty.structFieldType(elem_i, zcu); |
| 6299 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu)); | 6344 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt)); |
| 6300 | const elem_mcv = try func.resolveInst(elem); | 6345 | const elem_mcv = try func.resolveInst(elem); |
| 6301 | try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv); | 6346 | try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv); |
| 6302 | } | 6347 | } |
| ... | @@ -6304,8 +6349,8 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6304,8 +6349,8 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6304 | }, | 6349 | }, |
| 6305 | .Array => { | 6350 | .Array => { |
| 6306 | const elem_ty = result_ty.childType(zcu); | 6351 | const elem_ty = result_ty.childType(zcu); |
| 6307 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | 6352 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); |
| 6308 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | 6353 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 6309 | 6354 | ||
| 6310 | for (elements, 0..) |elem, elem_i| { | 6355 | for (elements, 0..) |elem, elem_i| { |
| 6311 | const elem_mcv = try func.resolveInst(elem); | 6356 | const elem_mcv = try func.resolveInst(elem); |
| ... | @@ -6325,7 +6370,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6325,7 +6370,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 6325 | ); | 6370 | ); |
| 6326 | break :result .{ .load_frame = .{ .index = frame_index } }; | 6371 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 6327 | }, | 6372 | }, |
| 6328 | else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(zcu)}), | 6373 | else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(pt)}), |
| 6329 | } | 6374 | } |
| 6330 | }; | 6375 | }; |
| 6331 | 6376 | ||
| ... | @@ -6364,11 +6409,11 @@ fn airMulAdd(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6364,11 +6409,11 @@ fn airMulAdd(func: *Func, inst: Air.Inst.Index) !void { |
| 6364 | } | 6409 | } |
| 6365 | 6410 | ||
| 6366 | fn resolveInst(func: *Func, ref: Air.Inst.Ref) InnerError!MCValue { | 6411 | fn resolveInst(func: *Func, ref: Air.Inst.Ref) InnerError!MCValue { |
| 6367 | const zcu = func.bin_file.comp.module.?; | 6412 | const pt = func.pt; |
| 6368 | 6413 | ||
| 6369 | // If the type has no codegen bits, no need to store it. | 6414 | // If the type has no codegen bits, no need to store it. |
| 6370 | const inst_ty = func.typeOf(ref); | 6415 | const inst_ty = func.typeOf(ref); |
| 6371 | if (!inst_ty.hasRuntimeBits(zcu)) | 6416 | if (!inst_ty.hasRuntimeBits(pt)) |
| 6372 | return .none; | 6417 | return .none; |
| 6373 | 6418 | ||
| 6374 | const mcv = if (ref.toIndex()) |inst| mcv: { | 6419 | const mcv = if (ref.toIndex()) |inst| mcv: { |
| ... | @@ -6394,9 +6439,11 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking { | ... | @@ -6394,9 +6439,11 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking { |
| 6394 | } | 6439 | } |
| 6395 | 6440 | ||
| 6396 | fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { | 6441 | fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { |
| 6397 | const zcu = func.bin_file.comp.module.?; | 6442 | const pt = func.pt; |
| 6443 | const zcu = pt.zcu; | ||
| 6398 | const result = try codegen.genTypedValue( | 6444 | const result = try codegen.genTypedValue( |
| 6399 | func.bin_file, | 6445 | func.bin_file, |
| 6446 | pt, | ||
| 6400 | func.src_loc, | 6447 | func.src_loc, |
| 6401 | val, | 6448 | val, |
| 6402 | zcu.funcOwnerDeclIndex(func.func_index), | 6449 | zcu.funcOwnerDeclIndex(func.func_index), |
| ... | @@ -6438,7 +6485,8 @@ fn resolveCallingConventionValues( | ... | @@ -6438,7 +6485,8 @@ fn resolveCallingConventionValues( |
| 6438 | fn_info: InternPool.Key.FuncType, | 6485 | fn_info: InternPool.Key.FuncType, |
| 6439 | var_args: []const Type, | 6486 | var_args: []const Type, |
| 6440 | ) !CallMCValues { | 6487 | ) !CallMCValues { |
| 6441 | const zcu = func.bin_file.comp.module.?; | 6488 | const pt = func.pt; |
| 6489 | const zcu = pt.zcu; | ||
| 6442 | const ip = &zcu.intern_pool; | 6490 | const ip = &zcu.intern_pool; |
| 6443 | 6491 | ||
| 6444 | const param_types = try func.gpa.alloc(Type, fn_info.param_types.len + var_args.len); | 6492 | const param_types = try func.gpa.alloc(Type, fn_info.param_types.len + var_args.len); |
| ... | @@ -6481,14 +6529,14 @@ fn resolveCallingConventionValues( | ... | @@ -6481,14 +6529,14 @@ fn resolveCallingConventionValues( |
| 6481 | // Return values | 6529 | // Return values |
| 6482 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | 6530 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { |
| 6483 | result.return_value = InstTracking.init(.unreach); | 6531 | result.return_value = InstTracking.init(.unreach); |
| 6484 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 6532 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6485 | result.return_value = InstTracking.init(.none); | 6533 | result.return_value = InstTracking.init(.none); |
| 6486 | } else { | 6534 | } else { |
| 6487 | var ret_tracking: [2]InstTracking = undefined; | 6535 | var ret_tracking: [2]InstTracking = undefined; |
| 6488 | var ret_tracking_i: usize = 0; | 6536 | var ret_tracking_i: usize = 0; |
| 6489 | var ret_float_reg_i: usize = 0; | 6537 | var ret_float_reg_i: usize = 0; |
| 6490 | 6538 | ||
| 6491 | const classes = mem.sliceTo(&abi.classifySystem(ret_ty, zcu), .none); | 6539 | const classes = mem.sliceTo(&abi.classifySystem(ret_ty, pt), .none); |
| 6492 | 6540 | ||
| 6493 | for (classes) |class| switch (class) { | 6541 | for (classes) |class| switch (class) { |
| 6494 | .integer => { | 6542 | .integer => { |
| ... | @@ -6521,7 +6569,7 @@ fn resolveCallingConventionValues( | ... | @@ -6521,7 +6569,7 @@ fn resolveCallingConventionValues( |
| 6521 | }; | 6569 | }; |
| 6522 | 6570 | ||
| 6523 | result.return_value = switch (ret_tracking_i) { | 6571 | result.return_value = switch (ret_tracking_i) { |
| 6524 | else => return func.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(zcu), ret_tracking_i }), | 6572 | else => return func.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(pt), ret_tracking_i }), |
| 6525 | 1 => ret_tracking[0], | 6573 | 1 => ret_tracking[0], |
| 6526 | 2 => InstTracking.init(.{ .register_pair = .{ | 6574 | 2 => InstTracking.init(.{ .register_pair = .{ |
| 6527 | ret_tracking[0].short.register, ret_tracking[1].short.register, | 6575 | ret_tracking[0].short.register, ret_tracking[1].short.register, |
| ... | @@ -6532,7 +6580,7 @@ fn resolveCallingConventionValues( | ... | @@ -6532,7 +6580,7 @@ fn resolveCallingConventionValues( |
| 6532 | var param_float_reg_i: usize = 0; | 6580 | var param_float_reg_i: usize = 0; |
| 6533 | 6581 | ||
| 6534 | for (param_types, result.args) |ty, *arg| { | 6582 | for (param_types, result.args) |ty, *arg| { |
| 6535 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 6583 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6536 | assert(cc == .Unspecified); | 6584 | assert(cc == .Unspecified); |
| 6537 | arg.* = .none; | 6585 | arg.* = .none; |
| 6538 | continue; | 6586 | continue; |
| ... | @@ -6541,7 +6589,7 @@ fn resolveCallingConventionValues( | ... | @@ -6541,7 +6589,7 @@ fn resolveCallingConventionValues( |
| 6541 | var arg_mcv: [2]MCValue = undefined; | 6589 | var arg_mcv: [2]MCValue = undefined; |
| 6542 | var arg_mcv_i: usize = 0; | 6590 | var arg_mcv_i: usize = 0; |
| 6543 | 6591 | ||
| 6544 | const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none); | 6592 | const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none); |
| 6545 | 6593 | ||
| 6546 | for (classes) |class| switch (class) { | 6594 | for (classes) |class| switch (class) { |
| 6547 | .integer => { | 6595 | .integer => { |
| ... | @@ -6576,7 +6624,7 @@ fn resolveCallingConventionValues( | ... | @@ -6576,7 +6624,7 @@ fn resolveCallingConventionValues( |
| 6576 | else => return func.fail("TODO: C calling convention arg class {}", .{class}), | 6624 | else => return func.fail("TODO: C calling convention arg class {}", .{class}), |
| 6577 | } else { | 6625 | } else { |
| 6578 | arg.* = switch (arg_mcv_i) { | 6626 | arg.* = switch (arg_mcv_i) { |
| 6579 | else => return func.fail("ty {} took {} tracking arg indices", .{ ty.fmt(zcu), arg_mcv_i }), | 6627 | else => return func.fail("ty {} took {} tracking arg indices", .{ ty.fmt(pt), arg_mcv_i }), |
| 6580 | 1 => arg_mcv[0], | 6628 | 1 => arg_mcv[0], |
| 6581 | 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } }, | 6629 | 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } }, |
| 6582 | }; | 6630 | }; |
| ... | @@ -6621,12 +6669,14 @@ fn parseRegName(name: []const u8) ?Register { | ... | @@ -6621,12 +6669,14 @@ fn parseRegName(name: []const u8) ?Register { |
| 6621 | } | 6669 | } |
| 6622 | 6670 | ||
| 6623 | fn typeOf(func: *Func, inst: Air.Inst.Ref) Type { | 6671 | fn typeOf(func: *Func, inst: Air.Inst.Ref) Type { |
| 6624 | const zcu = func.bin_file.comp.module.?; | 6672 | const pt = func.pt; |
| 6673 | const zcu = pt.zcu; | ||
| 6625 | return func.air.typeOf(inst, &zcu.intern_pool); | 6674 | return func.air.typeOf(inst, &zcu.intern_pool); |
| 6626 | } | 6675 | } |
| 6627 | 6676 | ||
| 6628 | fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type { | 6677 | fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type { |
| 6629 | const zcu = func.bin_file.comp.module.?; | 6678 | const pt = func.pt; |
| 6679 | const zcu = pt.zcu; | ||
| 6630 | return func.air.typeOfIndex(inst, &zcu.intern_pool); | 6680 | return func.air.typeOfIndex(inst, &zcu.intern_pool); |
| 6631 | } | 6681 | } |
| 6632 | 6682 | ||
| ... | @@ -6634,40 +6684,41 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool { | ... | @@ -6634,40 +6684,41 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool { |
| 6634 | return Target.riscv.featureSetHas(func.target.cpu.features, feature); | 6684 | return Target.riscv.featureSetHas(func.target.cpu.features, feature); |
| 6635 | } | 6685 | } |
| 6636 | 6686 | ||
| 6637 | pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 { | 6687 | pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { |
| 6638 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | 6688 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; |
| 6639 | const payload_align = payload_ty.abiAlignment(zcu); | 6689 | const payload_align = payload_ty.abiAlignment(pt); |
| 6640 | const error_align = Type.anyerror.abiAlignment(zcu); | 6690 | const error_align = Type.anyerror.abiAlignment(pt); |
| 6641 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 6691 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6642 | return 0; | 6692 | return 0; |
| 6643 | } else { | 6693 | } else { |
| 6644 | return payload_align.forward(Type.anyerror.abiSize(zcu)); | 6694 | return payload_align.forward(Type.anyerror.abiSize(pt)); |
| 6645 | } | 6695 | } |
| 6646 | } | 6696 | } |
| 6647 | 6697 | ||
| 6648 | pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 { | 6698 | pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { |
| 6649 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | 6699 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; |
| 6650 | const payload_align = payload_ty.abiAlignment(zcu); | 6700 | const payload_align = payload_ty.abiAlignment(pt); |
| 6651 | const error_align = Type.anyerror.abiAlignment(zcu); | 6701 | const error_align = Type.anyerror.abiAlignment(pt); |
| 6652 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 6702 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6653 | return error_align.forward(payload_ty.abiSize(zcu)); | 6703 | return error_align.forward(payload_ty.abiSize(pt)); |
| 6654 | } else { | 6704 | } else { |
| 6655 | return 0; | 6705 | return 0; |
| 6656 | } | 6706 | } |
| 6657 | } | 6707 | } |
| 6658 | 6708 | ||
| 6659 | fn promoteInt(func: *Func, ty: Type) Type { | 6709 | fn promoteInt(func: *Func, ty: Type) Type { |
| 6660 | const mod = func.bin_file.comp.module.?; | 6710 | const pt = func.pt; |
| 6711 | const zcu = pt.zcu; | ||
| 6661 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { | 6712 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { |
| 6662 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, | 6713 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, |
| 6663 | else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty, | 6714 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, |
| 6664 | }; | 6715 | }; |
| 6665 | for ([_]Type{ | 6716 | for ([_]Type{ |
| 6666 | Type.c_int, Type.c_uint, | 6717 | Type.c_int, Type.c_uint, |
| 6667 | Type.c_long, Type.c_ulong, | 6718 | Type.c_long, Type.c_ulong, |
| 6668 | Type.c_longlong, Type.c_ulonglong, | 6719 | Type.c_longlong, Type.c_ulonglong, |
| 6669 | }) |promote_ty| { | 6720 | }) |promote_ty| { |
| 6670 | const promote_info = promote_ty.intInfo(mod); | 6721 | const promote_info = promote_ty.intInfo(zcu); |
| 6671 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; | 6722 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; |
| 6672 | if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and | 6723 | if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and |
| 6673 | promote_info.signedness == .signed) <= promote_info.bits) return promote_ty; | 6724 | promote_info.signedness == .signed) <= promote_info.bits) return promote_ty; |
src/arch/riscv64/Emit.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | //! This file contains the functionality for emitting RISC-V MIR as machine code | 1 | //! This file contains the functionality for emitting RISC-V MIR as machine code |
| 2 | 2 | ||
| 3 | bin_file: *link.File, | ||
| 3 | lower: Lower, | 4 | lower: Lower, |
| 4 | debug_output: DebugInfoOutput, | 5 | debug_output: DebugInfoOutput, |
| 5 | code: *std.ArrayList(u8), | 6 | code: *std.ArrayList(u8), |
| ... | @@ -48,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -48,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 48 | .Lib => emit.lower.link_mode == .static, | 49 | .Lib => emit.lower.link_mode == .static, |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| { | 52 | if (emit.bin_file.cast(link.File.Elf)) |elf_file| { |
| 52 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; | 53 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; |
| 53 | const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index); | 54 | const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index); |
| 54 | const sym = elf_file.symbol(sym_index); | 55 | const sym = elf_file.symbol(sym_index); |
| ... | @@ -77,7 +78,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -77,7 +78,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 77 | } else return emit.fail("TODO: load_symbol_reloc non-ELF", .{}); | 78 | } else return emit.fail("TODO: load_symbol_reloc non-ELF", .{}); |
| 78 | }, | 79 | }, |
| 79 | .call_extern_fn_reloc => |symbol| { | 80 | .call_extern_fn_reloc => |symbol| { |
| 80 | if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| { | 81 | if (emit.bin_file.cast(link.File.Elf)) |elf_file| { |
| 81 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; | 82 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; |
| 82 | 83 | ||
| 83 | const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT); | 84 | const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT); |
src/arch/riscv64/Lower.zig+6-6| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | //! This file contains the functionality for lowering RISC-V MIR to Instructions | 1 | //! This file contains the functionality for lowering RISC-V MIR to Instructions |
| 2 | 2 | ||
| 3 | bin_file: *link.File, | 3 | pt: Zcu.PerThread, |
| 4 | output_mode: std.builtin.OutputMode, | 4 | output_mode: std.builtin.OutputMode, |
| 5 | link_mode: std.builtin.LinkMode, | 5 | link_mode: std.builtin.LinkMode, |
| 6 | pic: bool, | 6 | pic: bool, |
| ... | @@ -44,7 +44,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -44,7 +44,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 44 | insts: []const Instruction, | 44 | insts: []const Instruction, |
| 45 | relocs: []const Reloc, | 45 | relocs: []const Reloc, |
| 46 | } { | 46 | } { |
| 47 | const zcu = lower.bin_file.comp.module.?; | 47 | const pt = lower.pt; |
| 48 | 48 | ||
| 49 | lower.result_insts = undefined; | 49 | lower.result_insts = undefined; |
| 50 | lower.result_relocs = undefined; | 50 | lower.result_relocs = undefined; |
| ... | @@ -243,11 +243,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -243,11 +243,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 243 | 243 | ||
| 244 | const class = rs1.class(); | 244 | const class = rs1.class(); |
| 245 | const ty = compare.ty; | 245 | const ty = compare.ty; |
| 246 | const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(zcu)) catch { | 246 | const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(pt)) catch { |
| 247 | return lower.fail("pseudo_compare size {}", .{ty.bitSize(zcu)}); | 247 | return lower.fail("pseudo_compare size {}", .{ty.bitSize(pt)}); |
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | const is_unsigned = ty.isUnsignedInt(zcu); | 250 | const is_unsigned = ty.isUnsignedInt(pt.zcu); |
| 251 | 251 | ||
| 252 | const less_than: Encoding.Mnemonic = if (is_unsigned) .sltu else .slt; | 252 | const less_than: Encoding.Mnemonic = if (is_unsigned) .sltu else .slt; |
| 253 | 253 | ||
| ... | @@ -502,7 +502,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { | ... | @@ -502,7 +502,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool { | 504 | fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool { |
| 505 | const target = lower.bin_file.comp.module.?.getTarget(); | 505 | const target = lower.pt.zcu.getTarget(); |
| 506 | const features = target.cpu.features; | 506 | const features = target.cpu.features; |
| 507 | return std.Target.riscv.featureSetHas(features, feature); | 507 | return std.Target.riscv.featureSetHas(features, feature); |
| 508 | } | 508 | } |
src/arch/riscv64/abi.zig+28-27| ... | @@ -9,15 +9,15 @@ const assert = std.debug.assert; | ... | @@ -9,15 +9,15 @@ const assert = std.debug.assert; |
| 9 | 9 | ||
| 10 | pub const Class = enum { memory, byval, integer, double_integer, fields }; | 10 | pub const Class = enum { memory, byval, integer, double_integer, fields }; |
| 11 | 11 | ||
| 12 | pub fn classifyType(ty: Type, mod: *Zcu) Class { | 12 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { |
| 13 | const target = mod.getTarget(); | 13 | const target = pt.zcu.getTarget(); |
| 14 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 14 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 15 | 15 | ||
| 16 | const max_byval_size = target.ptrBitWidth() * 2; | 16 | const max_byval_size = target.ptrBitWidth() * 2; |
| 17 | switch (ty.zigTypeTag(mod)) { | 17 | switch (ty.zigTypeTag(pt.zcu)) { |
| 18 | .Struct => { | 18 | .Struct => { |
| 19 | const bit_size = ty.bitSize(mod); | 19 | const bit_size = ty.bitSize(pt); |
| 20 | if (ty.containerLayout(mod) == .@"packed") { | 20 | if (ty.containerLayout(pt.zcu) == .@"packed") { |
| 21 | if (bit_size > max_byval_size) return .memory; | 21 | if (bit_size > max_byval_size) return .memory; |
| 22 | return .byval; | 22 | return .byval; |
| 23 | } | 23 | } |
| ... | @@ -25,12 +25,12 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { | ... | @@ -25,12 +25,12 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { |
| 25 | if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: { | 25 | if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: { |
| 26 | var any_fp = false; | 26 | var any_fp = false; |
| 27 | var field_count: usize = 0; | 27 | var field_count: usize = 0; |
| 28 | for (0..ty.structFieldCount(mod)) |field_index| { | 28 | for (0..ty.structFieldCount(pt.zcu)) |field_index| { |
| 29 | const field_ty = ty.structFieldType(field_index, mod); | 29 | const field_ty = ty.structFieldType(field_index, pt.zcu); |
| 30 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 30 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 31 | if (field_ty.isRuntimeFloat()) | 31 | if (field_ty.isRuntimeFloat()) |
| 32 | any_fp = true | 32 | any_fp = true |
| 33 | else if (!field_ty.isAbiInt(mod)) | 33 | else if (!field_ty.isAbiInt(pt.zcu)) |
| 34 | break :fields; | 34 | break :fields; |
| 35 | field_count += 1; | 35 | field_count += 1; |
| 36 | if (field_count > 2) break :fields; | 36 | if (field_count > 2) break :fields; |
| ... | @@ -45,8 +45,8 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { | ... | @@ -45,8 +45,8 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { |
| 45 | return .integer; | 45 | return .integer; |
| 46 | }, | 46 | }, |
| 47 | .Union => { | 47 | .Union => { |
| 48 | const bit_size = ty.bitSize(mod); | 48 | const bit_size = ty.bitSize(pt); |
| 49 | if (ty.containerLayout(mod) == .@"packed") { | 49 | if (ty.containerLayout(pt.zcu) == .@"packed") { |
| 50 | if (bit_size > max_byval_size) return .memory; | 50 | if (bit_size > max_byval_size) return .memory; |
| 51 | return .byval; | 51 | return .byval; |
| 52 | } | 52 | } |
| ... | @@ -58,21 +58,21 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { | ... | @@ -58,21 +58,21 @@ pub fn classifyType(ty: Type, mod: *Zcu) Class { |
| 58 | .Bool => return .integer, | 58 | .Bool => return .integer, |
| 59 | .Float => return .byval, | 59 | .Float => return .byval, |
| 60 | .Int, .Enum, .ErrorSet => { | 60 | .Int, .Enum, .ErrorSet => { |
| 61 | const bit_size = ty.bitSize(mod); | 61 | const bit_size = ty.bitSize(pt); |
| 62 | if (bit_size > max_byval_size) return .memory; | 62 | if (bit_size > max_byval_size) return .memory; |
| 63 | return .byval; | 63 | return .byval; |
| 64 | }, | 64 | }, |
| 65 | .Vector => { | 65 | .Vector => { |
| 66 | const bit_size = ty.bitSize(mod); | 66 | const bit_size = ty.bitSize(pt); |
| 67 | if (bit_size > max_byval_size) return .memory; | 67 | if (bit_size > max_byval_size) return .memory; |
| 68 | return .integer; | 68 | return .integer; |
| 69 | }, | 69 | }, |
| 70 | .Optional => { | 70 | .Optional => { |
| 71 | std.debug.assert(ty.isPtrLikeOptional(mod)); | 71 | std.debug.assert(ty.isPtrLikeOptional(pt.zcu)); |
| 72 | return .byval; | 72 | return .byval; |
| 73 | }, | 73 | }, |
| 74 | .Pointer => { | 74 | .Pointer => { |
| 75 | std.debug.assert(!ty.isSlice(mod)); | 75 | std.debug.assert(!ty.isSlice(pt.zcu)); |
| 76 | return .byval; | 76 | return .byval; |
| 77 | }, | 77 | }, |
| 78 | .ErrorUnion, | 78 | .ErrorUnion, |
| ... | @@ -97,18 +97,19 @@ pub const SystemClass = enum { integer, float, memory, none }; | ... | @@ -97,18 +97,19 @@ pub const SystemClass = enum { integer, float, memory, none }; |
| 97 | 97 | ||
| 98 | /// There are a maximum of 8 possible return slots. Returned values are in | 98 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 99 | /// the beginning of the array; unused slots are filled with .none. | 99 | /// the beginning of the array; unused slots are filled with .none. |
| 100 | pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | 100 | pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 101 | const zcu = pt.zcu; | ||
| 101 | var result = [1]SystemClass{.none} ** 8; | 102 | var result = [1]SystemClass{.none} ** 8; |
| 102 | const memory_class = [_]SystemClass{ | 103 | const memory_class = [_]SystemClass{ |
| 103 | .memory, .none, .none, .none, | 104 | .memory, .none, .none, .none, |
| 104 | .none, .none, .none, .none, | 105 | .none, .none, .none, .none, |
| 105 | }; | 106 | }; |
| 106 | switch (ty.zigTypeTag(zcu)) { | 107 | switch (ty.zigTypeTag(pt.zcu)) { |
| 107 | .Bool, .Void, .NoReturn => { | 108 | .Bool, .Void, .NoReturn => { |
| 108 | result[0] = .integer; | 109 | result[0] = .integer; |
| 109 | return result; | 110 | return result; |
| 110 | }, | 111 | }, |
| 111 | .Pointer => switch (ty.ptrSize(zcu)) { | 112 | .Pointer => switch (ty.ptrSize(pt.zcu)) { |
| 112 | .Slice => { | 113 | .Slice => { |
| 113 | result[0] = .integer; | 114 | result[0] = .integer; |
| 114 | result[1] = .integer; | 115 | result[1] = .integer; |
| ... | @@ -120,17 +121,17 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | ... | @@ -120,17 +121,17 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { |
| 120 | }, | 121 | }, |
| 121 | }, | 122 | }, |
| 122 | .Optional => { | 123 | .Optional => { |
| 123 | if (ty.isPtrLikeOptional(zcu)) { | 124 | if (ty.isPtrLikeOptional(pt.zcu)) { |
| 124 | result[0] = .integer; | 125 | result[0] = .integer; |
| 125 | return result; | 126 | return result; |
| 126 | } | 127 | } |
| 127 | result[0] = .integer; | 128 | result[0] = .integer; |
| 128 | if (ty.optionalChild(zcu).abiSize(zcu) == 0) return result; | 129 | if (ty.optionalChild(zcu).abiSize(pt) == 0) return result; |
| 129 | result[1] = .integer; | 130 | result[1] = .integer; |
| 130 | return result; | 131 | return result; |
| 131 | }, | 132 | }, |
| 132 | .Int, .Enum, .ErrorSet => { | 133 | .Int, .Enum, .ErrorSet => { |
| 133 | const int_bits = ty.intInfo(zcu).bits; | 134 | const int_bits = ty.intInfo(pt.zcu).bits; |
| 134 | if (int_bits <= 64) { | 135 | if (int_bits <= 64) { |
| 135 | result[0] = .integer; | 136 | result[0] = .integer; |
| 136 | return result; | 137 | return result; |
| ... | @@ -155,8 +156,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | ... | @@ -155,8 +156,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { |
| 155 | unreachable; // support split float args | 156 | unreachable; // support split float args |
| 156 | }, | 157 | }, |
| 157 | .ErrorUnion => { | 158 | .ErrorUnion => { |
| 158 | const payload_ty = ty.errorUnionPayload(zcu); | 159 | const payload_ty = ty.errorUnionPayload(pt.zcu); |
| 159 | const payload_bits = payload_ty.bitSize(zcu); | 160 | const payload_bits = payload_ty.bitSize(pt); |
| 160 | 161 | ||
| 161 | // the error union itself | 162 | // the error union itself |
| 162 | result[0] = .integer; | 163 | result[0] = .integer; |
| ... | @@ -167,8 +168,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | ... | @@ -167,8 +168,8 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { |
| 167 | return memory_class; | 168 | return memory_class; |
| 168 | }, | 169 | }, |
| 169 | .Struct => { | 170 | .Struct => { |
| 170 | const layout = ty.containerLayout(zcu); | 171 | const layout = ty.containerLayout(pt.zcu); |
| 171 | const ty_size = ty.abiSize(zcu); | 172 | const ty_size = ty.abiSize(pt); |
| 172 | 173 | ||
| 173 | if (layout == .@"packed") { | 174 | if (layout == .@"packed") { |
| 174 | assert(ty_size <= 16); | 175 | assert(ty_size <= 16); |
| ... | @@ -180,7 +181,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | ... | @@ -180,7 +181,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { |
| 180 | return memory_class; | 181 | return memory_class; |
| 181 | }, | 182 | }, |
| 182 | .Array => { | 183 | .Array => { |
| 183 | const ty_size = ty.abiSize(zcu); | 184 | const ty_size = ty.abiSize(pt); |
| 184 | if (ty_size <= 8) { | 185 | if (ty_size <= 8) { |
| 185 | result[0] = .integer; | 186 | result[0] = .integer; |
| 186 | return result; | 187 | return result; |
src/arch/sparc64/CodeGen.zig+125-95| ... | @@ -11,11 +11,9 @@ const Allocator = mem.Allocator; | ... | @@ -11,11 +11,9 @@ const Allocator = mem.Allocator; |
| 11 | const builtin = @import("builtin"); | 11 | const builtin = @import("builtin"); |
| 12 | const link = @import("../../link.zig"); | 12 | const link = @import("../../link.zig"); |
| 13 | const Zcu = @import("../../Zcu.zig"); | 13 | const Zcu = @import("../../Zcu.zig"); |
| 14 | /// Deprecated. | ||
| 15 | const Module = Zcu; | ||
| 16 | const InternPool = @import("../../InternPool.zig"); | 14 | const InternPool = @import("../../InternPool.zig"); |
| 17 | const Value = @import("../../Value.zig"); | 15 | const Value = @import("../../Value.zig"); |
| 18 | const ErrorMsg = Module.ErrorMsg; | 16 | const ErrorMsg = Zcu.ErrorMsg; |
| 19 | const codegen = @import("../../codegen.zig"); | 17 | const codegen = @import("../../codegen.zig"); |
| 20 | const Air = @import("../../Air.zig"); | 18 | const Air = @import("../../Air.zig"); |
| 21 | const Mir = @import("Mir.zig"); | 19 | const Mir = @import("Mir.zig"); |
| ... | @@ -52,6 +50,7 @@ const RegisterView = enum(u1) { | ... | @@ -52,6 +50,7 @@ const RegisterView = enum(u1) { |
| 52 | }; | 50 | }; |
| 53 | 51 | ||
| 54 | gpa: Allocator, | 52 | gpa: Allocator, |
| 53 | pt: Zcu.PerThread, | ||
| 55 | air: Air, | 54 | air: Air, |
| 56 | liveness: Liveness, | 55 | liveness: Liveness, |
| 57 | bin_file: *link.File, | 56 | bin_file: *link.File, |
| ... | @@ -64,7 +63,7 @@ args: []MCValue, | ... | @@ -64,7 +63,7 @@ args: []MCValue, |
| 64 | ret_mcv: MCValue, | 63 | ret_mcv: MCValue, |
| 65 | fn_type: Type, | 64 | fn_type: Type, |
| 66 | arg_index: usize, | 65 | arg_index: usize, |
| 67 | src_loc: Module.LazySrcLoc, | 66 | src_loc: Zcu.LazySrcLoc, |
| 68 | stack_align: Alignment, | 67 | stack_align: Alignment, |
| 69 | 68 | ||
| 70 | /// MIR Instructions | 69 | /// MIR Instructions |
| ... | @@ -263,15 +262,16 @@ const BigTomb = struct { | ... | @@ -263,15 +262,16 @@ const BigTomb = struct { |
| 263 | 262 | ||
| 264 | pub fn generate( | 263 | pub fn generate( |
| 265 | lf: *link.File, | 264 | lf: *link.File, |
| 266 | src_loc: Module.LazySrcLoc, | 265 | pt: Zcu.PerThread, |
| 266 | src_loc: Zcu.LazySrcLoc, | ||
| 267 | func_index: InternPool.Index, | 267 | func_index: InternPool.Index, |
| 268 | air: Air, | 268 | air: Air, |
| 269 | liveness: Liveness, | 269 | liveness: Liveness, |
| 270 | code: *std.ArrayList(u8), | 270 | code: *std.ArrayList(u8), |
| 271 | debug_output: DebugInfoOutput, | 271 | debug_output: DebugInfoOutput, |
| 272 | ) CodeGenError!Result { | 272 | ) CodeGenError!Result { |
| 273 | const gpa = lf.comp.gpa; | 273 | const zcu = pt.zcu; |
| 274 | const zcu = lf.comp.module.?; | 274 | const gpa = zcu.gpa; |
| 275 | const func = zcu.funcInfo(func_index); | 275 | const func = zcu.funcInfo(func_index); |
| 276 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 276 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 277 | assert(fn_owner_decl.has_tv); | 277 | assert(fn_owner_decl.has_tv); |
| ... | @@ -289,11 +289,12 @@ pub fn generate( | ... | @@ -289,11 +289,12 @@ pub fn generate( |
| 289 | 289 | ||
| 290 | var function = Self{ | 290 | var function = Self{ |
| 291 | .gpa = gpa, | 291 | .gpa = gpa, |
| 292 | .pt = pt, | ||
| 292 | .air = air, | 293 | .air = air, |
| 293 | .liveness = liveness, | 294 | .liveness = liveness, |
| 294 | .target = target, | 295 | .target = target, |
| 295 | .func_index = func_index, | ||
| 296 | .bin_file = lf, | 296 | .bin_file = lf, |
| 297 | .func_index = func_index, | ||
| 297 | .code = code, | 298 | .code = code, |
| 298 | .debug_output = debug_output, | 299 | .debug_output = debug_output, |
| 299 | .err_msg = null, | 300 | .err_msg = null, |
| ... | @@ -365,7 +366,8 @@ pub fn generate( | ... | @@ -365,7 +366,8 @@ pub fn generate( |
| 365 | } | 366 | } |
| 366 | 367 | ||
| 367 | fn gen(self: *Self) !void { | 368 | fn gen(self: *Self) !void { |
| 368 | const mod = self.bin_file.comp.module.?; | 369 | const pt = self.pt; |
| 370 | const mod = pt.zcu; | ||
| 369 | const cc = self.fn_type.fnCallingConvention(mod); | 371 | const cc = self.fn_type.fnCallingConvention(mod); |
| 370 | if (cc != .Naked) { | 372 | if (cc != .Naked) { |
| 371 | // TODO Finish function prologue and epilogue for sparc64. | 373 | // TODO Finish function prologue and epilogue for sparc64. |
| ... | @@ -493,7 +495,8 @@ fn gen(self: *Self) !void { | ... | @@ -493,7 +495,8 @@ fn gen(self: *Self) !void { |
| 493 | } | 495 | } |
| 494 | 496 | ||
| 495 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | 497 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 496 | const mod = self.bin_file.comp.module.?; | 498 | const pt = self.pt; |
| 499 | const mod = pt.zcu; | ||
| 497 | const ip = &mod.intern_pool; | 500 | const ip = &mod.intern_pool; |
| 498 | const air_tags = self.air.instructions.items(.tag); | 501 | const air_tags = self.air.instructions.items(.tag); |
| 499 | 502 | ||
| ... | @@ -757,7 +760,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -757,7 +760,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 757 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 760 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 758 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 761 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 759 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 762 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 760 | const mod = self.bin_file.comp.module.?; | 763 | const pt = self.pt; |
| 764 | const mod = pt.zcu; | ||
| 761 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 765 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 762 | const lhs = try self.resolveInst(extra.lhs); | 766 | const lhs = try self.resolveInst(extra.lhs); |
| 763 | const rhs = try self.resolveInst(extra.rhs); | 767 | const rhs = try self.resolveInst(extra.rhs); |
| ... | @@ -835,7 +839,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -835,7 +839,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 835 | } | 839 | } |
| 836 | 840 | ||
| 837 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 841 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 838 | const mod = self.bin_file.comp.module.?; | 842 | const pt = self.pt; |
| 843 | const mod = pt.zcu; | ||
| 839 | const vector_ty = self.typeOfIndex(inst); | 844 | const vector_ty = self.typeOfIndex(inst); |
| 840 | const len = vector_ty.vectorLen(mod); | 845 | const len = vector_ty.vectorLen(mod); |
| 841 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 846 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -869,7 +874,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -869,7 +874,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 869 | } | 874 | } |
| 870 | 875 | ||
| 871 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | 876 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 872 | const mod = self.bin_file.comp.module.?; | 877 | const pt = self.pt; |
| 878 | const mod = pt.zcu; | ||
| 873 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 879 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 874 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 880 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 875 | const ptr_ty = self.typeOf(ty_op.operand); | 881 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -1006,7 +1012,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1006,7 +1012,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 1006 | } | 1012 | } |
| 1007 | 1013 | ||
| 1008 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { | 1014 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1009 | const mod = self.bin_file.comp.module.?; | 1015 | const pt = self.pt; |
| 1010 | const arg_index = self.arg_index; | 1016 | const arg_index = self.arg_index; |
| 1011 | self.arg_index += 1; | 1017 | self.arg_index += 1; |
| 1012 | 1018 | ||
| ... | @@ -1016,8 +1022,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1016,8 +1022,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1016 | const mcv = blk: { | 1022 | const mcv = blk: { |
| 1017 | switch (arg) { | 1023 | switch (arg) { |
| 1018 | .stack_offset => |off| { | 1024 | .stack_offset => |off| { |
| 1019 | const abi_size = math.cast(u32, ty.abiSize(mod)) orelse { | 1025 | const abi_size = math.cast(u32, ty.abiSize(pt)) orelse { |
| 1020 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)}); | 1026 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)}); |
| 1021 | }; | 1027 | }; |
| 1022 | const offset = off + abi_size; | 1028 | const offset = off + abi_size; |
| 1023 | break :blk MCValue{ .stack_offset = offset }; | 1029 | break :blk MCValue{ .stack_offset = offset }; |
| ... | @@ -1205,7 +1211,8 @@ fn airBreakpoint(self: *Self) !void { | ... | @@ -1205,7 +1211,8 @@ fn airBreakpoint(self: *Self) !void { |
| 1205 | } | 1211 | } |
| 1206 | 1212 | ||
| 1207 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { | 1213 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 1208 | const mod = self.bin_file.comp.module.?; | 1214 | const pt = self.pt; |
| 1215 | const mod = pt.zcu; | ||
| 1209 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1216 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1210 | 1217 | ||
| 1211 | // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you. | 1218 | // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you. |
| ... | @@ -1228,7 +1235,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1228,7 +1235,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 1228 | if (int_info.bits == 8) break :result operand; | 1235 | if (int_info.bits == 8) break :result operand; |
| 1229 | 1236 | ||
| 1230 | const abi_size = int_info.bits >> 3; | 1237 | const abi_size = int_info.bits >> 3; |
| 1231 | const abi_align = operand_ty.abiAlignment(mod); | 1238 | const abi_align = operand_ty.abiAlignment(pt); |
| 1232 | const opposite_endian_asi = switch (self.target.cpu.arch.endian()) { | 1239 | const opposite_endian_asi = switch (self.target.cpu.arch.endian()) { |
| 1233 | Endian.big => ASI.asi_primary_little, | 1240 | Endian.big => ASI.asi_primary_little, |
| 1234 | Endian.little => ASI.asi_primary, | 1241 | Endian.little => ASI.asi_primary, |
| ... | @@ -1297,7 +1304,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -1297,7 +1304,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 1297 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 1304 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 1298 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len])); | 1305 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len])); |
| 1299 | const ty = self.typeOf(callee); | 1306 | const ty = self.typeOf(callee); |
| 1300 | const mod = self.bin_file.comp.module.?; | 1307 | const pt = self.pt; |
| 1308 | const mod = pt.zcu; | ||
| 1301 | const fn_ty = switch (ty.zigTypeTag(mod)) { | 1309 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 1302 | .Fn => ty, | 1310 | .Fn => ty, |
| 1303 | .Pointer => ty.childType(mod), | 1311 | .Pointer => ty.childType(mod), |
| ... | @@ -1341,7 +1349,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -1341,7 +1349,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 1341 | 1349 | ||
| 1342 | // Due to incremental compilation, how function calls are generated depends | 1350 | // Due to incremental compilation, how function calls are generated depends |
| 1343 | // on linking. | 1351 | // on linking. |
| 1344 | if (try self.air.value(callee, mod)) |func_value| { | 1352 | if (try self.air.value(callee, pt)) |func_value| { |
| 1345 | if (self.bin_file.tag == link.File.Elf.base_tag) { | 1353 | if (self.bin_file.tag == link.File.Elf.base_tag) { |
| 1346 | switch (mod.intern_pool.indexToKey(func_value.ip_index)) { | 1354 | switch (mod.intern_pool.indexToKey(func_value.ip_index)) { |
| 1347 | .func => |func| { | 1355 | .func => |func| { |
| ... | @@ -1429,7 +1437,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1429,7 +1437,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 1429 | 1437 | ||
| 1430 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | 1438 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1431 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 1439 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1432 | const mod = self.bin_file.comp.module.?; | 1440 | const pt = self.pt; |
| 1441 | const mod = pt.zcu; | ||
| 1433 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1442 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1434 | const lhs = try self.resolveInst(bin_op.lhs); | 1443 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1435 | const rhs = try self.resolveInst(bin_op.rhs); | 1444 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -1444,7 +1453,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -1444,7 +1453,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1444 | .ErrorSet => Type.u16, | 1453 | .ErrorSet => Type.u16, |
| 1445 | .Optional => blk: { | 1454 | .Optional => blk: { |
| 1446 | const payload_ty = lhs_ty.optionalChild(mod); | 1455 | const payload_ty = lhs_ty.optionalChild(mod); |
| 1447 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1456 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1448 | break :blk Type.u1; | 1457 | break :blk Type.u1; |
| 1449 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | 1458 | } else if (lhs_ty.isPtrLikeOptional(mod)) { |
| 1450 | break :blk Type.usize; | 1459 | break :blk Type.usize; |
| ... | @@ -1655,7 +1664,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1655,7 +1664,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 1655 | } | 1664 | } |
| 1656 | 1665 | ||
| 1657 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | 1666 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 1658 | const mod = self.bin_file.comp.module.?; | 1667 | const pt = self.pt; |
| 1668 | const mod = pt.zcu; | ||
| 1659 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1669 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1660 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 1670 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 1661 | const func = mod.funcInfo(extra.data.func); | 1671 | const func = mod.funcInfo(extra.data.func); |
| ... | @@ -1753,7 +1763,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1753,7 +1763,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1753 | if (self.liveness.isUnused(inst)) | 1763 | if (self.liveness.isUnused(inst)) |
| 1754 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); | 1764 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 1755 | 1765 | ||
| 1756 | const mod = self.bin_file.comp.module.?; | 1766 | const pt = self.pt; |
| 1767 | const mod = pt.zcu; | ||
| 1757 | const operand_ty = self.typeOf(ty_op.operand); | 1768 | const operand_ty = self.typeOf(ty_op.operand); |
| 1758 | const operand = try self.resolveInst(ty_op.operand); | 1769 | const operand = try self.resolveInst(ty_op.operand); |
| 1759 | const info_a = operand_ty.intInfo(mod); | 1770 | const info_a = operand_ty.intInfo(mod); |
| ... | @@ -1814,12 +1825,13 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1814,12 +1825,13 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 1814 | } | 1825 | } |
| 1815 | 1826 | ||
| 1816 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | 1827 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1817 | const mod = self.bin_file.comp.module.?; | 1828 | const pt = self.pt; |
| 1829 | const mod = pt.zcu; | ||
| 1818 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1830 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1819 | const elem_ty = self.typeOfIndex(inst); | 1831 | const elem_ty = self.typeOfIndex(inst); |
| 1820 | const elem_size = elem_ty.abiSize(mod); | 1832 | const elem_size = elem_ty.abiSize(pt); |
| 1821 | const result: MCValue = result: { | 1833 | const result: MCValue = result: { |
| 1822 | if (!elem_ty.hasRuntimeBits(mod)) | 1834 | if (!elem_ty.hasRuntimeBits(pt)) |
| 1823 | break :result MCValue.none; | 1835 | break :result MCValue.none; |
| 1824 | 1836 | ||
| 1825 | const ptr = try self.resolveInst(ty_op.operand); | 1837 | const ptr = try self.resolveInst(ty_op.operand); |
| ... | @@ -1898,7 +1910,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1898,7 +1910,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 1898 | const rhs = try self.resolveInst(bin_op.rhs); | 1910 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1899 | const lhs_ty = self.typeOf(bin_op.lhs); | 1911 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 1900 | const rhs_ty = self.typeOf(bin_op.rhs); | 1912 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 1901 | assert(lhs_ty.eql(rhs_ty, self.bin_file.comp.module.?)); | 1913 | assert(lhs_ty.eql(rhs_ty, self.pt.zcu)); |
| 1902 | 1914 | ||
| 1903 | if (self.liveness.isUnused(inst)) | 1915 | if (self.liveness.isUnused(inst)) |
| 1904 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); | 1916 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -2040,7 +2052,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2040,7 +2052,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2040 | //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 2052 | //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 2041 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2053 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2042 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2054 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2043 | const mod = self.bin_file.comp.module.?; | 2055 | const pt = self.pt; |
| 2056 | const mod = pt.zcu; | ||
| 2044 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2057 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2045 | const lhs = try self.resolveInst(extra.lhs); | 2058 | const lhs = try self.resolveInst(extra.lhs); |
| 2046 | const rhs = try self.resolveInst(extra.rhs); | 2059 | const rhs = try self.resolveInst(extra.rhs); |
| ... | @@ -2104,7 +2117,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2104,7 +2117,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2104 | 2117 | ||
| 2105 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { | 2118 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 2106 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2119 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2107 | const mod = self.bin_file.comp.module.?; | 2120 | const pt = self.pt; |
| 2121 | const mod = pt.zcu; | ||
| 2108 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2122 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2109 | const operand = try self.resolveInst(ty_op.operand); | 2123 | const operand = try self.resolveInst(ty_op.operand); |
| 2110 | const operand_ty = self.typeOf(ty_op.operand); | 2124 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -2336,7 +2350,8 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2336,7 +2350,8 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 2336 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 2350 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2337 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2351 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2338 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2352 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2339 | const mod = self.bin_file.comp.module.?; | 2353 | const pt = self.pt; |
| 2354 | const mod = pt.zcu; | ||
| 2340 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2355 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2341 | const lhs = try self.resolveInst(extra.lhs); | 2356 | const lhs = try self.resolveInst(extra.lhs); |
| 2342 | const rhs = try self.resolveInst(extra.rhs); | 2357 | const rhs = try self.resolveInst(extra.rhs); |
| ... | @@ -2441,7 +2456,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2441,7 +2456,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 2441 | } | 2456 | } |
| 2442 | 2457 | ||
| 2443 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | 2458 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2444 | const mod = self.bin_file.comp.module.?; | 2459 | const pt = self.pt; |
| 2460 | const mod = pt.zcu; | ||
| 2445 | const is_volatile = false; // TODO | 2461 | const is_volatile = false; // TODO |
| 2446 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2462 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2447 | 2463 | ||
| ... | @@ -2452,7 +2468,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2452,7 +2468,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2452 | 2468 | ||
| 2453 | const slice_ty = self.typeOf(bin_op.lhs); | 2469 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2454 | const elem_ty = slice_ty.childType(mod); | 2470 | const elem_ty = slice_ty.childType(mod); |
| 2455 | const elem_size = elem_ty.abiSize(mod); | 2471 | const elem_size = elem_ty.abiSize(pt); |
| 2456 | 2472 | ||
| 2457 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | 2473 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| 2458 | 2474 | ||
| ... | @@ -2566,10 +2582,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2566,10 +2582,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2566 | const operand = extra.struct_operand; | 2582 | const operand = extra.struct_operand; |
| 2567 | const index = extra.field_index; | 2583 | const index = extra.field_index; |
| 2568 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2584 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2569 | const mod = self.bin_file.comp.module.?; | 2585 | const pt = self.pt; |
| 2570 | const mcv = try self.resolveInst(operand); | 2586 | const mcv = try self.resolveInst(operand); |
| 2571 | const struct_ty = self.typeOf(operand); | 2587 | const struct_ty = self.typeOf(operand); |
| 2572 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod))); | 2588 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); |
| 2573 | 2589 | ||
| 2574 | switch (mcv) { | 2590 | switch (mcv) { |
| 2575 | .dead, .unreach => unreachable, | 2591 | .dead, .unreach => unreachable, |
| ... | @@ -2699,13 +2715,14 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2699,13 +2715,14 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 2699 | } | 2715 | } |
| 2700 | 2716 | ||
| 2701 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | 2717 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2702 | const mod = self.bin_file.comp.module.?; | 2718 | const pt = self.pt; |
| 2719 | const mod = pt.zcu; | ||
| 2703 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2720 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2704 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2721 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2705 | const error_union_ty = self.typeOf(ty_op.operand); | 2722 | const error_union_ty = self.typeOf(ty_op.operand); |
| 2706 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2723 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2707 | const mcv = try self.resolveInst(ty_op.operand); | 2724 | const mcv = try self.resolveInst(ty_op.operand); |
| 2708 | if (!payload_ty.hasRuntimeBits(mod)) break :result mcv; | 2725 | if (!payload_ty.hasRuntimeBits(pt)) break :result mcv; |
| 2709 | 2726 | ||
| 2710 | return self.fail("TODO implement unwrap error union error for non-empty payloads", .{}); | 2727 | return self.fail("TODO implement unwrap error union error for non-empty payloads", .{}); |
| 2711 | }; | 2728 | }; |
| ... | @@ -2713,12 +2730,13 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2713,12 +2730,13 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2713 | } | 2730 | } |
| 2714 | 2731 | ||
| 2715 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { | 2732 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2716 | const mod = self.bin_file.comp.module.?; | 2733 | const pt = self.pt; |
| 2734 | const mod = pt.zcu; | ||
| 2717 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2735 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2718 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2736 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2719 | const error_union_ty = self.typeOf(ty_op.operand); | 2737 | const error_union_ty = self.typeOf(ty_op.operand); |
| 2720 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2738 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2721 | if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none; | 2739 | if (!payload_ty.hasRuntimeBits(pt)) break :result MCValue.none; |
| 2722 | 2740 | ||
| 2723 | return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{}); | 2741 | return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{}); |
| 2724 | }; | 2742 | }; |
| ... | @@ -2727,13 +2745,14 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2727,13 +2745,14 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2727 | 2745 | ||
| 2728 | /// E to E!T | 2746 | /// E to E!T |
| 2729 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 2747 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2730 | const mod = self.bin_file.comp.module.?; | 2748 | const pt = self.pt; |
| 2749 | const mod = pt.zcu; | ||
| 2731 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2750 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2732 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2751 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2733 | const error_union_ty = ty_op.ty.toType(); | 2752 | const error_union_ty = ty_op.ty.toType(); |
| 2734 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 2753 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2735 | const mcv = try self.resolveInst(ty_op.operand); | 2754 | const mcv = try self.resolveInst(ty_op.operand); |
| 2736 | if (!payload_ty.hasRuntimeBits(mod)) break :result mcv; | 2755 | if (!payload_ty.hasRuntimeBits(pt)) break :result mcv; |
| 2737 | 2756 | ||
| 2738 | return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); | 2757 | return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); |
| 2739 | }; | 2758 | }; |
| ... | @@ -2748,13 +2767,13 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2748,13 +2767,13 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2748 | } | 2767 | } |
| 2749 | 2768 | ||
| 2750 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | 2769 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2751 | const mod = self.bin_file.comp.module.?; | 2770 | const pt = self.pt; |
| 2752 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2771 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2753 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2772 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2754 | const optional_ty = self.typeOfIndex(inst); | 2773 | const optional_ty = self.typeOfIndex(inst); |
| 2755 | 2774 | ||
| 2756 | // Optional with a zero-bit payload type is just a boolean true | 2775 | // Optional with a zero-bit payload type is just a boolean true |
| 2757 | if (optional_ty.abiSize(mod) == 1) | 2776 | if (optional_ty.abiSize(pt) == 1) |
| 2758 | break :result MCValue{ .immediate = 1 }; | 2777 | break :result MCValue{ .immediate = 1 }; |
| 2759 | 2778 | ||
| 2760 | return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch}); | 2779 | return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch}); |
| ... | @@ -2788,10 +2807,11 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme | ... | @@ -2788,10 +2807,11 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme |
| 2788 | 2807 | ||
| 2789 | /// Use a pointer instruction as the basis for allocating stack memory. | 2808 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2790 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | 2809 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2791 | const mod = self.bin_file.comp.module.?; | 2810 | const pt = self.pt; |
| 2811 | const mod = pt.zcu; | ||
| 2792 | const elem_ty = self.typeOfIndex(inst).childType(mod); | 2812 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 2793 | 2813 | ||
| 2794 | if (!elem_ty.hasRuntimeBits(mod)) { | 2814 | if (!elem_ty.hasRuntimeBits(pt)) { |
| 2795 | // As this stack item will never be dereferenced at runtime, | 2815 | // As this stack item will never be dereferenced at runtime, |
| 2796 | // return the stack offset 0. Stack offset 0 will be where all | 2816 | // return the stack offset 0. Stack offset 0 will be where all |
| 2797 | // zero-sized stack allocations live as non-zero-sized | 2817 | // zero-sized stack allocations live as non-zero-sized |
| ... | @@ -2799,21 +2819,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | ... | @@ -2799,21 +2819,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2799 | return @as(u32, 0); | 2819 | return @as(u32, 0); |
| 2800 | } | 2820 | } |
| 2801 | 2821 | ||
| 2802 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 2822 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 2803 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 2823 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 2804 | }; | 2824 | }; |
| 2805 | // TODO swap this for inst.ty.ptrAlign | 2825 | // TODO swap this for inst.ty.ptrAlign |
| 2806 | const abi_align = elem_ty.abiAlignment(mod); | 2826 | const abi_align = elem_ty.abiAlignment(pt); |
| 2807 | return self.allocMem(inst, abi_size, abi_align); | 2827 | return self.allocMem(inst, abi_size, abi_align); |
| 2808 | } | 2828 | } |
| 2809 | 2829 | ||
| 2810 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | 2830 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 2811 | const mod = self.bin_file.comp.module.?; | 2831 | const pt = self.pt; |
| 2812 | const elem_ty = self.typeOfIndex(inst); | 2832 | const elem_ty = self.typeOfIndex(inst); |
| 2813 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { | 2833 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { |
| 2814 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); | 2834 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 2815 | }; | 2835 | }; |
| 2816 | const abi_align = elem_ty.abiAlignment(mod); | 2836 | const abi_align = elem_ty.abiAlignment(pt); |
| 2817 | self.stack_align = self.stack_align.max(abi_align); | 2837 | self.stack_align = self.stack_align.max(abi_align); |
| 2818 | 2838 | ||
| 2819 | if (reg_ok) { | 2839 | if (reg_ok) { |
| ... | @@ -2855,7 +2875,8 @@ fn binOp( | ... | @@ -2855,7 +2875,8 @@ fn binOp( |
| 2855 | rhs_ty: Type, | 2875 | rhs_ty: Type, |
| 2856 | metadata: ?BinOpMetadata, | 2876 | metadata: ?BinOpMetadata, |
| 2857 | ) InnerError!MCValue { | 2877 | ) InnerError!MCValue { |
| 2858 | const mod = self.bin_file.comp.module.?; | 2878 | const pt = self.pt; |
| 2879 | const mod = pt.zcu; | ||
| 2859 | switch (tag) { | 2880 | switch (tag) { |
| 2860 | .add, | 2881 | .add, |
| 2861 | .sub, | 2882 | .sub, |
| ... | @@ -2996,7 +3017,7 @@ fn binOp( | ... | @@ -2996,7 +3017,7 @@ fn binOp( |
| 2996 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | 3017 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type |
| 2997 | else => ptr_ty.childType(mod), | 3018 | else => ptr_ty.childType(mod), |
| 2998 | }; | 3019 | }; |
| 2999 | const elem_size = elem_ty.abiSize(mod); | 3020 | const elem_size = elem_ty.abiSize(pt); |
| 3000 | 3021 | ||
| 3001 | if (elem_size == 1) { | 3022 | if (elem_size == 1) { |
| 3002 | const base_tag: Mir.Inst.Tag = switch (tag) { | 3023 | const base_tag: Mir.Inst.Tag = switch (tag) { |
| ... | @@ -3396,8 +3417,8 @@ fn binOpRegister( | ... | @@ -3396,8 +3417,8 @@ fn binOpRegister( |
| 3396 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { | 3417 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 3397 | const block_data = self.blocks.getPtr(block).?; | 3418 | const block_data = self.blocks.getPtr(block).?; |
| 3398 | 3419 | ||
| 3399 | const mod = self.bin_file.comp.module.?; | 3420 | const pt = self.pt; |
| 3400 | if (self.typeOf(operand).hasRuntimeBits(mod)) { | 3421 | if (self.typeOf(operand).hasRuntimeBits(pt)) { |
| 3401 | const operand_mcv = try self.resolveInst(operand); | 3422 | const operand_mcv = try self.resolveInst(operand); |
| 3402 | const block_mcv = block_data.mcv; | 3423 | const block_mcv = block_data.mcv; |
| 3403 | if (block_mcv == .none) { | 3424 | if (block_mcv == .none) { |
| ... | @@ -3516,17 +3537,18 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void { | ... | @@ -3516,17 +3537,18 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void { |
| 3516 | 3537 | ||
| 3517 | /// Given an error union, returns the payload | 3538 | /// Given an error union, returns the payload |
| 3518 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 3539 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { |
| 3519 | const mod = self.bin_file.comp.module.?; | 3540 | const pt = self.pt; |
| 3541 | const mod = pt.zcu; | ||
| 3520 | const err_ty = error_union_ty.errorUnionSet(mod); | 3542 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3521 | const payload_ty = error_union_ty.errorUnionPayload(mod); | 3543 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3522 | if (err_ty.errorSetIsEmpty(mod)) { | 3544 | if (err_ty.errorSetIsEmpty(mod)) { |
| 3523 | return error_union_mcv; | 3545 | return error_union_mcv; |
| 3524 | } | 3546 | } |
| 3525 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3547 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3526 | return MCValue.none; | 3548 | return MCValue.none; |
| 3527 | } | 3549 | } |
| 3528 | 3550 | ||
| 3529 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod))); | 3551 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); |
| 3530 | switch (error_union_mcv) { | 3552 | switch (error_union_mcv) { |
| 3531 | .register => return self.fail("TODO errUnionPayload for registers", .{}), | 3553 | .register => return self.fail("TODO errUnionPayload for registers", .{}), |
| 3532 | .stack_offset => |off| { | 3554 | .stack_offset => |off| { |
| ... | @@ -3587,7 +3609,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live | ... | @@ -3587,7 +3609,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live |
| 3587 | } | 3609 | } |
| 3588 | 3610 | ||
| 3589 | fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { | 3611 | fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 3590 | const mod = self.bin_file.comp.module.?; | 3612 | const pt = self.pt; |
| 3613 | const mod = pt.zcu; | ||
| 3591 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; | 3614 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 3592 | const ty = arg.ty.toType(); | 3615 | const ty = arg.ty.toType(); |
| 3593 | const owner_decl = mod.funcOwnerDeclIndex(self.func_index); | 3616 | const owner_decl = mod.funcOwnerDeclIndex(self.func_index); |
| ... | @@ -3736,7 +3759,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg | ... | @@ -3736,7 +3759,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg |
| 3736 | } | 3759 | } |
| 3737 | 3760 | ||
| 3738 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 3761 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 3739 | const mod = self.bin_file.comp.module.?; | 3762 | const pt = self.pt; |
| 3740 | switch (mcv) { | 3763 | switch (mcv) { |
| 3741 | .dead => unreachable, | 3764 | .dead => unreachable, |
| 3742 | .unreach, .none => return, // Nothing to do. | 3765 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -3935,20 +3958,21 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -3935,20 +3958,21 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3935 | // The value is in memory at a hard-coded address. | 3958 | // The value is in memory at a hard-coded address. |
| 3936 | // If the type is a pointer, it means the pointer address is at this memory location. | 3959 | // If the type is a pointer, it means the pointer address is at this memory location. |
| 3937 | try self.genSetReg(ty, reg, .{ .immediate = addr }); | 3960 | try self.genSetReg(ty, reg, .{ .immediate = addr }); |
| 3938 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(mod)); | 3961 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(pt)); |
| 3939 | }, | 3962 | }, |
| 3940 | .stack_offset => |off| { | 3963 | .stack_offset => |off| { |
| 3941 | const real_offset = realStackOffset(off); | 3964 | const real_offset = realStackOffset(off); |
| 3942 | const simm13 = math.cast(i13, real_offset) orelse | 3965 | const simm13 = math.cast(i13, real_offset) orelse |
| 3943 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); | 3966 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3944 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(mod)); | 3967 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(pt)); |
| 3945 | }, | 3968 | }, |
| 3946 | } | 3969 | } |
| 3947 | } | 3970 | } |
| 3948 | 3971 | ||
| 3949 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { | 3972 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 3950 | const mod = self.bin_file.comp.module.?; | 3973 | const pt = self.pt; |
| 3951 | const abi_size = ty.abiSize(mod); | 3974 | const mod = pt.zcu; |
| 3975 | const abi_size = ty.abiSize(pt); | ||
| 3952 | switch (mcv) { | 3976 | switch (mcv) { |
| 3953 | .dead => unreachable, | 3977 | .dead => unreachable, |
| 3954 | .unreach, .none => return, // Nothing to do. | 3978 | .unreach, .none => return, // Nothing to do. |
| ... | @@ -3956,7 +3980,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3956,7 +3980,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3956 | if (!self.wantSafety()) | 3980 | if (!self.wantSafety()) |
| 3957 | return; // The already existing value will do just fine. | 3981 | return; // The already existing value will do just fine. |
| 3958 | // TODO Upgrade this to a memset call when we have that available. | 3982 | // TODO Upgrade this to a memset call when we have that available. |
| 3959 | switch (ty.abiSize(mod)) { | 3983 | switch (ty.abiSize(pt)) { |
| 3960 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), | 3984 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), |
| 3961 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), | 3985 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 3962 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), | 3986 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| ... | @@ -3986,7 +4010,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3986,7 +4010,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3986 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); | 4010 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); |
| 3987 | 4011 | ||
| 3988 | const overflow_bit_ty = ty.structFieldType(1, mod); | 4012 | const overflow_bit_ty = ty.structFieldType(1, mod); |
| 3989 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, mod))); | 4013 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt))); |
| 3990 | const cond_reg = try self.register_manager.allocReg(null, gp); | 4014 | const cond_reg = try self.register_manager.allocReg(null, gp); |
| 3991 | 4015 | ||
| 3992 | // TODO handle floating point CCRs | 4016 | // TODO handle floating point CCRs |
| ... | @@ -4032,7 +4056,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -4032,7 +4056,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4032 | const reg = try self.copyToTmpRegister(ty, mcv); | 4056 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 4033 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 4057 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 4034 | } else { | 4058 | } else { |
| 4035 | const ptr_ty = try mod.singleMutPtrType(ty); | 4059 | const ptr_ty = try pt.singleMutPtrType(ty); |
| 4036 | 4060 | ||
| 4037 | const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, gp); | 4061 | const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, gp); |
| 4038 | const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs); | 4062 | const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs); |
| ... | @@ -4121,12 +4145,13 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re | ... | @@ -4121,12 +4145,13 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re |
| 4121 | } | 4145 | } |
| 4122 | 4146 | ||
| 4123 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | 4147 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 4124 | const mod = self.bin_file.comp.module.?; | 4148 | const pt = self.pt; |
| 4125 | const mcv: MCValue = switch (try codegen.genTypedValue( | 4149 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 4126 | self.bin_file, | 4150 | self.bin_file, |
| 4151 | pt, | ||
| 4127 | self.src_loc, | 4152 | self.src_loc, |
| 4128 | val, | 4153 | val, |
| 4129 | mod.funcOwnerDeclIndex(self.func_index), | 4154 | pt.zcu.funcOwnerDeclIndex(self.func_index), |
| 4130 | )) { | 4155 | )) { |
| 4131 | .mcv => |mcv| switch (mcv) { | 4156 | .mcv => |mcv| switch (mcv) { |
| 4132 | .none => .none, | 4157 | .none => .none, |
| ... | @@ -4157,14 +4182,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -4157,14 +4182,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 4157 | } | 4182 | } |
| 4158 | 4183 | ||
| 4159 | fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue { | 4184 | fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue { |
| 4160 | const mod = self.bin_file.comp.module.?; | 4185 | const pt = self.pt; |
| 4186 | const mod = pt.zcu; | ||
| 4161 | const error_type = ty.errorUnionSet(mod); | 4187 | const error_type = ty.errorUnionSet(mod); |
| 4162 | const payload_type = ty.errorUnionPayload(mod); | 4188 | const payload_type = ty.errorUnionPayload(mod); |
| 4163 | 4189 | ||
| 4164 | if (!error_type.hasRuntimeBits(mod)) { | 4190 | if (!error_type.hasRuntimeBits(pt)) { |
| 4165 | return MCValue{ .immediate = 0 }; // always false | 4191 | return MCValue{ .immediate = 0 }; // always false |
| 4166 | } else if (!payload_type.hasRuntimeBits(mod)) { | 4192 | } else if (!payload_type.hasRuntimeBits(pt)) { |
| 4167 | if (error_type.abiSize(mod) <= 8) { | 4193 | if (error_type.abiSize(pt) <= 8) { |
| 4168 | const reg_mcv: MCValue = switch (operand) { | 4194 | const reg_mcv: MCValue = switch (operand) { |
| 4169 | .register => operand, | 4195 | .register => operand, |
| 4170 | else => .{ .register = try self.copyToTmpRegister(error_type, operand) }, | 4196 | else => .{ .register = try self.copyToTmpRegister(error_type, operand) }, |
| ... | @@ -4255,9 +4281,10 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { | ... | @@ -4255,9 +4281,10 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { |
| 4255 | } | 4281 | } |
| 4256 | 4282 | ||
| 4257 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { | 4283 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 4258 | const mod = self.bin_file.comp.module.?; | 4284 | const pt = self.pt; |
| 4285 | const mod = pt.zcu; | ||
| 4259 | const elem_ty = ptr_ty.childType(mod); | 4286 | const elem_ty = ptr_ty.childType(mod); |
| 4260 | const elem_size = elem_ty.abiSize(mod); | 4287 | const elem_size = elem_ty.abiSize(pt); |
| 4261 | 4288 | ||
| 4262 | switch (ptr) { | 4289 | switch (ptr) { |
| 4263 | .none => unreachable, | 4290 | .none => unreachable, |
| ... | @@ -4326,7 +4353,8 @@ fn minMax( | ... | @@ -4326,7 +4353,8 @@ fn minMax( |
| 4326 | lhs_ty: Type, | 4353 | lhs_ty: Type, |
| 4327 | rhs_ty: Type, | 4354 | rhs_ty: Type, |
| 4328 | ) InnerError!MCValue { | 4355 | ) InnerError!MCValue { |
| 4329 | const mod = self.bin_file.comp.module.?; | 4356 | const pt = self.pt; |
| 4357 | const mod = pt.zcu; | ||
| 4330 | assert(lhs_ty.eql(rhs_ty, mod)); | 4358 | assert(lhs_ty.eql(rhs_ty, mod)); |
| 4331 | switch (lhs_ty.zigTypeTag(mod)) { | 4359 | switch (lhs_ty.zigTypeTag(mod)) { |
| 4332 | .Float => return self.fail("TODO min/max on floats", .{}), | 4360 | .Float => return self.fail("TODO min/max on floats", .{}), |
| ... | @@ -4446,7 +4474,8 @@ fn realStackOffset(off: u32) u32 { | ... | @@ -4446,7 +4474,8 @@ fn realStackOffset(off: u32) u32 { |
| 4446 | 4474 | ||
| 4447 | /// Caller must call `CallMCValues.deinit`. | 4475 | /// Caller must call `CallMCValues.deinit`. |
| 4448 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { | 4476 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { |
| 4449 | const mod = self.bin_file.comp.module.?; | 4477 | const pt = self.pt; |
| 4478 | const mod = pt.zcu; | ||
| 4450 | const ip = &mod.intern_pool; | 4479 | const ip = &mod.intern_pool; |
| 4451 | const fn_info = mod.typeToFunc(fn_ty).?; | 4480 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 4452 | const cc = fn_info.cc; | 4481 | const cc = fn_info.cc; |
| ... | @@ -4487,7 +4516,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) | ... | @@ -4487,7 +4516,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4487 | }; | 4516 | }; |
| 4488 | 4517 | ||
| 4489 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { | 4518 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 4490 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(mod))); | 4519 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))); |
| 4491 | if (param_size <= 8) { | 4520 | if (param_size <= 8) { |
| 4492 | if (next_register < argument_registers.len) { | 4521 | if (next_register < argument_registers.len) { |
| 4493 | result_arg.* = .{ .register = argument_registers[next_register] }; | 4522 | result_arg.* = .{ .register = argument_registers[next_register] }; |
| ... | @@ -4516,10 +4545,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) | ... | @@ -4516,10 +4545,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4516 | 4545 | ||
| 4517 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 4546 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 4518 | result.return_value = .{ .unreach = {} }; | 4547 | result.return_value = .{ .unreach = {} }; |
| 4519 | } else if (!ret_ty.hasRuntimeBits(mod)) { | 4548 | } else if (!ret_ty.hasRuntimeBits(pt)) { |
| 4520 | result.return_value = .{ .none = {} }; | 4549 | result.return_value = .{ .none = {} }; |
| 4521 | } else { | 4550 | } else { |
| 4522 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod))); | 4551 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); |
| 4523 | // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller. | 4552 | // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller. |
| 4524 | if (ret_ty_size <= 8) { | 4553 | if (ret_ty_size <= 8) { |
| 4525 | result.return_value = switch (role) { | 4554 | result.return_value = switch (role) { |
| ... | @@ -4538,21 +4567,22 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) | ... | @@ -4538,21 +4567,22 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4538 | } | 4567 | } |
| 4539 | 4568 | ||
| 4540 | fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | 4569 | fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 4541 | const mod = self.bin_file.comp.module.?; | 4570 | const pt = self.pt; |
| 4542 | const ty = self.typeOf(ref); | 4571 | const ty = self.typeOf(ref); |
| 4543 | 4572 | ||
| 4544 | // If the type has no codegen bits, no need to store it. | 4573 | // If the type has no codegen bits, no need to store it. |
| 4545 | if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 4574 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 4546 | 4575 | ||
| 4547 | if (ref.toIndex()) |inst| { | 4576 | if (ref.toIndex()) |inst| { |
| 4548 | return self.getResolvedInstValue(inst); | 4577 | return self.getResolvedInstValue(inst); |
| 4549 | } | 4578 | } |
| 4550 | 4579 | ||
| 4551 | return self.genTypedValue((try self.air.value(ref, mod)).?); | 4580 | return self.genTypedValue((try self.air.value(ref, pt)).?); |
| 4552 | } | 4581 | } |
| 4553 | 4582 | ||
| 4554 | fn ret(self: *Self, mcv: MCValue) !void { | 4583 | fn ret(self: *Self, mcv: MCValue) !void { |
| 4555 | const mod = self.bin_file.comp.module.?; | 4584 | const pt = self.pt; |
| 4585 | const mod = pt.zcu; | ||
| 4556 | const ret_ty = self.fn_type.fnReturnType(mod); | 4586 | const ret_ty = self.fn_type.fnReturnType(mod); |
| 4557 | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); | 4587 | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); |
| 4558 | 4588 | ||
| ... | @@ -4654,8 +4684,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void | ... | @@ -4654,8 +4684,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void |
| 4654 | } | 4684 | } |
| 4655 | 4685 | ||
| 4656 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 4686 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 4657 | const mod = self.bin_file.comp.module.?; | 4687 | const pt = self.pt; |
| 4658 | const abi_size = value_ty.abiSize(mod); | 4688 | const abi_size = value_ty.abiSize(pt); |
| 4659 | 4689 | ||
| 4660 | switch (ptr) { | 4690 | switch (ptr) { |
| 4661 | .none => unreachable, | 4691 | .none => unreachable, |
| ... | @@ -4696,11 +4726,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -4696,11 +4726,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 4696 | 4726 | ||
| 4697 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 4727 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4698 | return if (self.liveness.isUnused(inst)) .dead else result: { | 4728 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 4699 | const mod = self.bin_file.comp.module.?; | 4729 | const pt = self.pt; |
| 4730 | const mod = pt.zcu; | ||
| 4700 | const mcv = try self.resolveInst(operand); | 4731 | const mcv = try self.resolveInst(operand); |
| 4701 | const ptr_ty = self.typeOf(operand); | 4732 | const ptr_ty = self.typeOf(operand); |
| 4702 | const struct_ty = ptr_ty.childType(mod); | 4733 | const struct_ty = ptr_ty.childType(mod); |
| 4703 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod))); | 4734 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); |
| 4704 | switch (mcv) { | 4735 | switch (mcv) { |
| 4705 | .ptr_stack_offset => |off| { | 4736 | .ptr_stack_offset => |off| { |
| 4706 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; | 4737 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| ... | @@ -4738,7 +4769,8 @@ fn trunc( | ... | @@ -4738,7 +4769,8 @@ fn trunc( |
| 4738 | operand_ty: Type, | 4769 | operand_ty: Type, |
| 4739 | dest_ty: Type, | 4770 | dest_ty: Type, |
| 4740 | ) !MCValue { | 4771 | ) !MCValue { |
| 4741 | const mod = self.bin_file.comp.module.?; | 4772 | const pt = self.pt; |
| 4773 | const mod = pt.zcu; | ||
| 4742 | const info_a = operand_ty.intInfo(mod); | 4774 | const info_a = operand_ty.intInfo(mod); |
| 4743 | const info_b = dest_ty.intInfo(mod); | 4775 | const info_b = dest_ty.intInfo(mod); |
| 4744 | 4776 | ||
| ... | @@ -4848,7 +4880,7 @@ fn truncRegister( | ... | @@ -4848,7 +4880,7 @@ fn truncRegister( |
| 4848 | } | 4880 | } |
| 4849 | } | 4881 | } |
| 4850 | 4882 | ||
| 4851 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. | 4883 | /// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`. |
| 4852 | fn wantSafety(self: *Self) bool { | 4884 | fn wantSafety(self: *Self) bool { |
| 4853 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | 4885 | return switch (self.bin_file.comp.root_mod.optimize_mode) { |
| 4854 | .Debug => true, | 4886 | .Debug => true, |
| ... | @@ -4859,11 +4891,9 @@ fn wantSafety(self: *Self) bool { | ... | @@ -4859,11 +4891,9 @@ fn wantSafety(self: *Self) bool { |
| 4859 | } | 4891 | } |
| 4860 | 4892 | ||
| 4861 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { | 4893 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 4862 | const mod = self.bin_file.comp.module.?; | 4894 | return self.air.typeOf(inst, &self.pt.zcu.intern_pool); |
| 4863 | return self.air.typeOf(inst, &mod.intern_pool); | ||
| 4864 | } | 4895 | } |
| 4865 | 4896 | ||
| 4866 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { | 4897 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 4867 | const mod = self.bin_file.comp.module.?; | 4898 | return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool); |
| 4868 | return self.air.typeOfIndex(inst, &mod.intern_pool); | ||
| 4869 | } | 4899 | } |
src/arch/sparc64/Emit.zig+2-4| ... | @@ -6,9 +6,7 @@ const Endian = std.builtin.Endian; | ... | @@ -6,9 +6,7 @@ const Endian = std.builtin.Endian; |
| 6 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 7 | const link = @import("../../link.zig"); | 7 | const link = @import("../../link.zig"); |
| 8 | const Zcu = @import("../../Zcu.zig"); | 8 | const Zcu = @import("../../Zcu.zig"); |
| 9 | /// Deprecated. | 9 | const ErrorMsg = Zcu.ErrorMsg; |
| 10 | const Module = Zcu; | ||
| 11 | const ErrorMsg = Module.ErrorMsg; | ||
| 12 | const Liveness = @import("../../Liveness.zig"); | 10 | const Liveness = @import("../../Liveness.zig"); |
| 13 | const log = std.log.scoped(.sparcv9_emit); | 11 | const log = std.log.scoped(.sparcv9_emit); |
| 14 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; | 12 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; |
| ... | @@ -24,7 +22,7 @@ bin_file: *link.File, | ... | @@ -24,7 +22,7 @@ bin_file: *link.File, |
| 24 | debug_output: DebugInfoOutput, | 22 | debug_output: DebugInfoOutput, |
| 25 | target: *const std.Target, | 23 | target: *const std.Target, |
| 26 | err_msg: ?*ErrorMsg = null, | 24 | err_msg: ?*ErrorMsg = null, |
| 27 | src_loc: Module.LazySrcLoc, | 25 | src_loc: Zcu.LazySrcLoc, |
| 28 | code: *std.ArrayList(u8), | 26 | code: *std.ArrayList(u8), |
| 29 | 27 | ||
| 30 | prev_di_line: u32, | 28 | prev_di_line: u32, |
src/arch/wasm/CodeGen.zig+532-429| ... | @@ -684,6 +684,7 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .{}, | ... | @@ -684,6 +684,7 @@ simd_immediates: std.ArrayListUnmanaged([16]u8) = .{}, |
| 684 | target: std.Target, | 684 | target: std.Target, |
| 685 | /// Represents the wasm binary file that is being linked. | 685 | /// Represents the wasm binary file that is being linked. |
| 686 | bin_file: *link.File.Wasm, | 686 | bin_file: *link.File.Wasm, |
| 687 | pt: Zcu.PerThread, | ||
| 687 | /// List of MIR Instructions | 688 | /// List of MIR Instructions |
| 688 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, | 689 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 689 | /// Contains extra data for MIR | 690 | /// Contains extra data for MIR |
| ... | @@ -764,8 +765,7 @@ pub fn deinit(func: *CodeGen) void { | ... | @@ -764,8 +765,7 @@ pub fn deinit(func: *CodeGen) void { |
| 764 | 765 | ||
| 765 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig | 766 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig |
| 766 | fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError { | 767 | fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError { |
| 767 | const mod = func.bin_file.base.comp.module.?; | 768 | const src_loc = func.decl.navSrcLoc(func.pt.zcu); |
| 768 | const src_loc = func.decl.navSrcLoc(mod); | ||
| 769 | func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args); | 769 | func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args); |
| 770 | return error.CodegenFail; | 770 | return error.CodegenFail; |
| 771 | } | 771 | } |
| ... | @@ -788,10 +788,11 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { | ... | @@ -788,10 +788,11 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 788 | const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref); | 788 | const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref); |
| 789 | assert(!gop.found_existing); | 789 | assert(!gop.found_existing); |
| 790 | 790 | ||
| 791 | const mod = func.bin_file.base.comp.module.?; | 791 | const pt = func.pt; |
| 792 | const val = (try func.air.value(ref, mod)).?; | 792 | const mod = pt.zcu; |
| 793 | const val = (try func.air.value(ref, pt)).?; | ||
| 793 | const ty = func.typeOf(ref); | 794 | const ty = func.typeOf(ref); |
| 794 | if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) { | 795 | if (!ty.hasRuntimeBitsIgnoreComptime(pt) and !ty.isInt(mod) and !ty.isError(mod)) { |
| 795 | gop.value_ptr.* = WValue{ .none = {} }; | 796 | gop.value_ptr.* = WValue{ .none = {} }; |
| 796 | return gop.value_ptr.*; | 797 | return gop.value_ptr.*; |
| 797 | } | 798 | } |
| ... | @@ -802,8 +803,8 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { | ... | @@ -802,8 +803,8 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 802 | // | 803 | // |
| 803 | // In the other cases, we will simply lower the constant to a value that fits | 804 | // In the other cases, we will simply lower the constant to a value that fits |
| 804 | // into a single local (such as a pointer, integer, bool, etc). | 805 | // into a single local (such as a pointer, integer, bool, etc). |
| 805 | const result = if (isByRef(ty, mod)) blk: { | 806 | const result = if (isByRef(ty, pt)) blk: { |
| 806 | const sym_index = try func.bin_file.lowerUnnamedConst(val, func.decl_index); | 807 | const sym_index = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index); |
| 807 | break :blk WValue{ .memory = sym_index }; | 808 | break :blk WValue{ .memory = sym_index }; |
| 808 | } else try func.lowerConstant(val, ty); | 809 | } else try func.lowerConstant(val, ty); |
| 809 | 810 | ||
| ... | @@ -990,7 +991,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32 | ... | @@ -990,7 +991,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32 |
| 990 | } | 991 | } |
| 991 | 992 | ||
| 992 | /// Using a given `Type`, returns the corresponding type | 993 | /// Using a given `Type`, returns the corresponding type |
| 993 | fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype { | 994 | fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype { |
| 995 | const mod = pt.zcu; | ||
| 994 | const target = mod.getTarget(); | 996 | const target = mod.getTarget(); |
| 995 | const ip = &mod.intern_pool; | 997 | const ip = &mod.intern_pool; |
| 996 | return switch (ty.zigTypeTag(mod)) { | 998 | return switch (ty.zigTypeTag(mod)) { |
| ... | @@ -1002,26 +1004,26 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype { | ... | @@ -1002,26 +1004,26 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype { |
| 1002 | else => unreachable, | 1004 | else => unreachable, |
| 1003 | }, | 1005 | }, |
| 1004 | .Int, .Enum => blk: { | 1006 | .Int, .Enum => blk: { |
| 1005 | const info = ty.intInfo(mod); | 1007 | const info = ty.intInfo(pt.zcu); |
| 1006 | if (info.bits <= 32) break :blk wasm.Valtype.i32; | 1008 | if (info.bits <= 32) break :blk wasm.Valtype.i32; |
| 1007 | if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64; | 1009 | if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64; |
| 1008 | break :blk wasm.Valtype.i32; // represented as pointer to stack | 1010 | break :blk wasm.Valtype.i32; // represented as pointer to stack |
| 1009 | }, | 1011 | }, |
| 1010 | .Struct => { | 1012 | .Struct => { |
| 1011 | if (mod.typeToPackedStruct(ty)) |packed_struct| { | 1013 | if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| { |
| 1012 | return typeToValtype(Type.fromInterned(packed_struct.backingIntType(ip).*), mod); | 1014 | return typeToValtype(Type.fromInterned(packed_struct.backingIntType(ip).*), pt); |
| 1013 | } else { | 1015 | } else { |
| 1014 | return wasm.Valtype.i32; | 1016 | return wasm.Valtype.i32; |
| 1015 | } | 1017 | } |
| 1016 | }, | 1018 | }, |
| 1017 | .Vector => switch (determineSimdStoreStrategy(ty, mod)) { | 1019 | .Vector => switch (determineSimdStoreStrategy(ty, pt)) { |
| 1018 | .direct => wasm.Valtype.v128, | 1020 | .direct => wasm.Valtype.v128, |
| 1019 | .unrolled => wasm.Valtype.i32, | 1021 | .unrolled => wasm.Valtype.i32, |
| 1020 | }, | 1022 | }, |
| 1021 | .Union => switch (ty.containerLayout(mod)) { | 1023 | .Union => switch (ty.containerLayout(pt.zcu)) { |
| 1022 | .@"packed" => { | 1024 | .@"packed" => { |
| 1023 | const int_ty = mod.intType(.unsigned, @as(u16, @intCast(ty.bitSize(mod)))) catch @panic("out of memory"); | 1025 | const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory"); |
| 1024 | return typeToValtype(int_ty, mod); | 1026 | return typeToValtype(int_ty, pt); |
| 1025 | }, | 1027 | }, |
| 1026 | else => wasm.Valtype.i32, | 1028 | else => wasm.Valtype.i32, |
| 1027 | }, | 1029 | }, |
| ... | @@ -1030,17 +1032,17 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype { | ... | @@ -1030,17 +1032,17 @@ fn typeToValtype(ty: Type, mod: *Zcu) wasm.Valtype { |
| 1030 | } | 1032 | } |
| 1031 | 1033 | ||
| 1032 | /// Using a given `Type`, returns the byte representation of its wasm value type | 1034 | /// Using a given `Type`, returns the byte representation of its wasm value type |
| 1033 | fn genValtype(ty: Type, mod: *Zcu) u8 { | 1035 | fn genValtype(ty: Type, pt: Zcu.PerThread) u8 { |
| 1034 | return wasm.valtype(typeToValtype(ty, mod)); | 1036 | return wasm.valtype(typeToValtype(ty, pt)); |
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| 1037 | /// Using a given `Type`, returns the corresponding wasm value type | 1039 | /// Using a given `Type`, returns the corresponding wasm value type |
| 1038 | /// Differently from `genValtype` this also allows `void` to create a block | 1040 | /// Differently from `genValtype` this also allows `void` to create a block |
| 1039 | /// with no return type | 1041 | /// with no return type |
| 1040 | fn genBlockType(ty: Type, mod: *Zcu) u8 { | 1042 | fn genBlockType(ty: Type, pt: Zcu.PerThread) u8 { |
| 1041 | return switch (ty.ip_index) { | 1043 | return switch (ty.ip_index) { |
| 1042 | .void_type, .noreturn_type => wasm.block_empty, | 1044 | .void_type, .noreturn_type => wasm.block_empty, |
| 1043 | else => genValtype(ty, mod), | 1045 | else => genValtype(ty, pt), |
| 1044 | }; | 1046 | }; |
| 1045 | } | 1047 | } |
| 1046 | 1048 | ||
| ... | @@ -1101,8 +1103,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue { | ... | @@ -1101,8 +1103,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue { |
| 1101 | /// Creates one locals for a given `Type`. | 1103 | /// Creates one locals for a given `Type`. |
| 1102 | /// Returns a corresponding `Wvalue` with `local` as active tag | 1104 | /// Returns a corresponding `Wvalue` with `local` as active tag |
| 1103 | fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { | 1105 | fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { |
| 1104 | const mod = func.bin_file.base.comp.module.?; | 1106 | const pt = func.pt; |
| 1105 | const valtype = typeToValtype(ty, mod); | 1107 | const valtype = typeToValtype(ty, pt); |
| 1106 | switch (valtype) { | 1108 | switch (valtype) { |
| 1107 | .i32 => if (func.free_locals_i32.popOrNull()) |index| { | 1109 | .i32 => if (func.free_locals_i32.popOrNull()) |index| { |
| 1108 | log.debug("reusing local ({d}) of type {}", .{ index, valtype }); | 1110 | log.debug("reusing local ({d}) of type {}", .{ index, valtype }); |
| ... | @@ -1133,8 +1135,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { | ... | @@ -1133,8 +1135,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { |
| 1133 | /// Ensures a new local will be created. This is useful when it's useful | 1135 | /// Ensures a new local will be created. This is useful when it's useful |
| 1134 | /// to use a zero-initialized local. | 1136 | /// to use a zero-initialized local. |
| 1135 | fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue { | 1137 | fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue { |
| 1136 | const mod = func.bin_file.base.comp.module.?; | 1138 | const pt = func.pt; |
| 1137 | try func.locals.append(func.gpa, genValtype(ty, mod)); | 1139 | try func.locals.append(func.gpa, genValtype(ty, pt)); |
| 1138 | const initial_index = func.local_index; | 1140 | const initial_index = func.local_index; |
| 1139 | func.local_index += 1; | 1141 | func.local_index += 1; |
| 1140 | return WValue{ .local = .{ .value = initial_index, .references = 1 } }; | 1142 | return WValue{ .local = .{ .value = initial_index, .references = 1 } }; |
| ... | @@ -1147,23 +1149,24 @@ fn genFunctype( | ... | @@ -1147,23 +1149,24 @@ fn genFunctype( |
| 1147 | cc: std.builtin.CallingConvention, | 1149 | cc: std.builtin.CallingConvention, |
| 1148 | params: []const InternPool.Index, | 1150 | params: []const InternPool.Index, |
| 1149 | return_type: Type, | 1151 | return_type: Type, |
| 1150 | mod: *Zcu, | 1152 | pt: Zcu.PerThread, |
| 1151 | ) !wasm.Type { | 1153 | ) !wasm.Type { |
| 1154 | const mod = pt.zcu; | ||
| 1152 | var temp_params = std.ArrayList(wasm.Valtype).init(gpa); | 1155 | var temp_params = std.ArrayList(wasm.Valtype).init(gpa); |
| 1153 | defer temp_params.deinit(); | 1156 | defer temp_params.deinit(); |
| 1154 | var returns = std.ArrayList(wasm.Valtype).init(gpa); | 1157 | var returns = std.ArrayList(wasm.Valtype).init(gpa); |
| 1155 | defer returns.deinit(); | 1158 | defer returns.deinit(); |
| 1156 | 1159 | ||
| 1157 | if (firstParamSRet(cc, return_type, mod)) { | 1160 | if (firstParamSRet(cc, return_type, pt)) { |
| 1158 | try temp_params.append(.i32); // memory address is always a 32-bit handle | 1161 | try temp_params.append(.i32); // memory address is always a 32-bit handle |
| 1159 | } else if (return_type.hasRuntimeBitsIgnoreComptime(mod)) { | 1162 | } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1160 | if (cc == .C) { | 1163 | if (cc == .C) { |
| 1161 | const res_classes = abi.classifyType(return_type, mod); | 1164 | const res_classes = abi.classifyType(return_type, pt); |
| 1162 | assert(res_classes[0] == .direct and res_classes[1] == .none); | 1165 | assert(res_classes[0] == .direct and res_classes[1] == .none); |
| 1163 | const scalar_type = abi.scalarType(return_type, mod); | 1166 | const scalar_type = abi.scalarType(return_type, pt); |
| 1164 | try returns.append(typeToValtype(scalar_type, mod)); | 1167 | try returns.append(typeToValtype(scalar_type, pt)); |
| 1165 | } else { | 1168 | } else { |
| 1166 | try returns.append(typeToValtype(return_type, mod)); | 1169 | try returns.append(typeToValtype(return_type, pt)); |
| 1167 | } | 1170 | } |
| 1168 | } else if (return_type.isError(mod)) { | 1171 | } else if (return_type.isError(mod)) { |
| 1169 | try returns.append(.i32); | 1172 | try returns.append(.i32); |
| ... | @@ -1172,25 +1175,25 @@ fn genFunctype( | ... | @@ -1172,25 +1175,25 @@ fn genFunctype( |
| 1172 | // param types | 1175 | // param types |
| 1173 | for (params) |param_type_ip| { | 1176 | for (params) |param_type_ip| { |
| 1174 | const param_type = Type.fromInterned(param_type_ip); | 1177 | const param_type = Type.fromInterned(param_type_ip); |
| 1175 | if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue; | 1178 | if (!param_type.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1176 | 1179 | ||
| 1177 | switch (cc) { | 1180 | switch (cc) { |
| 1178 | .C => { | 1181 | .C => { |
| 1179 | const param_classes = abi.classifyType(param_type, mod); | 1182 | const param_classes = abi.classifyType(param_type, pt); |
| 1180 | for (param_classes) |class| { | 1183 | for (param_classes) |class| { |
| 1181 | if (class == .none) continue; | 1184 | if (class == .none) continue; |
| 1182 | if (class == .direct) { | 1185 | if (class == .direct) { |
| 1183 | const scalar_type = abi.scalarType(param_type, mod); | 1186 | const scalar_type = abi.scalarType(param_type, pt); |
| 1184 | try temp_params.append(typeToValtype(scalar_type, mod)); | 1187 | try temp_params.append(typeToValtype(scalar_type, pt)); |
| 1185 | } else { | 1188 | } else { |
| 1186 | try temp_params.append(typeToValtype(param_type, mod)); | 1189 | try temp_params.append(typeToValtype(param_type, pt)); |
| 1187 | } | 1190 | } |
| 1188 | } | 1191 | } |
| 1189 | }, | 1192 | }, |
| 1190 | else => if (isByRef(param_type, mod)) | 1193 | else => if (isByRef(param_type, pt)) |
| 1191 | try temp_params.append(.i32) | 1194 | try temp_params.append(.i32) |
| 1192 | else | 1195 | else |
| 1193 | try temp_params.append(typeToValtype(param_type, mod)), | 1196 | try temp_params.append(typeToValtype(param_type, pt)), |
| 1194 | } | 1197 | } |
| 1195 | } | 1198 | } |
| 1196 | 1199 | ||
| ... | @@ -1202,6 +1205,7 @@ fn genFunctype( | ... | @@ -1202,6 +1205,7 @@ fn genFunctype( |
| 1202 | 1205 | ||
| 1203 | pub fn generate( | 1206 | pub fn generate( |
| 1204 | bin_file: *link.File, | 1207 | bin_file: *link.File, |
| 1208 | pt: Zcu.PerThread, | ||
| 1205 | src_loc: Zcu.LazySrcLoc, | 1209 | src_loc: Zcu.LazySrcLoc, |
| 1206 | func_index: InternPool.Index, | 1210 | func_index: InternPool.Index, |
| 1207 | air: Air, | 1211 | air: Air, |
| ... | @@ -1210,15 +1214,15 @@ pub fn generate( | ... | @@ -1210,15 +1214,15 @@ pub fn generate( |
| 1210 | debug_output: codegen.DebugInfoOutput, | 1214 | debug_output: codegen.DebugInfoOutput, |
| 1211 | ) codegen.CodeGenError!codegen.Result { | 1215 | ) codegen.CodeGenError!codegen.Result { |
| 1212 | _ = src_loc; | 1216 | _ = src_loc; |
| 1213 | const comp = bin_file.comp; | 1217 | const zcu = pt.zcu; |
| 1214 | const gpa = comp.gpa; | 1218 | const gpa = zcu.gpa; |
| 1215 | const zcu = comp.module.?; | ||
| 1216 | const func = zcu.funcInfo(func_index); | 1219 | const func = zcu.funcInfo(func_index); |
| 1217 | const decl = zcu.declPtr(func.owner_decl); | 1220 | const decl = zcu.declPtr(func.owner_decl); |
| 1218 | const namespace = zcu.namespacePtr(decl.src_namespace); | 1221 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 1219 | const target = namespace.fileScope(zcu).mod.resolved_target.result; | 1222 | const target = namespace.fileScope(zcu).mod.resolved_target.result; |
| 1220 | var code_gen: CodeGen = .{ | 1223 | var code_gen: CodeGen = .{ |
| 1221 | .gpa = gpa, | 1224 | .gpa = gpa, |
| 1225 | .pt = pt, | ||
| 1222 | .air = air, | 1226 | .air = air, |
| 1223 | .liveness = liveness, | 1227 | .liveness = liveness, |
| 1224 | .code = code, | 1228 | .code = code, |
| ... | @@ -1242,10 +1246,11 @@ pub fn generate( | ... | @@ -1242,10 +1246,11 @@ pub fn generate( |
| 1242 | } | 1246 | } |
| 1243 | 1247 | ||
| 1244 | fn genFunc(func: *CodeGen) InnerError!void { | 1248 | fn genFunc(func: *CodeGen) InnerError!void { |
| 1245 | const mod = func.bin_file.base.comp.module.?; | 1249 | const pt = func.pt; |
| 1250 | const mod = pt.zcu; | ||
| 1246 | const ip = &mod.intern_pool; | 1251 | const ip = &mod.intern_pool; |
| 1247 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; | 1252 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 1248 | var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod); | 1253 | var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt); |
| 1249 | defer func_type.deinit(func.gpa); | 1254 | defer func_type.deinit(func.gpa); |
| 1250 | _ = try func.bin_file.storeDeclType(func.decl_index, func_type); | 1255 | _ = try func.bin_file.storeDeclType(func.decl_index, func_type); |
| 1251 | 1256 | ||
| ... | @@ -1272,7 +1277,7 @@ fn genFunc(func: *CodeGen) InnerError!void { | ... | @@ -1272,7 +1277,7 @@ fn genFunc(func: *CodeGen) InnerError!void { |
| 1272 | if (func_type.returns.len != 0 and func.air.instructions.len > 0) { | 1277 | if (func_type.returns.len != 0 and func.air.instructions.len > 0) { |
| 1273 | const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1); | 1278 | const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1); |
| 1274 | const last_inst_ty = func.typeOfIndex(inst); | 1279 | const last_inst_ty = func.typeOfIndex(inst); |
| 1275 | if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn(mod)) { | 1280 | if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(pt) or last_inst_ty.isNoReturn(mod)) { |
| 1276 | try func.addTag(.@"unreachable"); | 1281 | try func.addTag(.@"unreachable"); |
| 1277 | } | 1282 | } |
| 1278 | } | 1283 | } |
| ... | @@ -1354,7 +1359,8 @@ const CallWValues = struct { | ... | @@ -1354,7 +1359,8 @@ const CallWValues = struct { |
| 1354 | }; | 1359 | }; |
| 1355 | 1360 | ||
| 1356 | fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues { | 1361 | fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues { |
| 1357 | const mod = func.bin_file.base.comp.module.?; | 1362 | const pt = func.pt; |
| 1363 | const mod = pt.zcu; | ||
| 1358 | const ip = &mod.intern_pool; | 1364 | const ip = &mod.intern_pool; |
| 1359 | const fn_info = mod.typeToFunc(fn_ty).?; | 1365 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 1360 | const cc = fn_info.cc; | 1366 | const cc = fn_info.cc; |
| ... | @@ -1369,7 +1375,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1369,7 +1375,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1369 | 1375 | ||
| 1370 | // Check if we store the result as a pointer to the stack rather than | 1376 | // Check if we store the result as a pointer to the stack rather than |
| 1371 | // by value | 1377 | // by value |
| 1372 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) { | 1378 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) { |
| 1373 | // the sret arg will be passed as first argument, therefore we | 1379 | // the sret arg will be passed as first argument, therefore we |
| 1374 | // set the `return_value` before allocating locals for regular args. | 1380 | // set the `return_value` before allocating locals for regular args. |
| 1375 | result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } }; | 1381 | result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } }; |
| ... | @@ -1379,7 +1385,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1379,7 +1385,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1379 | switch (cc) { | 1385 | switch (cc) { |
| 1380 | .Unspecified => { | 1386 | .Unspecified => { |
| 1381 | for (fn_info.param_types.get(ip)) |ty| { | 1387 | for (fn_info.param_types.get(ip)) |ty| { |
| 1382 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(mod)) { | 1388 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(pt)) { |
| 1383 | continue; | 1389 | continue; |
| 1384 | } | 1390 | } |
| 1385 | 1391 | ||
| ... | @@ -1389,7 +1395,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1389,7 +1395,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1389 | }, | 1395 | }, |
| 1390 | .C => { | 1396 | .C => { |
| 1391 | for (fn_info.param_types.get(ip)) |ty| { | 1397 | for (fn_info.param_types.get(ip)) |ty| { |
| 1392 | const ty_classes = abi.classifyType(Type.fromInterned(ty), mod); | 1398 | const ty_classes = abi.classifyType(Type.fromInterned(ty), pt); |
| 1393 | for (ty_classes) |class| { | 1399 | for (ty_classes) |class| { |
| 1394 | if (class == .none) continue; | 1400 | if (class == .none) continue; |
| 1395 | try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } }); | 1401 | try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } }); |
| ... | @@ -1403,11 +1409,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1403,11 +1409,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1403 | return result; | 1409 | return result; |
| 1404 | } | 1410 | } |
| 1405 | 1411 | ||
| 1406 | fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, mod: *Zcu) bool { | 1412 | fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread) bool { |
| 1407 | switch (cc) { | 1413 | switch (cc) { |
| 1408 | .Unspecified, .Inline => return isByRef(return_type, mod), | 1414 | .Unspecified, .Inline => return isByRef(return_type, pt), |
| 1409 | .C => { | 1415 | .C => { |
| 1410 | const ty_classes = abi.classifyType(return_type, mod); | 1416 | const ty_classes = abi.classifyType(return_type, pt); |
| 1411 | if (ty_classes[0] == .indirect) return true; | 1417 | if (ty_classes[0] == .indirect) return true; |
| 1412 | if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true; | 1418 | if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true; |
| 1413 | return false; | 1419 | return false; |
| ... | @@ -1423,8 +1429,9 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: | ... | @@ -1423,8 +1429,9 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1423 | return func.lowerToStack(value); | 1429 | return func.lowerToStack(value); |
| 1424 | } | 1430 | } |
| 1425 | 1431 | ||
| 1426 | const mod = func.bin_file.base.comp.module.?; | 1432 | const pt = func.pt; |
| 1427 | const ty_classes = abi.classifyType(ty, mod); | 1433 | const mod = pt.zcu; |
| 1434 | const ty_classes = abi.classifyType(ty, pt); | ||
| 1428 | assert(ty_classes[0] != .none); | 1435 | assert(ty_classes[0] != .none); |
| 1429 | switch (ty.zigTypeTag(mod)) { | 1436 | switch (ty.zigTypeTag(mod)) { |
| 1430 | .Struct, .Union => { | 1437 | .Struct, .Union => { |
| ... | @@ -1432,7 +1439,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: | ... | @@ -1432,7 +1439,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1432 | return func.lowerToStack(value); | 1439 | return func.lowerToStack(value); |
| 1433 | } | 1440 | } |
| 1434 | assert(ty_classes[0] == .direct); | 1441 | assert(ty_classes[0] == .direct); |
| 1435 | const scalar_type = abi.scalarType(ty, mod); | 1442 | const scalar_type = abi.scalarType(ty, pt); |
| 1436 | switch (value) { | 1443 | switch (value) { |
| 1437 | .memory, | 1444 | .memory, |
| 1438 | .memory_offset, | 1445 | .memory_offset, |
| ... | @@ -1447,7 +1454,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: | ... | @@ -1447,7 +1454,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1447 | return func.lowerToStack(value); | 1454 | return func.lowerToStack(value); |
| 1448 | } | 1455 | } |
| 1449 | assert(ty_classes[0] == .direct and ty_classes[1] == .direct); | 1456 | assert(ty_classes[0] == .direct and ty_classes[1] == .direct); |
| 1450 | assert(ty.abiSize(mod) == 16); | 1457 | assert(ty.abiSize(pt) == 16); |
| 1451 | // in this case we have an integer or float that must be lowered as 2 i64's. | 1458 | // in this case we have an integer or float that must be lowered as 2 i64's. |
| 1452 | try func.emitWValue(value); | 1459 | try func.emitWValue(value); |
| 1453 | try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 }); | 1460 | try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 }); |
| ... | @@ -1514,18 +1521,18 @@ fn restoreStackPointer(func: *CodeGen) !void { | ... | @@ -1514,18 +1521,18 @@ fn restoreStackPointer(func: *CodeGen) !void { |
| 1514 | /// | 1521 | /// |
| 1515 | /// Asserts Type has codegenbits | 1522 | /// Asserts Type has codegenbits |
| 1516 | fn allocStack(func: *CodeGen, ty: Type) !WValue { | 1523 | fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1517 | const mod = func.bin_file.base.comp.module.?; | 1524 | const pt = func.pt; |
| 1518 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 1525 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 1519 | if (func.initial_stack_value == .none) { | 1526 | if (func.initial_stack_value == .none) { |
| 1520 | try func.initializeStack(); | 1527 | try func.initializeStack(); |
| 1521 | } | 1528 | } |
| 1522 | 1529 | ||
| 1523 | const abi_size = std.math.cast(u32, ty.abiSize(mod)) orelse { | 1530 | const abi_size = std.math.cast(u32, ty.abiSize(pt)) orelse { |
| 1524 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ | 1531 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ |
| 1525 | ty.fmt(mod), ty.abiSize(mod), | 1532 | ty.fmt(pt), ty.abiSize(pt), |
| 1526 | }); | 1533 | }); |
| 1527 | }; | 1534 | }; |
| 1528 | const abi_align = ty.abiAlignment(mod); | 1535 | const abi_align = ty.abiAlignment(pt); |
| 1529 | 1536 | ||
| 1530 | func.stack_alignment = func.stack_alignment.max(abi_align); | 1537 | func.stack_alignment = func.stack_alignment.max(abi_align); |
| 1531 | 1538 | ||
| ... | @@ -1540,7 +1547,8 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue { | ... | @@ -1540,7 +1547,8 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1540 | /// This is different from allocStack where this will use the pointer's alignment | 1547 | /// This is different from allocStack where this will use the pointer's alignment |
| 1541 | /// if it is set, to ensure the stack alignment will be set correctly. | 1548 | /// if it is set, to ensure the stack alignment will be set correctly. |
| 1542 | fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { | 1549 | fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { |
| 1543 | const mod = func.bin_file.base.comp.module.?; | 1550 | const pt = func.pt; |
| 1551 | const mod = pt.zcu; | ||
| 1544 | const ptr_ty = func.typeOfIndex(inst); | 1552 | const ptr_ty = func.typeOfIndex(inst); |
| 1545 | const pointee_ty = ptr_ty.childType(mod); | 1553 | const pointee_ty = ptr_ty.childType(mod); |
| 1546 | 1554 | ||
| ... | @@ -1548,14 +1556,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { | ... | @@ -1548,14 +1556,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { |
| 1548 | try func.initializeStack(); | 1556 | try func.initializeStack(); |
| 1549 | } | 1557 | } |
| 1550 | 1558 | ||
| 1551 | if (!pointee_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1559 | if (!pointee_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1552 | return func.allocStack(Type.usize); // create a value containing just the stack pointer. | 1560 | return func.allocStack(Type.usize); // create a value containing just the stack pointer. |
| 1553 | } | 1561 | } |
| 1554 | 1562 | ||
| 1555 | const abi_alignment = ptr_ty.ptrAlignment(mod); | 1563 | const abi_alignment = ptr_ty.ptrAlignment(pt); |
| 1556 | const abi_size = std.math.cast(u32, pointee_ty.abiSize(mod)) orelse { | 1564 | const abi_size = std.math.cast(u32, pointee_ty.abiSize(pt)) orelse { |
| 1557 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ | 1565 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ |
| 1558 | pointee_ty.fmt(mod), pointee_ty.abiSize(mod), | 1566 | pointee_ty.fmt(pt), pointee_ty.abiSize(pt), |
| 1559 | }); | 1567 | }); |
| 1560 | }; | 1568 | }; |
| 1561 | func.stack_alignment = func.stack_alignment.max(abi_alignment); | 1569 | func.stack_alignment = func.stack_alignment.max(abi_alignment); |
| ... | @@ -1711,7 +1719,8 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch { | ... | @@ -1711,7 +1719,8 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch { |
| 1711 | 1719 | ||
| 1712 | /// For a given `Type`, will return true when the type will be passed | 1720 | /// For a given `Type`, will return true when the type will be passed |
| 1713 | /// by reference, rather than by value | 1721 | /// by reference, rather than by value |
| 1714 | fn isByRef(ty: Type, mod: *Zcu) bool { | 1722 | fn isByRef(ty: Type, pt: Zcu.PerThread) bool { |
| 1723 | const mod = pt.zcu; | ||
| 1715 | const ip = &mod.intern_pool; | 1724 | const ip = &mod.intern_pool; |
| 1716 | const target = mod.getTarget(); | 1725 | const target = mod.getTarget(); |
| 1717 | switch (ty.zigTypeTag(mod)) { | 1726 | switch (ty.zigTypeTag(mod)) { |
| ... | @@ -1734,28 +1743,28 @@ fn isByRef(ty: Type, mod: *Zcu) bool { | ... | @@ -1734,28 +1743,28 @@ fn isByRef(ty: Type, mod: *Zcu) bool { |
| 1734 | 1743 | ||
| 1735 | .Array, | 1744 | .Array, |
| 1736 | .Frame, | 1745 | .Frame, |
| 1737 | => return ty.hasRuntimeBitsIgnoreComptime(mod), | 1746 | => return ty.hasRuntimeBitsIgnoreComptime(pt), |
| 1738 | .Union => { | 1747 | .Union => { |
| 1739 | if (mod.typeToUnion(ty)) |union_obj| { | 1748 | if (mod.typeToUnion(ty)) |union_obj| { |
| 1740 | if (union_obj.getLayout(ip) == .@"packed") { | 1749 | if (union_obj.getLayout(ip) == .@"packed") { |
| 1741 | return ty.abiSize(mod) > 8; | 1750 | return ty.abiSize(pt) > 8; |
| 1742 | } | 1751 | } |
| 1743 | } | 1752 | } |
| 1744 | return ty.hasRuntimeBitsIgnoreComptime(mod); | 1753 | return ty.hasRuntimeBitsIgnoreComptime(pt); |
| 1745 | }, | 1754 | }, |
| 1746 | .Struct => { | 1755 | .Struct => { |
| 1747 | if (mod.typeToPackedStruct(ty)) |packed_struct| { | 1756 | if (mod.typeToPackedStruct(ty)) |packed_struct| { |
| 1748 | return isByRef(Type.fromInterned(packed_struct.backingIntType(ip).*), mod); | 1757 | return isByRef(Type.fromInterned(packed_struct.backingIntType(ip).*), pt); |
| 1749 | } | 1758 | } |
| 1750 | return ty.hasRuntimeBitsIgnoreComptime(mod); | 1759 | return ty.hasRuntimeBitsIgnoreComptime(pt); |
| 1751 | }, | 1760 | }, |
| 1752 | .Vector => return determineSimdStoreStrategy(ty, mod) == .unrolled, | 1761 | .Vector => return determineSimdStoreStrategy(ty, pt) == .unrolled, |
| 1753 | .Int => return ty.intInfo(mod).bits > 64, | 1762 | .Int => return ty.intInfo(mod).bits > 64, |
| 1754 | .Enum => return ty.intInfo(mod).bits > 64, | 1763 | .Enum => return ty.intInfo(mod).bits > 64, |
| 1755 | .Float => return ty.floatBits(target) > 64, | 1764 | .Float => return ty.floatBits(target) > 64, |
| 1756 | .ErrorUnion => { | 1765 | .ErrorUnion => { |
| 1757 | const pl_ty = ty.errorUnionPayload(mod); | 1766 | const pl_ty = ty.errorUnionPayload(mod); |
| 1758 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1767 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1759 | return false; | 1768 | return false; |
| 1760 | } | 1769 | } |
| 1761 | return true; | 1770 | return true; |
| ... | @@ -1764,7 +1773,7 @@ fn isByRef(ty: Type, mod: *Zcu) bool { | ... | @@ -1764,7 +1773,7 @@ fn isByRef(ty: Type, mod: *Zcu) bool { |
| 1764 | if (ty.isPtrLikeOptional(mod)) return false; | 1773 | if (ty.isPtrLikeOptional(mod)) return false; |
| 1765 | const pl_type = ty.optionalChild(mod); | 1774 | const pl_type = ty.optionalChild(mod); |
| 1766 | if (pl_type.zigTypeTag(mod) == .ErrorSet) return false; | 1775 | if (pl_type.zigTypeTag(mod) == .ErrorSet) return false; |
| 1767 | return pl_type.hasRuntimeBitsIgnoreComptime(mod); | 1776 | return pl_type.hasRuntimeBitsIgnoreComptime(pt); |
| 1768 | }, | 1777 | }, |
| 1769 | .Pointer => { | 1778 | .Pointer => { |
| 1770 | // Slices act like struct and will be passed by reference | 1779 | // Slices act like struct and will be passed by reference |
| ... | @@ -1783,11 +1792,11 @@ const SimdStoreStrategy = enum { | ... | @@ -1783,11 +1792,11 @@ const SimdStoreStrategy = enum { |
| 1783 | /// This means when a given type is 128 bits and either the simd128 or relaxed-simd | 1792 | /// This means when a given type is 128 bits and either the simd128 or relaxed-simd |
| 1784 | /// features are enabled, the function will return `.direct`. This would allow to store | 1793 | /// features are enabled, the function will return `.direct`. This would allow to store |
| 1785 | /// it using a instruction, rather than an unrolled version. | 1794 | /// it using a instruction, rather than an unrolled version. |
| 1786 | fn determineSimdStoreStrategy(ty: Type, mod: *Zcu) SimdStoreStrategy { | 1795 | fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread) SimdStoreStrategy { |
| 1787 | std.debug.assert(ty.zigTypeTag(mod) == .Vector); | 1796 | std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector); |
| 1788 | if (ty.bitSize(mod) != 128) return .unrolled; | 1797 | if (ty.bitSize(pt) != 128) return .unrolled; |
| 1789 | const hasFeature = std.Target.wasm.featureSetHas; | 1798 | const hasFeature = std.Target.wasm.featureSetHas; |
| 1790 | const target = mod.getTarget(); | 1799 | const target = pt.zcu.getTarget(); |
| 1791 | const features = target.cpu.features; | 1800 | const features = target.cpu.features; |
| 1792 | if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) { | 1801 | if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) { |
| 1793 | return .direct; | 1802 | return .direct; |
| ... | @@ -2064,7 +2073,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2064,7 +2073,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2064 | } | 2073 | } |
| 2065 | 2074 | ||
| 2066 | fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | 2075 | fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2067 | const mod = func.bin_file.base.comp.module.?; | 2076 | const pt = func.pt; |
| 2077 | const mod = pt.zcu; | ||
| 2068 | const ip = &mod.intern_pool; | 2078 | const ip = &mod.intern_pool; |
| 2069 | 2079 | ||
| 2070 | for (body) |inst| { | 2080 | for (body) |inst| { |
| ... | @@ -2085,7 +2095,8 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2085,7 +2095,8 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2085 | } | 2095 | } |
| 2086 | 2096 | ||
| 2087 | fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2097 | fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2088 | const mod = func.bin_file.base.comp.module.?; | 2098 | const pt = func.pt; |
| 2099 | const mod = pt.zcu; | ||
| 2089 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 2100 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2090 | const operand = try func.resolveInst(un_op); | 2101 | const operand = try func.resolveInst(un_op); |
| 2091 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; | 2102 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| ... | @@ -2095,27 +2106,27 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2095,27 +2106,27 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2095 | // to the stack instead | 2106 | // to the stack instead |
| 2096 | if (func.return_value != .none) { | 2107 | if (func.return_value != .none) { |
| 2097 | try func.store(func.return_value, operand, ret_ty, 0); | 2108 | try func.store(func.return_value, operand, ret_ty, 0); |
| 2098 | } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2109 | } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2099 | switch (ret_ty.zigTypeTag(mod)) { | 2110 | switch (ret_ty.zigTypeTag(mod)) { |
| 2100 | // Aggregate types can be lowered as a singular value | 2111 | // Aggregate types can be lowered as a singular value |
| 2101 | .Struct, .Union => { | 2112 | .Struct, .Union => { |
| 2102 | const scalar_type = abi.scalarType(ret_ty, mod); | 2113 | const scalar_type = abi.scalarType(ret_ty, pt); |
| 2103 | try func.emitWValue(operand); | 2114 | try func.emitWValue(operand); |
| 2104 | const opcode = buildOpcode(.{ | 2115 | const opcode = buildOpcode(.{ |
| 2105 | .op = .load, | 2116 | .op = .load, |
| 2106 | .width = @as(u8, @intCast(scalar_type.abiSize(mod) * 8)), | 2117 | .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)), |
| 2107 | .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned, | 2118 | .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned, |
| 2108 | .valtype1 = typeToValtype(scalar_type, mod), | 2119 | .valtype1 = typeToValtype(scalar_type, pt), |
| 2109 | }); | 2120 | }); |
| 2110 | try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{ | 2121 | try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{ |
| 2111 | .offset = operand.offset(), | 2122 | .offset = operand.offset(), |
| 2112 | .alignment = @intCast(scalar_type.abiAlignment(mod).toByteUnits().?), | 2123 | .alignment = @intCast(scalar_type.abiAlignment(pt).toByteUnits().?), |
| 2113 | }); | 2124 | }); |
| 2114 | }, | 2125 | }, |
| 2115 | else => try func.emitWValue(operand), | 2126 | else => try func.emitWValue(operand), |
| 2116 | } | 2127 | } |
| 2117 | } else { | 2128 | } else { |
| 2118 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and ret_ty.isError(mod)) { | 2129 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and ret_ty.isError(mod)) { |
| 2119 | try func.addImm32(0); | 2130 | try func.addImm32(0); |
| 2120 | } else { | 2131 | } else { |
| 2121 | try func.emitWValue(operand); | 2132 | try func.emitWValue(operand); |
| ... | @@ -2128,16 +2139,17 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2128,16 +2139,17 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2128 | } | 2139 | } |
| 2129 | 2140 | ||
| 2130 | fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2141 | fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2131 | const mod = func.bin_file.base.comp.module.?; | 2142 | const pt = func.pt; |
| 2143 | const mod = pt.zcu; | ||
| 2132 | const child_type = func.typeOfIndex(inst).childType(mod); | 2144 | const child_type = func.typeOfIndex(inst).childType(mod); |
| 2133 | 2145 | ||
| 2134 | const result = result: { | 2146 | const result = result: { |
| 2135 | if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 2147 | if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 2136 | break :result try func.allocStack(Type.usize); // create pointer to void | 2148 | break :result try func.allocStack(Type.usize); // create pointer to void |
| 2137 | } | 2149 | } |
| 2138 | 2150 | ||
| 2139 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; | 2151 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 2140 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) { | 2152 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) { |
| 2141 | break :result func.return_value; | 2153 | break :result func.return_value; |
| 2142 | } | 2154 | } |
| 2143 | 2155 | ||
| ... | @@ -2148,17 +2160,18 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2148,17 +2160,18 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2148 | } | 2160 | } |
| 2149 | 2161 | ||
| 2150 | fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2162 | fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2151 | const mod = func.bin_file.base.comp.module.?; | 2163 | const pt = func.pt; |
| 2164 | const mod = pt.zcu; | ||
| 2152 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 2165 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2153 | const operand = try func.resolveInst(un_op); | 2166 | const operand = try func.resolveInst(un_op); |
| 2154 | const ret_ty = func.typeOf(un_op).childType(mod); | 2167 | const ret_ty = func.typeOf(un_op).childType(mod); |
| 2155 | 2168 | ||
| 2156 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; | 2169 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 2157 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2170 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2158 | if (ret_ty.isError(mod)) { | 2171 | if (ret_ty.isError(mod)) { |
| 2159 | try func.addImm32(0); | 2172 | try func.addImm32(0); |
| 2160 | } | 2173 | } |
| 2161 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) { | 2174 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) { |
| 2162 | // leave on the stack | 2175 | // leave on the stack |
| 2163 | _ = try func.load(operand, ret_ty, 0); | 2176 | _ = try func.load(operand, ret_ty, 0); |
| 2164 | } | 2177 | } |
| ... | @@ -2175,7 +2188,8 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2175,7 +2188,8 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2175 | const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len])); | 2188 | const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len])); |
| 2176 | const ty = func.typeOf(pl_op.operand); | 2189 | const ty = func.typeOf(pl_op.operand); |
| 2177 | 2190 | ||
| 2178 | const mod = func.bin_file.base.comp.module.?; | 2191 | const pt = func.pt; |
| 2192 | const mod = pt.zcu; | ||
| 2179 | const ip = &mod.intern_pool; | 2193 | const ip = &mod.intern_pool; |
| 2180 | const fn_ty = switch (ty.zigTypeTag(mod)) { | 2194 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 2181 | .Fn => ty, | 2195 | .Fn => ty, |
| ... | @@ -2184,10 +2198,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2184,10 +2198,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2184 | }; | 2198 | }; |
| 2185 | const ret_ty = fn_ty.fnReturnType(mod); | 2199 | const ret_ty = fn_ty.fnReturnType(mod); |
| 2186 | const fn_info = mod.typeToFunc(fn_ty).?; | 2200 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 2187 | const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod); | 2201 | const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt); |
| 2188 | 2202 | ||
| 2189 | const callee: ?InternPool.DeclIndex = blk: { | 2203 | const callee: ?InternPool.DeclIndex = blk: { |
| 2190 | const func_val = (try func.air.value(pl_op.operand, mod)) orelse break :blk null; | 2204 | const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null; |
| 2191 | 2205 | ||
| 2192 | if (func_val.getFunction(mod)) |function| { | 2206 | if (func_val.getFunction(mod)) |function| { |
| 2193 | _ = try func.bin_file.getOrCreateAtomForDecl(function.owner_decl); | 2207 | _ = try func.bin_file.getOrCreateAtomForDecl(function.owner_decl); |
| ... | @@ -2195,7 +2209,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2195,7 +2209,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2195 | } else if (func_val.getExternFunc(mod)) |extern_func| { | 2209 | } else if (func_val.getExternFunc(mod)) |extern_func| { |
| 2196 | const ext_decl = mod.declPtr(extern_func.decl); | 2210 | const ext_decl = mod.declPtr(extern_func.decl); |
| 2197 | const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?; | 2211 | const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?; |
| 2198 | var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), mod); | 2212 | var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), pt); |
| 2199 | defer func_type.deinit(func.gpa); | 2213 | defer func_type.deinit(func.gpa); |
| 2200 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl); | 2214 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl); |
| 2201 | const atom = func.bin_file.getAtomPtr(atom_index); | 2215 | const atom = func.bin_file.getAtomPtr(atom_index); |
| ... | @@ -2230,7 +2244,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2230,7 +2244,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2230 | const arg_val = try func.resolveInst(arg); | 2244 | const arg_val = try func.resolveInst(arg); |
| 2231 | 2245 | ||
| 2232 | const arg_ty = func.typeOf(arg); | 2246 | const arg_ty = func.typeOf(arg); |
| 2233 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 2247 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2234 | 2248 | ||
| 2235 | try func.lowerArg(mod.typeToFunc(fn_ty).?.cc, arg_ty, arg_val); | 2249 | try func.lowerArg(mod.typeToFunc(fn_ty).?.cc, arg_ty, arg_val); |
| 2236 | } | 2250 | } |
| ... | @@ -2245,7 +2259,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2245,7 +2259,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2245 | const operand = try func.resolveInst(pl_op.operand); | 2259 | const operand = try func.resolveInst(pl_op.operand); |
| 2246 | try func.emitWValue(operand); | 2260 | try func.emitWValue(operand); |
| 2247 | 2261 | ||
| 2248 | var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod); | 2262 | var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt); |
| 2249 | defer fn_type.deinit(func.gpa); | 2263 | defer fn_type.deinit(func.gpa); |
| 2250 | 2264 | ||
| 2251 | const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type); | 2265 | const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type); |
| ... | @@ -2253,7 +2267,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2253,7 +2267,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2253 | } | 2267 | } |
| 2254 | 2268 | ||
| 2255 | const result_value = result_value: { | 2269 | const result_value = result_value: { |
| 2256 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) { | 2270 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { |
| 2257 | break :result_value WValue{ .none = {} }; | 2271 | break :result_value WValue{ .none = {} }; |
| 2258 | } else if (ret_ty.isNoReturn(mod)) { | 2272 | } else if (ret_ty.isNoReturn(mod)) { |
| 2259 | try func.addTag(.@"unreachable"); | 2273 | try func.addTag(.@"unreachable"); |
| ... | @@ -2264,7 +2278,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2264,7 +2278,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2264 | } else if (mod.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) { | 2278 | } else if (mod.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) { |
| 2265 | const result_local = try func.allocLocal(ret_ty); | 2279 | const result_local = try func.allocLocal(ret_ty); |
| 2266 | try func.addLabel(.local_set, result_local.local.value); | 2280 | try func.addLabel(.local_set, result_local.local.value); |
| 2267 | const scalar_type = abi.scalarType(ret_ty, mod); | 2281 | const scalar_type = abi.scalarType(ret_ty, pt); |
| 2268 | const result = try func.allocStack(scalar_type); | 2282 | const result = try func.allocStack(scalar_type); |
| 2269 | try func.store(result, result_local, scalar_type, 0); | 2283 | try func.store(result, result_local, scalar_type, 0); |
| 2270 | break :result_value result; | 2284 | break :result_value result; |
| ... | @@ -2287,7 +2301,8 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2287,7 +2301,8 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2287 | } | 2301 | } |
| 2288 | 2302 | ||
| 2289 | fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { | 2303 | fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 2290 | const mod = func.bin_file.base.comp.module.?; | 2304 | const pt = func.pt; |
| 2305 | const mod = pt.zcu; | ||
| 2291 | if (safety) { | 2306 | if (safety) { |
| 2292 | // TODO if the value is undef, write 0xaa bytes to dest | 2307 | // TODO if the value is undef, write 0xaa bytes to dest |
| 2293 | } else { | 2308 | } else { |
| ... | @@ -2306,13 +2321,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void | ... | @@ -2306,13 +2321,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2306 | } else { | 2321 | } else { |
| 2307 | // at this point we have a non-natural alignment, we must | 2322 | // at this point we have a non-natural alignment, we must |
| 2308 | // load the value, and then shift+or the rhs into the result location. | 2323 | // load the value, and then shift+or the rhs into the result location. |
| 2309 | const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8); | 2324 | const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8); |
| 2310 | 2325 | ||
| 2311 | if (isByRef(int_elem_ty, mod)) { | 2326 | if (isByRef(int_elem_ty, pt)) { |
| 2312 | return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{}); | 2327 | return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{}); |
| 2313 | } | 2328 | } |
| 2314 | 2329 | ||
| 2315 | var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(mod)))) - 1)); | 2330 | var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(pt)))) - 1)); |
| 2316 | mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset)); | 2331 | mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset)); |
| 2317 | mask ^= ~@as(u64, 0); | 2332 | mask ^= ~@as(u64, 0); |
| 2318 | const shift_val = if (ptr_info.packed_offset.host_size <= 4) | 2333 | const shift_val = if (ptr_info.packed_offset.host_size <= 4) |
| ... | @@ -2324,9 +2339,9 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void | ... | @@ -2324,9 +2339,9 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2324 | else | 2339 | else |
| 2325 | WValue{ .imm64 = mask }; | 2340 | WValue{ .imm64 = mask }; |
| 2326 | const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4) | 2341 | const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4) |
| 2327 | WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(mod))) } | 2342 | WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) } |
| 2328 | else | 2343 | else |
| 2329 | WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(mod)) }; | 2344 | WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) }; |
| 2330 | 2345 | ||
| 2331 | try func.emitWValue(lhs); | 2346 | try func.emitWValue(lhs); |
| 2332 | const loaded = try func.load(lhs, int_elem_ty, 0); | 2347 | const loaded = try func.load(lhs, int_elem_ty, 0); |
| ... | @@ -2346,12 +2361,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void | ... | @@ -2346,12 +2361,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2346 | 2361 | ||
| 2347 | fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void { | 2362 | fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void { |
| 2348 | assert(!(lhs != .stack and rhs == .stack)); | 2363 | assert(!(lhs != .stack and rhs == .stack)); |
| 2349 | const mod = func.bin_file.base.comp.module.?; | 2364 | const pt = func.pt; |
| 2350 | const abi_size = ty.abiSize(mod); | 2365 | const mod = pt.zcu; |
| 2366 | const abi_size = ty.abiSize(pt); | ||
| 2351 | switch (ty.zigTypeTag(mod)) { | 2367 | switch (ty.zigTypeTag(mod)) { |
| 2352 | .ErrorUnion => { | 2368 | .ErrorUnion => { |
| 2353 | const pl_ty = ty.errorUnionPayload(mod); | 2369 | const pl_ty = ty.errorUnionPayload(mod); |
| 2354 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2370 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2355 | return func.store(lhs, rhs, Type.anyerror, 0); | 2371 | return func.store(lhs, rhs, Type.anyerror, 0); |
| 2356 | } | 2372 | } |
| 2357 | 2373 | ||
| ... | @@ -2363,7 +2379,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2363,7 +2379,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2363 | return func.store(lhs, rhs, Type.usize, 0); | 2379 | return func.store(lhs, rhs, Type.usize, 0); |
| 2364 | } | 2380 | } |
| 2365 | const pl_ty = ty.optionalChild(mod); | 2381 | const pl_ty = ty.optionalChild(mod); |
| 2366 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2382 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2367 | return func.store(lhs, rhs, Type.u8, 0); | 2383 | return func.store(lhs, rhs, Type.u8, 0); |
| 2368 | } | 2384 | } |
| 2369 | if (pl_ty.zigTypeTag(mod) == .ErrorSet) { | 2385 | if (pl_ty.zigTypeTag(mod) == .ErrorSet) { |
| ... | @@ -2373,11 +2389,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2373,11 +2389,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2373 | const len = @as(u32, @intCast(abi_size)); | 2389 | const len = @as(u32, @intCast(abi_size)); |
| 2374 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); | 2390 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| 2375 | }, | 2391 | }, |
| 2376 | .Struct, .Array, .Union => if (isByRef(ty, mod)) { | 2392 | .Struct, .Array, .Union => if (isByRef(ty, pt)) { |
| 2377 | const len = @as(u32, @intCast(abi_size)); | 2393 | const len = @as(u32, @intCast(abi_size)); |
| 2378 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); | 2394 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| 2379 | }, | 2395 | }, |
| 2380 | .Vector => switch (determineSimdStoreStrategy(ty, mod)) { | 2396 | .Vector => switch (determineSimdStoreStrategy(ty, pt)) { |
| 2381 | .unrolled => { | 2397 | .unrolled => { |
| 2382 | const len: u32 = @intCast(abi_size); | 2398 | const len: u32 = @intCast(abi_size); |
| 2383 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); | 2399 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| ... | @@ -2391,7 +2407,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2391,7 +2407,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2391 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ | 2407 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 2392 | std.wasm.simdOpcode(.v128_store), | 2408 | std.wasm.simdOpcode(.v128_store), |
| 2393 | offset + lhs.offset(), | 2409 | offset + lhs.offset(), |
| 2394 | @intCast(ty.abiAlignment(mod).toByteUnits() orelse 0), | 2410 | @intCast(ty.abiAlignment(pt).toByteUnits() orelse 0), |
| 2395 | }); | 2411 | }); |
| 2396 | return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); | 2412 | return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 2397 | }, | 2413 | }, |
| ... | @@ -2421,11 +2437,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2421,11 +2437,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2421 | try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset()); | 2437 | try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset()); |
| 2422 | return; | 2438 | return; |
| 2423 | } else if (abi_size > 16) { | 2439 | } else if (abi_size > 16) { |
| 2424 | try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(mod))) }); | 2440 | try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(pt))) }); |
| 2425 | }, | 2441 | }, |
| 2426 | else => if (abi_size > 8) { | 2442 | else => if (abi_size > 8) { |
| 2427 | return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{ | 2443 | return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{ |
| 2428 | ty.fmt(func.bin_file.base.comp.module.?), | 2444 | ty.fmt(pt), |
| 2429 | abi_size, | 2445 | abi_size, |
| 2430 | }); | 2446 | }); |
| 2431 | }, | 2447 | }, |
| ... | @@ -2435,7 +2451,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2435,7 +2451,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2435 | // into lhs, so we calculate that and emit that instead | 2451 | // into lhs, so we calculate that and emit that instead |
| 2436 | try func.lowerToStack(rhs); | 2452 | try func.lowerToStack(rhs); |
| 2437 | 2453 | ||
| 2438 | const valtype = typeToValtype(ty, mod); | 2454 | const valtype = typeToValtype(ty, pt); |
| 2439 | const opcode = buildOpcode(.{ | 2455 | const opcode = buildOpcode(.{ |
| 2440 | .valtype1 = valtype, | 2456 | .valtype1 = valtype, |
| 2441 | .width = @as(u8, @intCast(abi_size * 8)), | 2457 | .width = @as(u8, @intCast(abi_size * 8)), |
| ... | @@ -2447,23 +2463,24 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE | ... | @@ -2447,23 +2463,24 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2447 | Mir.Inst.Tag.fromOpcode(opcode), | 2463 | Mir.Inst.Tag.fromOpcode(opcode), |
| 2448 | .{ | 2464 | .{ |
| 2449 | .offset = offset + lhs.offset(), | 2465 | .offset = offset + lhs.offset(), |
| 2450 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 2466 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 2451 | }, | 2467 | }, |
| 2452 | ); | 2468 | ); |
| 2453 | } | 2469 | } |
| 2454 | 2470 | ||
| 2455 | fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2471 | fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2456 | const mod = func.bin_file.base.comp.module.?; | 2472 | const pt = func.pt; |
| 2473 | const mod = pt.zcu; | ||
| 2457 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2474 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2458 | const operand = try func.resolveInst(ty_op.operand); | 2475 | const operand = try func.resolveInst(ty_op.operand); |
| 2459 | const ty = ty_op.ty.toType(); | 2476 | const ty = ty_op.ty.toType(); |
| 2460 | const ptr_ty = func.typeOf(ty_op.operand); | 2477 | const ptr_ty = func.typeOf(ty_op.operand); |
| 2461 | const ptr_info = ptr_ty.ptrInfo(mod); | 2478 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 2462 | 2479 | ||
| 2463 | if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand}); | 2480 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand}); |
| 2464 | 2481 | ||
| 2465 | const result = result: { | 2482 | const result = result: { |
| 2466 | if (isByRef(ty, mod)) { | 2483 | if (isByRef(ty, pt)) { |
| 2467 | const new_local = try func.allocStack(ty); | 2484 | const new_local = try func.allocStack(ty); |
| 2468 | try func.store(new_local, operand, ty, 0); | 2485 | try func.store(new_local, operand, ty, 0); |
| 2469 | break :result new_local; | 2486 | break :result new_local; |
| ... | @@ -2476,7 +2493,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2476,7 +2493,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2476 | 2493 | ||
| 2477 | // at this point we have a non-natural alignment, we must | 2494 | // at this point we have a non-natural alignment, we must |
| 2478 | // shift the value to obtain the correct bit. | 2495 | // shift the value to obtain the correct bit. |
| 2479 | const int_elem_ty = try mod.intType(.unsigned, ptr_info.packed_offset.host_size * 8); | 2496 | const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8); |
| 2480 | const shift_val = if (ptr_info.packed_offset.host_size <= 4) | 2497 | const shift_val = if (ptr_info.packed_offset.host_size <= 4) |
| 2481 | WValue{ .imm32 = ptr_info.packed_offset.bit_offset } | 2498 | WValue{ .imm32 = ptr_info.packed_offset.bit_offset } |
| 2482 | else if (ptr_info.packed_offset.host_size <= 8) | 2499 | else if (ptr_info.packed_offset.host_size <= 8) |
| ... | @@ -2496,7 +2513,8 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2496,7 +2513,8 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2496 | /// Loads an operand from the linear memory section. | 2513 | /// Loads an operand from the linear memory section. |
| 2497 | /// NOTE: Leaves the value on the stack. | 2514 | /// NOTE: Leaves the value on the stack. |
| 2498 | fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue { | 2515 | fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 2499 | const mod = func.bin_file.base.comp.module.?; | 2516 | const pt = func.pt; |
| 2517 | const mod = pt.zcu; | ||
| 2500 | // load local's value from memory by its stack position | 2518 | // load local's value from memory by its stack position |
| 2501 | try func.emitWValue(operand); | 2519 | try func.emitWValue(operand); |
| 2502 | 2520 | ||
| ... | @@ -2507,15 +2525,15 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu | ... | @@ -2507,15 +2525,15 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu |
| 2507 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ | 2525 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 2508 | std.wasm.simdOpcode(.v128_load), | 2526 | std.wasm.simdOpcode(.v128_load), |
| 2509 | offset + operand.offset(), | 2527 | offset + operand.offset(), |
| 2510 | @intCast(ty.abiAlignment(mod).toByteUnits().?), | 2528 | @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 2511 | }); | 2529 | }); |
| 2512 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); | 2530 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 2513 | return WValue{ .stack = {} }; | 2531 | return WValue{ .stack = {} }; |
| 2514 | } | 2532 | } |
| 2515 | 2533 | ||
| 2516 | const abi_size: u8 = @intCast(ty.abiSize(mod)); | 2534 | const abi_size: u8 = @intCast(ty.abiSize(pt)); |
| 2517 | const opcode = buildOpcode(.{ | 2535 | const opcode = buildOpcode(.{ |
| 2518 | .valtype1 = typeToValtype(ty, mod), | 2536 | .valtype1 = typeToValtype(ty, pt), |
| 2519 | .width = abi_size * 8, | 2537 | .width = abi_size * 8, |
| 2520 | .op = .load, | 2538 | .op = .load, |
| 2521 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, | 2539 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, |
| ... | @@ -2525,7 +2543,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu | ... | @@ -2525,7 +2543,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu |
| 2525 | Mir.Inst.Tag.fromOpcode(opcode), | 2543 | Mir.Inst.Tag.fromOpcode(opcode), |
| 2526 | .{ | 2544 | .{ |
| 2527 | .offset = offset + operand.offset(), | 2545 | .offset = offset + operand.offset(), |
| 2528 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 2546 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 2529 | }, | 2547 | }, |
| 2530 | ); | 2548 | ); |
| 2531 | 2549 | ||
| ... | @@ -2533,13 +2551,14 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu | ... | @@ -2533,13 +2551,14 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu |
| 2533 | } | 2551 | } |
| 2534 | 2552 | ||
| 2535 | fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2553 | fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2536 | const mod = func.bin_file.base.comp.module.?; | 2554 | const pt = func.pt; |
| 2555 | const mod = pt.zcu; | ||
| 2537 | const arg_index = func.arg_index; | 2556 | const arg_index = func.arg_index; |
| 2538 | const arg = func.args[arg_index]; | 2557 | const arg = func.args[arg_index]; |
| 2539 | const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc; | 2558 | const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc; |
| 2540 | const arg_ty = func.typeOfIndex(inst); | 2559 | const arg_ty = func.typeOfIndex(inst); |
| 2541 | if (cc == .C) { | 2560 | if (cc == .C) { |
| 2542 | const arg_classes = abi.classifyType(arg_ty, mod); | 2561 | const arg_classes = abi.classifyType(arg_ty, pt); |
| 2543 | for (arg_classes) |class| { | 2562 | for (arg_classes) |class| { |
| 2544 | if (class != .none) { | 2563 | if (class != .none) { |
| 2545 | func.arg_index += 1; | 2564 | func.arg_index += 1; |
| ... | @@ -2552,7 +2571,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2552,7 +2571,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2552 | if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) { | 2571 | if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) { |
| 2553 | return func.fail( | 2572 | return func.fail( |
| 2554 | "TODO: Implement C-ABI argument for type '{}'", | 2573 | "TODO: Implement C-ABI argument for type '{}'", |
| 2555 | .{arg_ty.fmt(func.bin_file.base.comp.module.?)}, | 2574 | .{arg_ty.fmt(pt)}, |
| 2556 | ); | 2575 | ); |
| 2557 | } | 2576 | } |
| 2558 | const result = try func.allocStack(arg_ty); | 2577 | const result = try func.allocStack(arg_ty); |
| ... | @@ -2579,7 +2598,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2579,7 +2598,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2579 | } | 2598 | } |
| 2580 | 2599 | ||
| 2581 | fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | 2600 | fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2582 | const mod = func.bin_file.base.comp.module.?; | 2601 | const pt = func.pt; |
| 2583 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2602 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2584 | const lhs = try func.resolveInst(bin_op.lhs); | 2603 | const lhs = try func.resolveInst(bin_op.lhs); |
| 2585 | const rhs = try func.resolveInst(bin_op.rhs); | 2604 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | @@ -2593,10 +2612,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -2593,10 +2612,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2593 | // For big integers we can ignore this as we will call into compiler-rt which handles this. | 2612 | // For big integers we can ignore this as we will call into compiler-rt which handles this. |
| 2594 | const result = switch (op) { | 2613 | const result = switch (op) { |
| 2595 | .shr, .shl => res: { | 2614 | .shr, .shl => res: { |
| 2596 | const lhs_wasm_bits = toWasmBits(@as(u16, @intCast(lhs_ty.bitSize(mod)))) orelse { | 2615 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse { |
| 2597 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); | 2616 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); |
| 2598 | }; | 2617 | }; |
| 2599 | const rhs_wasm_bits = toWasmBits(@as(u16, @intCast(rhs_ty.bitSize(mod)))).?; | 2618 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?; |
| 2600 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: { | 2619 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: { |
| 2601 | const tmp = try func.intcast(rhs, rhs_ty, lhs_ty); | 2620 | const tmp = try func.intcast(rhs, rhs_ty, lhs_ty); |
| 2602 | break :blk try tmp.toLocal(func, lhs_ty); | 2621 | break :blk try tmp.toLocal(func, lhs_ty); |
| ... | @@ -2616,7 +2635,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -2616,7 +2635,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2616 | /// Performs a binary operation on the given `WValue`'s | 2635 | /// Performs a binary operation on the given `WValue`'s |
| 2617 | /// NOTE: THis leaves the value on top of the stack. | 2636 | /// NOTE: THis leaves the value on top of the stack. |
| 2618 | fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { | 2637 | fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 2619 | const mod = func.bin_file.base.comp.module.?; | 2638 | const pt = func.pt; |
| 2639 | const mod = pt.zcu; | ||
| 2620 | assert(!(lhs != .stack and rhs == .stack)); | 2640 | assert(!(lhs != .stack and rhs == .stack)); |
| 2621 | 2641 | ||
| 2622 | if (ty.isAnyFloat()) { | 2642 | if (ty.isAnyFloat()) { |
| ... | @@ -2624,20 +2644,20 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! | ... | @@ -2624,20 +2644,20 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2624 | return func.floatOp(float_op, ty, &.{ lhs, rhs }); | 2644 | return func.floatOp(float_op, ty, &.{ lhs, rhs }); |
| 2625 | } | 2645 | } |
| 2626 | 2646 | ||
| 2627 | if (isByRef(ty, mod)) { | 2647 | if (isByRef(ty, pt)) { |
| 2628 | if (ty.zigTypeTag(mod) == .Int) { | 2648 | if (ty.zigTypeTag(mod) == .Int) { |
| 2629 | return func.binOpBigInt(lhs, rhs, ty, op); | 2649 | return func.binOpBigInt(lhs, rhs, ty, op); |
| 2630 | } else { | 2650 | } else { |
| 2631 | return func.fail( | 2651 | return func.fail( |
| 2632 | "TODO: Implement binary operation for type: {}", | 2652 | "TODO: Implement binary operation for type: {}", |
| 2633 | .{ty.fmt(func.bin_file.base.comp.module.?)}, | 2653 | .{ty.fmt(pt)}, |
| 2634 | ); | 2654 | ); |
| 2635 | } | 2655 | } |
| 2636 | } | 2656 | } |
| 2637 | 2657 | ||
| 2638 | const opcode: wasm.Opcode = buildOpcode(.{ | 2658 | const opcode: wasm.Opcode = buildOpcode(.{ |
| 2639 | .op = op, | 2659 | .op = op, |
| 2640 | .valtype1 = typeToValtype(ty, mod), | 2660 | .valtype1 = typeToValtype(ty, pt), |
| 2641 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, | 2661 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, |
| 2642 | }); | 2662 | }); |
| 2643 | try func.emitWValue(lhs); | 2663 | try func.emitWValue(lhs); |
| ... | @@ -2649,7 +2669,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! | ... | @@ -2649,7 +2669,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2649 | } | 2669 | } |
| 2650 | 2670 | ||
| 2651 | fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { | 2671 | fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 2652 | const mod = func.bin_file.base.comp.module.?; | 2672 | const pt = func.pt; |
| 2673 | const mod = pt.zcu; | ||
| 2653 | const int_info = ty.intInfo(mod); | 2674 | const int_info = ty.intInfo(mod); |
| 2654 | if (int_info.bits > 128) { | 2675 | if (int_info.bits > 128) { |
| 2655 | return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{}); | 2676 | return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{}); |
| ... | @@ -2785,7 +2806,8 @@ const FloatOp = enum { | ... | @@ -2785,7 +2806,8 @@ const FloatOp = enum { |
| 2785 | }; | 2806 | }; |
| 2786 | 2807 | ||
| 2787 | fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 2808 | fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2788 | const mod = func.bin_file.base.comp.module.?; | 2809 | const pt = func.pt; |
| 2810 | const mod = pt.zcu; | ||
| 2789 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2811 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2790 | const operand = try func.resolveInst(ty_op.operand); | 2812 | const operand = try func.resolveInst(ty_op.operand); |
| 2791 | const ty = func.typeOf(ty_op.operand); | 2813 | const ty = func.typeOf(ty_op.operand); |
| ... | @@ -2793,7 +2815,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2793,7 +2815,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2793 | 2815 | ||
| 2794 | switch (scalar_ty.zigTypeTag(mod)) { | 2816 | switch (scalar_ty.zigTypeTag(mod)) { |
| 2795 | .Int => if (ty.zigTypeTag(mod) == .Vector) { | 2817 | .Int => if (ty.zigTypeTag(mod) == .Vector) { |
| 2796 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(mod)}); | 2818 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 2797 | } else { | 2819 | } else { |
| 2798 | const int_bits = ty.intInfo(mod).bits; | 2820 | const int_bits = ty.intInfo(mod).bits; |
| 2799 | const wasm_bits = toWasmBits(int_bits) orelse { | 2821 | const wasm_bits = toWasmBits(int_bits) orelse { |
| ... | @@ -2877,7 +2899,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError | ... | @@ -2877,7 +2899,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError |
| 2877 | } | 2899 | } |
| 2878 | 2900 | ||
| 2879 | fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue { | 2901 | fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue { |
| 2880 | const mod = func.bin_file.base.comp.module.?; | 2902 | const pt = func.pt; |
| 2903 | const mod = pt.zcu; | ||
| 2881 | if (ty.zigTypeTag(mod) == .Vector) { | 2904 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2882 | return func.fail("TODO: Implement floatOps for vectors", .{}); | 2905 | return func.fail("TODO: Implement floatOps for vectors", .{}); |
| 2883 | } | 2906 | } |
| ... | @@ -2893,7 +2916,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In | ... | @@ -2893,7 +2916,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In |
| 2893 | for (args) |operand| { | 2916 | for (args) |operand| { |
| 2894 | try func.emitWValue(operand); | 2917 | try func.emitWValue(operand); |
| 2895 | } | 2918 | } |
| 2896 | const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, mod) }); | 2919 | const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt) }); |
| 2897 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); | 2920 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| 2898 | return .stack; | 2921 | return .stack; |
| 2899 | } | 2922 | } |
| ... | @@ -2983,7 +3006,8 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue { | ... | @@ -2983,7 +3006,8 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue { |
| 2983 | } | 3006 | } |
| 2984 | 3007 | ||
| 2985 | fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | 3008 | fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2986 | const mod = func.bin_file.base.comp.module.?; | 3009 | const pt = func.pt; |
| 3010 | const mod = pt.zcu; | ||
| 2987 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3011 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2988 | 3012 | ||
| 2989 | const lhs = try func.resolveInst(bin_op.lhs); | 3013 | const lhs = try func.resolveInst(bin_op.lhs); |
| ... | @@ -3002,10 +3026,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -3002,10 +3026,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3002 | // For big integers we can ignore this as we will call into compiler-rt which handles this. | 3026 | // For big integers we can ignore this as we will call into compiler-rt which handles this. |
| 3003 | const result = switch (op) { | 3027 | const result = switch (op) { |
| 3004 | .shr, .shl => res: { | 3028 | .shr, .shl => res: { |
| 3005 | const lhs_wasm_bits = toWasmBits(@as(u16, @intCast(lhs_ty.bitSize(mod)))) orelse { | 3029 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse { |
| 3006 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); | 3030 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); |
| 3007 | }; | 3031 | }; |
| 3008 | const rhs_wasm_bits = toWasmBits(@as(u16, @intCast(rhs_ty.bitSize(mod)))).?; | 3032 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?; |
| 3009 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: { | 3033 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: { |
| 3010 | const tmp = try func.intcast(rhs, rhs_ty, lhs_ty); | 3034 | const tmp = try func.intcast(rhs, rhs_ty, lhs_ty); |
| 3011 | break :blk try tmp.toLocal(func, lhs_ty); | 3035 | break :blk try tmp.toLocal(func, lhs_ty); |
| ... | @@ -3034,9 +3058,10 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr | ... | @@ -3034,9 +3058,10 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr |
| 3034 | /// Asserts `Type` is <= 128 bits. | 3058 | /// Asserts `Type` is <= 128 bits. |
| 3035 | /// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack, if wrapping was needed. | 3059 | /// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack, if wrapping was needed. |
| 3036 | fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { | 3060 | fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3037 | const mod = func.bin_file.base.comp.module.?; | 3061 | const pt = func.pt; |
| 3038 | assert(ty.abiSize(mod) <= 16); | 3062 | const mod = pt.zcu; |
| 3039 | const int_bits = @as(u16, @intCast(ty.bitSize(mod))); // TODO use ty.intInfo(mod).bits | 3063 | assert(ty.abiSize(pt) <= 16); |
| 3064 | const int_bits: u16 = @intCast(ty.bitSize(pt)); // TODO use ty.intInfo(mod).bits | ||
| 3040 | const wasm_bits = toWasmBits(int_bits) orelse { | 3065 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 3041 | return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{int_bits}); | 3066 | return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{int_bits}); |
| 3042 | }; | 3067 | }; |
| ... | @@ -3098,13 +3123,14 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { | ... | @@ -3098,13 +3123,14 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3098 | } | 3123 | } |
| 3099 | 3124 | ||
| 3100 | fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue { | 3125 | fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue { |
| 3101 | const zcu = func.bin_file.base.comp.module.?; | 3126 | const pt = func.pt; |
| 3127 | const zcu = pt.zcu; | ||
| 3102 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 3128 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 3103 | const offset: u64 = prev_offset + ptr.byte_offset; | 3129 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 3104 | return switch (ptr.base_addr) { | 3130 | return switch (ptr.base_addr) { |
| 3105 | .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)), | 3131 | .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)), |
| 3106 | .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)), | 3132 | .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)), |
| 3107 | .int => return func.lowerConstant(try zcu.intValue(Type.usize, offset), Type.usize), | 3133 | .int => return func.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize), |
| 3108 | .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}), | 3134 | .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}), |
| 3109 | .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset), | 3135 | .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset), |
| 3110 | .field => |field| { | 3136 | .field => |field| { |
| ... | @@ -3120,13 +3146,13 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr | ... | @@ -3120,13 +3146,13 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr |
| 3120 | }; | 3146 | }; |
| 3121 | }, | 3147 | }, |
| 3122 | .Struct => switch (base_ty.containerLayout(zcu)) { | 3148 | .Struct => switch (base_ty.containerLayout(zcu)) { |
| 3123 | .auto => base_ty.structFieldOffset(@intCast(field.index), zcu), | 3149 | .auto => base_ty.structFieldOffset(@intCast(field.index), pt), |
| 3124 | .@"extern", .@"packed" => unreachable, | 3150 | .@"extern", .@"packed" => unreachable, |
| 3125 | }, | 3151 | }, |
| 3126 | .Union => switch (base_ty.containerLayout(zcu)) { | 3152 | .Union => switch (base_ty.containerLayout(zcu)) { |
| 3127 | .auto => off: { | 3153 | .auto => off: { |
| 3128 | // Keep in sync with the `un` case of `generateSymbol`. | 3154 | // Keep in sync with the `un` case of `generateSymbol`. |
| 3129 | const layout = base_ty.unionGetLayout(zcu); | 3155 | const layout = base_ty.unionGetLayout(pt); |
| 3130 | if (layout.payload_size == 0) break :off 0; | 3156 | if (layout.payload_size == 0) break :off 0; |
| 3131 | if (layout.tag_size == 0) break :off 0; | 3157 | if (layout.tag_size == 0) break :off 0; |
| 3132 | if (layout.tag_align.compare(.gte, layout.payload_align)) { | 3158 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| ... | @@ -3152,17 +3178,18 @@ fn lowerAnonDeclRef( | ... | @@ -3152,17 +3178,18 @@ fn lowerAnonDeclRef( |
| 3152 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, | 3178 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, |
| 3153 | offset: u32, | 3179 | offset: u32, |
| 3154 | ) InnerError!WValue { | 3180 | ) InnerError!WValue { |
| 3155 | const mod = func.bin_file.base.comp.module.?; | 3181 | const pt = func.pt; |
| 3182 | const mod = pt.zcu; | ||
| 3156 | const decl_val = anon_decl.val; | 3183 | const decl_val = anon_decl.val; |
| 3157 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | 3184 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 3158 | 3185 | ||
| 3159 | const is_fn_body = ty.zigTypeTag(mod) == .Fn; | 3186 | const is_fn_body = ty.zigTypeTag(mod) == .Fn; |
| 3160 | if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3187 | if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3161 | return WValue{ .imm32 = 0xaaaaaaaa }; | 3188 | return WValue{ .imm32 = 0xaaaaaaaa }; |
| 3162 | } | 3189 | } |
| 3163 | 3190 | ||
| 3164 | const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | 3191 | const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; |
| 3165 | const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.navSrcLoc(mod)); | 3192 | const res = try func.bin_file.lowerAnonDecl(pt, decl_val, decl_align, func.decl.navSrcLoc(mod)); |
| 3166 | switch (res) { | 3193 | switch (res) { |
| 3167 | .ok => {}, | 3194 | .ok => {}, |
| 3168 | .fail => |em| { | 3195 | .fail => |em| { |
| ... | @@ -3180,7 +3207,8 @@ fn lowerAnonDeclRef( | ... | @@ -3180,7 +3207,8 @@ fn lowerAnonDeclRef( |
| 3180 | } | 3207 | } |
| 3181 | 3208 | ||
| 3182 | fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { | 3209 | fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { |
| 3183 | const mod = func.bin_file.base.comp.module.?; | 3210 | const pt = func.pt; |
| 3211 | const mod = pt.zcu; | ||
| 3184 | 3212 | ||
| 3185 | const decl = mod.declPtr(decl_index); | 3213 | const decl = mod.declPtr(decl_index); |
| 3186 | // check if decl is an alias to a function, in which case we | 3214 | // check if decl is an alias to a function, in which case we |
| ... | @@ -3195,7 +3223,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u | ... | @@ -3195,7 +3223,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u |
| 3195 | } | 3223 | } |
| 3196 | } | 3224 | } |
| 3197 | const decl_ty = decl.typeOf(mod); | 3225 | const decl_ty = decl.typeOf(mod); |
| 3198 | if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3226 | if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3199 | return WValue{ .imm32 = 0xaaaaaaaa }; | 3227 | return WValue{ .imm32 = 0xaaaaaaaa }; |
| 3200 | } | 3228 | } |
| 3201 | 3229 | ||
| ... | @@ -3212,8 +3240,9 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u | ... | @@ -3212,8 +3240,9 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u |
| 3212 | 3240 | ||
| 3213 | /// Asserts that `isByRef` returns `false` for `ty`. | 3241 | /// Asserts that `isByRef` returns `false` for `ty`. |
| 3214 | fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | 3242 | fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3215 | const mod = func.bin_file.base.comp.module.?; | 3243 | const pt = func.pt; |
| 3216 | assert(!isByRef(ty, mod)); | 3244 | const mod = pt.zcu; |
| 3245 | assert(!isByRef(ty, pt)); | ||
| 3217 | const ip = &mod.intern_pool; | 3246 | const ip = &mod.intern_pool; |
| 3218 | if (val.isUndefDeep(mod)) return func.emitUndefined(ty); | 3247 | if (val.isUndefDeep(mod)) return func.emitUndefined(ty); |
| 3219 | 3248 | ||
| ... | @@ -3261,13 +3290,13 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3261,13 +3290,13 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3261 | const int_info = ty.intInfo(mod); | 3290 | const int_info = ty.intInfo(mod); |
| 3262 | switch (int_info.signedness) { | 3291 | switch (int_info.signedness) { |
| 3263 | .signed => switch (int_info.bits) { | 3292 | .signed => switch (int_info.bits) { |
| 3264 | 0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(mod)))) }, | 3293 | 0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) }, |
| 3265 | 33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(mod)) }, | 3294 | 33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(pt)) }, |
| 3266 | else => unreachable, | 3295 | else => unreachable, |
| 3267 | }, | 3296 | }, |
| 3268 | .unsigned => switch (int_info.bits) { | 3297 | .unsigned => switch (int_info.bits) { |
| 3269 | 0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(mod)) }, | 3298 | 0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(pt)) }, |
| 3270 | 33...64 => return WValue{ .imm64 = val.toUnsignedInt(mod) }, | 3299 | 33...64 => return WValue{ .imm64 = val.toUnsignedInt(pt) }, |
| 3271 | else => unreachable, | 3300 | else => unreachable, |
| 3272 | }, | 3301 | }, |
| 3273 | } | 3302 | } |
| ... | @@ -3277,22 +3306,22 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3277,22 +3306,22 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3277 | return WValue{ .imm32 = int }; | 3306 | return WValue{ .imm32 = int }; |
| 3278 | }, | 3307 | }, |
| 3279 | .error_union => |error_union| { | 3308 | .error_union => |error_union| { |
| 3280 | const err_int_ty = try mod.errorIntType(); | 3309 | const err_int_ty = try pt.errorIntType(); |
| 3281 | const err_ty, const err_val = switch (error_union.val) { | 3310 | const err_ty, const err_val = switch (error_union.val) { |
| 3282 | .err_name => |err_name| .{ | 3311 | .err_name => |err_name| .{ |
| 3283 | ty.errorUnionSet(mod), | 3312 | ty.errorUnionSet(mod), |
| 3284 | Value.fromInterned((try mod.intern(.{ .err = .{ | 3313 | Value.fromInterned(try pt.intern(.{ .err = .{ |
| 3285 | .ty = ty.errorUnionSet(mod).toIntern(), | 3314 | .ty = ty.errorUnionSet(mod).toIntern(), |
| 3286 | .name = err_name, | 3315 | .name = err_name, |
| 3287 | } }))), | 3316 | } })), |
| 3288 | }, | 3317 | }, |
| 3289 | .payload => .{ | 3318 | .payload => .{ |
| 3290 | err_int_ty, | 3319 | err_int_ty, |
| 3291 | try mod.intValue(err_int_ty, 0), | 3320 | try pt.intValue(err_int_ty, 0), |
| 3292 | }, | 3321 | }, |
| 3293 | }; | 3322 | }; |
| 3294 | const payload_type = ty.errorUnionPayload(mod); | 3323 | const payload_type = ty.errorUnionPayload(mod); |
| 3295 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3324 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3296 | // We use the error type directly as the type. | 3325 | // We use the error type directly as the type. |
| 3297 | return func.lowerConstant(err_val, err_ty); | 3326 | return func.lowerConstant(err_val, err_ty); |
| 3298 | } | 3327 | } |
| ... | @@ -3318,7 +3347,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3318,7 +3347,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3318 | .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr, | 3347 | .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr, |
| 3319 | .arr_elem, .comptime_field, .comptime_alloc => unreachable, | 3348 | .arr_elem, .comptime_field, .comptime_alloc => unreachable, |
| 3320 | }; | 3349 | }; |
| 3321 | return .{ .memory = try func.bin_file.lowerUnnamedConst(val, owner_decl) }; | 3350 | return .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, owner_decl) }; |
| 3322 | }, | 3351 | }, |
| 3323 | .ptr => return func.lowerPtr(val.toIntern(), 0), | 3352 | .ptr => return func.lowerPtr(val.toIntern(), 0), |
| 3324 | .opt => if (ty.optionalReprIsPayload(mod)) { | 3353 | .opt => if (ty.optionalReprIsPayload(mod)) { |
| ... | @@ -3332,11 +3361,11 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3332,11 +3361,11 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3332 | return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) }; | 3361 | return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) }; |
| 3333 | }, | 3362 | }, |
| 3334 | .aggregate => switch (ip.indexToKey(ty.ip_index)) { | 3363 | .aggregate => switch (ip.indexToKey(ty.ip_index)) { |
| 3335 | .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(mod)}), | 3364 | .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}), |
| 3336 | .vector_type => { | 3365 | .vector_type => { |
| 3337 | assert(determineSimdStoreStrategy(ty, mod) == .direct); | 3366 | assert(determineSimdStoreStrategy(ty, pt) == .direct); |
| 3338 | var buf: [16]u8 = undefined; | 3367 | var buf: [16]u8 = undefined; |
| 3339 | val.writeToMemory(ty, mod, &buf) catch unreachable; | 3368 | val.writeToMemory(ty, pt, &buf) catch unreachable; |
| 3340 | return func.storeSimdImmd(buf); | 3369 | return func.storeSimdImmd(buf); |
| 3341 | }, | 3370 | }, |
| 3342 | .struct_type => { | 3371 | .struct_type => { |
| ... | @@ -3345,9 +3374,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3345,9 +3374,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3345 | // are by-ref types. | 3374 | // are by-ref types. |
| 3346 | assert(struct_type.layout == .@"packed"); | 3375 | assert(struct_type.layout == .@"packed"); |
| 3347 | var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer | 3376 | var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer |
| 3348 | val.writeToPackedMemory(ty, mod, &buf, 0) catch unreachable; | 3377 | val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable; |
| 3349 | const backing_int_ty = Type.fromInterned(struct_type.backingIntType(ip).*); | 3378 | const backing_int_ty = Type.fromInterned(struct_type.backingIntType(ip).*); |
| 3350 | const int_val = try mod.intValue( | 3379 | const int_val = try pt.intValue( |
| 3351 | backing_int_ty, | 3380 | backing_int_ty, |
| 3352 | mem.readInt(u64, &buf, .little), | 3381 | mem.readInt(u64, &buf, .little), |
| 3353 | ); | 3382 | ); |
| ... | @@ -3358,7 +3387,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3358,7 +3387,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3358 | .un => |un| { | 3387 | .un => |un| { |
| 3359 | // in this case we have a packed union which will not be passed by reference. | 3388 | // in this case we have a packed union which will not be passed by reference. |
| 3360 | const constant_ty = if (un.tag == .none) | 3389 | const constant_ty = if (un.tag == .none) |
| 3361 | try ty.unionBackingType(mod) | 3390 | try ty.unionBackingType(pt) |
| 3362 | else field_ty: { | 3391 | else field_ty: { |
| 3363 | const union_obj = mod.typeToUnion(ty).?; | 3392 | const union_obj = mod.typeToUnion(ty).?; |
| 3364 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | 3393 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| ... | @@ -3379,7 +3408,8 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue { | ... | @@ -3379,7 +3408,8 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue { |
| 3379 | } | 3408 | } |
| 3380 | 3409 | ||
| 3381 | fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { | 3410 | fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3382 | const mod = func.bin_file.base.comp.module.?; | 3411 | const pt = func.pt; |
| 3412 | const mod = pt.zcu; | ||
| 3383 | const ip = &mod.intern_pool; | 3413 | const ip = &mod.intern_pool; |
| 3384 | switch (ty.zigTypeTag(mod)) { | 3414 | switch (ty.zigTypeTag(mod)) { |
| 3385 | .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa }, | 3415 | .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa }, |
| ... | @@ -3421,15 +3451,16 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { | ... | @@ -3421,15 +3451,16 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3421 | /// It's illegal to provide a value with a type that cannot be represented | 3451 | /// It's illegal to provide a value with a type that cannot be represented |
| 3422 | /// as an integer value. | 3452 | /// as an integer value. |
| 3423 | fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 { | 3453 | fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 { |
| 3424 | const mod = func.bin_file.base.comp.module.?; | 3454 | const pt = func.pt; |
| 3455 | const mod = pt.zcu; | ||
| 3425 | 3456 | ||
| 3426 | switch (val.ip_index) { | 3457 | switch (val.ip_index) { |
| 3427 | .none => {}, | 3458 | .none => {}, |
| 3428 | .bool_true => return 1, | 3459 | .bool_true => return 1, |
| 3429 | .bool_false => return 0, | 3460 | .bool_false => return 0, |
| 3430 | else => return switch (mod.intern_pool.indexToKey(val.ip_index)) { | 3461 | else => return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 3431 | .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod), | 3462 | .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt), |
| 3432 | .int => |int| intStorageAsI32(int.storage, mod), | 3463 | .int => |int| intStorageAsI32(int.storage, pt), |
| 3433 | .ptr => |ptr| { | 3464 | .ptr => |ptr| { |
| 3434 | assert(ptr.base_addr == .int); | 3465 | assert(ptr.base_addr == .int); |
| 3435 | return @intCast(ptr.byte_offset); | 3466 | return @intCast(ptr.byte_offset); |
| ... | @@ -3445,17 +3476,17 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 { | ... | @@ -3445,17 +3476,17 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 { |
| 3445 | }; | 3476 | }; |
| 3446 | } | 3477 | } |
| 3447 | 3478 | ||
| 3448 | fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Zcu) i32 { | 3479 | fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 { |
| 3449 | return intStorageAsI32(ip.indexToKey(int).int.storage, mod); | 3480 | return intStorageAsI32(ip.indexToKey(int).int.storage, pt); |
| 3450 | } | 3481 | } |
| 3451 | 3482 | ||
| 3452 | fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Zcu) i32 { | 3483 | fn intStorageAsI32(storage: InternPool.Key.Int.Storage, pt: Zcu.PerThread) i32 { |
| 3453 | return switch (storage) { | 3484 | return switch (storage) { |
| 3454 | .i64 => |x| @as(i32, @intCast(x)), | 3485 | .i64 => |x| @as(i32, @intCast(x)), |
| 3455 | .u64 => |x| @as(i32, @bitCast(@as(u32, @intCast(x)))), | 3486 | .u64 => |x| @as(i32, @bitCast(@as(u32, @intCast(x)))), |
| 3456 | .big_int => unreachable, | 3487 | .big_int => unreachable, |
| 3457 | .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0)))), | 3488 | .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0)))), |
| 3458 | .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(mod))))), | 3489 | .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))))), |
| 3459 | }; | 3490 | }; |
| 3460 | } | 3491 | } |
| 3461 | 3492 | ||
| ... | @@ -3466,12 +3497,12 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3466,12 +3497,12 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3466 | } | 3497 | } |
| 3467 | 3498 | ||
| 3468 | fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void { | 3499 | fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void { |
| 3469 | const mod = func.bin_file.base.comp.module.?; | 3500 | const pt = func.pt; |
| 3470 | const wasm_block_ty = genBlockType(block_ty, mod); | 3501 | const wasm_block_ty = genBlockType(block_ty, pt); |
| 3471 | 3502 | ||
| 3472 | // if wasm_block_ty is non-empty, we create a register to store the temporary value | 3503 | // if wasm_block_ty is non-empty, we create a register to store the temporary value |
| 3473 | const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: { | 3504 | const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: { |
| 3474 | const ty: Type = if (isByRef(block_ty, mod)) Type.u32 else block_ty; | 3505 | const ty: Type = if (isByRef(block_ty, pt)) Type.u32 else block_ty; |
| 3475 | break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten | 3506 | break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten |
| 3476 | } else WValue.none; | 3507 | } else WValue.none; |
| 3477 | 3508 | ||
| ... | @@ -3583,10 +3614,11 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In | ... | @@ -3583,10 +3614,11 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In |
| 3583 | /// NOTE: This leaves the result on top of the stack, rather than a new local. | 3614 | /// NOTE: This leaves the result on top of the stack, rather than a new local. |
| 3584 | fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue { | 3615 | fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 3585 | assert(!(lhs != .stack and rhs == .stack)); | 3616 | assert(!(lhs != .stack and rhs == .stack)); |
| 3586 | const mod = func.bin_file.base.comp.module.?; | 3617 | const pt = func.pt; |
| 3618 | const mod = pt.zcu; | ||
| 3587 | if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) { | 3619 | if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) { |
| 3588 | const payload_ty = ty.optionalChild(mod); | 3620 | const payload_ty = ty.optionalChild(mod); |
| 3589 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3621 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3590 | // When we hit this case, we must check the value of optionals | 3622 | // When we hit this case, we must check the value of optionals |
| 3591 | // that are not pointers. This means first checking against non-null for | 3623 | // that are not pointers. This means first checking against non-null for |
| 3592 | // both lhs and rhs, as well as checking the payload are matching of lhs and rhs | 3624 | // both lhs and rhs, as well as checking the payload are matching of lhs and rhs |
| ... | @@ -3594,7 +3626,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO | ... | @@ -3594,7 +3626,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO |
| 3594 | } | 3626 | } |
| 3595 | } else if (ty.isAnyFloat()) { | 3627 | } else if (ty.isAnyFloat()) { |
| 3596 | return func.cmpFloat(ty, lhs, rhs, op); | 3628 | return func.cmpFloat(ty, lhs, rhs, op); |
| 3597 | } else if (isByRef(ty, mod)) { | 3629 | } else if (isByRef(ty, pt)) { |
| 3598 | return func.cmpBigInt(lhs, rhs, ty, op); | 3630 | return func.cmpBigInt(lhs, rhs, ty, op); |
| 3599 | } | 3631 | } |
| 3600 | 3632 | ||
| ... | @@ -3612,7 +3644,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO | ... | @@ -3612,7 +3644,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO |
| 3612 | try func.lowerToStack(rhs); | 3644 | try func.lowerToStack(rhs); |
| 3613 | 3645 | ||
| 3614 | const opcode: wasm.Opcode = buildOpcode(.{ | 3646 | const opcode: wasm.Opcode = buildOpcode(.{ |
| 3615 | .valtype1 = typeToValtype(ty, mod), | 3647 | .valtype1 = typeToValtype(ty, pt), |
| 3616 | .op = switch (op) { | 3648 | .op = switch (op) { |
| 3617 | .lt => .lt, | 3649 | .lt => .lt, |
| 3618 | .lte => .le, | 3650 | .lte => .le, |
| ... | @@ -3683,8 +3715,8 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3683,8 +3715,8 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3683 | const errors_len = WValue{ .memory = @intFromEnum(sym_index) }; | 3715 | const errors_len = WValue{ .memory = @intFromEnum(sym_index) }; |
| 3684 | 3716 | ||
| 3685 | try func.emitWValue(operand); | 3717 | try func.emitWValue(operand); |
| 3686 | const mod = func.bin_file.base.comp.module.?; | 3718 | const pt = func.pt; |
| 3687 | const err_int_ty = try mod.errorIntType(); | 3719 | const err_int_ty = try pt.errorIntType(); |
| 3688 | const errors_len_val = try func.load(errors_len, err_int_ty, 0); | 3720 | const errors_len_val = try func.load(errors_len, err_int_ty, 0); |
| 3689 | const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt); | 3721 | const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt); |
| 3690 | 3722 | ||
| ... | @@ -3692,12 +3724,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3692,12 +3724,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3692 | } | 3724 | } |
| 3693 | 3725 | ||
| 3694 | fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3726 | fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3695 | const mod = func.bin_file.base.comp.module.?; | 3727 | const pt = func.pt; |
| 3696 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; | 3728 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 3697 | const block = func.blocks.get(br.block_inst).?; | 3729 | const block = func.blocks.get(br.block_inst).?; |
| 3698 | 3730 | ||
| 3699 | // if operand has codegen bits we should break with a value | 3731 | // if operand has codegen bits we should break with a value |
| 3700 | if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) { | 3732 | if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(pt)) { |
| 3701 | const operand = try func.resolveInst(br.operand); | 3733 | const operand = try func.resolveInst(br.operand); |
| 3702 | try func.lowerToStack(operand); | 3734 | try func.lowerToStack(operand); |
| 3703 | 3735 | ||
| ... | @@ -3719,7 +3751,8 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3719,7 +3751,8 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3719 | 3751 | ||
| 3720 | const operand = try func.resolveInst(ty_op.operand); | 3752 | const operand = try func.resolveInst(ty_op.operand); |
| 3721 | const operand_ty = func.typeOf(ty_op.operand); | 3753 | const operand_ty = func.typeOf(ty_op.operand); |
| 3722 | const mod = func.bin_file.base.comp.module.?; | 3754 | const pt = func.pt; |
| 3755 | const mod = pt.zcu; | ||
| 3723 | 3756 | ||
| 3724 | const result = result: { | 3757 | const result = result: { |
| 3725 | if (operand_ty.zigTypeTag(mod) == .Bool) { | 3758 | if (operand_ty.zigTypeTag(mod) == .Bool) { |
| ... | @@ -3731,7 +3764,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3731,7 +3764,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3731 | } else { | 3764 | } else { |
| 3732 | const int_info = operand_ty.intInfo(mod); | 3765 | const int_info = operand_ty.intInfo(mod); |
| 3733 | const wasm_bits = toWasmBits(int_info.bits) orelse { | 3766 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 3734 | return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(mod)}); | 3767 | return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(pt)}); |
| 3735 | }; | 3768 | }; |
| 3736 | 3769 | ||
| 3737 | switch (wasm_bits) { | 3770 | switch (wasm_bits) { |
| ... | @@ -3798,13 +3831,14 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3798,13 +3831,14 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3798 | } | 3831 | } |
| 3799 | 3832 | ||
| 3800 | fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3833 | fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3801 | const mod = func.bin_file.base.comp.module.?; | 3834 | const pt = func.pt; |
| 3835 | const mod = pt.zcu; | ||
| 3802 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3836 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3803 | const operand = try func.resolveInst(ty_op.operand); | 3837 | const operand = try func.resolveInst(ty_op.operand); |
| 3804 | const wanted_ty = func.typeOfIndex(inst); | 3838 | const wanted_ty = func.typeOfIndex(inst); |
| 3805 | const given_ty = func.typeOf(ty_op.operand); | 3839 | const given_ty = func.typeOf(ty_op.operand); |
| 3806 | 3840 | ||
| 3807 | const bit_size = given_ty.bitSize(mod); | 3841 | const bit_size = given_ty.bitSize(pt); |
| 3808 | const needs_wrapping = (given_ty.isSignedInt(mod) != wanted_ty.isSignedInt(mod)) and | 3842 | const needs_wrapping = (given_ty.isSignedInt(mod) != wanted_ty.isSignedInt(mod)) and |
| 3809 | bit_size != 32 and bit_size != 64 and bit_size != 128; | 3843 | bit_size != 32 and bit_size != 64 and bit_size != 128; |
| 3810 | 3844 | ||
| ... | @@ -3814,7 +3848,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3814,7 +3848,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3814 | break :result try bitcast_result.toLocal(func, wanted_ty); | 3848 | break :result try bitcast_result.toLocal(func, wanted_ty); |
| 3815 | } | 3849 | } |
| 3816 | 3850 | ||
| 3817 | if (isByRef(given_ty, mod) and !isByRef(wanted_ty, mod)) { | 3851 | if (isByRef(given_ty, pt) and !isByRef(wanted_ty, pt)) { |
| 3818 | const loaded_memory = try func.load(operand, wanted_ty, 0); | 3852 | const loaded_memory = try func.load(operand, wanted_ty, 0); |
| 3819 | if (needs_wrapping) { | 3853 | if (needs_wrapping) { |
| 3820 | break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty); | 3854 | break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty); |
| ... | @@ -3822,7 +3856,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3822,7 +3856,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3822 | break :result try loaded_memory.toLocal(func, wanted_ty); | 3856 | break :result try loaded_memory.toLocal(func, wanted_ty); |
| 3823 | } | 3857 | } |
| 3824 | } | 3858 | } |
| 3825 | if (!isByRef(given_ty, mod) and isByRef(wanted_ty, mod)) { | 3859 | if (!isByRef(given_ty, pt) and isByRef(wanted_ty, pt)) { |
| 3826 | const stack_memory = try func.allocStack(wanted_ty); | 3860 | const stack_memory = try func.allocStack(wanted_ty); |
| 3827 | try func.store(stack_memory, operand, given_ty, 0); | 3861 | try func.store(stack_memory, operand, given_ty, 0); |
| 3828 | if (needs_wrapping) { | 3862 | if (needs_wrapping) { |
| ... | @@ -3842,17 +3876,18 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3842,17 +3876,18 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3842 | } | 3876 | } |
| 3843 | 3877 | ||
| 3844 | fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue { | 3878 | fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue { |
| 3845 | const mod = func.bin_file.base.comp.module.?; | 3879 | const pt = func.pt; |
| 3880 | const mod = pt.zcu; | ||
| 3846 | // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction | 3881 | // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction |
| 3847 | if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; | 3882 | if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; |
| 3848 | if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand; | 3883 | if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand; |
| 3849 | if (wanted_ty.bitSize(mod) > 64) return operand; | 3884 | if (wanted_ty.bitSize(pt) > 64) return operand; |
| 3850 | assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod))); | 3885 | assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod))); |
| 3851 | 3886 | ||
| 3852 | const opcode = buildOpcode(.{ | 3887 | const opcode = buildOpcode(.{ |
| 3853 | .op = .reinterpret, | 3888 | .op = .reinterpret, |
| 3854 | .valtype1 = typeToValtype(wanted_ty, mod), | 3889 | .valtype1 = typeToValtype(wanted_ty, pt), |
| 3855 | .valtype2 = typeToValtype(given_ty, mod), | 3890 | .valtype2 = typeToValtype(given_ty, pt), |
| 3856 | }); | 3891 | }); |
| 3857 | try func.emitWValue(operand); | 3892 | try func.emitWValue(operand); |
| 3858 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); | 3893 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| ... | @@ -3860,7 +3895,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn | ... | @@ -3860,7 +3895,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn |
| 3860 | } | 3895 | } |
| 3861 | 3896 | ||
| 3862 | fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3897 | fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3863 | const mod = func.bin_file.base.comp.module.?; | 3898 | const pt = func.pt; |
| 3899 | const mod = pt.zcu; | ||
| 3864 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3900 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3865 | const extra = func.air.extraData(Air.StructField, ty_pl.payload); | 3901 | const extra = func.air.extraData(Air.StructField, ty_pl.payload); |
| 3866 | 3902 | ||
| ... | @@ -3872,7 +3908,8 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3872,7 +3908,8 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3872 | } | 3908 | } |
| 3873 | 3909 | ||
| 3874 | fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void { | 3910 | fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void { |
| 3875 | const mod = func.bin_file.base.comp.module.?; | 3911 | const pt = func.pt; |
| 3912 | const mod = pt.zcu; | ||
| 3876 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3913 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3877 | const struct_ptr = try func.resolveInst(ty_op.operand); | 3914 | const struct_ptr = try func.resolveInst(ty_op.operand); |
| 3878 | const struct_ptr_ty = func.typeOf(ty_op.operand); | 3915 | const struct_ptr_ty = func.typeOf(ty_op.operand); |
| ... | @@ -3891,7 +3928,8 @@ fn structFieldPtr( | ... | @@ -3891,7 +3928,8 @@ fn structFieldPtr( |
| 3891 | struct_ty: Type, | 3928 | struct_ty: Type, |
| 3892 | index: u32, | 3929 | index: u32, |
| 3893 | ) InnerError!WValue { | 3930 | ) InnerError!WValue { |
| 3894 | const mod = func.bin_file.base.comp.module.?; | 3931 | const pt = func.pt; |
| 3932 | const mod = pt.zcu; | ||
| 3895 | const result_ty = func.typeOfIndex(inst); | 3933 | const result_ty = func.typeOfIndex(inst); |
| 3896 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); | 3934 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); |
| 3897 | 3935 | ||
| ... | @@ -3902,12 +3940,12 @@ fn structFieldPtr( | ... | @@ -3902,12 +3940,12 @@ fn structFieldPtr( |
| 3902 | break :offset @as(u32, 0); | 3940 | break :offset @as(u32, 0); |
| 3903 | } | 3941 | } |
| 3904 | const struct_type = mod.typeToStruct(struct_ty).?; | 3942 | const struct_type = mod.typeToStruct(struct_ty).?; |
| 3905 | break :offset @divExact(mod.structPackedFieldBitOffset(struct_type, index) + struct_ptr_ty_info.packed_offset.bit_offset, 8); | 3943 | break :offset @divExact(pt.structPackedFieldBitOffset(struct_type, index) + struct_ptr_ty_info.packed_offset.bit_offset, 8); |
| 3906 | }, | 3944 | }, |
| 3907 | .Union => 0, | 3945 | .Union => 0, |
| 3908 | else => unreachable, | 3946 | else => unreachable, |
| 3909 | }, | 3947 | }, |
| 3910 | else => struct_ty.structFieldOffset(index, mod), | 3948 | else => struct_ty.structFieldOffset(index, pt), |
| 3911 | }; | 3949 | }; |
| 3912 | // save a load and store when we can simply reuse the operand | 3950 | // save a load and store when we can simply reuse the operand |
| 3913 | if (offset == 0) { | 3951 | if (offset == 0) { |
| ... | @@ -3922,7 +3960,8 @@ fn structFieldPtr( | ... | @@ -3922,7 +3960,8 @@ fn structFieldPtr( |
| 3922 | } | 3960 | } |
| 3923 | 3961 | ||
| 3924 | fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3962 | fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3925 | const mod = func.bin_file.base.comp.module.?; | 3963 | const pt = func.pt; |
| 3964 | const mod = pt.zcu; | ||
| 3926 | const ip = &mod.intern_pool; | 3965 | const ip = &mod.intern_pool; |
| 3927 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3966 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3928 | const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data; | 3967 | const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -3931,13 +3970,13 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3931,13 +3970,13 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3931 | const operand = try func.resolveInst(struct_field.struct_operand); | 3970 | const operand = try func.resolveInst(struct_field.struct_operand); |
| 3932 | const field_index = struct_field.field_index; | 3971 | const field_index = struct_field.field_index; |
| 3933 | const field_ty = struct_ty.structFieldType(field_index, mod); | 3972 | const field_ty = struct_ty.structFieldType(field_index, mod); |
| 3934 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{struct_field.struct_operand}); | 3973 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{struct_field.struct_operand}); |
| 3935 | 3974 | ||
| 3936 | const result = switch (struct_ty.containerLayout(mod)) { | 3975 | const result = switch (struct_ty.containerLayout(mod)) { |
| 3937 | .@"packed" => switch (struct_ty.zigTypeTag(mod)) { | 3976 | .@"packed" => switch (struct_ty.zigTypeTag(mod)) { |
| 3938 | .Struct => result: { | 3977 | .Struct => result: { |
| 3939 | const packed_struct = mod.typeToPackedStruct(struct_ty).?; | 3978 | const packed_struct = mod.typeToPackedStruct(struct_ty).?; |
| 3940 | const offset = mod.structPackedFieldBitOffset(packed_struct, field_index); | 3979 | const offset = pt.structPackedFieldBitOffset(packed_struct, field_index); |
| 3941 | const backing_ty = Type.fromInterned(packed_struct.backingIntType(ip).*); | 3980 | const backing_ty = Type.fromInterned(packed_struct.backingIntType(ip).*); |
| 3942 | const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse { | 3981 | const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse { |
| 3943 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); | 3982 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); |
| ... | @@ -3956,7 +3995,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3956,7 +3995,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3956 | try func.binOp(operand, const_wvalue, backing_ty, .shr); | 3995 | try func.binOp(operand, const_wvalue, backing_ty, .shr); |
| 3957 | 3996 | ||
| 3958 | if (field_ty.zigTypeTag(mod) == .Float) { | 3997 | if (field_ty.zigTypeTag(mod) == .Float) { |
| 3959 | const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod)))); | 3998 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); |
| 3960 | const truncated = try func.trunc(shifted_value, int_type, backing_ty); | 3999 | const truncated = try func.trunc(shifted_value, int_type, backing_ty); |
| 3961 | const bitcasted = try func.bitcast(field_ty, int_type, truncated); | 4000 | const bitcasted = try func.bitcast(field_ty, int_type, truncated); |
| 3962 | break :result try bitcasted.toLocal(func, field_ty); | 4001 | break :result try bitcasted.toLocal(func, field_ty); |
| ... | @@ -3965,7 +4004,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3965,7 +4004,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3965 | // we can simply reuse the operand. | 4004 | // we can simply reuse the operand. |
| 3966 | break :result func.reuseOperand(struct_field.struct_operand, operand); | 4005 | break :result func.reuseOperand(struct_field.struct_operand, operand); |
| 3967 | } else if (field_ty.isPtrAtRuntime(mod)) { | 4006 | } else if (field_ty.isPtrAtRuntime(mod)) { |
| 3968 | const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod)))); | 4007 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); |
| 3969 | const truncated = try func.trunc(shifted_value, int_type, backing_ty); | 4008 | const truncated = try func.trunc(shifted_value, int_type, backing_ty); |
| 3970 | break :result try truncated.toLocal(func, field_ty); | 4009 | break :result try truncated.toLocal(func, field_ty); |
| 3971 | } | 4010 | } |
| ... | @@ -3973,8 +4012,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3973,8 +4012,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3973 | break :result try truncated.toLocal(func, field_ty); | 4012 | break :result try truncated.toLocal(func, field_ty); |
| 3974 | }, | 4013 | }, |
| 3975 | .Union => result: { | 4014 | .Union => result: { |
| 3976 | if (isByRef(struct_ty, mod)) { | 4015 | if (isByRef(struct_ty, pt)) { |
| 3977 | if (!isByRef(field_ty, mod)) { | 4016 | if (!isByRef(field_ty, pt)) { |
| 3978 | const val = try func.load(operand, field_ty, 0); | 4017 | const val = try func.load(operand, field_ty, 0); |
| 3979 | break :result try val.toLocal(func, field_ty); | 4018 | break :result try val.toLocal(func, field_ty); |
| 3980 | } else { | 4019 | } else { |
| ... | @@ -3984,14 +4023,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3984,14 +4023,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3984 | } | 4023 | } |
| 3985 | } | 4024 | } |
| 3986 | 4025 | ||
| 3987 | const union_int_type = try mod.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(mod)))); | 4026 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(pt)))); |
| 3988 | if (field_ty.zigTypeTag(mod) == .Float) { | 4027 | if (field_ty.zigTypeTag(mod) == .Float) { |
| 3989 | const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod)))); | 4028 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); |
| 3990 | const truncated = try func.trunc(operand, int_type, union_int_type); | 4029 | const truncated = try func.trunc(operand, int_type, union_int_type); |
| 3991 | const bitcasted = try func.bitcast(field_ty, int_type, truncated); | 4030 | const bitcasted = try func.bitcast(field_ty, int_type, truncated); |
| 3992 | break :result try bitcasted.toLocal(func, field_ty); | 4031 | break :result try bitcasted.toLocal(func, field_ty); |
| 3993 | } else if (field_ty.isPtrAtRuntime(mod)) { | 4032 | } else if (field_ty.isPtrAtRuntime(mod)) { |
| 3994 | const int_type = try mod.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(mod)))); | 4033 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); |
| 3995 | const truncated = try func.trunc(operand, int_type, union_int_type); | 4034 | const truncated = try func.trunc(operand, int_type, union_int_type); |
| 3996 | break :result try truncated.toLocal(func, field_ty); | 4035 | break :result try truncated.toLocal(func, field_ty); |
| 3997 | } | 4036 | } |
| ... | @@ -4001,10 +4040,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4001,10 +4040,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4001 | else => unreachable, | 4040 | else => unreachable, |
| 4002 | }, | 4041 | }, |
| 4003 | else => result: { | 4042 | else => result: { |
| 4004 | const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, mod)) orelse { | 4043 | const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse { |
| 4005 | return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(mod)}); | 4044 | return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)}); |
| 4006 | }; | 4045 | }; |
| 4007 | if (isByRef(field_ty, mod)) { | 4046 | if (isByRef(field_ty, pt)) { |
| 4008 | switch (operand) { | 4047 | switch (operand) { |
| 4009 | .stack_offset => |stack_offset| { | 4048 | .stack_offset => |stack_offset| { |
| 4010 | break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } }; | 4049 | break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } }; |
| ... | @@ -4021,7 +4060,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4021,7 +4060,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4021 | } | 4060 | } |
| 4022 | 4061 | ||
| 4023 | fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4062 | fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4024 | const mod = func.bin_file.base.comp.module.?; | 4063 | const pt = func.pt; |
| 4064 | const mod = pt.zcu; | ||
| 4025 | // result type is always 'noreturn' | 4065 | // result type is always 'noreturn' |
| 4026 | const blocktype = wasm.block_empty; | 4066 | const blocktype = wasm.block_empty; |
| 4027 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4067 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | @@ -4055,7 +4095,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4055,7 +4095,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4055 | errdefer func.gpa.free(values); | 4095 | errdefer func.gpa.free(values); |
| 4056 | 4096 | ||
| 4057 | for (items, 0..) |ref, i| { | 4097 | for (items, 0..) |ref, i| { |
| 4058 | const item_val = (try func.air.value(ref, mod)).?; | 4098 | const item_val = (try func.air.value(ref, pt)).?; |
| 4059 | const int_val = func.valueAsI32(item_val, target_ty); | 4099 | const int_val = func.valueAsI32(item_val, target_ty); |
| 4060 | if (lowest_maybe == null or int_val < lowest_maybe.?) { | 4100 | if (lowest_maybe == null or int_val < lowest_maybe.?) { |
| 4061 | lowest_maybe = int_val; | 4101 | lowest_maybe = int_val; |
| ... | @@ -4078,7 +4118,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4078,7 +4118,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4078 | // When the target is an integer size larger than u32, we have no way to use the value | 4118 | // When the target is an integer size larger than u32, we have no way to use the value |
| 4079 | // as an index, therefore we also use an if/else-chain for those cases. | 4119 | // as an index, therefore we also use an if/else-chain for those cases. |
| 4080 | // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'. | 4120 | // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'. |
| 4081 | const is_sparse = highest - lowest > 50 or target_ty.bitSize(mod) > 32; | 4121 | const is_sparse = highest - lowest > 50 or target_ty.bitSize(pt) > 32; |
| 4082 | 4122 | ||
| 4083 | const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]); | 4123 | const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]); |
| 4084 | const has_else_body = else_body.len != 0; | 4124 | const has_else_body = else_body.len != 0; |
| ... | @@ -4150,7 +4190,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4150,7 +4190,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4150 | const val = try func.lowerConstant(case.values[0].value, target_ty); | 4190 | const val = try func.lowerConstant(case.values[0].value, target_ty); |
| 4151 | try func.emitWValue(val); | 4191 | try func.emitWValue(val); |
| 4152 | const opcode = buildOpcode(.{ | 4192 | const opcode = buildOpcode(.{ |
| 4153 | .valtype1 = typeToValtype(target_ty, mod), | 4193 | .valtype1 = typeToValtype(target_ty, pt), |
| 4154 | .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition. | 4194 | .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition. |
| 4155 | .signedness = signedness, | 4195 | .signedness = signedness, |
| 4156 | }); | 4196 | }); |
| ... | @@ -4164,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4164,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4164 | const val = try func.lowerConstant(value.value, target_ty); | 4204 | const val = try func.lowerConstant(value.value, target_ty); |
| 4165 | try func.emitWValue(val); | 4205 | try func.emitWValue(val); |
| 4166 | const opcode = buildOpcode(.{ | 4206 | const opcode = buildOpcode(.{ |
| 4167 | .valtype1 = typeToValtype(target_ty, mod), | 4207 | .valtype1 = typeToValtype(target_ty, pt), |
| 4168 | .op = .eq, | 4208 | .op = .eq, |
| 4169 | .signedness = signedness, | 4209 | .signedness = signedness, |
| 4170 | }); | 4210 | }); |
| ... | @@ -4201,7 +4241,8 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4201,7 +4241,8 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4201 | } | 4241 | } |
| 4202 | 4242 | ||
| 4203 | fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void { | 4243 | fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void { |
| 4204 | const mod = func.bin_file.base.comp.module.?; | 4244 | const pt = func.pt; |
| 4245 | const mod = pt.zcu; | ||
| 4205 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4246 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4206 | const operand = try func.resolveInst(un_op); | 4247 | const operand = try func.resolveInst(un_op); |
| 4207 | const err_union_ty = func.typeOf(un_op); | 4248 | const err_union_ty = func.typeOf(un_op); |
| ... | @@ -4217,10 +4258,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro | ... | @@ -4217,10 +4258,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro |
| 4217 | } | 4258 | } |
| 4218 | 4259 | ||
| 4219 | try func.emitWValue(operand); | 4260 | try func.emitWValue(operand); |
| 4220 | if (pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4261 | if (pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4221 | try func.addMemArg(.i32_load16_u, .{ | 4262 | try func.addMemArg(.i32_load16_u, .{ |
| 4222 | .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod))), | 4263 | .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, pt))), |
| 4223 | .alignment = @intCast(Type.anyerror.abiAlignment(mod).toByteUnits().?), | 4264 | .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?), |
| 4224 | }); | 4265 | }); |
| 4225 | } | 4266 | } |
| 4226 | 4267 | ||
| ... | @@ -4236,7 +4277,8 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro | ... | @@ -4236,7 +4277,8 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro |
| 4236 | } | 4277 | } |
| 4237 | 4278 | ||
| 4238 | fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { | 4279 | fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4239 | const mod = func.bin_file.base.comp.module.?; | 4280 | const pt = func.pt; |
| 4281 | const mod = pt.zcu; | ||
| 4240 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4282 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4241 | 4283 | ||
| 4242 | const operand = try func.resolveInst(ty_op.operand); | 4284 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -4245,15 +4287,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo | ... | @@ -4245,15 +4287,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo |
| 4245 | const payload_ty = err_ty.errorUnionPayload(mod); | 4287 | const payload_ty = err_ty.errorUnionPayload(mod); |
| 4246 | 4288 | ||
| 4247 | const result = result: { | 4289 | const result = result: { |
| 4248 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4290 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4249 | if (op_is_ptr) { | 4291 | if (op_is_ptr) { |
| 4250 | break :result func.reuseOperand(ty_op.operand, operand); | 4292 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4251 | } | 4293 | } |
| 4252 | break :result WValue{ .none = {} }; | 4294 | break :result WValue{ .none = {} }; |
| 4253 | } | 4295 | } |
| 4254 | 4296 | ||
| 4255 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod))); | 4297 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); |
| 4256 | if (op_is_ptr or isByRef(payload_ty, mod)) { | 4298 | if (op_is_ptr or isByRef(payload_ty, pt)) { |
| 4257 | break :result try func.buildPointerOffset(operand, pl_offset, .new); | 4299 | break :result try func.buildPointerOffset(operand, pl_offset, .new); |
| 4258 | } | 4300 | } |
| 4259 | 4301 | ||
| ... | @@ -4264,7 +4306,8 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo | ... | @@ -4264,7 +4306,8 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo |
| 4264 | } | 4306 | } |
| 4265 | 4307 | ||
| 4266 | fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { | 4308 | fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4267 | const mod = func.bin_file.base.comp.module.?; | 4309 | const pt = func.pt; |
| 4310 | const mod = pt.zcu; | ||
| 4268 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4311 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4269 | 4312 | ||
| 4270 | const operand = try func.resolveInst(ty_op.operand); | 4313 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -4277,18 +4320,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) | ... | @@ -4277,18 +4320,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) |
| 4277 | break :result WValue{ .imm32 = 0 }; | 4320 | break :result WValue{ .imm32 = 0 }; |
| 4278 | } | 4321 | } |
| 4279 | 4322 | ||
| 4280 | if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4323 | if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4281 | break :result func.reuseOperand(ty_op.operand, operand); | 4324 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4282 | } | 4325 | } |
| 4283 | 4326 | ||
| 4284 | const error_val = try func.load(operand, Type.anyerror, @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod)))); | 4327 | const error_val = try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt))); |
| 4285 | break :result try error_val.toLocal(func, Type.anyerror); | 4328 | break :result try error_val.toLocal(func, Type.anyerror); |
| 4286 | }; | 4329 | }; |
| 4287 | func.finishAir(inst, result, &.{ty_op.operand}); | 4330 | func.finishAir(inst, result, &.{ty_op.operand}); |
| 4288 | } | 4331 | } |
| 4289 | 4332 | ||
| 4290 | fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4333 | fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4291 | const mod = func.bin_file.base.comp.module.?; | 4334 | const pt = func.pt; |
| 4292 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4335 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4293 | 4336 | ||
| 4294 | const operand = try func.resolveInst(ty_op.operand); | 4337 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -4296,18 +4339,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void | ... | @@ -4296,18 +4339,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4296 | 4339 | ||
| 4297 | const pl_ty = func.typeOf(ty_op.operand); | 4340 | const pl_ty = func.typeOf(ty_op.operand); |
| 4298 | const result = result: { | 4341 | const result = result: { |
| 4299 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4342 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4300 | break :result func.reuseOperand(ty_op.operand, operand); | 4343 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4301 | } | 4344 | } |
| 4302 | 4345 | ||
| 4303 | const err_union = try func.allocStack(err_ty); | 4346 | const err_union = try func.allocStack(err_ty); |
| 4304 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod))), .new); | 4347 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new); |
| 4305 | try func.store(payload_ptr, operand, pl_ty, 0); | 4348 | try func.store(payload_ptr, operand, pl_ty, 0); |
| 4306 | 4349 | ||
| 4307 | // ensure we also write '0' to the error part, so any present stack value gets overwritten by it. | 4350 | // ensure we also write '0' to the error part, so any present stack value gets overwritten by it. |
| 4308 | try func.emitWValue(err_union); | 4351 | try func.emitWValue(err_union); |
| 4309 | try func.addImm32(0); | 4352 | try func.addImm32(0); |
| 4310 | const err_val_offset = @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod))); | 4353 | const err_val_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 4311 | try func.addMemArg(.i32_store16, .{ | 4354 | try func.addMemArg(.i32_store16, .{ |
| 4312 | .offset = err_union.offset() + err_val_offset, | 4355 | .offset = err_union.offset() + err_val_offset, |
| 4313 | .alignment = 2, | 4356 | .alignment = 2, |
| ... | @@ -4318,7 +4361,8 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void | ... | @@ -4318,7 +4361,8 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4318 | } | 4361 | } |
| 4319 | 4362 | ||
| 4320 | fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4363 | fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4321 | const mod = func.bin_file.base.comp.module.?; | 4364 | const pt = func.pt; |
| 4365 | const mod = pt.zcu; | ||
| 4322 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4366 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4323 | 4367 | ||
| 4324 | const operand = try func.resolveInst(ty_op.operand); | 4368 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -4326,17 +4370,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4326,17 +4370,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4326 | const pl_ty = err_ty.errorUnionPayload(mod); | 4370 | const pl_ty = err_ty.errorUnionPayload(mod); |
| 4327 | 4371 | ||
| 4328 | const result = result: { | 4372 | const result = result: { |
| 4329 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4373 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4330 | break :result func.reuseOperand(ty_op.operand, operand); | 4374 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4331 | } | 4375 | } |
| 4332 | 4376 | ||
| 4333 | const err_union = try func.allocStack(err_ty); | 4377 | const err_union = try func.allocStack(err_ty); |
| 4334 | // store error value | 4378 | // store error value |
| 4335 | try func.store(err_union, operand, Type.anyerror, @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod)))); | 4379 | try func.store(err_union, operand, Type.anyerror, @intCast(errUnionErrorOffset(pl_ty, pt))); |
| 4336 | 4380 | ||
| 4337 | // write 'undefined' to the payload | 4381 | // write 'undefined' to the payload |
| 4338 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod))), .new); | 4382 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new); |
| 4339 | const len = @as(u32, @intCast(err_ty.errorUnionPayload(mod).abiSize(mod))); | 4383 | const len = @as(u32, @intCast(err_ty.errorUnionPayload(mod).abiSize(pt))); |
| 4340 | try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa }); | 4384 | try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa }); |
| 4341 | 4385 | ||
| 4342 | break :result err_union; | 4386 | break :result err_union; |
| ... | @@ -4350,16 +4394,17 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4350,16 +4394,17 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4350 | const ty = ty_op.ty.toType(); | 4394 | const ty = ty_op.ty.toType(); |
| 4351 | const operand = try func.resolveInst(ty_op.operand); | 4395 | const operand = try func.resolveInst(ty_op.operand); |
| 4352 | const operand_ty = func.typeOf(ty_op.operand); | 4396 | const operand_ty = func.typeOf(ty_op.operand); |
| 4353 | const mod = func.bin_file.base.comp.module.?; | 4397 | const pt = func.pt; |
| 4398 | const mod = pt.zcu; | ||
| 4354 | if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) { | 4399 | if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) { |
| 4355 | return func.fail("todo Wasm intcast for vectors", .{}); | 4400 | return func.fail("todo Wasm intcast for vectors", .{}); |
| 4356 | } | 4401 | } |
| 4357 | if (ty.abiSize(mod) > 16 or operand_ty.abiSize(mod) > 16) { | 4402 | if (ty.abiSize(pt) > 16 or operand_ty.abiSize(pt) > 16) { |
| 4358 | return func.fail("todo Wasm intcast for bitsize > 128", .{}); | 4403 | return func.fail("todo Wasm intcast for bitsize > 128", .{}); |
| 4359 | } | 4404 | } |
| 4360 | 4405 | ||
| 4361 | const op_bits = toWasmBits(@as(u16, @intCast(operand_ty.bitSize(mod)))).?; | 4406 | const op_bits = toWasmBits(@intCast(operand_ty.bitSize(pt))).?; |
| 4362 | const wanted_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?; | 4407 | const wanted_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; |
| 4363 | const result = if (op_bits == wanted_bits) | 4408 | const result = if (op_bits == wanted_bits) |
| 4364 | func.reuseOperand(ty_op.operand, operand) | 4409 | func.reuseOperand(ty_op.operand, operand) |
| 4365 | else | 4410 | else |
| ... | @@ -4373,9 +4418,10 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4373,9 +4418,10 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4373 | /// Asserts type's bitsize <= 128 | 4418 | /// Asserts type's bitsize <= 128 |
| 4374 | /// NOTE: May leave the result on the top of the stack. | 4419 | /// NOTE: May leave the result on the top of the stack. |
| 4375 | fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue { | 4420 | fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue { |
| 4376 | const mod = func.bin_file.base.comp.module.?; | 4421 | const pt = func.pt; |
| 4377 | const given_bitsize = @as(u16, @intCast(given.bitSize(mod))); | 4422 | const mod = pt.zcu; |
| 4378 | const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(mod))); | 4423 | const given_bitsize = @as(u16, @intCast(given.bitSize(pt))); |
| 4424 | const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(pt))); | ||
| 4379 | assert(given_bitsize <= 128); | 4425 | assert(given_bitsize <= 128); |
| 4380 | assert(wanted_bitsize <= 128); | 4426 | assert(wanted_bitsize <= 128); |
| 4381 | 4427 | ||
| ... | @@ -4422,7 +4468,8 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro | ... | @@ -4422,7 +4468,8 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4422 | } | 4468 | } |
| 4423 | 4469 | ||
| 4424 | fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { | 4470 | fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { |
| 4425 | const mod = func.bin_file.base.comp.module.?; | 4471 | const pt = func.pt; |
| 4472 | const mod = pt.zcu; | ||
| 4426 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4473 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4427 | const operand = try func.resolveInst(un_op); | 4474 | const operand = try func.resolveInst(un_op); |
| 4428 | 4475 | ||
| ... | @@ -4436,15 +4483,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: | ... | @@ -4436,15 +4483,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: |
| 4436 | /// For a given type and operand, checks if it's considered `null`. | 4483 | /// For a given type and operand, checks if it's considered `null`. |
| 4437 | /// NOTE: Leaves the result on the stack | 4484 | /// NOTE: Leaves the result on the stack |
| 4438 | fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue { | 4485 | fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue { |
| 4439 | const mod = func.bin_file.base.comp.module.?; | 4486 | const pt = func.pt; |
| 4487 | const mod = pt.zcu; | ||
| 4440 | try func.emitWValue(operand); | 4488 | try func.emitWValue(operand); |
| 4441 | const payload_ty = optional_ty.optionalChild(mod); | 4489 | const payload_ty = optional_ty.optionalChild(mod); |
| 4442 | if (!optional_ty.optionalReprIsPayload(mod)) { | 4490 | if (!optional_ty.optionalReprIsPayload(mod)) { |
| 4443 | // When payload is zero-bits, we can treat operand as a value, rather than | 4491 | // When payload is zero-bits, we can treat operand as a value, rather than |
| 4444 | // a pointer to the stack value | 4492 | // a pointer to the stack value |
| 4445 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4493 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4446 | const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse { | 4494 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { |
| 4447 | return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(mod)}); | 4495 | return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(pt)}); |
| 4448 | }; | 4496 | }; |
| 4449 | try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 }); | 4497 | try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 }); |
| 4450 | } | 4498 | } |
| ... | @@ -4464,11 +4512,12 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod | ... | @@ -4464,11 +4512,12 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod |
| 4464 | } | 4512 | } |
| 4465 | 4513 | ||
| 4466 | fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4514 | fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4467 | const mod = func.bin_file.base.comp.module.?; | 4515 | const pt = func.pt; |
| 4516 | const mod = pt.zcu; | ||
| 4468 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4517 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4469 | const opt_ty = func.typeOf(ty_op.operand); | 4518 | const opt_ty = func.typeOf(ty_op.operand); |
| 4470 | const payload_ty = func.typeOfIndex(inst); | 4519 | const payload_ty = func.typeOfIndex(inst); |
| 4471 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4520 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4472 | return func.finishAir(inst, .none, &.{ty_op.operand}); | 4521 | return func.finishAir(inst, .none, &.{ty_op.operand}); |
| 4473 | } | 4522 | } |
| 4474 | 4523 | ||
| ... | @@ -4476,7 +4525,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4476,7 +4525,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4476 | const operand = try func.resolveInst(ty_op.operand); | 4525 | const operand = try func.resolveInst(ty_op.operand); |
| 4477 | if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand); | 4526 | if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand); |
| 4478 | 4527 | ||
| 4479 | if (isByRef(payload_ty, mod)) { | 4528 | if (isByRef(payload_ty, pt)) { |
| 4480 | break :result try func.buildPointerOffset(operand, 0, .new); | 4529 | break :result try func.buildPointerOffset(operand, 0, .new); |
| 4481 | } | 4530 | } |
| 4482 | 4531 | ||
| ... | @@ -4487,14 +4536,15 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4487,14 +4536,15 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4487 | } | 4536 | } |
| 4488 | 4537 | ||
| 4489 | fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4538 | fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4490 | const mod = func.bin_file.base.comp.module.?; | 4539 | const pt = func.pt; |
| 4540 | const mod = pt.zcu; | ||
| 4491 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4541 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4492 | const operand = try func.resolveInst(ty_op.operand); | 4542 | const operand = try func.resolveInst(ty_op.operand); |
| 4493 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); | 4543 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); |
| 4494 | 4544 | ||
| 4495 | const result = result: { | 4545 | const result = result: { |
| 4496 | const payload_ty = opt_ty.optionalChild(mod); | 4546 | const payload_ty = opt_ty.optionalChild(mod); |
| 4497 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or opt_ty.optionalReprIsPayload(mod)) { | 4547 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or opt_ty.optionalReprIsPayload(mod)) { |
| 4498 | break :result func.reuseOperand(ty_op.operand, operand); | 4548 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4499 | } | 4549 | } |
| 4500 | 4550 | ||
| ... | @@ -4504,12 +4554,13 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4504,12 +4554,13 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4504 | } | 4554 | } |
| 4505 | 4555 | ||
| 4506 | fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4556 | fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4507 | const mod = func.bin_file.base.comp.module.?; | 4557 | const pt = func.pt; |
| 4558 | const mod = pt.zcu; | ||
| 4508 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4559 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4509 | const operand = try func.resolveInst(ty_op.operand); | 4560 | const operand = try func.resolveInst(ty_op.operand); |
| 4510 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); | 4561 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); |
| 4511 | const payload_ty = opt_ty.optionalChild(mod); | 4562 | const payload_ty = opt_ty.optionalChild(mod); |
| 4512 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4563 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4513 | return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()}); | 4564 | return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()}); |
| 4514 | } | 4565 | } |
| 4515 | 4566 | ||
| ... | @@ -4517,8 +4568,8 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi | ... | @@ -4517,8 +4568,8 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi |
| 4517 | return func.finishAir(inst, operand, &.{ty_op.operand}); | 4568 | return func.finishAir(inst, operand, &.{ty_op.operand}); |
| 4518 | } | 4569 | } |
| 4519 | 4570 | ||
| 4520 | const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse { | 4571 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { |
| 4521 | return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(mod)}); | 4572 | return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(pt)}); |
| 4522 | }; | 4573 | }; |
| 4523 | 4574 | ||
| 4524 | try func.emitWValue(operand); | 4575 | try func.emitWValue(operand); |
| ... | @@ -4532,10 +4583,11 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi | ... | @@ -4532,10 +4583,11 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi |
| 4532 | fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4583 | fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4533 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4584 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4534 | const payload_ty = func.typeOf(ty_op.operand); | 4585 | const payload_ty = func.typeOf(ty_op.operand); |
| 4535 | const mod = func.bin_file.base.comp.module.?; | 4586 | const pt = func.pt; |
| 4587 | const mod = pt.zcu; | ||
| 4536 | 4588 | ||
| 4537 | const result = result: { | 4589 | const result = result: { |
| 4538 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4590 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4539 | const non_null_bit = try func.allocStack(Type.u1); | 4591 | const non_null_bit = try func.allocStack(Type.u1); |
| 4540 | try func.emitWValue(non_null_bit); | 4592 | try func.emitWValue(non_null_bit); |
| 4541 | try func.addImm32(1); | 4593 | try func.addImm32(1); |
| ... | @@ -4548,8 +4600,8 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4548,8 +4600,8 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4548 | if (op_ty.optionalReprIsPayload(mod)) { | 4600 | if (op_ty.optionalReprIsPayload(mod)) { |
| 4549 | break :result func.reuseOperand(ty_op.operand, operand); | 4601 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4550 | } | 4602 | } |
| 4551 | const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse { | 4603 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { |
| 4552 | return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(mod)}); | 4604 | return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(pt)}); |
| 4553 | }; | 4605 | }; |
| 4554 | 4606 | ||
| 4555 | // Create optional type, set the non-null bit, and store the operand inside the optional type | 4607 | // Create optional type, set the non-null bit, and store the operand inside the optional type |
| ... | @@ -4589,14 +4641,15 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4589,14 +4641,15 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4589 | } | 4641 | } |
| 4590 | 4642 | ||
| 4591 | fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4643 | fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4592 | const mod = func.bin_file.base.comp.module.?; | 4644 | const pt = func.pt; |
| 4645 | const mod = pt.zcu; | ||
| 4593 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4646 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4594 | 4647 | ||
| 4595 | const slice_ty = func.typeOf(bin_op.lhs); | 4648 | const slice_ty = func.typeOf(bin_op.lhs); |
| 4596 | const slice = try func.resolveInst(bin_op.lhs); | 4649 | const slice = try func.resolveInst(bin_op.lhs); |
| 4597 | const index = try func.resolveInst(bin_op.rhs); | 4650 | const index = try func.resolveInst(bin_op.rhs); |
| 4598 | const elem_ty = slice_ty.childType(mod); | 4651 | const elem_ty = slice_ty.childType(mod); |
| 4599 | const elem_size = elem_ty.abiSize(mod); | 4652 | const elem_size = elem_ty.abiSize(pt); |
| 4600 | 4653 | ||
| 4601 | // load pointer onto stack | 4654 | // load pointer onto stack |
| 4602 | _ = try func.load(slice, Type.usize, 0); | 4655 | _ = try func.load(slice, Type.usize, 0); |
| ... | @@ -4610,7 +4663,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4610,7 +4663,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4610 | const result_ptr = try func.allocLocal(Type.usize); | 4663 | const result_ptr = try func.allocLocal(Type.usize); |
| 4611 | try func.addLabel(.local_set, result_ptr.local.value); | 4664 | try func.addLabel(.local_set, result_ptr.local.value); |
| 4612 | 4665 | ||
| 4613 | const result = if (!isByRef(elem_ty, mod)) result: { | 4666 | const result = if (!isByRef(elem_ty, pt)) result: { |
| 4614 | const elem_val = try func.load(result_ptr, elem_ty, 0); | 4667 | const elem_val = try func.load(result_ptr, elem_ty, 0); |
| 4615 | break :result try elem_val.toLocal(func, elem_ty); | 4668 | break :result try elem_val.toLocal(func, elem_ty); |
| 4616 | } else result_ptr; | 4669 | } else result_ptr; |
| ... | @@ -4619,12 +4672,13 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4619,12 +4672,13 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4619 | } | 4672 | } |
| 4620 | 4673 | ||
| 4621 | fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4674 | fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4622 | const mod = func.bin_file.base.comp.module.?; | 4675 | const pt = func.pt; |
| 4676 | const mod = pt.zcu; | ||
| 4623 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4677 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4624 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; | 4678 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4625 | 4679 | ||
| 4626 | const elem_ty = ty_pl.ty.toType().childType(mod); | 4680 | const elem_ty = ty_pl.ty.toType().childType(mod); |
| 4627 | const elem_size = elem_ty.abiSize(mod); | 4681 | const elem_size = elem_ty.abiSize(pt); |
| 4628 | 4682 | ||
| 4629 | const slice = try func.resolveInst(bin_op.lhs); | 4683 | const slice = try func.resolveInst(bin_op.lhs); |
| 4630 | const index = try func.resolveInst(bin_op.rhs); | 4684 | const index = try func.resolveInst(bin_op.rhs); |
| ... | @@ -4672,14 +4726,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4672,14 +4726,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4672 | /// Truncates a given operand to a given type, discarding any overflown bits. | 4726 | /// Truncates a given operand to a given type, discarding any overflown bits. |
| 4673 | /// NOTE: Resulting value is left on the stack. | 4727 | /// NOTE: Resulting value is left on the stack. |
| 4674 | fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue { | 4728 | fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue { |
| 4675 | const mod = func.bin_file.base.comp.module.?; | 4729 | const pt = func.pt; |
| 4676 | const given_bits = @as(u16, @intCast(given_ty.bitSize(mod))); | 4730 | const given_bits = @as(u16, @intCast(given_ty.bitSize(pt))); |
| 4677 | if (toWasmBits(given_bits) == null) { | 4731 | if (toWasmBits(given_bits) == null) { |
| 4678 | return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits}); | 4732 | return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits}); |
| 4679 | } | 4733 | } |
| 4680 | 4734 | ||
| 4681 | var result = try func.intcast(operand, given_ty, wanted_ty); | 4735 | var result = try func.intcast(operand, given_ty, wanted_ty); |
| 4682 | const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(mod))); | 4736 | const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(pt))); |
| 4683 | const wasm_bits = toWasmBits(wanted_bits).?; | 4737 | const wasm_bits = toWasmBits(wanted_bits).?; |
| 4684 | if (wasm_bits != wanted_bits) { | 4738 | if (wasm_bits != wanted_bits) { |
| 4685 | result = try func.wrapOperand(result, wanted_ty); | 4739 | result = try func.wrapOperand(result, wanted_ty); |
| ... | @@ -4696,7 +4750,8 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4696,7 +4750,8 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4696 | } | 4750 | } |
| 4697 | 4751 | ||
| 4698 | fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4752 | fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4699 | const mod = func.bin_file.base.comp.module.?; | 4753 | const pt = func.pt; |
| 4754 | const mod = pt.zcu; | ||
| 4700 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4755 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4701 | 4756 | ||
| 4702 | const operand = try func.resolveInst(ty_op.operand); | 4757 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -4707,7 +4762,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4707,7 +4762,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4707 | const slice_local = try func.allocStack(slice_ty); | 4762 | const slice_local = try func.allocStack(slice_ty); |
| 4708 | 4763 | ||
| 4709 | // store the array ptr in the slice | 4764 | // store the array ptr in the slice |
| 4710 | if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4765 | if (array_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4711 | try func.store(slice_local, operand, Type.usize, 0); | 4766 | try func.store(slice_local, operand, Type.usize, 0); |
| 4712 | } | 4767 | } |
| 4713 | 4768 | ||
| ... | @@ -4719,7 +4774,8 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4719,7 +4774,8 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4719 | } | 4774 | } |
| 4720 | 4775 | ||
| 4721 | fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4776 | fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4722 | const mod = func.bin_file.base.comp.module.?; | 4777 | const pt = func.pt; |
| 4778 | const mod = pt.zcu; | ||
| 4723 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4779 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4724 | const operand = try func.resolveInst(un_op); | 4780 | const operand = try func.resolveInst(un_op); |
| 4725 | const ptr_ty = func.typeOf(un_op); | 4781 | const ptr_ty = func.typeOf(un_op); |
| ... | @@ -4734,14 +4790,15 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4734,14 +4790,15 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4734 | } | 4790 | } |
| 4735 | 4791 | ||
| 4736 | fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4792 | fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4737 | const mod = func.bin_file.base.comp.module.?; | 4793 | const pt = func.pt; |
| 4794 | const mod = pt.zcu; | ||
| 4738 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4795 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4739 | 4796 | ||
| 4740 | const ptr_ty = func.typeOf(bin_op.lhs); | 4797 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4741 | const ptr = try func.resolveInst(bin_op.lhs); | 4798 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4742 | const index = try func.resolveInst(bin_op.rhs); | 4799 | const index = try func.resolveInst(bin_op.rhs); |
| 4743 | const elem_ty = ptr_ty.childType(mod); | 4800 | const elem_ty = ptr_ty.childType(mod); |
| 4744 | const elem_size = elem_ty.abiSize(mod); | 4801 | const elem_size = elem_ty.abiSize(pt); |
| 4745 | 4802 | ||
| 4746 | // load pointer onto the stack | 4803 | // load pointer onto the stack |
| 4747 | if (ptr_ty.isSlice(mod)) { | 4804 | if (ptr_ty.isSlice(mod)) { |
| ... | @@ -4759,7 +4816,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4759,7 +4816,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4759 | const elem_result = val: { | 4816 | const elem_result = val: { |
| 4760 | var result = try func.allocLocal(Type.usize); | 4817 | var result = try func.allocLocal(Type.usize); |
| 4761 | try func.addLabel(.local_set, result.local.value); | 4818 | try func.addLabel(.local_set, result.local.value); |
| 4762 | if (isByRef(elem_ty, mod)) { | 4819 | if (isByRef(elem_ty, pt)) { |
| 4763 | break :val result; | 4820 | break :val result; |
| 4764 | } | 4821 | } |
| 4765 | defer result.free(func); // only free if it's not returned like above | 4822 | defer result.free(func); // only free if it's not returned like above |
| ... | @@ -4771,13 +4828,14 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4771,13 +4828,14 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4771 | } | 4828 | } |
| 4772 | 4829 | ||
| 4773 | fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4830 | fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4774 | const mod = func.bin_file.base.comp.module.?; | 4831 | const pt = func.pt; |
| 4832 | const mod = pt.zcu; | ||
| 4775 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4833 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4776 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; | 4834 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4777 | 4835 | ||
| 4778 | const ptr_ty = func.typeOf(bin_op.lhs); | 4836 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4779 | const elem_ty = ty_pl.ty.toType().childType(mod); | 4837 | const elem_ty = ty_pl.ty.toType().childType(mod); |
| 4780 | const elem_size = elem_ty.abiSize(mod); | 4838 | const elem_size = elem_ty.abiSize(pt); |
| 4781 | 4839 | ||
| 4782 | const ptr = try func.resolveInst(bin_op.lhs); | 4840 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4783 | const index = try func.resolveInst(bin_op.rhs); | 4841 | const index = try func.resolveInst(bin_op.rhs); |
| ... | @@ -4801,7 +4859,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4801,7 +4859,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4801 | } | 4859 | } |
| 4802 | 4860 | ||
| 4803 | fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | 4861 | fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4804 | const mod = func.bin_file.base.comp.module.?; | 4862 | const pt = func.pt; |
| 4863 | const mod = pt.zcu; | ||
| 4805 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4864 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4806 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; | 4865 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4807 | 4866 | ||
| ... | @@ -4813,13 +4872,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -4813,13 +4872,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4813 | else => ptr_ty.childType(mod), | 4872 | else => ptr_ty.childType(mod), |
| 4814 | }; | 4873 | }; |
| 4815 | 4874 | ||
| 4816 | const valtype = typeToValtype(Type.usize, mod); | 4875 | const valtype = typeToValtype(Type.usize, pt); |
| 4817 | const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul }); | 4876 | const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul }); |
| 4818 | const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op }); | 4877 | const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op }); |
| 4819 | 4878 | ||
| 4820 | try func.lowerToStack(ptr); | 4879 | try func.lowerToStack(ptr); |
| 4821 | try func.emitWValue(offset); | 4880 | try func.emitWValue(offset); |
| 4822 | try func.addImm32(@intCast(pointee_ty.abiSize(mod))); | 4881 | try func.addImm32(@intCast(pointee_ty.abiSize(pt))); |
| 4823 | try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode)); | 4882 | try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode)); |
| 4824 | try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode)); | 4883 | try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode)); |
| 4825 | 4884 | ||
| ... | @@ -4829,7 +4888,8 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -4829,7 +4888,8 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4829 | } | 4888 | } |
| 4830 | 4889 | ||
| 4831 | fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { | 4890 | fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 4832 | const mod = func.bin_file.base.comp.module.?; | 4891 | const pt = func.pt; |
| 4892 | const mod = pt.zcu; | ||
| 4833 | if (safety) { | 4893 | if (safety) { |
| 4834 | // TODO if the value is undef, write 0xaa bytes to dest | 4894 | // TODO if the value is undef, write 0xaa bytes to dest |
| 4835 | } else { | 4895 | } else { |
| ... | @@ -4862,8 +4922,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void | ... | @@ -4862,8 +4922,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 4862 | /// this to wasm's memset instruction. When the feature is not present, | 4922 | /// this to wasm's memset instruction. When the feature is not present, |
| 4863 | /// we implement it manually. | 4923 | /// we implement it manually. |
| 4864 | fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void { | 4924 | fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void { |
| 4865 | const mod = func.bin_file.base.comp.module.?; | 4925 | const pt = func.pt; |
| 4866 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(mod))); | 4926 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(pt))); |
| 4867 | 4927 | ||
| 4868 | // When bulk_memory is enabled, we lower it to wasm's memset instruction. | 4928 | // When bulk_memory is enabled, we lower it to wasm's memset instruction. |
| 4869 | // If not, we lower it ourselves. | 4929 | // If not, we lower it ourselves. |
| ... | @@ -4951,16 +5011,17 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue | ... | @@ -4951,16 +5011,17 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue |
| 4951 | } | 5011 | } |
| 4952 | 5012 | ||
| 4953 | fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5013 | fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4954 | const mod = func.bin_file.base.comp.module.?; | 5014 | const pt = func.pt; |
| 5015 | const mod = pt.zcu; | ||
| 4955 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5016 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4956 | 5017 | ||
| 4957 | const array_ty = func.typeOf(bin_op.lhs); | 5018 | const array_ty = func.typeOf(bin_op.lhs); |
| 4958 | const array = try func.resolveInst(bin_op.lhs); | 5019 | const array = try func.resolveInst(bin_op.lhs); |
| 4959 | const index = try func.resolveInst(bin_op.rhs); | 5020 | const index = try func.resolveInst(bin_op.rhs); |
| 4960 | const elem_ty = array_ty.childType(mod); | 5021 | const elem_ty = array_ty.childType(mod); |
| 4961 | const elem_size = elem_ty.abiSize(mod); | 5022 | const elem_size = elem_ty.abiSize(pt); |
| 4962 | 5023 | ||
| 4963 | if (isByRef(array_ty, mod)) { | 5024 | if (isByRef(array_ty, pt)) { |
| 4964 | try func.lowerToStack(array); | 5025 | try func.lowerToStack(array); |
| 4965 | try func.emitWValue(index); | 5026 | try func.emitWValue(index); |
| 4966 | try func.addImm32(@intCast(elem_size)); | 5027 | try func.addImm32(@intCast(elem_size)); |
| ... | @@ -4971,7 +5032,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4971,7 +5032,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4971 | 5032 | ||
| 4972 | switch (index) { | 5033 | switch (index) { |
| 4973 | inline .imm32, .imm64 => |lane| { | 5034 | inline .imm32, .imm64 => |lane| { |
| 4974 | const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(mod)) { | 5035 | const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(pt)) { |
| 4975 | 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u, | 5036 | 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u, |
| 4976 | 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u, | 5037 | 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u, |
| 4977 | 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane, | 5038 | 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane, |
| ... | @@ -5007,7 +5068,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5007,7 +5068,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5007 | var result = try func.allocLocal(Type.usize); | 5068 | var result = try func.allocLocal(Type.usize); |
| 5008 | try func.addLabel(.local_set, result.local.value); | 5069 | try func.addLabel(.local_set, result.local.value); |
| 5009 | 5070 | ||
| 5010 | if (isByRef(elem_ty, mod)) { | 5071 | if (isByRef(elem_ty, pt)) { |
| 5011 | break :val result; | 5072 | break :val result; |
| 5012 | } | 5073 | } |
| 5013 | defer result.free(func); // only free if no longer needed and not returned like above | 5074 | defer result.free(func); // only free if no longer needed and not returned like above |
| ... | @@ -5020,7 +5081,8 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5020,7 +5081,8 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5020 | } | 5081 | } |
| 5021 | 5082 | ||
| 5022 | fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5083 | fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5023 | const mod = func.bin_file.base.comp.module.?; | 5084 | const pt = func.pt; |
| 5085 | const mod = pt.zcu; | ||
| 5024 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5086 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5025 | 5087 | ||
| 5026 | const operand = try func.resolveInst(ty_op.operand); | 5088 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -5054,8 +5116,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5054,8 +5116,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5054 | try func.emitWValue(operand); | 5116 | try func.emitWValue(operand); |
| 5055 | const op = buildOpcode(.{ | 5117 | const op = buildOpcode(.{ |
| 5056 | .op = .trunc, | 5118 | .op = .trunc, |
| 5057 | .valtype1 = typeToValtype(dest_ty, mod), | 5119 | .valtype1 = typeToValtype(dest_ty, pt), |
| 5058 | .valtype2 = typeToValtype(op_ty, mod), | 5120 | .valtype2 = typeToValtype(op_ty, pt), |
| 5059 | .signedness = dest_info.signedness, | 5121 | .signedness = dest_info.signedness, |
| 5060 | }); | 5122 | }); |
| 5061 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); | 5123 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| ... | @@ -5065,7 +5127,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5065,7 +5127,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5065 | } | 5127 | } |
| 5066 | 5128 | ||
| 5067 | fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5129 | fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5068 | const mod = func.bin_file.base.comp.module.?; | 5130 | const pt = func.pt; |
| 5131 | const mod = pt.zcu; | ||
| 5069 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5132 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5070 | 5133 | ||
| 5071 | const operand = try func.resolveInst(ty_op.operand); | 5134 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -5099,8 +5162,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5099,8 +5162,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5099 | try func.emitWValue(operand); | 5162 | try func.emitWValue(operand); |
| 5100 | const op = buildOpcode(.{ | 5163 | const op = buildOpcode(.{ |
| 5101 | .op = .convert, | 5164 | .op = .convert, |
| 5102 | .valtype1 = typeToValtype(dest_ty, mod), | 5165 | .valtype1 = typeToValtype(dest_ty, pt), |
| 5103 | .valtype2 = typeToValtype(op_ty, mod), | 5166 | .valtype2 = typeToValtype(op_ty, pt), |
| 5104 | .signedness = op_info.signedness, | 5167 | .signedness = op_info.signedness, |
| 5105 | }); | 5168 | }); |
| 5106 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); | 5169 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| ... | @@ -5111,19 +5174,20 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5111,19 +5174,20 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5111 | } | 5174 | } |
| 5112 | 5175 | ||
| 5113 | fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5176 | fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5114 | const mod = func.bin_file.base.comp.module.?; | 5177 | const pt = func.pt; |
| 5178 | const mod = pt.zcu; | ||
| 5115 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5179 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5116 | const operand = try func.resolveInst(ty_op.operand); | 5180 | const operand = try func.resolveInst(ty_op.operand); |
| 5117 | const ty = func.typeOfIndex(inst); | 5181 | const ty = func.typeOfIndex(inst); |
| 5118 | const elem_ty = ty.childType(mod); | 5182 | const elem_ty = ty.childType(mod); |
| 5119 | 5183 | ||
| 5120 | if (determineSimdStoreStrategy(ty, mod) == .direct) blk: { | 5184 | if (determineSimdStoreStrategy(ty, pt) == .direct) blk: { |
| 5121 | switch (operand) { | 5185 | switch (operand) { |
| 5122 | // when the operand lives in the linear memory section, we can directly | 5186 | // when the operand lives in the linear memory section, we can directly |
| 5123 | // load and splat the value at once. Meaning we do not first have to load | 5187 | // load and splat the value at once. Meaning we do not first have to load |
| 5124 | // the scalar value onto the stack. | 5188 | // the scalar value onto the stack. |
| 5125 | .stack_offset, .memory, .memory_offset => { | 5189 | .stack_offset, .memory, .memory_offset => { |
| 5126 | const opcode = switch (elem_ty.bitSize(mod)) { | 5190 | const opcode = switch (elem_ty.bitSize(pt)) { |
| 5127 | 8 => std.wasm.simdOpcode(.v128_load8_splat), | 5191 | 8 => std.wasm.simdOpcode(.v128_load8_splat), |
| 5128 | 16 => std.wasm.simdOpcode(.v128_load16_splat), | 5192 | 16 => std.wasm.simdOpcode(.v128_load16_splat), |
| 5129 | 32 => std.wasm.simdOpcode(.v128_load32_splat), | 5193 | 32 => std.wasm.simdOpcode(.v128_load32_splat), |
| ... | @@ -5138,14 +5202,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5138,14 +5202,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5138 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ | 5202 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 5139 | opcode, | 5203 | opcode, |
| 5140 | operand.offset(), | 5204 | operand.offset(), |
| 5141 | @intCast(elem_ty.abiAlignment(mod).toByteUnits().?), | 5205 | @intCast(elem_ty.abiAlignment(pt).toByteUnits().?), |
| 5142 | }); | 5206 | }); |
| 5143 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); | 5207 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 5144 | try func.addLabel(.local_set, result.local.value); | 5208 | try func.addLabel(.local_set, result.local.value); |
| 5145 | return func.finishAir(inst, result, &.{ty_op.operand}); | 5209 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 5146 | }, | 5210 | }, |
| 5147 | .local => { | 5211 | .local => { |
| 5148 | const opcode = switch (elem_ty.bitSize(mod)) { | 5212 | const opcode = switch (elem_ty.bitSize(pt)) { |
| 5149 | 8 => std.wasm.simdOpcode(.i8x16_splat), | 5213 | 8 => std.wasm.simdOpcode(.i8x16_splat), |
| 5150 | 16 => std.wasm.simdOpcode(.i16x8_splat), | 5214 | 16 => std.wasm.simdOpcode(.i16x8_splat), |
| 5151 | 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat), | 5215 | 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat), |
| ... | @@ -5163,14 +5227,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5163,14 +5227,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5163 | else => unreachable, | 5227 | else => unreachable, |
| 5164 | } | 5228 | } |
| 5165 | } | 5229 | } |
| 5166 | const elem_size = elem_ty.bitSize(mod); | 5230 | const elem_size = elem_ty.bitSize(pt); |
| 5167 | const vector_len = @as(usize, @intCast(ty.vectorLen(mod))); | 5231 | const vector_len = @as(usize, @intCast(ty.vectorLen(mod))); |
| 5168 | if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) { | 5232 | if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) { |
| 5169 | return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size}); | 5233 | return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size}); |
| 5170 | } | 5234 | } |
| 5171 | 5235 | ||
| 5172 | const result = try func.allocStack(ty); | 5236 | const result = try func.allocStack(ty); |
| 5173 | const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(mod))); | 5237 | const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(pt))); |
| 5174 | var index: usize = 0; | 5238 | var index: usize = 0; |
| 5175 | var offset: u32 = 0; | 5239 | var offset: u32 = 0; |
| 5176 | while (index < vector_len) : (index += 1) { | 5240 | while (index < vector_len) : (index += 1) { |
| ... | @@ -5190,7 +5254,8 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5190,7 +5254,8 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5190 | } | 5254 | } |
| 5191 | 5255 | ||
| 5192 | fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5256 | fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5193 | const mod = func.bin_file.base.comp.module.?; | 5257 | const pt = func.pt; |
| 5258 | const mod = pt.zcu; | ||
| 5194 | const inst_ty = func.typeOfIndex(inst); | 5259 | const inst_ty = func.typeOfIndex(inst); |
| 5195 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5260 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5196 | const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data; | 5261 | const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| ... | @@ -5201,14 +5266,14 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5201,14 +5266,14 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5201 | const mask_len = extra.mask_len; | 5266 | const mask_len = extra.mask_len; |
| 5202 | 5267 | ||
| 5203 | const child_ty = inst_ty.childType(mod); | 5268 | const child_ty = inst_ty.childType(mod); |
| 5204 | const elem_size = child_ty.abiSize(mod); | 5269 | const elem_size = child_ty.abiSize(pt); |
| 5205 | 5270 | ||
| 5206 | // TODO: One of them could be by ref; handle in loop | 5271 | // TODO: One of them could be by ref; handle in loop |
| 5207 | if (isByRef(func.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) { | 5272 | if (isByRef(func.typeOf(extra.a), pt) or isByRef(inst_ty, pt)) { |
| 5208 | const result = try func.allocStack(inst_ty); | 5273 | const result = try func.allocStack(inst_ty); |
| 5209 | 5274 | ||
| 5210 | for (0..mask_len) |index| { | 5275 | for (0..mask_len) |index| { |
| 5211 | const value = (try mask.elemValue(mod, index)).toSignedInt(mod); | 5276 | const value = (try mask.elemValue(pt, index)).toSignedInt(pt); |
| 5212 | 5277 | ||
| 5213 | try func.emitWValue(result); | 5278 | try func.emitWValue(result); |
| 5214 | 5279 | ||
| ... | @@ -5228,7 +5293,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5228,7 +5293,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5228 | 5293 | ||
| 5229 | var lanes = mem.asBytes(operands[1..]); | 5294 | var lanes = mem.asBytes(operands[1..]); |
| 5230 | for (0..@as(usize, @intCast(mask_len))) |index| { | 5295 | for (0..@as(usize, @intCast(mask_len))) |index| { |
| 5231 | const mask_elem = (try mask.elemValue(mod, index)).toSignedInt(mod); | 5296 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt); |
| 5232 | const base_index = if (mask_elem >= 0) | 5297 | const base_index = if (mask_elem >= 0) |
| 5233 | @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem)) | 5298 | @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem)) |
| 5234 | else | 5299 | else |
| ... | @@ -5259,7 +5324,8 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5259,7 +5324,8 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5259 | } | 5324 | } |
| 5260 | 5325 | ||
| 5261 | fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5326 | fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5262 | const mod = func.bin_file.base.comp.module.?; | 5327 | const pt = func.pt; |
| 5328 | const mod = pt.zcu; | ||
| 5263 | const ip = &mod.intern_pool; | 5329 | const ip = &mod.intern_pool; |
| 5264 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5330 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5265 | const result_ty = func.typeOfIndex(inst); | 5331 | const result_ty = func.typeOfIndex(inst); |
| ... | @@ -5271,7 +5337,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5271,7 +5337,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5271 | .Array => { | 5337 | .Array => { |
| 5272 | const result = try func.allocStack(result_ty); | 5338 | const result = try func.allocStack(result_ty); |
| 5273 | const elem_ty = result_ty.childType(mod); | 5339 | const elem_ty = result_ty.childType(mod); |
| 5274 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod))); | 5340 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt))); |
| 5275 | const sentinel = if (result_ty.sentinel(mod)) |sent| blk: { | 5341 | const sentinel = if (result_ty.sentinel(mod)) |sent| blk: { |
| 5276 | break :blk try func.lowerConstant(sent, elem_ty); | 5342 | break :blk try func.lowerConstant(sent, elem_ty); |
| 5277 | } else null; | 5343 | } else null; |
| ... | @@ -5279,7 +5345,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5279,7 +5345,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5279 | // When the element type is by reference, we must copy the entire | 5345 | // When the element type is by reference, we must copy the entire |
| 5280 | // value. It is therefore safer to move the offset pointer and store | 5346 | // value. It is therefore safer to move the offset pointer and store |
| 5281 | // each value individually, instead of using store offsets. | 5347 | // each value individually, instead of using store offsets. |
| 5282 | if (isByRef(elem_ty, mod)) { | 5348 | if (isByRef(elem_ty, pt)) { |
| 5283 | // copy stack pointer into a temporary local, which is | 5349 | // copy stack pointer into a temporary local, which is |
| 5284 | // moved for each element to store each value in the right position. | 5350 | // moved for each element to store each value in the right position. |
| 5285 | const offset = try func.buildPointerOffset(result, 0, .new); | 5351 | const offset = try func.buildPointerOffset(result, 0, .new); |
| ... | @@ -5309,7 +5375,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5309,7 +5375,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5309 | }, | 5375 | }, |
| 5310 | .Struct => switch (result_ty.containerLayout(mod)) { | 5376 | .Struct => switch (result_ty.containerLayout(mod)) { |
| 5311 | .@"packed" => { | 5377 | .@"packed" => { |
| 5312 | if (isByRef(result_ty, mod)) { | 5378 | if (isByRef(result_ty, pt)) { |
| 5313 | return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{}); | 5379 | return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{}); |
| 5314 | } | 5380 | } |
| 5315 | const packed_struct = mod.typeToPackedStruct(result_ty).?; | 5381 | const packed_struct = mod.typeToPackedStruct(result_ty).?; |
| ... | @@ -5318,7 +5384,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5318,7 +5384,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5318 | 5384 | ||
| 5319 | // ensure the result is zero'd | 5385 | // ensure the result is zero'd |
| 5320 | const result = try func.allocLocal(backing_type); | 5386 | const result = try func.allocLocal(backing_type); |
| 5321 | if (backing_type.bitSize(mod) <= 32) | 5387 | if (backing_type.bitSize(pt) <= 32) |
| 5322 | try func.addImm32(0) | 5388 | try func.addImm32(0) |
| 5323 | else | 5389 | else |
| 5324 | try func.addImm64(0); | 5390 | try func.addImm64(0); |
| ... | @@ -5327,16 +5393,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5327,16 +5393,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5327 | var current_bit: u16 = 0; | 5393 | var current_bit: u16 = 0; |
| 5328 | for (elements, 0..) |elem, elem_index| { | 5394 | for (elements, 0..) |elem, elem_index| { |
| 5329 | const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]); | 5395 | const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]); |
| 5330 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 5396 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 5331 | 5397 | ||
| 5332 | const shift_val = if (backing_type.bitSize(mod) <= 32) | 5398 | const shift_val = if (backing_type.bitSize(pt) <= 32) |
| 5333 | WValue{ .imm32 = current_bit } | 5399 | WValue{ .imm32 = current_bit } |
| 5334 | else | 5400 | else |
| 5335 | WValue{ .imm64 = current_bit }; | 5401 | WValue{ .imm64 = current_bit }; |
| 5336 | 5402 | ||
| 5337 | const value = try func.resolveInst(elem); | 5403 | const value = try func.resolveInst(elem); |
| 5338 | const value_bit_size: u16 = @intCast(field_ty.bitSize(mod)); | 5404 | const value_bit_size: u16 = @intCast(field_ty.bitSize(pt)); |
| 5339 | const int_ty = try mod.intType(.unsigned, value_bit_size); | 5405 | const int_ty = try pt.intType(.unsigned, value_bit_size); |
| 5340 | 5406 | ||
| 5341 | // load our current result on stack so we can perform all transformations | 5407 | // load our current result on stack so we can perform all transformations |
| 5342 | // using only stack values. Saving the cost of loads and stores. | 5408 | // using only stack values. Saving the cost of loads and stores. |
| ... | @@ -5359,10 +5425,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5359,10 +5425,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5359 | const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset | 5425 | const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset |
| 5360 | var prev_field_offset: u64 = 0; | 5426 | var prev_field_offset: u64 = 0; |
| 5361 | for (elements, 0..) |elem, elem_index| { | 5427 | for (elements, 0..) |elem, elem_index| { |
| 5362 | if ((try result_ty.structFieldValueComptime(mod, elem_index)) != null) continue; | 5428 | if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue; |
| 5363 | 5429 | ||
| 5364 | const elem_ty = result_ty.structFieldType(elem_index, mod); | 5430 | const elem_ty = result_ty.structFieldType(elem_index, mod); |
| 5365 | const field_offset = result_ty.structFieldOffset(elem_index, mod); | 5431 | const field_offset = result_ty.structFieldOffset(elem_index, pt); |
| 5366 | _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify); | 5432 | _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify); |
| 5367 | prev_field_offset = field_offset; | 5433 | prev_field_offset = field_offset; |
| 5368 | 5434 | ||
| ... | @@ -5389,14 +5455,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5389,14 +5455,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5389 | } | 5455 | } |
| 5390 | 5456 | ||
| 5391 | fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5457 | fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5392 | const mod = func.bin_file.base.comp.module.?; | 5458 | const pt = func.pt; |
| 5459 | const mod = pt.zcu; | ||
| 5393 | const ip = &mod.intern_pool; | 5460 | const ip = &mod.intern_pool; |
| 5394 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5461 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5395 | const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data; | 5462 | const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 5396 | 5463 | ||
| 5397 | const result = result: { | 5464 | const result = result: { |
| 5398 | const union_ty = func.typeOfIndex(inst); | 5465 | const union_ty = func.typeOfIndex(inst); |
| 5399 | const layout = union_ty.unionGetLayout(mod); | 5466 | const layout = union_ty.unionGetLayout(pt); |
| 5400 | const union_obj = mod.typeToUnion(union_ty).?; | 5467 | const union_obj = mod.typeToUnion(union_ty).?; |
| 5401 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); | 5468 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 5402 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 5469 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| ... | @@ -5404,22 +5471,22 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5404,22 +5471,22 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5404 | const tag_int = blk: { | 5471 | const tag_int = blk: { |
| 5405 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | 5472 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); |
| 5406 | const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?; | 5473 | const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?; |
| 5407 | const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index); | 5474 | const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index); |
| 5408 | break :blk try func.lowerConstant(tag_val, tag_ty); | 5475 | break :blk try func.lowerConstant(tag_val, tag_ty); |
| 5409 | }; | 5476 | }; |
| 5410 | if (layout.payload_size == 0) { | 5477 | if (layout.payload_size == 0) { |
| 5411 | if (layout.tag_size == 0) { | 5478 | if (layout.tag_size == 0) { |
| 5412 | break :result WValue{ .none = {} }; | 5479 | break :result WValue{ .none = {} }; |
| 5413 | } | 5480 | } |
| 5414 | assert(!isByRef(union_ty, mod)); | 5481 | assert(!isByRef(union_ty, pt)); |
| 5415 | break :result tag_int; | 5482 | break :result tag_int; |
| 5416 | } | 5483 | } |
| 5417 | 5484 | ||
| 5418 | if (isByRef(union_ty, mod)) { | 5485 | if (isByRef(union_ty, pt)) { |
| 5419 | const result_ptr = try func.allocStack(union_ty); | 5486 | const result_ptr = try func.allocStack(union_ty); |
| 5420 | const payload = try func.resolveInst(extra.init); | 5487 | const payload = try func.resolveInst(extra.init); |
| 5421 | if (layout.tag_align.compare(.gte, layout.payload_align)) { | 5488 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| 5422 | if (isByRef(field_ty, mod)) { | 5489 | if (isByRef(field_ty, pt)) { |
| 5423 | const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new); | 5490 | const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new); |
| 5424 | try func.store(payload_ptr, payload, field_ty, 0); | 5491 | try func.store(payload_ptr, payload, field_ty, 0); |
| 5425 | } else { | 5492 | } else { |
| ... | @@ -5443,14 +5510,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5443,14 +5510,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5443 | break :result result_ptr; | 5510 | break :result result_ptr; |
| 5444 | } else { | 5511 | } else { |
| 5445 | const operand = try func.resolveInst(extra.init); | 5512 | const operand = try func.resolveInst(extra.init); |
| 5446 | const union_int_type = try mod.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(mod)))); | 5513 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(pt)))); |
| 5447 | if (field_ty.zigTypeTag(mod) == .Float) { | 5514 | if (field_ty.zigTypeTag(mod) == .Float) { |
| 5448 | const int_type = try mod.intType(.unsigned, @intCast(field_ty.bitSize(mod))); | 5515 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt))); |
| 5449 | const bitcasted = try func.bitcast(field_ty, int_type, operand); | 5516 | const bitcasted = try func.bitcast(field_ty, int_type, operand); |
| 5450 | const casted = try func.trunc(bitcasted, int_type, union_int_type); | 5517 | const casted = try func.trunc(bitcasted, int_type, union_int_type); |
| 5451 | break :result try casted.toLocal(func, field_ty); | 5518 | break :result try casted.toLocal(func, field_ty); |
| 5452 | } else if (field_ty.isPtrAtRuntime(mod)) { | 5519 | } else if (field_ty.isPtrAtRuntime(mod)) { |
| 5453 | const int_type = try mod.intType(.unsigned, @intCast(field_ty.bitSize(mod))); | 5520 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt))); |
| 5454 | const casted = try func.intcast(operand, int_type, union_int_type); | 5521 | const casted = try func.intcast(operand, int_type, union_int_type); |
| 5455 | break :result try casted.toLocal(func, field_ty); | 5522 | break :result try casted.toLocal(func, field_ty); |
| 5456 | } | 5523 | } |
| ... | @@ -5488,8 +5555,9 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -5488,8 +5555,9 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void { |
| 5488 | } | 5555 | } |
| 5489 | 5556 | ||
| 5490 | fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { | 5557 | fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 5491 | const mod = func.bin_file.base.comp.module.?; | 5558 | const pt = func.pt; |
| 5492 | assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod)); | 5559 | const mod = pt.zcu; |
| 5560 | assert(operand_ty.hasRuntimeBitsIgnoreComptime(pt)); | ||
| 5493 | assert(op == .eq or op == .neq); | 5561 | assert(op == .eq or op == .neq); |
| 5494 | const payload_ty = operand_ty.optionalChild(mod); | 5562 | const payload_ty = operand_ty.optionalChild(mod); |
| 5495 | 5563 | ||
| ... | @@ -5506,7 +5574,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: | ... | @@ -5506,7 +5574,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: |
| 5506 | 5574 | ||
| 5507 | _ = try func.load(lhs, payload_ty, 0); | 5575 | _ = try func.load(lhs, payload_ty, 0); |
| 5508 | _ = try func.load(rhs, payload_ty, 0); | 5576 | _ = try func.load(rhs, payload_ty, 0); |
| 5509 | const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, mod) }); | 5577 | const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, pt) }); |
| 5510 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); | 5578 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| 5511 | try func.addLabel(.br_if, 0); | 5579 | try func.addLabel(.br_if, 0); |
| 5512 | 5580 | ||
| ... | @@ -5524,11 +5592,12 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: | ... | @@ -5524,11 +5592,12 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: |
| 5524 | /// NOTE: Leaves the result of the comparison on top of the stack. | 5592 | /// NOTE: Leaves the result of the comparison on top of the stack. |
| 5525 | /// TODO: Lower this to compiler_rt call when bitsize > 128 | 5593 | /// TODO: Lower this to compiler_rt call when bitsize > 128 |
| 5526 | fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { | 5594 | fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 5527 | const mod = func.bin_file.base.comp.module.?; | 5595 | const pt = func.pt; |
| 5528 | assert(operand_ty.abiSize(mod) >= 16); | 5596 | const mod = pt.zcu; |
| 5597 | assert(operand_ty.abiSize(pt) >= 16); | ||
| 5529 | assert(!(lhs != .stack and rhs == .stack)); | 5598 | assert(!(lhs != .stack and rhs == .stack)); |
| 5530 | if (operand_ty.bitSize(mod) > 128) { | 5599 | if (operand_ty.bitSize(pt) > 128) { |
| 5531 | return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(mod)}); | 5600 | return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(pt)}); |
| 5532 | } | 5601 | } |
| 5533 | 5602 | ||
| 5534 | var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64); | 5603 | var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64); |
| ... | @@ -5566,11 +5635,12 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std | ... | @@ -5566,11 +5635,12 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 5566 | } | 5635 | } |
| 5567 | 5636 | ||
| 5568 | fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5637 | fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5569 | const mod = func.bin_file.base.comp.module.?; | 5638 | const pt = func.pt; |
| 5639 | const mod = pt.zcu; | ||
| 5570 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5640 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5571 | const un_ty = func.typeOf(bin_op.lhs).childType(mod); | 5641 | const un_ty = func.typeOf(bin_op.lhs).childType(mod); |
| 5572 | const tag_ty = func.typeOf(bin_op.rhs); | 5642 | const tag_ty = func.typeOf(bin_op.rhs); |
| 5573 | const layout = un_ty.unionGetLayout(mod); | 5643 | const layout = un_ty.unionGetLayout(pt); |
| 5574 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs }); | 5644 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs }); |
| 5575 | 5645 | ||
| 5576 | const union_ptr = try func.resolveInst(bin_op.lhs); | 5646 | const union_ptr = try func.resolveInst(bin_op.lhs); |
| ... | @@ -5590,12 +5660,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5590,12 +5660,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5590 | } | 5660 | } |
| 5591 | 5661 | ||
| 5592 | fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5662 | fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5593 | const mod = func.bin_file.base.comp.module.?; | 5663 | const pt = func.pt; |
| 5594 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5664 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5595 | 5665 | ||
| 5596 | const un_ty = func.typeOf(ty_op.operand); | 5666 | const un_ty = func.typeOf(ty_op.operand); |
| 5597 | const tag_ty = func.typeOfIndex(inst); | 5667 | const tag_ty = func.typeOfIndex(inst); |
| 5598 | const layout = un_ty.unionGetLayout(mod); | 5668 | const layout = un_ty.unionGetLayout(pt); |
| 5599 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand}); | 5669 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand}); |
| 5600 | 5670 | ||
| 5601 | const operand = try func.resolveInst(ty_op.operand); | 5671 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -5695,7 +5765,8 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro | ... | @@ -5695,7 +5765,8 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 5695 | } | 5765 | } |
| 5696 | 5766 | ||
| 5697 | fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5767 | fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5698 | const mod = func.bin_file.base.comp.module.?; | 5768 | const pt = func.pt; |
| 5769 | const mod = pt.zcu; | ||
| 5699 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5770 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5700 | 5771 | ||
| 5701 | const err_set_ty = func.typeOf(ty_op.operand).childType(mod); | 5772 | const err_set_ty = func.typeOf(ty_op.operand).childType(mod); |
| ... | @@ -5707,27 +5778,28 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi | ... | @@ -5707,27 +5778,28 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi |
| 5707 | operand, | 5778 | operand, |
| 5708 | .{ .imm32 = 0 }, | 5779 | .{ .imm32 = 0 }, |
| 5709 | Type.anyerror, | 5780 | Type.anyerror, |
| 5710 | @as(u32, @intCast(errUnionErrorOffset(payload_ty, mod))), | 5781 | @intCast(errUnionErrorOffset(payload_ty, pt)), |
| 5711 | ); | 5782 | ); |
| 5712 | 5783 | ||
| 5713 | const result = result: { | 5784 | const result = result: { |
| 5714 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5785 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5715 | break :result func.reuseOperand(ty_op.operand, operand); | 5786 | break :result func.reuseOperand(ty_op.operand, operand); |
| 5716 | } | 5787 | } |
| 5717 | 5788 | ||
| 5718 | break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, mod))), .new); | 5789 | break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))), .new); |
| 5719 | }; | 5790 | }; |
| 5720 | func.finishAir(inst, result, &.{ty_op.operand}); | 5791 | func.finishAir(inst, result, &.{ty_op.operand}); |
| 5721 | } | 5792 | } |
| 5722 | 5793 | ||
| 5723 | fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5794 | fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5724 | const mod = func.bin_file.base.comp.module.?; | 5795 | const pt = func.pt; |
| 5796 | const mod = pt.zcu; | ||
| 5725 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5797 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5726 | const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 5798 | const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5727 | 5799 | ||
| 5728 | const field_ptr = try func.resolveInst(extra.field_ptr); | 5800 | const field_ptr = try func.resolveInst(extra.field_ptr); |
| 5729 | const parent_ty = ty_pl.ty.toType().childType(mod); | 5801 | const parent_ty = ty_pl.ty.toType().childType(mod); |
| 5730 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); | 5802 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); |
| 5731 | 5803 | ||
| 5732 | const result = if (field_offset != 0) result: { | 5804 | const result = if (field_offset != 0) result: { |
| 5733 | const base = try func.buildPointerOffset(field_ptr, 0, .new); | 5805 | const base = try func.buildPointerOffset(field_ptr, 0, .new); |
| ... | @@ -5742,7 +5814,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5742,7 +5814,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5742 | } | 5814 | } |
| 5743 | 5815 | ||
| 5744 | fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue { | 5816 | fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue { |
| 5745 | const mod = func.bin_file.base.comp.module.?; | 5817 | const pt = func.pt; |
| 5818 | const mod = pt.zcu; | ||
| 5746 | if (ptr_ty.isSlice(mod)) { | 5819 | if (ptr_ty.isSlice(mod)) { |
| 5747 | return func.slicePtr(ptr); | 5820 | return func.slicePtr(ptr); |
| 5748 | } else { | 5821 | } else { |
| ... | @@ -5751,7 +5824,8 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue | ... | @@ -5751,7 +5824,8 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue |
| 5751 | } | 5824 | } |
| 5752 | 5825 | ||
| 5753 | fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5826 | fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5754 | const mod = func.bin_file.base.comp.module.?; | 5827 | const pt = func.pt; |
| 5828 | const mod = pt.zcu; | ||
| 5755 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5829 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5756 | const dst = try func.resolveInst(bin_op.lhs); | 5830 | const dst = try func.resolveInst(bin_op.lhs); |
| 5757 | const dst_ty = func.typeOf(bin_op.lhs); | 5831 | const dst_ty = func.typeOf(bin_op.lhs); |
| ... | @@ -5761,16 +5835,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5761,16 +5835,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5761 | const len = switch (dst_ty.ptrSize(mod)) { | 5835 | const len = switch (dst_ty.ptrSize(mod)) { |
| 5762 | .Slice => blk: { | 5836 | .Slice => blk: { |
| 5763 | const slice_len = try func.sliceLen(dst); | 5837 | const slice_len = try func.sliceLen(dst); |
| 5764 | if (ptr_elem_ty.abiSize(mod) != 1) { | 5838 | if (ptr_elem_ty.abiSize(pt) != 1) { |
| 5765 | try func.emitWValue(slice_len); | 5839 | try func.emitWValue(slice_len); |
| 5766 | try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(mod))) }); | 5840 | try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(pt))) }); |
| 5767 | try func.addTag(.i32_mul); | 5841 | try func.addTag(.i32_mul); |
| 5768 | try func.addLabel(.local_set, slice_len.local.value); | 5842 | try func.addLabel(.local_set, slice_len.local.value); |
| 5769 | } | 5843 | } |
| 5770 | break :blk slice_len; | 5844 | break :blk slice_len; |
| 5771 | }, | 5845 | }, |
| 5772 | .One => @as(WValue, .{ | 5846 | .One => @as(WValue, .{ |
| 5773 | .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(mod))), | 5847 | .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(pt))), |
| 5774 | }), | 5848 | }), |
| 5775 | .C, .Many => unreachable, | 5849 | .C, .Many => unreachable, |
| 5776 | }; | 5850 | }; |
| ... | @@ -5791,7 +5865,8 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5791,7 +5865,8 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5791 | } | 5865 | } |
| 5792 | 5866 | ||
| 5793 | fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5867 | fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5794 | const mod = func.bin_file.base.comp.module.?; | 5868 | const pt = func.pt; |
| 5869 | const mod = pt.zcu; | ||
| 5795 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5870 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5796 | 5871 | ||
| 5797 | const operand = try func.resolveInst(ty_op.operand); | 5872 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -5812,14 +5887,14 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5812,14 +5887,14 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5812 | 32 => { | 5887 | 32 => { |
| 5813 | try func.emitWValue(operand); | 5888 | try func.emitWValue(operand); |
| 5814 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | 5889 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { |
| 5815 | _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits)); | 5890 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits)); |
| 5816 | } | 5891 | } |
| 5817 | try func.addTag(.i32_popcnt); | 5892 | try func.addTag(.i32_popcnt); |
| 5818 | }, | 5893 | }, |
| 5819 | 64 => { | 5894 | 64 => { |
| 5820 | try func.emitWValue(operand); | 5895 | try func.emitWValue(operand); |
| 5821 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | 5896 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { |
| 5822 | _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits)); | 5897 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits)); |
| 5823 | } | 5898 | } |
| 5824 | try func.addTag(.i64_popcnt); | 5899 | try func.addTag(.i64_popcnt); |
| 5825 | try func.addTag(.i32_wrap_i64); | 5900 | try func.addTag(.i32_wrap_i64); |
| ... | @@ -5830,7 +5905,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5830,7 +5905,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5830 | try func.addTag(.i64_popcnt); | 5905 | try func.addTag(.i64_popcnt); |
| 5831 | _ = try func.load(operand, Type.u64, 8); | 5906 | _ = try func.load(operand, Type.u64, 8); |
| 5832 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | 5907 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { |
| 5833 | _ = try func.wrapOperand(.stack, try mod.intType(.unsigned, bits - 64)); | 5908 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits - 64)); |
| 5834 | } | 5909 | } |
| 5835 | try func.addTag(.i64_popcnt); | 5910 | try func.addTag(.i64_popcnt); |
| 5836 | try func.addTag(.i64_add); | 5911 | try func.addTag(.i64_add); |
| ... | @@ -5845,7 +5920,8 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5845,7 +5920,8 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5845 | } | 5920 | } |
| 5846 | 5921 | ||
| 5847 | fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5922 | fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5848 | const mod = func.bin_file.base.comp.module.?; | 5923 | const pt = func.pt; |
| 5924 | const mod = pt.zcu; | ||
| 5849 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5925 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5850 | 5926 | ||
| 5851 | const operand = try func.resolveInst(ty_op.operand); | 5927 | const operand = try func.resolveInst(ty_op.operand); |
| ... | @@ -5956,10 +6032,10 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5956,10 +6032,10 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5956 | // | 6032 | // |
| 5957 | // As the names are global and the slice elements are constant, we do not have | 6033 | // As the names are global and the slice elements are constant, we do not have |
| 5958 | // to make a copy of the ptr+value but can point towards them directly. | 6034 | // to make a copy of the ptr+value but can point towards them directly. |
| 5959 | const error_table_symbol = try func.bin_file.getErrorTableSymbol(); | 6035 | const pt = func.pt; |
| 6036 | const error_table_symbol = try func.bin_file.getErrorTableSymbol(pt); | ||
| 5960 | const name_ty = Type.slice_const_u8_sentinel_0; | 6037 | const name_ty = Type.slice_const_u8_sentinel_0; |
| 5961 | const mod = func.bin_file.base.comp.module.?; | 6038 | const abi_size = name_ty.abiSize(pt); |
| 5962 | const abi_size = name_ty.abiSize(mod); | ||
| 5963 | 6039 | ||
| 5964 | const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation | 6040 | const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation |
| 5965 | try func.emitWValue(error_name_value); | 6041 | try func.emitWValue(error_name_value); |
| ... | @@ -5998,7 +6074,8 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro | ... | @@ -5998,7 +6074,8 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 5998 | const lhs = try func.resolveInst(extra.lhs); | 6074 | const lhs = try func.resolveInst(extra.lhs); |
| 5999 | const rhs = try func.resolveInst(extra.rhs); | 6075 | const rhs = try func.resolveInst(extra.rhs); |
| 6000 | const lhs_ty = func.typeOf(extra.lhs); | 6076 | const lhs_ty = func.typeOf(extra.lhs); |
| 6001 | const mod = func.bin_file.base.comp.module.?; | 6077 | const pt = func.pt; |
| 6078 | const mod = pt.zcu; | ||
| 6002 | 6079 | ||
| 6003 | if (lhs_ty.zigTypeTag(mod) == .Vector) { | 6080 | if (lhs_ty.zigTypeTag(mod) == .Vector) { |
| 6004 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); | 6081 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| ... | @@ -6044,14 +6121,15 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro | ... | @@ -6044,14 +6121,15 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 6044 | 6121 | ||
| 6045 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); | 6122 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); |
| 6046 | try func.store(result_ptr, result, lhs_ty, 0); | 6123 | try func.store(result_ptr, result, lhs_ty, 0); |
| 6047 | const offset = @as(u32, @intCast(lhs_ty.abiSize(mod))); | 6124 | const offset = @as(u32, @intCast(lhs_ty.abiSize(pt))); |
| 6048 | try func.store(result_ptr, overflow_local, Type.u1, offset); | 6125 | try func.store(result_ptr, overflow_local, Type.u1, offset); |
| 6049 | 6126 | ||
| 6050 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); | 6127 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); |
| 6051 | } | 6128 | } |
| 6052 | 6129 | ||
| 6053 | fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue { | 6130 | fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue { |
| 6054 | const mod = func.bin_file.base.comp.module.?; | 6131 | const pt = func.pt; |
| 6132 | const mod = pt.zcu; | ||
| 6055 | assert(op == .add or op == .sub); | 6133 | assert(op == .add or op == .sub); |
| 6056 | const int_info = ty.intInfo(mod); | 6134 | const int_info = ty.intInfo(mod); |
| 6057 | const is_signed = int_info.signedness == .signed; | 6135 | const is_signed = int_info.signedness == .signed; |
| ... | @@ -6116,7 +6194,8 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, | ... | @@ -6116,7 +6194,8 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, |
| 6116 | } | 6194 | } |
| 6117 | 6195 | ||
| 6118 | fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6196 | fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6119 | const mod = func.bin_file.base.comp.module.?; | 6197 | const pt = func.pt; |
| 6198 | const mod = pt.zcu; | ||
| 6120 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6199 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6121 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; | 6200 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6122 | 6201 | ||
| ... | @@ -6159,7 +6238,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6159,7 +6238,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6159 | 6238 | ||
| 6160 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); | 6239 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); |
| 6161 | try func.store(result_ptr, result, lhs_ty, 0); | 6240 | try func.store(result_ptr, result, lhs_ty, 0); |
| 6162 | const offset = @as(u32, @intCast(lhs_ty.abiSize(mod))); | 6241 | const offset = @as(u32, @intCast(lhs_ty.abiSize(pt))); |
| 6163 | try func.store(result_ptr, overflow_local, Type.u1, offset); | 6242 | try func.store(result_ptr, overflow_local, Type.u1, offset); |
| 6164 | 6243 | ||
| 6165 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); | 6244 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); |
| ... | @@ -6172,7 +6251,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6172,7 +6251,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6172 | const lhs = try func.resolveInst(extra.lhs); | 6251 | const lhs = try func.resolveInst(extra.lhs); |
| 6173 | const rhs = try func.resolveInst(extra.rhs); | 6252 | const rhs = try func.resolveInst(extra.rhs); |
| 6174 | const lhs_ty = func.typeOf(extra.lhs); | 6253 | const lhs_ty = func.typeOf(extra.lhs); |
| 6175 | const mod = func.bin_file.base.comp.module.?; | 6254 | const pt = func.pt; |
| 6255 | const mod = pt.zcu; | ||
| 6176 | 6256 | ||
| 6177 | if (lhs_ty.zigTypeTag(mod) == .Vector) { | 6257 | if (lhs_ty.zigTypeTag(mod) == .Vector) { |
| 6178 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); | 6258 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| ... | @@ -6332,7 +6412,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6332,7 +6412,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6332 | 6412 | ||
| 6333 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); | 6413 | const result_ptr = try func.allocStack(func.typeOfIndex(inst)); |
| 6334 | try func.store(result_ptr, bin_op_local, lhs_ty, 0); | 6414 | try func.store(result_ptr, bin_op_local, lhs_ty, 0); |
| 6335 | const offset = @as(u32, @intCast(lhs_ty.abiSize(mod))); | 6415 | const offset = @as(u32, @intCast(lhs_ty.abiSize(pt))); |
| 6336 | try func.store(result_ptr, overflow_bit, Type.u1, offset); | 6416 | try func.store(result_ptr, overflow_bit, Type.u1, offset); |
| 6337 | 6417 | ||
| 6338 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); | 6418 | func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs }); |
| ... | @@ -6340,7 +6420,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6340,7 +6420,8 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6340 | 6420 | ||
| 6341 | fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | 6421 | fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6342 | assert(op == .max or op == .min); | 6422 | assert(op == .max or op == .min); |
| 6343 | const mod = func.bin_file.base.comp.module.?; | 6423 | const pt = func.pt; |
| 6424 | const mod = pt.zcu; | ||
| 6344 | const target = mod.getTarget(); | 6425 | const target = mod.getTarget(); |
| 6345 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6426 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6346 | 6427 | ||
| ... | @@ -6349,7 +6430,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -6349,7 +6430,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6349 | return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{}); | 6430 | return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{}); |
| 6350 | } | 6431 | } |
| 6351 | 6432 | ||
| 6352 | if (ty.abiSize(mod) > 16) { | 6433 | if (ty.abiSize(pt) > 16) { |
| 6353 | return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{}); | 6434 | return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{}); |
| 6354 | } | 6435 | } |
| 6355 | 6436 | ||
| ... | @@ -6377,14 +6458,15 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -6377,14 +6458,15 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6377 | } | 6458 | } |
| 6378 | 6459 | ||
| 6379 | // store result in local | 6460 | // store result in local |
| 6380 | const result_ty = if (isByRef(ty, mod)) Type.u32 else ty; | 6461 | const result_ty = if (isByRef(ty, pt)) Type.u32 else ty; |
| 6381 | const result = try func.allocLocal(result_ty); | 6462 | const result = try func.allocLocal(result_ty); |
| 6382 | try func.addLabel(.local_set, result.local.value); | 6463 | try func.addLabel(.local_set, result.local.value); |
| 6383 | func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); | 6464 | func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs }); |
| 6384 | } | 6465 | } |
| 6385 | 6466 | ||
| 6386 | fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6467 | fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6387 | const mod = func.bin_file.base.comp.module.?; | 6468 | const pt = func.pt; |
| 6469 | const mod = pt.zcu; | ||
| 6388 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6470 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6389 | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; | 6471 | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; |
| 6390 | 6472 | ||
| ... | @@ -6418,7 +6500,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6418,7 +6500,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6418 | } | 6500 | } |
| 6419 | 6501 | ||
| 6420 | fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6502 | fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6421 | const mod = func.bin_file.base.comp.module.?; | 6503 | const pt = func.pt; |
| 6504 | const mod = pt.zcu; | ||
| 6422 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6505 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6423 | 6506 | ||
| 6424 | const ty = func.typeOf(ty_op.operand); | 6507 | const ty = func.typeOf(ty_op.operand); |
| ... | @@ -6471,7 +6554,8 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6471,7 +6554,8 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6471 | } | 6554 | } |
| 6472 | 6555 | ||
| 6473 | fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6556 | fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6474 | const mod = func.bin_file.base.comp.module.?; | 6557 | const pt = func.pt; |
| 6558 | const mod = pt.zcu; | ||
| 6475 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6559 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6476 | 6560 | ||
| 6477 | const ty = func.typeOf(ty_op.operand); | 6561 | const ty = func.typeOf(ty_op.operand); |
| ... | @@ -6558,7 +6642,8 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6558,7 +6642,8 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6558 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { | 6642 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { |
| 6559 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); | 6643 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); |
| 6560 | 6644 | ||
| 6561 | const mod = func.bin_file.base.comp.module.?; | 6645 | const pt = func.pt; |
| 6646 | const mod = pt.zcu; | ||
| 6562 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6647 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6563 | const ty = func.typeOf(pl_op.operand); | 6648 | const ty = func.typeOf(pl_op.operand); |
| 6564 | const operand = try func.resolveInst(pl_op.operand); | 6649 | const operand = try func.resolveInst(pl_op.operand); |
| ... | @@ -6591,7 +6676,8 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6591,7 +6676,8 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6591 | } | 6676 | } |
| 6592 | 6677 | ||
| 6593 | fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6678 | fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6594 | const mod = func.bin_file.base.comp.module.?; | 6679 | const pt = func.pt; |
| 6680 | const mod = pt.zcu; | ||
| 6595 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6681 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6596 | const extra = func.air.extraData(Air.TryPtr, ty_pl.payload); | 6682 | const extra = func.air.extraData(Air.TryPtr, ty_pl.payload); |
| 6597 | const err_union_ptr = try func.resolveInst(extra.data.ptr); | 6683 | const err_union_ptr = try func.resolveInst(extra.data.ptr); |
| ... | @@ -6609,13 +6695,14 @@ fn lowerTry( | ... | @@ -6609,13 +6695,14 @@ fn lowerTry( |
| 6609 | err_union_ty: Type, | 6695 | err_union_ty: Type, |
| 6610 | operand_is_ptr: bool, | 6696 | operand_is_ptr: bool, |
| 6611 | ) InnerError!WValue { | 6697 | ) InnerError!WValue { |
| 6612 | const mod = func.bin_file.base.comp.module.?; | 6698 | const pt = func.pt; |
| 6699 | const mod = pt.zcu; | ||
| 6613 | if (operand_is_ptr) { | 6700 | if (operand_is_ptr) { |
| 6614 | return func.fail("TODO: lowerTry for pointers", .{}); | 6701 | return func.fail("TODO: lowerTry for pointers", .{}); |
| 6615 | } | 6702 | } |
| 6616 | 6703 | ||
| 6617 | const pl_ty = err_union_ty.errorUnionPayload(mod); | 6704 | const pl_ty = err_union_ty.errorUnionPayload(mod); |
| 6618 | const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod); | 6705 | const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 6619 | 6706 | ||
| 6620 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | 6707 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| 6621 | // Block we can jump out of when error is not set | 6708 | // Block we can jump out of when error is not set |
| ... | @@ -6624,10 +6711,10 @@ fn lowerTry( | ... | @@ -6624,10 +6711,10 @@ fn lowerTry( |
| 6624 | // check if the error tag is set for the error union. | 6711 | // check if the error tag is set for the error union. |
| 6625 | try func.emitWValue(err_union); | 6712 | try func.emitWValue(err_union); |
| 6626 | if (pl_has_bits) { | 6713 | if (pl_has_bits) { |
| 6627 | const err_offset = @as(u32, @intCast(errUnionErrorOffset(pl_ty, mod))); | 6714 | const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 6628 | try func.addMemArg(.i32_load16_u, .{ | 6715 | try func.addMemArg(.i32_load16_u, .{ |
| 6629 | .offset = err_union.offset() + err_offset, | 6716 | .offset = err_union.offset() + err_offset, |
| 6630 | .alignment = @intCast(Type.anyerror.abiAlignment(mod).toByteUnits().?), | 6717 | .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?), |
| 6631 | }); | 6718 | }); |
| 6632 | } | 6719 | } |
| 6633 | try func.addTag(.i32_eqz); | 6720 | try func.addTag(.i32_eqz); |
| ... | @@ -6649,8 +6736,8 @@ fn lowerTry( | ... | @@ -6649,8 +6736,8 @@ fn lowerTry( |
| 6649 | return WValue{ .none = {} }; | 6736 | return WValue{ .none = {} }; |
| 6650 | } | 6737 | } |
| 6651 | 6738 | ||
| 6652 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(pl_ty, mod))); | 6739 | const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 6653 | if (isByRef(pl_ty, mod)) { | 6740 | if (isByRef(pl_ty, pt)) { |
| 6654 | return buildPointerOffset(func, err_union, pl_offset, .new); | 6741 | return buildPointerOffset(func, err_union, pl_offset, .new); |
| 6655 | } | 6742 | } |
| 6656 | const payload = try func.load(err_union, pl_ty, pl_offset); | 6743 | const payload = try func.load(err_union, pl_ty, pl_offset); |
| ... | @@ -6658,7 +6745,8 @@ fn lowerTry( | ... | @@ -6658,7 +6745,8 @@ fn lowerTry( |
| 6658 | } | 6745 | } |
| 6659 | 6746 | ||
| 6660 | fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6747 | fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6661 | const mod = func.bin_file.base.comp.module.?; | 6748 | const pt = func.pt; |
| 6749 | const mod = pt.zcu; | ||
| 6662 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6750 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6663 | 6751 | ||
| 6664 | const ty = func.typeOfIndex(inst); | 6752 | const ty = func.typeOfIndex(inst); |
| ... | @@ -6744,7 +6832,8 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6744,7 +6832,8 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6744 | fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6832 | fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6745 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6833 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6746 | 6834 | ||
| 6747 | const mod = func.bin_file.base.comp.module.?; | 6835 | const pt = func.pt; |
| 6836 | const mod = pt.zcu; | ||
| 6748 | const ty = func.typeOfIndex(inst); | 6837 | const ty = func.typeOfIndex(inst); |
| 6749 | const lhs = try func.resolveInst(bin_op.lhs); | 6838 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6750 | const rhs = try func.resolveInst(bin_op.rhs); | 6839 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | @@ -6864,7 +6953,8 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6864,7 +6953,8 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6864 | fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6953 | fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6865 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6954 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6866 | 6955 | ||
| 6867 | const mod = func.bin_file.base.comp.module.?; | 6956 | const pt = func.pt; |
| 6957 | const mod = pt.zcu; | ||
| 6868 | const ty = func.typeOfIndex(inst); | 6958 | const ty = func.typeOfIndex(inst); |
| 6869 | const lhs = try func.resolveInst(bin_op.lhs); | 6959 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6870 | const rhs = try func.resolveInst(bin_op.rhs); | 6960 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | @@ -6901,7 +6991,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -6901,7 +6991,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6901 | assert(op == .add or op == .sub); | 6991 | assert(op == .add or op == .sub); |
| 6902 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6992 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6903 | 6993 | ||
| 6904 | const mod = func.bin_file.base.comp.module.?; | 6994 | const pt = func.pt; |
| 6995 | const mod = pt.zcu; | ||
| 6905 | const ty = func.typeOfIndex(inst); | 6996 | const ty = func.typeOfIndex(inst); |
| 6906 | const lhs = try func.resolveInst(bin_op.lhs); | 6997 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6907 | const rhs = try func.resolveInst(bin_op.rhs); | 6998 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | @@ -6949,11 +7040,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { | ... | @@ -6949,11 +7040,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6949 | } | 7040 | } |
| 6950 | 7041 | ||
| 6951 | fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { | 7042 | fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 6952 | const mod = func.bin_file.base.comp.module.?; | 7043 | const pt = func.pt; |
| 7044 | const mod = pt.zcu; | ||
| 6953 | const int_info = ty.intInfo(mod); | 7045 | const int_info = ty.intInfo(mod); |
| 6954 | const wasm_bits = toWasmBits(int_info.bits).?; | 7046 | const wasm_bits = toWasmBits(int_info.bits).?; |
| 6955 | const is_wasm_bits = wasm_bits == int_info.bits; | 7047 | const is_wasm_bits = wasm_bits == int_info.bits; |
| 6956 | const ext_ty = if (!is_wasm_bits) try mod.intType(int_info.signedness, wasm_bits) else ty; | 7048 | const ext_ty = if (!is_wasm_bits) try pt.intType(int_info.signedness, wasm_bits) else ty; |
| 6957 | 7049 | ||
| 6958 | const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1)); | 7050 | const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1)); |
| 6959 | const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1; | 7051 | const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1; |
| ... | @@ -7007,7 +7099,8 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr | ... | @@ -7007,7 +7099,8 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr |
| 7007 | fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7099 | fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7008 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7100 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7009 | 7101 | ||
| 7010 | const mod = func.bin_file.base.comp.module.?; | 7102 | const pt = func.pt; |
| 7103 | const mod = pt.zcu; | ||
| 7011 | const ty = func.typeOfIndex(inst); | 7104 | const ty = func.typeOfIndex(inst); |
| 7012 | const int_info = ty.intInfo(mod); | 7105 | const int_info = ty.intInfo(mod); |
| 7013 | const is_signed = int_info.signedness == .signed; | 7106 | const is_signed = int_info.signedness == .signed; |
| ... | @@ -7061,7 +7154,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7061,7 +7154,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7061 | 64 => WValue{ .imm64 = shift_size }, | 7154 | 64 => WValue{ .imm64 = shift_size }, |
| 7062 | else => unreachable, | 7155 | else => unreachable, |
| 7063 | }; | 7156 | }; |
| 7064 | const ext_ty = try mod.intType(int_info.signedness, wasm_bits); | 7157 | const ext_ty = try pt.intType(int_info.signedness, wasm_bits); |
| 7065 | 7158 | ||
| 7066 | var shl_res = try (try func.binOp(lhs, shift_value, ext_ty, .shl)).toLocal(func, ext_ty); | 7159 | var shl_res = try (try func.binOp(lhs, shift_value, ext_ty, .shl)).toLocal(func, ext_ty); |
| 7067 | defer shl_res.free(func); | 7160 | defer shl_res.free(func); |
| ... | @@ -7128,13 +7221,14 @@ fn callIntrinsic( | ... | @@ -7128,13 +7221,14 @@ fn callIntrinsic( |
| 7128 | }; | 7221 | }; |
| 7129 | 7222 | ||
| 7130 | // Always pass over C-ABI | 7223 | // Always pass over C-ABI |
| 7131 | const mod = func.bin_file.base.comp.module.?; | 7224 | const pt = func.pt; |
| 7132 | var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod); | 7225 | const mod = pt.zcu; |
| 7226 | var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt); | ||
| 7133 | defer func_type.deinit(func.gpa); | 7227 | defer func_type.deinit(func.gpa); |
| 7134 | const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type); | 7228 | const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type); |
| 7135 | try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index); | 7229 | try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index); |
| 7136 | 7230 | ||
| 7137 | const want_sret_param = firstParamSRet(.C, return_type, mod); | 7231 | const want_sret_param = firstParamSRet(.C, return_type, pt); |
| 7138 | // if we want return as first param, we allocate a pointer to stack, | 7232 | // if we want return as first param, we allocate a pointer to stack, |
| 7139 | // and emit it as our first argument | 7233 | // and emit it as our first argument |
| 7140 | const sret = if (want_sret_param) blk: { | 7234 | const sret = if (want_sret_param) blk: { |
| ... | @@ -7146,14 +7240,14 @@ fn callIntrinsic( | ... | @@ -7146,14 +7240,14 @@ fn callIntrinsic( |
| 7146 | // Lower all arguments to the stack before we call our function | 7240 | // Lower all arguments to the stack before we call our function |
| 7147 | for (args, 0..) |arg, arg_i| { | 7241 | for (args, 0..) |arg, arg_i| { |
| 7148 | assert(!(want_sret_param and arg == .stack)); | 7242 | assert(!(want_sret_param and arg == .stack)); |
| 7149 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(mod)); | 7243 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(pt)); |
| 7150 | try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg); | 7244 | try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg); |
| 7151 | } | 7245 | } |
| 7152 | 7246 | ||
| 7153 | // Actually call our intrinsic | 7247 | // Actually call our intrinsic |
| 7154 | try func.addLabel(.call, @intFromEnum(symbol_index)); | 7248 | try func.addLabel(.call, @intFromEnum(symbol_index)); |
| 7155 | 7249 | ||
| 7156 | if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) { | 7250 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7157 | return WValue.none; | 7251 | return WValue.none; |
| 7158 | } else if (return_type.isNoReturn(mod)) { | 7252 | } else if (return_type.isNoReturn(mod)) { |
| 7159 | try func.addTag(.@"unreachable"); | 7253 | try func.addTag(.@"unreachable"); |
| ... | @@ -7181,7 +7275,8 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7181,7 +7275,8 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7181 | } | 7275 | } |
| 7182 | 7276 | ||
| 7183 | fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | 7277 | fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7184 | const mod = func.bin_file.base.comp.module.?; | 7278 | const pt = func.pt; |
| 7279 | const mod = pt.zcu; | ||
| 7185 | const ip = &mod.intern_pool; | 7280 | const ip = &mod.intern_pool; |
| 7186 | const enum_decl_index = enum_ty.getOwnerDecl(mod); | 7281 | const enum_decl_index = enum_ty.getOwnerDecl(mod); |
| 7187 | 7282 | ||
| ... | @@ -7199,7 +7294,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | ... | @@ -7199,7 +7294,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7199 | 7294 | ||
| 7200 | const int_tag_ty = enum_ty.intTagType(mod); | 7295 | const int_tag_ty = enum_ty.intTagType(mod); |
| 7201 | 7296 | ||
| 7202 | if (int_tag_ty.bitSize(mod) > 64) { | 7297 | if (int_tag_ty.bitSize(pt) > 64) { |
| 7203 | return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{}); | 7298 | return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{}); |
| 7204 | } | 7299 | } |
| 7205 | 7300 | ||
| ... | @@ -7225,16 +7320,17 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | ... | @@ -7225,16 +7320,17 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7225 | const tag_name_len = tag_name.length(ip); | 7320 | const tag_name_len = tag_name.length(ip); |
| 7226 | // for each tag name, create an unnamed const, | 7321 | // for each tag name, create an unnamed const, |
| 7227 | // and then get a pointer to its value. | 7322 | // and then get a pointer to its value. |
| 7228 | const name_ty = try mod.arrayType(.{ | 7323 | const name_ty = try pt.arrayType(.{ |
| 7229 | .len = tag_name_len, | 7324 | .len = tag_name_len, |
| 7230 | .child = .u8_type, | 7325 | .child = .u8_type, |
| 7231 | .sentinel = .zero_u8, | 7326 | .sentinel = .zero_u8, |
| 7232 | }); | 7327 | }); |
| 7233 | const name_val = try mod.intern(.{ .aggregate = .{ | 7328 | const name_val = try pt.intern(.{ .aggregate = .{ |
| 7234 | .ty = name_ty.toIntern(), | 7329 | .ty = name_ty.toIntern(), |
| 7235 | .storage = .{ .bytes = tag_name.toString() }, | 7330 | .storage = .{ .bytes = tag_name.toString() }, |
| 7236 | } }); | 7331 | } }); |
| 7237 | const tag_sym_index = try func.bin_file.lowerUnnamedConst( | 7332 | const tag_sym_index = try func.bin_file.lowerUnnamedConst( |
| 7333 | pt, | ||
| 7238 | Value.fromInterned(name_val), | 7334 | Value.fromInterned(name_val), |
| 7239 | enum_decl_index, | 7335 | enum_decl_index, |
| 7240 | ); | 7336 | ); |
| ... | @@ -7247,7 +7343,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | ... | @@ -7247,7 +7343,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7247 | try writer.writeByte(std.wasm.opcode(.local_get)); | 7343 | try writer.writeByte(std.wasm.opcode(.local_get)); |
| 7248 | try leb.writeUleb128(writer, @as(u32, 1)); | 7344 | try leb.writeUleb128(writer, @as(u32, 1)); |
| 7249 | 7345 | ||
| 7250 | const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index)); | 7346 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| 7251 | const tag_value = try func.lowerConstant(tag_val, enum_ty); | 7347 | const tag_value = try func.lowerConstant(tag_val, enum_ty); |
| 7252 | 7348 | ||
| 7253 | switch (tag_value) { | 7349 | switch (tag_value) { |
| ... | @@ -7334,13 +7430,14 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | ... | @@ -7334,13 +7430,14 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7334 | try writer.writeByte(std.wasm.opcode(.end)); | 7430 | try writer.writeByte(std.wasm.opcode(.end)); |
| 7335 | 7431 | ||
| 7336 | const slice_ty = Type.slice_const_u8_sentinel_0; | 7432 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 7337 | const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, mod); | 7433 | const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, pt); |
| 7338 | const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs); | 7434 | const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs); |
| 7339 | return @intFromEnum(sym_index); | 7435 | return @intFromEnum(sym_index); |
| 7340 | } | 7436 | } |
| 7341 | 7437 | ||
| 7342 | fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7438 | fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7343 | const mod = func.bin_file.base.comp.module.?; | 7439 | const pt = func.pt; |
| 7440 | const mod = pt.zcu; | ||
| 7344 | const ip = &mod.intern_pool; | 7441 | const ip = &mod.intern_pool; |
| 7345 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7442 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7346 | 7443 | ||
| ... | @@ -7426,7 +7523,8 @@ inline fn useAtomicFeature(func: *const CodeGen) bool { | ... | @@ -7426,7 +7523,8 @@ inline fn useAtomicFeature(func: *const CodeGen) bool { |
| 7426 | } | 7523 | } |
| 7427 | 7524 | ||
| 7428 | fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7525 | fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7429 | const mod = func.bin_file.base.comp.module.?; | 7526 | const pt = func.pt; |
| 7527 | const mod = pt.zcu; | ||
| 7430 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 7528 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7431 | const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 7529 | const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7432 | 7530 | ||
| ... | @@ -7445,7 +7543,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7445,7 +7543,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7445 | try func.emitWValue(ptr_operand); | 7543 | try func.emitWValue(ptr_operand); |
| 7446 | try func.lowerToStack(expected_val); | 7544 | try func.lowerToStack(expected_val); |
| 7447 | try func.lowerToStack(new_val); | 7545 | try func.lowerToStack(new_val); |
| 7448 | try func.addAtomicMemArg(switch (ty.abiSize(mod)) { | 7546 | try func.addAtomicMemArg(switch (ty.abiSize(pt)) { |
| 7449 | 1 => .i32_atomic_rmw8_cmpxchg_u, | 7547 | 1 => .i32_atomic_rmw8_cmpxchg_u, |
| 7450 | 2 => .i32_atomic_rmw16_cmpxchg_u, | 7548 | 2 => .i32_atomic_rmw16_cmpxchg_u, |
| 7451 | 4 => .i32_atomic_rmw_cmpxchg, | 7549 | 4 => .i32_atomic_rmw_cmpxchg, |
| ... | @@ -7453,14 +7551,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7453,14 +7551,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7453 | else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}), | 7551 | else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}), |
| 7454 | }, .{ | 7552 | }, .{ |
| 7455 | .offset = ptr_operand.offset(), | 7553 | .offset = ptr_operand.offset(), |
| 7456 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 7554 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 7457 | }); | 7555 | }); |
| 7458 | try func.addLabel(.local_tee, val_local.local.value); | 7556 | try func.addLabel(.local_tee, val_local.local.value); |
| 7459 | _ = try func.cmp(.stack, expected_val, ty, .eq); | 7557 | _ = try func.cmp(.stack, expected_val, ty, .eq); |
| 7460 | try func.addLabel(.local_set, cmp_result.local.value); | 7558 | try func.addLabel(.local_set, cmp_result.local.value); |
| 7461 | break :val val_local; | 7559 | break :val val_local; |
| 7462 | } else val: { | 7560 | } else val: { |
| 7463 | if (ty.abiSize(mod) > 8) { | 7561 | if (ty.abiSize(pt) > 8) { |
| 7464 | return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{}); | 7562 | return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{}); |
| 7465 | } | 7563 | } |
| 7466 | const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty); | 7564 | const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty); |
| ... | @@ -7476,7 +7574,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7476,7 +7574,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7476 | break :val ptr_val; | 7574 | break :val ptr_val; |
| 7477 | }; | 7575 | }; |
| 7478 | 7576 | ||
| 7479 | const result_ptr = if (isByRef(result_ty, mod)) val: { | 7577 | const result_ptr = if (isByRef(result_ty, pt)) val: { |
| 7480 | try func.emitWValue(cmp_result); | 7578 | try func.emitWValue(cmp_result); |
| 7481 | try func.addImm32(~@as(u32, 0)); | 7579 | try func.addImm32(~@as(u32, 0)); |
| 7482 | try func.addTag(.i32_xor); | 7580 | try func.addTag(.i32_xor); |
| ... | @@ -7484,7 +7582,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7484,7 +7582,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7484 | try func.addTag(.i32_and); | 7582 | try func.addTag(.i32_and); |
| 7485 | const and_result = try WValue.toLocal(.stack, func, Type.bool); | 7583 | const and_result = try WValue.toLocal(.stack, func, Type.bool); |
| 7486 | const result_ptr = try func.allocStack(result_ty); | 7584 | const result_ptr = try func.allocStack(result_ty); |
| 7487 | try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(mod)))); | 7585 | try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(pt)))); |
| 7488 | try func.store(result_ptr, ptr_val, ty, 0); | 7586 | try func.store(result_ptr, ptr_val, ty, 0); |
| 7489 | break :val result_ptr; | 7587 | break :val result_ptr; |
| 7490 | } else val: { | 7588 | } else val: { |
| ... | @@ -7499,13 +7597,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7499,13 +7597,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7499 | } | 7597 | } |
| 7500 | 7598 | ||
| 7501 | fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7599 | fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7502 | const mod = func.bin_file.base.comp.module.?; | 7600 | const pt = func.pt; |
| 7503 | const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; | 7601 | const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 7504 | const ptr = try func.resolveInst(atomic_load.ptr); | 7602 | const ptr = try func.resolveInst(atomic_load.ptr); |
| 7505 | const ty = func.typeOfIndex(inst); | 7603 | const ty = func.typeOfIndex(inst); |
| 7506 | 7604 | ||
| 7507 | if (func.useAtomicFeature()) { | 7605 | if (func.useAtomicFeature()) { |
| 7508 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) { | 7606 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { |
| 7509 | 1 => .i32_atomic_load8_u, | 7607 | 1 => .i32_atomic_load8_u, |
| 7510 | 2 => .i32_atomic_load16_u, | 7608 | 2 => .i32_atomic_load16_u, |
| 7511 | 4 => .i32_atomic_load, | 7609 | 4 => .i32_atomic_load, |
| ... | @@ -7515,7 +7613,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7515,7 +7613,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7515 | try func.emitWValue(ptr); | 7613 | try func.emitWValue(ptr); |
| 7516 | try func.addAtomicMemArg(tag, .{ | 7614 | try func.addAtomicMemArg(tag, .{ |
| 7517 | .offset = ptr.offset(), | 7615 | .offset = ptr.offset(), |
| 7518 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 7616 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 7519 | }); | 7617 | }); |
| 7520 | } else { | 7618 | } else { |
| 7521 | _ = try func.load(ptr, ty, 0); | 7619 | _ = try func.load(ptr, ty, 0); |
| ... | @@ -7526,7 +7624,8 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7526,7 +7624,8 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7526 | } | 7624 | } |
| 7527 | 7625 | ||
| 7528 | fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7626 | fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7529 | const mod = func.bin_file.base.comp.module.?; | 7627 | const pt = func.pt; |
| 7628 | const mod = pt.zcu; | ||
| 7530 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 7629 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 7531 | const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 7630 | const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 7532 | 7631 | ||
| ... | @@ -7550,7 +7649,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7550,7 +7649,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7550 | try func.emitWValue(ptr); | 7649 | try func.emitWValue(ptr); |
| 7551 | try func.emitWValue(value); | 7650 | try func.emitWValue(value); |
| 7552 | if (op == .Nand) { | 7651 | if (op == .Nand) { |
| 7553 | const wasm_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?; | 7652 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; |
| 7554 | 7653 | ||
| 7555 | const and_res = try func.binOp(value, operand, ty, .@"and"); | 7654 | const and_res = try func.binOp(value, operand, ty, .@"and"); |
| 7556 | if (wasm_bits == 32) | 7655 | if (wasm_bits == 32) |
| ... | @@ -7567,7 +7666,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7567,7 +7666,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7567 | try func.addTag(.select); | 7666 | try func.addTag(.select); |
| 7568 | } | 7667 | } |
| 7569 | try func.addAtomicMemArg( | 7668 | try func.addAtomicMemArg( |
| 7570 | switch (ty.abiSize(mod)) { | 7669 | switch (ty.abiSize(pt)) { |
| 7571 | 1 => .i32_atomic_rmw8_cmpxchg_u, | 7670 | 1 => .i32_atomic_rmw8_cmpxchg_u, |
| 7572 | 2 => .i32_atomic_rmw16_cmpxchg_u, | 7671 | 2 => .i32_atomic_rmw16_cmpxchg_u, |
| 7573 | 4 => .i32_atomic_rmw_cmpxchg, | 7672 | 4 => .i32_atomic_rmw_cmpxchg, |
| ... | @@ -7576,7 +7675,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7576,7 +7675,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7576 | }, | 7675 | }, |
| 7577 | .{ | 7676 | .{ |
| 7578 | .offset = ptr.offset(), | 7677 | .offset = ptr.offset(), |
| 7579 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 7678 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 7580 | }, | 7679 | }, |
| 7581 | ); | 7680 | ); |
| 7582 | const select_res = try func.allocLocal(ty); | 7681 | const select_res = try func.allocLocal(ty); |
| ... | @@ -7595,7 +7694,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7595,7 +7694,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7595 | else => { | 7694 | else => { |
| 7596 | try func.emitWValue(ptr); | 7695 | try func.emitWValue(ptr); |
| 7597 | try func.emitWValue(operand); | 7696 | try func.emitWValue(operand); |
| 7598 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) { | 7697 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { |
| 7599 | 1 => switch (op) { | 7698 | 1 => switch (op) { |
| 7600 | .Xchg => .i32_atomic_rmw8_xchg_u, | 7699 | .Xchg => .i32_atomic_rmw8_xchg_u, |
| 7601 | .Add => .i32_atomic_rmw8_add_u, | 7700 | .Add => .i32_atomic_rmw8_add_u, |
| ... | @@ -7636,7 +7735,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7636,7 +7735,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7636 | }; | 7735 | }; |
| 7637 | try func.addAtomicMemArg(tag, .{ | 7736 | try func.addAtomicMemArg(tag, .{ |
| 7638 | .offset = ptr.offset(), | 7737 | .offset = ptr.offset(), |
| 7639 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 7738 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 7640 | }); | 7739 | }); |
| 7641 | const result = try WValue.toLocal(.stack, func, ty); | 7740 | const result = try WValue.toLocal(.stack, func, ty); |
| 7642 | return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand }); | 7741 | return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand }); |
| ... | @@ -7681,7 +7780,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7681,7 +7780,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7681 | try func.store(.stack, .stack, ty, ptr.offset()); | 7780 | try func.store(.stack, .stack, ty, ptr.offset()); |
| 7682 | }, | 7781 | }, |
| 7683 | .Nand => { | 7782 | .Nand => { |
| 7684 | const wasm_bits = toWasmBits(@as(u16, @intCast(ty.bitSize(mod)))).?; | 7783 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; |
| 7685 | 7784 | ||
| 7686 | try func.emitWValue(ptr); | 7785 | try func.emitWValue(ptr); |
| 7687 | const and_res = try func.binOp(result, operand, ty, .@"and"); | 7786 | const and_res = try func.binOp(result, operand, ty, .@"and"); |
| ... | @@ -7701,7 +7800,8 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7701,7 +7800,8 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7701 | } | 7800 | } |
| 7702 | 7801 | ||
| 7703 | fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7802 | fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7704 | const zcu = func.bin_file.base.comp.module.?; | 7803 | const pt = func.pt; |
| 7804 | const zcu = pt.zcu; | ||
| 7705 | // Only when the atomic feature is enabled, and we're not building | 7805 | // Only when the atomic feature is enabled, and we're not building |
| 7706 | // for a single-threaded build, can we emit the `fence` instruction. | 7806 | // for a single-threaded build, can we emit the `fence` instruction. |
| 7707 | // In all other cases, we emit no instructions for a fence. | 7807 | // In all other cases, we emit no instructions for a fence. |
| ... | @@ -7715,7 +7815,8 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7715,7 +7815,8 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7715 | } | 7815 | } |
| 7716 | 7816 | ||
| 7717 | fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 7817 | fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7718 | const mod = func.bin_file.base.comp.module.?; | 7818 | const pt = func.pt; |
| 7819 | const mod = pt.zcu; | ||
| 7719 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7820 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7720 | 7821 | ||
| 7721 | const ptr = try func.resolveInst(bin_op.lhs); | 7822 | const ptr = try func.resolveInst(bin_op.lhs); |
| ... | @@ -7724,7 +7825,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7724,7 +7825,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7724 | const ty = ptr_ty.childType(mod); | 7825 | const ty = ptr_ty.childType(mod); |
| 7725 | 7826 | ||
| 7726 | if (func.useAtomicFeature()) { | 7827 | if (func.useAtomicFeature()) { |
| 7727 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) { | 7828 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { |
| 7728 | 1 => .i32_atomic_store8, | 7829 | 1 => .i32_atomic_store8, |
| 7729 | 2 => .i32_atomic_store16, | 7830 | 2 => .i32_atomic_store16, |
| 7730 | 4 => .i32_atomic_store, | 7831 | 4 => .i32_atomic_store, |
| ... | @@ -7735,7 +7836,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7735,7 +7836,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7735 | try func.lowerToStack(operand); | 7836 | try func.lowerToStack(operand); |
| 7736 | try func.addAtomicMemArg(tag, .{ | 7837 | try func.addAtomicMemArg(tag, .{ |
| 7737 | .offset = ptr.offset(), | 7838 | .offset = ptr.offset(), |
| 7738 | .alignment = @intCast(ty.abiAlignment(mod).toByteUnits().?), | 7839 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), |
| 7739 | }); | 7840 | }); |
| 7740 | } else { | 7841 | } else { |
| 7741 | try func.store(ptr, operand, ty, 0); | 7842 | try func.store(ptr, operand, ty, 0); |
| ... | @@ -7754,11 +7855,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7754,11 +7855,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7754 | } | 7855 | } |
| 7755 | 7856 | ||
| 7756 | fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type { | 7857 | fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type { |
| 7757 | const mod = func.bin_file.base.comp.module.?; | 7858 | const pt = func.pt; |
| 7859 | const mod = pt.zcu; | ||
| 7758 | return func.air.typeOf(inst, &mod.intern_pool); | 7860 | return func.air.typeOf(inst, &mod.intern_pool); |
| 7759 | } | 7861 | } |
| 7760 | 7862 | ||
| 7761 | fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type { | 7863 | fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type { |
| 7762 | const mod = func.bin_file.base.comp.module.?; | 7864 | const pt = func.pt; |
| 7865 | const mod = pt.zcu; | ||
| 7763 | return func.air.typeOfIndex(inst, &mod.intern_pool); | 7866 | return func.air.typeOfIndex(inst, &mod.intern_pool); |
| 7764 | } | 7867 | } |
src/arch/wasm/abi.zig+21-19| ... | @@ -22,15 +22,16 @@ const direct: [2]Class = .{ .direct, .none }; | ... | @@ -22,15 +22,16 @@ const direct: [2]Class = .{ .direct, .none }; |
| 22 | /// Classifies a given Zig type to determine how they must be passed | 22 | /// Classifies a given Zig type to determine how they must be passed |
| 23 | /// or returned as value within a wasm function. | 23 | /// or returned as value within a wasm function. |
| 24 | /// When all elements result in `.none`, no value must be passed in or returned. | 24 | /// When all elements result in `.none`, no value must be passed in or returned. |
| 25 | pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { | 25 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class { |
| 26 | const mod = pt.zcu; | ||
| 26 | const ip = &mod.intern_pool; | 27 | const ip = &mod.intern_pool; |
| 27 | const target = mod.getTarget(); | 28 | const target = mod.getTarget(); |
| 28 | if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none; | 29 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return none; |
| 29 | switch (ty.zigTypeTag(mod)) { | 30 | switch (ty.zigTypeTag(mod)) { |
| 30 | .Struct => { | 31 | .Struct => { |
| 31 | const struct_type = mod.typeToStruct(ty).?; | 32 | const struct_type = pt.zcu.typeToStruct(ty).?; |
| 32 | if (struct_type.layout == .@"packed") { | 33 | if (struct_type.layout == .@"packed") { |
| 33 | if (ty.bitSize(mod) <= 64) return direct; | 34 | if (ty.bitSize(pt) <= 64) return direct; |
| 34 | return .{ .direct, .direct }; | 35 | return .{ .direct, .direct }; |
| 35 | } | 36 | } |
| 36 | if (struct_type.field_types.len > 1) { | 37 | if (struct_type.field_types.len > 1) { |
| ... | @@ -40,13 +41,13 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { | ... | @@ -40,13 +41,13 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { |
| 40 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]); | 41 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]); |
| 41 | const explicit_align = struct_type.fieldAlign(ip, 0); | 42 | const explicit_align = struct_type.fieldAlign(ip, 0); |
| 42 | if (explicit_align != .none) { | 43 | if (explicit_align != .none) { |
| 43 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(mod))) | 44 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(pt))) |
| 44 | return memory; | 45 | return memory; |
| 45 | } | 46 | } |
| 46 | return classifyType(field_ty, mod); | 47 | return classifyType(field_ty, pt); |
| 47 | }, | 48 | }, |
| 48 | .Int, .Enum, .ErrorSet => { | 49 | .Int, .Enum, .ErrorSet => { |
| 49 | const int_bits = ty.intInfo(mod).bits; | 50 | const int_bits = ty.intInfo(pt.zcu).bits; |
| 50 | if (int_bits <= 64) return direct; | 51 | if (int_bits <= 64) return direct; |
| 51 | if (int_bits <= 128) return .{ .direct, .direct }; | 52 | if (int_bits <= 128) return .{ .direct, .direct }; |
| 52 | return memory; | 53 | return memory; |
| ... | @@ -61,24 +62,24 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { | ... | @@ -61,24 +62,24 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { |
| 61 | .Vector => return direct, | 62 | .Vector => return direct, |
| 62 | .Array => return memory, | 63 | .Array => return memory, |
| 63 | .Optional => { | 64 | .Optional => { |
| 64 | assert(ty.isPtrLikeOptional(mod)); | 65 | assert(ty.isPtrLikeOptional(pt.zcu)); |
| 65 | return direct; | 66 | return direct; |
| 66 | }, | 67 | }, |
| 67 | .Pointer => { | 68 | .Pointer => { |
| 68 | assert(!ty.isSlice(mod)); | 69 | assert(!ty.isSlice(pt.zcu)); |
| 69 | return direct; | 70 | return direct; |
| 70 | }, | 71 | }, |
| 71 | .Union => { | 72 | .Union => { |
| 72 | const union_obj = mod.typeToUnion(ty).?; | 73 | const union_obj = pt.zcu.typeToUnion(ty).?; |
| 73 | if (union_obj.getLayout(ip) == .@"packed") { | 74 | if (union_obj.getLayout(ip) == .@"packed") { |
| 74 | if (ty.bitSize(mod) <= 64) return direct; | 75 | if (ty.bitSize(pt) <= 64) return direct; |
| 75 | return .{ .direct, .direct }; | 76 | return .{ .direct, .direct }; |
| 76 | } | 77 | } |
| 77 | const layout = ty.unionGetLayout(mod); | 78 | const layout = ty.unionGetLayout(pt); |
| 78 | assert(layout.tag_size == 0); | 79 | assert(layout.tag_size == 0); |
| 79 | if (union_obj.field_types.len > 1) return memory; | 80 | if (union_obj.field_types.len > 1) return memory; |
| 80 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 81 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 81 | return classifyType(first_field_ty, mod); | 82 | return classifyType(first_field_ty, pt); |
| 82 | }, | 83 | }, |
| 83 | .ErrorUnion, | 84 | .ErrorUnion, |
| 84 | .Frame, | 85 | .Frame, |
| ... | @@ -100,28 +101,29 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { | ... | @@ -100,28 +101,29 @@ pub fn classifyType(ty: Type, mod: *Zcu) [2]Class { |
| 100 | /// Returns the scalar type a given type can represent. | 101 | /// Returns the scalar type a given type can represent. |
| 101 | /// Asserts given type can be represented as scalar, such as | 102 | /// Asserts given type can be represented as scalar, such as |
| 102 | /// a struct with a single scalar field. | 103 | /// a struct with a single scalar field. |
| 103 | pub fn scalarType(ty: Type, mod: *Zcu) Type { | 104 | pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type { |
| 105 | const mod = pt.zcu; | ||
| 104 | const ip = &mod.intern_pool; | 106 | const ip = &mod.intern_pool; |
| 105 | switch (ty.zigTypeTag(mod)) { | 107 | switch (ty.zigTypeTag(mod)) { |
| 106 | .Struct => { | 108 | .Struct => { |
| 107 | if (mod.typeToPackedStruct(ty)) |packed_struct| { | 109 | if (mod.typeToPackedStruct(ty)) |packed_struct| { |
| 108 | return scalarType(Type.fromInterned(packed_struct.backingIntType(ip).*), mod); | 110 | return scalarType(Type.fromInterned(packed_struct.backingIntType(ip).*), pt); |
| 109 | } else { | 111 | } else { |
| 110 | assert(ty.structFieldCount(mod) == 1); | 112 | assert(ty.structFieldCount(mod) == 1); |
| 111 | return scalarType(ty.structFieldType(0, mod), mod); | 113 | return scalarType(ty.structFieldType(0, mod), pt); |
| 112 | } | 114 | } |
| 113 | }, | 115 | }, |
| 114 | .Union => { | 116 | .Union => { |
| 115 | const union_obj = mod.typeToUnion(ty).?; | 117 | const union_obj = mod.typeToUnion(ty).?; |
| 116 | if (union_obj.getLayout(ip) != .@"packed") { | 118 | if (union_obj.getLayout(ip) != .@"packed") { |
| 117 | const layout = mod.getUnionLayout(union_obj); | 119 | const layout = pt.getUnionLayout(union_obj); |
| 118 | if (layout.payload_size == 0 and layout.tag_size != 0) { | 120 | if (layout.payload_size == 0 and layout.tag_size != 0) { |
| 119 | return scalarType(ty.unionTagTypeSafety(mod).?, mod); | 121 | return scalarType(ty.unionTagTypeSafety(mod).?, pt); |
| 120 | } | 122 | } |
| 121 | assert(union_obj.field_types.len == 1); | 123 | assert(union_obj.field_types.len == 1); |
| 122 | } | 124 | } |
| 123 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 125 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 124 | return scalarType(first_field_ty, mod); | 126 | return scalarType(first_field_ty, pt); |
| 125 | }, | 127 | }, |
| 126 | else => return ty, | 128 | else => return ty, |
| 127 | } | 129 | } |
src/arch/x86_64/CodeGen.zig+655-551| ... | @@ -19,7 +19,7 @@ const CodeGenError = codegen.CodeGenError; | ... | @@ -19,7 +19,7 @@ const CodeGenError = codegen.CodeGenError; |
| 19 | const Compilation = @import("../../Compilation.zig"); | 19 | const Compilation = @import("../../Compilation.zig"); |
| 20 | const DebugInfoOutput = codegen.DebugInfoOutput; | 20 | const DebugInfoOutput = codegen.DebugInfoOutput; |
| 21 | const DW = std.dwarf; | 21 | const DW = std.dwarf; |
| 22 | const ErrorMsg = Module.ErrorMsg; | 22 | const ErrorMsg = Zcu.ErrorMsg; |
| 23 | const Result = codegen.Result; | 23 | const Result = codegen.Result; |
| 24 | const Emit = @import("Emit.zig"); | 24 | const Emit = @import("Emit.zig"); |
| 25 | const Liveness = @import("../../Liveness.zig"); | 25 | const Liveness = @import("../../Liveness.zig"); |
| ... | @@ -27,8 +27,6 @@ const Lower = @import("Lower.zig"); | ... | @@ -27,8 +27,6 @@ const Lower = @import("Lower.zig"); |
| 27 | const Mir = @import("Mir.zig"); | 27 | const Mir = @import("Mir.zig"); |
| 28 | const Package = @import("../../Package.zig"); | 28 | const Package = @import("../../Package.zig"); |
| 29 | const Zcu = @import("../../Zcu.zig"); | 29 | const Zcu = @import("../../Zcu.zig"); |
| 30 | /// Deprecated. | ||
| 31 | const Module = Zcu; | ||
| 32 | const InternPool = @import("../../InternPool.zig"); | 30 | const InternPool = @import("../../InternPool.zig"); |
| 33 | const Alignment = InternPool.Alignment; | 31 | const Alignment = InternPool.Alignment; |
| 34 | const Target = std.Target; | 32 | const Target = std.Target; |
| ... | @@ -52,6 +50,7 @@ const FrameIndex = bits.FrameIndex; | ... | @@ -52,6 +50,7 @@ const FrameIndex = bits.FrameIndex; |
| 52 | const InnerError = CodeGenError || error{OutOfRegisters}; | 50 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 53 | 51 | ||
| 54 | gpa: Allocator, | 52 | gpa: Allocator, |
| 53 | pt: Zcu.PerThread, | ||
| 55 | air: Air, | 54 | air: Air, |
| 56 | liveness: Liveness, | 55 | liveness: Liveness, |
| 57 | bin_file: *link.File, | 56 | bin_file: *link.File, |
| ... | @@ -74,7 +73,7 @@ va_info: union { | ... | @@ -74,7 +73,7 @@ va_info: union { |
| 74 | ret_mcv: InstTracking, | 73 | ret_mcv: InstTracking, |
| 75 | fn_type: Type, | 74 | fn_type: Type, |
| 76 | arg_index: u32, | 75 | arg_index: u32, |
| 77 | src_loc: Module.LazySrcLoc, | 76 | src_loc: Zcu.LazySrcLoc, |
| 78 | 77 | ||
| 79 | eflags_inst: ?Air.Inst.Index = null, | 78 | eflags_inst: ?Air.Inst.Index = null, |
| 80 | 79 | ||
| ... | @@ -120,18 +119,18 @@ const Owner = union(enum) { | ... | @@ -120,18 +119,18 @@ const Owner = union(enum) { |
| 120 | func_index: InternPool.Index, | 119 | func_index: InternPool.Index, |
| 121 | lazy_sym: link.File.LazySymbol, | 120 | lazy_sym: link.File.LazySymbol, |
| 122 | 121 | ||
| 123 | fn getDecl(owner: Owner, mod: *Module) InternPool.DeclIndex { | 122 | fn getDecl(owner: Owner, zcu: *Zcu) InternPool.DeclIndex { |
| 124 | return switch (owner) { | 123 | return switch (owner) { |
| 125 | .func_index => |func_index| mod.funcOwnerDeclIndex(func_index), | 124 | .func_index => |func_index| zcu.funcOwnerDeclIndex(func_index), |
| 126 | .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(mod), | 125 | .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(zcu), |
| 127 | }; | 126 | }; |
| 128 | } | 127 | } |
| 129 | 128 | ||
| 130 | fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 { | 129 | fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 { |
| 130 | const pt = ctx.pt; | ||
| 131 | switch (owner) { | 131 | switch (owner) { |
| 132 | .func_index => |func_index| { | 132 | .func_index => |func_index| { |
| 133 | const mod = ctx.bin_file.comp.module.?; | 133 | const decl_index = ctx.pt.zcu.funcOwnerDeclIndex(func_index); |
| 134 | const decl_index = mod.funcOwnerDeclIndex(func_index); | ||
| 135 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { | 134 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { |
| 136 | return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); | 135 | return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 137 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | 136 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { |
| ... | @@ -145,17 +144,17 @@ const Owner = union(enum) { | ... | @@ -145,17 +144,17 @@ const Owner = union(enum) { |
| 145 | }, | 144 | }, |
| 146 | .lazy_sym => |lazy_sym| { | 145 | .lazy_sym => |lazy_sym| { |
| 147 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { | 146 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { |
| 148 | return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err| | 147 | return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err| |
| 149 | ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); | 148 | ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 150 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | 149 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { |
| 151 | return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err| | 150 | return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err| |
| 152 | ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); | 151 | ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 153 | } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { | 152 | } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { |
| 154 | const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 153 | const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| |
| 155 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); | 154 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 156 | return coff_file.getAtom(atom).getSymbolIndex().?; | 155 | return coff_file.getAtom(atom).getSymbolIndex().?; |
| 157 | } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| { | 156 | } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| { |
| 158 | return p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 157 | return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| |
| 159 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); | 158 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 160 | } else unreachable; | 159 | } else unreachable; |
| 161 | }, | 160 | }, |
| ... | @@ -753,14 +752,14 @@ const FrameAlloc = struct { | ... | @@ -753,14 +752,14 @@ const FrameAlloc = struct { |
| 753 | .ref_count = 0, | 752 | .ref_count = 0, |
| 754 | }; | 753 | }; |
| 755 | } | 754 | } |
| 756 | fn initType(ty: Type, mod: *Module) FrameAlloc { | 755 | fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc { |
| 757 | return init(.{ | 756 | return init(.{ |
| 758 | .size = ty.abiSize(mod), | 757 | .size = ty.abiSize(pt), |
| 759 | .alignment = ty.abiAlignment(mod), | 758 | .alignment = ty.abiAlignment(pt), |
| 760 | }); | 759 | }); |
| 761 | } | 760 | } |
| 762 | fn initSpill(ty: Type, mod: *Module) FrameAlloc { | 761 | fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc { |
| 763 | const abi_size = ty.abiSize(mod); | 762 | const abi_size = ty.abiSize(pt); |
| 764 | const spill_size = if (abi_size < 8) | 763 | const spill_size = if (abi_size < 8) |
| 765 | math.ceilPowerOfTwoAssert(u64, abi_size) | 764 | math.ceilPowerOfTwoAssert(u64, abi_size) |
| 766 | else | 765 | else |
| ... | @@ -768,7 +767,7 @@ const FrameAlloc = struct { | ... | @@ -768,7 +767,7 @@ const FrameAlloc = struct { |
| 768 | return init(.{ | 767 | return init(.{ |
| 769 | .size = spill_size, | 768 | .size = spill_size, |
| 770 | .pad = @intCast(spill_size - abi_size), | 769 | .pad = @intCast(spill_size - abi_size), |
| 771 | .alignment = ty.abiAlignment(mod).maxStrict( | 770 | .alignment = ty.abiAlignment(pt).maxStrict( |
| 772 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), | 771 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), |
| 773 | ), | 772 | ), |
| 774 | }); | 773 | }); |
| ... | @@ -777,7 +776,7 @@ const FrameAlloc = struct { | ... | @@ -777,7 +776,7 @@ const FrameAlloc = struct { |
| 777 | 776 | ||
| 778 | const StackAllocation = struct { | 777 | const StackAllocation = struct { |
| 779 | inst: ?Air.Inst.Index, | 778 | inst: ?Air.Inst.Index, |
| 780 | /// TODO do we need size? should be determined by inst.ty.abiSize(mod) | 779 | /// TODO do we need size? should be determined by inst.ty.abiSize(pt) |
| 781 | size: u32, | 780 | size: u32, |
| 782 | }; | 781 | }; |
| 783 | 782 | ||
| ... | @@ -795,16 +794,17 @@ const Self = @This(); | ... | @@ -795,16 +794,17 @@ const Self = @This(); |
| 795 | 794 | ||
| 796 | pub fn generate( | 795 | pub fn generate( |
| 797 | bin_file: *link.File, | 796 | bin_file: *link.File, |
| 798 | src_loc: Module.LazySrcLoc, | 797 | pt: Zcu.PerThread, |
| 798 | src_loc: Zcu.LazySrcLoc, | ||
| 799 | func_index: InternPool.Index, | 799 | func_index: InternPool.Index, |
| 800 | air: Air, | 800 | air: Air, |
| 801 | liveness: Liveness, | 801 | liveness: Liveness, |
| 802 | code: *std.ArrayList(u8), | 802 | code: *std.ArrayList(u8), |
| 803 | debug_output: DebugInfoOutput, | 803 | debug_output: DebugInfoOutput, |
| 804 | ) CodeGenError!Result { | 804 | ) CodeGenError!Result { |
| 805 | const comp = bin_file.comp; | 805 | const zcu = pt.zcu; |
| 806 | const gpa = comp.gpa; | 806 | const gpa = zcu.gpa; |
| 807 | const zcu = comp.module.?; | 807 | const comp = zcu.comp; |
| 808 | const func = zcu.funcInfo(func_index); | 808 | const func = zcu.funcInfo(func_index); |
| 809 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 809 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 810 | assert(fn_owner_decl.has_tv); | 810 | assert(fn_owner_decl.has_tv); |
| ... | @@ -812,8 +812,9 @@ pub fn generate( | ... | @@ -812,8 +812,9 @@ pub fn generate( |
| 812 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 812 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 813 | const mod = namespace.fileScope(zcu).mod; | 813 | const mod = namespace.fileScope(zcu).mod; |
| 814 | 814 | ||
| 815 | var function = Self{ | 815 | var function: Self = .{ |
| 816 | .gpa = gpa, | 816 | .gpa = gpa, |
| 817 | .pt = pt, | ||
| 817 | .air = air, | 818 | .air = air, |
| 818 | .liveness = liveness, | 819 | .liveness = liveness, |
| 819 | .target = &mod.resolved_target.result, | 820 | .target = &mod.resolved_target.result, |
| ... | @@ -882,11 +883,11 @@ pub fn generate( | ... | @@ -882,11 +883,11 @@ pub fn generate( |
| 882 | function.args = call_info.args; | 883 | function.args = call_info.args; |
| 883 | function.ret_mcv = call_info.return_value; | 884 | function.ret_mcv = call_info.return_value; |
| 884 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ | 885 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ |
| 885 | .size = Type.usize.abiSize(zcu), | 886 | .size = Type.usize.abiSize(pt), |
| 886 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), | 887 | .alignment = Type.usize.abiAlignment(pt).min(call_info.stack_align), |
| 887 | })); | 888 | })); |
| 888 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ | 889 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 889 | .size = Type.usize.abiSize(zcu), | 890 | .size = Type.usize.abiSize(pt), |
| 890 | .alignment = Alignment.min( | 891 | .alignment = Alignment.min( |
| 891 | call_info.stack_align, | 892 | call_info.stack_align, |
| 892 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), | 893 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), |
| ... | @@ -971,7 +972,8 @@ pub fn generate( | ... | @@ -971,7 +972,8 @@ pub fn generate( |
| 971 | 972 | ||
| 972 | pub fn generateLazy( | 973 | pub fn generateLazy( |
| 973 | bin_file: *link.File, | 974 | bin_file: *link.File, |
| 974 | src_loc: Module.LazySrcLoc, | 975 | pt: Zcu.PerThread, |
| 976 | src_loc: Zcu.LazySrcLoc, | ||
| 975 | lazy_sym: link.File.LazySymbol, | 977 | lazy_sym: link.File.LazySymbol, |
| 976 | code: *std.ArrayList(u8), | 978 | code: *std.ArrayList(u8), |
| 977 | debug_output: DebugInfoOutput, | 979 | debug_output: DebugInfoOutput, |
| ... | @@ -980,8 +982,9 @@ pub fn generateLazy( | ... | @@ -980,8 +982,9 @@ pub fn generateLazy( |
| 980 | const gpa = comp.gpa; | 982 | const gpa = comp.gpa; |
| 981 | // This function is for generating global code, so we use the root module. | 983 | // This function is for generating global code, so we use the root module. |
| 982 | const mod = comp.root_mod; | 984 | const mod = comp.root_mod; |
| 983 | var function = Self{ | 985 | var function: Self = .{ |
| 984 | .gpa = gpa, | 986 | .gpa = gpa, |
| 987 | .pt = pt, | ||
| 985 | .air = undefined, | 988 | .air = undefined, |
| 986 | .liveness = undefined, | 989 | .liveness = undefined, |
| 987 | .target = &mod.resolved_target.result, | 990 | .target = &mod.resolved_target.result, |
| ... | @@ -1065,7 +1068,7 @@ pub fn generateLazy( | ... | @@ -1065,7 +1068,7 @@ pub fn generateLazy( |
| 1065 | } | 1068 | } |
| 1066 | 1069 | ||
| 1067 | const FormatDeclData = struct { | 1070 | const FormatDeclData = struct { |
| 1068 | mod: *Module, | 1071 | zcu: *Zcu, |
| 1069 | decl_index: InternPool.DeclIndex, | 1072 | decl_index: InternPool.DeclIndex, |
| 1070 | }; | 1073 | }; |
| 1071 | fn formatDecl( | 1074 | fn formatDecl( |
| ... | @@ -1074,11 +1077,11 @@ fn formatDecl( | ... | @@ -1074,11 +1077,11 @@ fn formatDecl( |
| 1074 | _: std.fmt.FormatOptions, | 1077 | _: std.fmt.FormatOptions, |
| 1075 | writer: anytype, | 1078 | writer: anytype, |
| 1076 | ) @TypeOf(writer).Error!void { | 1079 | ) @TypeOf(writer).Error!void { |
| 1077 | try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer); | 1080 | try data.zcu.declPtr(data.decl_index).renderFullyQualifiedName(data.zcu, writer); |
| 1078 | } | 1081 | } |
| 1079 | fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { | 1082 | fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { |
| 1080 | return .{ .data = .{ | 1083 | return .{ .data = .{ |
| 1081 | .mod = self.bin_file.comp.module.?, | 1084 | .zcu = self.pt.zcu, |
| 1082 | .decl_index = decl_index, | 1085 | .decl_index = decl_index, |
| 1083 | } }; | 1086 | } }; |
| 1084 | } | 1087 | } |
| ... | @@ -1095,7 +1098,7 @@ fn formatAir( | ... | @@ -1095,7 +1098,7 @@ fn formatAir( |
| 1095 | ) @TypeOf(writer).Error!void { | 1098 | ) @TypeOf(writer).Error!void { |
| 1096 | @import("../../print_air.zig").dumpInst( | 1099 | @import("../../print_air.zig").dumpInst( |
| 1097 | data.inst, | 1100 | data.inst, |
| 1098 | data.self.bin_file.comp.module.?, | 1101 | data.self.pt, |
| 1099 | data.self.air, | 1102 | data.self.air, |
| 1100 | data.self.liveness, | 1103 | data.self.liveness, |
| 1101 | ); | 1104 | ); |
| ... | @@ -1746,7 +1749,8 @@ fn asmMemoryRegisterImmediate( | ... | @@ -1746,7 +1749,8 @@ fn asmMemoryRegisterImmediate( |
| 1746 | } | 1749 | } |
| 1747 | 1750 | ||
| 1748 | fn gen(self: *Self) InnerError!void { | 1751 | fn gen(self: *Self) InnerError!void { |
| 1749 | const mod = self.bin_file.comp.module.?; | 1752 | const pt = self.pt; |
| 1753 | const mod = pt.zcu; | ||
| 1750 | const fn_info = mod.typeToFunc(self.fn_type).?; | 1754 | const fn_info = mod.typeToFunc(self.fn_type).?; |
| 1751 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); | 1755 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); |
| 1752 | if (cc != .Naked) { | 1756 | if (cc != .Naked) { |
| ... | @@ -1764,7 +1768,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1764,7 +1768,7 @@ fn gen(self: *Self) InnerError!void { |
| 1764 | // The address where to store the return value for the caller is in a | 1768 | // The address where to store the return value for the caller is in a |
| 1765 | // register which the callee is free to clobber. Therefore, we purposely | 1769 | // register which the callee is free to clobber. Therefore, we purposely |
| 1766 | // spill it to stack immediately. | 1770 | // spill it to stack immediately. |
| 1767 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, mod)); | 1771 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, pt)); |
| 1768 | try self.genSetMem( | 1772 | try self.genSetMem( |
| 1769 | .{ .frame = frame_index }, | 1773 | .{ .frame = frame_index }, |
| 1770 | 0, | 1774 | 0, |
| ... | @@ -1800,7 +1804,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1800,7 +1804,7 @@ fn gen(self: *Self) InnerError!void { |
| 1800 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); | 1804 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); |
| 1801 | const skip_sse_reloc = try self.asmJccReloc(.na, undefined); | 1805 | const skip_sse_reloc = try self.asmJccReloc(.na, undefined); |
| 1802 | 1806 | ||
| 1803 | const vec_2_f64 = try mod.vectorType(.{ .len = 2, .child = .f64_type }); | 1807 | const vec_2_f64 = try pt.vectorType(.{ .len = 2, .child = .f64_type }); |
| 1804 | for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i| | 1808 | for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i| |
| 1805 | try self.genSetMem( | 1809 | try self.genSetMem( |
| 1806 | .{ .frame = reg_save_area_fi }, | 1810 | .{ .frame = reg_save_area_fi }, |
| ... | @@ -1951,7 +1955,8 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1951,7 +1955,8 @@ fn gen(self: *Self) InnerError!void { |
| 1951 | } | 1955 | } |
| 1952 | 1956 | ||
| 1953 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | 1957 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1954 | const mod = self.bin_file.comp.module.?; | 1958 | const pt = self.pt; |
| 1959 | const mod = pt.zcu; | ||
| 1955 | const ip = &mod.intern_pool; | 1960 | const ip = &mod.intern_pool; |
| 1956 | const air_tags = self.air.instructions.items(.tag); | 1961 | const air_tags = self.air.instructions.items(.tag); |
| 1957 | 1962 | ||
| ... | @@ -2222,12 +2227,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2222,12 +2227,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2222 | } | 2227 | } |
| 2223 | 2228 | ||
| 2224 | fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | 2229 | fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2225 | const mod = self.bin_file.comp.module.?; | 2230 | const pt = self.pt; |
| 2231 | const mod = pt.zcu; | ||
| 2226 | const ip = &mod.intern_pool; | 2232 | const ip = &mod.intern_pool; |
| 2227 | switch (lazy_sym.ty.zigTypeTag(mod)) { | 2233 | switch (lazy_sym.ty.zigTypeTag(mod)) { |
| 2228 | .Enum => { | 2234 | .Enum => { |
| 2229 | const enum_ty = lazy_sym.ty; | 2235 | const enum_ty = lazy_sym.ty; |
| 2230 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(mod)}); | 2236 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); |
| 2231 | 2237 | ||
| 2232 | const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*); | 2238 | const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*); |
| 2233 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); | 2239 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); |
| ... | @@ -2249,7 +2255,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2249,7 +2255,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2249 | const tag_names = enum_ty.enumFields(mod); | 2255 | const tag_names = enum_ty.enumFields(mod); |
| 2250 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { | 2256 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { |
| 2251 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); | 2257 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); |
| 2252 | const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index)); | 2258 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| 2253 | const tag_mcv = try self.genTypedValue(tag_val); | 2259 | const tag_mcv = try self.genTypedValue(tag_val); |
| 2254 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); | 2260 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); |
| 2255 | const skip_reloc = try self.asmJccReloc(.ne, undefined); | 2261 | const skip_reloc = try self.asmJccReloc(.ne, undefined); |
| ... | @@ -2282,7 +2288,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2282,7 +2288,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2282 | }, | 2288 | }, |
| 2283 | else => return self.fail( | 2289 | else => return self.fail( |
| 2284 | "TODO implement {s} for {}", | 2290 | "TODO implement {s} for {}", |
| 2285 | .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) }, | 2291 | .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) }, |
| 2286 | ), | 2292 | ), |
| 2287 | } | 2293 | } |
| 2288 | } | 2294 | } |
| ... | @@ -2481,14 +2487,15 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex { | ... | @@ -2481,14 +2487,15 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex { |
| 2481 | 2487 | ||
| 2482 | /// Use a pointer instruction as the basis for allocating stack memory. | 2488 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2483 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { | 2489 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { |
| 2484 | const mod = self.bin_file.comp.module.?; | 2490 | const pt = self.pt; |
| 2491 | const mod = pt.zcu; | ||
| 2485 | const ptr_ty = self.typeOfIndex(inst); | 2492 | const ptr_ty = self.typeOfIndex(inst); |
| 2486 | const val_ty = ptr_ty.childType(mod); | 2493 | const val_ty = ptr_ty.childType(mod); |
| 2487 | return self.allocFrameIndex(FrameAlloc.init(.{ | 2494 | return self.allocFrameIndex(FrameAlloc.init(.{ |
| 2488 | .size = math.cast(u32, val_ty.abiSize(mod)) orelse { | 2495 | .size = math.cast(u32, val_ty.abiSize(pt)) orelse { |
| 2489 | return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)}); | 2496 | return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); |
| 2490 | }, | 2497 | }, |
| 2491 | .alignment = ptr_ty.ptrAlignment(mod).max(.@"1"), | 2498 | .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"), |
| 2492 | })); | 2499 | })); |
| 2493 | } | 2500 | } |
| 2494 | 2501 | ||
| ... | @@ -2501,9 +2508,10 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue { | ... | @@ -2501,9 +2508,10 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue { |
| 2501 | } | 2508 | } |
| 2502 | 2509 | ||
| 2503 | fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue { | 2510 | fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue { |
| 2504 | const mod = self.bin_file.comp.module.?; | 2511 | const pt = self.pt; |
| 2505 | const abi_size = math.cast(u32, ty.abiSize(mod)) orelse { | 2512 | const mod = pt.zcu; |
| 2506 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)}); | 2513 | const abi_size = math.cast(u32, ty.abiSize(pt)) orelse { |
| 2514 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)}); | ||
| 2507 | }; | 2515 | }; |
| 2508 | 2516 | ||
| 2509 | if (reg_ok) need_mem: { | 2517 | if (reg_ok) need_mem: { |
| ... | @@ -2529,12 +2537,13 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b | ... | @@ -2529,12 +2537,13 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b |
| 2529 | } | 2537 | } |
| 2530 | } | 2538 | } |
| 2531 | 2539 | ||
| 2532 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, mod)); | 2540 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, pt)); |
| 2533 | return .{ .load_frame = .{ .index = frame_index } }; | 2541 | return .{ .load_frame = .{ .index = frame_index } }; |
| 2534 | } | 2542 | } |
| 2535 | 2543 | ||
| 2536 | fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { | 2544 | fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { |
| 2537 | const mod = self.bin_file.comp.module.?; | 2545 | const pt = self.pt; |
| 2546 | const mod = pt.zcu; | ||
| 2538 | return switch (ty.zigTypeTag(mod)) { | 2547 | return switch (ty.zigTypeTag(mod)) { |
| 2539 | .Float => switch (ty.floatBits(self.target.*)) { | 2548 | .Float => switch (ty.floatBits(self.target.*)) { |
| 2540 | 80 => abi.RegisterClass.x87, | 2549 | 80 => abi.RegisterClass.x87, |
| ... | @@ -2849,7 +2858,8 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2849,7 +2858,8 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2849 | } | 2858 | } |
| 2850 | 2859 | ||
| 2851 | fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | 2860 | fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2852 | const mod = self.bin_file.comp.module.?; | 2861 | const pt = self.pt; |
| 2862 | const mod = pt.zcu; | ||
| 2853 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2863 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2854 | const dst_ty = self.typeOfIndex(inst); | 2864 | const dst_ty = self.typeOfIndex(inst); |
| 2855 | const dst_scalar_ty = dst_ty.scalarType(mod); | 2865 | const dst_scalar_ty = dst_ty.scalarType(mod); |
| ... | @@ -2892,14 +2902,14 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2892,14 +2902,14 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2892 | } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }}); | 2902 | } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }}); |
| 2893 | } | 2903 | } |
| 2894 | 2904 | ||
| 2895 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 2905 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 2896 | const src_mcv = try self.resolveInst(ty_op.operand); | 2906 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 2897 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 2907 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2898 | src_mcv | 2908 | src_mcv |
| 2899 | else | 2909 | else |
| 2900 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 2910 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 2901 | const dst_reg = dst_mcv.getReg().?; | 2911 | const dst_reg = dst_mcv.getReg().?; |
| 2902 | const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(mod), 16))); | 2912 | const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(pt), 16))); |
| 2903 | const dst_lock = self.register_manager.lockReg(dst_reg); | 2913 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 2904 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 2914 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 2905 | 2915 | ||
| ... | @@ -2978,19 +2988,20 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2978,19 +2988,20 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2978 | } | 2988 | } |
| 2979 | break :result dst_mcv; | 2989 | break :result dst_mcv; |
| 2980 | } orelse return self.fail("TODO implement airFpext from {} to {}", .{ | 2990 | } orelse return self.fail("TODO implement airFpext from {} to {}", .{ |
| 2981 | src_ty.fmt(mod), dst_ty.fmt(mod), | 2991 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 2982 | }); | 2992 | }); |
| 2983 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2993 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2984 | } | 2994 | } |
| 2985 | 2995 | ||
| 2986 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | 2996 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2987 | const mod = self.bin_file.comp.module.?; | 2997 | const pt = self.pt; |
| 2998 | const mod = pt.zcu; | ||
| 2988 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2999 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2989 | const src_ty = self.typeOf(ty_op.operand); | 3000 | const src_ty = self.typeOf(ty_op.operand); |
| 2990 | const dst_ty = self.typeOfIndex(inst); | 3001 | const dst_ty = self.typeOfIndex(inst); |
| 2991 | 3002 | ||
| 2992 | const result = @as(?MCValue, result: { | 3003 | const result = @as(?MCValue, result: { |
| 2993 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 3004 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 2994 | 3005 | ||
| 2995 | const src_int_info = src_ty.intInfo(mod); | 3006 | const src_int_info = src_ty.intInfo(mod); |
| 2996 | const dst_int_info = dst_ty.intInfo(mod); | 3007 | const dst_int_info = dst_ty.intInfo(mod); |
| ... | @@ -3001,13 +3012,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3001,13 +3012,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 3001 | 3012 | ||
| 3002 | const src_mcv = try self.resolveInst(ty_op.operand); | 3013 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 3003 | if (dst_ty.isVector(mod)) { | 3014 | if (dst_ty.isVector(mod)) { |
| 3004 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 3015 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 3005 | const max_abi_size = @max(dst_abi_size, src_abi_size); | 3016 | const max_abi_size = @max(dst_abi_size, src_abi_size); |
| 3006 | if (max_abi_size > @as(u32, if (self.hasFeature(.avx2)) 32 else 16)) break :result null; | 3017 | if (max_abi_size > @as(u32, if (self.hasFeature(.avx2)) 32 else 16)) break :result null; |
| 3007 | const has_avx = self.hasFeature(.avx); | 3018 | const has_avx = self.hasFeature(.avx); |
| 3008 | 3019 | ||
| 3009 | const dst_elem_abi_size = dst_ty.childType(mod).abiSize(mod); | 3020 | const dst_elem_abi_size = dst_ty.childType(mod).abiSize(pt); |
| 3010 | const src_elem_abi_size = src_ty.childType(mod).abiSize(mod); | 3021 | const src_elem_abi_size = src_ty.childType(mod).abiSize(pt); |
| 3011 | switch (math.order(dst_elem_abi_size, src_elem_abi_size)) { | 3022 | switch (math.order(dst_elem_abi_size, src_elem_abi_size)) { |
| 3012 | .lt => { | 3023 | .lt => { |
| 3013 | const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) { | 3024 | const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) { |
| ... | @@ -3236,19 +3247,20 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3236,19 +3247,20 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 3236 | 3247 | ||
| 3237 | break :result dst_mcv; | 3248 | break :result dst_mcv; |
| 3238 | }) orelse return self.fail("TODO implement airIntCast from {} to {}", .{ | 3249 | }) orelse return self.fail("TODO implement airIntCast from {} to {}", .{ |
| 3239 | src_ty.fmt(mod), dst_ty.fmt(mod), | 3250 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 3240 | }); | 3251 | }); |
| 3241 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 3252 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3242 | } | 3253 | } |
| 3243 | 3254 | ||
| 3244 | fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | 3255 | fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3245 | const mod = self.bin_file.comp.module.?; | 3256 | const pt = self.pt; |
| 3257 | const mod = pt.zcu; | ||
| 3246 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3258 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3247 | 3259 | ||
| 3248 | const dst_ty = self.typeOfIndex(inst); | 3260 | const dst_ty = self.typeOfIndex(inst); |
| 3249 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 3261 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 3250 | const src_ty = self.typeOf(ty_op.operand); | 3262 | const src_ty = self.typeOf(ty_op.operand); |
| 3251 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 3263 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 3252 | 3264 | ||
| 3253 | const result = result: { | 3265 | const result = result: { |
| 3254 | const src_mcv = try self.resolveInst(ty_op.operand); | 3266 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | @@ -3278,9 +3290,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3278,9 +3290,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3278 | if (dst_ty.zigTypeTag(mod) == .Vector) { | 3290 | if (dst_ty.zigTypeTag(mod) == .Vector) { |
| 3279 | assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod)); | 3291 | assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod)); |
| 3280 | const dst_elem_ty = dst_ty.childType(mod); | 3292 | const dst_elem_ty = dst_ty.childType(mod); |
| 3281 | const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(mod)); | 3293 | const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(pt)); |
| 3282 | const src_elem_ty = src_ty.childType(mod); | 3294 | const src_elem_ty = src_ty.childType(mod); |
| 3283 | const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(mod)); | 3295 | const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(pt)); |
| 3284 | 3296 | ||
| 3285 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) { | 3297 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) { |
| 3286 | 1 => switch (src_elem_abi_size) { | 3298 | 1 => switch (src_elem_abi_size) { |
| ... | @@ -3305,20 +3317,20 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3305,20 +3317,20 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3305 | else => null, | 3317 | else => null, |
| 3306 | }, | 3318 | }, |
| 3307 | else => null, | 3319 | else => null, |
| 3308 | }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(mod)}); | 3320 | }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(pt)}); |
| 3309 | 3321 | ||
| 3310 | const dst_info = dst_elem_ty.intInfo(mod); | 3322 | const dst_info = dst_elem_ty.intInfo(mod); |
| 3311 | const src_info = src_elem_ty.intInfo(mod); | 3323 | const src_info = src_elem_ty.intInfo(mod); |
| 3312 | 3324 | ||
| 3313 | const mask_val = try mod.intValue(src_elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits)); | 3325 | const mask_val = try pt.intValue(src_elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits)); |
| 3314 | 3326 | ||
| 3315 | const splat_ty = try mod.vectorType(.{ | 3327 | const splat_ty = try pt.vectorType(.{ |
| 3316 | .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), | 3328 | .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), |
| 3317 | .child = src_elem_ty.ip_index, | 3329 | .child = src_elem_ty.ip_index, |
| 3318 | }); | 3330 | }); |
| 3319 | const splat_abi_size: u32 = @intCast(splat_ty.abiSize(mod)); | 3331 | const splat_abi_size: u32 = @intCast(splat_ty.abiSize(pt)); |
| 3320 | 3332 | ||
| 3321 | const splat_val = try mod.intern(.{ .aggregate = .{ | 3333 | const splat_val = try pt.intern(.{ .aggregate = .{ |
| 3322 | .ty = splat_ty.ip_index, | 3334 | .ty = splat_ty.ip_index, |
| 3323 | .storage = .{ .repeated_elem = mask_val.ip_index }, | 3335 | .storage = .{ .repeated_elem = mask_val.ip_index }, |
| 3324 | } }); | 3336 | } }); |
| ... | @@ -3375,7 +3387,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3375,7 +3387,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3375 | } | 3387 | } |
| 3376 | } else if (dst_abi_size <= 16) { | 3388 | } else if (dst_abi_size <= 16) { |
| 3377 | const dst_info = dst_ty.intInfo(mod); | 3389 | const dst_info = dst_ty.intInfo(mod); |
| 3378 | const high_ty = try mod.intType(dst_info.signedness, dst_info.bits - 64); | 3390 | const high_ty = try pt.intType(dst_info.signedness, dst_info.bits - 64); |
| 3379 | if (self.regExtraBits(high_ty) > 0) { | 3391 | if (self.regExtraBits(high_ty) > 0) { |
| 3380 | try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); | 3392 | try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); |
| 3381 | } | 3393 | } |
| ... | @@ -3400,12 +3412,12 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3400,12 +3412,12 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 3400 | } | 3412 | } |
| 3401 | 3413 | ||
| 3402 | fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | 3414 | fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3403 | const mod = self.bin_file.comp.module.?; | 3415 | const pt = self.pt; |
| 3404 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3416 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3405 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3417 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3406 | 3418 | ||
| 3407 | const slice_ty = self.typeOfIndex(inst); | 3419 | const slice_ty = self.typeOfIndex(inst); |
| 3408 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); | 3420 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); |
| 3409 | 3421 | ||
| 3410 | const ptr_ty = self.typeOf(bin_op.lhs); | 3422 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3411 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); | 3423 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); |
| ... | @@ -3413,7 +3425,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3413,7 +3425,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3413 | const len_ty = self.typeOf(bin_op.rhs); | 3425 | const len_ty = self.typeOf(bin_op.rhs); |
| 3414 | try self.genSetMem( | 3426 | try self.genSetMem( |
| 3415 | .{ .frame = frame_index }, | 3427 | .{ .frame = frame_index }, |
| 3416 | @intCast(ptr_ty.abiSize(mod)), | 3428 | @intCast(ptr_ty.abiSize(pt)), |
| 3417 | len_ty, | 3429 | len_ty, |
| 3418 | .{ .air_ref = bin_op.rhs }, | 3430 | .{ .air_ref = bin_op.rhs }, |
| 3419 | .{}, | 3431 | .{}, |
| ... | @@ -3430,14 +3442,15 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | ... | @@ -3430,14 +3442,15 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3430 | } | 3442 | } |
| 3431 | 3443 | ||
| 3432 | fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | 3444 | fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3433 | const mod = self.bin_file.comp.module.?; | 3445 | const pt = self.pt; |
| 3446 | const mod = pt.zcu; | ||
| 3434 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3447 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3435 | const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); | 3448 | const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); |
| 3436 | 3449 | ||
| 3437 | const dst_ty = self.typeOfIndex(inst); | 3450 | const dst_ty = self.typeOfIndex(inst); |
| 3438 | if (dst_ty.isAbiInt(mod)) { | 3451 | if (dst_ty.isAbiInt(mod)) { |
| 3439 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 3452 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 3440 | const bit_size: u32 = @intCast(dst_ty.bitSize(mod)); | 3453 | const bit_size: u32 = @intCast(dst_ty.bitSize(pt)); |
| 3441 | if (abi_size * 8 > bit_size) { | 3454 | if (abi_size * 8 > bit_size) { |
| 3442 | const dst_lock = switch (dst_mcv) { | 3455 | const dst_lock = switch (dst_mcv) { |
| 3443 | .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg), | 3456 | .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg), |
| ... | @@ -3452,7 +3465,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | ... | @@ -3452,7 +3465,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3452 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3465 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3453 | defer self.register_manager.unlockReg(tmp_lock); | 3466 | defer self.register_manager.unlockReg(tmp_lock); |
| 3454 | 3467 | ||
| 3455 | const hi_ty = try mod.intType(.unsigned, @intCast((dst_ty.bitSize(mod) - 1) % 64 + 1)); | 3468 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1)); |
| 3456 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); | 3469 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 3457 | try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{}); | 3470 | try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{}); |
| 3458 | try self.truncateRegister(dst_ty, tmp_reg); | 3471 | try self.truncateRegister(dst_ty, tmp_reg); |
| ... | @@ -3471,7 +3484,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void | ... | @@ -3471,7 +3484,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void |
| 3471 | } | 3484 | } |
| 3472 | 3485 | ||
| 3473 | fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { | 3486 | fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3474 | const mod = self.bin_file.comp.module.?; | 3487 | const pt = self.pt; |
| 3488 | const mod = pt.zcu; | ||
| 3475 | const air_tag = self.air.instructions.items(.tag); | 3489 | const air_tag = self.air.instructions.items(.tag); |
| 3476 | const air_data = self.air.instructions.items(.data); | 3490 | const air_data = self.air.instructions.items(.data); |
| 3477 | 3491 | ||
| ... | @@ -3497,7 +3511,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { | ... | @@ -3497,7 +3511,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3497 | } | 3511 | } |
| 3498 | } else if (dst_air.toInterned()) |ip_index| { | 3512 | } else if (dst_air.toInterned()) |ip_index| { |
| 3499 | var space: Value.BigIntSpace = undefined; | 3513 | var space: Value.BigIntSpace = undefined; |
| 3500 | const src_int = Value.fromInterned(ip_index).toBigInt(&space, mod); | 3514 | const src_int = Value.fromInterned(ip_index).toBigInt(&space, pt); |
| 3501 | return @as(u16, @intCast(src_int.bitCountTwosComp())) + | 3515 | return @as(u16, @intCast(src_int.bitCountTwosComp())) + |
| 3502 | @intFromBool(src_int.positive and dst_info.signedness == .signed); | 3516 | @intFromBool(src_int.positive and dst_info.signedness == .signed); |
| 3503 | } | 3517 | } |
| ... | @@ -3505,7 +3519,8 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { | ... | @@ -3505,7 +3519,8 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3505 | } | 3519 | } |
| 3506 | 3520 | ||
| 3507 | fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | 3521 | fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3508 | const mod = self.bin_file.comp.module.?; | 3522 | const pt = self.pt; |
| 3523 | const mod = pt.zcu; | ||
| 3509 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3524 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3510 | const result = result: { | 3525 | const result = result: { |
| 3511 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 3526 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| ... | @@ -3514,10 +3529,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3514,10 +3529,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3514 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), | 3529 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), |
| 3515 | else => {}, | 3530 | else => {}, |
| 3516 | } | 3531 | } |
| 3517 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 3532 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 3518 | 3533 | ||
| 3519 | const dst_info = dst_ty.intInfo(mod); | 3534 | const dst_info = dst_ty.intInfo(mod); |
| 3520 | const src_ty = try mod.intType(dst_info.signedness, switch (tag) { | 3535 | const src_ty = try pt.intType(dst_info.signedness, switch (tag) { |
| 3521 | else => unreachable, | 3536 | else => unreachable, |
| 3522 | .mul, .mul_wrap => @max( | 3537 | .mul, .mul_wrap => @max( |
| 3523 | self.activeIntBits(bin_op.lhs), | 3538 | self.activeIntBits(bin_op.lhs), |
| ... | @@ -3526,7 +3541,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3526,7 +3541,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3526 | ), | 3541 | ), |
| 3527 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, | 3542 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, |
| 3528 | }); | 3543 | }); |
| 3529 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 3544 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 3530 | 3545 | ||
| 3531 | if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) { | 3546 | if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) { |
| 3532 | else => unreachable, | 3547 | else => unreachable, |
| ... | @@ -3539,7 +3554,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3539,7 +3554,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3539 | state: State, | 3554 | state: State, |
| 3540 | reloc: Mir.Inst.Index, | 3555 | reloc: Mir.Inst.Index, |
| 3541 | } = if (signed and tag == .div_floor) state: { | 3556 | } = if (signed and tag == .div_floor) state: { |
| 3542 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod)); | 3557 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, pt)); |
| 3543 | try self.asmMemoryImmediate( | 3558 | try self.asmMemoryImmediate( |
| 3544 | .{ ._, .mov }, | 3559 | .{ ._, .mov }, |
| 3545 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, | 3560 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| ... | @@ -3614,7 +3629,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3614,7 +3629,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3614 | .rem, .mod => "mod", | 3629 | .rem, .mod => "mod", |
| 3615 | else => unreachable, | 3630 | else => unreachable, |
| 3616 | }, | 3631 | }, |
| 3617 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), | 3632 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))), |
| 3618 | }) catch unreachable, | 3633 | }) catch unreachable, |
| 3619 | } }, | 3634 | } }, |
| 3620 | &.{ src_ty, src_ty }, | 3635 | &.{ src_ty, src_ty }, |
| ... | @@ -3643,7 +3658,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3643,7 +3658,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3643 | .return_type = dst_ty.toIntern(), | 3658 | .return_type = dst_ty.toIntern(), |
| 3644 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, | 3659 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, |
| 3645 | .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{ | 3660 | .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{ |
| 3646 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), | 3661 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))), |
| 3647 | }) catch unreachable, | 3662 | }) catch unreachable, |
| 3648 | } }, | 3663 | } }, |
| 3649 | &.{ src_ty, src_ty }, | 3664 | &.{ src_ty, src_ty }, |
| ... | @@ -3734,12 +3749,13 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3734,12 +3749,13 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3734 | } | 3749 | } |
| 3735 | 3750 | ||
| 3736 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | 3751 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3737 | const mod = self.bin_file.comp.module.?; | 3752 | const pt = self.pt; |
| 3753 | const mod = pt.zcu; | ||
| 3738 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3754 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3739 | const ty = self.typeOf(bin_op.lhs); | 3755 | const ty = self.typeOf(bin_op.lhs); |
| 3740 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 3756 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( |
| 3741 | "TODO implement airAddSat for {}", | 3757 | "TODO implement airAddSat for {}", |
| 3742 | .{ty.fmt(mod)}, | 3758 | .{ty.fmt(pt)}, |
| 3743 | ); | 3759 | ); |
| 3744 | 3760 | ||
| 3745 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 3761 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| ... | @@ -3804,7 +3820,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3804,7 +3820,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3804 | break :cc .o; | 3820 | break :cc .o; |
| 3805 | } else cc: { | 3821 | } else cc: { |
| 3806 | try self.genSetReg(limit_reg, ty, .{ | 3822 | try self.genSetReg(limit_reg, ty, .{ |
| 3807 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)), | 3823 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(pt)), |
| 3808 | }, .{}); | 3824 | }, .{}); |
| 3809 | 3825 | ||
| 3810 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); | 3826 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); |
| ... | @@ -3815,7 +3831,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3815,7 +3831,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3815 | break :cc .c; | 3831 | break :cc .c; |
| 3816 | }; | 3832 | }; |
| 3817 | 3833 | ||
| 3818 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | 3834 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); |
| 3819 | try self.asmCmovccRegisterRegister( | 3835 | try self.asmCmovccRegisterRegister( |
| 3820 | cc, | 3836 | cc, |
| 3821 | registerAlias(dst_reg, cmov_abi_size), | 3837 | registerAlias(dst_reg, cmov_abi_size), |
| ... | @@ -3834,12 +3850,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3834,12 +3850,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3834 | } | 3850 | } |
| 3835 | 3851 | ||
| 3836 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | 3852 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3837 | const mod = self.bin_file.comp.module.?; | 3853 | const pt = self.pt; |
| 3854 | const mod = pt.zcu; | ||
| 3838 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3855 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3839 | const ty = self.typeOf(bin_op.lhs); | 3856 | const ty = self.typeOf(bin_op.lhs); |
| 3840 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 3857 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( |
| 3841 | "TODO implement airSubSat for {}", | 3858 | "TODO implement airSubSat for {}", |
| 3842 | .{ty.fmt(mod)}, | 3859 | .{ty.fmt(pt)}, |
| 3843 | ); | 3860 | ); |
| 3844 | 3861 | ||
| 3845 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 3862 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| ... | @@ -3908,7 +3925,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3908,7 +3925,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3908 | break :cc .c; | 3925 | break :cc .c; |
| 3909 | }; | 3926 | }; |
| 3910 | 3927 | ||
| 3911 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | 3928 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); |
| 3912 | try self.asmCmovccRegisterRegister( | 3929 | try self.asmCmovccRegisterRegister( |
| 3913 | cc, | 3930 | cc, |
| 3914 | registerAlias(dst_reg, cmov_abi_size), | 3931 | registerAlias(dst_reg, cmov_abi_size), |
| ... | @@ -3927,13 +3944,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3927,13 +3944,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3927 | } | 3944 | } |
| 3928 | 3945 | ||
| 3929 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | 3946 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3930 | const mod = self.bin_file.comp.module.?; | 3947 | const pt = self.pt; |
| 3948 | const mod = pt.zcu; | ||
| 3931 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3949 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3932 | const ty = self.typeOf(bin_op.lhs); | 3950 | const ty = self.typeOf(bin_op.lhs); |
| 3933 | 3951 | ||
| 3934 | const result = result: { | 3952 | const result = result: { |
| 3935 | if (ty.toIntern() == .i128_type) { | 3953 | if (ty.toIntern() == .i128_type) { |
| 3936 | const ptr_c_int = try mod.singleMutPtrType(Type.c_int); | 3954 | const ptr_c_int = try pt.singleMutPtrType(Type.c_int); |
| 3937 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); | 3955 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); |
| 3938 | 3956 | ||
| 3939 | const dst_mcv = try self.genCall(.{ .lib = .{ | 3957 | const dst_mcv = try self.genCall(.{ .lib = .{ |
| ... | @@ -4010,9 +4028,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4010,9 +4028,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4010 | break :result dst_mcv; | 4028 | break :result dst_mcv; |
| 4011 | } | 4029 | } |
| 4012 | 4030 | ||
| 4013 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 4031 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( |
| 4014 | "TODO implement airMulSat for {}", | 4032 | "TODO implement airMulSat for {}", |
| 4015 | .{ty.fmt(mod)}, | 4033 | .{ty.fmt(pt)}, |
| 4016 | ); | 4034 | ); |
| 4017 | 4035 | ||
| 4018 | try self.spillRegisters(&.{ .rax, .rcx, .rdx }); | 4036 | try self.spillRegisters(&.{ .rax, .rcx, .rdx }); |
| ... | @@ -4061,7 +4079,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4061,7 +4079,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4061 | }; | 4079 | }; |
| 4062 | 4080 | ||
| 4063 | const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv); | 4081 | const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv); |
| 4064 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | 4082 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); |
| 4065 | try self.asmCmovccRegisterRegister( | 4083 | try self.asmCmovccRegisterRegister( |
| 4066 | cc, | 4084 | cc, |
| 4067 | registerAlias(dst_mcv.register, cmov_abi_size), | 4085 | registerAlias(dst_mcv.register, cmov_abi_size), |
| ... | @@ -4073,7 +4091,8 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4073,7 +4091,8 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4073 | } | 4091 | } |
| 4074 | 4092 | ||
| 4075 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 4093 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4076 | const mod = self.bin_file.comp.module.?; | 4094 | const pt = self.pt; |
| 4095 | const mod = pt.zcu; | ||
| 4077 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4096 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4078 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4097 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4079 | const result: MCValue = result: { | 4098 | const result: MCValue = result: { |
| ... | @@ -4109,17 +4128,17 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4109,17 +4128,17 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4109 | } | 4128 | } |
| 4110 | 4129 | ||
| 4111 | const frame_index = | 4130 | const frame_index = |
| 4112 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4131 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4113 | try self.genSetMem( | 4132 | try self.genSetMem( |
| 4114 | .{ .frame = frame_index }, | 4133 | .{ .frame = frame_index }, |
| 4115 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4134 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4116 | Type.u1, | 4135 | Type.u1, |
| 4117 | .{ .eflags = cc }, | 4136 | .{ .eflags = cc }, |
| 4118 | .{}, | 4137 | .{}, |
| 4119 | ); | 4138 | ); |
| 4120 | try self.genSetMem( | 4139 | try self.genSetMem( |
| 4121 | .{ .frame = frame_index }, | 4140 | .{ .frame = frame_index }, |
| 4122 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4141 | @intCast(tuple_ty.structFieldOffset(0, pt)), |
| 4123 | ty, | 4142 | ty, |
| 4124 | partial_mcv, | 4143 | partial_mcv, |
| 4125 | .{}, | 4144 | .{}, |
| ... | @@ -4128,7 +4147,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4128,7 +4147,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4128 | } | 4147 | } |
| 4129 | 4148 | ||
| 4130 | const frame_index = | 4149 | const frame_index = |
| 4131 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4150 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4132 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 4151 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4133 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4152 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4134 | }, | 4153 | }, |
| ... | @@ -4139,7 +4158,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4139,7 +4158,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4139 | } | 4158 | } |
| 4140 | 4159 | ||
| 4141 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 4160 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4142 | const mod = self.bin_file.comp.module.?; | 4161 | const pt = self.pt; |
| 4162 | const mod = pt.zcu; | ||
| 4143 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4163 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4144 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4164 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4145 | const result: MCValue = result: { | 4165 | const result: MCValue = result: { |
| ... | @@ -4186,17 +4206,17 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4186,17 +4206,17 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4186 | } | 4206 | } |
| 4187 | 4207 | ||
| 4188 | const frame_index = | 4208 | const frame_index = |
| 4189 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4209 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4190 | try self.genSetMem( | 4210 | try self.genSetMem( |
| 4191 | .{ .frame = frame_index }, | 4211 | .{ .frame = frame_index }, |
| 4192 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4212 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4193 | tuple_ty.structFieldType(1, mod), | 4213 | tuple_ty.structFieldType(1, mod), |
| 4194 | .{ .eflags = cc }, | 4214 | .{ .eflags = cc }, |
| 4195 | .{}, | 4215 | .{}, |
| 4196 | ); | 4216 | ); |
| 4197 | try self.genSetMem( | 4217 | try self.genSetMem( |
| 4198 | .{ .frame = frame_index }, | 4218 | .{ .frame = frame_index }, |
| 4199 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4219 | @intCast(tuple_ty.structFieldOffset(0, pt)), |
| 4200 | tuple_ty.structFieldType(0, mod), | 4220 | tuple_ty.structFieldType(0, mod), |
| 4201 | partial_mcv, | 4221 | partial_mcv, |
| 4202 | .{}, | 4222 | .{}, |
| ... | @@ -4205,7 +4225,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4205,7 +4225,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4205 | } | 4225 | } |
| 4206 | 4226 | ||
| 4207 | const frame_index = | 4227 | const frame_index = |
| 4208 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4228 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4209 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 4229 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4210 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4230 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4211 | }, | 4231 | }, |
| ... | @@ -4222,7 +4242,8 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4222,7 +4242,8 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4222 | src_mcv: MCValue, | 4242 | src_mcv: MCValue, |
| 4223 | overflow_cc: ?Condition, | 4243 | overflow_cc: ?Condition, |
| 4224 | ) !void { | 4244 | ) !void { |
| 4225 | const mod = self.bin_file.comp.module.?; | 4245 | const pt = self.pt; |
| 4246 | const mod = pt.zcu; | ||
| 4226 | const src_lock = switch (src_mcv) { | 4247 | const src_lock = switch (src_mcv) { |
| 4227 | .register => |reg| self.register_manager.lockReg(reg), | 4248 | .register => |reg| self.register_manager.lockReg(reg), |
| 4228 | else => null, | 4249 | else => null, |
| ... | @@ -4233,12 +4254,12 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4233,12 +4254,12 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4233 | const int_info = ty.intInfo(mod); | 4254 | const int_info = ty.intInfo(mod); |
| 4234 | 4255 | ||
| 4235 | const hi_bits = (int_info.bits - 1) % 64 + 1; | 4256 | const hi_bits = (int_info.bits - 1) % 64 + 1; |
| 4236 | const hi_ty = try mod.intType(int_info.signedness, hi_bits); | 4257 | const hi_ty = try pt.intType(int_info.signedness, hi_bits); |
| 4237 | 4258 | ||
| 4238 | const limb_bits: u16 = @intCast(if (int_info.bits <= 64) self.regBitSize(ty) else 64); | 4259 | const limb_bits: u16 = @intCast(if (int_info.bits <= 64) self.regBitSize(ty) else 64); |
| 4239 | const limb_ty = try mod.intType(int_info.signedness, limb_bits); | 4260 | const limb_ty = try pt.intType(int_info.signedness, limb_bits); |
| 4240 | 4261 | ||
| 4241 | const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_bits); | 4262 | const rest_ty = try pt.intType(.unsigned, int_info.bits - hi_bits); |
| 4242 | 4263 | ||
| 4243 | const temp_regs = | 4264 | const temp_regs = |
| 4244 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); | 4265 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); |
| ... | @@ -4269,7 +4290,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4269,7 +4290,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4269 | ); | 4290 | ); |
| 4270 | } | 4291 | } |
| 4271 | 4292 | ||
| 4272 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod)); | 4293 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt)); |
| 4273 | if (hi_limb_off > 0) try self.genSetMem( | 4294 | if (hi_limb_off > 0) try self.genSetMem( |
| 4274 | .{ .frame = frame_index }, | 4295 | .{ .frame = frame_index }, |
| 4275 | payload_off, | 4296 | payload_off, |
| ... | @@ -4286,7 +4307,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4286,7 +4307,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4286 | ); | 4307 | ); |
| 4287 | try self.genSetMem( | 4308 | try self.genSetMem( |
| 4288 | .{ .frame = frame_index }, | 4309 | .{ .frame = frame_index }, |
| 4289 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4310 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4290 | tuple_ty.structFieldType(1, mod), | 4311 | tuple_ty.structFieldType(1, mod), |
| 4291 | if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, | 4312 | if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, |
| 4292 | .{}, | 4313 | .{}, |
| ... | @@ -4294,18 +4315,19 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4294,18 +4315,19 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4294 | } | 4315 | } |
| 4295 | 4316 | ||
| 4296 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 4317 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4297 | const mod = self.bin_file.comp.module.?; | 4318 | const pt = self.pt; |
| 4319 | const mod = pt.zcu; | ||
| 4298 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4320 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4299 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4321 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4300 | const tuple_ty = self.typeOfIndex(inst); | 4322 | const tuple_ty = self.typeOfIndex(inst); |
| 4301 | const dst_ty = self.typeOf(bin_op.lhs); | 4323 | const dst_ty = self.typeOf(bin_op.lhs); |
| 4302 | const result: MCValue = switch (dst_ty.zigTypeTag(mod)) { | 4324 | const result: MCValue = switch (dst_ty.zigTypeTag(mod)) { |
| 4303 | .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(mod)}), | 4325 | .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(pt)}), |
| 4304 | .Int => result: { | 4326 | .Int => result: { |
| 4305 | const dst_info = dst_ty.intInfo(mod); | 4327 | const dst_info = dst_ty.intInfo(mod); |
| 4306 | if (dst_info.bits > 128 and dst_info.signedness == .unsigned) { | 4328 | if (dst_info.bits > 128 and dst_info.signedness == .unsigned) { |
| 4307 | const slow_inc = self.hasFeature(.slow_incdec); | 4329 | const slow_inc = self.hasFeature(.slow_incdec); |
| 4308 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 4330 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 4309 | const limb_len = math.divCeil(u32, abi_size, 8) catch unreachable; | 4331 | const limb_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| 4310 | 4332 | ||
| 4311 | try self.spillRegisters(&.{ .rax, .rcx, .rdx }); | 4333 | try self.spillRegisters(&.{ .rax, .rcx, .rdx }); |
| ... | @@ -4316,7 +4338,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4316,7 +4338,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4316 | try self.genInlineMemset( | 4338 | try self.genInlineMemset( |
| 4317 | dst_mcv.address(), | 4339 | dst_mcv.address(), |
| 4318 | .{ .immediate = 0 }, | 4340 | .{ .immediate = 0 }, |
| 4319 | .{ .immediate = tuple_ty.abiSize(mod) }, | 4341 | .{ .immediate = tuple_ty.abiSize(pt) }, |
| 4320 | .{}, | 4342 | .{}, |
| 4321 | ); | 4343 | ); |
| 4322 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 4344 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| ... | @@ -4356,7 +4378,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4356,7 +4378,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4356 | .index = temp_regs[3].to64(), | 4378 | .index = temp_regs[3].to64(), |
| 4357 | .scale = .@"8", | 4379 | .scale = .@"8", |
| 4358 | .disp = dst_mcv.load_frame.off + | 4380 | .disp = dst_mcv.load_frame.off + |
| 4359 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), | 4381 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), |
| 4360 | } }, | 4382 | } }, |
| 4361 | }, .rdx); | 4383 | }, .rdx); |
| 4362 | try self.asmSetccRegister(.c, .cl); | 4384 | try self.asmSetccRegister(.c, .cl); |
| ... | @@ -4380,7 +4402,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4380,7 +4402,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4380 | .index = temp_regs[3].to64(), | 4402 | .index = temp_regs[3].to64(), |
| 4381 | .scale = .@"8", | 4403 | .scale = .@"8", |
| 4382 | .disp = dst_mcv.load_frame.off + | 4404 | .disp = dst_mcv.load_frame.off + |
| 4383 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), | 4405 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), |
| 4384 | } }, | 4406 | } }, |
| 4385 | }, .rax); | 4407 | }, .rax); |
| 4386 | try self.asmSetccRegister(.c, .ch); | 4408 | try self.asmSetccRegister(.c, .ch); |
| ... | @@ -4429,7 +4451,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4429,7 +4451,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4429 | .mod = .{ .rm = .{ | 4451 | .mod = .{ .rm = .{ |
| 4430 | .size = .byte, | 4452 | .size = .byte, |
| 4431 | .disp = dst_mcv.load_frame.off + | 4453 | .disp = dst_mcv.load_frame.off + |
| 4432 | @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))), | 4454 | @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), |
| 4433 | } }, | 4455 | } }, |
| 4434 | }, Immediate.u(1)); | 4456 | }, Immediate.u(1)); |
| 4435 | self.performReloc(no_overflow); | 4457 | self.performReloc(no_overflow); |
| ... | @@ -4453,11 +4475,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4453,11 +4475,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4453 | const lhs_active_bits = self.activeIntBits(bin_op.lhs); | 4475 | const lhs_active_bits = self.activeIntBits(bin_op.lhs); |
| 4454 | const rhs_active_bits = self.activeIntBits(bin_op.rhs); | 4476 | const rhs_active_bits = self.activeIntBits(bin_op.rhs); |
| 4455 | const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2); | 4477 | const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2); |
| 4456 | const src_ty = try mod.intType(dst_info.signedness, src_bits); | 4478 | const src_ty = try pt.intType(dst_info.signedness, src_bits); |
| 4457 | if (src_bits > 64 and src_bits <= 128 and | 4479 | if (src_bits > 64 and src_bits <= 128 and |
| 4458 | dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { | 4480 | dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { |
| 4459 | .signed => { | 4481 | .signed => { |
| 4460 | const ptr_c_int = try mod.singleMutPtrType(Type.c_int); | 4482 | const ptr_c_int = try pt.singleMutPtrType(Type.c_int); |
| 4461 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); | 4483 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); |
| 4462 | const result = try self.genCall(.{ .lib = .{ | 4484 | const result = try self.genCall(.{ .lib = .{ |
| 4463 | .return_type = .i128_type, | 4485 | .return_type = .i128_type, |
| ... | @@ -4472,7 +4494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4472,7 +4494,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4472 | const dst_mcv = try self.allocRegOrMem(inst, false); | 4494 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4473 | try self.genSetMem( | 4495 | try self.genSetMem( |
| 4474 | .{ .frame = dst_mcv.load_frame.index }, | 4496 | .{ .frame = dst_mcv.load_frame.index }, |
| 4475 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4497 | @intCast(tuple_ty.structFieldOffset(0, pt)), |
| 4476 | tuple_ty.structFieldType(0, mod), | 4498 | tuple_ty.structFieldType(0, mod), |
| 4477 | result, | 4499 | result, |
| 4478 | .{}, | 4500 | .{}, |
| ... | @@ -4484,7 +4506,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4484,7 +4506,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4484 | ); | 4506 | ); |
| 4485 | try self.genSetMem( | 4507 | try self.genSetMem( |
| 4486 | .{ .frame = dst_mcv.load_frame.index }, | 4508 | .{ .frame = dst_mcv.load_frame.index }, |
| 4487 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4509 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4488 | tuple_ty.structFieldType(1, mod), | 4510 | tuple_ty.structFieldType(1, mod), |
| 4489 | .{ .eflags = .ne }, | 4511 | .{ .eflags = .ne }, |
| 4490 | .{}, | 4512 | .{}, |
| ... | @@ -4596,14 +4618,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4596,14 +4618,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4596 | const dst_mcv = try self.allocRegOrMem(inst, false); | 4618 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4597 | try self.genSetMem( | 4619 | try self.genSetMem( |
| 4598 | .{ .frame = dst_mcv.load_frame.index }, | 4620 | .{ .frame = dst_mcv.load_frame.index }, |
| 4599 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4621 | @intCast(tuple_ty.structFieldOffset(0, pt)), |
| 4600 | tuple_ty.structFieldType(0, mod), | 4622 | tuple_ty.structFieldType(0, mod), |
| 4601 | .{ .register_pair = .{ .rax, .rdx } }, | 4623 | .{ .register_pair = .{ .rax, .rdx } }, |
| 4602 | .{}, | 4624 | .{}, |
| 4603 | ); | 4625 | ); |
| 4604 | try self.genSetMem( | 4626 | try self.genSetMem( |
| 4605 | .{ .frame = dst_mcv.load_frame.index }, | 4627 | .{ .frame = dst_mcv.load_frame.index }, |
| 4606 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4628 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4607 | tuple_ty.structFieldType(1, mod), | 4629 | tuple_ty.structFieldType(1, mod), |
| 4608 | .{ .register = tmp_regs[1] }, | 4630 | .{ .register = tmp_regs[1] }, |
| 4609 | .{}, | 4631 | .{}, |
| ... | @@ -4636,7 +4658,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4636,7 +4658,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4636 | self.eflags_inst = inst; | 4658 | self.eflags_inst = inst; |
| 4637 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; | 4659 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; |
| 4638 | } else { | 4660 | } else { |
| 4639 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4661 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4640 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 4662 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4641 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4663 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4642 | }, | 4664 | }, |
| ... | @@ -4644,21 +4666,21 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4644,21 +4666,21 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4644 | // For now, this is the only supported multiply that doesn't fit in a register. | 4666 | // For now, this is the only supported multiply that doesn't fit in a register. |
| 4645 | if (dst_info.bits > 128 or src_bits != 64) | 4667 | if (dst_info.bits > 128 or src_bits != 64) |
| 4646 | return self.fail("TODO implement airWithOverflow from {} to {}", .{ | 4668 | return self.fail("TODO implement airWithOverflow from {} to {}", .{ |
| 4647 | src_ty.fmt(mod), dst_ty.fmt(mod), | 4669 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 4648 | }); | 4670 | }); |
| 4649 | 4671 | ||
| 4650 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, mod)); | 4672 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); |
| 4651 | if (dst_info.bits >= lhs_active_bits + rhs_active_bits) { | 4673 | if (dst_info.bits >= lhs_active_bits + rhs_active_bits) { |
| 4652 | try self.genSetMem( | 4674 | try self.genSetMem( |
| 4653 | .{ .frame = frame_index }, | 4675 | .{ .frame = frame_index }, |
| 4654 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4676 | @intCast(tuple_ty.structFieldOffset(0, pt)), |
| 4655 | tuple_ty.structFieldType(0, mod), | 4677 | tuple_ty.structFieldType(0, mod), |
| 4656 | partial_mcv, | 4678 | partial_mcv, |
| 4657 | .{}, | 4679 | .{}, |
| 4658 | ); | 4680 | ); |
| 4659 | try self.genSetMem( | 4681 | try self.genSetMem( |
| 4660 | .{ .frame = frame_index }, | 4682 | .{ .frame = frame_index }, |
| 4661 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4683 | @intCast(tuple_ty.structFieldOffset(1, pt)), |
| 4662 | tuple_ty.structFieldType(1, mod), | 4684 | tuple_ty.structFieldType(1, mod), |
| 4663 | .{ .immediate = 0 }, // cc being set is impossible | 4685 | .{ .immediate = 0 }, // cc being set is impossible |
| 4664 | .{}, | 4686 | .{}, |
| ... | @@ -4682,8 +4704,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4682,8 +4704,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4682 | /// Clobbers .rax and .rdx registers. | 4704 | /// Clobbers .rax and .rdx registers. |
| 4683 | /// Quotient is saved in .rax and remainder in .rdx. | 4705 | /// Quotient is saved in .rax and remainder in .rdx. |
| 4684 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { | 4706 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { |
| 4685 | const mod = self.bin_file.comp.module.?; | 4707 | const pt = self.pt; |
| 4686 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 4708 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 4687 | const bit_size: u32 = @intCast(self.regBitSize(ty)); | 4709 | const bit_size: u32 = @intCast(self.regBitSize(ty)); |
| 4688 | if (abi_size > 8) { | 4710 | if (abi_size > 8) { |
| 4689 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); | 4711 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); |
| ... | @@ -4732,8 +4754,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -4732,8 +4754,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 4732 | /// Always returns a register. | 4754 | /// Always returns a register. |
| 4733 | /// Clobbers .rax and .rdx registers. | 4755 | /// Clobbers .rax and .rdx registers. |
| 4734 | fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue { | 4756 | fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue { |
| 4735 | const mod = self.bin_file.comp.module.?; | 4757 | const pt = self.pt; |
| 4736 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 4758 | const mod = pt.zcu; |
| 4759 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | ||
| 4737 | const int_info = ty.intInfo(mod); | 4760 | const int_info = ty.intInfo(mod); |
| 4738 | const dividend = switch (lhs) { | 4761 | const dividend = switch (lhs) { |
| 4739 | .register => |reg| reg, | 4762 | .register => |reg| reg, |
| ... | @@ -4784,7 +4807,8 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -4784,7 +4807,8 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 4784 | } | 4807 | } |
| 4785 | 4808 | ||
| 4786 | fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | 4809 | fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4787 | const mod = self.bin_file.comp.module.?; | 4810 | const pt = self.pt; |
| 4811 | const mod = pt.zcu; | ||
| 4788 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4812 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4789 | 4813 | ||
| 4790 | const air_tags = self.air.instructions.items(.tag); | 4814 | const air_tags = self.air.instructions.items(.tag); |
| ... | @@ -4811,7 +4835,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4811,7 +4835,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4811 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 4835 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 4812 | defer self.register_manager.unlockReg(tmp_lock); | 4836 | defer self.register_manager.unlockReg(tmp_lock); |
| 4813 | 4837 | ||
| 4814 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(mod)); | 4838 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(pt)); |
| 4815 | const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty; | 4839 | const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty; |
| 4816 | const off = frame_addr.off + (lhs_bits - 1) / 64 * 8; | 4840 | const off = frame_addr.off + (lhs_bits - 1) / 64 * 8; |
| 4817 | try self.genSetReg( | 4841 | try self.genSetReg( |
| ... | @@ -4922,11 +4946,11 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4922,11 +4946,11 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4922 | .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_q, .sll } else null, | 4946 | .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_q, .sll } else null, |
| 4923 | }, | 4947 | }, |
| 4924 | }, | 4948 | }, |
| 4925 | })) |mir_tag| if (try self.air.value(bin_op.rhs, mod)) |rhs_val| { | 4949 | })) |mir_tag| if (try self.air.value(bin_op.rhs, pt)) |rhs_val| { |
| 4926 | switch (mod.intern_pool.indexToKey(rhs_val.toIntern())) { | 4950 | switch (mod.intern_pool.indexToKey(rhs_val.toIntern())) { |
| 4927 | .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) { | 4951 | .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) { |
| 4928 | .repeated_elem => |rhs_elem| { | 4952 | .repeated_elem => |rhs_elem| { |
| 4929 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 4953 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); |
| 4930 | 4954 | ||
| 4931 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 4955 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 4932 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and | 4956 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and |
| ... | @@ -4946,7 +4970,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4946,7 +4970,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4946 | self.register_manager.unlockReg(lock); | 4970 | self.register_manager.unlockReg(lock); |
| 4947 | 4971 | ||
| 4948 | const shift_imm = | 4972 | const shift_imm = |
| 4949 | Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(mod))); | 4973 | Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(pt))); |
| 4950 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate( | 4974 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate( |
| 4951 | mir_tag, | 4975 | mir_tag, |
| 4952 | registerAlias(dst_reg, abi_size), | 4976 | registerAlias(dst_reg, abi_size), |
| ... | @@ -4968,7 +4992,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4968,7 +4992,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4968 | } | 4992 | } |
| 4969 | } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) { | 4993 | } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) { |
| 4970 | .splat => { | 4994 | .splat => { |
| 4971 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 4995 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); |
| 4972 | 4996 | ||
| 4973 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 4997 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 4974 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and | 4998 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and |
| ... | @@ -4991,13 +5015,13 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4991,13 +5015,13 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4991 | const shift_lock = self.register_manager.lockRegAssumeUnused(shift_reg); | 5015 | const shift_lock = self.register_manager.lockRegAssumeUnused(shift_reg); |
| 4992 | defer self.register_manager.unlockReg(shift_lock); | 5016 | defer self.register_manager.unlockReg(shift_lock); |
| 4993 | 5017 | ||
| 4994 | const mask_ty = try mod.vectorType(.{ .len = 16, .child = .u8_type }); | 5018 | const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type }); |
| 4995 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 5019 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 4996 | .ty = mask_ty.toIntern(), | 5020 | .ty = mask_ty.toIntern(), |
| 4997 | .storage = .{ .elems = &([1]InternPool.Index{ | 5021 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 4998 | (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(), | 5022 | (try rhs_ty.childType(mod).maxIntScalar(pt, Type.u8)).toIntern(), |
| 4999 | } ++ [1]InternPool.Index{ | 5023 | } ++ [1]InternPool.Index{ |
| 5000 | (try mod.intValue(Type.u8, 0)).toIntern(), | 5024 | (try pt.intValue(Type.u8, 0)).toIntern(), |
| 5001 | } ** 15) }, | 5025 | } ** 15) }, |
| 5002 | } }))); | 5026 | } }))); |
| 5003 | const mask_addr_reg = | 5027 | const mask_addr_reg = |
| ... | @@ -5045,7 +5069,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5045,7 +5069,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5045 | }, | 5069 | }, |
| 5046 | else => {}, | 5070 | else => {}, |
| 5047 | } | 5071 | } |
| 5048 | return self.fail("TODO implement airShlShrBinOp for {}", .{lhs_ty.fmt(mod)}); | 5072 | return self.fail("TODO implement airShlShrBinOp for {}", .{lhs_ty.fmt(pt)}); |
| 5049 | }; | 5073 | }; |
| 5050 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 5074 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5051 | } | 5075 | } |
| ... | @@ -5058,11 +5082,11 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5058,11 +5082,11 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 5058 | } | 5082 | } |
| 5059 | 5083 | ||
| 5060 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { | 5084 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5061 | const mod = self.bin_file.comp.module.?; | 5085 | const pt = self.pt; |
| 5062 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5086 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5063 | const result: MCValue = result: { | 5087 | const result: MCValue = result: { |
| 5064 | const pl_ty = self.typeOfIndex(inst); | 5088 | const pl_ty = self.typeOfIndex(inst); |
| 5065 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 5089 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 5066 | 5090 | ||
| 5067 | const opt_mcv = try self.resolveInst(ty_op.operand); | 5091 | const opt_mcv = try self.resolveInst(ty_op.operand); |
| 5068 | if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { | 5092 | if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { |
| ... | @@ -5104,7 +5128,8 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5104,7 +5128,8 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5104 | } | 5128 | } |
| 5105 | 5129 | ||
| 5106 | fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | 5130 | fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5107 | const mod = self.bin_file.comp.module.?; | 5131 | const pt = self.pt; |
| 5132 | const mod = pt.zcu; | ||
| 5108 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5133 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5109 | const result = result: { | 5134 | const result = result: { |
| 5110 | const dst_ty = self.typeOfIndex(inst); | 5135 | const dst_ty = self.typeOfIndex(inst); |
| ... | @@ -5130,7 +5155,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5130,7 +5155,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5130 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 5155 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 5131 | 5156 | ||
| 5132 | const pl_ty = dst_ty.childType(mod); | 5157 | const pl_ty = dst_ty.childType(mod); |
| 5133 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); | 5158 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); |
| 5134 | try self.genSetMem( | 5159 | try self.genSetMem( |
| 5135 | .{ .reg = dst_mcv.getReg().? }, | 5160 | .{ .reg = dst_mcv.getReg().? }, |
| 5136 | pl_abi_size, | 5161 | pl_abi_size, |
| ... | @@ -5144,7 +5169,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5144,7 +5169,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5144 | } | 5169 | } |
| 5145 | 5170 | ||
| 5146 | fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 5171 | fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5147 | const mod = self.bin_file.comp.module.?; | 5172 | const pt = self.pt; |
| 5173 | const mod = pt.zcu; | ||
| 5148 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5174 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5149 | const err_union_ty = self.typeOf(ty_op.operand); | 5175 | const err_union_ty = self.typeOf(ty_op.operand); |
| 5150 | const err_ty = err_union_ty.errorUnionSet(mod); | 5176 | const err_ty = err_union_ty.errorUnionSet(mod); |
| ... | @@ -5156,11 +5182,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5156,11 +5182,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5156 | break :result MCValue{ .immediate = 0 }; | 5182 | break :result MCValue{ .immediate = 0 }; |
| 5157 | } | 5183 | } |
| 5158 | 5184 | ||
| 5159 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5185 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5160 | break :result operand; | 5186 | break :result operand; |
| 5161 | } | 5187 | } |
| 5162 | 5188 | ||
| 5163 | const err_off = errUnionErrorOffset(payload_ty, mod); | 5189 | const err_off = errUnionErrorOffset(payload_ty, pt); |
| 5164 | switch (operand) { | 5190 | switch (operand) { |
| 5165 | .register => |reg| { | 5191 | .register => |reg| { |
| 5166 | // TODO reuse operand | 5192 | // TODO reuse operand |
| ... | @@ -5197,7 +5223,8 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5197,7 +5223,8 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5197 | 5223 | ||
| 5198 | // *(E!T) -> E | 5224 | // *(E!T) -> E |
| 5199 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 5225 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5200 | const mod = self.bin_file.comp.module.?; | 5226 | const pt = self.pt; |
| 5227 | const mod = pt.zcu; | ||
| 5201 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5228 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5202 | 5229 | ||
| 5203 | const src_ty = self.typeOf(ty_op.operand); | 5230 | const src_ty = self.typeOf(ty_op.operand); |
| ... | @@ -5217,8 +5244,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5217,8 +5244,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5217 | const eu_ty = src_ty.childType(mod); | 5244 | const eu_ty = src_ty.childType(mod); |
| 5218 | const pl_ty = eu_ty.errorUnionPayload(mod); | 5245 | const pl_ty = eu_ty.errorUnionPayload(mod); |
| 5219 | const err_ty = eu_ty.errorUnionSet(mod); | 5246 | const err_ty = eu_ty.errorUnionSet(mod); |
| 5220 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5247 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 5221 | const err_abi_size: u32 = @intCast(err_ty.abiSize(mod)); | 5248 | const err_abi_size: u32 = @intCast(err_ty.abiSize(pt)); |
| 5222 | try self.asmRegisterMemory( | 5249 | try self.asmRegisterMemory( |
| 5223 | .{ ._, .mov }, | 5250 | .{ ._, .mov }, |
| 5224 | registerAlias(dst_reg, err_abi_size), | 5251 | registerAlias(dst_reg, err_abi_size), |
| ... | @@ -5244,7 +5271,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5244,7 +5271,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5244 | } | 5271 | } |
| 5245 | 5272 | ||
| 5246 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | 5273 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5247 | const mod = self.bin_file.comp.module.?; | 5274 | const pt = self.pt; |
| 5275 | const mod = pt.zcu; | ||
| 5248 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5276 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5249 | const result: MCValue = result: { | 5277 | const result: MCValue = result: { |
| 5250 | const src_ty = self.typeOf(ty_op.operand); | 5278 | const src_ty = self.typeOf(ty_op.operand); |
| ... | @@ -5259,8 +5287,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5259,8 +5287,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5259 | const eu_ty = src_ty.childType(mod); | 5287 | const eu_ty = src_ty.childType(mod); |
| 5260 | const pl_ty = eu_ty.errorUnionPayload(mod); | 5288 | const pl_ty = eu_ty.errorUnionPayload(mod); |
| 5261 | const err_ty = eu_ty.errorUnionSet(mod); | 5289 | const err_ty = eu_ty.errorUnionSet(mod); |
| 5262 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5290 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 5263 | const err_abi_size: u32 = @intCast(err_ty.abiSize(mod)); | 5291 | const err_abi_size: u32 = @intCast(err_ty.abiSize(pt)); |
| 5264 | try self.asmMemoryImmediate( | 5292 | try self.asmMemoryImmediate( |
| 5265 | .{ ._, .mov }, | 5293 | .{ ._, .mov }, |
| 5266 | .{ | 5294 | .{ |
| ... | @@ -5283,8 +5311,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5283,8 +5311,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5283 | const dst_lock = self.register_manager.lockReg(dst_reg); | 5311 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5284 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 5312 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5285 | 5313 | ||
| 5286 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | 5314 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 5287 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 5315 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 5288 | try self.asmRegisterMemory( | 5316 | try self.asmRegisterMemory( |
| 5289 | .{ ._, .lea }, | 5317 | .{ ._, .lea }, |
| 5290 | registerAlias(dst_reg, dst_abi_size), | 5318 | registerAlias(dst_reg, dst_abi_size), |
| ... | @@ -5304,13 +5332,14 @@ fn genUnwrapErrUnionPayloadMir( | ... | @@ -5304,13 +5332,14 @@ fn genUnwrapErrUnionPayloadMir( |
| 5304 | err_union_ty: Type, | 5332 | err_union_ty: Type, |
| 5305 | err_union: MCValue, | 5333 | err_union: MCValue, |
| 5306 | ) !MCValue { | 5334 | ) !MCValue { |
| 5307 | const mod = self.bin_file.comp.module.?; | 5335 | const pt = self.pt; |
| 5336 | const mod = pt.zcu; | ||
| 5308 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 5337 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 5309 | 5338 | ||
| 5310 | const result: MCValue = result: { | 5339 | const result: MCValue = result: { |
| 5311 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 5340 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 5312 | 5341 | ||
| 5313 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, mod)); | 5342 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt)); |
| 5314 | switch (err_union) { | 5343 | switch (err_union) { |
| 5315 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ | 5344 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ |
| 5316 | .index = frame_addr.index, | 5345 | .index = frame_addr.index, |
| ... | @@ -5353,12 +5382,13 @@ fn genUnwrapErrUnionPayloadPtrMir( | ... | @@ -5353,12 +5382,13 @@ fn genUnwrapErrUnionPayloadPtrMir( |
| 5353 | ptr_ty: Type, | 5382 | ptr_ty: Type, |
| 5354 | ptr_mcv: MCValue, | 5383 | ptr_mcv: MCValue, |
| 5355 | ) !MCValue { | 5384 | ) !MCValue { |
| 5356 | const mod = self.bin_file.comp.module.?; | 5385 | const pt = self.pt; |
| 5386 | const mod = pt.zcu; | ||
| 5357 | const err_union_ty = ptr_ty.childType(mod); | 5387 | const err_union_ty = ptr_ty.childType(mod); |
| 5358 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 5388 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 5359 | 5389 | ||
| 5360 | const result: MCValue = result: { | 5390 | const result: MCValue = result: { |
| 5361 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | 5391 | const payload_off = errUnionPayloadOffset(payload_ty, pt); |
| 5362 | const result_mcv: MCValue = if (maybe_inst) |inst| | 5392 | const result_mcv: MCValue = if (maybe_inst) |inst| |
| 5363 | try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv) | 5393 | try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv) |
| 5364 | else | 5394 | else |
| ... | @@ -5387,11 +5417,12 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5387,11 +5417,12 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 5387 | } | 5417 | } |
| 5388 | 5418 | ||
| 5389 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | 5419 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5390 | const mod = self.bin_file.comp.module.?; | 5420 | const pt = self.pt; |
| 5421 | const mod = pt.zcu; | ||
| 5391 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5422 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5392 | const result: MCValue = result: { | 5423 | const result: MCValue = result: { |
| 5393 | const pl_ty = self.typeOf(ty_op.operand); | 5424 | const pl_ty = self.typeOf(ty_op.operand); |
| 5394 | if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 }; | 5425 | if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 }; |
| 5395 | 5426 | ||
| 5396 | const opt_ty = self.typeOfIndex(inst); | 5427 | const opt_ty = self.typeOfIndex(inst); |
| 5397 | const pl_mcv = try self.resolveInst(ty_op.operand); | 5428 | const pl_mcv = try self.resolveInst(ty_op.operand); |
| ... | @@ -5408,7 +5439,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5408,7 +5439,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5408 | try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{}); | 5439 | try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{}); |
| 5409 | 5440 | ||
| 5410 | if (!same_repr) { | 5441 | if (!same_repr) { |
| 5411 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); | 5442 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); |
| 5412 | switch (opt_mcv) { | 5443 | switch (opt_mcv) { |
| 5413 | else => unreachable, | 5444 | else => unreachable, |
| 5414 | 5445 | ||
| ... | @@ -5441,7 +5472,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5441,7 +5472,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5441 | 5472 | ||
| 5442 | /// T to E!T | 5473 | /// T to E!T |
| 5443 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | 5474 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5444 | const mod = self.bin_file.comp.module.?; | 5475 | const pt = self.pt; |
| 5476 | const mod = pt.zcu; | ||
| 5445 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5477 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5446 | 5478 | ||
| 5447 | const eu_ty = ty_op.ty.toType(); | 5479 | const eu_ty = ty_op.ty.toType(); |
| ... | @@ -5450,11 +5482,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5450,11 +5482,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5450 | const operand = try self.resolveInst(ty_op.operand); | 5482 | const operand = try self.resolveInst(ty_op.operand); |
| 5451 | 5483 | ||
| 5452 | const result: MCValue = result: { | 5484 | const result: MCValue = result: { |
| 5453 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 }; | 5485 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 }; |
| 5454 | 5486 | ||
| 5455 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); | 5487 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); |
| 5456 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | 5488 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 5457 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5489 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 5458 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); | 5490 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); |
| 5459 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{}); | 5491 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{}); |
| 5460 | break :result .{ .load_frame = .{ .index = frame_index } }; | 5492 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -5464,7 +5496,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5464,7 +5496,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5464 | 5496 | ||
| 5465 | /// E to E!T | 5497 | /// E to E!T |
| 5466 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 5498 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5467 | const mod = self.bin_file.comp.module.?; | 5499 | const pt = self.pt; |
| 5500 | const mod = pt.zcu; | ||
| 5468 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5501 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5469 | 5502 | ||
| 5470 | const eu_ty = ty_op.ty.toType(); | 5503 | const eu_ty = ty_op.ty.toType(); |
| ... | @@ -5472,11 +5505,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5472,11 +5505,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5472 | const err_ty = eu_ty.errorUnionSet(mod); | 5505 | const err_ty = eu_ty.errorUnionSet(mod); |
| 5473 | 5506 | ||
| 5474 | const result: MCValue = result: { | 5507 | const result: MCValue = result: { |
| 5475 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand); | 5508 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try self.resolveInst(ty_op.operand); |
| 5476 | 5509 | ||
| 5477 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); | 5510 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); |
| 5478 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | 5511 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); |
| 5479 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5512 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); |
| 5480 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); | 5513 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); |
| 5481 | const operand = try self.resolveInst(ty_op.operand); | 5514 | const operand = try self.resolveInst(ty_op.operand); |
| 5482 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{}); | 5515 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{}); |
| ... | @@ -5523,7 +5556,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5523,7 +5556,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5523 | } | 5556 | } |
| 5524 | 5557 | ||
| 5525 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { | 5558 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5526 | const mod = self.bin_file.comp.module.?; | 5559 | const pt = self.pt; |
| 5527 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5560 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5528 | 5561 | ||
| 5529 | const src_ty = self.typeOf(ty_op.operand); | 5562 | const src_ty = self.typeOf(ty_op.operand); |
| ... | @@ -5544,7 +5577,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5544,7 +5577,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5544 | const dst_lock = self.register_manager.lockReg(dst_reg); | 5577 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5545 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 5578 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5546 | 5579 | ||
| 5547 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 5580 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 5548 | try self.asmRegisterMemory( | 5581 | try self.asmRegisterMemory( |
| 5549 | .{ ._, .lea }, | 5582 | .{ ._, .lea }, |
| 5550 | registerAlias(dst_reg, dst_abi_size), | 5583 | registerAlias(dst_reg, dst_abi_size), |
| ... | @@ -5591,7 +5624,8 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi | ... | @@ -5591,7 +5624,8 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi |
| 5591 | } | 5624 | } |
| 5592 | 5625 | ||
| 5593 | fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | 5626 | fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5594 | const mod = self.bin_file.comp.module.?; | 5627 | const pt = self.pt; |
| 5628 | const mod = pt.zcu; | ||
| 5595 | const slice_ty = self.typeOf(lhs); | 5629 | const slice_ty = self.typeOf(lhs); |
| 5596 | const slice_mcv = try self.resolveInst(lhs); | 5630 | const slice_mcv = try self.resolveInst(lhs); |
| 5597 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { | 5631 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { |
| ... | @@ -5601,7 +5635,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -5601,7 +5635,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5601 | defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock); | 5635 | defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock); |
| 5602 | 5636 | ||
| 5603 | const elem_ty = slice_ty.childType(mod); | 5637 | const elem_ty = slice_ty.childType(mod); |
| 5604 | const elem_size = elem_ty.abiSize(mod); | 5638 | const elem_size = elem_ty.abiSize(pt); |
| 5605 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | 5639 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| 5606 | 5640 | ||
| 5607 | const index_ty = self.typeOf(rhs); | 5641 | const index_ty = self.typeOf(rhs); |
| ... | @@ -5627,12 +5661,13 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -5627,12 +5661,13 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5627 | } | 5661 | } |
| 5628 | 5662 | ||
| 5629 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | 5663 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5630 | const mod = self.bin_file.comp.module.?; | 5664 | const pt = self.pt; |
| 5665 | const mod = pt.zcu; | ||
| 5631 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5666 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5632 | 5667 | ||
| 5633 | const result: MCValue = result: { | 5668 | const result: MCValue = result: { |
| 5634 | const elem_ty = self.typeOfIndex(inst); | 5669 | const elem_ty = self.typeOfIndex(inst); |
| 5635 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 5670 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 5636 | 5671 | ||
| 5637 | const slice_ty = self.typeOf(bin_op.lhs); | 5672 | const slice_ty = self.typeOf(bin_op.lhs); |
| 5638 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | 5673 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| ... | @@ -5652,7 +5687,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5652,7 +5687,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5652 | } | 5687 | } |
| 5653 | 5688 | ||
| 5654 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | 5689 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5655 | const mod = self.bin_file.comp.module.?; | 5690 | const pt = self.pt; |
| 5691 | const mod = pt.zcu; | ||
| 5656 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5692 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5657 | 5693 | ||
| 5658 | const result: MCValue = result: { | 5694 | const result: MCValue = result: { |
| ... | @@ -5675,7 +5711,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5675,7 +5711,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5675 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); | 5711 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); |
| 5676 | 5712 | ||
| 5677 | try self.spillEflagsIfOccupied(); | 5713 | try self.spillEflagsIfOccupied(); |
| 5678 | if (array_ty.isVector(mod) and elem_ty.bitSize(mod) == 1) { | 5714 | if (array_ty.isVector(mod) and elem_ty.bitSize(pt) == 1) { |
| 5679 | const index_reg = switch (index_mcv) { | 5715 | const index_reg = switch (index_mcv) { |
| 5680 | .register => |reg| reg, | 5716 | .register => |reg| reg, |
| 5681 | else => try self.copyToTmpRegister(index_ty, index_mcv), | 5717 | else => try self.copyToTmpRegister(index_ty, index_mcv), |
| ... | @@ -5688,7 +5724,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5688,7 +5724,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5688 | index_reg.to64(), | 5724 | index_reg.to64(), |
| 5689 | ), | 5725 | ), |
| 5690 | .sse => { | 5726 | .sse => { |
| 5691 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); | 5727 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); |
| 5692 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); | 5728 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 5693 | try self.asmMemoryRegister( | 5729 | try self.asmMemoryRegister( |
| 5694 | .{ ._, .bt }, | 5730 | .{ ._, .bt }, |
| ... | @@ -5717,7 +5753,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5717,7 +5753,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5717 | index_reg.to64(), | 5753 | index_reg.to64(), |
| 5718 | ), | 5754 | ), |
| 5719 | else => return self.fail("TODO airArrayElemVal for {s} of {}", .{ | 5755 | else => return self.fail("TODO airArrayElemVal for {s} of {}", .{ |
| 5720 | @tagName(array_mcv), array_ty.fmt(mod), | 5756 | @tagName(array_mcv), array_ty.fmt(pt), |
| 5721 | }), | 5757 | }), |
| 5722 | } | 5758 | } |
| 5723 | 5759 | ||
| ... | @@ -5726,14 +5762,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5726,14 +5762,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5726 | break :result .{ .register = dst_reg }; | 5762 | break :result .{ .register = dst_reg }; |
| 5727 | } | 5763 | } |
| 5728 | 5764 | ||
| 5729 | const elem_abi_size = elem_ty.abiSize(mod); | 5765 | const elem_abi_size = elem_ty.abiSize(pt); |
| 5730 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 5766 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 5731 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 5767 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 5732 | defer self.register_manager.unlockReg(addr_lock); | 5768 | defer self.register_manager.unlockReg(addr_lock); |
| 5733 | 5769 | ||
| 5734 | switch (array_mcv) { | 5770 | switch (array_mcv) { |
| 5735 | .register => { | 5771 | .register => { |
| 5736 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); | 5772 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); |
| 5737 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); | 5773 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 5738 | try self.asmRegisterMemory( | 5774 | try self.asmRegisterMemory( |
| 5739 | .{ ._, .lea }, | 5775 | .{ ._, .lea }, |
| ... | @@ -5757,7 +5793,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5757,7 +5793,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5757 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}), | 5793 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}), |
| 5758 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, | 5794 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, |
| 5759 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ | 5795 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ |
| 5760 | @tagName(array_mcv), array_ty.fmt(mod), | 5796 | @tagName(array_mcv), array_ty.fmt(pt), |
| 5761 | }), | 5797 | }), |
| 5762 | } | 5798 | } |
| 5763 | 5799 | ||
| ... | @@ -5781,7 +5817,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5781,7 +5817,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5781 | } | 5817 | } |
| 5782 | 5818 | ||
| 5783 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | 5819 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5784 | const mod = self.bin_file.comp.module.?; | 5820 | const pt = self.pt; |
| 5821 | const mod = pt.zcu; | ||
| 5785 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5822 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5786 | const ptr_ty = self.typeOf(bin_op.lhs); | 5823 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 5787 | 5824 | ||
| ... | @@ -5790,9 +5827,9 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5790,9 +5827,9 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5790 | 5827 | ||
| 5791 | const result = result: { | 5828 | const result = result: { |
| 5792 | const elem_ty = ptr_ty.elemType2(mod); | 5829 | const elem_ty = ptr_ty.elemType2(mod); |
| 5793 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 5830 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 5794 | 5831 | ||
| 5795 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); | 5832 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 5796 | const index_ty = self.typeOf(bin_op.rhs); | 5833 | const index_ty = self.typeOf(bin_op.rhs); |
| 5797 | const index_mcv = try self.resolveInst(bin_op.rhs); | 5834 | const index_mcv = try self.resolveInst(bin_op.rhs); |
| 5798 | const index_lock = switch (index_mcv) { | 5835 | const index_lock = switch (index_mcv) { |
| ... | @@ -5831,7 +5868,8 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5831,7 +5868,8 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5831 | } | 5868 | } |
| 5832 | 5869 | ||
| 5833 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | 5870 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5834 | const mod = self.bin_file.comp.module.?; | 5871 | const pt = self.pt; |
| 5872 | const mod = pt.zcu; | ||
| 5835 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5873 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5836 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 5874 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 5837 | 5875 | ||
| ... | @@ -5854,7 +5892,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5854,7 +5892,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5854 | } | 5892 | } |
| 5855 | 5893 | ||
| 5856 | const elem_ty = base_ptr_ty.elemType2(mod); | 5894 | const elem_ty = base_ptr_ty.elemType2(mod); |
| 5857 | const elem_abi_size = elem_ty.abiSize(mod); | 5895 | const elem_abi_size = elem_ty.abiSize(pt); |
| 5858 | const index_ty = self.typeOf(extra.rhs); | 5896 | const index_ty = self.typeOf(extra.rhs); |
| 5859 | const index_mcv = try self.resolveInst(extra.rhs); | 5897 | const index_mcv = try self.resolveInst(extra.rhs); |
| 5860 | const index_lock: ?RegisterLock = switch (index_mcv) { | 5898 | const index_lock: ?RegisterLock = switch (index_mcv) { |
| ... | @@ -5876,12 +5914,13 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5876,12 +5914,13 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5876 | } | 5914 | } |
| 5877 | 5915 | ||
| 5878 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | 5916 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5879 | const mod = self.bin_file.comp.module.?; | 5917 | const pt = self.pt; |
| 5918 | const mod = pt.zcu; | ||
| 5880 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5919 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5881 | const ptr_union_ty = self.typeOf(bin_op.lhs); | 5920 | const ptr_union_ty = self.typeOf(bin_op.lhs); |
| 5882 | const union_ty = ptr_union_ty.childType(mod); | 5921 | const union_ty = ptr_union_ty.childType(mod); |
| 5883 | const tag_ty = self.typeOf(bin_op.rhs); | 5922 | const tag_ty = self.typeOf(bin_op.rhs); |
| 5884 | const layout = union_ty.unionGetLayout(mod); | 5923 | const layout = union_ty.unionGetLayout(pt); |
| 5885 | 5924 | ||
| 5886 | if (layout.tag_size == 0) { | 5925 | if (layout.tag_size == 0) { |
| 5887 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 5926 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -5913,19 +5952,19 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5913,19 +5952,19 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5913 | break :blk MCValue{ .register = reg }; | 5952 | break :blk MCValue{ .register = reg }; |
| 5914 | } else ptr; | 5953 | } else ptr; |
| 5915 | 5954 | ||
| 5916 | const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); | 5955 | const ptr_tag_ty = try pt.adjustPtrTypeChild(ptr_union_ty, tag_ty); |
| 5917 | try self.store(ptr_tag_ty, adjusted_ptr, tag, .{}); | 5956 | try self.store(ptr_tag_ty, adjusted_ptr, tag, .{}); |
| 5918 | 5957 | ||
| 5919 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 5958 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5920 | } | 5959 | } |
| 5921 | 5960 | ||
| 5922 | fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | 5961 | fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5923 | const mod = self.bin_file.comp.module.?; | 5962 | const pt = self.pt; |
| 5924 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5963 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5925 | 5964 | ||
| 5926 | const tag_ty = self.typeOfIndex(inst); | 5965 | const tag_ty = self.typeOfIndex(inst); |
| 5927 | const union_ty = self.typeOf(ty_op.operand); | 5966 | const union_ty = self.typeOf(ty_op.operand); |
| 5928 | const layout = union_ty.unionGetLayout(mod); | 5967 | const layout = union_ty.unionGetLayout(pt); |
| 5929 | 5968 | ||
| 5930 | if (layout.tag_size == 0) { | 5969 | if (layout.tag_size == 0) { |
| 5931 | return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none }); | 5970 | return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none }); |
| ... | @@ -5939,7 +5978,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5939,7 +5978,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5939 | }; | 5978 | }; |
| 5940 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); | 5979 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); |
| 5941 | 5980 | ||
| 5942 | const tag_abi_size = tag_ty.abiSize(mod); | 5981 | const tag_abi_size = tag_ty.abiSize(pt); |
| 5943 | const dst_mcv: MCValue = blk: { | 5982 | const dst_mcv: MCValue = blk: { |
| 5944 | switch (operand) { | 5983 | switch (operand) { |
| 5945 | .load_frame => |frame_addr| { | 5984 | .load_frame => |frame_addr| { |
| ... | @@ -5983,7 +6022,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5983,7 +6022,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5983 | } | 6022 | } |
| 5984 | 6023 | ||
| 5985 | fn airClz(self: *Self, inst: Air.Inst.Index) !void { | 6024 | fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 5986 | const mod = self.bin_file.comp.module.?; | 6025 | const pt = self.pt; |
| 6026 | const mod = pt.zcu; | ||
| 5987 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6027 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5988 | const result = result: { | 6028 | const result = result: { |
| 5989 | try self.spillEflagsIfOccupied(); | 6029 | try self.spillEflagsIfOccupied(); |
| ... | @@ -5991,7 +6031,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5991,7 +6031,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 5991 | const dst_ty = self.typeOfIndex(inst); | 6031 | const dst_ty = self.typeOfIndex(inst); |
| 5992 | const src_ty = self.typeOf(ty_op.operand); | 6032 | const src_ty = self.typeOf(ty_op.operand); |
| 5993 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{ | 6033 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{ |
| 5994 | src_ty.fmt(mod), | 6034 | src_ty.fmt(pt), |
| 5995 | }); | 6035 | }); |
| 5996 | 6036 | ||
| 5997 | const src_mcv = try self.resolveInst(ty_op.operand); | 6037 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | @@ -6010,8 +6050,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6010,8 +6050,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6010 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 6050 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 6011 | defer self.register_manager.unlockReg(dst_lock); | 6051 | defer self.register_manager.unlockReg(dst_lock); |
| 6012 | 6052 | ||
| 6013 | const abi_size: u31 = @intCast(src_ty.abiSize(mod)); | 6053 | const abi_size: u31 = @intCast(src_ty.abiSize(pt)); |
| 6014 | const src_bits: u31 = @intCast(src_ty.bitSize(mod)); | 6054 | const src_bits: u31 = @intCast(src_ty.bitSize(pt)); |
| 6015 | const has_lzcnt = self.hasFeature(.lzcnt); | 6055 | const has_lzcnt = self.hasFeature(.lzcnt); |
| 6016 | if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) { | 6056 | if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) { |
| 6017 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; | 6057 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| ... | @@ -6121,7 +6161,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6121,7 +6161,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6121 | } | 6161 | } |
| 6122 | 6162 | ||
| 6123 | assert(src_bits <= 64); | 6163 | assert(src_bits <= 64); |
| 6124 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2); | 6164 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2); |
| 6125 | if (math.isPowerOfTwo(src_bits)) { | 6165 | if (math.isPowerOfTwo(src_bits)) { |
| 6126 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ | 6166 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ |
| 6127 | .immediate = src_bits ^ (src_bits - 1), | 6167 | .immediate = src_bits ^ (src_bits - 1), |
| ... | @@ -6179,7 +6219,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6179,7 +6219,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6179 | } | 6219 | } |
| 6180 | 6220 | ||
| 6181 | fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | 6221 | fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6182 | const mod = self.bin_file.comp.module.?; | 6222 | const pt = self.pt; |
| 6223 | const mod = pt.zcu; | ||
| 6183 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6224 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6184 | const result = result: { | 6225 | const result = result: { |
| 6185 | try self.spillEflagsIfOccupied(); | 6226 | try self.spillEflagsIfOccupied(); |
| ... | @@ -6187,7 +6228,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6187,7 +6228,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6187 | const dst_ty = self.typeOfIndex(inst); | 6228 | const dst_ty = self.typeOfIndex(inst); |
| 6188 | const src_ty = self.typeOf(ty_op.operand); | 6229 | const src_ty = self.typeOf(ty_op.operand); |
| 6189 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{ | 6230 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{ |
| 6190 | src_ty.fmt(mod), | 6231 | src_ty.fmt(pt), |
| 6191 | }); | 6232 | }); |
| 6192 | 6233 | ||
| 6193 | const src_mcv = try self.resolveInst(ty_op.operand); | 6234 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | @@ -6206,8 +6247,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6206,8 +6247,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6206 | const dst_lock = self.register_manager.lockReg(dst_reg); | 6247 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 6207 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 6248 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 6208 | 6249 | ||
| 6209 | const abi_size: u31 = @intCast(src_ty.abiSize(mod)); | 6250 | const abi_size: u31 = @intCast(src_ty.abiSize(pt)); |
| 6210 | const src_bits: u31 = @intCast(src_ty.bitSize(mod)); | 6251 | const src_bits: u31 = @intCast(src_ty.bitSize(pt)); |
| 6211 | const has_bmi = self.hasFeature(.bmi); | 6252 | const has_bmi = self.hasFeature(.bmi); |
| 6212 | if (src_bits > @as(u32, if (has_bmi) 128 else 64)) { | 6253 | if (src_bits > @as(u32, if (has_bmi) 128 else 64)) { |
| 6213 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; | 6254 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| ... | @@ -6328,7 +6369,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6328,7 +6369,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6328 | try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg }); | 6369 | try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg }); |
| 6329 | } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv); | 6370 | } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv); |
| 6330 | 6371 | ||
| 6331 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2); | 6372 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2); |
| 6332 | try self.asmCmovccRegisterRegister( | 6373 | try self.asmCmovccRegisterRegister( |
| 6333 | .z, | 6374 | .z, |
| 6334 | registerAlias(dst_reg, cmov_abi_size), | 6375 | registerAlias(dst_reg, cmov_abi_size), |
| ... | @@ -6340,15 +6381,16 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6340,15 +6381,16 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6340 | } | 6381 | } |
| 6341 | 6382 | ||
| 6342 | fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { | 6383 | fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { |
| 6343 | const mod = self.bin_file.comp.module.?; | 6384 | const pt = self.pt; |
| 6385 | const mod = pt.zcu; | ||
| 6344 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6386 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6345 | const result: MCValue = result: { | 6387 | const result: MCValue = result: { |
| 6346 | try self.spillEflagsIfOccupied(); | 6388 | try self.spillEflagsIfOccupied(); |
| 6347 | 6389 | ||
| 6348 | const src_ty = self.typeOf(ty_op.operand); | 6390 | const src_ty = self.typeOf(ty_op.operand); |
| 6349 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 6391 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 6350 | if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 16) | 6392 | if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 16) |
| 6351 | return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(mod)}); | 6393 | return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(pt)}); |
| 6352 | const src_mcv = try self.resolveInst(ty_op.operand); | 6394 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6353 | 6395 | ||
| 6354 | const mat_src_mcv = switch (src_mcv) { | 6396 | const mat_src_mcv = switch (src_mcv) { |
| ... | @@ -6385,7 +6427,7 @@ fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6385,7 +6427,7 @@ fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { |
| 6385 | else | 6427 | else |
| 6386 | .{ .register = mat_src_mcv.register_pair[0] }, false); | 6428 | .{ .register = mat_src_mcv.register_pair[0] }, false); |
| 6387 | const src_info = src_ty.intInfo(mod); | 6429 | const src_info = src_ty.intInfo(mod); |
| 6388 | const hi_ty = try mod.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1); | 6430 | const hi_ty = try pt.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1); |
| 6389 | try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isMemory()) | 6431 | try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isMemory()) |
| 6390 | mat_src_mcv.address().offset(8).deref() | 6432 | mat_src_mcv.address().offset(8).deref() |
| 6391 | else | 6433 | else |
| ... | @@ -6403,16 +6445,16 @@ fn genPopCount( | ... | @@ -6403,16 +6445,16 @@ fn genPopCount( |
| 6403 | src_mcv: MCValue, | 6445 | src_mcv: MCValue, |
| 6404 | dst_contains_src: bool, | 6446 | dst_contains_src: bool, |
| 6405 | ) !void { | 6447 | ) !void { |
| 6406 | const mod = self.bin_file.comp.module.?; | 6448 | const pt = self.pt; |
| 6407 | 6449 | ||
| 6408 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 6450 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 6409 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( | 6451 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( |
| 6410 | .{ ._, .popcnt }, | 6452 | .{ ._, .popcnt }, |
| 6411 | if (src_abi_size > 1) src_ty else Type.u32, | 6453 | if (src_abi_size > 1) src_ty else Type.u32, |
| 6412 | .{ .register = dst_reg }, | 6454 | .{ .register = dst_reg }, |
| 6413 | if (src_abi_size > 1) src_mcv else src: { | 6455 | if (src_abi_size > 1) src_mcv else src: { |
| 6414 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); | 6456 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); |
| 6415 | try self.truncateRegister(try src_ty.toUnsigned(mod), dst_reg); | 6457 | try self.truncateRegister(try src_ty.toUnsigned(pt), dst_reg); |
| 6416 | break :src .{ .register = dst_reg }; | 6458 | break :src .{ .register = dst_reg }; |
| 6417 | }, | 6459 | }, |
| 6418 | ); | 6460 | ); |
| ... | @@ -6495,13 +6537,14 @@ fn genByteSwap( | ... | @@ -6495,13 +6537,14 @@ fn genByteSwap( |
| 6495 | src_mcv: MCValue, | 6537 | src_mcv: MCValue, |
| 6496 | mem_ok: bool, | 6538 | mem_ok: bool, |
| 6497 | ) !MCValue { | 6539 | ) !MCValue { |
| 6498 | const mod = self.bin_file.comp.module.?; | 6540 | const pt = self.pt; |
| 6541 | const mod = pt.zcu; | ||
| 6499 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6542 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6500 | const has_movbe = self.hasFeature(.movbe); | 6543 | const has_movbe = self.hasFeature(.movbe); |
| 6501 | 6544 | ||
| 6502 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail( | 6545 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail( |
| 6503 | "TODO implement genByteSwap for {}", | 6546 | "TODO implement genByteSwap for {}", |
| 6504 | .{src_ty.fmt(mod)}, | 6547 | .{src_ty.fmt(pt)}, |
| 6505 | ); | 6548 | ); |
| 6506 | 6549 | ||
| 6507 | const src_lock = switch (src_mcv) { | 6550 | const src_lock = switch (src_mcv) { |
| ... | @@ -6510,7 +6553,7 @@ fn genByteSwap( | ... | @@ -6510,7 +6553,7 @@ fn genByteSwap( |
| 6510 | }; | 6553 | }; |
| 6511 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 6554 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 6512 | 6555 | ||
| 6513 | const abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 6556 | const abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 6514 | switch (abi_size) { | 6557 | switch (abi_size) { |
| 6515 | 0 => unreachable, | 6558 | 0 => unreachable, |
| 6516 | 1 => return if ((mem_ok or src_mcv.isRegister()) and | 6559 | 1 => return if ((mem_ok or src_mcv.isRegister()) and |
| ... | @@ -6658,11 +6701,12 @@ fn genByteSwap( | ... | @@ -6658,11 +6701,12 @@ fn genByteSwap( |
| 6658 | } | 6701 | } |
| 6659 | 6702 | ||
| 6660 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { | 6703 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 6661 | const mod = self.bin_file.comp.module.?; | 6704 | const pt = self.pt; |
| 6705 | const mod = pt.zcu; | ||
| 6662 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6706 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6663 | 6707 | ||
| 6664 | const src_ty = self.typeOf(ty_op.operand); | 6708 | const src_ty = self.typeOf(ty_op.operand); |
| 6665 | const src_bits: u32 = @intCast(src_ty.bitSize(mod)); | 6709 | const src_bits: u32 = @intCast(src_ty.bitSize(pt)); |
| 6666 | const src_mcv = try self.resolveInst(ty_op.operand); | 6710 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6667 | 6711 | ||
| 6668 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true); | 6712 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true); |
| ... | @@ -6674,18 +6718,19 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6674,18 +6718,19 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 6674 | src_ty, | 6718 | src_ty, |
| 6675 | dst_mcv, | 6719 | dst_mcv, |
| 6676 | if (src_bits > 256) Type.u16 else Type.u8, | 6720 | if (src_bits > 256) Type.u16 else Type.u8, |
| 6677 | .{ .immediate = src_ty.abiSize(mod) * 8 - src_bits }, | 6721 | .{ .immediate = src_ty.abiSize(pt) * 8 - src_bits }, |
| 6678 | ); | 6722 | ); |
| 6679 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 6723 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 6680 | } | 6724 | } |
| 6681 | 6725 | ||
| 6682 | fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | 6726 | fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6683 | const mod = self.bin_file.comp.module.?; | 6727 | const pt = self.pt; |
| 6728 | const mod = pt.zcu; | ||
| 6684 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6729 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6685 | 6730 | ||
| 6686 | const src_ty = self.typeOf(ty_op.operand); | 6731 | const src_ty = self.typeOf(ty_op.operand); |
| 6687 | const abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 6732 | const abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 6688 | const bit_size: u32 = @intCast(src_ty.bitSize(mod)); | 6733 | const bit_size: u32 = @intCast(src_ty.bitSize(pt)); |
| 6689 | const src_mcv = try self.resolveInst(ty_op.operand); | 6734 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6690 | 6735 | ||
| 6691 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false); | 6736 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false); |
| ... | @@ -6802,14 +6847,15 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6802,14 +6847,15 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6802 | } | 6847 | } |
| 6803 | 6848 | ||
| 6804 | fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void { | 6849 | fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void { |
| 6805 | const mod = self.bin_file.comp.module.?; | 6850 | const pt = self.pt; |
| 6851 | const mod = pt.zcu; | ||
| 6806 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; | 6852 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 6807 | 6853 | ||
| 6808 | const result = result: { | 6854 | const result = result: { |
| 6809 | const scalar_bits = ty.scalarType(mod).floatBits(self.target.*); | 6855 | const scalar_bits = ty.scalarType(mod).floatBits(self.target.*); |
| 6810 | if (scalar_bits == 80) { | 6856 | if (scalar_bits == 80) { |
| 6811 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement floatSign for {}", .{ | 6857 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement floatSign for {}", .{ |
| 6812 | ty.fmt(mod), | 6858 | ty.fmt(pt), |
| 6813 | }); | 6859 | }); |
| 6814 | 6860 | ||
| 6815 | const src_mcv = try self.resolveInst(operand); | 6861 | const src_mcv = try self.resolveInst(operand); |
| ... | @@ -6829,11 +6875,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6829,11 +6875,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6829 | break :result dst_mcv; | 6875 | break :result dst_mcv; |
| 6830 | } | 6876 | } |
| 6831 | 6877 | ||
| 6832 | const abi_size: u32 = switch (ty.abiSize(mod)) { | 6878 | const abi_size: u32 = switch (ty.abiSize(pt)) { |
| 6833 | 1...16 => 16, | 6879 | 1...16 => 16, |
| 6834 | 17...32 => 32, | 6880 | 17...32 => 32, |
| 6835 | else => return self.fail("TODO implement floatSign for {}", .{ | 6881 | else => return self.fail("TODO implement floatSign for {}", .{ |
| 6836 | ty.fmt(mod), | 6882 | ty.fmt(pt), |
| 6837 | }), | 6883 | }), |
| 6838 | }; | 6884 | }; |
| 6839 | 6885 | ||
| ... | @@ -6852,14 +6898,14 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6852,14 +6898,14 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6852 | const dst_lock = self.register_manager.lockReg(dst_reg); | 6898 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 6853 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 6899 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 6854 | 6900 | ||
| 6855 | const vec_ty = try mod.vectorType(.{ | 6901 | const vec_ty = try pt.vectorType(.{ |
| 6856 | .len = @divExact(abi_size * 8, scalar_bits), | 6902 | .len = @divExact(abi_size * 8, scalar_bits), |
| 6857 | .child = (try mod.intType(.signed, scalar_bits)).ip_index, | 6903 | .child = (try pt.intType(.signed, scalar_bits)).ip_index, |
| 6858 | }); | 6904 | }); |
| 6859 | 6905 | ||
| 6860 | const sign_mcv = try self.genTypedValue(switch (tag) { | 6906 | const sign_mcv = try self.genTypedValue(switch (tag) { |
| 6861 | .neg => try vec_ty.minInt(mod, vec_ty), | 6907 | .neg => try vec_ty.minInt(pt, vec_ty), |
| 6862 | .abs => try vec_ty.maxInt(mod, vec_ty), | 6908 | .abs => try vec_ty.maxInt(pt, vec_ty), |
| 6863 | else => unreachable, | 6909 | else => unreachable, |
| 6864 | }); | 6910 | }); |
| 6865 | const sign_mem: Memory = if (sign_mcv.isMemory()) | 6911 | const sign_mem: Memory = if (sign_mcv.isMemory()) |
| ... | @@ -6891,7 +6937,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6891,7 +6937,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6891 | .abs => .{ .v_pd, .@"and" }, | 6937 | .abs => .{ .v_pd, .@"and" }, |
| 6892 | else => unreachable, | 6938 | else => unreachable, |
| 6893 | }, | 6939 | }, |
| 6894 | 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(mod)}), | 6940 | 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}), |
| 6895 | else => unreachable, | 6941 | else => unreachable, |
| 6896 | }, | 6942 | }, |
| 6897 | registerAlias(dst_reg, abi_size), | 6943 | registerAlias(dst_reg, abi_size), |
| ... | @@ -6917,7 +6963,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6917,7 +6963,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6917 | .abs => .{ ._pd, .@"and" }, | 6963 | .abs => .{ ._pd, .@"and" }, |
| 6918 | else => unreachable, | 6964 | else => unreachable, |
| 6919 | }, | 6965 | }, |
| 6920 | 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(mod)}), | 6966 | 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}), |
| 6921 | else => unreachable, | 6967 | else => unreachable, |
| 6922 | }, | 6968 | }, |
| 6923 | registerAlias(dst_reg, abi_size), | 6969 | registerAlias(dst_reg, abi_size), |
| ... | @@ -6978,7 +7024,8 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void { | ... | @@ -6978,7 +7024,8 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void { |
| 6978 | } | 7024 | } |
| 6979 | 7025 | ||
| 6980 | fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { | 7026 | fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 6981 | const mod = self.bin_file.comp.module.?; | 7027 | const pt = self.pt; |
| 7028 | const mod = pt.zcu; | ||
| 6982 | return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) { | 7029 | return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) { |
| 6983 | .Float => switch (ty.floatBits(self.target.*)) { | 7030 | .Float => switch (ty.floatBits(self.target.*)) { |
| 6984 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, | 7031 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, |
| ... | @@ -7010,11 +7057,12 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { | ... | @@ -7010,11 +7057,12 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 7010 | } | 7057 | } |
| 7011 | 7058 | ||
| 7012 | fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue { | 7059 | fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue { |
| 7013 | const mod = self.bin_file.comp.module.?; | 7060 | const pt = self.pt; |
| 7061 | const mod = pt.zcu; | ||
| 7014 | if (self.getRoundTag(ty)) |_| return .none; | 7062 | if (self.getRoundTag(ty)) |_| return .none; |
| 7015 | 7063 | ||
| 7016 | if (ty.zigTypeTag(mod) != .Float) | 7064 | if (ty.zigTypeTag(mod) != .Float) |
| 7017 | return self.fail("TODO implement genRound for {}", .{ty.fmt(mod)}); | 7065 | return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)}); |
| 7018 | 7066 | ||
| 7019 | var callee_buf: ["__trunc?".len]u8 = undefined; | 7067 | var callee_buf: ["__trunc?".len]u8 = undefined; |
| 7020 | return try self.genCall(.{ .lib = .{ | 7068 | return try self.genCall(.{ .lib = .{ |
| ... | @@ -7034,12 +7082,12 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC | ... | @@ -7034,12 +7082,12 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC |
| 7034 | } | 7082 | } |
| 7035 | 7083 | ||
| 7036 | fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void { | 7084 | fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void { |
| 7037 | const mod = self.bin_file.comp.module.?; | 7085 | const pt = self.pt; |
| 7038 | const mir_tag = self.getRoundTag(ty) orelse { | 7086 | const mir_tag = self.getRoundTag(ty) orelse { |
| 7039 | const result = try self.genRoundLibcall(ty, src_mcv, mode); | 7087 | const result = try self.genRoundLibcall(ty, src_mcv, mode); |
| 7040 | return self.genSetReg(dst_reg, ty, result, .{}); | 7088 | return self.genSetReg(dst_reg, ty, result, .{}); |
| 7041 | }; | 7089 | }; |
| 7042 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 7090 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 7043 | const dst_alias = registerAlias(dst_reg, abi_size); | 7091 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 7044 | switch (mir_tag[0]) { | 7092 | switch (mir_tag[0]) { |
| 7045 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( | 7093 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( |
| ... | @@ -7076,14 +7124,15 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -7076,14 +7124,15 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 7076 | } | 7124 | } |
| 7077 | 7125 | ||
| 7078 | fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | 7126 | fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7079 | const mod = self.bin_file.comp.module.?; | 7127 | const pt = self.pt; |
| 7128 | const mod = pt.zcu; | ||
| 7080 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7129 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7081 | const ty = self.typeOf(ty_op.operand); | 7130 | const ty = self.typeOf(ty_op.operand); |
| 7082 | 7131 | ||
| 7083 | const result: MCValue = result: { | 7132 | const result: MCValue = result: { |
| 7084 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { | 7133 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { |
| 7085 | else => null, | 7134 | else => null, |
| 7086 | .Int => switch (ty.abiSize(mod)) { | 7135 | .Int => switch (ty.abiSize(pt)) { |
| 7087 | 0 => unreachable, | 7136 | 0 => unreachable, |
| 7088 | 1...8 => { | 7137 | 1...8 => { |
| 7089 | try self.spillEflagsIfOccupied(); | 7138 | try self.spillEflagsIfOccupied(); |
| ... | @@ -7092,7 +7141,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7092,7 +7141,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7092 | 7141 | ||
| 7093 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); | 7142 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); |
| 7094 | 7143 | ||
| 7095 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | 7144 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); |
| 7096 | switch (src_mcv) { | 7145 | switch (src_mcv) { |
| 7097 | .register => |val_reg| try self.asmCmovccRegisterRegister( | 7146 | .register => |val_reg| try self.asmCmovccRegisterRegister( |
| 7098 | .l, | 7147 | .l, |
| ... | @@ -7151,7 +7200,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7151,7 +7200,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7151 | break :result dst_mcv; | 7200 | break :result dst_mcv; |
| 7152 | }, | 7201 | }, |
| 7153 | else => { | 7202 | else => { |
| 7154 | const abi_size: u31 = @intCast(ty.abiSize(mod)); | 7203 | const abi_size: u31 = @intCast(ty.abiSize(pt)); |
| 7155 | const limb_len = math.divCeil(u31, abi_size, 8) catch unreachable; | 7204 | const limb_len = math.divCeil(u31, abi_size, 8) catch unreachable; |
| 7156 | 7205 | ||
| 7157 | const tmp_regs = | 7206 | const tmp_regs = |
| ... | @@ -7249,9 +7298,9 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7249,9 +7298,9 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7249 | }, | 7298 | }, |
| 7250 | .Float => return self.floatSign(inst, ty_op.operand, ty), | 7299 | .Float => return self.floatSign(inst, ty_op.operand, ty), |
| 7251 | }, | 7300 | }, |
| 7252 | }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(mod)}); | 7301 | }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 7253 | 7302 | ||
| 7254 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 7303 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 7255 | const src_mcv = try self.resolveInst(ty_op.operand); | 7304 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 7256 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 7305 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 7257 | src_mcv.getReg().? | 7306 | src_mcv.getReg().? |
| ... | @@ -7276,10 +7325,11 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7276,10 +7325,11 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7276 | } | 7325 | } |
| 7277 | 7326 | ||
| 7278 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | 7327 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7279 | const mod = self.bin_file.comp.module.?; | 7328 | const pt = self.pt; |
| 7329 | const mod = pt.zcu; | ||
| 7280 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 7330 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7281 | const ty = self.typeOf(un_op); | 7331 | const ty = self.typeOf(un_op); |
| 7282 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 7332 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 7283 | 7333 | ||
| 7284 | const result: MCValue = result: { | 7334 | const result: MCValue = result: { |
| 7285 | switch (ty.zigTypeTag(mod)) { | 7335 | switch (ty.zigTypeTag(mod)) { |
| ... | @@ -7408,7 +7458,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7408,7 +7458,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7408 | }, | 7458 | }, |
| 7409 | else => unreachable, | 7459 | else => unreachable, |
| 7410 | }) orelse return self.fail("TODO implement airSqrt for {}", .{ | 7460 | }) orelse return self.fail("TODO implement airSqrt for {}", .{ |
| 7411 | ty.fmt(mod), | 7461 | ty.fmt(pt), |
| 7412 | }); | 7462 | }); |
| 7413 | switch (mir_tag[0]) { | 7463 | switch (mir_tag[0]) { |
| 7414 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 7464 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( |
| ... | @@ -7521,14 +7571,15 @@ fn reuseOperandAdvanced( | ... | @@ -7521,14 +7571,15 @@ fn reuseOperandAdvanced( |
| 7521 | } | 7571 | } |
| 7522 | 7572 | ||
| 7523 | fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { | 7573 | fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| 7524 | const mod = self.bin_file.comp.module.?; | 7574 | const pt = self.pt; |
| 7575 | const mod = pt.zcu; | ||
| 7525 | 7576 | ||
| 7526 | const ptr_info = ptr_ty.ptrInfo(mod); | 7577 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 7527 | const val_ty = Type.fromInterned(ptr_info.child); | 7578 | const val_ty = Type.fromInterned(ptr_info.child); |
| 7528 | if (!val_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 7579 | if (!val_ty.hasRuntimeBitsIgnoreComptime(pt)) return; |
| 7529 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); | 7580 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); |
| 7530 | 7581 | ||
| 7531 | const val_bit_size: u32 = @intCast(val_ty.bitSize(mod)); | 7582 | const val_bit_size: u32 = @intCast(val_ty.bitSize(pt)); |
| 7532 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { | 7583 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 7533 | .none => 0, | 7584 | .none => 0, |
| 7534 | .runtime => unreachable, | 7585 | .runtime => unreachable, |
| ... | @@ -7566,7 +7617,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -7566,7 +7617,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 7566 | return; | 7617 | return; |
| 7567 | } | 7618 | } |
| 7568 | 7619 | ||
| 7569 | if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(mod)}); | 7620 | if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(pt)}); |
| 7570 | 7621 | ||
| 7571 | const limb_abi_size: u31 = @min(val_abi_size, 8); | 7622 | const limb_abi_size: u31 = @min(val_abi_size, 8); |
| 7572 | const limb_abi_bits = limb_abi_size * 8; | 7623 | const limb_abi_bits = limb_abi_size * 8; |
| ... | @@ -7633,9 +7684,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -7633,9 +7684,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 7633 | } | 7684 | } |
| 7634 | 7685 | ||
| 7635 | fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { | 7686 | fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| 7636 | const mod = self.bin_file.comp.module.?; | 7687 | const pt = self.pt; |
| 7688 | const mod = pt.zcu; | ||
| 7637 | const dst_ty = ptr_ty.childType(mod); | 7689 | const dst_ty = ptr_ty.childType(mod); |
| 7638 | if (!dst_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 7690 | if (!dst_ty.hasRuntimeBitsIgnoreComptime(pt)) return; |
| 7639 | switch (ptr_mcv) { | 7691 | switch (ptr_mcv) { |
| 7640 | .none, | 7692 | .none, |
| 7641 | .unreach, | 7693 | .unreach, |
| ... | @@ -7675,18 +7727,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro | ... | @@ -7675,18 +7727,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 7675 | } | 7727 | } |
| 7676 | 7728 | ||
| 7677 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | 7729 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7678 | const mod = self.bin_file.comp.module.?; | 7730 | const pt = self.pt; |
| 7731 | const mod = pt.zcu; | ||
| 7679 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7732 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7680 | const elem_ty = self.typeOfIndex(inst); | 7733 | const elem_ty = self.typeOfIndex(inst); |
| 7681 | const result: MCValue = result: { | 7734 | const result: MCValue = result: { |
| 7682 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 7735 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 7683 | 7736 | ||
| 7684 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); | 7737 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| 7685 | const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx }); | 7738 | const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx }); |
| 7686 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); | 7739 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 7687 | 7740 | ||
| 7688 | const ptr_ty = self.typeOf(ty_op.operand); | 7741 | const ptr_ty = self.typeOf(ty_op.operand); |
| 7689 | const elem_size = elem_ty.abiSize(mod); | 7742 | const elem_size = elem_ty.abiSize(pt); |
| 7690 | 7743 | ||
| 7691 | const elem_rc = self.regClassForType(elem_ty); | 7744 | const elem_rc = self.regClassForType(elem_ty); |
| 7692 | const ptr_rc = self.regClassForType(ptr_ty); | 7745 | const ptr_rc = self.regClassForType(ptr_ty); |
| ... | @@ -7706,7 +7759,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7706,7 +7759,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7706 | try self.load(dst_mcv, ptr_ty, ptr_mcv); | 7759 | try self.load(dst_mcv, ptr_ty, ptr_mcv); |
| 7707 | } | 7760 | } |
| 7708 | 7761 | ||
| 7709 | if (elem_ty.isAbiInt(mod) and elem_size * 8 > elem_ty.bitSize(mod)) { | 7762 | if (elem_ty.isAbiInt(mod) and elem_size * 8 > elem_ty.bitSize(pt)) { |
| 7710 | const high_mcv: MCValue = switch (dst_mcv) { | 7763 | const high_mcv: MCValue = switch (dst_mcv) { |
| 7711 | .register => |dst_reg| .{ .register = dst_reg }, | 7764 | .register => |dst_reg| .{ .register = dst_reg }, |
| 7712 | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, | 7765 | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| ... | @@ -7733,16 +7786,17 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7733,16 +7786,17 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7733 | } | 7786 | } |
| 7734 | 7787 | ||
| 7735 | fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 7788 | fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 7736 | const mod = self.bin_file.comp.module.?; | 7789 | const pt = self.pt; |
| 7790 | const mod = pt.zcu; | ||
| 7737 | const ptr_info = ptr_ty.ptrInfo(mod); | 7791 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 7738 | const src_ty = Type.fromInterned(ptr_info.child); | 7792 | const src_ty = Type.fromInterned(ptr_info.child); |
| 7739 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 7793 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return; |
| 7740 | 7794 | ||
| 7741 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); | 7795 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); |
| 7742 | const limb_abi_bits = limb_abi_size * 8; | 7796 | const limb_abi_bits = limb_abi_size * 8; |
| 7743 | const limb_ty = try mod.intType(.unsigned, limb_abi_bits); | 7797 | const limb_ty = try pt.intType(.unsigned, limb_abi_bits); |
| 7744 | 7798 | ||
| 7745 | const src_bit_size = src_ty.bitSize(mod); | 7799 | const src_bit_size = src_ty.bitSize(pt); |
| 7746 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { | 7800 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 7747 | .none => 0, | 7801 | .none => 0, |
| 7748 | .runtime => unreachable, | 7802 | .runtime => unreachable, |
| ... | @@ -7827,7 +7881,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -7827,7 +7881,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7827 | limb_mem, | 7881 | limb_mem, |
| 7828 | registerAlias(tmp_reg, limb_abi_size), | 7882 | registerAlias(tmp_reg, limb_abi_size), |
| 7829 | ); | 7883 | ); |
| 7830 | } else return self.fail("TODO: implement packed store of {}", .{src_ty.fmt(mod)}); | 7884 | } else return self.fail("TODO: implement packed store of {}", .{src_ty.fmt(pt)}); |
| 7831 | } | 7885 | } |
| 7832 | } | 7886 | } |
| 7833 | 7887 | ||
| ... | @@ -7838,9 +7892,10 @@ fn store( | ... | @@ -7838,9 +7892,10 @@ fn store( |
| 7838 | src_mcv: MCValue, | 7892 | src_mcv: MCValue, |
| 7839 | opts: CopyOptions, | 7893 | opts: CopyOptions, |
| 7840 | ) InnerError!void { | 7894 | ) InnerError!void { |
| 7841 | const mod = self.bin_file.comp.module.?; | 7895 | const pt = self.pt; |
| 7896 | const mod = pt.zcu; | ||
| 7842 | const src_ty = ptr_ty.childType(mod); | 7897 | const src_ty = ptr_ty.childType(mod); |
| 7843 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 7898 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return; |
| 7844 | switch (ptr_mcv) { | 7899 | switch (ptr_mcv) { |
| 7845 | .none, | 7900 | .none, |
| 7846 | .unreach, | 7901 | .unreach, |
| ... | @@ -7880,7 +7935,8 @@ fn store( | ... | @@ -7880,7 +7935,8 @@ fn store( |
| 7880 | } | 7935 | } |
| 7881 | 7936 | ||
| 7882 | fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | 7937 | fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 7883 | const mod = self.bin_file.comp.module.?; | 7938 | const pt = self.pt; |
| 7939 | const mod = pt.zcu; | ||
| 7884 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7940 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7885 | 7941 | ||
| 7886 | result: { | 7942 | result: { |
| ... | @@ -7918,15 +7974,16 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -7918,15 +7974,16 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 7918 | } | 7974 | } |
| 7919 | 7975 | ||
| 7920 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 7976 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 7921 | const mod = self.bin_file.comp.module.?; | 7977 | const pt = self.pt; |
| 7978 | const mod = pt.zcu; | ||
| 7922 | const ptr_field_ty = self.typeOfIndex(inst); | 7979 | const ptr_field_ty = self.typeOfIndex(inst); |
| 7923 | const ptr_container_ty = self.typeOf(operand); | 7980 | const ptr_container_ty = self.typeOf(operand); |
| 7924 | const container_ty = ptr_container_ty.childType(mod); | 7981 | const container_ty = ptr_container_ty.childType(mod); |
| 7925 | 7982 | ||
| 7926 | const field_off: i32 = switch (container_ty.containerLayout(mod)) { | 7983 | const field_off: i32 = switch (container_ty.containerLayout(mod)) { |
| 7927 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, mod)), | 7984 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, pt)), |
| 7928 | .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(mod).packed_offset.bit_offset) + | 7985 | .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(mod).packed_offset.bit_offset) + |
| 7929 | (if (mod.typeToStruct(container_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, index) else 0) - | 7986 | (if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, index) else 0) - |
| 7930 | ptr_field_ty.ptrInfo(mod).packed_offset.bit_offset, 8), | 7987 | ptr_field_ty.ptrInfo(mod).packed_offset.bit_offset, 8), |
| 7931 | }; | 7988 | }; |
| 7932 | 7989 | ||
| ... | @@ -7940,7 +7997,8 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 | ... | @@ -7940,7 +7997,8 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 |
| 7940 | } | 7997 | } |
| 7941 | 7998 | ||
| 7942 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 7999 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7943 | const mod = self.bin_file.comp.module.?; | 8000 | const pt = self.pt; |
| 8001 | const mod = pt.zcu; | ||
| 7944 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8002 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7945 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 8003 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 7946 | const result: MCValue = result: { | 8004 | const result: MCValue = result: { |
| ... | @@ -7950,14 +8008,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7950,14 +8008,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7950 | const container_ty = self.typeOf(operand); | 8008 | const container_ty = self.typeOf(operand); |
| 7951 | const container_rc = self.regClassForType(container_ty); | 8009 | const container_rc = self.regClassForType(container_ty); |
| 7952 | const field_ty = container_ty.structFieldType(index, mod); | 8010 | const field_ty = container_ty.structFieldType(index, mod); |
| 7953 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | 8011 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; |
| 7954 | const field_rc = self.regClassForType(field_ty); | 8012 | const field_rc = self.regClassForType(field_ty); |
| 7955 | const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp); | 8013 | const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp); |
| 7956 | 8014 | ||
| 7957 | const src_mcv = try self.resolveInst(operand); | 8015 | const src_mcv = try self.resolveInst(operand); |
| 7958 | const field_off: u32 = switch (container_ty.containerLayout(mod)) { | 8016 | const field_off: u32 = switch (container_ty.containerLayout(mod)) { |
| 7959 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, mod) * 8), | 8017 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, pt) * 8), |
| 7960 | .@"packed" => if (mod.typeToStruct(container_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0, | 8018 | .@"packed" => if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0, |
| 7961 | }; | 8019 | }; |
| 7962 | 8020 | ||
| 7963 | switch (src_mcv) { | 8021 | switch (src_mcv) { |
| ... | @@ -7988,7 +8046,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7988,7 +8046,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7988 | ); | 8046 | ); |
| 7989 | } | 8047 | } |
| 7990 | if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and | 8048 | if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and |
| 7991 | container_ty.abiSize(mod) * 8 > field_ty.bitSize(mod)) | 8049 | container_ty.abiSize(pt) * 8 > field_ty.bitSize(pt)) |
| 7992 | try self.truncateRegister(field_ty, dst_reg); | 8050 | try self.truncateRegister(field_ty, dst_reg); |
| 7993 | 8051 | ||
| 7994 | break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp)) | 8052 | break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp)) |
| ... | @@ -8000,7 +8058,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8000,7 +8058,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8000 | const src_regs_lock = self.register_manager.lockRegsAssumeUnused(2, src_regs); | 8058 | const src_regs_lock = self.register_manager.lockRegsAssumeUnused(2, src_regs); |
| 8001 | defer for (src_regs_lock) |lock| self.register_manager.unlockReg(lock); | 8059 | defer for (src_regs_lock) |lock| self.register_manager.unlockReg(lock); |
| 8002 | 8060 | ||
| 8003 | const field_bit_size: u32 = @intCast(field_ty.bitSize(mod)); | 8061 | const field_bit_size: u32 = @intCast(field_ty.bitSize(pt)); |
| 8004 | const src_reg = if (field_off + field_bit_size <= 64) | 8062 | const src_reg = if (field_off + field_bit_size <= 64) |
| 8005 | src_regs[0] | 8063 | src_regs[0] |
| 8006 | else if (field_off >= 64) | 8064 | else if (field_off >= 64) |
| ... | @@ -8044,7 +8102,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8044,7 +8102,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8044 | } | 8102 | } |
| 8045 | 8103 | ||
| 8046 | if (field_bit_size < 128) try self.truncateRegister( | 8104 | if (field_bit_size < 128) try self.truncateRegister( |
| 8047 | try mod.intType(.unsigned, @intCast(field_bit_size - 64)), | 8105 | try pt.intType(.unsigned, @intCast(field_bit_size - 64)), |
| 8048 | dst_regs[1], | 8106 | dst_regs[1], |
| 8049 | ); | 8107 | ); |
| 8050 | break :result if (field_rc.supersetOf(abi.RegisterClass.gp)) | 8108 | break :result if (field_rc.supersetOf(abi.RegisterClass.gp)) |
| ... | @@ -8099,14 +8157,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8099,14 +8157,14 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8099 | } | 8157 | } |
| 8100 | }, | 8158 | }, |
| 8101 | .load_frame => |frame_addr| { | 8159 | .load_frame => |frame_addr| { |
| 8102 | const field_abi_size: u32 = @intCast(field_ty.abiSize(mod)); | 8160 | const field_abi_size: u32 = @intCast(field_ty.abiSize(pt)); |
| 8103 | if (field_off % 8 == 0) { | 8161 | if (field_off % 8 == 0) { |
| 8104 | const field_byte_off = @divExact(field_off, 8); | 8162 | const field_byte_off = @divExact(field_off, 8); |
| 8105 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); | 8163 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); |
| 8106 | const field_bit_size = field_ty.bitSize(mod); | 8164 | const field_bit_size = field_ty.bitSize(pt); |
| 8107 | 8165 | ||
| 8108 | if (field_abi_size <= 8) { | 8166 | if (field_abi_size <= 8) { |
| 8109 | const int_ty = try mod.intType( | 8167 | const int_ty = try pt.intType( |
| 8110 | if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, | 8168 | if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, |
| 8111 | @intCast(field_bit_size), | 8169 | @intCast(field_bit_size), |
| 8112 | ); | 8170 | ); |
| ... | @@ -8127,7 +8185,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8127,7 +8185,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8127 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); | 8185 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 8128 | } | 8186 | } |
| 8129 | 8187 | ||
| 8130 | const container_abi_size: u32 = @intCast(container_ty.abiSize(mod)); | 8188 | const container_abi_size: u32 = @intCast(container_ty.abiSize(pt)); |
| 8131 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and | 8189 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and |
| 8132 | self.reuseOperand(inst, operand, 0, src_mcv)) | 8190 | self.reuseOperand(inst, operand, 0, src_mcv)) |
| 8133 | off_mcv | 8191 | off_mcv |
| ... | @@ -8228,16 +8286,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8228,16 +8286,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8228 | } | 8286 | } |
| 8229 | 8287 | ||
| 8230 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | 8288 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 8231 | const mod = self.bin_file.comp.module.?; | 8289 | const pt = self.pt; |
| 8290 | const mod = pt.zcu; | ||
| 8232 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8291 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8233 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 8292 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 8234 | 8293 | ||
| 8235 | const inst_ty = self.typeOfIndex(inst); | 8294 | const inst_ty = self.typeOfIndex(inst); |
| 8236 | const parent_ty = inst_ty.childType(mod); | 8295 | const parent_ty = inst_ty.childType(mod); |
| 8237 | const field_off: i32 = switch (parent_ty.containerLayout(mod)) { | 8296 | const field_off: i32 = switch (parent_ty.containerLayout(mod)) { |
| 8238 | .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, mod)), | 8297 | .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, pt)), |
| 8239 | .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(mod).packed_offset.bit_offset) + | 8298 | .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(mod).packed_offset.bit_offset) + |
| 8240 | (if (mod.typeToStruct(parent_ty)) |struct_obj| mod.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) - | 8299 | (if (mod.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) - |
| 8241 | self.typeOf(extra.field_ptr).ptrInfo(mod).packed_offset.bit_offset, 8), | 8300 | self.typeOf(extra.field_ptr).ptrInfo(mod).packed_offset.bit_offset, 8), |
| 8242 | }; | 8301 | }; |
| 8243 | 8302 | ||
| ... | @@ -8252,10 +8311,11 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8252,10 +8311,11 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 8252 | } | 8311 | } |
| 8253 | 8312 | ||
| 8254 | fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { | 8313 | fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { |
| 8255 | const mod = self.bin_file.comp.module.?; | 8314 | const pt = self.pt; |
| 8315 | const mod = pt.zcu; | ||
| 8256 | const src_ty = self.typeOf(src_air); | 8316 | const src_ty = self.typeOf(src_air); |
| 8257 | if (src_ty.zigTypeTag(mod) == .Vector) | 8317 | if (src_ty.zigTypeTag(mod) == .Vector) |
| 8258 | return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(mod)}); | 8318 | return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(pt)}); |
| 8259 | 8319 | ||
| 8260 | var src_mcv = try self.resolveInst(src_air); | 8320 | var src_mcv = try self.resolveInst(src_air); |
| 8261 | switch (src_mcv) { | 8321 | switch (src_mcv) { |
| ... | @@ -8290,7 +8350,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: | ... | @@ -8290,7 +8350,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8290 | }; | 8350 | }; |
| 8291 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 8351 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 8292 | 8352 | ||
| 8293 | const abi_size: u16 = @intCast(src_ty.abiSize(mod)); | 8353 | const abi_size: u16 = @intCast(src_ty.abiSize(pt)); |
| 8294 | switch (tag) { | 8354 | switch (tag) { |
| 8295 | .not => { | 8355 | .not => { |
| 8296 | const limb_abi_size: u16 = @min(abi_size, 8); | 8356 | const limb_abi_size: u16 = @min(abi_size, 8); |
| ... | @@ -8304,7 +8364,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: | ... | @@ -8304,7 +8364,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8304 | .signed => abi_size * 8, | 8364 | .signed => abi_size * 8, |
| 8305 | .unsigned => int_info.bits, | 8365 | .unsigned => int_info.bits, |
| 8306 | } - byte_off * 8, limb_abi_size * 8)); | 8366 | } - byte_off * 8, limb_abi_size * 8)); |
| 8307 | const limb_ty = try mod.intType(int_info.signedness, limb_bits); | 8367 | const limb_ty = try pt.intType(int_info.signedness, limb_bits); |
| 8308 | const limb_mcv = switch (byte_off) { | 8368 | const limb_mcv = switch (byte_off) { |
| 8309 | 0 => dst_mcv, | 8369 | 0 => dst_mcv, |
| 8310 | else => dst_mcv.address().offset(byte_off).deref(), | 8370 | else => dst_mcv.address().offset(byte_off).deref(), |
| ... | @@ -8340,9 +8400,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: | ... | @@ -8340,9 +8400,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8340 | } | 8400 | } |
| 8341 | 8401 | ||
| 8342 | fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void { | 8402 | fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void { |
| 8343 | const mod = self.bin_file.comp.module.?; | 8403 | const pt = self.pt; |
| 8344 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 8404 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 8345 | if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(mod) }); | 8405 | if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(pt) }); |
| 8346 | switch (dst_mcv) { | 8406 | switch (dst_mcv) { |
| 8347 | .none, | 8407 | .none, |
| 8348 | .unreach, | 8408 | .unreach, |
| ... | @@ -8389,9 +8449,9 @@ fn genShiftBinOpMir( | ... | @@ -8389,9 +8449,9 @@ fn genShiftBinOpMir( |
| 8389 | rhs_ty: Type, | 8449 | rhs_ty: Type, |
| 8390 | rhs_mcv: MCValue, | 8450 | rhs_mcv: MCValue, |
| 8391 | ) !void { | 8451 | ) !void { |
| 8392 | const mod = self.bin_file.comp.module.?; | 8452 | const pt = self.pt; |
| 8393 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 8453 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); |
| 8394 | const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(mod)); | 8454 | const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(pt)); |
| 8395 | try self.spillEflagsIfOccupied(); | 8455 | try self.spillEflagsIfOccupied(); |
| 8396 | 8456 | ||
| 8397 | if (abi_size > 16) { | 8457 | if (abi_size > 16) { |
| ... | @@ -9046,9 +9106,10 @@ fn genShiftBinOp( | ... | @@ -9046,9 +9106,10 @@ fn genShiftBinOp( |
| 9046 | lhs_ty: Type, | 9106 | lhs_ty: Type, |
| 9047 | rhs_ty: Type, | 9107 | rhs_ty: Type, |
| 9048 | ) !MCValue { | 9108 | ) !MCValue { |
| 9049 | const mod = self.bin_file.comp.module.?; | 9109 | const pt = self.pt; |
| 9110 | const mod = pt.zcu; | ||
| 9050 | if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{ | 9111 | if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{ |
| 9051 | lhs_ty.fmt(mod), | 9112 | lhs_ty.fmt(pt), |
| 9052 | }); | 9113 | }); |
| 9053 | 9114 | ||
| 9054 | try self.register_manager.getKnownReg(.rcx, null); | 9115 | try self.register_manager.getKnownReg(.rcx, null); |
| ... | @@ -9104,13 +9165,14 @@ fn genMulDivBinOp( | ... | @@ -9104,13 +9165,14 @@ fn genMulDivBinOp( |
| 9104 | lhs_mcv: MCValue, | 9165 | lhs_mcv: MCValue, |
| 9105 | rhs_mcv: MCValue, | 9166 | rhs_mcv: MCValue, |
| 9106 | ) !MCValue { | 9167 | ) !MCValue { |
| 9107 | const mod = self.bin_file.comp.module.?; | 9168 | const pt = self.pt; |
| 9169 | const mod = pt.zcu; | ||
| 9108 | if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail( | 9170 | if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail( |
| 9109 | "TODO implement genMulDivBinOp for {s} from {} to {}", | 9171 | "TODO implement genMulDivBinOp for {s} from {} to {}", |
| 9110 | .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, | 9172 | .{ @tagName(tag), src_ty.fmt(pt), dst_ty.fmt(pt) }, |
| 9111 | ); | 9173 | ); |
| 9112 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 9174 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 9113 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); | 9175 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); |
| 9114 | 9176 | ||
| 9115 | assert(self.register_manager.isRegFree(.rax)); | 9177 | assert(self.register_manager.isRegFree(.rax)); |
| 9116 | assert(self.register_manager.isRegFree(.rcx)); | 9178 | assert(self.register_manager.isRegFree(.rcx)); |
| ... | @@ -9299,13 +9361,13 @@ fn genMulDivBinOp( | ... | @@ -9299,13 +9361,13 @@ fn genMulDivBinOp( |
| 9299 | .signed => {}, | 9361 | .signed => {}, |
| 9300 | .unsigned => { | 9362 | .unsigned => { |
| 9301 | const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); | 9363 | const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); |
| 9302 | const manyptr_u32_ty = try mod.ptrType(.{ | 9364 | const manyptr_u32_ty = try pt.ptrType(.{ |
| 9303 | .child = .u32_type, | 9365 | .child = .u32_type, |
| 9304 | .flags = .{ | 9366 | .flags = .{ |
| 9305 | .size = .Many, | 9367 | .size = .Many, |
| 9306 | }, | 9368 | }, |
| 9307 | }); | 9369 | }); |
| 9308 | const manyptr_const_u32_ty = try mod.ptrType(.{ | 9370 | const manyptr_const_u32_ty = try pt.ptrType(.{ |
| 9309 | .child = .u32_type, | 9371 | .child = .u32_type, |
| 9310 | .flags = .{ | 9372 | .flags = .{ |
| 9311 | .size = .Many, | 9373 | .size = .Many, |
| ... | @@ -9348,7 +9410,7 @@ fn genMulDivBinOp( | ... | @@ -9348,7 +9410,7 @@ fn genMulDivBinOp( |
| 9348 | } | 9410 | } |
| 9349 | return self.fail( | 9411 | return self.fail( |
| 9350 | "TODO implement genMulDivBinOp for {s} from {} to {}", | 9412 | "TODO implement genMulDivBinOp for {s} from {} to {}", |
| 9351 | .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, | 9413 | .{ @tagName(tag), src_ty.fmt(pt), dst_ty.fmt(pt) }, |
| 9352 | ); | 9414 | ); |
| 9353 | } | 9415 | } |
| 9354 | const ty = if (dst_abi_size <= 8) dst_ty else src_ty; | 9416 | const ty = if (dst_abi_size <= 8) dst_ty else src_ty; |
| ... | @@ -9515,10 +9577,11 @@ fn genBinOp( | ... | @@ -9515,10 +9577,11 @@ fn genBinOp( |
| 9515 | lhs_air: Air.Inst.Ref, | 9577 | lhs_air: Air.Inst.Ref, |
| 9516 | rhs_air: Air.Inst.Ref, | 9578 | rhs_air: Air.Inst.Ref, |
| 9517 | ) !MCValue { | 9579 | ) !MCValue { |
| 9518 | const mod = self.bin_file.comp.module.?; | 9580 | const pt = self.pt; |
| 9581 | const mod = pt.zcu; | ||
| 9519 | const lhs_ty = self.typeOf(lhs_air); | 9582 | const lhs_ty = self.typeOf(lhs_air); |
| 9520 | const rhs_ty = self.typeOf(rhs_air); | 9583 | const rhs_ty = self.typeOf(rhs_air); |
| 9521 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 9584 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); |
| 9522 | 9585 | ||
| 9523 | if (lhs_ty.isRuntimeFloat()) libcall: { | 9586 | if (lhs_ty.isRuntimeFloat()) libcall: { |
| 9524 | const float_bits = lhs_ty.floatBits(self.target.*); | 9587 | const float_bits = lhs_ty.floatBits(self.target.*); |
| ... | @@ -9556,7 +9619,7 @@ fn genBinOp( | ... | @@ -9556,7 +9619,7 @@ fn genBinOp( |
| 9556 | floatLibcAbiSuffix(lhs_ty), | 9619 | floatLibcAbiSuffix(lhs_ty), |
| 9557 | }), | 9620 | }), |
| 9558 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | 9621 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 9559 | @tagName(air_tag), lhs_ty.fmt(mod), | 9622 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 9560 | }), | 9623 | }), |
| 9561 | } catch unreachable; | 9624 | } catch unreachable; |
| 9562 | const result = try self.genCall(.{ .lib = .{ | 9625 | const result = try self.genCall(.{ .lib = .{ |
| ... | @@ -9668,7 +9731,7 @@ fn genBinOp( | ... | @@ -9668,7 +9731,7 @@ fn genBinOp( |
| 9668 | break :adjusted .{ .register = dst_reg }; | 9731 | break :adjusted .{ .register = dst_reg }; |
| 9669 | }, | 9732 | }, |
| 9670 | 80, 128 => return self.fail("TODO implement genBinOp for {s} of {}", .{ | 9733 | 80, 128 => return self.fail("TODO implement genBinOp for {s} of {}", .{ |
| 9671 | @tagName(air_tag), lhs_ty.fmt(mod), | 9734 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 9672 | }), | 9735 | }), |
| 9673 | else => unreachable, | 9736 | else => unreachable, |
| 9674 | }; | 9737 | }; |
| ... | @@ -9700,8 +9763,8 @@ fn genBinOp( | ... | @@ -9700,8 +9763,8 @@ fn genBinOp( |
| 9700 | }; | 9763 | }; |
| 9701 | if (sse_op and ((lhs_ty.scalarType(mod).isRuntimeFloat() and | 9764 | if (sse_op and ((lhs_ty.scalarType(mod).isRuntimeFloat() and |
| 9702 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or | 9765 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or |
| 9703 | lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))) | 9766 | lhs_ty.abiSize(pt) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))) |
| 9704 | return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(mod) }); | 9767 | return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(pt) }); |
| 9705 | 9768 | ||
| 9706 | const maybe_mask_reg = switch (air_tag) { | 9769 | const maybe_mask_reg = switch (air_tag) { |
| 9707 | else => null, | 9770 | else => null, |
| ... | @@ -9857,7 +9920,7 @@ fn genBinOp( | ... | @@ -9857,7 +9920,7 @@ fn genBinOp( |
| 9857 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 9920 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 9858 | defer self.register_manager.unlockReg(tmp_lock); | 9921 | defer self.register_manager.unlockReg(tmp_lock); |
| 9859 | 9922 | ||
| 9860 | const elem_size = lhs_ty.elemType2(mod).abiSize(mod); | 9923 | const elem_size = lhs_ty.elemType2(mod).abiSize(pt); |
| 9861 | try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); | 9924 | try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); |
| 9862 | try self.genBinOpMir( | 9925 | try self.genBinOpMir( |
| 9863 | switch (air_tag) { | 9926 | switch (air_tag) { |
| ... | @@ -10003,7 +10066,7 @@ fn genBinOp( | ... | @@ -10003,7 +10066,7 @@ fn genBinOp( |
| 10003 | }, | 10066 | }, |
| 10004 | }; | 10067 | }; |
| 10005 | 10068 | ||
| 10006 | const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(mod))), 2); | 10069 | const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(pt))), 2); |
| 10007 | const tmp_reg = switch (dst_mcv) { | 10070 | const tmp_reg = switch (dst_mcv) { |
| 10008 | .register => |reg| reg, | 10071 | .register => |reg| reg, |
| 10009 | else => try self.copyToTmpRegister(lhs_ty, dst_mcv), | 10072 | else => try self.copyToTmpRegister(lhs_ty, dst_mcv), |
| ... | @@ -10082,7 +10145,7 @@ fn genBinOp( | ... | @@ -10082,7 +10145,7 @@ fn genBinOp( |
| 10082 | }, | 10145 | }, |
| 10083 | 10146 | ||
| 10084 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | 10147 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 10085 | @tagName(air_tag), lhs_ty.fmt(mod), | 10148 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 10086 | }), | 10149 | }), |
| 10087 | } | 10150 | } |
| 10088 | return dst_mcv; | 10151 | return dst_mcv; |
| ... | @@ -10835,7 +10898,7 @@ fn genBinOp( | ... | @@ -10835,7 +10898,7 @@ fn genBinOp( |
| 10835 | }, | 10898 | }, |
| 10836 | }, | 10899 | }, |
| 10837 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 10900 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 10838 | @tagName(air_tag), lhs_ty.fmt(mod), | 10901 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 10839 | }); | 10902 | }); |
| 10840 | 10903 | ||
| 10841 | const lhs_copy_reg = if (maybe_mask_reg) |_| registerAlias( | 10904 | const lhs_copy_reg = if (maybe_mask_reg) |_| registerAlias( |
| ... | @@ -10978,7 +11041,7 @@ fn genBinOp( | ... | @@ -10978,7 +11041,7 @@ fn genBinOp( |
| 10978 | }, | 11041 | }, |
| 10979 | else => unreachable, | 11042 | else => unreachable, |
| 10980 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 11043 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 10981 | @tagName(air_tag), lhs_ty.fmt(mod), | 11044 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 10982 | }), | 11045 | }), |
| 10983 | mask_reg, | 11046 | mask_reg, |
| 10984 | rhs_copy_reg, | 11047 | rhs_copy_reg, |
| ... | @@ -11010,7 +11073,7 @@ fn genBinOp( | ... | @@ -11010,7 +11073,7 @@ fn genBinOp( |
| 11010 | }, | 11073 | }, |
| 11011 | else => unreachable, | 11074 | else => unreachable, |
| 11012 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 11075 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 11013 | @tagName(air_tag), lhs_ty.fmt(mod), | 11076 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 11014 | }), | 11077 | }), |
| 11015 | dst_reg, | 11078 | dst_reg, |
| 11016 | dst_reg, | 11079 | dst_reg, |
| ... | @@ -11046,7 +11109,7 @@ fn genBinOp( | ... | @@ -11046,7 +11109,7 @@ fn genBinOp( |
| 11046 | }, | 11109 | }, |
| 11047 | else => unreachable, | 11110 | else => unreachable, |
| 11048 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 11111 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 11049 | @tagName(air_tag), lhs_ty.fmt(mod), | 11112 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 11050 | }), | 11113 | }), |
| 11051 | mask_reg, | 11114 | mask_reg, |
| 11052 | mask_reg, | 11115 | mask_reg, |
| ... | @@ -11077,7 +11140,7 @@ fn genBinOp( | ... | @@ -11077,7 +11140,7 @@ fn genBinOp( |
| 11077 | }, | 11140 | }, |
| 11078 | else => unreachable, | 11141 | else => unreachable, |
| 11079 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 11142 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 11080 | @tagName(air_tag), lhs_ty.fmt(mod), | 11143 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 11081 | }), | 11144 | }), |
| 11082 | dst_reg, | 11145 | dst_reg, |
| 11083 | lhs_copy_reg.?, | 11146 | lhs_copy_reg.?, |
| ... | @@ -11107,7 +11170,7 @@ fn genBinOp( | ... | @@ -11107,7 +11170,7 @@ fn genBinOp( |
| 11107 | }, | 11170 | }, |
| 11108 | else => unreachable, | 11171 | else => unreachable, |
| 11109 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | 11172 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 11110 | @tagName(air_tag), lhs_ty.fmt(mod), | 11173 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 11111 | }); | 11174 | }); |
| 11112 | try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg); | 11175 | try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg); |
| 11113 | try self.asmRegisterRegister(.{ mir_fixes, .andn }, mask_reg, lhs_copy_reg.?); | 11176 | try self.asmRegisterRegister(.{ mir_fixes, .andn }, mask_reg, lhs_copy_reg.?); |
| ... | @@ -11125,8 +11188,8 @@ fn genBinOp( | ... | @@ -11125,8 +11188,8 @@ fn genBinOp( |
| 11125 | .cmp_gte, | 11188 | .cmp_gte, |
| 11126 | .cmp_neq, | 11189 | .cmp_neq, |
| 11127 | => { | 11190 | => { |
| 11128 | const unsigned_ty = try lhs_ty.toUnsigned(mod); | 11191 | const unsigned_ty = try lhs_ty.toUnsigned(pt); |
| 11129 | const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(mod, unsigned_ty)); | 11192 | const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(pt, unsigned_ty)); |
| 11130 | const not_mem: Memory = if (not_mcv.isMemory()) | 11193 | const not_mem: Memory = if (not_mcv.isMemory()) |
| 11131 | try not_mcv.mem(self, Memory.Size.fromSize(abi_size)) | 11194 | try not_mcv.mem(self, Memory.Size.fromSize(abi_size)) |
| 11132 | else | 11195 | else |
| ... | @@ -11195,8 +11258,9 @@ fn genBinOpMir( | ... | @@ -11195,8 +11258,9 @@ fn genBinOpMir( |
| 11195 | dst_mcv: MCValue, | 11258 | dst_mcv: MCValue, |
| 11196 | src_mcv: MCValue, | 11259 | src_mcv: MCValue, |
| 11197 | ) !void { | 11260 | ) !void { |
| 11198 | const mod = self.bin_file.comp.module.?; | 11261 | const pt = self.pt; |
| 11199 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 11262 | const mod = pt.zcu; |
| 11263 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | ||
| 11200 | try self.spillEflagsIfOccupied(); | 11264 | try self.spillEflagsIfOccupied(); |
| 11201 | switch (dst_mcv) { | 11265 | switch (dst_mcv) { |
| 11202 | .none, | 11266 | .none, |
| ... | @@ -11358,7 +11422,7 @@ fn genBinOpMir( | ... | @@ -11358,7 +11422,7 @@ fn genBinOpMir( |
| 11358 | .load_got, | 11422 | .load_got, |
| 11359 | .load_tlv, | 11423 | .load_tlv, |
| 11360 | => { | 11424 | => { |
| 11361 | const ptr_ty = try mod.singleConstPtrType(ty); | 11425 | const ptr_ty = try pt.singleConstPtrType(ty); |
| 11362 | const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address()); | 11426 | const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address()); |
| 11363 | return self.genBinOpMir(mir_limb_tag, ty, dst_mcv, .{ | 11427 | return self.genBinOpMir(mir_limb_tag, ty, dst_mcv, .{ |
| 11364 | .indirect = .{ .reg = addr_reg, .off = off }, | 11428 | .indirect = .{ .reg = addr_reg, .off = off }, |
| ... | @@ -11619,8 +11683,8 @@ fn genBinOpMir( | ... | @@ -11619,8 +11683,8 @@ fn genBinOpMir( |
| 11619 | /// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv. | 11683 | /// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv. |
| 11620 | /// Does not support byte-size operands. | 11684 | /// Does not support byte-size operands. |
| 11621 | fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 11685 | fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 11622 | const mod = self.bin_file.comp.module.?; | 11686 | const pt = self.pt; |
| 11623 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 11687 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 11624 | try self.spillEflagsIfOccupied(); | 11688 | try self.spillEflagsIfOccupied(); |
| 11625 | switch (dst_mcv) { | 11689 | switch (dst_mcv) { |
| 11626 | .none, | 11690 | .none, |
| ... | @@ -11746,7 +11810,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -11746,7 +11810,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 11746 | } | 11810 | } |
| 11747 | 11811 | ||
| 11748 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { | 11812 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11749 | const mod = self.bin_file.comp.module.?; | 11813 | const pt = self.pt; |
| 11814 | const mod = pt.zcu; | ||
| 11750 | // skip zero-bit arguments as they don't have a corresponding arg instruction | 11815 | // skip zero-bit arguments as they don't have a corresponding arg instruction |
| 11751 | var arg_index = self.arg_index; | 11816 | var arg_index = self.arg_index; |
| 11752 | while (self.args[arg_index] == .none) arg_index += 1; | 11817 | while (self.args[arg_index] == .none) arg_index += 1; |
| ... | @@ -11808,7 +11873,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11808,7 +11873,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11808 | try self.genInlineMemset( | 11873 | try self.genInlineMemset( |
| 11809 | dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)), | 11874 | dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)), |
| 11810 | .{ .immediate = 0 }, | 11875 | .{ .immediate = 0 }, |
| 11811 | .{ .immediate = arg_ty.abiSize(mod) - @intFromBool(regs_frame_addr.regs > 0) }, | 11876 | .{ .immediate = arg_ty.abiSize(pt) - @intFromBool(regs_frame_addr.regs > 0) }, |
| 11812 | .{}, | 11877 | .{}, |
| 11813 | ); | 11878 | ); |
| 11814 | 11879 | ||
| ... | @@ -11865,7 +11930,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11865,7 +11930,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11865 | } | 11930 | } |
| 11866 | 11931 | ||
| 11867 | fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { | 11932 | fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 11868 | const mod = self.bin_file.comp.module.?; | 11933 | const pt = self.pt; |
| 11934 | const mod = pt.zcu; | ||
| 11869 | switch (self.debug_output) { | 11935 | switch (self.debug_output) { |
| 11870 | .dwarf => |dw| { | 11936 | .dwarf => |dw| { |
| 11871 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { | 11937 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { |
| ... | @@ -11901,7 +11967,8 @@ fn genVarDbgInfo( | ... | @@ -11901,7 +11967,8 @@ fn genVarDbgInfo( |
| 11901 | mcv: MCValue, | 11967 | mcv: MCValue, |
| 11902 | name: [:0]const u8, | 11968 | name: [:0]const u8, |
| 11903 | ) !void { | 11969 | ) !void { |
| 11904 | const mod = self.bin_file.comp.module.?; | 11970 | const pt = self.pt; |
| 11971 | const mod = pt.zcu; | ||
| 11905 | const is_ptr = switch (tag) { | 11972 | const is_ptr = switch (tag) { |
| 11906 | .dbg_var_ptr => true, | 11973 | .dbg_var_ptr => true, |
| 11907 | .dbg_var_val => false, | 11974 | .dbg_var_val => false, |
| ... | @@ -12020,7 +12087,8 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12020,7 +12087,8 @@ fn genCall(self: *Self, info: union(enum) { |
| 12020 | callee: []const u8, | 12087 | callee: []const u8, |
| 12021 | }, | 12088 | }, |
| 12022 | }, arg_types: []const Type, args: []const MCValue) !MCValue { | 12089 | }, arg_types: []const Type, args: []const MCValue) !MCValue { |
| 12023 | const mod = self.bin_file.comp.module.?; | 12090 | const pt = self.pt; |
| 12091 | const mod = pt.zcu; | ||
| 12024 | 12092 | ||
| 12025 | const fn_ty = switch (info) { | 12093 | const fn_ty = switch (info) { |
| 12026 | .air => |callee| fn_info: { | 12094 | .air => |callee| fn_info: { |
| ... | @@ -12031,7 +12099,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12031,7 +12099,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12031 | else => unreachable, | 12099 | else => unreachable, |
| 12032 | }; | 12100 | }; |
| 12033 | }, | 12101 | }, |
| 12034 | .lib => |lib| try mod.funcType(.{ | 12102 | .lib => |lib| try pt.funcType(.{ |
| 12035 | .param_types = lib.param_types, | 12103 | .param_types = lib.param_types, |
| 12036 | .return_type = lib.return_type, | 12104 | .return_type = lib.return_type, |
| 12037 | .cc = .C, | 12105 | .cc = .C, |
| ... | @@ -12101,7 +12169,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12101,7 +12169,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12101 | try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs)); | 12169 | try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs)); |
| 12102 | }, | 12170 | }, |
| 12103 | .indirect => |reg_off| { | 12171 | .indirect => |reg_off| { |
| 12104 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod)); | 12172 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, pt)); |
| 12105 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); | 12173 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); |
| 12106 | try self.register_manager.getReg(reg_off.reg, null); | 12174 | try self.register_manager.getReg(reg_off.reg, null); |
| 12107 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); | 12175 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); |
| ... | @@ -12173,7 +12241,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12173,7 +12241,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12173 | .none, .unreach => {}, | 12241 | .none, .unreach => {}, |
| 12174 | .indirect => |reg_off| { | 12242 | .indirect => |reg_off| { |
| 12175 | const ret_ty = Type.fromInterned(fn_info.return_type); | 12243 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 12176 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, mod)); | 12244 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt)); |
| 12177 | try self.genSetReg(reg_off.reg, Type.usize, .{ | 12245 | try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 12178 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 12246 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 12179 | }, .{}); | 12247 | }, .{}); |
| ... | @@ -12188,14 +12256,14 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12188,14 +12256,14 @@ fn genCall(self: *Self, info: union(enum) { |
| 12188 | .none, .load_frame => {}, | 12256 | .none, .load_frame => {}, |
| 12189 | .register => |dst_reg| switch (fn_info.cc) { | 12257 | .register => |dst_reg| switch (fn_info.cc) { |
| 12190 | else => try self.genSetReg( | 12258 | else => try self.genSetReg( |
| 12191 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))), | 12259 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(pt))), |
| 12192 | arg_ty, | 12260 | arg_ty, |
| 12193 | src_arg, | 12261 | src_arg, |
| 12194 | .{}, | 12262 | .{}, |
| 12195 | ), | 12263 | ), |
| 12196 | .C, .SysV, .Win64 => { | 12264 | .C, .SysV, .Win64 => { |
| 12197 | const promoted_ty = self.promoteInt(arg_ty); | 12265 | const promoted_ty = self.promoteInt(arg_ty); |
| 12198 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod)); | 12266 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(pt)); |
| 12199 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); | 12267 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); |
| 12200 | try self.genSetReg(dst_alias, promoted_ty, src_arg, .{}); | 12268 | try self.genSetReg(dst_alias, promoted_ty, src_arg, .{}); |
| 12201 | if (promoted_ty.toIntern() != arg_ty.toIntern()) | 12269 | if (promoted_ty.toIntern() != arg_ty.toIntern()) |
| ... | @@ -12246,7 +12314,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12246,7 +12314,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12246 | // Due to incremental compilation, how function calls are generated depends | 12314 | // Due to incremental compilation, how function calls are generated depends |
| 12247 | // on linking. | 12315 | // on linking. |
| 12248 | switch (info) { | 12316 | switch (info) { |
| 12249 | .air => |callee| if (try self.air.value(callee, mod)) |func_value| { | 12317 | .air => |callee| if (try self.air.value(callee, pt)) |func_value| { |
| 12250 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); | 12318 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); |
| 12251 | switch (switch (func_key) { | 12319 | switch (switch (func_key) { |
| 12252 | else => func_key, | 12320 | else => func_key, |
| ... | @@ -12332,7 +12400,8 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12332,7 +12400,8 @@ fn genCall(self: *Self, info: union(enum) { |
| 12332 | } | 12400 | } |
| 12333 | 12401 | ||
| 12334 | fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | 12402 | fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 12335 | const mod = self.bin_file.comp.module.?; | 12403 | const pt = self.pt; |
| 12404 | const mod = pt.zcu; | ||
| 12336 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 12405 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 12337 | 12406 | ||
| 12338 | const ret_ty = self.fn_type.fnReturnType(mod); | 12407 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | @@ -12387,7 +12456,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12387,7 +12456,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 12387 | } | 12456 | } |
| 12388 | 12457 | ||
| 12389 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | 12458 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12390 | const mod = self.bin_file.comp.module.?; | 12459 | const pt = self.pt; |
| 12460 | const mod = pt.zcu; | ||
| 12391 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 12461 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 12392 | var ty = self.typeOf(bin_op.lhs); | 12462 | var ty = self.typeOf(bin_op.lhs); |
| 12393 | var null_compare: ?Mir.Inst.Index = null; | 12463 | var null_compare: ?Mir.Inst.Index = null; |
| ... | @@ -12457,9 +12527,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -12457,9 +12527,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12457 | }, | 12527 | }, |
| 12458 | .Optional => if (!ty.optionalReprIsPayload(mod)) { | 12528 | .Optional => if (!ty.optionalReprIsPayload(mod)) { |
| 12459 | const opt_ty = ty; | 12529 | const opt_ty = ty; |
| 12460 | const opt_abi_size: u31 = @intCast(opt_ty.abiSize(mod)); | 12530 | const opt_abi_size: u31 = @intCast(opt_ty.abiSize(pt)); |
| 12461 | ty = opt_ty.optionalChild(mod); | 12531 | ty = opt_ty.optionalChild(mod); |
| 12462 | const payload_abi_size: u31 = @intCast(ty.abiSize(mod)); | 12532 | const payload_abi_size: u31 = @intCast(ty.abiSize(pt)); |
| 12463 | 12533 | ||
| 12464 | const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 12534 | const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 12465 | const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg); | 12535 | const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg); |
| ... | @@ -12518,7 +12588,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -12518,7 +12588,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12518 | 12588 | ||
| 12519 | switch (ty.zigTypeTag(mod)) { | 12589 | switch (ty.zigTypeTag(mod)) { |
| 12520 | else => { | 12590 | else => { |
| 12521 | const abi_size: u16 = @intCast(ty.abiSize(mod)); | 12591 | const abi_size: u16 = @intCast(ty.abiSize(pt)); |
| 12522 | const may_flip: enum { | 12592 | const may_flip: enum { |
| 12523 | may_flip, | 12593 | may_flip, |
| 12524 | must_flip, | 12594 | must_flip, |
| ... | @@ -12845,7 +12915,8 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12845,7 +12915,8 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| 12845 | } | 12915 | } |
| 12846 | 12916 | ||
| 12847 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | 12917 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 12848 | const mod = self.bin_file.comp.module.?; | 12918 | const pt = self.pt; |
| 12919 | const mod = pt.zcu; | ||
| 12849 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 12920 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 12850 | 12921 | ||
| 12851 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 12922 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | @@ -12856,7 +12927,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12856,7 +12927,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 12856 | try self.spillEflagsIfOccupied(); | 12927 | try self.spillEflagsIfOccupied(); |
| 12857 | 12928 | ||
| 12858 | const op_ty = self.typeOf(un_op); | 12929 | const op_ty = self.typeOf(un_op); |
| 12859 | const op_abi_size: u32 = @intCast(op_ty.abiSize(mod)); | 12930 | const op_abi_size: u32 = @intCast(op_ty.abiSize(pt)); |
| 12860 | const op_mcv = try self.resolveInst(un_op); | 12931 | const op_mcv = try self.resolveInst(un_op); |
| 12861 | const dst_reg = switch (op_mcv) { | 12932 | const dst_reg = switch (op_mcv) { |
| 12862 | .register => |reg| reg, | 12933 | .register => |reg| reg, |
| ... | @@ -12987,8 +13058,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12987,8 +13058,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 12987 | } | 13058 | } |
| 12988 | 13059 | ||
| 12989 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { | 13060 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { |
| 12990 | const mod = self.bin_file.comp.module.?; | 13061 | const pt = self.pt; |
| 12991 | const abi_size = ty.abiSize(mod); | 13062 | const abi_size = ty.abiSize(pt); |
| 12992 | switch (mcv) { | 13063 | switch (mcv) { |
| 12993 | .eflags => |cc| { | 13064 | .eflags => |cc| { |
| 12994 | // Here we map the opposites since the jump is to the false branch. | 13065 | // Here we map the opposites since the jump is to the false branch. |
| ... | @@ -13060,7 +13131,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13060,7 +13131,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13060 | } | 13131 | } |
| 13061 | 13132 | ||
| 13062 | fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { | 13133 | fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { |
| 13063 | const mod = self.bin_file.comp.module.?; | 13134 | const pt = self.pt; |
| 13135 | const mod = pt.zcu; | ||
| 13064 | switch (opt_mcv) { | 13136 | switch (opt_mcv) { |
| 13065 | .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() }, | 13137 | .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() }, |
| 13066 | else => {}, | 13138 | else => {}, |
| ... | @@ -13073,7 +13145,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13073,7 +13145,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13073 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | 13145 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) |
| 13074 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } | 13146 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } |
| 13075 | else | 13147 | else |
| 13076 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; | 13148 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; |
| 13077 | 13149 | ||
| 13078 | self.eflags_inst = inst; | 13150 | self.eflags_inst = inst; |
| 13079 | switch (opt_mcv) { | 13151 | switch (opt_mcv) { |
| ... | @@ -13098,14 +13170,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13098,14 +13170,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13098 | 13170 | ||
| 13099 | .register => |opt_reg| { | 13171 | .register => |opt_reg| { |
| 13100 | if (some_info.off == 0) { | 13172 | if (some_info.off == 0) { |
| 13101 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 13173 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); |
| 13102 | const alias_reg = registerAlias(opt_reg, some_abi_size); | 13174 | const alias_reg = registerAlias(opt_reg, some_abi_size); |
| 13103 | assert(some_abi_size * 8 == alias_reg.bitSize()); | 13175 | assert(some_abi_size * 8 == alias_reg.bitSize()); |
| 13104 | try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg); | 13176 | try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg); |
| 13105 | return .{ .eflags = .z }; | 13177 | return .{ .eflags = .z }; |
| 13106 | } | 13178 | } |
| 13107 | assert(some_info.ty.ip_index == .bool_type); | 13179 | assert(some_info.ty.ip_index == .bool_type); |
| 13108 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(mod)); | 13180 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt)); |
| 13109 | try self.asmRegisterImmediate( | 13181 | try self.asmRegisterImmediate( |
| 13110 | .{ ._, .bt }, | 13182 | .{ ._, .bt }, |
| 13111 | registerAlias(opt_reg, opt_abi_size), | 13183 | registerAlias(opt_reg, opt_abi_size), |
| ... | @@ -13125,7 +13197,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13125,7 +13197,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13125 | defer self.register_manager.unlockReg(addr_reg_lock); | 13197 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 13126 | 13198 | ||
| 13127 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); | 13199 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); |
| 13128 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 13200 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); |
| 13129 | try self.asmMemoryImmediate( | 13201 | try self.asmMemoryImmediate( |
| 13130 | .{ ._, .cmp }, | 13202 | .{ ._, .cmp }, |
| 13131 | .{ | 13203 | .{ |
| ... | @@ -13141,7 +13213,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13141,7 +13213,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13141 | }, | 13213 | }, |
| 13142 | 13214 | ||
| 13143 | .indirect, .load_frame => { | 13215 | .indirect, .load_frame => { |
| 13144 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 13216 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); |
| 13145 | try self.asmMemoryImmediate( | 13217 | try self.asmMemoryImmediate( |
| 13146 | .{ ._, .cmp }, | 13218 | .{ ._, .cmp }, |
| 13147 | switch (opt_mcv) { | 13219 | switch (opt_mcv) { |
| ... | @@ -13169,7 +13241,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13169,7 +13241,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13169 | } | 13241 | } |
| 13170 | 13242 | ||
| 13171 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { | 13243 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 13172 | const mod = self.bin_file.comp.module.?; | 13244 | const pt = self.pt; |
| 13245 | const mod = pt.zcu; | ||
| 13173 | const opt_ty = ptr_ty.childType(mod); | 13246 | const opt_ty = ptr_ty.childType(mod); |
| 13174 | const pl_ty = opt_ty.optionalChild(mod); | 13247 | const pl_ty = opt_ty.optionalChild(mod); |
| 13175 | 13248 | ||
| ... | @@ -13178,7 +13251,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -13178,7 +13251,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13178 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | 13251 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) |
| 13179 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } | 13252 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } |
| 13180 | else | 13253 | else |
| 13181 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; | 13254 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; |
| 13182 | 13255 | ||
| 13183 | const ptr_reg = switch (ptr_mcv) { | 13256 | const ptr_reg = switch (ptr_mcv) { |
| 13184 | .register => |reg| reg, | 13257 | .register => |reg| reg, |
| ... | @@ -13187,7 +13260,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -13187,7 +13260,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13187 | const ptr_lock = self.register_manager.lockReg(ptr_reg); | 13260 | const ptr_lock = self.register_manager.lockReg(ptr_reg); |
| 13188 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | 13261 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 13189 | 13262 | ||
| 13190 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 13263 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); |
| 13191 | try self.asmMemoryImmediate( | 13264 | try self.asmMemoryImmediate( |
| 13192 | .{ ._, .cmp }, | 13265 | .{ ._, .cmp }, |
| 13193 | .{ | 13266 | .{ |
| ... | @@ -13205,13 +13278,14 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -13205,13 +13278,14 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13205 | } | 13278 | } |
| 13206 | 13279 | ||
| 13207 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { | 13280 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { |
| 13208 | const mod = self.bin_file.comp.module.?; | 13281 | const pt = self.pt; |
| 13282 | const mod = pt.zcu; | ||
| 13209 | const err_ty = eu_ty.errorUnionSet(mod); | 13283 | const err_ty = eu_ty.errorUnionSet(mod); |
| 13210 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | 13284 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false |
| 13211 | 13285 | ||
| 13212 | try self.spillEflagsIfOccupied(); | 13286 | try self.spillEflagsIfOccupied(); |
| 13213 | 13287 | ||
| 13214 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); | 13288 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt)); |
| 13215 | switch (eu_mcv) { | 13289 | switch (eu_mcv) { |
| 13216 | .register => |reg| { | 13290 | .register => |reg| { |
| 13217 | const eu_lock = self.register_manager.lockReg(reg); | 13291 | const eu_lock = self.register_manager.lockReg(reg); |
| ... | @@ -13253,7 +13327,8 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) | ... | @@ -13253,7 +13327,8 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) |
| 13253 | } | 13327 | } |
| 13254 | 13328 | ||
| 13255 | fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { | 13329 | fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 13256 | const mod = self.bin_file.comp.module.?; | 13330 | const pt = self.pt; |
| 13331 | const mod = pt.zcu; | ||
| 13257 | const eu_ty = ptr_ty.childType(mod); | 13332 | const eu_ty = ptr_ty.childType(mod); |
| 13258 | const err_ty = eu_ty.errorUnionSet(mod); | 13333 | const err_ty = eu_ty.errorUnionSet(mod); |
| 13259 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | 13334 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false |
| ... | @@ -13267,7 +13342,7 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV | ... | @@ -13267,7 +13342,7 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV |
| 13267 | const ptr_lock = self.register_manager.lockReg(ptr_reg); | 13342 | const ptr_lock = self.register_manager.lockReg(ptr_reg); |
| 13268 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | 13343 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 13269 | 13344 | ||
| 13270 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); | 13345 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt)); |
| 13271 | try self.asmMemoryImmediate( | 13346 | try self.asmMemoryImmediate( |
| 13272 | .{ ._, .cmp }, | 13347 | .{ ._, .cmp }, |
| 13273 | .{ | 13348 | .{ |
| ... | @@ -13539,12 +13614,12 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) void { | ... | @@ -13539,12 +13614,12 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) void { |
| 13539 | } | 13614 | } |
| 13540 | 13615 | ||
| 13541 | fn airBr(self: *Self, inst: Air.Inst.Index) !void { | 13616 | fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13542 | const mod = self.bin_file.comp.module.?; | 13617 | const pt = self.pt; |
| 13543 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 13618 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 13544 | 13619 | ||
| 13545 | const block_ty = self.typeOfIndex(br.block_inst); | 13620 | const block_ty = self.typeOfIndex(br.block_inst); |
| 13546 | const block_unused = | 13621 | const block_unused = |
| 13547 | !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst); | 13622 | !block_ty.hasRuntimeBitsIgnoreComptime(pt) or self.liveness.isUnused(br.block_inst); |
| 13548 | const block_tracking = self.inst_tracking.getPtr(br.block_inst).?; | 13623 | const block_tracking = self.inst_tracking.getPtr(br.block_inst).?; |
| 13549 | const block_data = self.blocks.getPtr(br.block_inst).?; | 13624 | const block_data = self.blocks.getPtr(br.block_inst).?; |
| 13550 | const first_br = block_data.relocs.items.len == 0; | 13625 | const first_br = block_data.relocs.items.len == 0; |
| ... | @@ -13600,7 +13675,8 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13600,7 +13675,8 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13600 | } | 13675 | } |
| 13601 | 13676 | ||
| 13602 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | 13677 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13603 | const mod = self.bin_file.comp.module.?; | 13678 | const pt = self.pt; |
| 13679 | const mod = pt.zcu; | ||
| 13604 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 13680 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 13605 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); | 13681 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 13606 | const clobbers_len: u31 = @truncate(extra.data.flags); | 13682 | const clobbers_len: u31 = @truncate(extra.data.flags); |
| ... | @@ -13664,7 +13740,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13664,7 +13740,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13664 | 'x' => abi.RegisterClass.sse, | 13740 | 'x' => abi.RegisterClass.sse, |
| 13665 | else => unreachable, | 13741 | else => unreachable, |
| 13666 | }) orelse return self.fail("ran out of registers lowering inline asm", .{}), | 13742 | }) orelse return self.fail("ran out of registers lowering inline asm", .{}), |
| 13667 | @intCast(ty.abiSize(mod)), | 13743 | @intCast(ty.abiSize(pt)), |
| 13668 | ) | 13744 | ) |
| 13669 | else if (mem.eql(u8, rest, "m")) | 13745 | else if (mem.eql(u8, rest, "m")) |
| 13670 | if (output != .none) null else return self.fail( | 13746 | if (output != .none) null else return self.fail( |
| ... | @@ -13734,7 +13810,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13734,7 +13810,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13734 | break :arg input_mcv; | 13810 | break :arg input_mcv; |
| 13735 | const reg = try self.register_manager.allocReg(null, rc); | 13811 | const reg = try self.register_manager.allocReg(null, rc); |
| 13736 | try self.genSetReg(reg, ty, input_mcv, .{}); | 13812 | try self.genSetReg(reg, ty, input_mcv, .{}); |
| 13737 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(mod))) }; | 13813 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(pt))) }; |
| 13738 | } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) | 13814 | } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) |
| 13739 | switch (input_mcv) { | 13815 | switch (input_mcv) { |
| 13740 | .immediate => |imm| .{ .immediate = imm }, | 13816 | .immediate => |imm| .{ .immediate = imm }, |
| ... | @@ -14310,18 +14386,19 @@ const MoveStrategy = union(enum) { | ... | @@ -14310,18 +14386,19 @@ const MoveStrategy = union(enum) { |
| 14310 | } | 14386 | } |
| 14311 | }; | 14387 | }; |
| 14312 | fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy { | 14388 | fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy { |
| 14313 | const mod = self.bin_file.comp.module.?; | 14389 | const pt = self.pt; |
| 14390 | const mod = pt.zcu; | ||
| 14314 | switch (class) { | 14391 | switch (class) { |
| 14315 | .general_purpose, .segment => return .{ .move = .{ ._, .mov } }, | 14392 | .general_purpose, .segment => return .{ .move = .{ ._, .mov } }, |
| 14316 | .x87 => return .x87_load_store, | 14393 | .x87 => return .x87_load_store, |
| 14317 | .mmx => {}, | 14394 | .mmx => {}, |
| 14318 | .sse => switch (ty.zigTypeTag(mod)) { | 14395 | .sse => switch (ty.zigTypeTag(mod)) { |
| 14319 | else => { | 14396 | else => { |
| 14320 | const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none); | 14397 | const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none); |
| 14321 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ | 14398 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ |
| 14322 | .integer, .sse, .sseup, .memory, .float, .float_combine, | 14399 | .integer, .sse, .sseup, .memory, .float, .float_combine, |
| 14323 | }) == null); | 14400 | }) == null); |
| 14324 | const abi_size = ty.abiSize(mod); | 14401 | const abi_size = ty.abiSize(pt); |
| 14325 | if (abi_size < 4 or | 14402 | if (abi_size < 4 or |
| 14326 | std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) { | 14403 | std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) { |
| 14327 | 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ | 14404 | 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ |
| ... | @@ -14532,7 +14609,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo | ... | @@ -14532,7 +14609,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14532 | }, | 14609 | }, |
| 14533 | .ip => {}, | 14610 | .ip => {}, |
| 14534 | } | 14611 | } |
| 14535 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)}); | 14612 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(pt)}); |
| 14536 | } | 14613 | } |
| 14537 | 14614 | ||
| 14538 | const CopyOptions = struct { | 14615 | const CopyOptions = struct { |
| ... | @@ -14540,7 +14617,7 @@ const CopyOptions = struct { | ... | @@ -14540,7 +14617,7 @@ const CopyOptions = struct { |
| 14540 | }; | 14617 | }; |
| 14541 | 14618 | ||
| 14542 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void { | 14619 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void { |
| 14543 | const mod = self.bin_file.comp.module.?; | 14620 | const pt = self.pt; |
| 14544 | 14621 | ||
| 14545 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 14622 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 14546 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 14623 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -14601,7 +14678,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy | ... | @@ -14601,7 +14678,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy |
| 14601 | opts, | 14678 | opts, |
| 14602 | ), | 14679 | ), |
| 14603 | else => return self.fail("TODO implement genCopy for {s} of {}", .{ | 14680 | else => return self.fail("TODO implement genCopy for {s} of {}", .{ |
| 14604 | @tagName(src_mcv), ty.fmt(mod), | 14681 | @tagName(src_mcv), ty.fmt(pt), |
| 14605 | }), | 14682 | }), |
| 14606 | }; | 14683 | }; |
| 14607 | defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock); | 14684 | defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock); |
| ... | @@ -14617,7 +14694,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy | ... | @@ -14617,7 +14694,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy |
| 14617 | } }, | 14694 | } }, |
| 14618 | else => unreachable, | 14695 | else => unreachable, |
| 14619 | }, opts); | 14696 | }, opts); |
| 14620 | part_disp += @intCast(dst_ty.abiSize(mod)); | 14697 | part_disp += @intCast(dst_ty.abiSize(pt)); |
| 14621 | } | 14698 | } |
| 14622 | }, | 14699 | }, |
| 14623 | .indirect => |reg_off| try self.genSetMem( | 14700 | .indirect => |reg_off| try self.genSetMem( |
| ... | @@ -14658,9 +14735,10 @@ fn genSetReg( | ... | @@ -14658,9 +14735,10 @@ fn genSetReg( |
| 14658 | src_mcv: MCValue, | 14735 | src_mcv: MCValue, |
| 14659 | opts: CopyOptions, | 14736 | opts: CopyOptions, |
| 14660 | ) InnerError!void { | 14737 | ) InnerError!void { |
| 14661 | const mod = self.bin_file.comp.module.?; | 14738 | const pt = self.pt; |
| 14662 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 14739 | const mod = pt.zcu; |
| 14663 | if (ty.bitSize(mod) > dst_reg.bitSize()) | 14740 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 14741 | if (ty.bitSize(pt) > dst_reg.bitSize()) | ||
| 14664 | return self.fail("genSetReg called with a value larger than dst_reg", .{}); | 14742 | return self.fail("genSetReg called with a value larger than dst_reg", .{}); |
| 14665 | switch (src_mcv) { | 14743 | switch (src_mcv) { |
| 14666 | .none, | 14744 | .none, |
| ... | @@ -14686,7 +14764,7 @@ fn genSetReg( | ... | @@ -14686,7 +14764,7 @@ fn genSetReg( |
| 14686 | ), | 14764 | ), |
| 14687 | else => unreachable, | 14765 | else => unreachable, |
| 14688 | }, | 14766 | }, |
| 14689 | .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try mod.undefValue(ty)), opts), | 14767 | .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try pt.undefValue(ty)), opts), |
| 14690 | .ip => unreachable, | 14768 | .ip => unreachable, |
| 14691 | }, | 14769 | }, |
| 14692 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), | 14770 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| ... | @@ -14797,7 +14875,7 @@ fn genSetReg( | ... | @@ -14797,7 +14875,7 @@ fn genSetReg( |
| 14797 | 80 => null, | 14875 | 80 => null, |
| 14798 | else => unreachable, | 14876 | else => unreachable, |
| 14799 | }, | 14877 | }, |
| 14800 | }) orelse return self.fail("TODO implement genSetReg for {}", .{ty.fmt(mod)}), | 14878 | }) orelse return self.fail("TODO implement genSetReg for {}", .{ty.fmt(pt)}), |
| 14801 | registerAlias(dst_reg, abi_size), | 14879 | registerAlias(dst_reg, abi_size), |
| 14802 | registerAlias(src_reg, abi_size), | 14880 | registerAlias(src_reg, abi_size), |
| 14803 | ), | 14881 | ), |
| ... | @@ -14847,7 +14925,7 @@ fn genSetReg( | ... | @@ -14847,7 +14925,7 @@ fn genSetReg( |
| 14847 | return (try self.moveStrategy( | 14925 | return (try self.moveStrategy( |
| 14848 | ty, | 14926 | ty, |
| 14849 | dst_reg.class(), | 14927 | dst_reg.class(), |
| 14850 | ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))), | 14928 | ty.abiAlignment(pt).check(@as(u32, @bitCast(small_addr))), |
| 14851 | )).read(self, registerAlias(dst_reg, abi_size), .{ | 14929 | )).read(self, registerAlias(dst_reg, abi_size), .{ |
| 14852 | .base = .{ .reg = .ds }, | 14930 | .base = .{ .reg = .ds }, |
| 14853 | .mod = .{ .rm = .{ | 14931 | .mod = .{ .rm = .{ |
| ... | @@ -14967,8 +15045,9 @@ fn genSetMem( | ... | @@ -14967,8 +15045,9 @@ fn genSetMem( |
| 14967 | src_mcv: MCValue, | 15045 | src_mcv: MCValue, |
| 14968 | opts: CopyOptions, | 15046 | opts: CopyOptions, |
| 14969 | ) InnerError!void { | 15047 | ) InnerError!void { |
| 14970 | const mod = self.bin_file.comp.module.?; | 15048 | const pt = self.pt; |
| 14971 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 15049 | const mod = pt.zcu; |
| 15050 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | ||
| 14972 | const dst_ptr_mcv: MCValue = switch (base) { | 15051 | const dst_ptr_mcv: MCValue = switch (base) { |
| 14973 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, | 15052 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 14974 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | 15053 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| ... | @@ -15094,21 +15173,21 @@ fn genSetMem( | ... | @@ -15094,21 +15173,21 @@ fn genSetMem( |
| 15094 | var part_disp: i32 = disp; | 15173 | var part_disp: i32 = disp; |
| 15095 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { | 15174 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { |
| 15096 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts); | 15175 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts); |
| 15097 | part_disp += @intCast(src_ty.abiSize(mod)); | 15176 | part_disp += @intCast(src_ty.abiSize(pt)); |
| 15098 | } | 15177 | } |
| 15099 | }, | 15178 | }, |
| 15100 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { | 15179 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { |
| 15101 | .Struct => { | 15180 | .Struct => { |
| 15102 | try self.genSetMem( | 15181 | try self.genSetMem( |
| 15103 | base, | 15182 | base, |
| 15104 | disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), | 15183 | disp + @as(i32, @intCast(ty.structFieldOffset(0, pt))), |
| 15105 | ty.structFieldType(0, mod), | 15184 | ty.structFieldType(0, mod), |
| 15106 | .{ .register = ro.reg }, | 15185 | .{ .register = ro.reg }, |
| 15107 | opts, | 15186 | opts, |
| 15108 | ); | 15187 | ); |
| 15109 | try self.genSetMem( | 15188 | try self.genSetMem( |
| 15110 | base, | 15189 | base, |
| 15111 | disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), | 15190 | disp + @as(i32, @intCast(ty.structFieldOffset(1, pt))), |
| 15112 | ty.structFieldType(1, mod), | 15191 | ty.structFieldType(1, mod), |
| 15113 | .{ .eflags = ro.eflags }, | 15192 | .{ .eflags = ro.eflags }, |
| 15114 | opts, | 15193 | opts, |
| ... | @@ -15120,14 +15199,14 @@ fn genSetMem( | ... | @@ -15120,14 +15199,14 @@ fn genSetMem( |
| 15120 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts); | 15199 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts); |
| 15121 | try self.genSetMem( | 15200 | try self.genSetMem( |
| 15122 | base, | 15201 | base, |
| 15123 | disp + @as(i32, @intCast(child_ty.abiSize(mod))), | 15202 | disp + @as(i32, @intCast(child_ty.abiSize(pt))), |
| 15124 | Type.bool, | 15203 | Type.bool, |
| 15125 | .{ .eflags = ro.eflags }, | 15204 | .{ .eflags = ro.eflags }, |
| 15126 | opts, | 15205 | opts, |
| 15127 | ); | 15206 | ); |
| 15128 | }, | 15207 | }, |
| 15129 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ | 15208 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ |
| 15130 | @tagName(src_mcv), ty.fmt(mod), | 15209 | @tagName(src_mcv), ty.fmt(pt), |
| 15131 | }), | 15210 | }), |
| 15132 | }, | 15211 | }, |
| 15133 | .register_offset, | 15212 | .register_offset, |
| ... | @@ -15236,8 +15315,9 @@ fn genLazySymbolRef( | ... | @@ -15236,8 +15315,9 @@ fn genLazySymbolRef( |
| 15236 | reg: Register, | 15315 | reg: Register, |
| 15237 | lazy_sym: link.File.LazySymbol, | 15316 | lazy_sym: link.File.LazySymbol, |
| 15238 | ) InnerError!void { | 15317 | ) InnerError!void { |
| 15318 | const pt = self.pt; | ||
| 15239 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 15319 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 15240 | const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err| | 15320 | const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err| |
| 15241 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 15321 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 15242 | const sym = elf_file.symbol(sym_index); | 15322 | const sym = elf_file.symbol(sym_index); |
| 15243 | if (self.mod.pic) { | 15323 | if (self.mod.pic) { |
| ... | @@ -15273,7 +15353,7 @@ fn genLazySymbolRef( | ... | @@ -15273,7 +15353,7 @@ fn genLazySymbolRef( |
| 15273 | } | 15353 | } |
| 15274 | } | 15354 | } |
| 15275 | } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { | 15355 | } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { |
| 15276 | const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 15356 | const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| |
| 15277 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 15357 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 15278 | var atom = p9_file.getAtom(atom_index); | 15358 | var atom = p9_file.getAtom(atom_index); |
| 15279 | _ = atom.getOrCreateOffsetTableEntry(p9_file); | 15359 | _ = atom.getOrCreateOffsetTableEntry(p9_file); |
| ... | @@ -15300,7 +15380,7 @@ fn genLazySymbolRef( | ... | @@ -15300,7 +15380,7 @@ fn genLazySymbolRef( |
| 15300 | else => unreachable, | 15380 | else => unreachable, |
| 15301 | } | 15381 | } |
| 15302 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 15382 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 15303 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 15383 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err| |
| 15304 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 15384 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 15305 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 15385 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 15306 | switch (tag) { | 15386 | switch (tag) { |
| ... | @@ -15314,7 +15394,7 @@ fn genLazySymbolRef( | ... | @@ -15314,7 +15394,7 @@ fn genLazySymbolRef( |
| 15314 | else => unreachable, | 15394 | else => unreachable, |
| 15315 | } | 15395 | } |
| 15316 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 15396 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 15317 | const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err| | 15397 | const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err| |
| 15318 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 15398 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 15319 | const sym = macho_file.getSymbol(sym_index); | 15399 | const sym = macho_file.getSymbol(sym_index); |
| 15320 | switch (tag) { | 15400 | switch (tag) { |
| ... | @@ -15353,7 +15433,8 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15353,7 +15433,8 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 15353 | } | 15433 | } |
| 15354 | 15434 | ||
| 15355 | fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | 15435 | fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15356 | const mod = self.bin_file.comp.module.?; | 15436 | const pt = self.pt; |
| 15437 | const mod = pt.zcu; | ||
| 15357 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 15438 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15358 | const dst_ty = self.typeOfIndex(inst); | 15439 | const dst_ty = self.typeOfIndex(inst); |
| 15359 | const src_ty = self.typeOf(ty_op.operand); | 15440 | const src_ty = self.typeOf(ty_op.operand); |
| ... | @@ -15366,10 +15447,10 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15366,10 +15447,10 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15366 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 15447 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 15367 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 15448 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 15368 | 15449 | ||
| 15369 | const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(mod) <= src_ty.abiSize(mod) and | 15450 | const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and |
| 15370 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { | 15451 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 15371 | const dst_mcv = try self.allocRegOrMem(inst, true); | 15452 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 15372 | try self.genCopy(switch (math.order(dst_ty.abiSize(mod), src_ty.abiSize(mod))) { | 15453 | try self.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) { |
| 15373 | .lt => dst_ty, | 15454 | .lt => dst_ty, |
| 15374 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, | 15455 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, |
| 15375 | .gt => src_ty, | 15456 | .gt => src_ty, |
| ... | @@ -15382,8 +15463,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15382,8 +15463,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15382 | if (dst_ty.isAbiInt(mod) and src_ty.isAbiInt(mod) and | 15463 | if (dst_ty.isAbiInt(mod) and src_ty.isAbiInt(mod) and |
| 15383 | dst_ty.intInfo(mod).signedness == src_ty.intInfo(mod).signedness) break :result dst_mcv; | 15464 | dst_ty.intInfo(mod).signedness == src_ty.intInfo(mod).signedness) break :result dst_mcv; |
| 15384 | 15465 | ||
| 15385 | const abi_size = dst_ty.abiSize(mod); | 15466 | const abi_size = dst_ty.abiSize(pt); |
| 15386 | const bit_size = dst_ty.bitSize(mod); | 15467 | const bit_size = dst_ty.bitSize(pt); |
| 15387 | if (abi_size * 8 <= bit_size or dst_ty.isVector(mod)) break :result dst_mcv; | 15468 | if (abi_size * 8 <= bit_size or dst_ty.isVector(mod)) break :result dst_mcv; |
| 15388 | 15469 | ||
| 15389 | const dst_limbs_len = math.divCeil(i32, @intCast(bit_size), 64) catch unreachable; | 15470 | const dst_limbs_len = math.divCeil(i32, @intCast(bit_size), 64) catch unreachable; |
| ... | @@ -15412,7 +15493,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15412,7 +15493,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15412 | } | 15493 | } |
| 15413 | 15494 | ||
| 15414 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | 15495 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 15415 | const mod = self.bin_file.comp.module.?; | 15496 | const pt = self.pt; |
| 15497 | const mod = pt.zcu; | ||
| 15416 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 15498 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15417 | 15499 | ||
| 15418 | const slice_ty = self.typeOfIndex(inst); | 15500 | const slice_ty = self.typeOfIndex(inst); |
| ... | @@ -15421,11 +15503,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15421,11 +15503,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 15421 | const array_ty = ptr_ty.childType(mod); | 15503 | const array_ty = ptr_ty.childType(mod); |
| 15422 | const array_len = array_ty.arrayLen(mod); | 15504 | const array_len = array_ty.arrayLen(mod); |
| 15423 | 15505 | ||
| 15424 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); | 15506 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); |
| 15425 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); | 15507 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); |
| 15426 | try self.genSetMem( | 15508 | try self.genSetMem( |
| 15427 | .{ .frame = frame_index }, | 15509 | .{ .frame = frame_index }, |
| 15428 | @intCast(ptr_ty.abiSize(mod)), | 15510 | @intCast(ptr_ty.abiSize(pt)), |
| 15429 | Type.usize, | 15511 | Type.usize, |
| 15430 | .{ .immediate = array_len }, | 15512 | .{ .immediate = array_len }, |
| 15431 | .{}, | 15513 | .{}, |
| ... | @@ -15436,14 +15518,15 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15436,14 +15518,15 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 15436 | } | 15518 | } |
| 15437 | 15519 | ||
| 15438 | fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | 15520 | fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15439 | const mod = self.bin_file.comp.module.?; | 15521 | const pt = self.pt; |
| 15522 | const mod = pt.zcu; | ||
| 15440 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 15523 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15441 | 15524 | ||
| 15442 | const dst_ty = self.typeOfIndex(inst); | 15525 | const dst_ty = self.typeOfIndex(inst); |
| 15443 | const dst_bits = dst_ty.floatBits(self.target.*); | 15526 | const dst_bits = dst_ty.floatBits(self.target.*); |
| 15444 | 15527 | ||
| 15445 | const src_ty = self.typeOf(ty_op.operand); | 15528 | const src_ty = self.typeOf(ty_op.operand); |
| 15446 | const src_bits: u32 = @intCast(src_ty.bitSize(mod)); | 15529 | const src_bits: u32 = @intCast(src_ty.bitSize(pt)); |
| 15447 | const src_signedness = | 15530 | const src_signedness = |
| 15448 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; | 15531 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; |
| 15449 | const src_size = math.divCeil(u32, @max(switch (src_signedness) { | 15532 | const src_size = math.divCeil(u32, @max(switch (src_signedness) { |
| ... | @@ -15458,7 +15541,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15458,7 +15541,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15458 | else => unreachable, | 15541 | else => unreachable, |
| 15459 | }) { | 15542 | }) { |
| 15460 | if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | 15543 | if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {} to {}", .{ |
| 15461 | src_ty.fmt(mod), dst_ty.fmt(mod), | 15544 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 15462 | }); | 15545 | }); |
| 15463 | 15546 | ||
| 15464 | var callee_buf: ["__floatun?i?f".len]u8 = undefined; | 15547 | var callee_buf: ["__floatun?i?f".len]u8 = undefined; |
| ... | @@ -15500,7 +15583,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15500,7 +15583,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15500 | }, | 15583 | }, |
| 15501 | else => null, | 15584 | else => null, |
| 15502 | }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | 15585 | }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{ |
| 15503 | src_ty.fmt(mod), dst_ty.fmt(mod), | 15586 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 15504 | }); | 15587 | }); |
| 15505 | const dst_alias = dst_reg.to128(); | 15588 | const dst_alias = dst_reg.to128(); |
| 15506 | const src_alias = registerAlias(src_reg, src_size); | 15589 | const src_alias = registerAlias(src_reg, src_size); |
| ... | @@ -15515,11 +15598,12 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15515,11 +15598,12 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15515 | } | 15598 | } |
| 15516 | 15599 | ||
| 15517 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { | 15600 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 15518 | const mod = self.bin_file.comp.module.?; | 15601 | const pt = self.pt; |
| 15602 | const mod = pt.zcu; | ||
| 15519 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 15603 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15520 | 15604 | ||
| 15521 | const dst_ty = self.typeOfIndex(inst); | 15605 | const dst_ty = self.typeOfIndex(inst); |
| 15522 | const dst_bits: u32 = @intCast(dst_ty.bitSize(mod)); | 15606 | const dst_bits: u32 = @intCast(dst_ty.bitSize(pt)); |
| 15523 | const dst_signedness = | 15607 | const dst_signedness = |
| 15524 | if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned; | 15608 | if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned; |
| 15525 | const dst_size = math.divCeil(u32, @max(switch (dst_signedness) { | 15609 | const dst_size = math.divCeil(u32, @max(switch (dst_signedness) { |
| ... | @@ -15537,7 +15621,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15537,7 +15621,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 15537 | else => unreachable, | 15621 | else => unreachable, |
| 15538 | }) { | 15622 | }) { |
| 15539 | if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {} to {}", .{ | 15623 | if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {} to {}", .{ |
| 15540 | src_ty.fmt(mod), dst_ty.fmt(mod), | 15624 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 15541 | }); | 15625 | }); |
| 15542 | 15626 | ||
| 15543 | var callee_buf: ["__fixuns?f?i".len]u8 = undefined; | 15627 | var callee_buf: ["__fixuns?f?i".len]u8 = undefined; |
| ... | @@ -15586,13 +15670,13 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15586,13 +15670,13 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 15586 | } | 15670 | } |
| 15587 | 15671 | ||
| 15588 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | 15672 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 15589 | const mod = self.bin_file.comp.module.?; | 15673 | const pt = self.pt; |
| 15590 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 15674 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 15591 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 15675 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 15592 | 15676 | ||
| 15593 | const ptr_ty = self.typeOf(extra.ptr); | 15677 | const ptr_ty = self.typeOf(extra.ptr); |
| 15594 | const val_ty = self.typeOf(extra.expected_value); | 15678 | const val_ty = self.typeOf(extra.expected_value); |
| 15595 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); | 15679 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); |
| 15596 | 15680 | ||
| 15597 | try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx }); | 15681 | try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx }); |
| 15598 | const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx }); | 15682 | const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx }); |
| ... | @@ -15682,7 +15766,8 @@ fn atomicOp( | ... | @@ -15682,7 +15766,8 @@ fn atomicOp( |
| 15682 | rmw_op: ?std.builtin.AtomicRmwOp, | 15766 | rmw_op: ?std.builtin.AtomicRmwOp, |
| 15683 | order: std.builtin.AtomicOrder, | 15767 | order: std.builtin.AtomicOrder, |
| 15684 | ) InnerError!MCValue { | 15768 | ) InnerError!MCValue { |
| 15685 | const mod = self.bin_file.comp.module.?; | 15769 | const pt = self.pt; |
| 15770 | const mod = pt.zcu; | ||
| 15686 | const ptr_lock = switch (ptr_mcv) { | 15771 | const ptr_lock = switch (ptr_mcv) { |
| 15687 | .register => |reg| self.register_manager.lockReg(reg), | 15772 | .register => |reg| self.register_manager.lockReg(reg), |
| 15688 | else => null, | 15773 | else => null, |
| ... | @@ -15695,7 +15780,7 @@ fn atomicOp( | ... | @@ -15695,7 +15780,7 @@ fn atomicOp( |
| 15695 | }; | 15780 | }; |
| 15696 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); | 15781 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); |
| 15697 | 15782 | ||
| 15698 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); | 15783 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); |
| 15699 | const mem_size = Memory.Size.fromSize(val_abi_size); | 15784 | const mem_size = Memory.Size.fromSize(val_abi_size); |
| 15700 | const ptr_mem: Memory = switch (ptr_mcv) { | 15785 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 15701 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), | 15786 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), |
| ... | @@ -15809,7 +15894,7 @@ fn atomicOp( | ... | @@ -15809,7 +15894,7 @@ fn atomicOp( |
| 15809 | }, | 15894 | }, |
| 15810 | else => unreachable, | 15895 | else => unreachable, |
| 15811 | }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{ | 15896 | }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{ |
| 15812 | @tagName(op), val_ty.fmt(mod), | 15897 | @tagName(op), val_ty.fmt(pt), |
| 15813 | }); | 15898 | }); |
| 15814 | try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{}); | 15899 | try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{}); |
| 15815 | switch (mir_tag[0]) { | 15900 | switch (mir_tag[0]) { |
| ... | @@ -16086,7 +16171,8 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr | ... | @@ -16086,7 +16171,8 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 16086 | } | 16171 | } |
| 16087 | 16172 | ||
| 16088 | fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | 16173 | fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16089 | const mod = self.bin_file.comp.module.?; | 16174 | const pt = self.pt; |
| 16175 | const mod = pt.zcu; | ||
| 16090 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 16176 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 16091 | 16177 | ||
| 16092 | result: { | 16178 | result: { |
| ... | @@ -16112,7 +16198,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -16112,7 +16198,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16112 | }; | 16198 | }; |
| 16113 | defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock); | 16199 | defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock); |
| 16114 | 16200 | ||
| 16115 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(mod)); | 16201 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt)); |
| 16116 | 16202 | ||
| 16117 | if (elem_abi_size == 1) { | 16203 | if (elem_abi_size == 1) { |
| 16118 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { | 16204 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { |
| ... | @@ -16185,7 +16271,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -16185,7 +16271,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16185 | self.performReloc(skip_reloc); | 16271 | self.performReloc(skip_reloc); |
| 16186 | }, | 16272 | }, |
| 16187 | .One => { | 16273 | .One => { |
| 16188 | const elem_ptr_ty = try mod.singleMutPtrType(elem_ty); | 16274 | const elem_ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 16189 | 16275 | ||
| 16190 | const len = dst_ptr_ty.childType(mod).arrayLen(mod); | 16276 | const len = dst_ptr_ty.childType(mod).arrayLen(mod); |
| 16191 | 16277 | ||
| ... | @@ -16214,7 +16300,8 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -16214,7 +16300,8 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16214 | } | 16300 | } |
| 16215 | 16301 | ||
| 16216 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | 16302 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16217 | const mod = self.bin_file.comp.module.?; | 16303 | const pt = self.pt; |
| 16304 | const mod = pt.zcu; | ||
| 16218 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 16305 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 16219 | 16306 | ||
| 16220 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); | 16307 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| ... | @@ -16246,13 +16333,13 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16246,13 +16333,13 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16246 | .{ .i_, .mul }, | 16333 | .{ .i_, .mul }, |
| 16247 | len_reg, | 16334 | len_reg, |
| 16248 | try dst_ptr.address().offset(8).deref().mem(self, .qword), | 16335 | try dst_ptr.address().offset(8).deref().mem(self, .qword), |
| 16249 | Immediate.s(@intCast(dst_ptr_ty.childType(mod).abiSize(mod))), | 16336 | Immediate.s(@intCast(dst_ptr_ty.childType(mod).abiSize(pt))), |
| 16250 | ); | 16337 | ); |
| 16251 | break :len .{ .register = len_reg }; | 16338 | break :len .{ .register = len_reg }; |
| 16252 | }, | 16339 | }, |
| 16253 | .One => len: { | 16340 | .One => len: { |
| 16254 | const array_ty = dst_ptr_ty.childType(mod); | 16341 | const array_ty = dst_ptr_ty.childType(mod); |
| 16255 | break :len .{ .immediate = array_ty.arrayLen(mod) * array_ty.childType(mod).abiSize(mod) }; | 16342 | break :len .{ .immediate = array_ty.arrayLen(mod) * array_ty.childType(mod).abiSize(pt) }; |
| 16256 | }, | 16343 | }, |
| 16257 | .C, .Many => unreachable, | 16344 | .C, .Many => unreachable, |
| 16258 | }; | 16345 | }; |
| ... | @@ -16269,7 +16356,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16269,7 +16356,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16269 | } | 16356 | } |
| 16270 | 16357 | ||
| 16271 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | 16358 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16272 | const mod = self.bin_file.comp.module.?; | 16359 | const pt = self.pt; |
| 16360 | const mod = pt.zcu; | ||
| 16273 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 16361 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 16274 | const inst_ty = self.typeOfIndex(inst); | 16362 | const inst_ty = self.typeOfIndex(inst); |
| 16275 | const enum_ty = self.typeOf(un_op); | 16363 | const enum_ty = self.typeOf(un_op); |
| ... | @@ -16278,8 +16366,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16278,8 +16366,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16278 | // We need a properly aligned and sized call frame to be able to call this function. | 16366 | // We need a properly aligned and sized call frame to be able to call this function. |
| 16279 | { | 16367 | { |
| 16280 | const needed_call_frame = FrameAlloc.init(.{ | 16368 | const needed_call_frame = FrameAlloc.init(.{ |
| 16281 | .size = inst_ty.abiSize(mod), | 16369 | .size = inst_ty.abiSize(pt), |
| 16282 | .alignment = inst_ty.abiAlignment(mod), | 16370 | .alignment = inst_ty.abiAlignment(pt), |
| 16283 | }); | 16371 | }); |
| 16284 | const frame_allocs_slice = self.frame_allocs.slice(); | 16372 | const frame_allocs_slice = self.frame_allocs.slice(); |
| 16285 | const stack_frame_size = | 16373 | const stack_frame_size = |
| ... | @@ -16311,7 +16399,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16311,7 +16399,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16311 | } | 16399 | } |
| 16312 | 16400 | ||
| 16313 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | 16401 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 16314 | const mod = self.bin_file.comp.module.?; | 16402 | const pt = self.pt; |
| 16403 | const mod = pt.zcu; | ||
| 16315 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 16404 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 16316 | 16405 | ||
| 16317 | const err_ty = self.typeOf(un_op); | 16406 | const err_ty = self.typeOf(un_op); |
| ... | @@ -16413,7 +16502,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16413,7 +16502,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 16413 | } | 16502 | } |
| 16414 | 16503 | ||
| 16415 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | 16504 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16416 | const mod = self.bin_file.comp.module.?; | 16505 | const pt = self.pt; |
| 16506 | const mod = pt.zcu; | ||
| 16417 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 16507 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 16418 | const vector_ty = self.typeOfIndex(inst); | 16508 | const vector_ty = self.typeOfIndex(inst); |
| 16419 | const vector_len = vector_ty.vectorLen(mod); | 16509 | const vector_len = vector_ty.vectorLen(mod); |
| ... | @@ -16495,15 +16585,15 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16495,15 +16585,15 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16495 | const src_mcv = try self.resolveInst(ty_op.operand); | 16585 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 16496 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 16586 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 16497 | mir_tag, | 16587 | mir_tag, |
| 16498 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))), | 16588 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))), |
| 16499 | try src_mcv.mem(self, self.memSize(scalar_ty)), | 16589 | try src_mcv.mem(self, self.memSize(scalar_ty)), |
| 16500 | ) else { | 16590 | ) else { |
| 16501 | if (mir_tag[0] == .v_i128) break :avx2; | 16591 | if (mir_tag[0] == .v_i128) break :avx2; |
| 16502 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); | 16592 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 16503 | try self.asmRegisterRegister( | 16593 | try self.asmRegisterRegister( |
| 16504 | mir_tag, | 16594 | mir_tag, |
| 16505 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))), | 16595 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))), |
| 16506 | registerAlias(dst_reg, @intCast(scalar_ty.abiSize(mod))), | 16596 | registerAlias(dst_reg, @intCast(scalar_ty.abiSize(pt))), |
| 16507 | ); | 16597 | ); |
| 16508 | } | 16598 | } |
| 16509 | break :result .{ .register = dst_reg }; | 16599 | break :result .{ .register = dst_reg }; |
| ... | @@ -16515,7 +16605,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16515,7 +16605,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16515 | try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{}); | 16605 | try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{}); |
| 16516 | if (vector_len == 1) break :result .{ .register = dst_reg }; | 16606 | if (vector_len == 1) break :result .{ .register = dst_reg }; |
| 16517 | 16607 | ||
| 16518 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))); | 16608 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))); |
| 16519 | const scalar_bits = scalar_ty.intInfo(mod).bits; | 16609 | const scalar_bits = scalar_ty.intInfo(mod).bits; |
| 16520 | if (switch (scalar_bits) { | 16610 | if (switch (scalar_bits) { |
| 16521 | 1...8 => true, | 16611 | 1...8 => true, |
| ... | @@ -16745,20 +16835,21 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16745,20 +16835,21 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16745 | else => unreachable, | 16835 | else => unreachable, |
| 16746 | }, | 16836 | }, |
| 16747 | } | 16837 | } |
| 16748 | return self.fail("TODO implement airSplat for {}", .{vector_ty.fmt(mod)}); | 16838 | return self.fail("TODO implement airSplat for {}", .{vector_ty.fmt(pt)}); |
| 16749 | }; | 16839 | }; |
| 16750 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 16840 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 16751 | } | 16841 | } |
| 16752 | 16842 | ||
| 16753 | fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | 16843 | fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16754 | const mod = self.bin_file.comp.module.?; | 16844 | const pt = self.pt; |
| 16845 | const mod = pt.zcu; | ||
| 16755 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 16846 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 16756 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 16847 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 16757 | const ty = self.typeOfIndex(inst); | 16848 | const ty = self.typeOfIndex(inst); |
| 16758 | const vec_len = ty.vectorLen(mod); | 16849 | const vec_len = ty.vectorLen(mod); |
| 16759 | const elem_ty = ty.childType(mod); | 16850 | const elem_ty = ty.childType(mod); |
| 16760 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); | 16851 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 16761 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 16852 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 16762 | const pred_ty = self.typeOf(pl_op.operand); | 16853 | const pred_ty = self.typeOf(pl_op.operand); |
| 16763 | 16854 | ||
| 16764 | const result = result: { | 16855 | const result = result: { |
| ... | @@ -16878,17 +16969,17 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16878,17 +16969,17 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16878 | else => unreachable, | 16969 | else => unreachable, |
| 16879 | }), | 16970 | }), |
| 16880 | ); | 16971 | ); |
| 16881 | } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)}); | 16972 | } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}); |
| 16882 | const elem_bits: u16 = @intCast(elem_abi_size * 8); | 16973 | const elem_bits: u16 = @intCast(elem_abi_size * 8); |
| 16883 | const mask_elem_ty = try mod.intType(.unsigned, elem_bits); | 16974 | const mask_elem_ty = try pt.intType(.unsigned, elem_bits); |
| 16884 | const mask_ty = try mod.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() }); | 16975 | const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() }); |
| 16885 | if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) { | 16976 | if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) { |
| 16886 | var mask_elems: [32]InternPool.Index = undefined; | 16977 | var mask_elems: [32]InternPool.Index = undefined; |
| 16887 | for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try mod.intern(.{ .int = .{ | 16978 | for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{ |
| 16888 | .ty = mask_elem_ty.toIntern(), | 16979 | .ty = mask_elem_ty.toIntern(), |
| 16889 | .storage = .{ .u64 = bit / elem_bits }, | 16980 | .storage = .{ .u64 = bit / elem_bits }, |
| 16890 | } }); | 16981 | } }); |
| 16891 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 16982 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 16892 | .ty = mask_ty.toIntern(), | 16983 | .ty = mask_ty.toIntern(), |
| 16893 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 16984 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 16894 | } }))); | 16985 | } }))); |
| ... | @@ -16906,14 +16997,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16906,14 +16997,14 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16906 | mask_alias, | 16997 | mask_alias, |
| 16907 | mask_mem, | 16998 | mask_mem, |
| 16908 | ); | 16999 | ); |
| 16909 | } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)}); | 17000 | } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}); |
| 16910 | { | 17001 | { |
| 16911 | var mask_elems: [32]InternPool.Index = undefined; | 17002 | var mask_elems: [32]InternPool.Index = undefined; |
| 16912 | for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try mod.intern(.{ .int = .{ | 17003 | for (mask_elems[0..vec_len], 0..) |*elem, bit| elem.* = try pt.intern(.{ .int = .{ |
| 16913 | .ty = mask_elem_ty.toIntern(), | 17004 | .ty = mask_elem_ty.toIntern(), |
| 16914 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, | 17005 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, |
| 16915 | } }); | 17006 | } }); |
| 16916 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17007 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 16917 | .ty = mask_ty.toIntern(), | 17008 | .ty = mask_ty.toIntern(), |
| 16918 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 17009 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 16919 | } }))); | 17010 | } }))); |
| ... | @@ -17014,7 +17105,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17014,7 +17105,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17014 | else => null, | 17105 | else => null, |
| 17015 | }, | 17106 | }, |
| 17016 | }, | 17107 | }, |
| 17017 | }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)}); | 17108 | }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}); |
| 17018 | if (has_avx) { | 17109 | if (has_avx) { |
| 17019 | const rhs_alias = if (rhs_mcv.isRegister()) | 17110 | const rhs_alias = if (rhs_mcv.isRegister()) |
| 17020 | registerAlias(rhs_mcv.getReg().?, abi_size) | 17111 | registerAlias(rhs_mcv.getReg().?, abi_size) |
| ... | @@ -17061,7 +17152,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17061,7 +17152,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17061 | 16, 80, 128 => null, | 17152 | 16, 80, 128 => null, |
| 17062 | else => unreachable, | 17153 | else => unreachable, |
| 17063 | }, | 17154 | }, |
| 17064 | }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(mod)}); | 17155 | }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}); |
| 17065 | try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_alias, mask_alias); | 17156 | try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_alias, mask_alias); |
| 17066 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( | 17157 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 17067 | .{ mir_fixes, .andn }, | 17158 | .{ mir_fixes, .andn }, |
| ... | @@ -17083,18 +17174,19 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17083,18 +17174,19 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17083 | } | 17174 | } |
| 17084 | 17175 | ||
| 17085 | fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | 17176 | fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17086 | const mod = self.bin_file.comp.module.?; | 17177 | const pt = self.pt; |
| 17178 | const mod = pt.zcu; | ||
| 17087 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 17179 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 17088 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 17180 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 17089 | 17181 | ||
| 17090 | const dst_ty = self.typeOfIndex(inst); | 17182 | const dst_ty = self.typeOfIndex(inst); |
| 17091 | const elem_ty = dst_ty.childType(mod); | 17183 | const elem_ty = dst_ty.childType(mod); |
| 17092 | const elem_abi_size: u16 = @intCast(elem_ty.abiSize(mod)); | 17184 | const elem_abi_size: u16 = @intCast(elem_ty.abiSize(pt)); |
| 17093 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | 17185 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); |
| 17094 | const lhs_ty = self.typeOf(extra.a); | 17186 | const lhs_ty = self.typeOf(extra.a); |
| 17095 | const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 17187 | const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); |
| 17096 | const rhs_ty = self.typeOf(extra.b); | 17188 | const rhs_ty = self.typeOf(extra.b); |
| 17097 | const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(mod)); | 17189 | const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(pt)); |
| 17098 | const max_abi_size = @max(dst_abi_size, lhs_abi_size, rhs_abi_size); | 17190 | const max_abi_size = @max(dst_abi_size, lhs_abi_size, rhs_abi_size); |
| 17099 | 17191 | ||
| 17100 | const ExpectedContents = [32]?i32; | 17192 | const ExpectedContents = [32]?i32; |
| ... | @@ -17106,11 +17198,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17106,11 +17198,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17106 | defer allocator.free(mask_elems); | 17198 | defer allocator.free(mask_elems); |
| 17107 | for (mask_elems, 0..) |*mask_elem, elem_index| { | 17199 | for (mask_elems, 0..) |*mask_elem, elem_index| { |
| 17108 | const mask_elem_val = | 17200 | const mask_elem_val = |
| 17109 | Value.fromInterned(extra.mask).elemValue(mod, elem_index) catch unreachable; | 17201 | Value.fromInterned(extra.mask).elemValue(pt, elem_index) catch unreachable; |
| 17110 | mask_elem.* = if (mask_elem_val.isUndef(mod)) | 17202 | mask_elem.* = if (mask_elem_val.isUndef(mod)) |
| 17111 | null | 17203 | null |
| 17112 | else | 17204 | else |
| 17113 | @intCast(mask_elem_val.toSignedInt(mod)); | 17205 | @intCast(mask_elem_val.toSignedInt(pt)); |
| 17114 | } | 17206 | } |
| 17115 | 17207 | ||
| 17116 | const has_avx = self.hasFeature(.avx); | 17208 | const has_avx = self.hasFeature(.avx); |
| ... | @@ -17626,8 +17718,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17626,8 +17718,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17626 | else | 17718 | else |
| 17627 | self.hasFeature(.avx2)) 32 else 16)) break :blendv; | 17719 | self.hasFeature(.avx2)) 32 else 16)) break :blendv; |
| 17628 | 17720 | ||
| 17629 | const select_mask_elem_ty = try mod.intType(.unsigned, elem_abi_size * 8); | 17721 | const select_mask_elem_ty = try pt.intType(.unsigned, elem_abi_size * 8); |
| 17630 | const select_mask_ty = try mod.vectorType(.{ | 17722 | const select_mask_ty = try pt.vectorType(.{ |
| 17631 | .len = @intCast(mask_elems.len), | 17723 | .len = @intCast(mask_elems.len), |
| 17632 | .child = select_mask_elem_ty.toIntern(), | 17724 | .child = select_mask_elem_ty.toIntern(), |
| 17633 | }); | 17725 | }); |
| ... | @@ -17643,11 +17735,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17643,11 +17735,11 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17643 | if (mask_elem_index != elem_index) break :blendv; | 17735 | if (mask_elem_index != elem_index) break :blendv; |
| 17644 | 17736 | ||
| 17645 | select_mask_elem.* = (if (mask_elem < 0) | 17737 | select_mask_elem.* = (if (mask_elem < 0) |
| 17646 | try select_mask_elem_ty.maxIntScalar(mod, select_mask_elem_ty) | 17738 | try select_mask_elem_ty.maxIntScalar(pt, select_mask_elem_ty) |
| 17647 | else | 17739 | else |
| 17648 | try select_mask_elem_ty.minIntScalar(mod, select_mask_elem_ty)).toIntern(); | 17740 | try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern(); |
| 17649 | } | 17741 | } |
| 17650 | const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17742 | const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 17651 | .ty = select_mask_ty.toIntern(), | 17743 | .ty = select_mask_ty.toIntern(), |
| 17652 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, | 17744 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, |
| 17653 | } }))); | 17745 | } }))); |
| ... | @@ -17783,7 +17875,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17783,7 +17875,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17783 | var lhs_mask_elems: [16]InternPool.Index = undefined; | 17875 | var lhs_mask_elems: [16]InternPool.Index = undefined; |
| 17784 | for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| { | 17876 | for (lhs_mask_elems[0..max_abi_size], 0..) |*lhs_mask_elem, byte_index| { |
| 17785 | const elem_index = byte_index / elem_abi_size; | 17877 | const elem_index = byte_index / elem_abi_size; |
| 17786 | lhs_mask_elem.* = try mod.intern(.{ .int = .{ | 17878 | lhs_mask_elem.* = try pt.intern(.{ .int = .{ |
| 17787 | .ty = .u8_type, | 17879 | .ty = .u8_type, |
| 17788 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { | 17880 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { |
| 17789 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; | 17881 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; |
| ... | @@ -17794,8 +17886,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17794,8 +17886,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17794 | } }, | 17886 | } }, |
| 17795 | } }); | 17887 | } }); |
| 17796 | } | 17888 | } |
| 17797 | const lhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 17889 | const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 17798 | const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17890 | const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 17799 | .ty = lhs_mask_ty.toIntern(), | 17891 | .ty = lhs_mask_ty.toIntern(), |
| 17800 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, | 17892 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, |
| 17801 | } }))); | 17893 | } }))); |
| ... | @@ -17817,7 +17909,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17817,7 +17909,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17817 | var rhs_mask_elems: [16]InternPool.Index = undefined; | 17909 | var rhs_mask_elems: [16]InternPool.Index = undefined; |
| 17818 | for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| { | 17910 | for (rhs_mask_elems[0..max_abi_size], 0..) |*rhs_mask_elem, byte_index| { |
| 17819 | const elem_index = byte_index / elem_abi_size; | 17911 | const elem_index = byte_index / elem_abi_size; |
| 17820 | rhs_mask_elem.* = try mod.intern(.{ .int = .{ | 17912 | rhs_mask_elem.* = try pt.intern(.{ .int = .{ |
| 17821 | .ty = .u8_type, | 17913 | .ty = .u8_type, |
| 17822 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { | 17914 | .storage = .{ .u64 = if (elem_index >= mask_elems.len) 0b1_00_00000 else elem: { |
| 17823 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; | 17915 | const mask_elem = mask_elems[elem_index] orelse break :elem 0b1_00_00000; |
| ... | @@ -17828,8 +17920,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17828,8 +17920,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17828 | } }, | 17920 | } }, |
| 17829 | } }); | 17921 | } }); |
| 17830 | } | 17922 | } |
| 17831 | const rhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 17923 | const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 17832 | const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17924 | const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 17833 | .ty = rhs_mask_ty.toIntern(), | 17925 | .ty = rhs_mask_ty.toIntern(), |
| 17834 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, | 17926 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, |
| 17835 | } }))); | 17927 | } }))); |
| ... | @@ -17881,14 +17973,15 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17881,14 +17973,15 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17881 | 17973 | ||
| 17882 | break :result null; | 17974 | break :result null; |
| 17883 | }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ | 17975 | }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ |
| 17884 | lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod), | 17976 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), dst_ty.fmt(pt), |
| 17885 | Value.fromInterned(extra.mask).fmtValue(mod, null), | 17977 | Value.fromInterned(extra.mask).fmtValue(pt, null), |
| 17886 | }); | 17978 | }); |
| 17887 | return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); | 17979 | return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); |
| 17888 | } | 17980 | } |
| 17889 | 17981 | ||
| 17890 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | 17982 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 17891 | const mod = self.bin_file.comp.module.?; | 17983 | const pt = self.pt; |
| 17984 | const mod = pt.zcu; | ||
| 17892 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 17985 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 17893 | 17986 | ||
| 17894 | const result: MCValue = result: { | 17987 | const result: MCValue = result: { |
| ... | @@ -17898,9 +17991,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17898,9 +17991,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 17898 | 17991 | ||
| 17899 | const operand_mcv = try self.resolveInst(reduce.operand); | 17992 | const operand_mcv = try self.resolveInst(reduce.operand); |
| 17900 | const mask_len = (math.cast(u6, operand_ty.vectorLen(mod)) orelse | 17993 | const mask_len = (math.cast(u6, operand_ty.vectorLen(mod)) orelse |
| 17901 | return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)})); | 17994 | return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)})); |
| 17902 | const mask = (@as(u64, 1) << mask_len) - 1; | 17995 | const mask = (@as(u64, 1) << mask_len) - 1; |
| 17903 | const abi_size: u32 = @intCast(operand_ty.abiSize(mod)); | 17996 | const abi_size: u32 = @intCast(operand_ty.abiSize(pt)); |
| 17904 | switch (reduce.operation) { | 17997 | switch (reduce.operation) { |
| 17905 | .Or => { | 17998 | .Or => { |
| 17906 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( | 17999 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( |
| ... | @@ -17936,16 +18029,17 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17936,16 +18029,17 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 17936 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_reg, tmp_reg); | 18029 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_reg, tmp_reg); |
| 17937 | break :result .{ .eflags = .z }; | 18030 | break :result .{ .eflags = .z }; |
| 17938 | }, | 18031 | }, |
| 17939 | else => return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)}), | 18032 | else => return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)}), |
| 17940 | } | 18033 | } |
| 17941 | } | 18034 | } |
| 17942 | return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(mod)}); | 18035 | return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)}); |
| 17943 | }; | 18036 | }; |
| 17944 | return self.finishAir(inst, result, .{ reduce.operand, .none, .none }); | 18037 | return self.finishAir(inst, result, .{ reduce.operand, .none, .none }); |
| 17945 | } | 18038 | } |
| 17946 | 18039 | ||
| 17947 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 18040 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 17948 | const mod = self.bin_file.comp.module.?; | 18041 | const pt = self.pt; |
| 18042 | const mod = pt.zcu; | ||
| 17949 | const result_ty = self.typeOfIndex(inst); | 18043 | const result_ty = self.typeOfIndex(inst); |
| 17950 | const len: usize = @intCast(result_ty.arrayLen(mod)); | 18044 | const len: usize = @intCast(result_ty.arrayLen(mod)); |
| 17951 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 18045 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -17953,30 +18047,30 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17953,30 +18047,30 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 17953 | const result: MCValue = result: { | 18047 | const result: MCValue = result: { |
| 17954 | switch (result_ty.zigTypeTag(mod)) { | 18048 | switch (result_ty.zigTypeTag(mod)) { |
| 17955 | .Struct => { | 18049 | .Struct => { |
| 17956 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, mod)); | 18050 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); |
| 17957 | if (result_ty.containerLayout(mod) == .@"packed") { | 18051 | if (result_ty.containerLayout(mod) == .@"packed") { |
| 17958 | const struct_obj = mod.typeToStruct(result_ty).?; | 18052 | const struct_obj = mod.typeToStruct(result_ty).?; |
| 17959 | try self.genInlineMemset( | 18053 | try self.genInlineMemset( |
| 17960 | .{ .lea_frame = .{ .index = frame_index } }, | 18054 | .{ .lea_frame = .{ .index = frame_index } }, |
| 17961 | .{ .immediate = 0 }, | 18055 | .{ .immediate = 0 }, |
| 17962 | .{ .immediate = result_ty.abiSize(mod) }, | 18056 | .{ .immediate = result_ty.abiSize(pt) }, |
| 17963 | .{}, | 18057 | .{}, |
| 17964 | ); | 18058 | ); |
| 17965 | for (elements, 0..) |elem, elem_i_usize| { | 18059 | for (elements, 0..) |elem, elem_i_usize| { |
| 17966 | const elem_i: u32 = @intCast(elem_i_usize); | 18060 | const elem_i: u32 = @intCast(elem_i_usize); |
| 17967 | if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue; | 18061 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 17968 | 18062 | ||
| 17969 | const elem_ty = result_ty.structFieldType(elem_i, mod); | 18063 | const elem_ty = result_ty.structFieldType(elem_i, mod); |
| 17970 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(mod)); | 18064 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt)); |
| 17971 | if (elem_bit_size > 64) { | 18065 | if (elem_bit_size > 64) { |
| 17972 | return self.fail( | 18066 | return self.fail( |
| 17973 | "TODO airAggregateInit implement packed structs with large fields", | 18067 | "TODO airAggregateInit implement packed structs with large fields", |
| 17974 | .{}, | 18068 | .{}, |
| 17975 | ); | 18069 | ); |
| 17976 | } | 18070 | } |
| 17977 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); | 18071 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 17978 | const elem_abi_bits = elem_abi_size * 8; | 18072 | const elem_abi_bits = elem_abi_size * 8; |
| 17979 | const elem_off = mod.structPackedFieldBitOffset(struct_obj, elem_i); | 18073 | const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i); |
| 17980 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); | 18074 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| 17981 | const elem_bit_off = elem_off % elem_abi_bits; | 18075 | const elem_bit_off = elem_off % elem_abi_bits; |
| 17982 | const elem_mcv = try self.resolveInst(elem); | 18076 | const elem_mcv = try self.resolveInst(elem); |
| ... | @@ -18046,10 +18140,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18046,10 +18140,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18046 | } | 18140 | } |
| 18047 | } | 18141 | } |
| 18048 | } else for (elements, 0..) |elem, elem_i| { | 18142 | } else for (elements, 0..) |elem, elem_i| { |
| 18049 | if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue; | 18143 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 18050 | 18144 | ||
| 18051 | const elem_ty = result_ty.structFieldType(elem_i, mod); | 18145 | const elem_ty = result_ty.structFieldType(elem_i, mod); |
| 18052 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, mod)); | 18146 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt)); |
| 18053 | const elem_mcv = try self.resolveInst(elem); | 18147 | const elem_mcv = try self.resolveInst(elem); |
| 18054 | const mat_elem_mcv = switch (elem_mcv) { | 18148 | const mat_elem_mcv = switch (elem_mcv) { |
| 18055 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, | 18149 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| ... | @@ -18062,7 +18156,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18062,7 +18156,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18062 | .Array, .Vector => { | 18156 | .Array, .Vector => { |
| 18063 | const elem_ty = result_ty.childType(mod); | 18157 | const elem_ty = result_ty.childType(mod); |
| 18064 | if (result_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) { | 18158 | if (result_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) { |
| 18065 | const result_size: u32 = @intCast(result_ty.abiSize(mod)); | 18159 | const result_size: u32 = @intCast(result_ty.abiSize(pt)); |
| 18066 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); | 18160 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); |
| 18067 | try self.asmRegisterRegister( | 18161 | try self.asmRegisterRegister( |
| 18068 | .{ ._, .xor }, | 18162 | .{ ._, .xor }, |
| ... | @@ -18093,8 +18187,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18093,8 +18187,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18093 | } | 18187 | } |
| 18094 | break :result .{ .register = dst_reg }; | 18188 | break :result .{ .register = dst_reg }; |
| 18095 | } else { | 18189 | } else { |
| 18096 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, mod)); | 18190 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); |
| 18097 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); | 18191 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); |
| 18098 | 18192 | ||
| 18099 | for (elements, 0..) |elem, elem_i| { | 18193 | for (elements, 0..) |elem, elem_i| { |
| 18100 | const elem_mcv = try self.resolveInst(elem); | 18194 | const elem_mcv = try self.resolveInst(elem); |
| ... | @@ -18136,18 +18230,19 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18136,18 +18230,19 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18136 | } | 18230 | } |
| 18137 | 18231 | ||
| 18138 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | 18232 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18139 | const mod = self.bin_file.comp.module.?; | 18233 | const pt = self.pt; |
| 18234 | const mod = pt.zcu; | ||
| 18140 | const ip = &mod.intern_pool; | 18235 | const ip = &mod.intern_pool; |
| 18141 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 18236 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 18142 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 18237 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 18143 | const result: MCValue = result: { | 18238 | const result: MCValue = result: { |
| 18144 | const union_ty = self.typeOfIndex(inst); | 18239 | const union_ty = self.typeOfIndex(inst); |
| 18145 | const layout = union_ty.unionGetLayout(mod); | 18240 | const layout = union_ty.unionGetLayout(pt); |
| 18146 | 18241 | ||
| 18147 | const src_ty = self.typeOf(extra.init); | 18242 | const src_ty = self.typeOf(extra.init); |
| 18148 | const src_mcv = try self.resolveInst(extra.init); | 18243 | const src_mcv = try self.resolveInst(extra.init); |
| 18149 | if (layout.tag_size == 0) { | 18244 | if (layout.tag_size == 0) { |
| 18150 | if (layout.abi_size <= src_ty.abiSize(mod) and | 18245 | if (layout.abi_size <= src_ty.abiSize(pt) and |
| 18151 | self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; | 18246 | self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; |
| 18152 | 18247 | ||
| 18153 | const dst_mcv = try self.allocRegOrMem(inst, true); | 18248 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| ... | @@ -18161,9 +18256,9 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18161,9 +18256,9 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18161 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 18256 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 18162 | const tag_ty = Type.fromInterned(union_obj.enum_tag_ty); | 18257 | const tag_ty = Type.fromInterned(union_obj.enum_tag_ty); |
| 18163 | const field_index = tag_ty.enumFieldIndex(field_name, mod).?; | 18258 | const field_index = tag_ty.enumFieldIndex(field_name, mod).?; |
| 18164 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); | 18259 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 18165 | const tag_int_val = try tag_val.intFromEnum(tag_ty, mod); | 18260 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| 18166 | const tag_int = tag_int_val.toUnsignedInt(mod); | 18261 | const tag_int = tag_int_val.toUnsignedInt(pt); |
| 18167 | const tag_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align)) | 18262 | const tag_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align)) |
| 18168 | @intCast(layout.payload_size) | 18263 | @intCast(layout.payload_size) |
| 18169 | else | 18264 | else |
| ... | @@ -18192,7 +18287,8 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18192,7 +18287,8 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { |
| 18192 | } | 18287 | } |
| 18193 | 18288 | ||
| 18194 | fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | 18289 | fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18195 | const mod = self.bin_file.comp.module.?; | 18290 | const pt = self.pt; |
| 18291 | const mod = pt.zcu; | ||
| 18196 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 18292 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 18197 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 18293 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 18198 | const ty = self.typeOfIndex(inst); | 18294 | const ty = self.typeOfIndex(inst); |
| ... | @@ -18205,7 +18301,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18205,7 +18301,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18205 | else => unreachable, | 18301 | else => unreachable, |
| 18206 | }) { | 18302 | }) { |
| 18207 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airMulAdd for {}", .{ | 18303 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airMulAdd for {}", .{ |
| 18208 | ty.fmt(mod), | 18304 | ty.fmt(pt), |
| 18209 | }); | 18305 | }); |
| 18210 | 18306 | ||
| 18211 | var callee_buf: ["__fma?".len]u8 = undefined; | 18307 | var callee_buf: ["__fma?".len]u8 = undefined; |
| ... | @@ -18334,12 +18430,12 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18334,12 +18430,12 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18334 | else => unreachable, | 18430 | else => unreachable, |
| 18335 | } | 18431 | } |
| 18336 | else | 18432 | else |
| 18337 | unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{ty.fmt(mod)}); | 18433 | unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{ty.fmt(pt)}); |
| 18338 | 18434 | ||
| 18339 | var mops: [3]MCValue = undefined; | 18435 | var mops: [3]MCValue = undefined; |
| 18340 | for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv; | 18436 | for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv; |
| 18341 | 18437 | ||
| 18342 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 18438 | const abi_size: u32 = @intCast(ty.abiSize(pt)); |
| 18343 | const mop1_reg = registerAlias(mops[0].getReg().?, abi_size); | 18439 | const mop1_reg = registerAlias(mops[0].getReg().?, abi_size); |
| 18344 | const mop2_reg = registerAlias(mops[1].getReg().?, abi_size); | 18440 | const mop2_reg = registerAlias(mops[1].getReg().?, abi_size); |
| 18345 | if (mops[2].isRegister()) try self.asmRegisterRegisterRegister( | 18441 | if (mops[2].isRegister()) try self.asmRegisterRegisterRegister( |
| ... | @@ -18359,9 +18455,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18359,9 +18455,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18359 | } | 18455 | } |
| 18360 | 18456 | ||
| 18361 | fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | 18457 | fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18362 | const mod = self.bin_file.comp.module.?; | 18458 | const pt = self.pt; |
| 18459 | const mod = pt.zcu; | ||
| 18363 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; | 18460 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; |
| 18364 | const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque); | 18461 | const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque); |
| 18365 | 18462 | ||
| 18366 | const result: MCValue = switch (abi.resolveCallingConvention( | 18463 | const result: MCValue = switch (abi.resolveCallingConvention( |
| 18367 | self.fn_type.fnCallingConvention(mod), | 18464 | self.fn_type.fnCallingConvention(mod), |
| ... | @@ -18369,7 +18466,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18369,7 +18466,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18369 | )) { | 18466 | )) { |
| 18370 | .SysV => result: { | 18467 | .SysV => result: { |
| 18371 | const info = self.va_info.sysv; | 18468 | const info = self.va_info.sysv; |
| 18372 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, mod)); | 18469 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, pt)); |
| 18373 | var field_off: u31 = 0; | 18470 | var field_off: u31 = 0; |
| 18374 | // gp_offset: c_uint, | 18471 | // gp_offset: c_uint, |
| 18375 | try self.genSetMem( | 18472 | try self.genSetMem( |
| ... | @@ -18379,7 +18476,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18379,7 +18476,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18379 | .{ .immediate = info.gp_count * 8 }, | 18476 | .{ .immediate = info.gp_count * 8 }, |
| 18380 | .{}, | 18477 | .{}, |
| 18381 | ); | 18478 | ); |
| 18382 | field_off += @intCast(Type.c_uint.abiSize(mod)); | 18479 | field_off += @intCast(Type.c_uint.abiSize(pt)); |
| 18383 | // fp_offset: c_uint, | 18480 | // fp_offset: c_uint, |
| 18384 | try self.genSetMem( | 18481 | try self.genSetMem( |
| 18385 | .{ .frame = dst_fi }, | 18482 | .{ .frame = dst_fi }, |
| ... | @@ -18388,7 +18485,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18388,7 +18485,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18388 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, | 18485 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, |
| 18389 | .{}, | 18486 | .{}, |
| 18390 | ); | 18487 | ); |
| 18391 | field_off += @intCast(Type.c_uint.abiSize(mod)); | 18488 | field_off += @intCast(Type.c_uint.abiSize(pt)); |
| 18392 | // overflow_arg_area: *anyopaque, | 18489 | // overflow_arg_area: *anyopaque, |
| 18393 | try self.genSetMem( | 18490 | try self.genSetMem( |
| 18394 | .{ .frame = dst_fi }, | 18491 | .{ .frame = dst_fi }, |
| ... | @@ -18397,7 +18494,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18397,7 +18494,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18397 | .{ .lea_frame = info.overflow_arg_area }, | 18494 | .{ .lea_frame = info.overflow_arg_area }, |
| 18398 | .{}, | 18495 | .{}, |
| 18399 | ); | 18496 | ); |
| 18400 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); | 18497 | field_off += @intCast(ptr_anyopaque_ty.abiSize(pt)); |
| 18401 | // reg_save_area: *anyopaque, | 18498 | // reg_save_area: *anyopaque, |
| 18402 | try self.genSetMem( | 18499 | try self.genSetMem( |
| 18403 | .{ .frame = dst_fi }, | 18500 | .{ .frame = dst_fi }, |
| ... | @@ -18406,7 +18503,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18406,7 +18503,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18406 | .{ .lea_frame = info.reg_save_area }, | 18503 | .{ .lea_frame = info.reg_save_area }, |
| 18407 | .{}, | 18504 | .{}, |
| 18408 | ); | 18505 | ); |
| 18409 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); | 18506 | field_off += @intCast(ptr_anyopaque_ty.abiSize(pt)); |
| 18410 | break :result .{ .load_frame = .{ .index = dst_fi } }; | 18507 | break :result .{ .load_frame = .{ .index = dst_fi } }; |
| 18411 | }, | 18508 | }, |
| 18412 | .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}), | 18509 | .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}), |
| ... | @@ -18416,11 +18513,12 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18416,11 +18513,12 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18416 | } | 18513 | } |
| 18417 | 18514 | ||
| 18418 | fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | 18515 | fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18419 | const mod = self.bin_file.comp.module.?; | 18516 | const pt = self.pt; |
| 18517 | const mod = pt.zcu; | ||
| 18420 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 18518 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 18421 | const ty = self.typeOfIndex(inst); | 18519 | const ty = self.typeOfIndex(inst); |
| 18422 | const promote_ty = self.promoteVarArg(ty); | 18520 | const promote_ty = self.promoteVarArg(ty); |
| 18423 | const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque); | 18521 | const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque); |
| 18424 | const unused = self.liveness.isUnused(inst); | 18522 | const unused = self.liveness.isUnused(inst); |
| 18425 | 18523 | ||
| 18426 | const result: MCValue = switch (abi.resolveCallingConvention( | 18524 | const result: MCValue = switch (abi.resolveCallingConvention( |
| ... | @@ -18454,7 +18552,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18454,7 +18552,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18454 | const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } }; | 18552 | const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } }; |
| 18455 | const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } }; | 18553 | const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } }; |
| 18456 | 18554 | ||
| 18457 | const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, mod, self.target.*, .arg), .none); | 18555 | const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, pt, self.target.*, .arg), .none); |
| 18458 | switch (classes[0]) { | 18556 | switch (classes[0]) { |
| 18459 | .integer => { | 18557 | .integer => { |
| 18460 | assert(classes.len == 1); | 18558 | assert(classes.len == 1); |
| ... | @@ -18489,7 +18587,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18489,7 +18587,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18489 | .base = .{ .reg = addr_reg }, | 18587 | .base = .{ .reg = addr_reg }, |
| 18490 | .mod = .{ .rm = .{ | 18588 | .mod = .{ .rm = .{ |
| 18491 | .size = .qword, | 18589 | .size = .qword, |
| 18492 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), | 18590 | .disp = @intCast(@max(promote_ty.abiSize(pt), 8)), |
| 18493 | } }, | 18591 | } }, |
| 18494 | }); | 18592 | }); |
| 18495 | try self.genCopy( | 18593 | try self.genCopy( |
| ... | @@ -18537,7 +18635,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18537,7 +18635,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18537 | .base = .{ .reg = addr_reg }, | 18635 | .base = .{ .reg = addr_reg }, |
| 18538 | .mod = .{ .rm = .{ | 18636 | .mod = .{ .rm = .{ |
| 18539 | .size = .qword, | 18637 | .size = .qword, |
| 18540 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), | 18638 | .disp = @intCast(@max(promote_ty.abiSize(pt), 8)), |
| 18541 | } }, | 18639 | } }, |
| 18542 | }); | 18640 | }); |
| 18543 | try self.genCopy( | 18641 | try self.genCopy( |
| ... | @@ -18557,7 +18655,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18557,7 +18655,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18557 | unreachable; | 18655 | unreachable; |
| 18558 | }, | 18656 | }, |
| 18559 | else => return self.fail("TODO implement c_va_arg for {} on SysV", .{ | 18657 | else => return self.fail("TODO implement c_va_arg for {} on SysV", .{ |
| 18560 | promote_ty.fmt(mod), | 18658 | promote_ty.fmt(pt), |
| 18561 | }), | 18659 | }), |
| 18562 | } | 18660 | } |
| 18563 | 18661 | ||
| ... | @@ -18627,11 +18725,11 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18627,11 +18725,11 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void { |
| 18627 | } | 18725 | } |
| 18628 | 18726 | ||
| 18629 | fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | 18727 | fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 18630 | const mod = self.bin_file.comp.module.?; | 18728 | const pt = self.pt; |
| 18631 | const ty = self.typeOf(ref); | 18729 | const ty = self.typeOf(ref); |
| 18632 | 18730 | ||
| 18633 | // If the type has no codegen bits, no need to store it. | 18731 | // If the type has no codegen bits, no need to store it. |
| 18634 | if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 18732 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 18635 | 18733 | ||
| 18636 | const mcv = if (ref.toIndex()) |inst| mcv: { | 18734 | const mcv = if (ref.toIndex()) |inst| mcv: { |
| 18637 | break :mcv self.inst_tracking.getPtr(inst).?.short; | 18735 | break :mcv self.inst_tracking.getPtr(inst).?.short; |
| ... | @@ -18705,8 +18803,8 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV | ... | @@ -18705,8 +18803,8 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 18705 | } | 18803 | } |
| 18706 | 18804 | ||
| 18707 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | 18805 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 18708 | const mod = self.bin_file.comp.module.?; | 18806 | const pt = self.pt; |
| 18709 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, val, self.owner.getDecl(mod))) { | 18807 | return switch (try codegen.genTypedValue(self.bin_file, pt, self.src_loc, val, self.owner.getDecl(pt.zcu))) { |
| 18710 | .mcv => |mcv| switch (mcv) { | 18808 | .mcv => |mcv| switch (mcv) { |
| 18711 | .none => .none, | 18809 | .none => .none, |
| 18712 | .undef => .undef, | 18810 | .undef => .undef, |
| ... | @@ -18745,7 +18843,8 @@ fn resolveCallingConventionValues( | ... | @@ -18745,7 +18843,8 @@ fn resolveCallingConventionValues( |
| 18745 | var_args: []const Type, | 18843 | var_args: []const Type, |
| 18746 | stack_frame_base: FrameIndex, | 18844 | stack_frame_base: FrameIndex, |
| 18747 | ) !CallMCValues { | 18845 | ) !CallMCValues { |
| 18748 | const mod = self.bin_file.comp.module.?; | 18846 | const pt = self.pt; |
| 18847 | const mod = pt.zcu; | ||
| 18749 | const ip = &mod.intern_pool; | 18848 | const ip = &mod.intern_pool; |
| 18750 | const cc = fn_info.cc; | 18849 | const cc = fn_info.cc; |
| 18751 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); | 18850 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); |
| ... | @@ -18788,7 +18887,7 @@ fn resolveCallingConventionValues( | ... | @@ -18788,7 +18887,7 @@ fn resolveCallingConventionValues( |
| 18788 | .SysV => {}, | 18887 | .SysV => {}, |
| 18789 | .Win64 => { | 18888 | .Win64 => { |
| 18790 | // Align the stack to 16bytes before allocating shadow stack space (if any). | 18889 | // Align the stack to 16bytes before allocating shadow stack space (if any). |
| 18791 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(mod)); | 18890 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(pt)); |
| 18792 | }, | 18891 | }, |
| 18793 | else => unreachable, | 18892 | else => unreachable, |
| 18794 | } | 18893 | } |
| ... | @@ -18796,7 +18895,7 @@ fn resolveCallingConventionValues( | ... | @@ -18796,7 +18895,7 @@ fn resolveCallingConventionValues( |
| 18796 | // Return values | 18895 | // Return values |
| 18797 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 18896 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 18798 | result.return_value = InstTracking.init(.unreach); | 18897 | result.return_value = InstTracking.init(.unreach); |
| 18799 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 18898 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 18800 | // TODO: is this even possible for C calling convention? | 18899 | // TODO: is this even possible for C calling convention? |
| 18801 | result.return_value = InstTracking.init(.none); | 18900 | result.return_value = InstTracking.init(.none); |
| 18802 | } else { | 18901 | } else { |
| ... | @@ -18804,15 +18903,15 @@ fn resolveCallingConventionValues( | ... | @@ -18804,15 +18903,15 @@ fn resolveCallingConventionValues( |
| 18804 | var ret_tracking_i: usize = 0; | 18903 | var ret_tracking_i: usize = 0; |
| 18805 | 18904 | ||
| 18806 | const classes = switch (resolved_cc) { | 18905 | const classes = switch (resolved_cc) { |
| 18807 | .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, mod, self.target.*, .ret), .none), | 18906 | .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, pt, self.target.*, .ret), .none), |
| 18808 | .Win64 => &.{abi.classifyWindows(ret_ty, mod)}, | 18907 | .Win64 => &.{abi.classifyWindows(ret_ty, pt)}, |
| 18809 | else => unreachable, | 18908 | else => unreachable, |
| 18810 | }; | 18909 | }; |
| 18811 | for (classes) |class| switch (class) { | 18910 | for (classes) |class| switch (class) { |
| 18812 | .integer => { | 18911 | .integer => { |
| 18813 | const ret_int_reg = registerAlias( | 18912 | const ret_int_reg = registerAlias( |
| 18814 | abi.getCAbiIntReturnRegs(resolved_cc)[ret_int_reg_i], | 18913 | abi.getCAbiIntReturnRegs(resolved_cc)[ret_int_reg_i], |
| 18815 | @intCast(@min(ret_ty.abiSize(mod), 8)), | 18914 | @intCast(@min(ret_ty.abiSize(pt), 8)), |
| 18816 | ); | 18915 | ); |
| 18817 | ret_int_reg_i += 1; | 18916 | ret_int_reg_i += 1; |
| 18818 | 18917 | ||
| ... | @@ -18822,7 +18921,7 @@ fn resolveCallingConventionValues( | ... | @@ -18822,7 +18921,7 @@ fn resolveCallingConventionValues( |
| 18822 | .sse, .float, .float_combine, .win_i128 => { | 18921 | .sse, .float, .float_combine, .win_i128 => { |
| 18823 | const ret_sse_reg = registerAlias( | 18922 | const ret_sse_reg = registerAlias( |
| 18824 | abi.getCAbiSseReturnRegs(resolved_cc)[ret_sse_reg_i], | 18923 | abi.getCAbiSseReturnRegs(resolved_cc)[ret_sse_reg_i], |
| 18825 | @intCast(ret_ty.abiSize(mod)), | 18924 | @intCast(ret_ty.abiSize(pt)), |
| 18826 | ); | 18925 | ); |
| 18827 | ret_sse_reg_i += 1; | 18926 | ret_sse_reg_i += 1; |
| 18828 | 18927 | ||
| ... | @@ -18865,7 +18964,7 @@ fn resolveCallingConventionValues( | ... | @@ -18865,7 +18964,7 @@ fn resolveCallingConventionValues( |
| 18865 | 18964 | ||
| 18866 | // Input params | 18965 | // Input params |
| 18867 | for (param_types, result.args) |ty, *arg| { | 18966 | for (param_types, result.args) |ty, *arg| { |
| 18868 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); | 18967 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 18869 | switch (resolved_cc) { | 18968 | switch (resolved_cc) { |
| 18870 | .SysV => {}, | 18969 | .SysV => {}, |
| 18871 | .Win64 => { | 18970 | .Win64 => { |
| ... | @@ -18879,8 +18978,8 @@ fn resolveCallingConventionValues( | ... | @@ -18879,8 +18978,8 @@ fn resolveCallingConventionValues( |
| 18879 | var arg_mcv_i: usize = 0; | 18978 | var arg_mcv_i: usize = 0; |
| 18880 | 18979 | ||
| 18881 | const classes = switch (resolved_cc) { | 18980 | const classes = switch (resolved_cc) { |
| 18882 | .SysV => mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .arg), .none), | 18981 | .SysV => mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .arg), .none), |
| 18883 | .Win64 => &.{abi.classifyWindows(ty, mod)}, | 18982 | .Win64 => &.{abi.classifyWindows(ty, pt)}, |
| 18884 | else => unreachable, | 18983 | else => unreachable, |
| 18885 | }; | 18984 | }; |
| 18886 | for (classes) |class| switch (class) { | 18985 | for (classes) |class| switch (class) { |
| ... | @@ -18890,7 +18989,7 @@ fn resolveCallingConventionValues( | ... | @@ -18890,7 +18989,7 @@ fn resolveCallingConventionValues( |
| 18890 | 18989 | ||
| 18891 | const param_int_reg = registerAlias( | 18990 | const param_int_reg = registerAlias( |
| 18892 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i], | 18991 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i], |
| 18893 | @intCast(@min(ty.abiSize(mod), 8)), | 18992 | @intCast(@min(ty.abiSize(pt), 8)), |
| 18894 | ); | 18993 | ); |
| 18895 | param_int_reg_i += 1; | 18994 | param_int_reg_i += 1; |
| 18896 | 18995 | ||
| ... | @@ -18903,7 +19002,7 @@ fn resolveCallingConventionValues( | ... | @@ -18903,7 +19002,7 @@ fn resolveCallingConventionValues( |
| 18903 | 19002 | ||
| 18904 | const param_sse_reg = registerAlias( | 19003 | const param_sse_reg = registerAlias( |
| 18905 | abi.getCAbiSseParamRegs(resolved_cc)[param_sse_reg_i], | 19004 | abi.getCAbiSseParamRegs(resolved_cc)[param_sse_reg_i], |
| 18906 | @intCast(ty.abiSize(mod)), | 19005 | @intCast(ty.abiSize(pt)), |
| 18907 | ); | 19006 | ); |
| 18908 | param_sse_reg_i += 1; | 19007 | param_sse_reg_i += 1; |
| 18909 | 19008 | ||
| ... | @@ -18916,7 +19015,7 @@ fn resolveCallingConventionValues( | ... | @@ -18916,7 +19015,7 @@ fn resolveCallingConventionValues( |
| 18916 | .x87, .x87up, .complex_x87, .memory => break, | 19015 | .x87, .x87up, .complex_x87, .memory => break, |
| 18917 | else => unreachable, | 19016 | else => unreachable, |
| 18918 | }, | 19017 | }, |
| 18919 | .Win64 => if (ty.abiSize(mod) > 8) { | 19018 | .Win64 => if (ty.abiSize(pt) > 8) { |
| 18920 | const param_int_reg = | 19019 | const param_int_reg = |
| 18921 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64(); | 19020 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64(); |
| 18922 | param_int_reg_i += 1; | 19021 | param_int_reg_i += 1; |
| ... | @@ -18938,7 +19037,7 @@ fn resolveCallingConventionValues( | ... | @@ -18938,7 +19037,7 @@ fn resolveCallingConventionValues( |
| 18938 | const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs; | 19037 | const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs; |
| 18939 | const frame_elem_size = mem.alignForward( | 19038 | const frame_elem_size = mem.alignForward( |
| 18940 | u64, | 19039 | u64, |
| 18941 | ty.childType(mod).abiSize(mod), | 19040 | ty.childType(mod).abiSize(pt), |
| 18942 | frame_elem_align, | 19041 | frame_elem_align, |
| 18943 | ); | 19042 | ); |
| 18944 | const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size); | 19043 | const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size); |
| ... | @@ -18962,9 +19061,9 @@ fn resolveCallingConventionValues( | ... | @@ -18962,9 +19061,9 @@ fn resolveCallingConventionValues( |
| 18962 | continue; | 19061 | continue; |
| 18963 | } | 19062 | } |
| 18964 | 19063 | ||
| 18965 | const param_size: u31 = @intCast(ty.abiSize(mod)); | 19064 | const param_size: u31 = @intCast(ty.abiSize(pt)); |
| 18966 | const param_align: u31 = | 19065 | const param_align: u31 = |
| 18967 | @intCast(@max(ty.abiAlignment(mod).toByteUnits().?, 8)); | 19066 | @intCast(@max(ty.abiAlignment(pt).toByteUnits().?, 8)); |
| 18968 | result.stack_byte_count = | 19067 | result.stack_byte_count = |
| 18969 | mem.alignForward(u31, result.stack_byte_count, param_align); | 19068 | mem.alignForward(u31, result.stack_byte_count, param_align); |
| 18970 | arg.* = .{ .load_frame = .{ | 19069 | arg.* = .{ .load_frame = .{ |
| ... | @@ -18984,11 +19083,11 @@ fn resolveCallingConventionValues( | ... | @@ -18984,11 +19083,11 @@ fn resolveCallingConventionValues( |
| 18984 | // Return values | 19083 | // Return values |
| 18985 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | 19084 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { |
| 18986 | result.return_value = InstTracking.init(.unreach); | 19085 | result.return_value = InstTracking.init(.unreach); |
| 18987 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 19086 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 18988 | result.return_value = InstTracking.init(.none); | 19087 | result.return_value = InstTracking.init(.none); |
| 18989 | } else { | 19088 | } else { |
| 18990 | const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0]; | 19089 | const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0]; |
| 18991 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(mod)); | 19090 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(pt)); |
| 18992 | if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) { | 19091 | if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) { |
| 18993 | const aliased_reg = registerAlias(ret_reg, ret_ty_size); | 19092 | const aliased_reg = registerAlias(ret_reg, ret_ty_size); |
| 18994 | result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none }; | 19093 | result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none }; |
| ... | @@ -19003,12 +19102,12 @@ fn resolveCallingConventionValues( | ... | @@ -19003,12 +19102,12 @@ fn resolveCallingConventionValues( |
| 19003 | 19102 | ||
| 19004 | // Input params | 19103 | // Input params |
| 19005 | for (param_types, result.args) |ty, *arg| { | 19104 | for (param_types, result.args) |ty, *arg| { |
| 19006 | if (!ty.hasRuntimeBitsIgnoreComptime(mod)) { | 19105 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 19007 | arg.* = .none; | 19106 | arg.* = .none; |
| 19008 | continue; | 19107 | continue; |
| 19009 | } | 19108 | } |
| 19010 | const param_size: u31 = @intCast(ty.abiSize(mod)); | 19109 | const param_size: u31 = @intCast(ty.abiSize(pt)); |
| 19011 | const param_align: u31 = @intCast(ty.abiAlignment(mod).toByteUnits().?); | 19110 | const param_align: u31 = @intCast(ty.abiAlignment(pt).toByteUnits().?); |
| 19012 | result.stack_byte_count = | 19111 | result.stack_byte_count = |
| 19013 | mem.alignForward(u31, result.stack_byte_count, param_align); | 19112 | mem.alignForward(u31, result.stack_byte_count, param_align); |
| 19014 | arg.* = .{ .load_frame = .{ | 19113 | arg.* = .{ .load_frame = .{ |
| ... | @@ -19093,47 +19192,49 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -19093,47 +19192,49 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 19093 | } | 19192 | } |
| 19094 | 19193 | ||
| 19095 | fn memSize(self: *Self, ty: Type) Memory.Size { | 19194 | fn memSize(self: *Self, ty: Type) Memory.Size { |
| 19096 | const mod = self.bin_file.comp.module.?; | 19195 | const pt = self.pt; |
| 19196 | const mod = pt.zcu; | ||
| 19097 | return switch (ty.zigTypeTag(mod)) { | 19197 | return switch (ty.zigTypeTag(mod)) { |
| 19098 | .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), | 19198 | .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), |
| 19099 | else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))), | 19199 | else => Memory.Size.fromSize(@intCast(ty.abiSize(pt))), |
| 19100 | }; | 19200 | }; |
| 19101 | } | 19201 | } |
| 19102 | 19202 | ||
| 19103 | fn splitType(self: *Self, ty: Type) ![2]Type { | 19203 | fn splitType(self: *Self, ty: Type) ![2]Type { |
| 19104 | const mod = self.bin_file.comp.module.?; | 19204 | const pt = self.pt; |
| 19105 | const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none); | 19205 | const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none); |
| 19106 | var parts: [2]Type = undefined; | 19206 | var parts: [2]Type = undefined; |
| 19107 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { | 19207 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { |
| 19108 | part.* = switch (class) { | 19208 | part.* = switch (class) { |
| 19109 | .integer => switch (part_i) { | 19209 | .integer => switch (part_i) { |
| 19110 | 0 => Type.u64, | 19210 | 0 => Type.u64, |
| 19111 | 1 => part: { | 19211 | 1 => part: { |
| 19112 | const elem_size = ty.abiAlignment(mod).minStrict(.@"8").toByteUnits().?; | 19212 | const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?; |
| 19113 | const elem_ty = try mod.intType(.unsigned, @intCast(elem_size * 8)); | 19213 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); |
| 19114 | break :part switch (@divExact(ty.abiSize(mod) - 8, elem_size)) { | 19214 | break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) { |
| 19115 | 1 => elem_ty, | 19215 | 1 => elem_ty, |
| 19116 | else => |len| try mod.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), | 19216 | else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), |
| 19117 | }; | 19217 | }; |
| 19118 | }, | 19218 | }, |
| 19119 | else => unreachable, | 19219 | else => unreachable, |
| 19120 | }, | 19220 | }, |
| 19121 | .float => Type.f32, | 19221 | .float => Type.f32, |
| 19122 | .float_combine => try mod.arrayType(.{ .len = 2, .child = .f32_type }), | 19222 | .float_combine => try pt.arrayType(.{ .len = 2, .child = .f32_type }), |
| 19123 | .sse => Type.f64, | 19223 | .sse => Type.f64, |
| 19124 | else => break, | 19224 | else => break, |
| 19125 | }; | 19225 | }; |
| 19126 | } else if (parts[0].abiSize(mod) + parts[1].abiSize(mod) == ty.abiSize(mod)) return parts; | 19226 | } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts; |
| 19127 | return self.fail("TODO implement splitType for {}", .{ty.fmt(mod)}); | 19227 | return self.fail("TODO implement splitType for {}", .{ty.fmt(pt)}); |
| 19128 | } | 19228 | } |
| 19129 | 19229 | ||
| 19130 | /// Truncates the value in the register in place. | 19230 | /// Truncates the value in the register in place. |
| 19131 | /// Clobbers any remaining bits. | 19231 | /// Clobbers any remaining bits. |
| 19132 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { | 19232 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 19133 | const mod = self.bin_file.comp.module.?; | 19233 | const pt = self.pt; |
| 19234 | const mod = pt.zcu; | ||
| 19134 | const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ | 19235 | const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ |
| 19135 | .signedness = .unsigned, | 19236 | .signedness = .unsigned, |
| 19136 | .bits = @intCast(ty.bitSize(mod)), | 19237 | .bits = @intCast(ty.bitSize(pt)), |
| 19137 | }; | 19238 | }; |
| 19138 | const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; | 19239 | const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; |
| 19139 | try self.spillEflagsIfOccupied(); | 19240 | try self.spillEflagsIfOccupied(); |
| ... | @@ -19177,8 +19278,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { | ... | @@ -19177,8 +19278,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 19177 | } | 19278 | } |
| 19178 | 19279 | ||
| 19179 | fn regBitSize(self: *Self, ty: Type) u64 { | 19280 | fn regBitSize(self: *Self, ty: Type) u64 { |
| 19180 | const mod = self.bin_file.comp.module.?; | 19281 | const pt = self.pt; |
| 19181 | const abi_size = ty.abiSize(mod); | 19282 | const mod = pt.zcu; |
| 19283 | const abi_size = ty.abiSize(pt); | ||
| 19182 | return switch (ty.zigTypeTag(mod)) { | 19284 | return switch (ty.zigTypeTag(mod)) { |
| 19183 | else => switch (abi_size) { | 19285 | else => switch (abi_size) { |
| 19184 | 1 => 8, | 19286 | 1 => 8, |
| ... | @@ -19196,8 +19298,7 @@ fn regBitSize(self: *Self, ty: Type) u64 { | ... | @@ -19196,8 +19298,7 @@ fn regBitSize(self: *Self, ty: Type) u64 { |
| 19196 | } | 19298 | } |
| 19197 | 19299 | ||
| 19198 | fn regExtraBits(self: *Self, ty: Type) u64 { | 19300 | fn regExtraBits(self: *Self, ty: Type) u64 { |
| 19199 | const mod = self.bin_file.comp.module.?; | 19301 | return self.regBitSize(ty) - ty.bitSize(self.pt); |
| 19200 | return self.regBitSize(ty) - ty.bitSize(mod); | ||
| 19201 | } | 19302 | } |
| 19202 | 19303 | ||
| 19203 | fn hasFeature(self: *Self, feature: Target.x86.Feature) bool { | 19304 | fn hasFeature(self: *Self, feature: Target.x86.Feature) bool { |
| ... | @@ -19211,12 +19312,14 @@ fn hasAllFeatures(self: *Self, features: anytype) bool { | ... | @@ -19211,12 +19312,14 @@ fn hasAllFeatures(self: *Self, features: anytype) bool { |
| 19211 | } | 19312 | } |
| 19212 | 19313 | ||
| 19213 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { | 19314 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 19214 | const mod = self.bin_file.comp.module.?; | 19315 | const pt = self.pt; |
| 19316 | const mod = pt.zcu; | ||
| 19215 | return self.air.typeOf(inst, &mod.intern_pool); | 19317 | return self.air.typeOf(inst, &mod.intern_pool); |
| 19216 | } | 19318 | } |
| 19217 | 19319 | ||
| 19218 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { | 19320 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 19219 | const mod = self.bin_file.comp.module.?; | 19321 | const pt = self.pt; |
| 19322 | const mod = pt.zcu; | ||
| 19220 | return self.air.typeOfIndex(inst, &mod.intern_pool); | 19323 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 19221 | } | 19324 | } |
| 19222 | 19325 | ||
| ... | @@ -19268,7 +19371,8 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 { | ... | @@ -19268,7 +19371,8 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 { |
| 19268 | } | 19371 | } |
| 19269 | 19372 | ||
| 19270 | fn promoteInt(self: *Self, ty: Type) Type { | 19373 | fn promoteInt(self: *Self, ty: Type) Type { |
| 19271 | const mod = self.bin_file.comp.module.?; | 19374 | const pt = self.pt; |
| 19375 | const mod = pt.zcu; | ||
| 19272 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { | 19376 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { |
| 19273 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, | 19377 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, |
| 19274 | else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty, | 19378 | else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty, |
src/arch/x86_64/Lower.zig+2-4| ... | @@ -8,7 +8,7 @@ allocator: Allocator, | ... | @@ -8,7 +8,7 @@ allocator: Allocator, |
| 8 | mir: Mir, | 8 | mir: Mir, |
| 9 | cc: std.builtin.CallingConvention, | 9 | cc: std.builtin.CallingConvention, |
| 10 | err_msg: ?*ErrorMsg = null, | 10 | err_msg: ?*ErrorMsg = null, |
| 11 | src_loc: Module.LazySrcLoc, | 11 | src_loc: Zcu.LazySrcLoc, |
| 12 | result_insts_len: u8 = undefined, | 12 | result_insts_len: u8 = undefined, |
| 13 | result_relocs_len: u8 = undefined, | 13 | result_relocs_len: u8 = undefined, |
| 14 | result_insts: [ | 14 | result_insts: [ |
| ... | @@ -657,7 +657,7 @@ const std = @import("std"); | ... | @@ -657,7 +657,7 @@ const std = @import("std"); |
| 657 | 657 | ||
| 658 | const Air = @import("../../Air.zig"); | 658 | const Air = @import("../../Air.zig"); |
| 659 | const Allocator = std.mem.Allocator; | 659 | const Allocator = std.mem.Allocator; |
| 660 | const ErrorMsg = Module.ErrorMsg; | 660 | const ErrorMsg = Zcu.ErrorMsg; |
| 661 | const Immediate = bits.Immediate; | 661 | const Immediate = bits.Immediate; |
| 662 | const Instruction = encoder.Instruction; | 662 | const Instruction = encoder.Instruction; |
| 663 | const Lower = @This(); | 663 | const Lower = @This(); |
| ... | @@ -665,8 +665,6 @@ const Memory = Instruction.Memory; | ... | @@ -665,8 +665,6 @@ const Memory = Instruction.Memory; |
| 665 | const Mir = @import("Mir.zig"); | 665 | const Mir = @import("Mir.zig"); |
| 666 | const Mnemonic = Instruction.Mnemonic; | 666 | const Mnemonic = Instruction.Mnemonic; |
| 667 | const Zcu = @import("../../Zcu.zig"); | 667 | const Zcu = @import("../../Zcu.zig"); |
| 668 | /// Deprecated. | ||
| 669 | const Module = Zcu; | ||
| 670 | const Operand = Instruction.Operand; | 668 | const Operand = Instruction.Operand; |
| 671 | const Prefix = Instruction.Prefix; | 669 | const Prefix = Instruction.Prefix; |
| 672 | const Register = bits.Register; | 670 | const Register = bits.Register; |
src/arch/x86_64/abi.zig+35-35| ... | @@ -44,7 +44,7 @@ pub const Class = enum { | ... | @@ -44,7 +44,7 @@ pub const Class = enum { |
| 44 | } | 44 | } |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { | 47 | pub fn classifyWindows(ty: Type, pt: Zcu.PerThread) Class { |
| 48 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 | 48 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 |
| 49 | // "There's a strict one-to-one correspondence between a function call's arguments | 49 | // "There's a strict one-to-one correspondence between a function call's arguments |
| 50 | // and the registers used for those arguments. Any argument that doesn't fit in 8 | 50 | // and the registers used for those arguments. Any argument that doesn't fit in 8 |
| ... | @@ -53,7 +53,7 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { | ... | @@ -53,7 +53,7 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { |
| 53 | // "All floating point operations are done using the 16 XMM registers." | 53 | // "All floating point operations are done using the 16 XMM registers." |
| 54 | // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed | 54 | // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed |
| 55 | // as if they were integers of the same size." | 55 | // as if they were integers of the same size." |
| 56 | switch (ty.zigTypeTag(zcu)) { | 56 | switch (ty.zigTypeTag(pt.zcu)) { |
| 57 | .Pointer, | 57 | .Pointer, |
| 58 | .Int, | 58 | .Int, |
| 59 | .Bool, | 59 | .Bool, |
| ... | @@ -68,12 +68,12 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { | ... | @@ -68,12 +68,12 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { |
| 68 | .ErrorUnion, | 68 | .ErrorUnion, |
| 69 | .AnyFrame, | 69 | .AnyFrame, |
| 70 | .Frame, | 70 | .Frame, |
| 71 | => switch (ty.abiSize(zcu)) { | 71 | => switch (ty.abiSize(pt)) { |
| 72 | 0 => unreachable, | 72 | 0 => unreachable, |
| 73 | 1, 2, 4, 8 => return .integer, | 73 | 1, 2, 4, 8 => return .integer, |
| 74 | else => switch (ty.zigTypeTag(zcu)) { | 74 | else => switch (ty.zigTypeTag(pt.zcu)) { |
| 75 | .Int => return .win_i128, | 75 | .Int => return .win_i128, |
| 76 | .Struct, .Union => if (ty.containerLayout(zcu) == .@"packed") { | 76 | .Struct, .Union => if (ty.containerLayout(pt.zcu) == .@"packed") { |
| 77 | return .win_i128; | 77 | return .win_i128; |
| 78 | } else { | 78 | } else { |
| 79 | return .memory; | 79 | return .memory; |
| ... | @@ -100,14 +100,14 @@ pub const Context = enum { ret, arg, field, other }; | ... | @@ -100,14 +100,14 @@ pub const Context = enum { ret, arg, field, other }; |
| 100 | 100 | ||
| 101 | /// There are a maximum of 8 possible return slots. Returned values are in | 101 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 102 | /// the beginning of the array; unused slots are filled with .none. | 102 | /// the beginning of the array; unused slots are filled with .none. |
| 103 | pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8]Class { | 103 | pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Context) [8]Class { |
| 104 | const memory_class = [_]Class{ | 104 | const memory_class = [_]Class{ |
| 105 | .memory, .none, .none, .none, | 105 | .memory, .none, .none, .none, |
| 106 | .none, .none, .none, .none, | 106 | .none, .none, .none, .none, |
| 107 | }; | 107 | }; |
| 108 | var result = [1]Class{.none} ** 8; | 108 | var result = [1]Class{.none} ** 8; |
| 109 | switch (ty.zigTypeTag(zcu)) { | 109 | switch (ty.zigTypeTag(pt.zcu)) { |
| 110 | .Pointer => switch (ty.ptrSize(zcu)) { | 110 | .Pointer => switch (ty.ptrSize(pt.zcu)) { |
| 111 | .Slice => { | 111 | .Slice => { |
| 112 | result[0] = .integer; | 112 | result[0] = .integer; |
| 113 | result[1] = .integer; | 113 | result[1] = .integer; |
| ... | @@ -119,7 +119,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -119,7 +119,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 119 | }, | 119 | }, |
| 120 | }, | 120 | }, |
| 121 | .Int, .Enum, .ErrorSet => { | 121 | .Int, .Enum, .ErrorSet => { |
| 122 | const bits = ty.intInfo(zcu).bits; | 122 | const bits = ty.intInfo(pt.zcu).bits; |
| 123 | if (bits <= 64) { | 123 | if (bits <= 64) { |
| 124 | result[0] = .integer; | 124 | result[0] = .integer; |
| 125 | return result; | 125 | return result; |
| ... | @@ -185,8 +185,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -185,8 +185,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 185 | else => unreachable, | 185 | else => unreachable, |
| 186 | }, | 186 | }, |
| 187 | .Vector => { | 187 | .Vector => { |
| 188 | const elem_ty = ty.childType(zcu); | 188 | const elem_ty = ty.childType(pt.zcu); |
| 189 | const bits = elem_ty.bitSize(zcu) * ty.arrayLen(zcu); | 189 | const bits = elem_ty.bitSize(pt) * ty.arrayLen(pt.zcu); |
| 190 | if (elem_ty.toIntern() == .bool_type) { | 190 | if (elem_ty.toIntern() == .bool_type) { |
| 191 | if (bits <= 32) return .{ | 191 | if (bits <= 32) return .{ |
| 192 | .integer, .none, .none, .none, | 192 | .integer, .none, .none, .none, |
| ... | @@ -250,7 +250,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -250,7 +250,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 250 | return memory_class; | 250 | return memory_class; |
| 251 | }, | 251 | }, |
| 252 | .Optional => { | 252 | .Optional => { |
| 253 | if (ty.isPtrLikeOptional(zcu)) { | 253 | if (ty.isPtrLikeOptional(pt.zcu)) { |
| 254 | result[0] = .integer; | 254 | result[0] = .integer; |
| 255 | return result; | 255 | return result; |
| 256 | } | 256 | } |
| ... | @@ -261,8 +261,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -261,8 +261,8 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 261 | // it contains unaligned fields, it has class MEMORY" | 261 | // it contains unaligned fields, it has class MEMORY" |
| 262 | // "If the size of the aggregate exceeds a single eightbyte, each is classified | 262 | // "If the size of the aggregate exceeds a single eightbyte, each is classified |
| 263 | // separately.". | 263 | // separately.". |
| 264 | const ty_size = ty.abiSize(zcu); | 264 | const ty_size = ty.abiSize(pt); |
| 265 | switch (ty.containerLayout(zcu)) { | 265 | switch (ty.containerLayout(pt.zcu)) { |
| 266 | .auto, .@"extern" => {}, | 266 | .auto, .@"extern" => {}, |
| 267 | .@"packed" => { | 267 | .@"packed" => { |
| 268 | assert(ty_size <= 16); | 268 | assert(ty_size <= 16); |
| ... | @@ -274,10 +274,10 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -274,10 +274,10 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 274 | if (ty_size > 64) | 274 | if (ty_size > 64) |
| 275 | return memory_class; | 275 | return memory_class; |
| 276 | 276 | ||
| 277 | _ = if (zcu.typeToStruct(ty)) |loaded_struct| | 277 | _ = if (pt.zcu.typeToStruct(ty)) |loaded_struct| |
| 278 | classifySystemVStruct(&result, 0, loaded_struct, zcu, target) | 278 | classifySystemVStruct(&result, 0, loaded_struct, pt, target) |
| 279 | else if (zcu.typeToUnion(ty)) |loaded_union| | 279 | else if (pt.zcu.typeToUnion(ty)) |loaded_union| |
| 280 | classifySystemVUnion(&result, 0, loaded_union, zcu, target) | 280 | classifySystemVUnion(&result, 0, loaded_union, pt, target) |
| 281 | else | 281 | else |
| 282 | unreachable; | 282 | unreachable; |
| 283 | 283 | ||
| ... | @@ -306,7 +306,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 | ... | @@ -306,7 +306,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 |
| 306 | return result; | 306 | return result; |
| 307 | }, | 307 | }, |
| 308 | .Array => { | 308 | .Array => { |
| 309 | const ty_size = ty.abiSize(zcu); | 309 | const ty_size = ty.abiSize(pt); |
| 310 | if (ty_size <= 8) { | 310 | if (ty_size <= 8) { |
| 311 | result[0] = .integer; | 311 | result[0] = .integer; |
| 312 | return result; | 312 | return result; |
| ... | @@ -326,10 +326,10 @@ fn classifySystemVStruct( | ... | @@ -326,10 +326,10 @@ fn classifySystemVStruct( |
| 326 | result: *[8]Class, | 326 | result: *[8]Class, |
| 327 | starting_byte_offset: u64, | 327 | starting_byte_offset: u64, |
| 328 | loaded_struct: InternPool.LoadedStructType, | 328 | loaded_struct: InternPool.LoadedStructType, |
| 329 | zcu: *Zcu, | 329 | pt: Zcu.PerThread, |
| 330 | target: std.Target, | 330 | target: std.Target, |
| 331 | ) u64 { | 331 | ) u64 { |
| 332 | const ip = &zcu.intern_pool; | 332 | const ip = &pt.zcu.intern_pool; |
| 333 | var byte_offset = starting_byte_offset; | 333 | var byte_offset = starting_byte_offset; |
| 334 | var field_it = loaded_struct.iterateRuntimeOrder(ip); | 334 | var field_it = loaded_struct.iterateRuntimeOrder(ip); |
| 335 | while (field_it.next()) |field_index| { | 335 | while (field_it.next()) |field_index| { |
| ... | @@ -338,29 +338,29 @@ fn classifySystemVStruct( | ... | @@ -338,29 +338,29 @@ fn classifySystemVStruct( |
| 338 | byte_offset = std.mem.alignForward( | 338 | byte_offset = std.mem.alignForward( |
| 339 | u64, | 339 | u64, |
| 340 | byte_offset, | 340 | byte_offset, |
| 341 | field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?, | 341 | field_align.toByteUnits() orelse field_ty.abiAlignment(pt).toByteUnits().?, |
| 342 | ); | 342 | ); |
| 343 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | 343 | if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| { |
| 344 | switch (field_loaded_struct.layout) { | 344 | switch (field_loaded_struct.layout) { |
| 345 | .auto, .@"extern" => { | 345 | .auto, .@"extern" => { |
| 346 | byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, zcu, target); | 346 | byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, pt, target); |
| 347 | continue; | 347 | continue; |
| 348 | }, | 348 | }, |
| 349 | .@"packed" => {}, | 349 | .@"packed" => {}, |
| 350 | } | 350 | } |
| 351 | } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| { | 351 | } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| { |
| 352 | switch (field_loaded_union.getLayout(ip)) { | 352 | switch (field_loaded_union.getLayout(ip)) { |
| 353 | .auto, .@"extern" => { | 353 | .auto, .@"extern" => { |
| 354 | byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target); | 354 | byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, pt, target); |
| 355 | continue; | 355 | continue; |
| 356 | }, | 356 | }, |
| 357 | .@"packed" => {}, | 357 | .@"packed" => {}, |
| 358 | } | 358 | } |
| 359 | } | 359 | } |
| 360 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none); | 360 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none); |
| 361 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| | 361 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| 362 | result_class.* = result_class.combineSystemV(field_class); | 362 | result_class.* = result_class.combineSystemV(field_class); |
| 363 | byte_offset += field_ty.abiSize(zcu); | 363 | byte_offset += field_ty.abiSize(pt); |
| 364 | } | 364 | } |
| 365 | const final_byte_offset = starting_byte_offset + loaded_struct.size(ip).*; | 365 | const final_byte_offset = starting_byte_offset + loaded_struct.size(ip).*; |
| 366 | std.debug.assert(final_byte_offset == std.mem.alignForward( | 366 | std.debug.assert(final_byte_offset == std.mem.alignForward( |
| ... | @@ -375,30 +375,30 @@ fn classifySystemVUnion( | ... | @@ -375,30 +375,30 @@ fn classifySystemVUnion( |
| 375 | result: *[8]Class, | 375 | result: *[8]Class, |
| 376 | starting_byte_offset: u64, | 376 | starting_byte_offset: u64, |
| 377 | loaded_union: InternPool.LoadedUnionType, | 377 | loaded_union: InternPool.LoadedUnionType, |
| 378 | zcu: *Zcu, | 378 | pt: Zcu.PerThread, |
| 379 | target: std.Target, | 379 | target: std.Target, |
| 380 | ) u64 { | 380 | ) u64 { |
| 381 | const ip = &zcu.intern_pool; | 381 | const ip = &pt.zcu.intern_pool; |
| 382 | for (0..loaded_union.field_types.len) |field_index| { | 382 | for (0..loaded_union.field_types.len) |field_index| { |
| 383 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | 383 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 384 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | 384 | if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| { |
| 385 | switch (field_loaded_struct.layout) { | 385 | switch (field_loaded_struct.layout) { |
| 386 | .auto, .@"extern" => { | 386 | .auto, .@"extern" => { |
| 387 | _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, zcu, target); | 387 | _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, pt, target); |
| 388 | continue; | 388 | continue; |
| 389 | }, | 389 | }, |
| 390 | .@"packed" => {}, | 390 | .@"packed" => {}, |
| 391 | } | 391 | } |
| 392 | } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| { | 392 | } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| { |
| 393 | switch (field_loaded_union.getLayout(ip)) { | 393 | switch (field_loaded_union.getLayout(ip)) { |
| 394 | .auto, .@"extern" => { | 394 | .auto, .@"extern" => { |
| 395 | _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target); | 395 | _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, pt, target); |
| 396 | continue; | 396 | continue; |
| 397 | }, | 397 | }, |
| 398 | .@"packed" => {}, | 398 | .@"packed" => {}, |
| 399 | } | 399 | } |
| 400 | } | 400 | } |
| 401 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none); | 401 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none); |
| 402 | for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| | 402 | for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| 403 | result_class.* = result_class.combineSystemV(field_class); | 403 | result_class.* = result_class.combineSystemV(field_class); |
| 404 | } | 404 | } |
src/codegen.zig+140-129| ... | @@ -13,12 +13,10 @@ const trace = @import("tracy.zig").trace; | ... | @@ -13,12 +13,10 @@ const trace = @import("tracy.zig").trace; |
| 13 | const Air = @import("Air.zig"); | 13 | const Air = @import("Air.zig"); |
| 14 | const Allocator = mem.Allocator; | 14 | const Allocator = mem.Allocator; |
| 15 | const Compilation = @import("Compilation.zig"); | 15 | const Compilation = @import("Compilation.zig"); |
| 16 | const ErrorMsg = Module.ErrorMsg; | 16 | const ErrorMsg = Zcu.ErrorMsg; |
| 17 | const InternPool = @import("InternPool.zig"); | 17 | const InternPool = @import("InternPool.zig"); |
| 18 | const Liveness = @import("Liveness.zig"); | 18 | const Liveness = @import("Liveness.zig"); |
| 19 | const Zcu = @import("Zcu.zig"); | 19 | const Zcu = @import("Zcu.zig"); |
| 20 | /// Deprecated. | ||
| 21 | const Module = Zcu; | ||
| 22 | const Target = std.Target; | 20 | const Target = std.Target; |
| 23 | const Type = @import("Type.zig"); | 21 | const Type = @import("Type.zig"); |
| 24 | const Value = @import("Value.zig"); | 22 | const Value = @import("Value.zig"); |
| ... | @@ -47,14 +45,15 @@ pub const DebugInfoOutput = union(enum) { | ... | @@ -47,14 +45,15 @@ pub const DebugInfoOutput = union(enum) { |
| 47 | 45 | ||
| 48 | pub fn generateFunction( | 46 | pub fn generateFunction( |
| 49 | lf: *link.File, | 47 | lf: *link.File, |
| 50 | src_loc: Module.LazySrcLoc, | 48 | pt: Zcu.PerThread, |
| 49 | src_loc: Zcu.LazySrcLoc, | ||
| 51 | func_index: InternPool.Index, | 50 | func_index: InternPool.Index, |
| 52 | air: Air, | 51 | air: Air, |
| 53 | liveness: Liveness, | 52 | liveness: Liveness, |
| 54 | code: *std.ArrayList(u8), | 53 | code: *std.ArrayList(u8), |
| 55 | debug_output: DebugInfoOutput, | 54 | debug_output: DebugInfoOutput, |
| 56 | ) CodeGenError!Result { | 55 | ) CodeGenError!Result { |
| 57 | const zcu = lf.comp.module.?; | 56 | const zcu = pt.zcu; |
| 58 | const func = zcu.funcInfo(func_index); | 57 | const func = zcu.funcInfo(func_index); |
| 59 | const decl = zcu.declPtr(func.owner_decl); | 58 | const decl = zcu.declPtr(func.owner_decl); |
| 60 | const namespace = zcu.namespacePtr(decl.src_namespace); | 59 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| ... | @@ -62,35 +61,36 @@ pub fn generateFunction( | ... | @@ -62,35 +61,36 @@ pub fn generateFunction( |
| 62 | switch (target.cpu.arch) { | 61 | switch (target.cpu.arch) { |
| 63 | .arm, | 62 | .arm, |
| 64 | .armeb, | 63 | .armeb, |
| 65 | => return @import("arch/arm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 64 | => return @import("arch/arm/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 66 | .aarch64, | 65 | .aarch64, |
| 67 | .aarch64_be, | 66 | .aarch64_be, |
| 68 | .aarch64_32, | 67 | .aarch64_32, |
| 69 | => return @import("arch/aarch64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 68 | => return @import("arch/aarch64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 70 | .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 69 | .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 71 | .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 70 | .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 72 | .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 71 | .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 73 | .wasm32, | 72 | .wasm32, |
| 74 | .wasm64, | 73 | .wasm64, |
| 75 | => return @import("arch/wasm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output), | 74 | => return @import("arch/wasm/CodeGen.zig").generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output), |
| 76 | else => unreachable, | 75 | else => unreachable, |
| 77 | } | 76 | } |
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | pub fn generateLazyFunction( | 79 | pub fn generateLazyFunction( |
| 81 | lf: *link.File, | 80 | lf: *link.File, |
| 82 | src_loc: Module.LazySrcLoc, | 81 | pt: Zcu.PerThread, |
| 82 | src_loc: Zcu.LazySrcLoc, | ||
| 83 | lazy_sym: link.File.LazySymbol, | 83 | lazy_sym: link.File.LazySymbol, |
| 84 | code: *std.ArrayList(u8), | 84 | code: *std.ArrayList(u8), |
| 85 | debug_output: DebugInfoOutput, | 85 | debug_output: DebugInfoOutput, |
| 86 | ) CodeGenError!Result { | 86 | ) CodeGenError!Result { |
| 87 | const zcu = lf.comp.module.?; | 87 | const zcu = pt.zcu; |
| 88 | const decl_index = lazy_sym.ty.getOwnerDecl(zcu); | 88 | const decl_index = lazy_sym.ty.getOwnerDecl(zcu); |
| 89 | const decl = zcu.declPtr(decl_index); | 89 | const decl = zcu.declPtr(decl_index); |
| 90 | const namespace = zcu.namespacePtr(decl.src_namespace); | 90 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 91 | const target = namespace.fileScope(zcu).mod.resolved_target.result; | 91 | const target = namespace.fileScope(zcu).mod.resolved_target.result; |
| 92 | switch (target.cpu.arch) { | 92 | switch (target.cpu.arch) { |
| 93 | .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output), | 93 | .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output), |
| 94 | else => unreachable, | 94 | else => unreachable, |
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| ... | @@ -105,7 +105,8 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian | ... | @@ -105,7 +105,8 @@ fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian |
| 105 | 105 | ||
| 106 | pub fn generateLazySymbol( | 106 | pub fn generateLazySymbol( |
| 107 | bin_file: *link.File, | 107 | bin_file: *link.File, |
| 108 | src_loc: Module.LazySrcLoc, | 108 | pt: Zcu.PerThread, |
| 109 | src_loc: Zcu.LazySrcLoc, | ||
| 109 | lazy_sym: link.File.LazySymbol, | 110 | lazy_sym: link.File.LazySymbol, |
| 110 | // TODO don't use an "out" parameter like this; put it in the result instead | 111 | // TODO don't use an "out" parameter like this; put it in the result instead |
| 111 | alignment: *Alignment, | 112 | alignment: *Alignment, |
| ... | @@ -119,25 +120,24 @@ pub fn generateLazySymbol( | ... | @@ -119,25 +120,24 @@ pub fn generateLazySymbol( |
| 119 | defer tracy.end(); | 120 | defer tracy.end(); |
| 120 | 121 | ||
| 121 | const comp = bin_file.comp; | 122 | const comp = bin_file.comp; |
| 122 | const zcu = comp.module.?; | 123 | const ip = &pt.zcu.intern_pool; |
| 123 | const ip = &zcu.intern_pool; | ||
| 124 | const target = comp.root_mod.resolved_target.result; | 124 | const target = comp.root_mod.resolved_target.result; |
| 125 | const endian = target.cpu.arch.endian(); | 125 | const endian = target.cpu.arch.endian(); |
| 126 | const gpa = comp.gpa; | 126 | const gpa = comp.gpa; |
| 127 | 127 | ||
| 128 | log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ | 128 | log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ |
| 129 | @tagName(lazy_sym.kind), | 129 | @tagName(lazy_sym.kind), |
| 130 | lazy_sym.ty.fmt(zcu), | 130 | lazy_sym.ty.fmt(pt), |
| 131 | }); | 131 | }); |
| 132 | 132 | ||
| 133 | if (lazy_sym.kind == .code) { | 133 | if (lazy_sym.kind == .code) { |
| 134 | alignment.* = target_util.defaultFunctionAlignment(target); | 134 | alignment.* = target_util.defaultFunctionAlignment(target); |
| 135 | return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output); | 135 | return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | if (lazy_sym.ty.isAnyError(zcu)) { | 138 | if (lazy_sym.ty.isAnyError(pt.zcu)) { |
| 139 | alignment.* = .@"4"; | 139 | alignment.* = .@"4"; |
| 140 | const err_names = zcu.global_error_set.keys(); | 140 | const err_names = pt.zcu.global_error_set.keys(); |
| 141 | mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian); | 141 | mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian); |
| 142 | var offset = code.items.len; | 142 | var offset = code.items.len; |
| 143 | try code.resize((1 + err_names.len + 1) * 4); | 143 | try code.resize((1 + err_names.len + 1) * 4); |
| ... | @@ -151,9 +151,9 @@ pub fn generateLazySymbol( | ... | @@ -151,9 +151,9 @@ pub fn generateLazySymbol( |
| 151 | } | 151 | } |
| 152 | mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian); | 152 | mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian); |
| 153 | return Result.ok; | 153 | return Result.ok; |
| 154 | } else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) { | 154 | } else if (lazy_sym.ty.zigTypeTag(pt.zcu) == .Enum) { |
| 155 | alignment.* = .@"1"; | 155 | alignment.* = .@"1"; |
| 156 | const tag_names = lazy_sym.ty.enumFields(zcu); | 156 | const tag_names = lazy_sym.ty.enumFields(pt.zcu); |
| 157 | for (0..tag_names.len) |tag_index| { | 157 | for (0..tag_names.len) |tag_index| { |
| 158 | const tag_name = tag_names.get(ip)[tag_index].toSlice(ip); | 158 | const tag_name = tag_names.get(ip)[tag_index].toSlice(ip); |
| 159 | try code.ensureUnusedCapacity(tag_name.len + 1); | 159 | try code.ensureUnusedCapacity(tag_name.len + 1); |
| ... | @@ -165,13 +165,14 @@ pub fn generateLazySymbol( | ... | @@ -165,13 +165,14 @@ pub fn generateLazySymbol( |
| 165 | gpa, | 165 | gpa, |
| 166 | src_loc, | 166 | src_loc, |
| 167 | "TODO implement generateLazySymbol for {s} {}", | 167 | "TODO implement generateLazySymbol for {s} {}", |
| 168 | .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(zcu) }, | 168 | .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) }, |
| 169 | ) }; | 169 | ) }; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | pub fn generateSymbol( | 172 | pub fn generateSymbol( |
| 173 | bin_file: *link.File, | 173 | bin_file: *link.File, |
| 174 | src_loc: Module.LazySrcLoc, | 174 | pt: Zcu.PerThread, |
| 175 | src_loc: Zcu.LazySrcLoc, | ||
| 175 | val: Value, | 176 | val: Value, |
| 176 | code: *std.ArrayList(u8), | 177 | code: *std.ArrayList(u8), |
| 177 | debug_output: DebugInfoOutput, | 178 | debug_output: DebugInfoOutput, |
| ... | @@ -180,17 +181,17 @@ pub fn generateSymbol( | ... | @@ -180,17 +181,17 @@ pub fn generateSymbol( |
| 180 | const tracy = trace(@src()); | 181 | const tracy = trace(@src()); |
| 181 | defer tracy.end(); | 182 | defer tracy.end(); |
| 182 | 183 | ||
| 183 | const mod = bin_file.comp.module.?; | 184 | const mod = pt.zcu; |
| 184 | const ip = &mod.intern_pool; | 185 | const ip = &mod.intern_pool; |
| 185 | const ty = val.typeOf(mod); | 186 | const ty = val.typeOf(mod); |
| 186 | 187 | ||
| 187 | const target = mod.getTarget(); | 188 | const target = mod.getTarget(); |
| 188 | const endian = target.cpu.arch.endian(); | 189 | const endian = target.cpu.arch.endian(); |
| 189 | 190 | ||
| 190 | log.debug("generateSymbol: val = {}", .{val.fmtValue(mod, null)}); | 191 | log.debug("generateSymbol: val = {}", .{val.fmtValue(pt, null)}); |
| 191 | 192 | ||
| 192 | if (val.isUndefDeep(mod)) { | 193 | if (val.isUndefDeep(mod)) { |
| 193 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; | 194 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 194 | try code.appendNTimes(0xaa, abi_size); | 195 | try code.appendNTimes(0xaa, abi_size); |
| 195 | return .ok; | 196 | return .ok; |
| 196 | } | 197 | } |
| ... | @@ -236,9 +237,9 @@ pub fn generateSymbol( | ... | @@ -236,9 +237,9 @@ pub fn generateSymbol( |
| 236 | .empty_enum_value, | 237 | .empty_enum_value, |
| 237 | => unreachable, // non-runtime values | 238 | => unreachable, // non-runtime values |
| 238 | .int => { | 239 | .int => { |
| 239 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; | 240 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 240 | var space: Value.BigIntSpace = undefined; | 241 | var space: Value.BigIntSpace = undefined; |
| 241 | const int_val = val.toBigInt(&space, mod); | 242 | const int_val = val.toBigInt(&space, pt); |
| 242 | int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); | 243 | int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); |
| 243 | }, | 244 | }, |
| 244 | .err => |err| { | 245 | .err => |err| { |
| ... | @@ -252,14 +253,14 @@ pub fn generateSymbol( | ... | @@ -252,14 +253,14 @@ pub fn generateSymbol( |
| 252 | .payload => 0, | 253 | .payload => 0, |
| 253 | }; | 254 | }; |
| 254 | 255 | ||
| 255 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 256 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 256 | try code.writer().writeInt(u16, err_val, endian); | 257 | try code.writer().writeInt(u16, err_val, endian); |
| 257 | return .ok; | 258 | return .ok; |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | const payload_align = payload_ty.abiAlignment(mod); | 261 | const payload_align = payload_ty.abiAlignment(pt); |
| 261 | const error_align = Type.anyerror.abiAlignment(mod); | 262 | const error_align = Type.anyerror.abiAlignment(pt); |
| 262 | const abi_align = ty.abiAlignment(mod); | 263 | const abi_align = ty.abiAlignment(pt); |
| 263 | 264 | ||
| 264 | // error value first when its type is larger than the error union's payload | 265 | // error value first when its type is larger than the error union's payload |
| 265 | if (error_align.order(payload_align) == .gt) { | 266 | if (error_align.order(payload_align) == .gt) { |
| ... | @@ -269,8 +270,8 @@ pub fn generateSymbol( | ... | @@ -269,8 +270,8 @@ pub fn generateSymbol( |
| 269 | // emit payload part of the error union | 270 | // emit payload part of the error union |
| 270 | { | 271 | { |
| 271 | const begin = code.items.len; | 272 | const begin = code.items.len; |
| 272 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (error_union.val) { | 273 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { |
| 273 | .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 274 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 274 | .payload => |payload| payload, | 275 | .payload => |payload| payload, |
| 275 | }), code, debug_output, reloc_info)) { | 276 | }), code, debug_output, reloc_info)) { |
| 276 | .ok => {}, | 277 | .ok => {}, |
| ... | @@ -300,7 +301,7 @@ pub fn generateSymbol( | ... | @@ -300,7 +301,7 @@ pub fn generateSymbol( |
| 300 | }, | 301 | }, |
| 301 | .enum_tag => |enum_tag| { | 302 | .enum_tag => |enum_tag| { |
| 302 | const int_tag_ty = ty.intTagType(mod); | 303 | const int_tag_ty = ty.intTagType(mod); |
| 303 | switch (try generateSymbol(bin_file, src_loc, try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) { | 304 | switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) { |
| 304 | .ok => {}, | 305 | .ok => {}, |
| 305 | .fail => |em| return .{ .fail = em }, | 306 | .fail => |em| return .{ .fail = em }, |
| 306 | } | 307 | } |
| ... | @@ -311,21 +312,21 @@ pub fn generateSymbol( | ... | @@ -311,21 +312,21 @@ pub fn generateSymbol( |
| 311 | .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)), | 312 | .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)), |
| 312 | .f80 => |f80_val| { | 313 | .f80 => |f80_val| { |
| 313 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10)); | 314 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10)); |
| 314 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; | 315 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 315 | try code.appendNTimes(0, abi_size - 10); | 316 | try code.appendNTimes(0, abi_size - 10); |
| 316 | }, | 317 | }, |
| 317 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), | 318 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), |
| 318 | }, | 319 | }, |
| 319 | .ptr => switch (try lowerPtr(bin_file, src_loc, val.toIntern(), code, debug_output, reloc_info, 0)) { | 320 | .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, debug_output, reloc_info, 0)) { |
| 320 | .ok => {}, | 321 | .ok => {}, |
| 321 | .fail => |em| return .{ .fail = em }, | 322 | .fail => |em| return .{ .fail = em }, |
| 322 | }, | 323 | }, |
| 323 | .slice => |slice| { | 324 | .slice => |slice| { |
| 324 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) { | 325 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) { |
| 325 | .ok => {}, | 326 | .ok => {}, |
| 326 | .fail => |em| return .{ .fail = em }, | 327 | .fail => |em| return .{ .fail = em }, |
| 327 | } | 328 | } |
| 328 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) { | 329 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) { |
| 329 | .ok => {}, | 330 | .ok => {}, |
| 330 | .fail => |em| return .{ .fail = em }, | 331 | .fail => |em| return .{ .fail = em }, |
| 331 | } | 332 | } |
| ... | @@ -333,11 +334,11 @@ pub fn generateSymbol( | ... | @@ -333,11 +334,11 @@ pub fn generateSymbol( |
| 333 | .opt => { | 334 | .opt => { |
| 334 | const payload_type = ty.optionalChild(mod); | 335 | const payload_type = ty.optionalChild(mod); |
| 335 | const payload_val = val.optionalValue(mod); | 336 | const payload_val = val.optionalValue(mod); |
| 336 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; | 337 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 337 | 338 | ||
| 338 | if (ty.optionalReprIsPayload(mod)) { | 339 | if (ty.optionalReprIsPayload(mod)) { |
| 339 | if (payload_val) |value| { | 340 | if (payload_val) |value| { |
| 340 | switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) { | 341 | switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) { |
| 341 | .ok => {}, | 342 | .ok => {}, |
| 342 | .fail => |em| return Result{ .fail = em }, | 343 | .fail => |em| return Result{ .fail = em }, |
| 343 | } | 344 | } |
| ... | @@ -345,10 +346,12 @@ pub fn generateSymbol( | ... | @@ -345,10 +346,12 @@ pub fn generateSymbol( |
| 345 | try code.appendNTimes(0, abi_size); | 346 | try code.appendNTimes(0, abi_size); |
| 346 | } | 347 | } |
| 347 | } else { | 348 | } else { |
| 348 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1; | 349 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(pt)) orelse return error.Overflow) - 1; |
| 349 | if (payload_type.hasRuntimeBits(mod)) { | 350 | if (payload_type.hasRuntimeBits(pt)) { |
| 350 | const value = payload_val orelse Value.fromInterned((try mod.intern(.{ .undef = payload_type.toIntern() }))); | 351 | const value = payload_val orelse Value.fromInterned(try pt.intern(.{ |
| 351 | switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) { | 352 | .undef = payload_type.toIntern(), |
| 353 | })); | ||
| 354 | switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) { | ||
| 352 | .ok => {}, | 355 | .ok => {}, |
| 353 | .fail => |em| return Result{ .fail = em }, | 356 | .fail => |em| return Result{ .fail = em }, |
| 354 | } | 357 | } |
| ... | @@ -363,7 +366,7 @@ pub fn generateSymbol( | ... | @@ -363,7 +366,7 @@ pub fn generateSymbol( |
| 363 | .elems, .repeated_elem => { | 366 | .elems, .repeated_elem => { |
| 364 | var index: u64 = 0; | 367 | var index: u64 = 0; |
| 365 | while (index < array_type.lenIncludingSentinel()) : (index += 1) { | 368 | while (index < array_type.lenIncludingSentinel()) : (index += 1) { |
| 366 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) { | 369 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { |
| 367 | .bytes => unreachable, | 370 | .bytes => unreachable, |
| 368 | .elems => |elems| elems[@intCast(index)], | 371 | .elems => |elems| elems[@intCast(index)], |
| 369 | .repeated_elem => |elem| if (index < array_type.len) | 372 | .repeated_elem => |elem| if (index < array_type.len) |
| ... | @@ -378,8 +381,7 @@ pub fn generateSymbol( | ... | @@ -378,8 +381,7 @@ pub fn generateSymbol( |
| 378 | }, | 381 | }, |
| 379 | }, | 382 | }, |
| 380 | .vector_type => |vector_type| { | 383 | .vector_type => |vector_type| { |
| 381 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse | 384 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 382 | return error.Overflow; | ||
| 383 | if (vector_type.child == .bool_type) { | 385 | if (vector_type.child == .bool_type) { |
| 384 | const bytes = try code.addManyAsSlice(abi_size); | 386 | const bytes = try code.addManyAsSlice(abi_size); |
| 385 | @memset(bytes, 0xaa); | 387 | @memset(bytes, 0xaa); |
| ... | @@ -424,7 +426,7 @@ pub fn generateSymbol( | ... | @@ -424,7 +426,7 @@ pub fn generateSymbol( |
| 424 | .elems, .repeated_elem => { | 426 | .elems, .repeated_elem => { |
| 425 | var index: u64 = 0; | 427 | var index: u64 = 0; |
| 426 | while (index < vector_type.len) : (index += 1) { | 428 | while (index < vector_type.len) : (index += 1) { |
| 427 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) { | 429 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { |
| 428 | .bytes => unreachable, | 430 | .bytes => unreachable, |
| 429 | .elems => |elems| elems[ | 431 | .elems => |elems| elems[ |
| 430 | math.cast(usize, index) orelse return error.Overflow | 432 | math.cast(usize, index) orelse return error.Overflow |
| ... | @@ -439,7 +441,7 @@ pub fn generateSymbol( | ... | @@ -439,7 +441,7 @@ pub fn generateSymbol( |
| 439 | } | 441 | } |
| 440 | 442 | ||
| 441 | const padding = abi_size - | 443 | const padding = abi_size - |
| 442 | (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(mod) * vector_type.len) orelse | 444 | (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(pt) * vector_type.len) orelse |
| 443 | return error.Overflow); | 445 | return error.Overflow); |
| 444 | if (padding > 0) try code.appendNTimes(0, padding); | 446 | if (padding > 0) try code.appendNTimes(0, padding); |
| 445 | } | 447 | } |
| ... | @@ -452,10 +454,10 @@ pub fn generateSymbol( | ... | @@ -452,10 +454,10 @@ pub fn generateSymbol( |
| 452 | 0.., | 454 | 0.., |
| 453 | ) |field_ty, comptime_val, index| { | 455 | ) |field_ty, comptime_val, index| { |
| 454 | if (comptime_val != .none) continue; | 456 | if (comptime_val != .none) continue; |
| 455 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 457 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 456 | 458 | ||
| 457 | const field_val = switch (aggregate.storage) { | 459 | const field_val = switch (aggregate.storage) { |
| 458 | .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{ | 460 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 459 | .ty = field_ty, | 461 | .ty = field_ty, |
| 460 | .storage = .{ .u64 = bytes.at(index, ip) }, | 462 | .storage = .{ .u64 = bytes.at(index, ip) }, |
| 461 | } }), | 463 | } }), |
| ... | @@ -463,14 +465,14 @@ pub fn generateSymbol( | ... | @@ -463,14 +465,14 @@ pub fn generateSymbol( |
| 463 | .repeated_elem => |elem| elem, | 465 | .repeated_elem => |elem| elem, |
| 464 | }; | 466 | }; |
| 465 | 467 | ||
| 466 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { | 468 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { |
| 467 | .ok => {}, | 469 | .ok => {}, |
| 468 | .fail => |em| return Result{ .fail = em }, | 470 | .fail => |em| return Result{ .fail = em }, |
| 469 | } | 471 | } |
| 470 | const unpadded_field_end = code.items.len - struct_begin; | 472 | const unpadded_field_end = code.items.len - struct_begin; |
| 471 | 473 | ||
| 472 | // Pad struct members if required | 474 | // Pad struct members if required |
| 473 | const padded_field_end = ty.structFieldOffset(index + 1, mod); | 475 | const padded_field_end = ty.structFieldOffset(index + 1, pt); |
| 474 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse | 476 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse |
| 475 | return error.Overflow; | 477 | return error.Overflow; |
| 476 | 478 | ||
| ... | @@ -483,15 +485,14 @@ pub fn generateSymbol( | ... | @@ -483,15 +485,14 @@ pub fn generateSymbol( |
| 483 | const struct_type = ip.loadStructType(ty.toIntern()); | 485 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 484 | switch (struct_type.layout) { | 486 | switch (struct_type.layout) { |
| 485 | .@"packed" => { | 487 | .@"packed" => { |
| 486 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse | 488 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; |
| 487 | return error.Overflow; | ||
| 488 | const current_pos = code.items.len; | 489 | const current_pos = code.items.len; |
| 489 | try code.appendNTimes(0, abi_size); | 490 | try code.appendNTimes(0, abi_size); |
| 490 | var bits: u16 = 0; | 491 | var bits: u16 = 0; |
| 491 | 492 | ||
| 492 | for (struct_type.field_types.get(ip), 0..) |field_ty, index| { | 493 | for (struct_type.field_types.get(ip), 0..) |field_ty, index| { |
| 493 | const field_val = switch (aggregate.storage) { | 494 | const field_val = switch (aggregate.storage) { |
| 494 | .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{ | 495 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 495 | .ty = field_ty, | 496 | .ty = field_ty, |
| 496 | .storage = .{ .u64 = bytes.at(index, ip) }, | 497 | .storage = .{ .u64 = bytes.at(index, ip) }, |
| 497 | } }), | 498 | } }), |
| ... | @@ -502,18 +503,18 @@ pub fn generateSymbol( | ... | @@ -502,18 +503,18 @@ pub fn generateSymbol( |
| 502 | // pointer may point to a decl which must be marked used | 503 | // pointer may point to a decl which must be marked used |
| 503 | // but can also result in a relocation. Therefore we handle those separately. | 504 | // but can also result in a relocation. Therefore we handle those separately. |
| 504 | if (Type.fromInterned(field_ty).zigTypeTag(mod) == .Pointer) { | 505 | if (Type.fromInterned(field_ty).zigTypeTag(mod) == .Pointer) { |
| 505 | const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(mod)) orelse | 506 | const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(pt)) orelse |
| 506 | return error.Overflow; | 507 | return error.Overflow; |
| 507 | var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); | 508 | var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); |
| 508 | defer tmp_list.deinit(); | 509 | defer tmp_list.deinit(); |
| 509 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) { | 510 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) { |
| 510 | .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), | 511 | .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), |
| 511 | .fail => |em| return Result{ .fail = em }, | 512 | .fail => |em| return Result{ .fail = em }, |
| 512 | } | 513 | } |
| 513 | } else { | 514 | } else { |
| 514 | Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), mod, code.items[current_pos..], bits) catch unreachable; | 515 | Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; |
| 515 | } | 516 | } |
| 516 | bits += @intCast(Type.fromInterned(field_ty).bitSize(mod)); | 517 | bits += @intCast(Type.fromInterned(field_ty).bitSize(pt)); |
| 517 | } | 518 | } |
| 518 | }, | 519 | }, |
| 519 | .auto, .@"extern" => { | 520 | .auto, .@"extern" => { |
| ... | @@ -524,10 +525,10 @@ pub fn generateSymbol( | ... | @@ -524,10 +525,10 @@ pub fn generateSymbol( |
| 524 | var it = struct_type.iterateRuntimeOrder(ip); | 525 | var it = struct_type.iterateRuntimeOrder(ip); |
| 525 | while (it.next()) |field_index| { | 526 | while (it.next()) |field_index| { |
| 526 | const field_ty = field_types[field_index]; | 527 | const field_ty = field_types[field_index]; |
| 527 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 528 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 528 | 529 | ||
| 529 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 530 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 530 | .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{ | 531 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 531 | .ty = field_ty, | 532 | .ty = field_ty, |
| 532 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 533 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| 533 | } }), | 534 | } }), |
| ... | @@ -541,7 +542,7 @@ pub fn generateSymbol( | ... | @@ -541,7 +542,7 @@ pub fn generateSymbol( |
| 541 | ) orelse return error.Overflow; | 542 | ) orelse return error.Overflow; |
| 542 | if (padding > 0) try code.appendNTimes(0, padding); | 543 | if (padding > 0) try code.appendNTimes(0, padding); |
| 543 | 544 | ||
| 544 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { | 545 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { |
| 545 | .ok => {}, | 546 | .ok => {}, |
| 546 | .fail => |em| return Result{ .fail = em }, | 547 | .fail => |em| return Result{ .fail = em }, |
| 547 | } | 548 | } |
| ... | @@ -562,15 +563,15 @@ pub fn generateSymbol( | ... | @@ -562,15 +563,15 @@ pub fn generateSymbol( |
| 562 | else => unreachable, | 563 | else => unreachable, |
| 563 | }, | 564 | }, |
| 564 | .un => |un| { | 565 | .un => |un| { |
| 565 | const layout = ty.unionGetLayout(mod); | 566 | const layout = ty.unionGetLayout(pt); |
| 566 | 567 | ||
| 567 | if (layout.payload_size == 0) { | 568 | if (layout.payload_size == 0) { |
| 568 | return generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info); | 569 | return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info); |
| 569 | } | 570 | } |
| 570 | 571 | ||
| 571 | // Check if we should store the tag first. | 572 | // Check if we should store the tag first. |
| 572 | if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { | 573 | if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { |
| 573 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { | 574 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { |
| 574 | .ok => {}, | 575 | .ok => {}, |
| 575 | .fail => |em| return Result{ .fail = em }, | 576 | .fail => |em| return Result{ .fail = em }, |
| 576 | } | 577 | } |
| ... | @@ -580,28 +581,28 @@ pub fn generateSymbol( | ... | @@ -580,28 +581,28 @@ pub fn generateSymbol( |
| 580 | if (un.tag != .none) { | 581 | if (un.tag != .none) { |
| 581 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; | 582 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; |
| 582 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 583 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 583 | if (!field_ty.hasRuntimeBits(mod)) { | 584 | if (!field_ty.hasRuntimeBits(pt)) { |
| 584 | try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); | 585 | try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); |
| 585 | } else { | 586 | } else { |
| 586 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { | 587 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { |
| 587 | .ok => {}, | 588 | .ok => {}, |
| 588 | .fail => |em| return Result{ .fail = em }, | 589 | .fail => |em| return Result{ .fail = em }, |
| 589 | } | 590 | } |
| 590 | 591 | ||
| 591 | const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(mod)) orelse return error.Overflow; | 592 | const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(pt)) orelse return error.Overflow; |
| 592 | if (padding > 0) { | 593 | if (padding > 0) { |
| 593 | try code.appendNTimes(0, padding); | 594 | try code.appendNTimes(0, padding); |
| 594 | } | 595 | } |
| 595 | } | 596 | } |
| 596 | } else { | 597 | } else { |
| 597 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { | 598 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { |
| 598 | .ok => {}, | 599 | .ok => {}, |
| 599 | .fail => |em| return Result{ .fail = em }, | 600 | .fail => |em| return Result{ .fail = em }, |
| 600 | } | 601 | } |
| 601 | } | 602 | } |
| 602 | 603 | ||
| 603 | if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { | 604 | if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { |
| 604 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { | 605 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { |
| 605 | .ok => {}, | 606 | .ok => {}, |
| 606 | .fail => |em| return Result{ .fail = em }, | 607 | .fail => |em| return Result{ .fail = em }, |
| 607 | } | 608 | } |
| ... | @@ -618,22 +619,24 @@ pub fn generateSymbol( | ... | @@ -618,22 +619,24 @@ pub fn generateSymbol( |
| 618 | 619 | ||
| 619 | fn lowerPtr( | 620 | fn lowerPtr( |
| 620 | bin_file: *link.File, | 621 | bin_file: *link.File, |
| 621 | src_loc: Module.LazySrcLoc, | 622 | pt: Zcu.PerThread, |
| 623 | src_loc: Zcu.LazySrcLoc, | ||
| 622 | ptr_val: InternPool.Index, | 624 | ptr_val: InternPool.Index, |
| 623 | code: *std.ArrayList(u8), | 625 | code: *std.ArrayList(u8), |
| 624 | debug_output: DebugInfoOutput, | 626 | debug_output: DebugInfoOutput, |
| 625 | reloc_info: RelocInfo, | 627 | reloc_info: RelocInfo, |
| 626 | prev_offset: u64, | 628 | prev_offset: u64, |
| 627 | ) CodeGenError!Result { | 629 | ) CodeGenError!Result { |
| 628 | const zcu = bin_file.comp.module.?; | 630 | const zcu = pt.zcu; |
| 629 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 631 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 630 | const offset: u64 = prev_offset + ptr.byte_offset; | 632 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 631 | return switch (ptr.base_addr) { | 633 | return switch (ptr.base_addr) { |
| 632 | .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info, offset), | 634 | .decl => |decl| try lowerDeclRef(bin_file, pt, src_loc, decl, code, debug_output, reloc_info, offset), |
| 633 | .anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info, offset), | 635 | .anon_decl => |ad| try lowerAnonDeclRef(bin_file, pt, src_loc, ad, code, debug_output, reloc_info, offset), |
| 634 | .int => try generateSymbol(bin_file, src_loc, try zcu.intValue(Type.usize, offset), code, debug_output, reloc_info), | 636 | .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info), |
| 635 | .eu_payload => |eu_ptr| try lowerPtr( | 637 | .eu_payload => |eu_ptr| try lowerPtr( |
| 636 | bin_file, | 638 | bin_file, |
| 639 | pt, | ||
| 637 | src_loc, | 640 | src_loc, |
| 638 | eu_ptr, | 641 | eu_ptr, |
| 639 | code, | 642 | code, |
| ... | @@ -641,11 +644,12 @@ fn lowerPtr( | ... | @@ -641,11 +644,12 @@ fn lowerPtr( |
| 641 | reloc_info, | 644 | reloc_info, |
| 642 | offset + errUnionPayloadOffset( | 645 | offset + errUnionPayloadOffset( |
| 643 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu), | 646 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu), |
| 644 | zcu, | 647 | pt, |
| 645 | ), | 648 | ), |
| 646 | ), | 649 | ), |
| 647 | .opt_payload => |opt_ptr| try lowerPtr( | 650 | .opt_payload => |opt_ptr| try lowerPtr( |
| 648 | bin_file, | 651 | bin_file, |
| 652 | pt, | ||
| 649 | src_loc, | 653 | src_loc, |
| 650 | opt_ptr, | 654 | opt_ptr, |
| 651 | code, | 655 | code, |
| ... | @@ -666,12 +670,12 @@ fn lowerPtr( | ... | @@ -666,12 +670,12 @@ fn lowerPtr( |
| 666 | }; | 670 | }; |
| 667 | }, | 671 | }, |
| 668 | .Struct, .Union => switch (base_ty.containerLayout(zcu)) { | 672 | .Struct, .Union => switch (base_ty.containerLayout(zcu)) { |
| 669 | .auto => base_ty.structFieldOffset(@intCast(field.index), zcu), | 673 | .auto => base_ty.structFieldOffset(@intCast(field.index), pt), |
| 670 | .@"extern", .@"packed" => unreachable, | 674 | .@"extern", .@"packed" => unreachable, |
| 671 | }, | 675 | }, |
| 672 | else => unreachable, | 676 | else => unreachable, |
| 673 | }; | 677 | }; |
| 674 | return lowerPtr(bin_file, src_loc, field.base, code, debug_output, reloc_info, offset + field_off); | 678 | return lowerPtr(bin_file, pt, src_loc, field.base, code, debug_output, reloc_info, offset + field_off); |
| 675 | }, | 679 | }, |
| 676 | .arr_elem, .comptime_field, .comptime_alloc => unreachable, | 680 | .arr_elem, .comptime_field, .comptime_alloc => unreachable, |
| 677 | }; | 681 | }; |
| ... | @@ -683,7 +687,8 @@ const RelocInfo = struct { | ... | @@ -683,7 +687,8 @@ const RelocInfo = struct { |
| 683 | 687 | ||
| 684 | fn lowerAnonDeclRef( | 688 | fn lowerAnonDeclRef( |
| 685 | lf: *link.File, | 689 | lf: *link.File, |
| 686 | src_loc: Module.LazySrcLoc, | 690 | pt: Zcu.PerThread, |
| 691 | src_loc: Zcu.LazySrcLoc, | ||
| 687 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, | 692 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, |
| 688 | code: *std.ArrayList(u8), | 693 | code: *std.ArrayList(u8), |
| 689 | debug_output: DebugInfoOutput, | 694 | debug_output: DebugInfoOutput, |
| ... | @@ -691,22 +696,21 @@ fn lowerAnonDeclRef( | ... | @@ -691,22 +696,21 @@ fn lowerAnonDeclRef( |
| 691 | offset: u64, | 696 | offset: u64, |
| 692 | ) CodeGenError!Result { | 697 | ) CodeGenError!Result { |
| 693 | _ = debug_output; | 698 | _ = debug_output; |
| 694 | const zcu = lf.comp.module.?; | 699 | const ip = &pt.zcu.intern_pool; |
| 695 | const ip = &zcu.intern_pool; | ||
| 696 | const target = lf.comp.root_mod.resolved_target.result; | 700 | const target = lf.comp.root_mod.resolved_target.result; |
| 697 | 701 | ||
| 698 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); | 702 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 699 | const decl_val = anon_decl.val; | 703 | const decl_val = anon_decl.val; |
| 700 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); | 704 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); |
| 701 | log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(zcu)}); | 705 | log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(pt)}); |
| 702 | const is_fn_body = decl_ty.zigTypeTag(zcu) == .Fn; | 706 | const is_fn_body = decl_ty.zigTypeTag(pt.zcu) == .Fn; |
| 703 | if (!is_fn_body and !decl_ty.hasRuntimeBits(zcu)) { | 707 | if (!is_fn_body and !decl_ty.hasRuntimeBits(pt)) { |
| 704 | try code.appendNTimes(0xaa, ptr_width_bytes); | 708 | try code.appendNTimes(0xaa, ptr_width_bytes); |
| 705 | return Result.ok; | 709 | return Result.ok; |
| 706 | } | 710 | } |
| 707 | 711 | ||
| 708 | const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | 712 | const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; |
| 709 | const res = try lf.lowerAnonDecl(decl_val, decl_align, src_loc); | 713 | const res = try lf.lowerAnonDecl(pt, decl_val, decl_align, src_loc); |
| 710 | switch (res) { | 714 | switch (res) { |
| 711 | .ok => {}, | 715 | .ok => {}, |
| 712 | .fail => |em| return .{ .fail = em }, | 716 | .fail => |em| return .{ .fail = em }, |
| ... | @@ -730,7 +734,8 @@ fn lowerAnonDeclRef( | ... | @@ -730,7 +734,8 @@ fn lowerAnonDeclRef( |
| 730 | 734 | ||
| 731 | fn lowerDeclRef( | 735 | fn lowerDeclRef( |
| 732 | lf: *link.File, | 736 | lf: *link.File, |
| 733 | src_loc: Module.LazySrcLoc, | 737 | pt: Zcu.PerThread, |
| 738 | src_loc: Zcu.LazySrcLoc, | ||
| 734 | decl_index: InternPool.DeclIndex, | 739 | decl_index: InternPool.DeclIndex, |
| 735 | code: *std.ArrayList(u8), | 740 | code: *std.ArrayList(u8), |
| 736 | debug_output: DebugInfoOutput, | 741 | debug_output: DebugInfoOutput, |
| ... | @@ -739,14 +744,14 @@ fn lowerDeclRef( | ... | @@ -739,14 +744,14 @@ fn lowerDeclRef( |
| 739 | ) CodeGenError!Result { | 744 | ) CodeGenError!Result { |
| 740 | _ = src_loc; | 745 | _ = src_loc; |
| 741 | _ = debug_output; | 746 | _ = debug_output; |
| 742 | const zcu = lf.comp.module.?; | 747 | const zcu = pt.zcu; |
| 743 | const decl = zcu.declPtr(decl_index); | 748 | const decl = zcu.declPtr(decl_index); |
| 744 | const namespace = zcu.namespacePtr(decl.src_namespace); | 749 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 745 | const target = namespace.fileScope(zcu).mod.resolved_target.result; | 750 | const target = namespace.fileScope(zcu).mod.resolved_target.result; |
| 746 | 751 | ||
| 747 | const ptr_width = target.ptrBitWidth(); | 752 | const ptr_width = target.ptrBitWidth(); |
| 748 | const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn; | 753 | const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn; |
| 749 | if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(zcu)) { | 754 | if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(pt)) { |
| 750 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); | 755 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); |
| 751 | return Result.ok; | 756 | return Result.ok; |
| 752 | } | 757 | } |
| ... | @@ -814,7 +819,7 @@ pub const GenResult = union(enum) { | ... | @@ -814,7 +819,7 @@ pub const GenResult = union(enum) { |
| 814 | 819 | ||
| 815 | fn fail( | 820 | fn fail( |
| 816 | gpa: Allocator, | 821 | gpa: Allocator, |
| 817 | src_loc: Module.LazySrcLoc, | 822 | src_loc: Zcu.LazySrcLoc, |
| 818 | comptime format: []const u8, | 823 | comptime format: []const u8, |
| 819 | args: anytype, | 824 | args: anytype, |
| 820 | ) Allocator.Error!GenResult { | 825 | ) Allocator.Error!GenResult { |
| ... | @@ -825,14 +830,15 @@ pub const GenResult = union(enum) { | ... | @@ -825,14 +830,15 @@ pub const GenResult = union(enum) { |
| 825 | 830 | ||
| 826 | fn genDeclRef( | 831 | fn genDeclRef( |
| 827 | lf: *link.File, | 832 | lf: *link.File, |
| 828 | src_loc: Module.LazySrcLoc, | 833 | pt: Zcu.PerThread, |
| 834 | src_loc: Zcu.LazySrcLoc, | ||
| 829 | val: Value, | 835 | val: Value, |
| 830 | ptr_decl_index: InternPool.DeclIndex, | 836 | ptr_decl_index: InternPool.DeclIndex, |
| 831 | ) CodeGenError!GenResult { | 837 | ) CodeGenError!GenResult { |
| 832 | const zcu = lf.comp.module.?; | 838 | const zcu = pt.zcu; |
| 833 | const ip = &zcu.intern_pool; | 839 | const ip = &zcu.intern_pool; |
| 834 | const ty = val.typeOf(zcu); | 840 | const ty = val.typeOf(zcu); |
| 835 | log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu, null)}); | 841 | log.debug("genDeclRef: val = {}", .{val.fmtValue(pt, null)}); |
| 836 | 842 | ||
| 837 | const ptr_decl = zcu.declPtr(ptr_decl_index); | 843 | const ptr_decl = zcu.declPtr(ptr_decl_index); |
| 838 | const namespace = zcu.namespacePtr(ptr_decl.src_namespace); | 844 | const namespace = zcu.namespacePtr(ptr_decl.src_namespace); |
| ... | @@ -848,7 +854,7 @@ fn genDeclRef( | ... | @@ -848,7 +854,7 @@ fn genDeclRef( |
| 848 | }; | 854 | }; |
| 849 | const decl = zcu.declPtr(decl_index); | 855 | const decl = zcu.declPtr(decl_index); |
| 850 | 856 | ||
| 851 | if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | 857 | if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 852 | const imm: u64 = switch (ptr_bytes) { | 858 | const imm: u64 = switch (ptr_bytes) { |
| 853 | 1 => 0xaa, | 859 | 1 => 0xaa, |
| 854 | 2 => 0xaaaa, | 860 | 2 => 0xaaaa, |
| ... | @@ -865,12 +871,12 @@ fn genDeclRef( | ... | @@ -865,12 +871,12 @@ fn genDeclRef( |
| 865 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? | 871 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? |
| 866 | if (ty.castPtrToFn(zcu)) |fn_ty| { | 872 | if (ty.castPtrToFn(zcu)) |fn_ty| { |
| 867 | if (zcu.typeToFunc(fn_ty).?.is_generic) { | 873 | if (zcu.typeToFunc(fn_ty).?.is_generic) { |
| 868 | return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? }); | 874 | return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(pt).toByteUnits().? }); |
| 869 | } | 875 | } |
| 870 | } else if (ty.zigTypeTag(zcu) == .Pointer) { | 876 | } else if (ty.zigTypeTag(zcu) == .Pointer) { |
| 871 | const elem_ty = ty.elemType2(zcu); | 877 | const elem_ty = ty.elemType2(zcu); |
| 872 | if (!elem_ty.hasRuntimeBits(zcu)) { | 878 | if (!elem_ty.hasRuntimeBits(pt)) { |
| 873 | return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? }); | 879 | return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(pt).toByteUnits().? }); |
| 874 | } | 880 | } |
| 875 | } | 881 | } |
| 876 | 882 | ||
| ... | @@ -931,15 +937,15 @@ fn genDeclRef( | ... | @@ -931,15 +937,15 @@ fn genDeclRef( |
| 931 | 937 | ||
| 932 | fn genUnnamedConst( | 938 | fn genUnnamedConst( |
| 933 | lf: *link.File, | 939 | lf: *link.File, |
| 934 | src_loc: Module.LazySrcLoc, | 940 | pt: Zcu.PerThread, |
| 941 | src_loc: Zcu.LazySrcLoc, | ||
| 935 | val: Value, | 942 | val: Value, |
| 936 | owner_decl_index: InternPool.DeclIndex, | 943 | owner_decl_index: InternPool.DeclIndex, |
| 937 | ) CodeGenError!GenResult { | 944 | ) CodeGenError!GenResult { |
| 938 | const zcu = lf.comp.module.?; | ||
| 939 | const gpa = lf.comp.gpa; | 945 | const gpa = lf.comp.gpa; |
| 940 | log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu, null)}); | 946 | log.debug("genUnnamedConst: val = {}", .{val.fmtValue(pt, null)}); |
| 941 | 947 | ||
| 942 | const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| { | 948 | const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| { |
| 943 | return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); | 949 | return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| 944 | }; | 950 | }; |
| 945 | switch (lf.tag) { | 951 | switch (lf.tag) { |
| ... | @@ -970,15 +976,16 @@ fn genUnnamedConst( | ... | @@ -970,15 +976,16 @@ fn genUnnamedConst( |
| 970 | 976 | ||
| 971 | pub fn genTypedValue( | 977 | pub fn genTypedValue( |
| 972 | lf: *link.File, | 978 | lf: *link.File, |
| 973 | src_loc: Module.LazySrcLoc, | 979 | pt: Zcu.PerThread, |
| 980 | src_loc: Zcu.LazySrcLoc, | ||
| 974 | val: Value, | 981 | val: Value, |
| 975 | owner_decl_index: InternPool.DeclIndex, | 982 | owner_decl_index: InternPool.DeclIndex, |
| 976 | ) CodeGenError!GenResult { | 983 | ) CodeGenError!GenResult { |
| 977 | const zcu = lf.comp.module.?; | 984 | const zcu = pt.zcu; |
| 978 | const ip = &zcu.intern_pool; | 985 | const ip = &zcu.intern_pool; |
| 979 | const ty = val.typeOf(zcu); | 986 | const ty = val.typeOf(zcu); |
| 980 | 987 | ||
| 981 | log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu, null)}); | 988 | log.debug("genTypedValue: val = {}", .{val.fmtValue(pt, null)}); |
| 982 | 989 | ||
| 983 | if (val.isUndef(zcu)) | 990 | if (val.isUndef(zcu)) |
| 984 | return GenResult.mcv(.undef); | 991 | return GenResult.mcv(.undef); |
| ... | @@ -990,7 +997,7 @@ pub fn genTypedValue( | ... | @@ -990,7 +997,7 @@ pub fn genTypedValue( |
| 990 | 997 | ||
| 991 | if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) { | 998 | if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) { |
| 992 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 999 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { |
| 993 | .decl => |decl| return genDeclRef(lf, src_loc, val, decl), | 1000 | .decl => |decl| return genDeclRef(lf, pt, src_loc, val, decl), |
| 994 | else => {}, | 1001 | else => {}, |
| 995 | }, | 1002 | }, |
| 996 | else => {}, | 1003 | else => {}, |
| ... | @@ -1007,7 +1014,7 @@ pub fn genTypedValue( | ... | @@ -1007,7 +1014,7 @@ pub fn genTypedValue( |
| 1007 | .none => {}, | 1014 | .none => {}, |
| 1008 | else => switch (ip.indexToKey(val.toIntern())) { | 1015 | else => switch (ip.indexToKey(val.toIntern())) { |
| 1009 | .int => { | 1016 | .int => { |
| 1010 | return GenResult.mcv(.{ .immediate = val.toUnsignedInt(zcu) }); | 1017 | return GenResult.mcv(.{ .immediate = val.toUnsignedInt(pt) }); |
| 1011 | }, | 1018 | }, |
| 1012 | else => {}, | 1019 | else => {}, |
| 1013 | }, | 1020 | }, |
| ... | @@ -1017,8 +1024,8 @@ pub fn genTypedValue( | ... | @@ -1017,8 +1024,8 @@ pub fn genTypedValue( |
| 1017 | const info = ty.intInfo(zcu); | 1024 | const info = ty.intInfo(zcu); |
| 1018 | if (info.bits <= ptr_bits) { | 1025 | if (info.bits <= ptr_bits) { |
| 1019 | const unsigned: u64 = switch (info.signedness) { | 1026 | const unsigned: u64 = switch (info.signedness) { |
| 1020 | .signed => @bitCast(val.toSignedInt(zcu)), | 1027 | .signed => @bitCast(val.toSignedInt(pt)), |
| 1021 | .unsigned => val.toUnsignedInt(zcu), | 1028 | .unsigned => val.toUnsignedInt(pt), |
| 1022 | }; | 1029 | }; |
| 1023 | return GenResult.mcv(.{ .immediate = unsigned }); | 1030 | return GenResult.mcv(.{ .immediate = unsigned }); |
| 1024 | } | 1031 | } |
| ... | @@ -1030,11 +1037,12 @@ pub fn genTypedValue( | ... | @@ -1030,11 +1037,12 @@ pub fn genTypedValue( |
| 1030 | if (ty.isPtrLikeOptional(zcu)) { | 1037 | if (ty.isPtrLikeOptional(zcu)) { |
| 1031 | return genTypedValue( | 1038 | return genTypedValue( |
| 1032 | lf, | 1039 | lf, |
| 1040 | pt, | ||
| 1033 | src_loc, | 1041 | src_loc, |
| 1034 | val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }), | 1042 | val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }), |
| 1035 | owner_decl_index, | 1043 | owner_decl_index, |
| 1036 | ); | 1044 | ); |
| 1037 | } else if (ty.abiSize(zcu) == 1) { | 1045 | } else if (ty.abiSize(pt) == 1) { |
| 1038 | return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) }); | 1046 | return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) }); |
| 1039 | } | 1047 | } |
| 1040 | }, | 1048 | }, |
| ... | @@ -1042,6 +1050,7 @@ pub fn genTypedValue( | ... | @@ -1042,6 +1050,7 @@ pub fn genTypedValue( |
| 1042 | const enum_tag = ip.indexToKey(val.toIntern()).enum_tag; | 1050 | const enum_tag = ip.indexToKey(val.toIntern()).enum_tag; |
| 1043 | return genTypedValue( | 1051 | return genTypedValue( |
| 1044 | lf, | 1052 | lf, |
| 1053 | pt, | ||
| 1045 | src_loc, | 1054 | src_loc, |
| 1046 | Value.fromInterned(enum_tag.int), | 1055 | Value.fromInterned(enum_tag.int), |
| 1047 | owner_decl_index, | 1056 | owner_decl_index, |
| ... | @@ -1055,14 +1064,15 @@ pub fn genTypedValue( | ... | @@ -1055,14 +1064,15 @@ pub fn genTypedValue( |
| 1055 | .ErrorUnion => { | 1064 | .ErrorUnion => { |
| 1056 | const err_type = ty.errorUnionSet(zcu); | 1065 | const err_type = ty.errorUnionSet(zcu); |
| 1057 | const payload_type = ty.errorUnionPayload(zcu); | 1066 | const payload_type = ty.errorUnionPayload(zcu); |
| 1058 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { | 1067 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1059 | // We use the error type directly as the type. | 1068 | // We use the error type directly as the type. |
| 1060 | const err_int_ty = try zcu.errorIntType(); | 1069 | const err_int_ty = try pt.errorIntType(); |
| 1061 | switch (ip.indexToKey(val.toIntern()).error_union.val) { | 1070 | switch (ip.indexToKey(val.toIntern()).error_union.val) { |
| 1062 | .err_name => |err_name| return genTypedValue( | 1071 | .err_name => |err_name| return genTypedValue( |
| 1063 | lf, | 1072 | lf, |
| 1073 | pt, | ||
| 1064 | src_loc, | 1074 | src_loc, |
| 1065 | Value.fromInterned(try zcu.intern(.{ .err = .{ | 1075 | Value.fromInterned(try pt.intern(.{ .err = .{ |
| 1066 | .ty = err_type.toIntern(), | 1076 | .ty = err_type.toIntern(), |
| 1067 | .name = err_name, | 1077 | .name = err_name, |
| 1068 | } })), | 1078 | } })), |
| ... | @@ -1070,8 +1080,9 @@ pub fn genTypedValue( | ... | @@ -1070,8 +1080,9 @@ pub fn genTypedValue( |
| 1070 | ), | 1080 | ), |
| 1071 | .payload => return genTypedValue( | 1081 | .payload => return genTypedValue( |
| 1072 | lf, | 1082 | lf, |
| 1083 | pt, | ||
| 1073 | src_loc, | 1084 | src_loc, |
| 1074 | try zcu.intValue(err_int_ty, 0), | 1085 | try pt.intValue(err_int_ty, 0), |
| 1075 | owner_decl_index, | 1086 | owner_decl_index, |
| 1076 | ), | 1087 | ), |
| 1077 | } | 1088 | } |
| ... | @@ -1090,26 +1101,26 @@ pub fn genTypedValue( | ... | @@ -1090,26 +1101,26 @@ pub fn genTypedValue( |
| 1090 | else => {}, | 1101 | else => {}, |
| 1091 | } | 1102 | } |
| 1092 | 1103 | ||
| 1093 | return genUnnamedConst(lf, src_loc, val, owner_decl_index); | 1104 | return genUnnamedConst(lf, pt, src_loc, val, owner_decl_index); |
| 1094 | } | 1105 | } |
| 1095 | 1106 | ||
| 1096 | pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 { | 1107 | pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { |
| 1097 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0; | 1108 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; |
| 1098 | const payload_align = payload_ty.abiAlignment(mod); | 1109 | const payload_align = payload_ty.abiAlignment(pt); |
| 1099 | const error_align = Type.anyerror.abiAlignment(mod); | 1110 | const error_align = Type.anyerror.abiAlignment(pt); |
| 1100 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1111 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1101 | return 0; | 1112 | return 0; |
| 1102 | } else { | 1113 | } else { |
| 1103 | return payload_align.forward(Type.anyerror.abiSize(mod)); | 1114 | return payload_align.forward(Type.anyerror.abiSize(pt)); |
| 1104 | } | 1115 | } |
| 1105 | } | 1116 | } |
| 1106 | 1117 | ||
| 1107 | pub fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u64 { | 1118 | pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { |
| 1108 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0; | 1119 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; |
| 1109 | const payload_align = payload_ty.abiAlignment(mod); | 1120 | const payload_align = payload_ty.abiAlignment(pt); |
| 1110 | const error_align = Type.anyerror.abiAlignment(mod); | 1121 | const error_align = Type.anyerror.abiAlignment(pt); |
| 1111 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1122 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1112 | return error_align.forward(payload_ty.abiSize(mod)); | 1123 | return error_align.forward(payload_ty.abiSize(pt)); |
| 1113 | } else { | 1124 | } else { |
| 1114 | return 0; | 1125 | return 0; |
| 1115 | } | 1126 | } |
src/codegen/c.zig+408-337| ... | @@ -333,15 +333,15 @@ pub const Function = struct { | ... | @@ -333,15 +333,15 @@ pub const Function = struct { |
| 333 | const gop = try f.value_map.getOrPut(ref); | 333 | const gop = try f.value_map.getOrPut(ref); |
| 334 | if (gop.found_existing) return gop.value_ptr.*; | 334 | if (gop.found_existing) return gop.value_ptr.*; |
| 335 | 335 | ||
| 336 | const zcu = f.object.dg.zcu; | 336 | const pt = f.object.dg.pt; |
| 337 | const val = (try f.air.value(ref, zcu)).?; | 337 | const val = (try f.air.value(ref, pt)).?; |
| 338 | const ty = f.typeOf(ref); | 338 | const ty = f.typeOf(ref); |
| 339 | 339 | ||
| 340 | const result: CValue = if (lowersToArray(ty, zcu)) result: { | 340 | const result: CValue = if (lowersToArray(ty, pt)) result: { |
| 341 | const writer = f.object.codeHeaderWriter(); | 341 | const writer = f.object.codeHeaderWriter(); |
| 342 | const decl_c_value = try f.allocLocalValue(.{ | 342 | const decl_c_value = try f.allocLocalValue(.{ |
| 343 | .ctype = try f.ctypeFromType(ty, .complete), | 343 | .ctype = try f.ctypeFromType(ty, .complete), |
| 344 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(zcu)), | 344 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt)), |
| 345 | }); | 345 | }); |
| 346 | const gpa = f.object.dg.gpa; | 346 | const gpa = f.object.dg.gpa; |
| 347 | try f.allocs.put(gpa, decl_c_value.new_local, false); | 347 | try f.allocs.put(gpa, decl_c_value.new_local, false); |
| ... | @@ -358,7 +358,7 @@ pub const Function = struct { | ... | @@ -358,7 +358,7 @@ pub const Function = struct { |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | fn wantSafety(f: *Function) bool { | 360 | fn wantSafety(f: *Function) bool { |
| 361 | return switch (f.object.dg.zcu.optimizeMode()) { | 361 | return switch (f.object.dg.pt.zcu.optimizeMode()) { |
| 362 | .Debug, .ReleaseSafe => true, | 362 | .Debug, .ReleaseSafe => true, |
| 363 | .ReleaseFast, .ReleaseSmall => false, | 363 | .ReleaseFast, .ReleaseSmall => false, |
| 364 | }; | 364 | }; |
| ... | @@ -379,7 +379,7 @@ pub const Function = struct { | ... | @@ -379,7 +379,7 @@ pub const Function = struct { |
| 379 | fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue { | 379 | fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue { |
| 380 | return f.allocAlignedLocal(inst, .{ | 380 | return f.allocAlignedLocal(inst, .{ |
| 381 | .ctype = try f.ctypeFromType(ty, .complete), | 381 | .ctype = try f.ctypeFromType(ty, .complete), |
| 382 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.zcu)), | 382 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt)), |
| 383 | }); | 383 | }); |
| 384 | } | 384 | } |
| 385 | 385 | ||
| ... | @@ -500,7 +500,8 @@ pub const Function = struct { | ... | @@ -500,7 +500,8 @@ pub const Function = struct { |
| 500 | 500 | ||
| 501 | fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 { | 501 | fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 { |
| 502 | const gpa = f.object.dg.gpa; | 502 | const gpa = f.object.dg.gpa; |
| 503 | const zcu = f.object.dg.zcu; | 503 | const pt = f.object.dg.pt; |
| 504 | const zcu = pt.zcu; | ||
| 504 | const ctype_pool = &f.object.dg.ctype_pool; | 505 | const ctype_pool = &f.object.dg.ctype_pool; |
| 505 | 506 | ||
| 506 | const gop = try f.lazy_fns.getOrPut(gpa, key); | 507 | const gop = try f.lazy_fns.getOrPut(gpa, key); |
| ... | @@ -539,13 +540,11 @@ pub const Function = struct { | ... | @@ -539,13 +540,11 @@ pub const Function = struct { |
| 539 | } | 540 | } |
| 540 | 541 | ||
| 541 | fn typeOf(f: *Function, inst: Air.Inst.Ref) Type { | 542 | fn typeOf(f: *Function, inst: Air.Inst.Ref) Type { |
| 542 | const zcu = f.object.dg.zcu; | 543 | return f.air.typeOf(inst, &f.object.dg.pt.zcu.intern_pool); |
| 543 | return f.air.typeOf(inst, &zcu.intern_pool); | ||
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type { | 546 | fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type { |
| 547 | const zcu = f.object.dg.zcu; | 547 | return f.air.typeOfIndex(inst, &f.object.dg.pt.zcu.intern_pool); |
| 548 | return f.air.typeOfIndex(inst, &zcu.intern_pool); | ||
| 549 | } | 548 | } |
| 550 | 549 | ||
| 551 | fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void { | 550 | fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void { |
| ... | @@ -608,7 +607,7 @@ pub const Object = struct { | ... | @@ -608,7 +607,7 @@ pub const Object = struct { |
| 608 | /// This data is available both when outputting .c code and when outputting an .h file. | 607 | /// This data is available both when outputting .c code and when outputting an .h file. |
| 609 | pub const DeclGen = struct { | 608 | pub const DeclGen = struct { |
| 610 | gpa: mem.Allocator, | 609 | gpa: mem.Allocator, |
| 611 | zcu: *Zcu, | 610 | pt: Zcu.PerThread, |
| 612 | mod: *Module, | 611 | mod: *Module, |
| 613 | pass: Pass, | 612 | pass: Pass, |
| 614 | is_naked_fn: bool, | 613 | is_naked_fn: bool, |
| ... | @@ -634,7 +633,7 @@ pub const DeclGen = struct { | ... | @@ -634,7 +633,7 @@ pub const DeclGen = struct { |
| 634 | 633 | ||
| 635 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { | 634 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { |
| 636 | @setCold(true); | 635 | @setCold(true); |
| 637 | const zcu = dg.zcu; | 636 | const zcu = dg.pt.zcu; |
| 638 | const decl_index = dg.pass.decl; | 637 | const decl_index = dg.pass.decl; |
| 639 | const decl = zcu.declPtr(decl_index); | 638 | const decl = zcu.declPtr(decl_index); |
| 640 | const src_loc = decl.navSrcLoc(zcu); | 639 | const src_loc = decl.navSrcLoc(zcu); |
| ... | @@ -648,7 +647,8 @@ pub const DeclGen = struct { | ... | @@ -648,7 +647,8 @@ pub const DeclGen = struct { |
| 648 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, | 647 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, |
| 649 | location: ValueRenderLocation, | 648 | location: ValueRenderLocation, |
| 650 | ) error{ OutOfMemory, AnalysisFail }!void { | 649 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 651 | const zcu = dg.zcu; | 650 | const pt = dg.pt; |
| 651 | const zcu = pt.zcu; | ||
| 652 | const ip = &zcu.intern_pool; | 652 | const ip = &zcu.intern_pool; |
| 653 | const ctype_pool = &dg.ctype_pool; | 653 | const ctype_pool = &dg.ctype_pool; |
| 654 | const decl_val = Value.fromInterned(anon_decl.val); | 654 | const decl_val = Value.fromInterned(anon_decl.val); |
| ... | @@ -656,7 +656,7 @@ pub const DeclGen = struct { | ... | @@ -656,7 +656,7 @@ pub const DeclGen = struct { |
| 656 | 656 | ||
| 657 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 657 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 658 | const ptr_ty = Type.fromInterned(anon_decl.orig_ty); | 658 | const ptr_ty = Type.fromInterned(anon_decl.orig_ty); |
| 659 | if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(zcu)) { | 659 | if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(pt)) { |
| 660 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); | 660 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); |
| 661 | } | 661 | } |
| 662 | 662 | ||
| ... | @@ -696,7 +696,7 @@ pub const DeclGen = struct { | ... | @@ -696,7 +696,7 @@ pub const DeclGen = struct { |
| 696 | // alignment. If there is already an entry, keep the greater alignment. | 696 | // alignment. If there is already an entry, keep the greater alignment. |
| 697 | const explicit_alignment = ptr_type.flags.alignment; | 697 | const explicit_alignment = ptr_type.flags.alignment; |
| 698 | if (explicit_alignment != .none) { | 698 | if (explicit_alignment != .none) { |
| 699 | const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(zcu); | 699 | const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt); |
| 700 | if (explicit_alignment.order(abi_alignment).compare(.gt)) { | 700 | if (explicit_alignment.order(abi_alignment).compare(.gt)) { |
| 701 | const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val); | 701 | const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val); |
| 702 | aligned_gop.value_ptr.* = if (aligned_gop.found_existing) | 702 | aligned_gop.value_ptr.* = if (aligned_gop.found_existing) |
| ... | @@ -713,15 +713,16 @@ pub const DeclGen = struct { | ... | @@ -713,15 +713,16 @@ pub const DeclGen = struct { |
| 713 | decl_index: InternPool.DeclIndex, | 713 | decl_index: InternPool.DeclIndex, |
| 714 | location: ValueRenderLocation, | 714 | location: ValueRenderLocation, |
| 715 | ) error{ OutOfMemory, AnalysisFail }!void { | 715 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 716 | const zcu = dg.zcu; | 716 | const pt = dg.pt; |
| 717 | const zcu = pt.zcu; | ||
| 717 | const ctype_pool = &dg.ctype_pool; | 718 | const ctype_pool = &dg.ctype_pool; |
| 718 | const decl = zcu.declPtr(decl_index); | 719 | const decl = zcu.declPtr(decl_index); |
| 719 | assert(decl.has_tv); | 720 | assert(decl.has_tv); |
| 720 | 721 | ||
| 721 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 722 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 722 | const decl_ty = decl.typeOf(zcu); | 723 | const decl_ty = decl.typeOf(zcu); |
| 723 | const ptr_ty = try decl.declPtrType(zcu); | 724 | const ptr_ty = try decl.declPtrType(pt); |
| 724 | if (!decl_ty.isFnOrHasRuntimeBits(zcu)) { | 725 | if (!decl_ty.isFnOrHasRuntimeBits(pt)) { |
| 725 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); | 726 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); |
| 726 | } | 727 | } |
| 727 | 728 | ||
| ... | @@ -756,12 +757,13 @@ pub const DeclGen = struct { | ... | @@ -756,12 +757,13 @@ pub const DeclGen = struct { |
| 756 | derivation: Value.PointerDeriveStep, | 757 | derivation: Value.PointerDeriveStep, |
| 757 | location: ValueRenderLocation, | 758 | location: ValueRenderLocation, |
| 758 | ) error{ OutOfMemory, AnalysisFail }!void { | 759 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 759 | const zcu = dg.zcu; | 760 | const pt = dg.pt; |
| 761 | const zcu = pt.zcu; | ||
| 760 | switch (derivation) { | 762 | switch (derivation) { |
| 761 | .comptime_alloc_ptr, .comptime_field_ptr => unreachable, | 763 | .comptime_alloc_ptr, .comptime_field_ptr => unreachable, |
| 762 | .int => |int| { | 764 | .int => |int| { |
| 763 | const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete); | 765 | const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete); |
| 764 | const addr_val = try zcu.intValue(Type.usize, int.addr); | 766 | const addr_val = try pt.intValue(Type.usize, int.addr); |
| 765 | try writer.writeByte('('); | 767 | try writer.writeByte('('); |
| 766 | try dg.renderCType(writer, ptr_ctype); | 768 | try dg.renderCType(writer, ptr_ctype); |
| 767 | try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)}); | 769 | try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)}); |
| ... | @@ -777,12 +779,12 @@ pub const DeclGen = struct { | ... | @@ -777,12 +779,12 @@ pub const DeclGen = struct { |
| 777 | }, | 779 | }, |
| 778 | 780 | ||
| 779 | .field_ptr => |field| { | 781 | .field_ptr => |field| { |
| 780 | const parent_ptr_ty = try field.parent.ptrType(zcu); | 782 | const parent_ptr_ty = try field.parent.ptrType(pt); |
| 781 | 783 | ||
| 782 | // Ensure complete type definition is available before accessing fields. | 784 | // Ensure complete type definition is available before accessing fields. |
| 783 | _ = try dg.ctypeFromType(parent_ptr_ty.childType(zcu), .complete); | 785 | _ = try dg.ctypeFromType(parent_ptr_ty.childType(zcu), .complete); |
| 784 | 786 | ||
| 785 | switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, zcu)) { | 787 | switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) { |
| 786 | .begin => { | 788 | .begin => { |
| 787 | const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete); | 789 | const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete); |
| 788 | try writer.writeByte('('); | 790 | try writer.writeByte('('); |
| ... | @@ -801,7 +803,7 @@ pub const DeclGen = struct { | ... | @@ -801,7 +803,7 @@ pub const DeclGen = struct { |
| 801 | try writer.writeByte('('); | 803 | try writer.writeByte('('); |
| 802 | try dg.renderCType(writer, ptr_ctype); | 804 | try dg.renderCType(writer, ptr_ctype); |
| 803 | try writer.writeByte(')'); | 805 | try writer.writeByte(')'); |
| 804 | const offset_val = try zcu.intValue(Type.usize, byte_offset); | 806 | const offset_val = try pt.intValue(Type.usize, byte_offset); |
| 805 | try writer.writeAll("((char *)"); | 807 | try writer.writeAll("((char *)"); |
| 806 | try dg.renderPointer(writer, field.parent.*, location); | 808 | try dg.renderPointer(writer, field.parent.*, location); |
| 807 | try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); | 809 | try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); |
| ... | @@ -809,7 +811,7 @@ pub const DeclGen = struct { | ... | @@ -809,7 +811,7 @@ pub const DeclGen = struct { |
| 809 | } | 811 | } |
| 810 | }, | 812 | }, |
| 811 | 813 | ||
| 812 | .elem_ptr => |elem| if (!(try elem.parent.ptrType(zcu)).childType(zcu).hasRuntimeBits(zcu)) { | 814 | .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(pt)) { |
| 813 | // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer. | 815 | // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer. |
| 814 | const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete); | 816 | const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete); |
| 815 | try writer.writeByte('('); | 817 | try writer.writeByte('('); |
| ... | @@ -817,11 +819,11 @@ pub const DeclGen = struct { | ... | @@ -817,11 +819,11 @@ pub const DeclGen = struct { |
| 817 | try writer.writeByte(')'); | 819 | try writer.writeByte(')'); |
| 818 | try dg.renderPointer(writer, elem.parent.*, location); | 820 | try dg.renderPointer(writer, elem.parent.*, location); |
| 819 | } else { | 821 | } else { |
| 820 | const index_val = try zcu.intValue(Type.usize, elem.elem_idx); | 822 | const index_val = try pt.intValue(Type.usize, elem.elem_idx); |
| 821 | // We want to do pointer arithmetic on a pointer to the element type. | 823 | // We want to do pointer arithmetic on a pointer to the element type. |
| 822 | // We might have a pointer-to-array. In this case, we must cast first. | 824 | // We might have a pointer-to-array. In this case, we must cast first. |
| 823 | const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete); | 825 | const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete); |
| 824 | const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(zcu), .complete); | 826 | const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete); |
| 825 | if (result_ctype.eql(parent_ctype)) { | 827 | if (result_ctype.eql(parent_ctype)) { |
| 826 | // The pointer already has an appropriate type - just do the arithmetic. | 828 | // The pointer already has an appropriate type - just do the arithmetic. |
| 827 | try writer.writeByte('('); | 829 | try writer.writeByte('('); |
| ... | @@ -846,7 +848,7 @@ pub const DeclGen = struct { | ... | @@ -846,7 +848,7 @@ pub const DeclGen = struct { |
| 846 | if (oac.byte_offset == 0) { | 848 | if (oac.byte_offset == 0) { |
| 847 | try dg.renderPointer(writer, oac.parent.*, location); | 849 | try dg.renderPointer(writer, oac.parent.*, location); |
| 848 | } else { | 850 | } else { |
| 849 | const offset_val = try zcu.intValue(Type.usize, oac.byte_offset); | 851 | const offset_val = try pt.intValue(Type.usize, oac.byte_offset); |
| 850 | try writer.writeAll("((char *)"); | 852 | try writer.writeAll("((char *)"); |
| 851 | try dg.renderPointer(writer, oac.parent.*, location); | 853 | try dg.renderPointer(writer, oac.parent.*, location); |
| 852 | try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); | 854 | try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); |
| ... | @@ -856,8 +858,7 @@ pub const DeclGen = struct { | ... | @@ -856,8 +858,7 @@ pub const DeclGen = struct { |
| 856 | } | 858 | } |
| 857 | 859 | ||
| 858 | fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void { | 860 | fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void { |
| 859 | const zcu = dg.zcu; | 861 | const ip = &dg.pt.zcu.intern_pool; |
| 860 | const ip = &zcu.intern_pool; | ||
| 861 | try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))}); | 862 | try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))}); |
| 862 | } | 863 | } |
| 863 | 864 | ||
| ... | @@ -867,7 +868,8 @@ pub const DeclGen = struct { | ... | @@ -867,7 +868,8 @@ pub const DeclGen = struct { |
| 867 | val: Value, | 868 | val: Value, |
| 868 | location: ValueRenderLocation, | 869 | location: ValueRenderLocation, |
| 869 | ) error{ OutOfMemory, AnalysisFail }!void { | 870 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 870 | const zcu = dg.zcu; | 871 | const pt = dg.pt; |
| 872 | const zcu = pt.zcu; | ||
| 871 | const ip = &zcu.intern_pool; | 873 | const ip = &zcu.intern_pool; |
| 872 | const target = &dg.mod.resolved_target.result; | 874 | const target = &dg.mod.resolved_target.result; |
| 873 | const ctype_pool = &dg.ctype_pool; | 875 | const ctype_pool = &dg.ctype_pool; |
| ... | @@ -927,7 +929,7 @@ pub const DeclGen = struct { | ... | @@ -927,7 +929,7 @@ pub const DeclGen = struct { |
| 927 | try writer.writeAll("(("); | 929 | try writer.writeAll("(("); |
| 928 | try dg.renderCType(writer, ctype); | 930 | try dg.renderCType(writer, ctype); |
| 929 | try writer.print("){x})", .{try dg.fmtIntLiteral( | 931 | try writer.print("){x})", .{try dg.fmtIntLiteral( |
| 930 | try zcu.intValue(Type.usize, val.toUnsignedInt(zcu)), | 932 | try pt.intValue(Type.usize, val.toUnsignedInt(pt)), |
| 931 | .Other, | 933 | .Other, |
| 932 | )}); | 934 | )}); |
| 933 | }, | 935 | }, |
| ... | @@ -974,10 +976,10 @@ pub const DeclGen = struct { | ... | @@ -974,10 +976,10 @@ pub const DeclGen = struct { |
| 974 | .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location), | 976 | .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location), |
| 975 | .float => { | 977 | .float => { |
| 976 | const bits = ty.floatBits(target.*); | 978 | const bits = ty.floatBits(target.*); |
| 977 | const f128_val = val.toFloat(f128, zcu); | 979 | const f128_val = val.toFloat(f128, pt); |
| 978 | 980 | ||
| 979 | // All unsigned ints matching float types are pre-allocated. | 981 | // All unsigned ints matching float types are pre-allocated. |
| 980 | const repr_ty = zcu.intType(.unsigned, bits) catch unreachable; | 982 | const repr_ty = pt.intType(.unsigned, bits) catch unreachable; |
| 981 | 983 | ||
| 982 | assert(bits <= 128); | 984 | assert(bits <= 128); |
| 983 | var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; | 985 | var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; |
| ... | @@ -988,10 +990,10 @@ pub const DeclGen = struct { | ... | @@ -988,10 +990,10 @@ pub const DeclGen = struct { |
| 988 | }; | 990 | }; |
| 989 | 991 | ||
| 990 | switch (bits) { | 992 | switch (bits) { |
| 991 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))), | 993 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, pt)))), |
| 992 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))), | 994 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, pt)))), |
| 993 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))), | 995 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, pt)))), |
| 994 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))), | 996 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, pt)))), |
| 995 | 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))), | 997 | 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))), |
| 996 | else => unreachable, | 998 | else => unreachable, |
| 997 | } | 999 | } |
| ... | @@ -1002,10 +1004,10 @@ pub const DeclGen = struct { | ... | @@ -1002,10 +1004,10 @@ pub const DeclGen = struct { |
| 1002 | try dg.renderTypeForBuiltinFnName(writer, ty); | 1004 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 1003 | try writer.writeByte('('); | 1005 | try writer.writeByte('('); |
| 1004 | switch (bits) { | 1006 | switch (bits) { |
| 1005 | 16 => try writer.print("{x}", .{val.toFloat(f16, zcu)}), | 1007 | 16 => try writer.print("{x}", .{val.toFloat(f16, pt)}), |
| 1006 | 32 => try writer.print("{x}", .{val.toFloat(f32, zcu)}), | 1008 | 32 => try writer.print("{x}", .{val.toFloat(f32, pt)}), |
| 1007 | 64 => try writer.print("{x}", .{val.toFloat(f64, zcu)}), | 1009 | 64 => try writer.print("{x}", .{val.toFloat(f64, pt)}), |
| 1008 | 80 => try writer.print("{x}", .{val.toFloat(f80, zcu)}), | 1010 | 80 => try writer.print("{x}", .{val.toFloat(f80, pt)}), |
| 1009 | 128 => try writer.print("{x}", .{f128_val}), | 1011 | 128 => try writer.print("{x}", .{f128_val}), |
| 1010 | else => unreachable, | 1012 | else => unreachable, |
| 1011 | } | 1013 | } |
| ... | @@ -1045,10 +1047,10 @@ pub const DeclGen = struct { | ... | @@ -1045,10 +1047,10 @@ pub const DeclGen = struct { |
| 1045 | if (std.math.isNan(f128_val)) switch (bits) { | 1047 | if (std.math.isNan(f128_val)) switch (bits) { |
| 1046 | // We only actually need to pass the significand, but it will get | 1048 | // We only actually need to pass the significand, but it will get |
| 1047 | // properly masked anyway, so just pass the whole value. | 1049 | // properly masked anyway, so just pass the whole value. |
| 1048 | 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}), | 1050 | 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, pt)))}), |
| 1049 | 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}), | 1051 | 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, pt)))}), |
| 1050 | 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}), | 1052 | 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, pt)))}), |
| 1051 | 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}), | 1053 | 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, pt)))}), |
| 1052 | 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}), | 1054 | 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}), |
| 1053 | else => unreachable, | 1055 | else => unreachable, |
| 1054 | }; | 1056 | }; |
| ... | @@ -1056,7 +1058,7 @@ pub const DeclGen = struct { | ... | @@ -1056,7 +1058,7 @@ pub const DeclGen = struct { |
| 1056 | empty = false; | 1058 | empty = false; |
| 1057 | } | 1059 | } |
| 1058 | try writer.print("{x}", .{try dg.fmtIntLiteral( | 1060 | try writer.print("{x}", .{try dg.fmtIntLiteral( |
| 1059 | try zcu.intValue_big(repr_ty, repr_val_big.toConst()), | 1061 | try pt.intValue_big(repr_ty, repr_val_big.toConst()), |
| 1060 | location, | 1062 | location, |
| 1061 | )}); | 1063 | )}); |
| 1062 | if (!empty) try writer.writeByte(')'); | 1064 | if (!empty) try writer.writeByte(')'); |
| ... | @@ -1084,7 +1086,7 @@ pub const DeclGen = struct { | ... | @@ -1084,7 +1086,7 @@ pub const DeclGen = struct { |
| 1084 | .ptr => { | 1086 | .ptr => { |
| 1085 | var arena = std.heap.ArenaAllocator.init(zcu.gpa); | 1087 | var arena = std.heap.ArenaAllocator.init(zcu.gpa); |
| 1086 | defer arena.deinit(); | 1088 | defer arena.deinit(); |
| 1087 | const derivation = try val.pointerDerivation(arena.allocator(), zcu); | 1089 | const derivation = try val.pointerDerivation(arena.allocator(), pt); |
| 1088 | try dg.renderPointer(writer, derivation, location); | 1090 | try dg.renderPointer(writer, derivation, location); |
| 1089 | }, | 1091 | }, |
| 1090 | .opt => |opt| switch (ctype.info(ctype_pool)) { | 1092 | .opt => |opt| switch (ctype.info(ctype_pool)) { |
| ... | @@ -1167,15 +1169,15 @@ pub const DeclGen = struct { | ... | @@ -1167,15 +1169,15 @@ pub const DeclGen = struct { |
| 1167 | try literal.start(); | 1169 | try literal.start(); |
| 1168 | var index: usize = 0; | 1170 | var index: usize = 0; |
| 1169 | while (index < ai.len) : (index += 1) { | 1171 | while (index < ai.len) : (index += 1) { |
| 1170 | const elem_val = try val.elemValue(zcu, index); | 1172 | const elem_val = try val.elemValue(pt, index); |
| 1171 | const elem_val_u8: u8 = if (elem_val.isUndef(zcu)) | 1173 | const elem_val_u8: u8 = if (elem_val.isUndef(zcu)) |
| 1172 | undefPattern(u8) | 1174 | undefPattern(u8) |
| 1173 | else | 1175 | else |
| 1174 | @intCast(elem_val.toUnsignedInt(zcu)); | 1176 | @intCast(elem_val.toUnsignedInt(pt)); |
| 1175 | try literal.writeChar(elem_val_u8); | 1177 | try literal.writeChar(elem_val_u8); |
| 1176 | } | 1178 | } |
| 1177 | if (ai.sentinel) |s| { | 1179 | if (ai.sentinel) |s| { |
| 1178 | const s_u8: u8 = @intCast(s.toUnsignedInt(zcu)); | 1180 | const s_u8: u8 = @intCast(s.toUnsignedInt(pt)); |
| 1179 | if (s_u8 != 0) try literal.writeChar(s_u8); | 1181 | if (s_u8 != 0) try literal.writeChar(s_u8); |
| 1180 | } | 1182 | } |
| 1181 | try literal.end(); | 1183 | try literal.end(); |
| ... | @@ -1184,7 +1186,7 @@ pub const DeclGen = struct { | ... | @@ -1184,7 +1186,7 @@ pub const DeclGen = struct { |
| 1184 | var index: usize = 0; | 1186 | var index: usize = 0; |
| 1185 | while (index < ai.len) : (index += 1) { | 1187 | while (index < ai.len) : (index += 1) { |
| 1186 | if (index != 0) try writer.writeByte(','); | 1188 | if (index != 0) try writer.writeByte(','); |
| 1187 | const elem_val = try val.elemValue(zcu, index); | 1189 | const elem_val = try val.elemValue(pt, index); |
| 1188 | try dg.renderValue(writer, elem_val, initializer_type); | 1190 | try dg.renderValue(writer, elem_val, initializer_type); |
| 1189 | } | 1191 | } |
| 1190 | if (ai.sentinel) |s| { | 1192 | if (ai.sentinel) |s| { |
| ... | @@ -1207,13 +1209,13 @@ pub const DeclGen = struct { | ... | @@ -1207,13 +1209,13 @@ pub const DeclGen = struct { |
| 1207 | const comptime_val = tuple.values.get(ip)[field_index]; | 1209 | const comptime_val = tuple.values.get(ip)[field_index]; |
| 1208 | if (comptime_val != .none) continue; | 1210 | if (comptime_val != .none) continue; |
| 1209 | const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]); | 1211 | const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]); |
| 1210 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1212 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1211 | 1213 | ||
| 1212 | if (!empty) try writer.writeByte(','); | 1214 | if (!empty) try writer.writeByte(','); |
| 1213 | 1215 | ||
| 1214 | const field_val = Value.fromInterned( | 1216 | const field_val = Value.fromInterned( |
| 1215 | switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 1217 | switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 1216 | .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{ | 1218 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1217 | .ty = field_ty.toIntern(), | 1219 | .ty = field_ty.toIntern(), |
| 1218 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 1220 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| 1219 | } }), | 1221 | } }), |
| ... | @@ -1242,12 +1244,12 @@ pub const DeclGen = struct { | ... | @@ -1242,12 +1244,12 @@ pub const DeclGen = struct { |
| 1242 | var need_comma = false; | 1244 | var need_comma = false; |
| 1243 | while (field_it.next()) |field_index| { | 1245 | while (field_it.next()) |field_index| { |
| 1244 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 1246 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1245 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1247 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1246 | 1248 | ||
| 1247 | if (need_comma) try writer.writeByte(','); | 1249 | if (need_comma) try writer.writeByte(','); |
| 1248 | need_comma = true; | 1250 | need_comma = true; |
| 1249 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 1251 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 1250 | .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{ | 1252 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1251 | .ty = field_ty.toIntern(), | 1253 | .ty = field_ty.toIntern(), |
| 1252 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 1254 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| 1253 | } }), | 1255 | } }), |
| ... | @@ -1262,14 +1264,14 @@ pub const DeclGen = struct { | ... | @@ -1262,14 +1264,14 @@ pub const DeclGen = struct { |
| 1262 | const int_info = ty.intInfo(zcu); | 1264 | const int_info = ty.intInfo(zcu); |
| 1263 | 1265 | ||
| 1264 | const bits = Type.smallestUnsignedBits(int_info.bits - 1); | 1266 | const bits = Type.smallestUnsignedBits(int_info.bits - 1); |
| 1265 | const bit_offset_ty = try zcu.intType(.unsigned, bits); | 1267 | const bit_offset_ty = try pt.intType(.unsigned, bits); |
| 1266 | 1268 | ||
| 1267 | var bit_offset: u64 = 0; | 1269 | var bit_offset: u64 = 0; |
| 1268 | var eff_num_fields: usize = 0; | 1270 | var eff_num_fields: usize = 0; |
| 1269 | 1271 | ||
| 1270 | for (0..loaded_struct.field_types.len) |field_index| { | 1272 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1271 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 1273 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1272 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1274 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1273 | eff_num_fields += 1; | 1275 | eff_num_fields += 1; |
| 1274 | } | 1276 | } |
| 1275 | 1277 | ||
| ... | @@ -1277,7 +1279,7 @@ pub const DeclGen = struct { | ... | @@ -1277,7 +1279,7 @@ pub const DeclGen = struct { |
| 1277 | try writer.writeByte('('); | 1279 | try writer.writeByte('('); |
| 1278 | try dg.renderUndefValue(writer, ty, location); | 1280 | try dg.renderUndefValue(writer, ty, location); |
| 1279 | try writer.writeByte(')'); | 1281 | try writer.writeByte(')'); |
| 1280 | } else if (ty.bitSize(zcu) > 64) { | 1282 | } else if (ty.bitSize(pt) > 64) { |
| 1281 | // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off)) | 1283 | // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off)) |
| 1282 | var num_or = eff_num_fields - 1; | 1284 | var num_or = eff_num_fields - 1; |
| 1283 | while (num_or > 0) : (num_or -= 1) { | 1285 | while (num_or > 0) : (num_or -= 1) { |
| ... | @@ -1290,10 +1292,10 @@ pub const DeclGen = struct { | ... | @@ -1290,10 +1292,10 @@ pub const DeclGen = struct { |
| 1290 | var needs_closing_paren = false; | 1292 | var needs_closing_paren = false; |
| 1291 | for (0..loaded_struct.field_types.len) |field_index| { | 1293 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1292 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 1294 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1293 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1295 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1294 | 1296 | ||
| 1295 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 1297 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 1296 | .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{ | 1298 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1297 | .ty = field_ty.toIntern(), | 1299 | .ty = field_ty.toIntern(), |
| 1298 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 1300 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| 1299 | } }), | 1301 | } }), |
| ... | @@ -1307,7 +1309,7 @@ pub const DeclGen = struct { | ... | @@ -1307,7 +1309,7 @@ pub const DeclGen = struct { |
| 1307 | try writer.writeByte('('); | 1309 | try writer.writeByte('('); |
| 1308 | try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument); | 1310 | try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument); |
| 1309 | try writer.writeAll(", "); | 1311 | try writer.writeAll(", "); |
| 1310 | try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument); | 1312 | try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument); |
| 1311 | try writer.writeByte(')'); | 1313 | try writer.writeByte(')'); |
| 1312 | } else { | 1314 | } else { |
| 1313 | try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument); | 1315 | try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument); |
| ... | @@ -1316,7 +1318,7 @@ pub const DeclGen = struct { | ... | @@ -1316,7 +1318,7 @@ pub const DeclGen = struct { |
| 1316 | if (needs_closing_paren) try writer.writeByte(')'); | 1318 | if (needs_closing_paren) try writer.writeByte(')'); |
| 1317 | if (eff_index != eff_num_fields - 1) try writer.writeAll(", "); | 1319 | if (eff_index != eff_num_fields - 1) try writer.writeAll(", "); |
| 1318 | 1320 | ||
| 1319 | bit_offset += field_ty.bitSize(zcu); | 1321 | bit_offset += field_ty.bitSize(pt); |
| 1320 | needs_closing_paren = true; | 1322 | needs_closing_paren = true; |
| 1321 | eff_index += 1; | 1323 | eff_index += 1; |
| 1322 | } | 1324 | } |
| ... | @@ -1326,7 +1328,7 @@ pub const DeclGen = struct { | ... | @@ -1326,7 +1328,7 @@ pub const DeclGen = struct { |
| 1326 | var empty = true; | 1328 | var empty = true; |
| 1327 | for (0..loaded_struct.field_types.len) |field_index| { | 1329 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1328 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 1330 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1329 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1331 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1330 | 1332 | ||
| 1331 | if (!empty) try writer.writeAll(" | "); | 1333 | if (!empty) try writer.writeAll(" | "); |
| 1332 | try writer.writeByte('('); | 1334 | try writer.writeByte('('); |
| ... | @@ -1334,7 +1336,7 @@ pub const DeclGen = struct { | ... | @@ -1334,7 +1336,7 @@ pub const DeclGen = struct { |
| 1334 | try writer.writeByte(')'); | 1336 | try writer.writeByte(')'); |
| 1335 | 1337 | ||
| 1336 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 1338 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 1337 | .bytes => |bytes| try ip.get(zcu.gpa, .{ .int = .{ | 1339 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1338 | .ty = field_ty.toIntern(), | 1340 | .ty = field_ty.toIntern(), |
| 1339 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 1341 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| 1340 | } }), | 1342 | } }), |
| ... | @@ -1345,12 +1347,12 @@ pub const DeclGen = struct { | ... | @@ -1345,12 +1347,12 @@ pub const DeclGen = struct { |
| 1345 | if (bit_offset != 0) { | 1347 | if (bit_offset != 0) { |
| 1346 | try dg.renderValue(writer, Value.fromInterned(field_val), .Other); | 1348 | try dg.renderValue(writer, Value.fromInterned(field_val), .Other); |
| 1347 | try writer.writeAll(" << "); | 1349 | try writer.writeAll(" << "); |
| 1348 | try dg.renderValue(writer, try zcu.intValue(bit_offset_ty, bit_offset), .FunctionArgument); | 1350 | try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument); |
| 1349 | } else { | 1351 | } else { |
| 1350 | try dg.renderValue(writer, Value.fromInterned(field_val), .Other); | 1352 | try dg.renderValue(writer, Value.fromInterned(field_val), .Other); |
| 1351 | } | 1353 | } |
| 1352 | 1354 | ||
| 1353 | bit_offset += field_ty.bitSize(zcu); | 1355 | bit_offset += field_ty.bitSize(pt); |
| 1354 | empty = false; | 1356 | empty = false; |
| 1355 | } | 1357 | } |
| 1356 | try writer.writeByte(')'); | 1358 | try writer.writeByte(')'); |
| ... | @@ -1363,7 +1365,7 @@ pub const DeclGen = struct { | ... | @@ -1363,7 +1365,7 @@ pub const DeclGen = struct { |
| 1363 | .un => |un| { | 1365 | .un => |un| { |
| 1364 | const loaded_union = ip.loadUnionType(ty.toIntern()); | 1366 | const loaded_union = ip.loadUnionType(ty.toIntern()); |
| 1365 | if (un.tag == .none) { | 1367 | if (un.tag == .none) { |
| 1366 | const backing_ty = try ty.unionBackingType(zcu); | 1368 | const backing_ty = try ty.unionBackingType(pt); |
| 1367 | switch (loaded_union.getLayout(ip)) { | 1369 | switch (loaded_union.getLayout(ip)) { |
| 1368 | .@"packed" => { | 1370 | .@"packed" => { |
| 1369 | if (!location.isInitializer()) { | 1371 | if (!location.isInitializer()) { |
| ... | @@ -1378,7 +1380,7 @@ pub const DeclGen = struct { | ... | @@ -1378,7 +1380,7 @@ pub const DeclGen = struct { |
| 1378 | return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{}); | 1380 | return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{}); |
| 1379 | } | 1381 | } |
| 1380 | 1382 | ||
| 1381 | const ptr_ty = try zcu.singleConstPtrType(ty); | 1383 | const ptr_ty = try pt.singleConstPtrType(ty); |
| 1382 | try writer.writeAll("*(("); | 1384 | try writer.writeAll("*(("); |
| 1383 | try dg.renderType(writer, ptr_ty); | 1385 | try dg.renderType(writer, ptr_ty); |
| 1384 | try writer.writeAll(")("); | 1386 | try writer.writeAll(")("); |
| ... | @@ -1400,7 +1402,7 @@ pub const DeclGen = struct { | ... | @@ -1400,7 +1402,7 @@ pub const DeclGen = struct { |
| 1400 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | 1402 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 1401 | const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index]; | 1403 | const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index]; |
| 1402 | if (loaded_union.getLayout(ip) == .@"packed") { | 1404 | if (loaded_union.getLayout(ip) == .@"packed") { |
| 1403 | if (field_ty.hasRuntimeBits(zcu)) { | 1405 | if (field_ty.hasRuntimeBits(pt)) { |
| 1404 | if (field_ty.isPtrAtRuntime(zcu)) { | 1406 | if (field_ty.isPtrAtRuntime(zcu)) { |
| 1405 | try writer.writeByte('('); | 1407 | try writer.writeByte('('); |
| 1406 | try dg.renderCType(writer, ctype); | 1408 | try dg.renderCType(writer, ctype); |
| ... | @@ -1431,7 +1433,7 @@ pub const DeclGen = struct { | ... | @@ -1431,7 +1433,7 @@ pub const DeclGen = struct { |
| 1431 | ), | 1433 | ), |
| 1432 | .payload => { | 1434 | .payload => { |
| 1433 | try writer.writeByte('{'); | 1435 | try writer.writeByte('{'); |
| 1434 | if (field_ty.hasRuntimeBits(zcu)) { | 1436 | if (field_ty.hasRuntimeBits(pt)) { |
| 1435 | try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))}); | 1437 | try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))}); |
| 1436 | try dg.renderValue( | 1438 | try dg.renderValue( |
| 1437 | writer, | 1439 | writer, |
| ... | @@ -1443,7 +1445,7 @@ pub const DeclGen = struct { | ... | @@ -1443,7 +1445,7 @@ pub const DeclGen = struct { |
| 1443 | const inner_field_ty = Type.fromInterned( | 1445 | const inner_field_ty = Type.fromInterned( |
| 1444 | loaded_union.field_types.get(ip)[inner_field_index], | 1446 | loaded_union.field_types.get(ip)[inner_field_index], |
| 1445 | ); | 1447 | ); |
| 1446 | if (!inner_field_ty.hasRuntimeBits(zcu)) continue; | 1448 | if (!inner_field_ty.hasRuntimeBits(pt)) continue; |
| 1447 | try dg.renderUndefValue(writer, inner_field_ty, initializer_type); | 1449 | try dg.renderUndefValue(writer, inner_field_ty, initializer_type); |
| 1448 | break; | 1450 | break; |
| 1449 | } | 1451 | } |
| ... | @@ -1464,7 +1466,8 @@ pub const DeclGen = struct { | ... | @@ -1464,7 +1466,8 @@ pub const DeclGen = struct { |
| 1464 | ty: Type, | 1466 | ty: Type, |
| 1465 | location: ValueRenderLocation, | 1467 | location: ValueRenderLocation, |
| 1466 | ) error{ OutOfMemory, AnalysisFail }!void { | 1468 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 1467 | const zcu = dg.zcu; | 1469 | const pt = dg.pt; |
| 1470 | const zcu = pt.zcu; | ||
| 1468 | const ip = &zcu.intern_pool; | 1471 | const ip = &zcu.intern_pool; |
| 1469 | const target = &dg.mod.resolved_target.result; | 1472 | const target = &dg.mod.resolved_target.result; |
| 1470 | const ctype_pool = &dg.ctype_pool; | 1473 | const ctype_pool = &dg.ctype_pool; |
| ... | @@ -1490,7 +1493,7 @@ pub const DeclGen = struct { | ... | @@ -1490,7 +1493,7 @@ pub const DeclGen = struct { |
| 1490 | => { | 1493 | => { |
| 1491 | const bits = ty.floatBits(target.*); | 1494 | const bits = ty.floatBits(target.*); |
| 1492 | // All unsigned ints matching float types are pre-allocated. | 1495 | // All unsigned ints matching float types are pre-allocated. |
| 1493 | const repr_ty = zcu.intType(.unsigned, bits) catch unreachable; | 1496 | const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable; |
| 1494 | 1497 | ||
| 1495 | try writer.writeAll("zig_make_"); | 1498 | try writer.writeAll("zig_make_"); |
| 1496 | try dg.renderTypeForBuiltinFnName(writer, ty); | 1499 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| ... | @@ -1515,14 +1518,14 @@ pub const DeclGen = struct { | ... | @@ -1515,14 +1518,14 @@ pub const DeclGen = struct { |
| 1515 | .error_set_type, | 1518 | .error_set_type, |
| 1516 | .inferred_error_set_type, | 1519 | .inferred_error_set_type, |
| 1517 | => return writer.print("{x}", .{ | 1520 | => return writer.print("{x}", .{ |
| 1518 | try dg.fmtIntLiteral(try zcu.undefValue(ty), location), | 1521 | try dg.fmtIntLiteral(try pt.undefValue(ty), location), |
| 1519 | }), | 1522 | }), |
| 1520 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 1523 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1521 | .One, .Many, .C => { | 1524 | .One, .Many, .C => { |
| 1522 | try writer.writeAll("(("); | 1525 | try writer.writeAll("(("); |
| 1523 | try dg.renderCType(writer, ctype); | 1526 | try dg.renderCType(writer, ctype); |
| 1524 | return writer.print("){x})", .{ | 1527 | return writer.print("){x})", .{ |
| 1525 | try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other), | 1528 | try dg.fmtIntLiteral(try pt.undefValue(Type.usize), .Other), |
| 1526 | }); | 1529 | }); |
| 1527 | }, | 1530 | }, |
| 1528 | .Slice => { | 1531 | .Slice => { |
| ... | @@ -1536,7 +1539,7 @@ pub const DeclGen = struct { | ... | @@ -1536,7 +1539,7 @@ pub const DeclGen = struct { |
| 1536 | const ptr_ty = ty.slicePtrFieldType(zcu); | 1539 | const ptr_ty = ty.slicePtrFieldType(zcu); |
| 1537 | try dg.renderType(writer, ptr_ty); | 1540 | try dg.renderType(writer, ptr_ty); |
| 1538 | return writer.print("){x}, {0x}}}", .{ | 1541 | return writer.print("){x}, {0x}}}", .{ |
| 1539 | try dg.fmtIntLiteral(try zcu.undefValue(Type.usize), .Other), | 1542 | try dg.fmtIntLiteral(try dg.pt.undefValue(Type.usize), .Other), |
| 1540 | }); | 1543 | }); |
| 1541 | }, | 1544 | }, |
| 1542 | }, | 1545 | }, |
| ... | @@ -1591,7 +1594,7 @@ pub const DeclGen = struct { | ... | @@ -1591,7 +1594,7 @@ pub const DeclGen = struct { |
| 1591 | var need_comma = false; | 1594 | var need_comma = false; |
| 1592 | while (field_it.next()) |field_index| { | 1595 | while (field_it.next()) |field_index| { |
| 1593 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 1596 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1594 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1597 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1595 | 1598 | ||
| 1596 | if (need_comma) try writer.writeByte(','); | 1599 | if (need_comma) try writer.writeByte(','); |
| 1597 | need_comma = true; | 1600 | need_comma = true; |
| ... | @@ -1600,7 +1603,7 @@ pub const DeclGen = struct { | ... | @@ -1600,7 +1603,7 @@ pub const DeclGen = struct { |
| 1600 | return writer.writeByte('}'); | 1603 | return writer.writeByte('}'); |
| 1601 | }, | 1604 | }, |
| 1602 | .@"packed" => return writer.print("{x}", .{ | 1605 | .@"packed" => return writer.print("{x}", .{ |
| 1603 | try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other), | 1606 | try dg.fmtIntLiteral(try pt.undefValue(ty), .Other), |
| 1604 | }), | 1607 | }), |
| 1605 | } | 1608 | } |
| 1606 | }, | 1609 | }, |
| ... | @@ -1616,7 +1619,7 @@ pub const DeclGen = struct { | ... | @@ -1616,7 +1619,7 @@ pub const DeclGen = struct { |
| 1616 | for (0..anon_struct_info.types.len) |field_index| { | 1619 | for (0..anon_struct_info.types.len) |field_index| { |
| 1617 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; | 1620 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; |
| 1618 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); | 1621 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); |
| 1619 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1622 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1620 | 1623 | ||
| 1621 | if (need_comma) try writer.writeByte(','); | 1624 | if (need_comma) try writer.writeByte(','); |
| 1622 | need_comma = true; | 1625 | need_comma = true; |
| ... | @@ -1654,7 +1657,7 @@ pub const DeclGen = struct { | ... | @@ -1654,7 +1657,7 @@ pub const DeclGen = struct { |
| 1654 | const inner_field_ty = Type.fromInterned( | 1657 | const inner_field_ty = Type.fromInterned( |
| 1655 | loaded_union.field_types.get(ip)[inner_field_index], | 1658 | loaded_union.field_types.get(ip)[inner_field_index], |
| 1656 | ); | 1659 | ); |
| 1657 | if (!inner_field_ty.hasRuntimeBits(zcu)) continue; | 1660 | if (!inner_field_ty.hasRuntimeBits(pt)) continue; |
| 1658 | try dg.renderUndefValue( | 1661 | try dg.renderUndefValue( |
| 1659 | writer, | 1662 | writer, |
| 1660 | inner_field_ty, | 1663 | inner_field_ty, |
| ... | @@ -1670,7 +1673,7 @@ pub const DeclGen = struct { | ... | @@ -1670,7 +1673,7 @@ pub const DeclGen = struct { |
| 1670 | if (has_tag) try writer.writeByte('}'); | 1673 | if (has_tag) try writer.writeByte('}'); |
| 1671 | }, | 1674 | }, |
| 1672 | .@"packed" => return writer.print("{x}", .{ | 1675 | .@"packed" => return writer.print("{x}", .{ |
| 1673 | try dg.fmtIntLiteral(try zcu.undefValue(ty), .Other), | 1676 | try dg.fmtIntLiteral(try pt.undefValue(ty), .Other), |
| 1674 | }), | 1677 | }), |
| 1675 | } | 1678 | } |
| 1676 | }, | 1679 | }, |
| ... | @@ -1775,7 +1778,7 @@ pub const DeclGen = struct { | ... | @@ -1775,7 +1778,7 @@ pub const DeclGen = struct { |
| 1775 | }, | 1778 | }, |
| 1776 | }, | 1779 | }, |
| 1777 | ) !void { | 1780 | ) !void { |
| 1778 | const zcu = dg.zcu; | 1781 | const zcu = dg.pt.zcu; |
| 1779 | const ip = &zcu.intern_pool; | 1782 | const ip = &zcu.intern_pool; |
| 1780 | 1783 | ||
| 1781 | const fn_ty = fn_val.typeOf(zcu); | 1784 | const fn_ty = fn_val.typeOf(zcu); |
| ... | @@ -1856,7 +1859,7 @@ pub const DeclGen = struct { | ... | @@ -1856,7 +1859,7 @@ pub const DeclGen = struct { |
| 1856 | 1859 | ||
| 1857 | fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType { | 1860 | fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType { |
| 1858 | defer std.debug.assert(dg.scratch.items.len == 0); | 1861 | defer std.debug.assert(dg.scratch.items.len == 0); |
| 1859 | return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.zcu, dg.mod, kind); | 1862 | return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.pt, dg.mod, kind); |
| 1860 | } | 1863 | } |
| 1861 | 1864 | ||
| 1862 | fn byteSize(dg: *DeclGen, ctype: CType) u64 { | 1865 | fn byteSize(dg: *DeclGen, ctype: CType) u64 { |
| ... | @@ -1879,8 +1882,8 @@ pub const DeclGen = struct { | ... | @@ -1879,8 +1882,8 @@ pub const DeclGen = struct { |
| 1879 | } | 1882 | } |
| 1880 | 1883 | ||
| 1881 | fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void { | 1884 | fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void { |
| 1882 | _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{}); | 1885 | _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{}); |
| 1883 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{}); | 1886 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{}); |
| 1884 | } | 1887 | } |
| 1885 | 1888 | ||
| 1886 | const IntCastContext = union(enum) { | 1889 | const IntCastContext = union(enum) { |
| ... | @@ -1904,18 +1907,18 @@ pub const DeclGen = struct { | ... | @@ -1904,18 +1907,18 @@ pub const DeclGen = struct { |
| 1904 | } | 1907 | } |
| 1905 | }; | 1908 | }; |
| 1906 | fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool { | 1909 | fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool { |
| 1907 | const zcu = dg.zcu; | 1910 | const pt = dg.pt; |
| 1908 | const dest_bits = dest_ty.bitSize(zcu); | 1911 | const dest_bits = dest_ty.bitSize(pt); |
| 1909 | const dest_int_info = dest_ty.intInfo(zcu); | 1912 | const dest_int_info = dest_ty.intInfo(pt.zcu); |
| 1910 | 1913 | ||
| 1911 | const src_is_ptr = src_ty.isPtrAtRuntime(zcu); | 1914 | const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu); |
| 1912 | const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) { | 1915 | const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) { |
| 1913 | .unsigned => Type.usize, | 1916 | .unsigned => Type.usize, |
| 1914 | .signed => Type.isize, | 1917 | .signed => Type.isize, |
| 1915 | } else src_ty; | 1918 | } else src_ty; |
| 1916 | 1919 | ||
| 1917 | const src_bits = src_eff_ty.bitSize(zcu); | 1920 | const src_bits = src_eff_ty.bitSize(pt); |
| 1918 | const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null; | 1921 | const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null; |
| 1919 | if (dest_bits <= 64 and src_bits <= 64) { | 1922 | if (dest_bits <= 64 and src_bits <= 64) { |
| 1920 | const needs_cast = src_int_info == null or | 1923 | const needs_cast = src_int_info == null or |
| 1921 | (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or | 1924 | (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or |
| ... | @@ -1944,8 +1947,9 @@ pub const DeclGen = struct { | ... | @@ -1944,8 +1947,9 @@ pub const DeclGen = struct { |
| 1944 | src_ty: Type, | 1947 | src_ty: Type, |
| 1945 | location: ValueRenderLocation, | 1948 | location: ValueRenderLocation, |
| 1946 | ) !void { | 1949 | ) !void { |
| 1947 | const zcu = dg.zcu; | 1950 | const pt = dg.pt; |
| 1948 | const dest_bits = dest_ty.bitSize(zcu); | 1951 | const zcu = pt.zcu; |
| 1952 | const dest_bits = dest_ty.bitSize(pt); | ||
| 1949 | const dest_int_info = dest_ty.intInfo(zcu); | 1953 | const dest_int_info = dest_ty.intInfo(zcu); |
| 1950 | 1954 | ||
| 1951 | const src_is_ptr = src_ty.isPtrAtRuntime(zcu); | 1955 | const src_is_ptr = src_ty.isPtrAtRuntime(zcu); |
| ... | @@ -1954,7 +1958,7 @@ pub const DeclGen = struct { | ... | @@ -1954,7 +1958,7 @@ pub const DeclGen = struct { |
| 1954 | .signed => Type.isize, | 1958 | .signed => Type.isize, |
| 1955 | } else src_ty; | 1959 | } else src_ty; |
| 1956 | 1960 | ||
| 1957 | const src_bits = src_eff_ty.bitSize(zcu); | 1961 | const src_bits = src_eff_ty.bitSize(pt); |
| 1958 | const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null; | 1962 | const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null; |
| 1959 | if (dest_bits <= 64 and src_bits <= 64) { | 1963 | if (dest_bits <= 64 and src_bits <= 64) { |
| 1960 | const needs_cast = src_int_info == null or | 1964 | const needs_cast = src_int_info == null or |
| ... | @@ -2035,7 +2039,7 @@ pub const DeclGen = struct { | ... | @@ -2035,7 +2039,7 @@ pub const DeclGen = struct { |
| 2035 | qualifiers, | 2039 | qualifiers, |
| 2036 | CType.AlignAs.fromAlignment(.{ | 2040 | CType.AlignAs.fromAlignment(.{ |
| 2037 | .@"align" = alignment, | 2041 | .@"align" = alignment, |
| 2038 | .abi = ty.abiAlignment(dg.zcu), | 2042 | .abi = ty.abiAlignment(dg.pt), |
| 2039 | }), | 2043 | }), |
| 2040 | ); | 2044 | ); |
| 2041 | } | 2045 | } |
| ... | @@ -2048,6 +2052,7 @@ pub const DeclGen = struct { | ... | @@ -2048,6 +2052,7 @@ pub const DeclGen = struct { |
| 2048 | qualifiers: CQualifiers, | 2052 | qualifiers: CQualifiers, |
| 2049 | alignas: CType.AlignAs, | 2053 | alignas: CType.AlignAs, |
| 2050 | ) error{ OutOfMemory, AnalysisFail }!void { | 2054 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 2055 | const zcu = dg.pt.zcu; | ||
| 2051 | switch (alignas.abiOrder()) { | 2056 | switch (alignas.abiOrder()) { |
| 2052 | .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}), | 2057 | .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}), |
| 2053 | .eq => {}, | 2058 | .eq => {}, |
| ... | @@ -2055,10 +2060,10 @@ pub const DeclGen = struct { | ... | @@ -2055,10 +2060,10 @@ pub const DeclGen = struct { |
| 2055 | } | 2060 | } |
| 2056 | 2061 | ||
| 2057 | try w.print("{}", .{ | 2062 | try w.print("{}", .{ |
| 2058 | try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, qualifiers), | 2063 | try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers), |
| 2059 | }); | 2064 | }); |
| 2060 | try dg.writeName(w, name); | 2065 | try dg.writeName(w, name); |
| 2061 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{}); | 2066 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{}); |
| 2062 | } | 2067 | } |
| 2063 | 2068 | ||
| 2064 | fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void { | 2069 | fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void { |
| ... | @@ -2162,7 +2167,7 @@ pub const DeclGen = struct { | ... | @@ -2162,7 +2167,7 @@ pub const DeclGen = struct { |
| 2162 | decl_index: InternPool.DeclIndex, | 2167 | decl_index: InternPool.DeclIndex, |
| 2163 | variable: InternPool.Key.Variable, | 2168 | variable: InternPool.Key.Variable, |
| 2164 | ) !void { | 2169 | ) !void { |
| 2165 | const zcu = dg.zcu; | 2170 | const zcu = dg.pt.zcu; |
| 2166 | const decl = zcu.declPtr(decl_index); | 2171 | const decl = zcu.declPtr(decl_index); |
| 2167 | const fwd = dg.fwdDeclWriter(); | 2172 | const fwd = dg.fwdDeclWriter(); |
| 2168 | try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static "); | 2173 | try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static "); |
| ... | @@ -2180,7 +2185,7 @@ pub const DeclGen = struct { | ... | @@ -2180,7 +2185,7 @@ pub const DeclGen = struct { |
| 2180 | } | 2185 | } |
| 2181 | 2186 | ||
| 2182 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void { | 2187 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void { |
| 2183 | const zcu = dg.zcu; | 2188 | const zcu = dg.pt.zcu; |
| 2184 | const ip = &zcu.intern_pool; | 2189 | const ip = &zcu.intern_pool; |
| 2185 | const decl = zcu.declPtr(decl_index); | 2190 | const decl = zcu.declPtr(decl_index); |
| 2186 | 2191 | ||
| ... | @@ -2236,15 +2241,15 @@ pub const DeclGen = struct { | ... | @@ -2236,15 +2241,15 @@ pub const DeclGen = struct { |
| 2236 | .bits => {}, | 2241 | .bits => {}, |
| 2237 | } | 2242 | } |
| 2238 | 2243 | ||
| 2239 | const zcu = dg.zcu; | 2244 | const pt = dg.pt; |
| 2240 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ | 2245 | const int_info = if (ty.isAbiInt(pt.zcu)) ty.intInfo(pt.zcu) else std.builtin.Type.Int{ |
| 2241 | .signedness = .unsigned, | 2246 | .signedness = .unsigned, |
| 2242 | .bits = @as(u16, @intCast(ty.bitSize(zcu))), | 2247 | .bits = @as(u16, @intCast(ty.bitSize(pt))), |
| 2243 | }; | 2248 | }; |
| 2244 | 2249 | ||
| 2245 | if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); | 2250 | if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); |
| 2246 | try writer.print(", {}", .{try dg.fmtIntLiteral( | 2251 | try writer.print(", {}", .{try dg.fmtIntLiteral( |
| 2247 | try zcu.intValue(if (is_big) Type.u16 else Type.u8, int_info.bits), | 2252 | try pt.intValue(if (is_big) Type.u16 else Type.u8, int_info.bits), |
| 2248 | .FunctionArgument, | 2253 | .FunctionArgument, |
| 2249 | )}); | 2254 | )}); |
| 2250 | } | 2255 | } |
| ... | @@ -2254,7 +2259,7 @@ pub const DeclGen = struct { | ... | @@ -2254,7 +2259,7 @@ pub const DeclGen = struct { |
| 2254 | val: Value, | 2259 | val: Value, |
| 2255 | loc: ValueRenderLocation, | 2260 | loc: ValueRenderLocation, |
| 2256 | ) !std.fmt.Formatter(formatIntLiteral) { | 2261 | ) !std.fmt.Formatter(formatIntLiteral) { |
| 2257 | const zcu = dg.zcu; | 2262 | const zcu = dg.pt.zcu; |
| 2258 | const kind = loc.toCTypeKind(); | 2263 | const kind = loc.toCTypeKind(); |
| 2259 | const ty = val.typeOf(zcu); | 2264 | const ty = val.typeOf(zcu); |
| 2260 | return std.fmt.Formatter(formatIntLiteral){ .data = .{ | 2265 | return std.fmt.Formatter(formatIntLiteral){ .data = .{ |
| ... | @@ -2616,7 +2621,8 @@ pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void { | ... | @@ -2616,7 +2621,8 @@ pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void { |
| 2616 | } | 2621 | } |
| 2617 | 2622 | ||
| 2618 | pub fn genErrDecls(o: *Object) !void { | 2623 | pub fn genErrDecls(o: *Object) !void { |
| 2619 | const zcu = o.dg.zcu; | 2624 | const pt = o.dg.pt; |
| 2625 | const zcu = pt.zcu; | ||
| 2620 | const ip = &zcu.intern_pool; | 2626 | const ip = &zcu.intern_pool; |
| 2621 | const writer = o.writer(); | 2627 | const writer = o.writer(); |
| 2622 | 2628 | ||
| ... | @@ -2628,7 +2634,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2628,7 +2634,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2628 | for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| { | 2634 | for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| { |
| 2629 | const name = name_nts.toSlice(ip); | 2635 | const name = name_nts.toSlice(ip); |
| 2630 | max_name_len = @max(name.len, max_name_len); | 2636 | max_name_len = @max(name.len, max_name_len); |
| 2631 | const err_val = try zcu.intern(.{ .err = .{ | 2637 | const err_val = try pt.intern(.{ .err = .{ |
| 2632 | .ty = .anyerror_type, | 2638 | .ty = .anyerror_type, |
| 2633 | .name = name_nts, | 2639 | .name = name_nts, |
| 2634 | } }); | 2640 | } }); |
| ... | @@ -2649,12 +2655,12 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2649,12 +2655,12 @@ pub fn genErrDecls(o: *Object) !void { |
| 2649 | @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice); | 2655 | @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice); |
| 2650 | const identifier = name_buf[0 .. name_prefix.len + name_slice.len]; | 2656 | const identifier = name_buf[0 .. name_prefix.len + name_slice.len]; |
| 2651 | 2657 | ||
| 2652 | const name_ty = try zcu.arrayType(.{ | 2658 | const name_ty = try pt.arrayType(.{ |
| 2653 | .len = name_slice.len, | 2659 | .len = name_slice.len, |
| 2654 | .child = .u8_type, | 2660 | .child = .u8_type, |
| 2655 | .sentinel = .zero_u8, | 2661 | .sentinel = .zero_u8, |
| 2656 | }); | 2662 | }); |
| 2657 | const name_val = try zcu.intern(.{ .aggregate = .{ | 2663 | const name_val = try pt.intern(.{ .aggregate = .{ |
| 2658 | .ty = name_ty.toIntern(), | 2664 | .ty = name_ty.toIntern(), |
| 2659 | .storage = .{ .bytes = name.toString() }, | 2665 | .storage = .{ .bytes = name.toString() }, |
| 2660 | } }); | 2666 | } }); |
| ... | @@ -2673,7 +2679,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2673,7 +2679,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2673 | try writer.writeAll(";\n"); | 2679 | try writer.writeAll(";\n"); |
| 2674 | } | 2680 | } |
| 2675 | 2681 | ||
| 2676 | const name_array_ty = try zcu.arrayType(.{ | 2682 | const name_array_ty = try pt.arrayType(.{ |
| 2677 | .len = zcu.global_error_set.count(), | 2683 | .len = zcu.global_error_set.count(), |
| 2678 | .child = .slice_const_u8_sentinel_0_type, | 2684 | .child = .slice_const_u8_sentinel_0_type, |
| 2679 | }); | 2685 | }); |
| ... | @@ -2693,14 +2699,15 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2693,14 +2699,15 @@ pub fn genErrDecls(o: *Object) !void { |
| 2693 | if (value != 0) try writer.writeByte(','); | 2699 | if (value != 0) try writer.writeByte(','); |
| 2694 | try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ | 2700 | try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ |
| 2695 | fmtIdent(name), | 2701 | fmtIdent(name), |
| 2696 | try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, name.len), .StaticInitializer), | 2702 | try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer), |
| 2697 | }); | 2703 | }); |
| 2698 | } | 2704 | } |
| 2699 | try writer.writeAll("};\n"); | 2705 | try writer.writeAll("};\n"); |
| 2700 | } | 2706 | } |
| 2701 | 2707 | ||
| 2702 | pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void { | 2708 | pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void { |
| 2703 | const zcu = o.dg.zcu; | 2709 | const pt = o.dg.pt; |
| 2710 | const zcu = pt.zcu; | ||
| 2704 | const ip = &zcu.intern_pool; | 2711 | const ip = &zcu.intern_pool; |
| 2705 | const ctype_pool = &o.dg.ctype_pool; | 2712 | const ctype_pool = &o.dg.ctype_pool; |
| 2706 | const w = o.writer(); | 2713 | const w = o.writer(); |
| ... | @@ -2721,20 +2728,20 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2721,20 +2728,20 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2721 | for (0..tag_names.len) |tag_index| { | 2728 | for (0..tag_names.len) |tag_index| { |
| 2722 | const tag_name = tag_names.get(ip)[tag_index]; | 2729 | const tag_name = tag_names.get(ip)[tag_index]; |
| 2723 | const tag_name_len = tag_name.length(ip); | 2730 | const tag_name_len = tag_name.length(ip); |
| 2724 | const tag_val = try zcu.enumValueFieldIndex(enum_ty, @intCast(tag_index)); | 2731 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| 2725 | 2732 | ||
| 2726 | const name_ty = try zcu.arrayType(.{ | 2733 | const name_ty = try pt.arrayType(.{ |
| 2727 | .len = tag_name_len, | 2734 | .len = tag_name_len, |
| 2728 | .child = .u8_type, | 2735 | .child = .u8_type, |
| 2729 | .sentinel = .zero_u8, | 2736 | .sentinel = .zero_u8, |
| 2730 | }); | 2737 | }); |
| 2731 | const name_val = try zcu.intern(.{ .aggregate = .{ | 2738 | const name_val = try pt.intern(.{ .aggregate = .{ |
| 2732 | .ty = name_ty.toIntern(), | 2739 | .ty = name_ty.toIntern(), |
| 2733 | .storage = .{ .bytes = tag_name.toString() }, | 2740 | .storage = .{ .bytes = tag_name.toString() }, |
| 2734 | } }); | 2741 | } }); |
| 2735 | 2742 | ||
| 2736 | try w.print(" case {}: {{\n static ", .{ | 2743 | try w.print(" case {}: {{\n static ", .{ |
| 2737 | try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, zcu), .Other), | 2744 | try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other), |
| 2738 | }); | 2745 | }); |
| 2739 | try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete); | 2746 | try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete); |
| 2740 | try w.writeAll(" = "); | 2747 | try w.writeAll(" = "); |
| ... | @@ -2743,7 +2750,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn | ... | @@ -2743,7 +2750,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2743 | try o.dg.renderType(w, name_slice_ty); | 2750 | try o.dg.renderType(w, name_slice_ty); |
| 2744 | try w.print("){{{}, {}}};\n", .{ | 2751 | try w.print("){{{}, {}}};\n", .{ |
| 2745 | fmtIdent("name"), | 2752 | fmtIdent("name"), |
| 2746 | try o.dg.fmtIntLiteral(try zcu.intValue(Type.usize, tag_name_len), .Other), | 2753 | try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, tag_name_len), .Other), |
| 2747 | }); | 2754 | }); |
| 2748 | 2755 | ||
| 2749 | try w.writeAll(" }\n"); | 2756 | try w.writeAll(" }\n"); |
| ... | @@ -2788,7 +2795,7 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -2788,7 +2795,7 @@ pub fn genFunc(f: *Function) !void { |
| 2788 | defer tracy.end(); | 2795 | defer tracy.end(); |
| 2789 | 2796 | ||
| 2790 | const o = &f.object; | 2797 | const o = &f.object; |
| 2791 | const zcu = o.dg.zcu; | 2798 | const zcu = o.dg.pt.zcu; |
| 2792 | const gpa = o.dg.gpa; | 2799 | const gpa = o.dg.gpa; |
| 2793 | const decl_index = o.dg.pass.decl; | 2800 | const decl_index = o.dg.pass.decl; |
| 2794 | const decl = zcu.declPtr(decl_index); | 2801 | const decl = zcu.declPtr(decl_index); |
| ... | @@ -2879,12 +2886,13 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2879,12 +2886,13 @@ pub fn genDecl(o: *Object) !void { |
| 2879 | const tracy = trace(@src()); | 2886 | const tracy = trace(@src()); |
| 2880 | defer tracy.end(); | 2887 | defer tracy.end(); |
| 2881 | 2888 | ||
| 2882 | const zcu = o.dg.zcu; | 2889 | const pt = o.dg.pt; |
| 2890 | const zcu = pt.zcu; | ||
| 2883 | const decl_index = o.dg.pass.decl; | 2891 | const decl_index = o.dg.pass.decl; |
| 2884 | const decl = zcu.declPtr(decl_index); | 2892 | const decl = zcu.declPtr(decl_index); |
| 2885 | const decl_ty = decl.typeOf(zcu); | 2893 | const decl_ty = decl.typeOf(zcu); |
| 2886 | 2894 | ||
| 2887 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return; | 2895 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return; |
| 2888 | if (decl.val.getExternFunc(zcu)) |_| { | 2896 | if (decl.val.getExternFunc(zcu)) |_| { |
| 2889 | const fwd = o.dg.fwdDeclWriter(); | 2897 | const fwd = o.dg.fwdDeclWriter(); |
| 2890 | try fwd.writeAll("zig_extern "); | 2898 | try fwd.writeAll("zig_extern "); |
| ... | @@ -2928,7 +2936,7 @@ pub fn genDeclValue( | ... | @@ -2928,7 +2936,7 @@ pub fn genDeclValue( |
| 2928 | alignment: Alignment, | 2936 | alignment: Alignment, |
| 2929 | @"linksection": InternPool.OptionalNullTerminatedString, | 2937 | @"linksection": InternPool.OptionalNullTerminatedString, |
| 2930 | ) !void { | 2938 | ) !void { |
| 2931 | const zcu = o.dg.zcu; | 2939 | const zcu = o.dg.pt.zcu; |
| 2932 | const ty = val.typeOf(zcu); | 2940 | const ty = val.typeOf(zcu); |
| 2933 | 2941 | ||
| 2934 | const fwd = o.dg.fwdDeclWriter(); | 2942 | const fwd = o.dg.fwdDeclWriter(); |
| ... | @@ -2946,7 +2954,7 @@ pub fn genDeclValue( | ... | @@ -2946,7 +2954,7 @@ pub fn genDeclValue( |
| 2946 | } | 2954 | } |
| 2947 | 2955 | ||
| 2948 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void { | 2956 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void { |
| 2949 | const zcu = dg.zcu; | 2957 | const zcu = dg.pt.zcu; |
| 2950 | const ip = &zcu.intern_pool; | 2958 | const ip = &zcu.intern_pool; |
| 2951 | const fwd = dg.fwdDeclWriter(); | 2959 | const fwd = dg.fwdDeclWriter(); |
| 2952 | 2960 | ||
| ... | @@ -3088,7 +3096,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con | ... | @@ -3088,7 +3096,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con |
| 3088 | } | 3096 | } |
| 3089 | 3097 | ||
| 3090 | fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void { | 3098 | fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void { |
| 3091 | const zcu = f.object.dg.zcu; | 3099 | const zcu = f.object.dg.pt.zcu; |
| 3092 | const ip = &zcu.intern_pool; | 3100 | const ip = &zcu.intern_pool; |
| 3093 | const air_tags = f.air.instructions.items(.tag); | 3101 | const air_tags = f.air.instructions.items(.tag); |
| 3094 | const air_datas = f.air.instructions.items(.data); | 3102 | const air_datas = f.air.instructions.items(.data); |
| ... | @@ -3388,10 +3396,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ | ... | @@ -3388,10 +3396,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 3388 | } | 3396 | } |
| 3389 | 3397 | ||
| 3390 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 3398 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3391 | const zcu = f.object.dg.zcu; | 3399 | const pt = f.object.dg.pt; |
| 3392 | const inst_ty = f.typeOfIndex(inst); | 3400 | const inst_ty = f.typeOfIndex(inst); |
| 3393 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3401 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3394 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 3402 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3395 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3403 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3396 | return .none; | 3404 | return .none; |
| 3397 | } | 3405 | } |
| ... | @@ -3414,13 +3422,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3414,13 +3422,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3414 | } | 3422 | } |
| 3415 | 3423 | ||
| 3416 | fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 3424 | fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3417 | const zcu = f.object.dg.zcu; | 3425 | const pt = f.object.dg.pt; |
| 3426 | const zcu = pt.zcu; | ||
| 3418 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3427 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3419 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 3428 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3420 | 3429 | ||
| 3421 | const inst_ty = f.typeOfIndex(inst); | 3430 | const inst_ty = f.typeOfIndex(inst); |
| 3422 | const ptr_ty = f.typeOf(bin_op.lhs); | 3431 | const ptr_ty = f.typeOf(bin_op.lhs); |
| 3423 | const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu); | 3432 | const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(pt); |
| 3424 | 3433 | ||
| 3425 | const ptr = try f.resolveInst(bin_op.lhs); | 3434 | const ptr = try f.resolveInst(bin_op.lhs); |
| 3426 | const index = try f.resolveInst(bin_op.rhs); | 3435 | const index = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3449,10 +3458,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3449,10 +3458,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3449 | } | 3458 | } |
| 3450 | 3459 | ||
| 3451 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 3460 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3452 | const zcu = f.object.dg.zcu; | 3461 | const pt = f.object.dg.pt; |
| 3453 | const inst_ty = f.typeOfIndex(inst); | 3462 | const inst_ty = f.typeOfIndex(inst); |
| 3454 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3463 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3455 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 3464 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3456 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3465 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3457 | return .none; | 3466 | return .none; |
| 3458 | } | 3467 | } |
| ... | @@ -3475,14 +3484,15 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3475,14 +3484,15 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3475 | } | 3484 | } |
| 3476 | 3485 | ||
| 3477 | fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 3486 | fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3478 | const zcu = f.object.dg.zcu; | 3487 | const pt = f.object.dg.pt; |
| 3488 | const zcu = pt.zcu; | ||
| 3479 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3489 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3480 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 3490 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3481 | 3491 | ||
| 3482 | const inst_ty = f.typeOfIndex(inst); | 3492 | const inst_ty = f.typeOfIndex(inst); |
| 3483 | const slice_ty = f.typeOf(bin_op.lhs); | 3493 | const slice_ty = f.typeOf(bin_op.lhs); |
| 3484 | const elem_ty = slice_ty.elemType2(zcu); | 3494 | const elem_ty = slice_ty.elemType2(zcu); |
| 3485 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu); | 3495 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 3486 | 3496 | ||
| 3487 | const slice = try f.resolveInst(bin_op.lhs); | 3497 | const slice = try f.resolveInst(bin_op.lhs); |
| 3488 | const index = try f.resolveInst(bin_op.rhs); | 3498 | const index = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3505,10 +3515,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3505,10 +3515,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3505 | } | 3515 | } |
| 3506 | 3516 | ||
| 3507 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 3517 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3508 | const zcu = f.object.dg.zcu; | 3518 | const pt = f.object.dg.pt; |
| 3509 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3519 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3510 | const inst_ty = f.typeOfIndex(inst); | 3520 | const inst_ty = f.typeOfIndex(inst); |
| 3511 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 3521 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3512 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3522 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3513 | return .none; | 3523 | return .none; |
| 3514 | } | 3524 | } |
| ... | @@ -3531,40 +3541,40 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3531,40 +3541,40 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3531 | } | 3541 | } |
| 3532 | 3542 | ||
| 3533 | fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { | 3543 | fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3534 | const zcu = f.object.dg.zcu; | 3544 | const pt = f.object.dg.pt; |
| 3545 | const zcu = pt.zcu; | ||
| 3535 | const inst_ty = f.typeOfIndex(inst); | 3546 | const inst_ty = f.typeOfIndex(inst); |
| 3536 | const elem_ty = inst_ty.childType(zcu); | 3547 | const elem_ty = inst_ty.childType(zcu); |
| 3537 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty }; | 3548 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty }; |
| 3538 | 3549 | ||
| 3539 | const local = try f.allocLocalValue(.{ | 3550 | const local = try f.allocLocalValue(.{ |
| 3540 | .ctype = try f.ctypeFromType(elem_ty, .complete), | 3551 | .ctype = try f.ctypeFromType(elem_ty, .complete), |
| 3541 | .alignas = CType.AlignAs.fromAlignment(.{ | 3552 | .alignas = CType.AlignAs.fromAlignment(.{ |
| 3542 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, | 3553 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, |
| 3543 | .abi = elem_ty.abiAlignment(zcu), | 3554 | .abi = elem_ty.abiAlignment(pt), |
| 3544 | }), | 3555 | }), |
| 3545 | }); | 3556 | }); |
| 3546 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); | 3557 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| 3547 | const gpa = f.object.dg.zcu.gpa; | 3558 | try f.allocs.put(zcu.gpa, local.new_local, true); |
| 3548 | try f.allocs.put(gpa, local.new_local, true); | ||
| 3549 | return .{ .local_ref = local.new_local }; | 3559 | return .{ .local_ref = local.new_local }; |
| 3550 | } | 3560 | } |
| 3551 | 3561 | ||
| 3552 | fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 3562 | fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3553 | const zcu = f.object.dg.zcu; | 3563 | const pt = f.object.dg.pt; |
| 3564 | const zcu = pt.zcu; | ||
| 3554 | const inst_ty = f.typeOfIndex(inst); | 3565 | const inst_ty = f.typeOfIndex(inst); |
| 3555 | const elem_ty = inst_ty.childType(zcu); | 3566 | const elem_ty = inst_ty.childType(zcu); |
| 3556 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty }; | 3567 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty }; |
| 3557 | 3568 | ||
| 3558 | const local = try f.allocLocalValue(.{ | 3569 | const local = try f.allocLocalValue(.{ |
| 3559 | .ctype = try f.ctypeFromType(elem_ty, .complete), | 3570 | .ctype = try f.ctypeFromType(elem_ty, .complete), |
| 3560 | .alignas = CType.AlignAs.fromAlignment(.{ | 3571 | .alignas = CType.AlignAs.fromAlignment(.{ |
| 3561 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, | 3572 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, |
| 3562 | .abi = elem_ty.abiAlignment(zcu), | 3573 | .abi = elem_ty.abiAlignment(pt), |
| 3563 | }), | 3574 | }), |
| 3564 | }); | 3575 | }); |
| 3565 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); | 3576 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| 3566 | const gpa = f.object.dg.zcu.gpa; | 3577 | try f.allocs.put(zcu.gpa, local.new_local, true); |
| 3567 | try f.allocs.put(gpa, local.new_local, true); | ||
| 3568 | return .{ .local_ref = local.new_local }; | 3578 | return .{ .local_ref = local.new_local }; |
| 3569 | } | 3579 | } |
| 3570 | 3580 | ||
| ... | @@ -3593,7 +3603,8 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3593,7 +3603,8 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3593 | } | 3603 | } |
| 3594 | 3604 | ||
| 3595 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | 3605 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3596 | const zcu = f.object.dg.zcu; | 3606 | const pt = f.object.dg.pt; |
| 3607 | const zcu = pt.zcu; | ||
| 3597 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3608 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3598 | 3609 | ||
| 3599 | const ptr_ty = f.typeOf(ty_op.operand); | 3610 | const ptr_ty = f.typeOf(ty_op.operand); |
| ... | @@ -3601,7 +3612,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3601,7 +3612,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3601 | const ptr_info = ptr_scalar_ty.ptrInfo(zcu); | 3612 | const ptr_info = ptr_scalar_ty.ptrInfo(zcu); |
| 3602 | const src_ty = Type.fromInterned(ptr_info.child); | 3613 | const src_ty = Type.fromInterned(ptr_info.child); |
| 3603 | 3614 | ||
| 3604 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 3615 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3605 | try reap(f, inst, &.{ty_op.operand}); | 3616 | try reap(f, inst, &.{ty_op.operand}); |
| 3606 | return .none; | 3617 | return .none; |
| 3607 | } | 3618 | } |
| ... | @@ -3611,10 +3622,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3611,10 +3622,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3611 | try reap(f, inst, &.{ty_op.operand}); | 3622 | try reap(f, inst, &.{ty_op.operand}); |
| 3612 | 3623 | ||
| 3613 | const is_aligned = if (ptr_info.flags.alignment != .none) | 3624 | const is_aligned = if (ptr_info.flags.alignment != .none) |
| 3614 | ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte) | 3625 | ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte) |
| 3615 | else | 3626 | else |
| 3616 | true; | 3627 | true; |
| 3617 | const is_array = lowersToArray(src_ty, zcu); | 3628 | const is_array = lowersToArray(src_ty, pt); |
| 3618 | const need_memcpy = !is_aligned or is_array; | 3629 | const need_memcpy = !is_aligned or is_array; |
| 3619 | 3630 | ||
| 3620 | const writer = f.object.writer(); | 3631 | const writer = f.object.writer(); |
| ... | @@ -3634,12 +3645,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3634,12 +3645,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3634 | try writer.writeAll("))"); | 3645 | try writer.writeAll("))"); |
| 3635 | } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) { | 3646 | } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) { |
| 3636 | const host_bits: u16 = ptr_info.packed_offset.host_size * 8; | 3647 | const host_bits: u16 = ptr_info.packed_offset.host_size * 8; |
| 3637 | const host_ty = try zcu.intType(.unsigned, host_bits); | 3648 | const host_ty = try pt.intType(.unsigned, host_bits); |
| 3638 | 3649 | ||
| 3639 | const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); | 3650 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); |
| 3640 | const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); | 3651 | const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); |
| 3641 | 3652 | ||
| 3642 | const field_ty = try zcu.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu)))); | 3653 | const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(pt)))); |
| 3643 | 3654 | ||
| 3644 | try f.writeCValue(writer, local, .Other); | 3655 | try f.writeCValue(writer, local, .Other); |
| 3645 | try v.elem(f, writer); | 3656 | try v.elem(f, writer); |
| ... | @@ -3650,9 +3661,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3650,9 +3661,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3650 | try writer.writeAll("(("); | 3661 | try writer.writeAll("(("); |
| 3651 | try f.renderType(writer, field_ty); | 3662 | try f.renderType(writer, field_ty); |
| 3652 | try writer.writeByte(')'); | 3663 | try writer.writeByte(')'); |
| 3653 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64; | 3664 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64; |
| 3654 | if (cant_cast) { | 3665 | if (cant_cast) { |
| 3655 | if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | 3666 | if (field_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); |
| 3656 | try writer.writeAll("zig_lo_"); | 3667 | try writer.writeAll("zig_lo_"); |
| 3657 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | 3668 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3658 | try writer.writeByte('('); | 3669 | try writer.writeByte('('); |
| ... | @@ -3680,7 +3691,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3680,7 +3691,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3680 | } | 3691 | } |
| 3681 | 3692 | ||
| 3682 | fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | 3693 | fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3683 | const zcu = f.object.dg.zcu; | 3694 | const pt = f.object.dg.pt; |
| 3695 | const zcu = pt.zcu; | ||
| 3684 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 3696 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 3685 | const writer = f.object.writer(); | 3697 | const writer = f.object.writer(); |
| 3686 | const op_inst = un_op.toIndex(); | 3698 | const op_inst = un_op.toIndex(); |
| ... | @@ -3695,11 +3707,11 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3695,11 +3707,11 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3695 | const operand = try f.resolveInst(un_op); | 3707 | const operand = try f.resolveInst(un_op); |
| 3696 | try reap(f, inst, &.{un_op}); | 3708 | try reap(f, inst, &.{un_op}); |
| 3697 | var deref = is_ptr; | 3709 | var deref = is_ptr; |
| 3698 | const is_array = lowersToArray(ret_ty, zcu); | 3710 | const is_array = lowersToArray(ret_ty, pt); |
| 3699 | const ret_val = if (is_array) ret_val: { | 3711 | const ret_val = if (is_array) ret_val: { |
| 3700 | const array_local = try f.allocAlignedLocal(inst, .{ | 3712 | const array_local = try f.allocAlignedLocal(inst, .{ |
| 3701 | .ctype = ret_ctype, | 3713 | .ctype = ret_ctype, |
| 3702 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(f.object.dg.zcu)), | 3714 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)), |
| 3703 | }); | 3715 | }); |
| 3704 | try writer.writeAll("memcpy("); | 3716 | try writer.writeAll("memcpy("); |
| 3705 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); | 3717 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); |
| ... | @@ -3733,7 +3745,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3733,7 +3745,8 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3733 | } | 3745 | } |
| 3734 | 3746 | ||
| 3735 | fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | 3747 | fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3736 | const zcu = f.object.dg.zcu; | 3748 | const pt = f.object.dg.pt; |
| 3749 | const zcu = pt.zcu; | ||
| 3737 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3750 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3738 | 3751 | ||
| 3739 | const operand = try f.resolveInst(ty_op.operand); | 3752 | const operand = try f.resolveInst(ty_op.operand); |
| ... | @@ -3760,7 +3773,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3760,7 +3773,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3760 | } | 3773 | } |
| 3761 | 3774 | ||
| 3762 | fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | 3775 | fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3763 | const zcu = f.object.dg.zcu; | 3776 | const pt = f.object.dg.pt; |
| 3777 | const zcu = pt.zcu; | ||
| 3764 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3778 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3765 | 3779 | ||
| 3766 | const operand = try f.resolveInst(ty_op.operand); | 3780 | const operand = try f.resolveInst(ty_op.operand); |
| ... | @@ -3809,13 +3823,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3809,13 +3823,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3809 | try f.writeCValue(writer, operand, .FunctionArgument); | 3823 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3810 | try v.elem(f, writer); | 3824 | try v.elem(f, writer); |
| 3811 | try writer.print(", {x})", .{ | 3825 | try writer.print(", {x})", .{ |
| 3812 | try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(zcu, scalar_ty)), | 3826 | try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)), |
| 3813 | }); | 3827 | }); |
| 3814 | }, | 3828 | }, |
| 3815 | .signed => { | 3829 | .signed => { |
| 3816 | const c_bits = toCIntBits(scalar_int_info.bits) orelse | 3830 | const c_bits = toCIntBits(scalar_int_info.bits) orelse |
| 3817 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 3831 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 3818 | const shift_val = try zcu.intValue(Type.u8, c_bits - dest_bits); | 3832 | const shift_val = try pt.intValue(Type.u8, c_bits - dest_bits); |
| 3819 | 3833 | ||
| 3820 | try writer.writeAll("zig_shr_"); | 3834 | try writer.writeAll("zig_shr_"); |
| 3821 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | 3835 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); |
| ... | @@ -3860,7 +3874,8 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3860,7 +3874,8 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3860 | } | 3874 | } |
| 3861 | 3875 | ||
| 3862 | fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | 3876 | fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3863 | const zcu = f.object.dg.zcu; | 3877 | const pt = f.object.dg.pt; |
| 3878 | const zcu = pt.zcu; | ||
| 3864 | // *a = b; | 3879 | // *a = b; |
| 3865 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3880 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3866 | 3881 | ||
| ... | @@ -3871,7 +3886,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3871,7 +3886,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3871 | const ptr_val = try f.resolveInst(bin_op.lhs); | 3886 | const ptr_val = try f.resolveInst(bin_op.lhs); |
| 3872 | const src_ty = f.typeOf(bin_op.rhs); | 3887 | const src_ty = f.typeOf(bin_op.rhs); |
| 3873 | 3888 | ||
| 3874 | const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |v| v.isUndefDeep(zcu) else false; | 3889 | const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndefDeep(zcu) else false; |
| 3875 | 3890 | ||
| 3876 | if (val_is_undef) { | 3891 | if (val_is_undef) { |
| 3877 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3892 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| ... | @@ -3887,10 +3902,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3887,10 +3902,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3887 | } | 3902 | } |
| 3888 | 3903 | ||
| 3889 | const is_aligned = if (ptr_info.flags.alignment != .none) | 3904 | const is_aligned = if (ptr_info.flags.alignment != .none) |
| 3890 | ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte) | 3905 | ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte) |
| 3891 | else | 3906 | else |
| 3892 | true; | 3907 | true; |
| 3893 | const is_array = lowersToArray(Type.fromInterned(ptr_info.child), zcu); | 3908 | const is_array = lowersToArray(Type.fromInterned(ptr_info.child), pt); |
| 3894 | const need_memcpy = !is_aligned or is_array; | 3909 | const need_memcpy = !is_aligned or is_array; |
| 3895 | 3910 | ||
| 3896 | const src_val = try f.resolveInst(bin_op.rhs); | 3911 | const src_val = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3901,7 +3916,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3901,7 +3916,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3901 | if (need_memcpy) { | 3916 | if (need_memcpy) { |
| 3902 | // For this memcpy to safely work we need the rhs to have the same | 3917 | // For this memcpy to safely work we need the rhs to have the same |
| 3903 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). | 3918 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). |
| 3904 | assert(src_ty.eql(Type.fromInterned(ptr_info.child), f.object.dg.zcu)); | 3919 | assert(src_ty.eql(Type.fromInterned(ptr_info.child), zcu)); |
| 3905 | 3920 | ||
| 3906 | // If the source is a constant, writeCValue will emit a brace initialization | 3921 | // If the source is a constant, writeCValue will emit a brace initialization |
| 3907 | // so work around this by initializing into new local. | 3922 | // so work around this by initializing into new local. |
| ... | @@ -3932,12 +3947,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3932,12 +3947,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3932 | try v.end(f, inst, writer); | 3947 | try v.end(f, inst, writer); |
| 3933 | } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) { | 3948 | } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) { |
| 3934 | const host_bits = ptr_info.packed_offset.host_size * 8; | 3949 | const host_bits = ptr_info.packed_offset.host_size * 8; |
| 3935 | const host_ty = try zcu.intType(.unsigned, host_bits); | 3950 | const host_ty = try pt.intType(.unsigned, host_bits); |
| 3936 | 3951 | ||
| 3937 | const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); | 3952 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); |
| 3938 | const bit_offset_val = try zcu.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); | 3953 | const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); |
| 3939 | 3954 | ||
| 3940 | const src_bits = src_ty.bitSize(zcu); | 3955 | const src_bits = src_ty.bitSize(pt); |
| 3941 | 3956 | ||
| 3942 | const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb; | 3957 | const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb; |
| 3943 | var stack align(@alignOf(ExpectedContents)) = | 3958 | var stack align(@alignOf(ExpectedContents)) = |
| ... | @@ -3950,7 +3965,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3950,7 +3965,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3950 | try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset); | 3965 | try mask.shiftLeft(&mask, ptr_info.packed_offset.bit_offset); |
| 3951 | try mask.bitNotWrap(&mask, .unsigned, host_bits); | 3966 | try mask.bitNotWrap(&mask, .unsigned, host_bits); |
| 3952 | 3967 | ||
| 3953 | const mask_val = try zcu.intValue_big(host_ty, mask.toConst()); | 3968 | const mask_val = try pt.intValue_big(host_ty, mask.toConst()); |
| 3954 | 3969 | ||
| 3955 | const v = try Vectorize.start(f, inst, writer, ptr_ty); | 3970 | const v = try Vectorize.start(f, inst, writer, ptr_ty); |
| 3956 | const a = try Assignment.start(f, writer, src_scalar_ctype); | 3971 | const a = try Assignment.start(f, writer, src_scalar_ctype); |
| ... | @@ -3967,9 +3982,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3967,9 +3982,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3967 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)}); | 3982 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)}); |
| 3968 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | 3983 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3969 | try writer.writeByte('('); | 3984 | try writer.writeByte('('); |
| 3970 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64; | 3985 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64; |
| 3971 | if (cant_cast) { | 3986 | if (cant_cast) { |
| 3972 | if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | 3987 | if (src_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); |
| 3973 | try writer.writeAll("zig_make_"); | 3988 | try writer.writeAll("zig_make_"); |
| 3974 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | 3989 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3975 | try writer.writeAll("(0, "); | 3990 | try writer.writeAll("(0, "); |
| ... | @@ -4013,7 +4028,8 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -4013,7 +4028,8 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 4013 | } | 4028 | } |
| 4014 | 4029 | ||
| 4015 | fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue { | 4030 | fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue { |
| 4016 | const zcu = f.object.dg.zcu; | 4031 | const pt = f.object.dg.pt; |
| 4032 | const zcu = pt.zcu; | ||
| 4017 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4033 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4018 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 4034 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4019 | 4035 | ||
| ... | @@ -4051,7 +4067,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: | ... | @@ -4051,7 +4067,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 4051 | } | 4067 | } |
| 4052 | 4068 | ||
| 4053 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { | 4069 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4054 | const zcu = f.object.dg.zcu; | 4070 | const pt = f.object.dg.pt; |
| 4071 | const zcu = pt.zcu; | ||
| 4055 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4072 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4056 | const operand_ty = f.typeOf(ty_op.operand); | 4073 | const operand_ty = f.typeOf(ty_op.operand); |
| 4057 | const scalar_ty = operand_ty.scalarType(zcu); | 4074 | const scalar_ty = operand_ty.scalarType(zcu); |
| ... | @@ -4084,11 +4101,12 @@ fn airBinOp( | ... | @@ -4084,11 +4101,12 @@ fn airBinOp( |
| 4084 | operation: []const u8, | 4101 | operation: []const u8, |
| 4085 | info: BuiltinInfo, | 4102 | info: BuiltinInfo, |
| 4086 | ) !CValue { | 4103 | ) !CValue { |
| 4087 | const zcu = f.object.dg.zcu; | 4104 | const pt = f.object.dg.pt; |
| 4105 | const zcu = pt.zcu; | ||
| 4088 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4106 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4089 | const operand_ty = f.typeOf(bin_op.lhs); | 4107 | const operand_ty = f.typeOf(bin_op.lhs); |
| 4090 | const scalar_ty = operand_ty.scalarType(zcu); | 4108 | const scalar_ty = operand_ty.scalarType(zcu); |
| 4091 | if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat()) | 4109 | if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(pt) > 64) or scalar_ty.isRuntimeFloat()) |
| 4092 | return try airBinBuiltinCall(f, inst, operation, info); | 4110 | return try airBinBuiltinCall(f, inst, operation, info); |
| 4093 | 4111 | ||
| 4094 | const lhs = try f.resolveInst(bin_op.lhs); | 4112 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | @@ -4122,11 +4140,12 @@ fn airCmpOp( | ... | @@ -4122,11 +4140,12 @@ fn airCmpOp( |
| 4122 | data: anytype, | 4140 | data: anytype, |
| 4123 | operator: std.math.CompareOperator, | 4141 | operator: std.math.CompareOperator, |
| 4124 | ) !CValue { | 4142 | ) !CValue { |
| 4125 | const zcu = f.object.dg.zcu; | 4143 | const pt = f.object.dg.pt; |
| 4144 | const zcu = pt.zcu; | ||
| 4126 | const lhs_ty = f.typeOf(data.lhs); | 4145 | const lhs_ty = f.typeOf(data.lhs); |
| 4127 | const scalar_ty = lhs_ty.scalarType(zcu); | 4146 | const scalar_ty = lhs_ty.scalarType(zcu); |
| 4128 | 4147 | ||
| 4129 | const scalar_bits = scalar_ty.bitSize(zcu); | 4148 | const scalar_bits = scalar_ty.bitSize(pt); |
| 4130 | if (scalar_ty.isInt(zcu) and scalar_bits > 64) | 4149 | if (scalar_ty.isInt(zcu) and scalar_bits > 64) |
| 4131 | return airCmpBuiltinCall( | 4150 | return airCmpBuiltinCall( |
| 4132 | f, | 4151 | f, |
| ... | @@ -4170,12 +4189,13 @@ fn airEquality( | ... | @@ -4170,12 +4189,13 @@ fn airEquality( |
| 4170 | inst: Air.Inst.Index, | 4189 | inst: Air.Inst.Index, |
| 4171 | operator: std.math.CompareOperator, | 4190 | operator: std.math.CompareOperator, |
| 4172 | ) !CValue { | 4191 | ) !CValue { |
| 4173 | const zcu = f.object.dg.zcu; | 4192 | const pt = f.object.dg.pt; |
| 4193 | const zcu = pt.zcu; | ||
| 4174 | const ctype_pool = &f.object.dg.ctype_pool; | 4194 | const ctype_pool = &f.object.dg.ctype_pool; |
| 4175 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4195 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4176 | 4196 | ||
| 4177 | const operand_ty = f.typeOf(bin_op.lhs); | 4197 | const operand_ty = f.typeOf(bin_op.lhs); |
| 4178 | const operand_bits = operand_ty.bitSize(zcu); | 4198 | const operand_bits = operand_ty.bitSize(pt); |
| 4179 | if (operand_ty.isAbiInt(zcu) and operand_bits > 64) | 4199 | if (operand_ty.isAbiInt(zcu) and operand_bits > 64) |
| 4180 | return airCmpBuiltinCall( | 4200 | return airCmpBuiltinCall( |
| 4181 | f, | 4201 | f, |
| ... | @@ -4256,7 +4276,8 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4256,7 +4276,8 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4256 | } | 4276 | } |
| 4257 | 4277 | ||
| 4258 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | 4278 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 4259 | const zcu = f.object.dg.zcu; | 4279 | const pt = f.object.dg.pt; |
| 4280 | const zcu = pt.zcu; | ||
| 4260 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4281 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4261 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 4282 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4262 | 4283 | ||
| ... | @@ -4267,7 +4288,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ... | @@ -4267,7 +4288,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 4267 | const inst_ty = f.typeOfIndex(inst); | 4288 | const inst_ty = f.typeOfIndex(inst); |
| 4268 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 4289 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 4269 | const elem_ty = inst_scalar_ty.elemType2(zcu); | 4290 | const elem_ty = inst_scalar_ty.elemType2(zcu); |
| 4270 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs); | 4291 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return f.moveCValue(inst, inst_ty, lhs); |
| 4271 | const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete); | 4292 | const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete); |
| 4272 | 4293 | ||
| 4273 | const local = try f.allocLocal(inst, inst_ty); | 4294 | const local = try f.allocLocal(inst, inst_ty); |
| ... | @@ -4299,13 +4320,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ... | @@ -4299,13 +4320,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 4299 | } | 4320 | } |
| 4300 | 4321 | ||
| 4301 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue { | 4322 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue { |
| 4302 | const zcu = f.object.dg.zcu; | 4323 | const pt = f.object.dg.pt; |
| 4324 | const zcu = pt.zcu; | ||
| 4303 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4325 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4304 | 4326 | ||
| 4305 | const inst_ty = f.typeOfIndex(inst); | 4327 | const inst_ty = f.typeOfIndex(inst); |
| 4306 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 4328 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 4307 | 4329 | ||
| 4308 | if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat()) | 4330 | if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(pt) > 64) or inst_scalar_ty.isRuntimeFloat()) |
| 4309 | return try airBinBuiltinCall(f, inst, operation, .none); | 4331 | return try airBinBuiltinCall(f, inst, operation, .none); |
| 4310 | 4332 | ||
| 4311 | const lhs = try f.resolveInst(bin_op.lhs); | 4333 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | @@ -4339,7 +4361,8 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons | ... | @@ -4339,7 +4361,8 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4339 | } | 4361 | } |
| 4340 | 4362 | ||
| 4341 | fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { | 4363 | fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4342 | const zcu = f.object.dg.zcu; | 4364 | const pt = f.object.dg.pt; |
| 4365 | const zcu = pt.zcu; | ||
| 4343 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4366 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4344 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 4367 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4345 | 4368 | ||
| ... | @@ -4374,7 +4397,8 @@ fn airCall( | ... | @@ -4374,7 +4397,8 @@ fn airCall( |
| 4374 | inst: Air.Inst.Index, | 4397 | inst: Air.Inst.Index, |
| 4375 | modifier: std.builtin.CallModifier, | 4398 | modifier: std.builtin.CallModifier, |
| 4376 | ) !CValue { | 4399 | ) !CValue { |
| 4377 | const zcu = f.object.dg.zcu; | 4400 | const pt = f.object.dg.pt; |
| 4401 | const zcu = pt.zcu; | ||
| 4378 | // Not even allowed to call panic in a naked function. | 4402 | // Not even allowed to call panic in a naked function. |
| 4379 | if (f.object.dg.is_naked_fn) return .none; | 4403 | if (f.object.dg.is_naked_fn) return .none; |
| 4380 | 4404 | ||
| ... | @@ -4398,7 +4422,7 @@ fn airCall( | ... | @@ -4398,7 +4422,7 @@ fn airCall( |
| 4398 | if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) { | 4422 | if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) { |
| 4399 | const array_local = try f.allocAlignedLocal(inst, .{ | 4423 | const array_local = try f.allocAlignedLocal(inst, .{ |
| 4400 | .ctype = arg_ctype, | 4424 | .ctype = arg_ctype, |
| 4401 | .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)), | 4425 | .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(pt)), |
| 4402 | }); | 4426 | }); |
| 4403 | try writer.writeAll("memcpy("); | 4427 | try writer.writeAll("memcpy("); |
| 4404 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); | 4428 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); |
| ... | @@ -4445,7 +4469,7 @@ fn airCall( | ... | @@ -4445,7 +4469,7 @@ fn airCall( |
| 4445 | } else { | 4469 | } else { |
| 4446 | const local = try f.allocAlignedLocal(inst, .{ | 4470 | const local = try f.allocAlignedLocal(inst, .{ |
| 4447 | .ctype = ret_ctype, | 4471 | .ctype = ret_ctype, |
| 4448 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)), | 4472 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)), |
| 4449 | }); | 4473 | }); |
| 4450 | try f.writeCValue(writer, local, .Other); | 4474 | try f.writeCValue(writer, local, .Other); |
| 4451 | try writer.writeAll(" = "); | 4475 | try writer.writeAll(" = "); |
| ... | @@ -4456,7 +4480,7 @@ fn airCall( | ... | @@ -4456,7 +4480,7 @@ fn airCall( |
| 4456 | callee: { | 4480 | callee: { |
| 4457 | known: { | 4481 | known: { |
| 4458 | const fn_decl = fn_decl: { | 4482 | const fn_decl = fn_decl: { |
| 4459 | const callee_val = (try f.air.value(pl_op.operand, zcu)) orelse break :known; | 4483 | const callee_val = (try f.air.value(pl_op.operand, pt)) orelse break :known; |
| 4460 | break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) { | 4484 | break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) { |
| 4461 | .extern_func => |extern_func| extern_func.decl, | 4485 | .extern_func => |extern_func| extern_func.decl, |
| 4462 | .func => |func| func.owner_decl, | 4486 | .func => |func| func.owner_decl, |
| ... | @@ -4499,7 +4523,7 @@ fn airCall( | ... | @@ -4499,7 +4523,7 @@ fn airCall( |
| 4499 | try writer.writeAll(");\n"); | 4523 | try writer.writeAll(");\n"); |
| 4500 | 4524 | ||
| 4501 | const result = result: { | 4525 | const result = result: { |
| 4502 | if (result_local == .none or !lowersToArray(ret_ty, zcu)) | 4526 | if (result_local == .none or !lowersToArray(ret_ty, pt)) |
| 4503 | break :result result_local; | 4527 | break :result result_local; |
| 4504 | 4528 | ||
| 4505 | const array_local = try f.allocLocal(inst, ret_ty); | 4529 | const array_local = try f.allocLocal(inst, ret_ty); |
| ... | @@ -4533,7 +4557,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4533,7 +4557,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4533 | } | 4557 | } |
| 4534 | 4558 | ||
| 4535 | fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { | 4559 | fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4536 | const zcu = f.object.dg.zcu; | 4560 | const pt = f.object.dg.pt; |
| 4561 | const zcu = pt.zcu; | ||
| 4537 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4562 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4538 | const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | 4563 | const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4539 | const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func); | 4564 | const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func); |
| ... | @@ -4545,10 +4570,11 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4545,10 +4570,11 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4545 | } | 4570 | } |
| 4546 | 4571 | ||
| 4547 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { | 4572 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4548 | const zcu = f.object.dg.zcu; | 4573 | const pt = f.object.dg.pt; |
| 4574 | const zcu = pt.zcu; | ||
| 4549 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4575 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4550 | const name = f.air.nullTerminatedString(pl_op.payload); | 4576 | const name = f.air.nullTerminatedString(pl_op.payload); |
| 4551 | const operand_is_undef = if (try f.air.value(pl_op.operand, zcu)) |v| v.isUndefDeep(zcu) else false; | 4577 | const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false; |
| 4552 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); | 4578 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); |
| 4553 | 4579 | ||
| 4554 | try reap(f, inst, &.{pl_op.operand}); | 4580 | try reap(f, inst, &.{pl_op.operand}); |
| ... | @@ -4564,7 +4590,8 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4564,7 +4590,8 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4564 | } | 4590 | } |
| 4565 | 4591 | ||
| 4566 | fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue { | 4592 | fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue { |
| 4567 | const zcu = f.object.dg.zcu; | 4593 | const pt = f.object.dg.pt; |
| 4594 | const zcu = pt.zcu; | ||
| 4568 | const liveness_block = f.liveness.getBlock(inst); | 4595 | const liveness_block = f.liveness.getBlock(inst); |
| 4569 | 4596 | ||
| 4570 | const block_id: usize = f.next_block_index; | 4597 | const block_id: usize = f.next_block_index; |
| ... | @@ -4572,7 +4599,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) | ... | @@ -4572,7 +4599,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) |
| 4572 | const writer = f.object.writer(); | 4599 | const writer = f.object.writer(); |
| 4573 | 4600 | ||
| 4574 | const inst_ty = f.typeOfIndex(inst); | 4601 | const inst_ty = f.typeOfIndex(inst); |
| 4575 | const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst)) | 4602 | const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !f.liveness.isUnused(inst)) |
| 4576 | try f.allocLocal(inst, inst_ty) | 4603 | try f.allocLocal(inst, inst_ty) |
| 4577 | else | 4604 | else |
| 4578 | .none; | 4605 | .none; |
| ... | @@ -4611,7 +4638,8 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4611,7 +4638,8 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4611 | } | 4638 | } |
| 4612 | 4639 | ||
| 4613 | fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 4640 | fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4614 | const zcu = f.object.dg.zcu; | 4641 | const pt = f.object.dg.pt; |
| 4642 | const zcu = pt.zcu; | ||
| 4615 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4643 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4616 | const extra = f.air.extraData(Air.TryPtr, ty_pl.payload); | 4644 | const extra = f.air.extraData(Air.TryPtr, ty_pl.payload); |
| 4617 | const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]); | 4645 | const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]); |
| ... | @@ -4627,13 +4655,14 @@ fn lowerTry( | ... | @@ -4627,13 +4655,14 @@ fn lowerTry( |
| 4627 | err_union_ty: Type, | 4655 | err_union_ty: Type, |
| 4628 | is_ptr: bool, | 4656 | is_ptr: bool, |
| 4629 | ) !CValue { | 4657 | ) !CValue { |
| 4630 | const zcu = f.object.dg.zcu; | 4658 | const pt = f.object.dg.pt; |
| 4659 | const zcu = pt.zcu; | ||
| 4631 | const err_union = try f.resolveInst(operand); | 4660 | const err_union = try f.resolveInst(operand); |
| 4632 | const inst_ty = f.typeOfIndex(inst); | 4661 | const inst_ty = f.typeOfIndex(inst); |
| 4633 | const liveness_condbr = f.liveness.getCondBr(inst); | 4662 | const liveness_condbr = f.liveness.getCondBr(inst); |
| 4634 | const writer = f.object.writer(); | 4663 | const writer = f.object.writer(); |
| 4635 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 4664 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 4636 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | 4665 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 4637 | 4666 | ||
| 4638 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | 4667 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 4639 | try writer.writeAll("if ("); | 4668 | try writer.writeAll("if ("); |
| ... | @@ -4725,7 +4754,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4725,7 +4754,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4725 | } | 4754 | } |
| 4726 | 4755 | ||
| 4727 | fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue { | 4756 | fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue { |
| 4728 | const zcu = f.object.dg.zcu; | 4757 | const pt = f.object.dg.pt; |
| 4758 | const zcu = pt.zcu; | ||
| 4729 | const target = &f.object.dg.mod.resolved_target.result; | 4759 | const target = &f.object.dg.mod.resolved_target.result; |
| 4730 | const ctype_pool = &f.object.dg.ctype_pool; | 4760 | const ctype_pool = &f.object.dg.ctype_pool; |
| 4731 | const writer = f.object.writer(); | 4761 | const writer = f.object.writer(); |
| ... | @@ -4771,7 +4801,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal | ... | @@ -4771,7 +4801,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 4771 | try writer.writeAll(", sizeof("); | 4801 | try writer.writeAll(", sizeof("); |
| 4772 | try f.renderType( | 4802 | try f.renderType( |
| 4773 | writer, | 4803 | writer, |
| 4774 | if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty, | 4804 | if (dest_ty.abiSize(pt) <= operand_ty.abiSize(pt)) dest_ty else operand_ty, |
| 4775 | ); | 4805 | ); |
| 4776 | try writer.writeAll("));\n"); | 4806 | try writer.writeAll("));\n"); |
| 4777 | 4807 | ||
| ... | @@ -4805,7 +4835,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal | ... | @@ -4805,7 +4835,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 4805 | try writer.writeByte('('); | 4835 | try writer.writeByte('('); |
| 4806 | } | 4836 | } |
| 4807 | try writer.writeAll("zig_wrap_"); | 4837 | try writer.writeAll("zig_wrap_"); |
| 4808 | const info_ty = try zcu.intType(dest_info.signedness, bits); | 4838 | const info_ty = try pt.intType(dest_info.signedness, bits); |
| 4809 | if (wrap_ctype) |ctype| | 4839 | if (wrap_ctype) |ctype| |
| 4810 | try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype) | 4840 | try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype) |
| 4811 | else | 4841 | else |
| ... | @@ -4935,7 +4965,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4935,7 +4965,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4935 | } | 4965 | } |
| 4936 | 4966 | ||
| 4937 | fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | 4967 | fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4938 | const zcu = f.object.dg.zcu; | 4968 | const pt = f.object.dg.pt; |
| 4969 | const zcu = pt.zcu; | ||
| 4939 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4970 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4940 | const condition = try f.resolveInst(pl_op.operand); | 4971 | const condition = try f.resolveInst(pl_op.operand); |
| 4941 | try reap(f, inst, &.{pl_op.operand}); | 4972 | try reap(f, inst, &.{pl_op.operand}); |
| ... | @@ -4979,16 +5010,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4979,16 +5010,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4979 | for (items) |item| { | 5010 | for (items) |item| { |
| 4980 | try f.object.indent_writer.insertNewline(); | 5011 | try f.object.indent_writer.insertNewline(); |
| 4981 | try writer.writeAll("case "); | 5012 | try writer.writeAll("case "); |
| 4982 | const item_value = try f.air.value(item, zcu); | 5013 | const item_value = try f.air.value(item, pt); |
| 4983 | if (item_value.?.getUnsignedInt(zcu)) |item_int| try writer.print("{}\n", .{ | 5014 | if (item_value.?.getUnsignedInt(pt)) |item_int| try writer.print("{}\n", .{ |
| 4984 | try f.fmtIntLiteral(try zcu.intValue(lowered_condition_ty, item_int)), | 5015 | try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int)), |
| 4985 | }) else { | 5016 | }) else { |
| 4986 | if (condition_ty.isPtrAtRuntime(zcu)) { | 5017 | if (condition_ty.isPtrAtRuntime(zcu)) { |
| 4987 | try writer.writeByte('('); | 5018 | try writer.writeByte('('); |
| 4988 | try f.renderType(writer, Type.usize); | 5019 | try f.renderType(writer, Type.usize); |
| 4989 | try writer.writeByte(')'); | 5020 | try writer.writeByte(')'); |
| 4990 | } | 5021 | } |
| 4991 | try f.object.dg.renderValue(writer, (try f.air.value(item, zcu)).?, .Other); | 5022 | try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other); |
| 4992 | } | 5023 | } |
| 4993 | try writer.writeByte(':'); | 5024 | try writer.writeByte(':'); |
| 4994 | } | 5025 | } |
| ... | @@ -5026,13 +5057,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5026,13 +5057,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5026 | } | 5057 | } |
| 5027 | 5058 | ||
| 5028 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { | 5059 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { |
| 5029 | const target = &f.object.dg.mod.resolved_target.result; | 5060 | const dg = f.object.dg; |
| 5061 | const target = &dg.mod.resolved_target.result; | ||
| 5030 | return switch (constraint[0]) { | 5062 | return switch (constraint[0]) { |
| 5031 | '{' => true, | 5063 | '{' => true, |
| 5032 | 'i', 'r' => false, | 5064 | 'i', 'r' => false, |
| 5033 | 'I' => !target.cpu.arch.isArmOrThumb(), | 5065 | 'I' => !target.cpu.arch.isArmOrThumb(), |
| 5034 | else => switch (value) { | 5066 | else => switch (value) { |
| 5035 | .constant => |val| switch (f.object.dg.zcu.intern_pool.indexToKey(val.toIntern())) { | 5067 | .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 5036 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 5068 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { |
| 5037 | .decl => false, | 5069 | .decl => false, |
| 5038 | else => true, | 5070 | else => true, |
| ... | @@ -5045,7 +5077,8 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool | ... | @@ -5045,7 +5077,8 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool |
| 5045 | } | 5077 | } |
| 5046 | 5078 | ||
| 5047 | fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | 5079 | fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5048 | const zcu = f.object.dg.zcu; | 5080 | const pt = f.object.dg.pt; |
| 5081 | const zcu = pt.zcu; | ||
| 5049 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5082 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5050 | const extra = f.air.extraData(Air.Asm, ty_pl.payload); | 5083 | const extra = f.air.extraData(Air.Asm, ty_pl.payload); |
| 5051 | const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; | 5084 | const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; |
| ... | @@ -5060,10 +5093,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5060,10 +5093,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5060 | const result = result: { | 5093 | const result = result: { |
| 5061 | const writer = f.object.writer(); | 5094 | const writer = f.object.writer(); |
| 5062 | const inst_ty = f.typeOfIndex(inst); | 5095 | const inst_ty = f.typeOfIndex(inst); |
| 5063 | const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: { | 5096 | const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt)) local: { |
| 5064 | const inst_local = try f.allocLocalValue(.{ | 5097 | const inst_local = try f.allocLocalValue(.{ |
| 5065 | .ctype = try f.ctypeFromType(inst_ty, .complete), | 5098 | .ctype = try f.ctypeFromType(inst_ty, .complete), |
| 5066 | .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)), | 5099 | .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(pt)), |
| 5067 | }); | 5100 | }); |
| 5068 | if (f.wantSafety()) { | 5101 | if (f.wantSafety()) { |
| 5069 | try f.writeCValue(writer, inst_local, .Other); | 5102 | try f.writeCValue(writer, inst_local, .Other); |
| ... | @@ -5096,7 +5129,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5096,7 +5129,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5096 | try writer.writeAll("register "); | 5129 | try writer.writeAll("register "); |
| 5097 | const output_local = try f.allocLocalValue(.{ | 5130 | const output_local = try f.allocLocalValue(.{ |
| 5098 | .ctype = try f.ctypeFromType(output_ty, .complete), | 5131 | .ctype = try f.ctypeFromType(output_ty, .complete), |
| 5099 | .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)), | 5132 | .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(pt)), |
| 5100 | }); | 5133 | }); |
| 5101 | try f.allocs.put(gpa, output_local.new_local, false); | 5134 | try f.allocs.put(gpa, output_local.new_local, false); |
| 5102 | try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete); | 5135 | try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete); |
| ... | @@ -5131,7 +5164,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5131,7 +5164,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5131 | if (is_reg) try writer.writeAll("register "); | 5164 | if (is_reg) try writer.writeAll("register "); |
| 5132 | const input_local = try f.allocLocalValue(.{ | 5165 | const input_local = try f.allocLocalValue(.{ |
| 5133 | .ctype = try f.ctypeFromType(input_ty, .complete), | 5166 | .ctype = try f.ctypeFromType(input_ty, .complete), |
| 5134 | .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)), | 5167 | .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(pt)), |
| 5135 | }); | 5168 | }); |
| 5136 | try f.allocs.put(gpa, input_local.new_local, false); | 5169 | try f.allocs.put(gpa, input_local.new_local, false); |
| 5137 | try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete); | 5170 | try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete); |
| ... | @@ -5314,7 +5347,8 @@ fn airIsNull( | ... | @@ -5314,7 +5347,8 @@ fn airIsNull( |
| 5314 | operator: std.math.CompareOperator, | 5347 | operator: std.math.CompareOperator, |
| 5315 | is_ptr: bool, | 5348 | is_ptr: bool, |
| 5316 | ) !CValue { | 5349 | ) !CValue { |
| 5317 | const zcu = f.object.dg.zcu; | 5350 | const pt = f.object.dg.pt; |
| 5351 | const zcu = pt.zcu; | ||
| 5318 | const ctype_pool = &f.object.dg.ctype_pool; | 5352 | const ctype_pool = &f.object.dg.ctype_pool; |
| 5319 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5353 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5320 | 5354 | ||
| ... | @@ -5369,7 +5403,8 @@ fn airIsNull( | ... | @@ -5369,7 +5403,8 @@ fn airIsNull( |
| 5369 | } | 5403 | } |
| 5370 | 5404 | ||
| 5371 | fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | 5405 | fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 5372 | const zcu = f.object.dg.zcu; | 5406 | const pt = f.object.dg.pt; |
| 5407 | const zcu = pt.zcu; | ||
| 5373 | const ctype_pool = &f.object.dg.ctype_pool; | 5408 | const ctype_pool = &f.object.dg.ctype_pool; |
| 5374 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5409 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5375 | 5410 | ||
| ... | @@ -5404,7 +5439,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue | ... | @@ -5404,7 +5439,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue |
| 5404 | } | 5439 | } |
| 5405 | 5440 | ||
| 5406 | fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | 5441 | fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5407 | const zcu = f.object.dg.zcu; | 5442 | const pt = f.object.dg.pt; |
| 5443 | const zcu = pt.zcu; | ||
| 5408 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5444 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5409 | const writer = f.object.writer(); | 5445 | const writer = f.object.writer(); |
| 5410 | const operand = try f.resolveInst(ty_op.operand); | 5446 | const operand = try f.resolveInst(ty_op.operand); |
| ... | @@ -5458,21 +5494,22 @@ fn fieldLocation( | ... | @@ -5458,21 +5494,22 @@ fn fieldLocation( |
| 5458 | container_ptr_ty: Type, | 5494 | container_ptr_ty: Type, |
| 5459 | field_ptr_ty: Type, | 5495 | field_ptr_ty: Type, |
| 5460 | field_index: u32, | 5496 | field_index: u32, |
| 5461 | zcu: *Zcu, | 5497 | pt: Zcu.PerThread, |
| 5462 | ) union(enum) { | 5498 | ) union(enum) { |
| 5463 | begin: void, | 5499 | begin: void, |
| 5464 | field: CValue, | 5500 | field: CValue, |
| 5465 | byte_offset: u64, | 5501 | byte_offset: u64, |
| 5466 | } { | 5502 | } { |
| 5503 | const zcu = pt.zcu; | ||
| 5467 | const ip = &zcu.intern_pool; | 5504 | const ip = &zcu.intern_pool; |
| 5468 | const container_ty = Type.fromInterned(ip.indexToKey(container_ptr_ty.toIntern()).ptr_type.child); | 5505 | const container_ty = Type.fromInterned(ip.indexToKey(container_ptr_ty.toIntern()).ptr_type.child); |
| 5469 | switch (ip.indexToKey(container_ty.toIntern())) { | 5506 | switch (ip.indexToKey(container_ty.toIntern())) { |
| 5470 | .struct_type => { | 5507 | .struct_type => { |
| 5471 | const loaded_struct = ip.loadStructType(container_ty.toIntern()); | 5508 | const loaded_struct = ip.loadStructType(container_ty.toIntern()); |
| 5472 | return switch (loaded_struct.layout) { | 5509 | return switch (loaded_struct.layout) { |
| 5473 | .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu)) | 5510 | .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 5474 | .begin | 5511 | .begin |
| 5475 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) | 5512 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt)) |
| 5476 | .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] } | 5513 | .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] } |
| 5477 | else | 5514 | else |
| 5478 | .{ .field = if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| | 5515 | .{ .field = if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | @@ -5480,16 +5517,16 @@ fn fieldLocation( | ... | @@ -5480,16 +5517,16 @@ fn fieldLocation( |
| 5480 | else | 5517 | else |
| 5481 | .{ .field = field_index } }, | 5518 | .{ .field = field_index } }, |
| 5482 | .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0) | 5519 | .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0) |
| 5483 | .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) + | 5520 | .{ .byte_offset = @divExact(pt.structPackedFieldBitOffset(loaded_struct, field_index) + |
| 5484 | container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) } | 5521 | container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) } |
| 5485 | else | 5522 | else |
| 5486 | .begin, | 5523 | .begin, |
| 5487 | }; | 5524 | }; |
| 5488 | }, | 5525 | }, |
| 5489 | .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu)) | 5526 | .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 5490 | .begin | 5527 | .begin |
| 5491 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) | 5528 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt)) |
| 5492 | .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) } | 5529 | .{ .byte_offset = container_ty.structFieldOffset(field_index, pt) } |
| 5493 | else | 5530 | else |
| 5494 | .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| | 5531 | .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| |
| 5495 | .{ .identifier = field_name.toSlice(ip) } | 5532 | .{ .identifier = field_name.toSlice(ip) } |
| ... | @@ -5500,8 +5537,8 @@ fn fieldLocation( | ... | @@ -5500,8 +5537,8 @@ fn fieldLocation( |
| 5500 | switch (loaded_union.getLayout(ip)) { | 5537 | switch (loaded_union.getLayout(ip)) { |
| 5501 | .auto, .@"extern" => { | 5538 | .auto, .@"extern" => { |
| 5502 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | 5539 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 5503 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) | 5540 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 5504 | return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(zcu)) | 5541 | return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(pt)) |
| 5505 | .{ .field = .{ .identifier = "payload" } } | 5542 | .{ .field = .{ .identifier = "payload" } } |
| 5506 | else | 5543 | else |
| 5507 | .begin; | 5544 | .begin; |
| ... | @@ -5546,7 +5583,8 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue | ... | @@ -5546,7 +5583,8 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue |
| 5546 | } | 5583 | } |
| 5547 | 5584 | ||
| 5548 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 5585 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5549 | const zcu = f.object.dg.zcu; | 5586 | const pt = f.object.dg.pt; |
| 5587 | const zcu = pt.zcu; | ||
| 5550 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5588 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5551 | const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 5589 | const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5552 | 5590 | ||
| ... | @@ -5564,10 +5602,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5564,10 +5602,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5564 | try f.renderType(writer, container_ptr_ty); | 5602 | try f.renderType(writer, container_ptr_ty); |
| 5565 | try writer.writeByte(')'); | 5603 | try writer.writeByte(')'); |
| 5566 | 5604 | ||
| 5567 | switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, zcu)) { | 5605 | switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) { |
| 5568 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), | 5606 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), |
| 5569 | .field => |field| { | 5607 | .field => |field| { |
| 5570 | const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8); | 5608 | const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5571 | 5609 | ||
| 5572 | try writer.writeAll("(("); | 5610 | try writer.writeAll("(("); |
| 5573 | try f.renderType(writer, u8_ptr_ty); | 5611 | try f.renderType(writer, u8_ptr_ty); |
| ... | @@ -5580,14 +5618,14 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5580,14 +5618,14 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5580 | try writer.writeAll("))"); | 5618 | try writer.writeAll("))"); |
| 5581 | }, | 5619 | }, |
| 5582 | .byte_offset => |byte_offset| { | 5620 | .byte_offset => |byte_offset| { |
| 5583 | const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8); | 5621 | const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5584 | 5622 | ||
| 5585 | try writer.writeAll("(("); | 5623 | try writer.writeAll("(("); |
| 5586 | try f.renderType(writer, u8_ptr_ty); | 5624 | try f.renderType(writer, u8_ptr_ty); |
| 5587 | try writer.writeByte(')'); | 5625 | try writer.writeByte(')'); |
| 5588 | try f.writeCValue(writer, field_ptr_val, .Other); | 5626 | try f.writeCValue(writer, field_ptr_val, .Other); |
| 5589 | try writer.print(" - {})", .{ | 5627 | try writer.print(" - {})", .{ |
| 5590 | try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)), | 5628 | try f.fmtIntLiteral(try pt.intValue(Type.usize, byte_offset)), |
| 5591 | }); | 5629 | }); |
| 5592 | }, | 5630 | }, |
| 5593 | } | 5631 | } |
| ... | @@ -5603,7 +5641,8 @@ fn fieldPtr( | ... | @@ -5603,7 +5641,8 @@ fn fieldPtr( |
| 5603 | container_ptr_val: CValue, | 5641 | container_ptr_val: CValue, |
| 5604 | field_index: u32, | 5642 | field_index: u32, |
| 5605 | ) !CValue { | 5643 | ) !CValue { |
| 5606 | const zcu = f.object.dg.zcu; | 5644 | const pt = f.object.dg.pt; |
| 5645 | const zcu = pt.zcu; | ||
| 5607 | const container_ty = container_ptr_ty.childType(zcu); | 5646 | const container_ty = container_ptr_ty.childType(zcu); |
| 5608 | const field_ptr_ty = f.typeOfIndex(inst); | 5647 | const field_ptr_ty = f.typeOfIndex(inst); |
| 5609 | 5648 | ||
| ... | @@ -5617,21 +5656,21 @@ fn fieldPtr( | ... | @@ -5617,21 +5656,21 @@ fn fieldPtr( |
| 5617 | try f.renderType(writer, field_ptr_ty); | 5656 | try f.renderType(writer, field_ptr_ty); |
| 5618 | try writer.writeByte(')'); | 5657 | try writer.writeByte(')'); |
| 5619 | 5658 | ||
| 5620 | switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, zcu)) { | 5659 | switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) { |
| 5621 | .begin => try f.writeCValue(writer, container_ptr_val, .Initializer), | 5660 | .begin => try f.writeCValue(writer, container_ptr_val, .Initializer), |
| 5622 | .field => |field| { | 5661 | .field => |field| { |
| 5623 | try writer.writeByte('&'); | 5662 | try writer.writeByte('&'); |
| 5624 | try f.writeCValueDerefMember(writer, container_ptr_val, field); | 5663 | try f.writeCValueDerefMember(writer, container_ptr_val, field); |
| 5625 | }, | 5664 | }, |
| 5626 | .byte_offset => |byte_offset| { | 5665 | .byte_offset => |byte_offset| { |
| 5627 | const u8_ptr_ty = try zcu.adjustPtrTypeChild(field_ptr_ty, Type.u8); | 5666 | const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5628 | 5667 | ||
| 5629 | try writer.writeAll("(("); | 5668 | try writer.writeAll("(("); |
| 5630 | try f.renderType(writer, u8_ptr_ty); | 5669 | try f.renderType(writer, u8_ptr_ty); |
| 5631 | try writer.writeByte(')'); | 5670 | try writer.writeByte(')'); |
| 5632 | try f.writeCValue(writer, container_ptr_val, .Other); | 5671 | try f.writeCValue(writer, container_ptr_val, .Other); |
| 5633 | try writer.print(" + {})", .{ | 5672 | try writer.print(" + {})", .{ |
| 5634 | try f.fmtIntLiteral(try zcu.intValue(Type.usize, byte_offset)), | 5673 | try f.fmtIntLiteral(try pt.intValue(Type.usize, byte_offset)), |
| 5635 | }); | 5674 | }); |
| 5636 | }, | 5675 | }, |
| 5637 | } | 5676 | } |
| ... | @@ -5641,13 +5680,14 @@ fn fieldPtr( | ... | @@ -5641,13 +5680,14 @@ fn fieldPtr( |
| 5641 | } | 5680 | } |
| 5642 | 5681 | ||
| 5643 | fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | 5682 | fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5644 | const zcu = f.object.dg.zcu; | 5683 | const pt = f.object.dg.pt; |
| 5684 | const zcu = pt.zcu; | ||
| 5645 | const ip = &zcu.intern_pool; | 5685 | const ip = &zcu.intern_pool; |
| 5646 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5686 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5647 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; | 5687 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5648 | 5688 | ||
| 5649 | const inst_ty = f.typeOfIndex(inst); | 5689 | const inst_ty = f.typeOfIndex(inst); |
| 5650 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 5690 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5651 | try reap(f, inst, &.{extra.struct_operand}); | 5691 | try reap(f, inst, &.{extra.struct_operand}); |
| 5652 | return .none; | 5692 | return .none; |
| 5653 | } | 5693 | } |
| ... | @@ -5671,15 +5711,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5671,15 +5711,15 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5671 | .@"packed" => { | 5711 | .@"packed" => { |
| 5672 | const int_info = struct_ty.intInfo(zcu); | 5712 | const int_info = struct_ty.intInfo(zcu); |
| 5673 | 5713 | ||
| 5674 | const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); | 5714 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); |
| 5675 | 5715 | ||
| 5676 | const bit_offset = zcu.structPackedFieldBitOffset(loaded_struct, extra.field_index); | 5716 | const bit_offset = pt.structPackedFieldBitOffset(loaded_struct, extra.field_index); |
| 5677 | 5717 | ||
| 5678 | const field_int_signedness = if (inst_ty.isAbiInt(zcu)) | 5718 | const field_int_signedness = if (inst_ty.isAbiInt(zcu)) |
| 5679 | inst_ty.intInfo(zcu).signedness | 5719 | inst_ty.intInfo(zcu).signedness |
| 5680 | else | 5720 | else |
| 5681 | .unsigned; | 5721 | .unsigned; |
| 5682 | const field_int_ty = try zcu.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu)))); | 5722 | const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(pt)))); |
| 5683 | 5723 | ||
| 5684 | const temp_local = try f.allocLocal(inst, field_int_ty); | 5724 | const temp_local = try f.allocLocal(inst, field_int_ty); |
| 5685 | try f.writeCValue(writer, temp_local, .Other); | 5725 | try f.writeCValue(writer, temp_local, .Other); |
| ... | @@ -5690,7 +5730,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5690,7 +5730,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5690 | try writer.writeByte(')'); | 5730 | try writer.writeByte(')'); |
| 5691 | const cant_cast = int_info.bits > 64; | 5731 | const cant_cast = int_info.bits > 64; |
| 5692 | if (cant_cast) { | 5732 | if (cant_cast) { |
| 5693 | if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | 5733 | if (field_int_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); |
| 5694 | try writer.writeAll("zig_lo_"); | 5734 | try writer.writeAll("zig_lo_"); |
| 5695 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); | 5735 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5696 | try writer.writeByte('('); | 5736 | try writer.writeByte('('); |
| ... | @@ -5702,12 +5742,12 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5702,12 +5742,12 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5702 | } | 5742 | } |
| 5703 | try f.writeCValue(writer, struct_byval, .Other); | 5743 | try f.writeCValue(writer, struct_byval, .Other); |
| 5704 | if (bit_offset > 0) try writer.print(", {})", .{ | 5744 | if (bit_offset > 0) try writer.print(", {})", .{ |
| 5705 | try f.fmtIntLiteral(try zcu.intValue(bit_offset_ty, bit_offset)), | 5745 | try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)), |
| 5706 | }); | 5746 | }); |
| 5707 | if (cant_cast) try writer.writeByte(')'); | 5747 | if (cant_cast) try writer.writeByte(')'); |
| 5708 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); | 5748 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); |
| 5709 | try writer.writeAll(");\n"); | 5749 | try writer.writeAll(");\n"); |
| 5710 | if (inst_ty.eql(field_int_ty, f.object.dg.zcu)) return temp_local; | 5750 | if (inst_ty.eql(field_int_ty, zcu)) return temp_local; |
| 5711 | 5751 | ||
| 5712 | const local = try f.allocLocal(inst, inst_ty); | 5752 | const local = try f.allocLocal(inst, inst_ty); |
| 5713 | if (local.new_local != temp_local.new_local) { | 5753 | if (local.new_local != temp_local.new_local) { |
| ... | @@ -5783,7 +5823,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5783,7 +5823,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5783 | /// *(E!T) -> E | 5823 | /// *(E!T) -> E |
| 5784 | /// Note that the result is never a pointer. | 5824 | /// Note that the result is never a pointer. |
| 5785 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | 5825 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5786 | const zcu = f.object.dg.zcu; | 5826 | const pt = f.object.dg.pt; |
| 5827 | const zcu = pt.zcu; | ||
| 5787 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5828 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5788 | 5829 | ||
| 5789 | const inst_ty = f.typeOfIndex(inst); | 5830 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -5797,7 +5838,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5797,7 +5838,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5797 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | 5838 | const payload_ty = error_union_ty.errorUnionPayload(zcu); |
| 5798 | const local = try f.allocLocal(inst, inst_ty); | 5839 | const local = try f.allocLocal(inst, inst_ty); |
| 5799 | 5840 | ||
| 5800 | if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) { | 5841 | if (!payload_ty.hasRuntimeBits(pt) and operand == .local and operand.local == local.new_local) { |
| 5801 | // The store will be 'x = x'; elide it. | 5842 | // The store will be 'x = x'; elide it. |
| 5802 | return local; | 5843 | return local; |
| 5803 | } | 5844 | } |
| ... | @@ -5806,11 +5847,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5806,11 +5847,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5806 | try f.writeCValue(writer, local, .Other); | 5847 | try f.writeCValue(writer, local, .Other); |
| 5807 | try writer.writeAll(" = "); | 5848 | try writer.writeAll(" = "); |
| 5808 | 5849 | ||
| 5809 | if (!payload_ty.hasRuntimeBits(zcu)) | 5850 | if (!payload_ty.hasRuntimeBits(pt)) |
| 5810 | try f.writeCValue(writer, operand, .Other) | 5851 | try f.writeCValue(writer, operand, .Other) |
| 5811 | else if (error_ty.errorSetIsEmpty(zcu)) | 5852 | else if (error_ty.errorSetIsEmpty(zcu)) |
| 5812 | try writer.print("{}", .{ | 5853 | try writer.print("{}", .{ |
| 5813 | try f.fmtIntLiteral(try zcu.intValue(try zcu.errorIntType(), 0)), | 5854 | try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)), |
| 5814 | }) | 5855 | }) |
| 5815 | else if (operand_is_ptr) | 5856 | else if (operand_is_ptr) |
| 5816 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) | 5857 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| ... | @@ -5821,7 +5862,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5821,7 +5862,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5821 | } | 5862 | } |
| 5822 | 5863 | ||
| 5823 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | 5864 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 5824 | const zcu = f.object.dg.zcu; | 5865 | const pt = f.object.dg.pt; |
| 5866 | const zcu = pt.zcu; | ||
| 5825 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5867 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5826 | 5868 | ||
| 5827 | const inst_ty = f.typeOfIndex(inst); | 5869 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -5831,7 +5873,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu | ... | @@ -5831,7 +5873,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 5831 | const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty; | 5873 | const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 5832 | 5874 | ||
| 5833 | const writer = f.object.writer(); | 5875 | const writer = f.object.writer(); |
| 5834 | if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) { | 5876 | if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(pt)) { |
| 5835 | if (!is_ptr) return .none; | 5877 | if (!is_ptr) return .none; |
| 5836 | 5878 | ||
| 5837 | const local = try f.allocLocal(inst, inst_ty); | 5879 | const local = try f.allocLocal(inst, inst_ty); |
| ... | @@ -5896,12 +5938,13 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5896,12 +5938,13 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5896 | } | 5938 | } |
| 5897 | 5939 | ||
| 5898 | fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | 5940 | fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5899 | const zcu = f.object.dg.zcu; | 5941 | const pt = f.object.dg.pt; |
| 5942 | const zcu = pt.zcu; | ||
| 5900 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5943 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5901 | 5944 | ||
| 5902 | const inst_ty = f.typeOfIndex(inst); | 5945 | const inst_ty = f.typeOfIndex(inst); |
| 5903 | const payload_ty = inst_ty.errorUnionPayload(zcu); | 5946 | const payload_ty = inst_ty.errorUnionPayload(zcu); |
| 5904 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | 5947 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 5905 | const err_ty = inst_ty.errorUnionSet(zcu); | 5948 | const err_ty = inst_ty.errorUnionSet(zcu); |
| 5906 | const err = try f.resolveInst(ty_op.operand); | 5949 | const err = try f.resolveInst(ty_op.operand); |
| 5907 | try reap(f, inst, &.{ty_op.operand}); | 5950 | try reap(f, inst, &.{ty_op.operand}); |
| ... | @@ -5935,7 +5978,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5935,7 +5978,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5935 | } | 5978 | } |
| 5936 | 5979 | ||
| 5937 | fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | 5980 | fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5938 | const zcu = f.object.dg.zcu; | 5981 | const pt = f.object.dg.pt; |
| 5982 | const zcu = pt.zcu; | ||
| 5939 | const writer = f.object.writer(); | 5983 | const writer = f.object.writer(); |
| 5940 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5984 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5941 | const inst_ty = f.typeOfIndex(inst); | 5985 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -5944,12 +5988,12 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5944,12 +5988,12 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5944 | const error_union_ty = operand_ty.childType(zcu); | 5988 | const error_union_ty = operand_ty.childType(zcu); |
| 5945 | 5989 | ||
| 5946 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | 5990 | const payload_ty = error_union_ty.errorUnionPayload(zcu); |
| 5947 | const err_int_ty = try zcu.errorIntType(); | 5991 | const err_int_ty = try pt.errorIntType(); |
| 5948 | const no_err = try zcu.intValue(err_int_ty, 0); | 5992 | const no_err = try pt.intValue(err_int_ty, 0); |
| 5949 | try reap(f, inst, &.{ty_op.operand}); | 5993 | try reap(f, inst, &.{ty_op.operand}); |
| 5950 | 5994 | ||
| 5951 | // First, set the non-error value. | 5995 | // First, set the non-error value. |
| 5952 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 5996 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5953 | const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete)); | 5997 | const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete)); |
| 5954 | try f.writeCValueDeref(writer, operand); | 5998 | try f.writeCValueDeref(writer, operand); |
| 5955 | try a.assign(f, writer); | 5999 | try a.assign(f, writer); |
| ... | @@ -5994,13 +6038,14 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5994,13 +6038,14 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5994 | } | 6038 | } |
| 5995 | 6039 | ||
| 5996 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | 6040 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5997 | const zcu = f.object.dg.zcu; | 6041 | const pt = f.object.dg.pt; |
| 6042 | const zcu = pt.zcu; | ||
| 5998 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6043 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5999 | 6044 | ||
| 6000 | const inst_ty = f.typeOfIndex(inst); | 6045 | const inst_ty = f.typeOfIndex(inst); |
| 6001 | const payload_ty = inst_ty.errorUnionPayload(zcu); | 6046 | const payload_ty = inst_ty.errorUnionPayload(zcu); |
| 6002 | const payload = try f.resolveInst(ty_op.operand); | 6047 | const payload = try f.resolveInst(ty_op.operand); |
| 6003 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | 6048 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 6004 | const err_ty = inst_ty.errorUnionSet(zcu); | 6049 | const err_ty = inst_ty.errorUnionSet(zcu); |
| 6005 | try reap(f, inst, &.{ty_op.operand}); | 6050 | try reap(f, inst, &.{ty_op.operand}); |
| 6006 | 6051 | ||
| ... | @@ -6020,14 +6065,15 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6020,14 +6065,15 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6020 | else | 6065 | else |
| 6021 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); | 6066 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); |
| 6022 | try a.assign(f, writer); | 6067 | try a.assign(f, writer); |
| 6023 | try f.object.dg.renderValue(writer, try zcu.intValue(try zcu.errorIntType(), 0), .Other); | 6068 | try f.object.dg.renderValue(writer, try pt.intValue(try pt.errorIntType(), 0), .Other); |
| 6024 | try a.end(f, writer); | 6069 | try a.end(f, writer); |
| 6025 | } | 6070 | } |
| 6026 | return local; | 6071 | return local; |
| 6027 | } | 6072 | } |
| 6028 | 6073 | ||
| 6029 | fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue { | 6074 | fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue { |
| 6030 | const zcu = f.object.dg.zcu; | 6075 | const pt = f.object.dg.pt; |
| 6076 | const zcu = pt.zcu; | ||
| 6031 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6077 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6032 | 6078 | ||
| 6033 | const writer = f.object.writer(); | 6079 | const writer = f.object.writer(); |
| ... | @@ -6042,9 +6088,9 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const | ... | @@ -6042,9 +6088,9 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const |
| 6042 | const a = try Assignment.start(f, writer, CType.bool); | 6088 | const a = try Assignment.start(f, writer, CType.bool); |
| 6043 | try f.writeCValue(writer, local, .Other); | 6089 | try f.writeCValue(writer, local, .Other); |
| 6044 | try a.assign(f, writer); | 6090 | try a.assign(f, writer); |
| 6045 | const err_int_ty = try zcu.errorIntType(); | 6091 | const err_int_ty = try pt.errorIntType(); |
| 6046 | if (!error_ty.errorSetIsEmpty(zcu)) | 6092 | if (!error_ty.errorSetIsEmpty(zcu)) |
| 6047 | if (payload_ty.hasRuntimeBits(zcu)) | 6093 | if (payload_ty.hasRuntimeBits(pt)) |
| 6048 | if (is_ptr) | 6094 | if (is_ptr) |
| 6049 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) | 6095 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| 6050 | else | 6096 | else |
| ... | @@ -6052,17 +6098,18 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const | ... | @@ -6052,17 +6098,18 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const |
| 6052 | else | 6098 | else |
| 6053 | try f.writeCValue(writer, operand, .Other) | 6099 | try f.writeCValue(writer, operand, .Other) |
| 6054 | else | 6100 | else |
| 6055 | try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other); | 6101 | try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other); |
| 6056 | try writer.writeByte(' '); | 6102 | try writer.writeByte(' '); |
| 6057 | try writer.writeAll(operator); | 6103 | try writer.writeAll(operator); |
| 6058 | try writer.writeByte(' '); | 6104 | try writer.writeByte(' '); |
| 6059 | try f.object.dg.renderValue(writer, try zcu.intValue(err_int_ty, 0), .Other); | 6105 | try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other); |
| 6060 | try a.end(f, writer); | 6106 | try a.end(f, writer); |
| 6061 | return local; | 6107 | return local; |
| 6062 | } | 6108 | } |
| 6063 | 6109 | ||
| 6064 | fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | 6110 | fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6065 | const zcu = f.object.dg.zcu; | 6111 | const pt = f.object.dg.pt; |
| 6112 | const zcu = pt.zcu; | ||
| 6066 | const ctype_pool = &f.object.dg.ctype_pool; | 6113 | const ctype_pool = &f.object.dg.ctype_pool; |
| 6067 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6114 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6068 | 6115 | ||
| ... | @@ -6096,7 +6143,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6096,7 +6143,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6096 | if (operand_child_ctype.info(ctype_pool) == .array) { | 6143 | if (operand_child_ctype.info(ctype_pool) == .array) { |
| 6097 | try writer.writeByte('&'); | 6144 | try writer.writeByte('&'); |
| 6098 | try f.writeCValueDeref(writer, operand); | 6145 | try f.writeCValueDeref(writer, operand); |
| 6099 | try writer.print("[{}]", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))}); | 6146 | try writer.print("[{}]", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 0))}); |
| 6100 | } else try f.writeCValue(writer, operand, .Initializer); | 6147 | } else try f.writeCValue(writer, operand, .Initializer); |
| 6101 | } | 6148 | } |
| 6102 | try a.end(f, writer); | 6149 | try a.end(f, writer); |
| ... | @@ -6106,7 +6153,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6106,7 +6153,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6106 | try f.writeCValueMember(writer, local, .{ .identifier = "len" }); | 6153 | try f.writeCValueMember(writer, local, .{ .identifier = "len" }); |
| 6107 | try a.assign(f, writer); | 6154 | try a.assign(f, writer); |
| 6108 | try writer.print("{}", .{ | 6155 | try writer.print("{}", .{ |
| 6109 | try f.fmtIntLiteral(try zcu.intValue(Type.usize, array_ty.arrayLen(zcu))), | 6156 | try f.fmtIntLiteral(try pt.intValue(Type.usize, array_ty.arrayLen(zcu))), |
| 6110 | }); | 6157 | }); |
| 6111 | try a.end(f, writer); | 6158 | try a.end(f, writer); |
| 6112 | } | 6159 | } |
| ... | @@ -6115,7 +6162,8 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6115,7 +6162,8 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6115 | } | 6162 | } |
| 6116 | 6163 | ||
| 6117 | fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { | 6164 | fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6118 | const zcu = f.object.dg.zcu; | 6165 | const pt = f.object.dg.pt; |
| 6166 | const zcu = pt.zcu; | ||
| 6119 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6167 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6120 | 6168 | ||
| 6121 | const inst_ty = f.typeOfIndex(inst); | 6169 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -6165,7 +6213,8 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6165,7 +6213,8 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6165 | } | 6213 | } |
| 6166 | 6214 | ||
| 6167 | fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 6215 | fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6168 | const zcu = f.object.dg.zcu; | 6216 | const pt = f.object.dg.pt; |
| 6217 | const zcu = pt.zcu; | ||
| 6169 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6218 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6170 | 6219 | ||
| 6171 | const operand = try f.resolveInst(un_op); | 6220 | const operand = try f.resolveInst(un_op); |
| ... | @@ -6194,7 +6243,8 @@ fn airUnBuiltinCall( | ... | @@ -6194,7 +6243,8 @@ fn airUnBuiltinCall( |
| 6194 | operation: []const u8, | 6243 | operation: []const u8, |
| 6195 | info: BuiltinInfo, | 6244 | info: BuiltinInfo, |
| 6196 | ) !CValue { | 6245 | ) !CValue { |
| 6197 | const zcu = f.object.dg.zcu; | 6246 | const pt = f.object.dg.pt; |
| 6247 | const zcu = pt.zcu; | ||
| 6198 | 6248 | ||
| 6199 | const operand = try f.resolveInst(operand_ref); | 6249 | const operand = try f.resolveInst(operand_ref); |
| 6200 | try reap(f, inst, &.{operand_ref}); | 6250 | try reap(f, inst, &.{operand_ref}); |
| ... | @@ -6237,7 +6287,8 @@ fn airBinBuiltinCall( | ... | @@ -6237,7 +6287,8 @@ fn airBinBuiltinCall( |
| 6237 | operation: []const u8, | 6287 | operation: []const u8, |
| 6238 | info: BuiltinInfo, | 6288 | info: BuiltinInfo, |
| 6239 | ) !CValue { | 6289 | ) !CValue { |
| 6240 | const zcu = f.object.dg.zcu; | 6290 | const pt = f.object.dg.pt; |
| 6291 | const zcu = pt.zcu; | ||
| 6241 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6292 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6242 | 6293 | ||
| 6243 | const operand_ty = f.typeOf(bin_op.lhs); | 6294 | const operand_ty = f.typeOf(bin_op.lhs); |
| ... | @@ -6292,7 +6343,8 @@ fn airCmpBuiltinCall( | ... | @@ -6292,7 +6343,8 @@ fn airCmpBuiltinCall( |
| 6292 | operation: enum { cmp, operator }, | 6343 | operation: enum { cmp, operator }, |
| 6293 | info: BuiltinInfo, | 6344 | info: BuiltinInfo, |
| 6294 | ) !CValue { | 6345 | ) !CValue { |
| 6295 | const zcu = f.object.dg.zcu; | 6346 | const pt = f.object.dg.pt; |
| 6347 | const zcu = pt.zcu; | ||
| 6296 | const lhs = try f.resolveInst(data.lhs); | 6348 | const lhs = try f.resolveInst(data.lhs); |
| 6297 | const rhs = try f.resolveInst(data.rhs); | 6349 | const rhs = try f.resolveInst(data.rhs); |
| 6298 | try reap(f, inst, &.{ data.lhs, data.rhs }); | 6350 | try reap(f, inst, &.{ data.lhs, data.rhs }); |
| ... | @@ -6333,7 +6385,7 @@ fn airCmpBuiltinCall( | ... | @@ -6333,7 +6385,7 @@ fn airCmpBuiltinCall( |
| 6333 | try writer.writeByte(')'); | 6385 | try writer.writeByte(')'); |
| 6334 | if (!ref_ret) try writer.print("{s}{}", .{ | 6386 | if (!ref_ret) try writer.print("{s}{}", .{ |
| 6335 | compareOperatorC(operator), | 6387 | compareOperatorC(operator), |
| 6336 | try f.fmtIntLiteral(try zcu.intValue(Type.i32, 0)), | 6388 | try f.fmtIntLiteral(try pt.intValue(Type.i32, 0)), |
| 6337 | }); | 6389 | }); |
| 6338 | try writer.writeAll(";\n"); | 6390 | try writer.writeAll(";\n"); |
| 6339 | try v.end(f, inst, writer); | 6391 | try v.end(f, inst, writer); |
| ... | @@ -6342,7 +6394,8 @@ fn airCmpBuiltinCall( | ... | @@ -6342,7 +6394,8 @@ fn airCmpBuiltinCall( |
| 6342 | } | 6394 | } |
| 6343 | 6395 | ||
| 6344 | fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue { | 6396 | fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue { |
| 6345 | const zcu = f.object.dg.zcu; | 6397 | const pt = f.object.dg.pt; |
| 6398 | const zcu = pt.zcu; | ||
| 6346 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6399 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6347 | const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 6400 | const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 6348 | const inst_ty = f.typeOfIndex(inst); | 6401 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -6358,7 +6411,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -6358,7 +6411,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6358 | try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value }); | 6411 | try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value }); |
| 6359 | 6412 | ||
| 6360 | const repr_ty = if (ty.isRuntimeFloat()) | 6413 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6361 | zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | 6414 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable |
| 6362 | else | 6415 | else |
| 6363 | ty; | 6416 | ty; |
| 6364 | 6417 | ||
| ... | @@ -6448,7 +6501,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -6448,7 +6501,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6448 | } | 6501 | } |
| 6449 | 6502 | ||
| 6450 | fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | 6503 | fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6451 | const zcu = f.object.dg.zcu; | 6504 | const pt = f.object.dg.pt; |
| 6505 | const zcu = pt.zcu; | ||
| 6452 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6506 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6453 | const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 6507 | const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 6454 | const inst_ty = f.typeOfIndex(inst); | 6508 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -6461,10 +6515,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6461,10 +6515,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6461 | const operand_mat = try Materialize.start(f, inst, ty, operand); | 6515 | const operand_mat = try Materialize.start(f, inst, ty, operand); |
| 6462 | try reap(f, inst, &.{ pl_op.operand, extra.operand }); | 6516 | try reap(f, inst, &.{ pl_op.operand, extra.operand }); |
| 6463 | 6517 | ||
| 6464 | const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8)); | 6518 | const repr_bits = @as(u16, @intCast(ty.abiSize(pt) * 8)); |
| 6465 | const is_float = ty.isRuntimeFloat(); | 6519 | const is_float = ty.isRuntimeFloat(); |
| 6466 | const is_128 = repr_bits == 128; | 6520 | const is_128 = repr_bits == 128; |
| 6467 | const repr_ty = if (is_float) zcu.intType(.unsigned, repr_bits) catch unreachable else ty; | 6521 | const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty; |
| 6468 | 6522 | ||
| 6469 | const local = try f.allocLocal(inst, inst_ty); | 6523 | const local = try f.allocLocal(inst, inst_ty); |
| 6470 | try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())}); | 6524 | try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())}); |
| ... | @@ -6503,7 +6557,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6503,7 +6557,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6503 | } | 6557 | } |
| 6504 | 6558 | ||
| 6505 | fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | 6559 | fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6506 | const zcu = f.object.dg.zcu; | 6560 | const pt = f.object.dg.pt; |
| 6561 | const zcu = pt.zcu; | ||
| 6507 | const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; | 6562 | const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 6508 | const ptr = try f.resolveInst(atomic_load.ptr); | 6563 | const ptr = try f.resolveInst(atomic_load.ptr); |
| 6509 | try reap(f, inst, &.{atomic_load.ptr}); | 6564 | try reap(f, inst, &.{atomic_load.ptr}); |
| ... | @@ -6511,7 +6566,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6511,7 +6566,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6511 | const ty = ptr_ty.childType(zcu); | 6566 | const ty = ptr_ty.childType(zcu); |
| 6512 | 6567 | ||
| 6513 | const repr_ty = if (ty.isRuntimeFloat()) | 6568 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6514 | zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | 6569 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable |
| 6515 | else | 6570 | else |
| 6516 | ty; | 6571 | ty; |
| 6517 | 6572 | ||
| ... | @@ -6539,7 +6594,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6539,7 +6594,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6539 | } | 6594 | } |
| 6540 | 6595 | ||
| 6541 | fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue { | 6596 | fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue { |
| 6542 | const zcu = f.object.dg.zcu; | 6597 | const pt = f.object.dg.pt; |
| 6598 | const zcu = pt.zcu; | ||
| 6543 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6599 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6544 | const ptr_ty = f.typeOf(bin_op.lhs); | 6600 | const ptr_ty = f.typeOf(bin_op.lhs); |
| 6545 | const ty = ptr_ty.childType(zcu); | 6601 | const ty = ptr_ty.childType(zcu); |
| ... | @@ -6551,7 +6607,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa | ... | @@ -6551,7 +6607,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 6551 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 6607 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6552 | 6608 | ||
| 6553 | const repr_ty = if (ty.isRuntimeFloat()) | 6609 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6554 | zcu.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | 6610 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable |
| 6555 | else | 6611 | else |
| 6556 | ty; | 6612 | ty; |
| 6557 | 6613 | ||
| ... | @@ -6574,7 +6630,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa | ... | @@ -6574,7 +6630,8 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 6574 | } | 6630 | } |
| 6575 | 6631 | ||
| 6576 | fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void { | 6632 | fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void { |
| 6577 | const zcu = f.object.dg.zcu; | 6633 | const pt = f.object.dg.pt; |
| 6634 | const zcu = pt.zcu; | ||
| 6578 | if (ptr_ty.isSlice(zcu)) { | 6635 | if (ptr_ty.isSlice(zcu)) { |
| 6579 | try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" }); | 6636 | try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" }); |
| 6580 | } else { | 6637 | } else { |
| ... | @@ -6583,14 +6640,15 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo | ... | @@ -6583,14 +6640,15 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo |
| 6583 | } | 6640 | } |
| 6584 | 6641 | ||
| 6585 | fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | 6642 | fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6586 | const zcu = f.object.dg.zcu; | 6643 | const pt = f.object.dg.pt; |
| 6644 | const zcu = pt.zcu; | ||
| 6587 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6645 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6588 | const dest_ty = f.typeOf(bin_op.lhs); | 6646 | const dest_ty = f.typeOf(bin_op.lhs); |
| 6589 | const dest_slice = try f.resolveInst(bin_op.lhs); | 6647 | const dest_slice = try f.resolveInst(bin_op.lhs); |
| 6590 | const value = try f.resolveInst(bin_op.rhs); | 6648 | const value = try f.resolveInst(bin_op.rhs); |
| 6591 | const elem_ty = f.typeOf(bin_op.rhs); | 6649 | const elem_ty = f.typeOf(bin_op.rhs); |
| 6592 | const elem_abi_size = elem_ty.abiSize(zcu); | 6650 | const elem_abi_size = elem_ty.abiSize(pt); |
| 6593 | const val_is_undef = if (try f.air.value(bin_op.rhs, zcu)) |val| val.isUndefDeep(zcu) else false; | 6651 | const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false; |
| 6594 | const writer = f.object.writer(); | 6652 | const writer = f.object.writer(); |
| 6595 | 6653 | ||
| 6596 | if (val_is_undef) { | 6654 | if (val_is_undef) { |
| ... | @@ -6628,7 +6686,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6628,7 +6686,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6628 | // For the assignment in this loop, the array pointer needs to get | 6686 | // For the assignment in this loop, the array pointer needs to get |
| 6629 | // casted to a regular pointer, otherwise an error like this occurs: | 6687 | // casted to a regular pointer, otherwise an error like this occurs: |
| 6630 | // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable | 6688 | // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable |
| 6631 | const elem_ptr_ty = try zcu.ptrType(.{ | 6689 | const elem_ptr_ty = try pt.ptrType(.{ |
| 6632 | .child = elem_ty.toIntern(), | 6690 | .child = elem_ty.toIntern(), |
| 6633 | .flags = .{ | 6691 | .flags = .{ |
| 6634 | .size = .C, | 6692 | .size = .C, |
| ... | @@ -6640,7 +6698,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6640,7 +6698,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6640 | try writer.writeAll("for ("); | 6698 | try writer.writeAll("for ("); |
| 6641 | try f.writeCValue(writer, index, .Other); | 6699 | try f.writeCValue(writer, index, .Other); |
| 6642 | try writer.writeAll(" = "); | 6700 | try writer.writeAll(" = "); |
| 6643 | try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, 0), .Initializer); | 6701 | try f.object.dg.renderValue(writer, try pt.intValue(Type.usize, 0), .Initializer); |
| 6644 | try writer.writeAll("; "); | 6702 | try writer.writeAll("; "); |
| 6645 | try f.writeCValue(writer, index, .Other); | 6703 | try f.writeCValue(writer, index, .Other); |
| 6646 | try writer.writeAll(" != "); | 6704 | try writer.writeAll(" != "); |
| ... | @@ -6705,7 +6763,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6705,7 +6763,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6705 | } | 6763 | } |
| 6706 | 6764 | ||
| 6707 | fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { | 6765 | fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6708 | const zcu = f.object.dg.zcu; | 6766 | const pt = f.object.dg.pt; |
| 6767 | const zcu = pt.zcu; | ||
| 6709 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6768 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6710 | const dest_ptr = try f.resolveInst(bin_op.lhs); | 6769 | const dest_ptr = try f.resolveInst(bin_op.lhs); |
| 6711 | const src_ptr = try f.resolveInst(bin_op.rhs); | 6770 | const src_ptr = try f.resolveInst(bin_op.rhs); |
| ... | @@ -6733,10 +6792,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6733,10 +6792,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6733 | } | 6792 | } |
| 6734 | 6793 | ||
| 6735 | fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void { | 6794 | fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void { |
| 6736 | const zcu = f.object.dg.zcu; | 6795 | const pt = f.object.dg.pt; |
| 6796 | const zcu = pt.zcu; | ||
| 6737 | switch (dest_ty.ptrSize(zcu)) { | 6797 | switch (dest_ty.ptrSize(zcu)) { |
| 6738 | .One => try writer.print("{}", .{ | 6798 | .One => try writer.print("{}", .{ |
| 6739 | try f.fmtIntLiteral(try zcu.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))), | 6799 | try f.fmtIntLiteral(try pt.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))), |
| 6740 | }), | 6800 | }), |
| 6741 | .Many, .C => unreachable, | 6801 | .Many, .C => unreachable, |
| 6742 | .Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }), | 6802 | .Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }), |
| ... | @@ -6744,14 +6804,15 @@ fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_t | ... | @@ -6744,14 +6804,15 @@ fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_t |
| 6744 | } | 6804 | } |
| 6745 | 6805 | ||
| 6746 | fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | 6806 | fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6747 | const zcu = f.object.dg.zcu; | 6807 | const pt = f.object.dg.pt; |
| 6808 | const zcu = pt.zcu; | ||
| 6748 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6809 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6749 | const union_ptr = try f.resolveInst(bin_op.lhs); | 6810 | const union_ptr = try f.resolveInst(bin_op.lhs); |
| 6750 | const new_tag = try f.resolveInst(bin_op.rhs); | 6811 | const new_tag = try f.resolveInst(bin_op.rhs); |
| 6751 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 6812 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6752 | 6813 | ||
| 6753 | const union_ty = f.typeOf(bin_op.lhs).childType(zcu); | 6814 | const union_ty = f.typeOf(bin_op.lhs).childType(zcu); |
| 6754 | const layout = union_ty.unionGetLayout(zcu); | 6815 | const layout = union_ty.unionGetLayout(pt); |
| 6755 | if (layout.tag_size == 0) return .none; | 6816 | if (layout.tag_size == 0) return .none; |
| 6756 | const tag_ty = union_ty.unionTagTypeSafety(zcu).?; | 6817 | const tag_ty = union_ty.unionTagTypeSafety(zcu).?; |
| 6757 | 6818 | ||
| ... | @@ -6765,14 +6826,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6765,14 +6826,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6765 | } | 6826 | } |
| 6766 | 6827 | ||
| 6767 | fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | 6828 | fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6768 | const zcu = f.object.dg.zcu; | 6829 | const pt = f.object.dg.pt; |
| 6769 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6830 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6770 | 6831 | ||
| 6771 | const operand = try f.resolveInst(ty_op.operand); | 6832 | const operand = try f.resolveInst(ty_op.operand); |
| 6772 | try reap(f, inst, &.{ty_op.operand}); | 6833 | try reap(f, inst, &.{ty_op.operand}); |
| 6773 | 6834 | ||
| 6774 | const union_ty = f.typeOf(ty_op.operand); | 6835 | const union_ty = f.typeOf(ty_op.operand); |
| 6775 | const layout = union_ty.unionGetLayout(zcu); | 6836 | const layout = union_ty.unionGetLayout(pt); |
| 6776 | if (layout.tag_size == 0) return .none; | 6837 | if (layout.tag_size == 0) return .none; |
| 6777 | 6838 | ||
| 6778 | const inst_ty = f.typeOfIndex(inst); | 6839 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -6787,7 +6848,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6787,7 +6848,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6787 | } | 6848 | } |
| 6788 | 6849 | ||
| 6789 | fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { | 6850 | fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6790 | const zcu = f.object.dg.zcu; | 6851 | const pt = f.object.dg.pt; |
| 6852 | const zcu = pt.zcu; | ||
| 6791 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6853 | const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6792 | 6854 | ||
| 6793 | const inst_ty = f.typeOfIndex(inst); | 6855 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -6824,7 +6886,8 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6824,7 +6886,8 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6824 | } | 6886 | } |
| 6825 | 6887 | ||
| 6826 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { | 6888 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6827 | const zcu = f.object.dg.zcu; | 6889 | const pt = f.object.dg.pt; |
| 6890 | const zcu = pt.zcu; | ||
| 6828 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6891 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6829 | 6892 | ||
| 6830 | const operand = try f.resolveInst(ty_op.operand); | 6893 | const operand = try f.resolveInst(ty_op.operand); |
| ... | @@ -6879,7 +6942,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6879,7 +6942,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6879 | } | 6942 | } |
| 6880 | 6943 | ||
| 6881 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { | 6944 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6882 | const zcu = f.object.dg.zcu; | 6945 | const pt = f.object.dg.pt; |
| 6883 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6946 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6884 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; | 6947 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 6885 | 6948 | ||
| ... | @@ -6895,11 +6958,11 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6895,11 +6958,11 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6895 | for (0..extra.mask_len) |index| { | 6958 | for (0..extra.mask_len) |index| { |
| 6896 | try f.writeCValue(writer, local, .Other); | 6959 | try f.writeCValue(writer, local, .Other); |
| 6897 | try writer.writeByte('['); | 6960 | try writer.writeByte('['); |
| 6898 | try f.object.dg.renderValue(writer, try zcu.intValue(Type.usize, index), .Other); | 6961 | try f.object.dg.renderValue(writer, try pt.intValue(Type.usize, index), .Other); |
| 6899 | try writer.writeAll("] = "); | 6962 | try writer.writeAll("] = "); |
| 6900 | 6963 | ||
| 6901 | const mask_elem = (try mask.elemValue(zcu, index)).toSignedInt(zcu); | 6964 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt); |
| 6902 | const src_val = try zcu.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63))); | 6965 | const src_val = try pt.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63))); |
| 6903 | 6966 | ||
| 6904 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); | 6967 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); |
| 6905 | try writer.writeByte('['); | 6968 | try writer.writeByte('['); |
| ... | @@ -6911,7 +6974,8 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6911,7 +6974,8 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6911 | } | 6974 | } |
| 6912 | 6975 | ||
| 6913 | fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | 6976 | fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6914 | const zcu = f.object.dg.zcu; | 6977 | const pt = f.object.dg.pt; |
| 6978 | const zcu = pt.zcu; | ||
| 6915 | const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 6979 | const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 6916 | 6980 | ||
| 6917 | const scalar_ty = f.typeOfIndex(inst); | 6981 | const scalar_ty = f.typeOfIndex(inst); |
| ... | @@ -6920,7 +6984,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6920,7 +6984,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6920 | const operand_ty = f.typeOf(reduce.operand); | 6984 | const operand_ty = f.typeOf(reduce.operand); |
| 6921 | const writer = f.object.writer(); | 6985 | const writer = f.object.writer(); |
| 6922 | 6986 | ||
| 6923 | const use_operator = scalar_ty.bitSize(zcu) <= 64; | 6987 | const use_operator = scalar_ty.bitSize(pt) <= 64; |
| 6924 | const op: union(enum) { | 6988 | const op: union(enum) { |
| 6925 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; | 6989 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; |
| 6926 | builtin: Func, | 6990 | builtin: Func, |
| ... | @@ -6971,37 +7035,37 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6971,37 +7035,37 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6971 | try f.object.dg.renderValue(writer, switch (reduce.operation) { | 7035 | try f.object.dg.renderValue(writer, switch (reduce.operation) { |
| 6972 | .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) { | 7036 | .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6973 | .Bool => Value.false, | 7037 | .Bool => Value.false, |
| 6974 | .Int => try zcu.intValue(scalar_ty, 0), | 7038 | .Int => try pt.intValue(scalar_ty, 0), |
| 6975 | else => unreachable, | 7039 | else => unreachable, |
| 6976 | }, | 7040 | }, |
| 6977 | .And => switch (scalar_ty.zigTypeTag(zcu)) { | 7041 | .And => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6978 | .Bool => Value.true, | 7042 | .Bool => Value.true, |
| 6979 | .Int => switch (scalar_ty.intInfo(zcu).signedness) { | 7043 | .Int => switch (scalar_ty.intInfo(zcu).signedness) { |
| 6980 | .unsigned => try scalar_ty.maxIntScalar(zcu, scalar_ty), | 7044 | .unsigned => try scalar_ty.maxIntScalar(pt, scalar_ty), |
| 6981 | .signed => try zcu.intValue(scalar_ty, -1), | 7045 | .signed => try pt.intValue(scalar_ty, -1), |
| 6982 | }, | 7046 | }, |
| 6983 | else => unreachable, | 7047 | else => unreachable, |
| 6984 | }, | 7048 | }, |
| 6985 | .Add => switch (scalar_ty.zigTypeTag(zcu)) { | 7049 | .Add => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6986 | .Int => try zcu.intValue(scalar_ty, 0), | 7050 | .Int => try pt.intValue(scalar_ty, 0), |
| 6987 | .Float => try zcu.floatValue(scalar_ty, 0.0), | 7051 | .Float => try pt.floatValue(scalar_ty, 0.0), |
| 6988 | else => unreachable, | 7052 | else => unreachable, |
| 6989 | }, | 7053 | }, |
| 6990 | .Mul => switch (scalar_ty.zigTypeTag(zcu)) { | 7054 | .Mul => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6991 | .Int => try zcu.intValue(scalar_ty, 1), | 7055 | .Int => try pt.intValue(scalar_ty, 1), |
| 6992 | .Float => try zcu.floatValue(scalar_ty, 1.0), | 7056 | .Float => try pt.floatValue(scalar_ty, 1.0), |
| 6993 | else => unreachable, | 7057 | else => unreachable, |
| 6994 | }, | 7058 | }, |
| 6995 | .Min => switch (scalar_ty.zigTypeTag(zcu)) { | 7059 | .Min => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6996 | .Bool => Value.true, | 7060 | .Bool => Value.true, |
| 6997 | .Int => try scalar_ty.maxIntScalar(zcu, scalar_ty), | 7061 | .Int => try scalar_ty.maxIntScalar(pt, scalar_ty), |
| 6998 | .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)), | 7062 | .Float => try pt.floatValue(scalar_ty, std.math.nan(f128)), |
| 6999 | else => unreachable, | 7063 | else => unreachable, |
| 7000 | }, | 7064 | }, |
| 7001 | .Max => switch (scalar_ty.zigTypeTag(zcu)) { | 7065 | .Max => switch (scalar_ty.zigTypeTag(zcu)) { |
| 7002 | .Bool => Value.false, | 7066 | .Bool => Value.false, |
| 7003 | .Int => try scalar_ty.minIntScalar(zcu, scalar_ty), | 7067 | .Int => try scalar_ty.minIntScalar(pt, scalar_ty), |
| 7004 | .Float => try zcu.floatValue(scalar_ty, std.math.nan(f128)), | 7068 | .Float => try pt.floatValue(scalar_ty, std.math.nan(f128)), |
| 7005 | else => unreachable, | 7069 | else => unreachable, |
| 7006 | }, | 7070 | }, |
| 7007 | }, .Initializer); | 7071 | }, .Initializer); |
| ... | @@ -7046,7 +7110,8 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7046,7 +7110,8 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7046 | } | 7110 | } |
| 7047 | 7111 | ||
| 7048 | fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | 7112 | fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7049 | const zcu = f.object.dg.zcu; | 7113 | const pt = f.object.dg.pt; |
| 7114 | const zcu = pt.zcu; | ||
| 7050 | const ip = &zcu.intern_pool; | 7115 | const ip = &zcu.intern_pool; |
| 7051 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 7116 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7052 | const inst_ty = f.typeOfIndex(inst); | 7117 | const inst_ty = f.typeOfIndex(inst); |
| ... | @@ -7096,7 +7161,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7096,7 +7161,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7096 | var field_it = loaded_struct.iterateRuntimeOrder(ip); | 7161 | var field_it = loaded_struct.iterateRuntimeOrder(ip); |
| 7097 | while (field_it.next()) |field_index| { | 7162 | while (field_it.next()) |field_index| { |
| 7098 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 7163 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 7099 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 7164 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 7100 | 7165 | ||
| 7101 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); | 7166 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); |
| 7102 | try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| | 7167 | try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | @@ -7113,7 +7178,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7113,7 +7178,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7113 | try writer.writeAll(" = "); | 7178 | try writer.writeAll(" = "); |
| 7114 | const int_info = inst_ty.intInfo(zcu); | 7179 | const int_info = inst_ty.intInfo(zcu); |
| 7115 | 7180 | ||
| 7116 | const bit_offset_ty = try zcu.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); | 7181 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); |
| 7117 | 7182 | ||
| 7118 | var bit_offset: u64 = 0; | 7183 | var bit_offset: u64 = 0; |
| 7119 | 7184 | ||
| ... | @@ -7121,7 +7186,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7121,7 +7186,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7121 | for (0..elements.len) |field_index| { | 7186 | for (0..elements.len) |field_index| { |
| 7122 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; | 7187 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; |
| 7123 | const field_ty = inst_ty.structFieldType(field_index, zcu); | 7188 | const field_ty = inst_ty.structFieldType(field_index, zcu); |
| 7124 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 7189 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 7125 | 7190 | ||
| 7126 | if (!empty) { | 7191 | if (!empty) { |
| 7127 | try writer.writeAll("zig_or_"); | 7192 | try writer.writeAll("zig_or_"); |
| ... | @@ -7134,7 +7199,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7134,7 +7199,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7134 | for (resolved_elements, 0..) |element, field_index| { | 7199 | for (resolved_elements, 0..) |element, field_index| { |
| 7135 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; | 7200 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; |
| 7136 | const field_ty = inst_ty.structFieldType(field_index, zcu); | 7201 | const field_ty = inst_ty.structFieldType(field_index, zcu); |
| 7137 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 7202 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 7138 | 7203 | ||
| 7139 | if (!empty) try writer.writeAll(", "); | 7204 | if (!empty) try writer.writeAll(", "); |
| 7140 | // TODO: Skip this entire shift if val is 0? | 7205 | // TODO: Skip this entire shift if val is 0? |
| ... | @@ -7160,13 +7225,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7160,13 +7225,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7160 | } | 7225 | } |
| 7161 | 7226 | ||
| 7162 | try writer.print(", {}", .{ | 7227 | try writer.print(", {}", .{ |
| 7163 | try f.fmtIntLiteral(try zcu.intValue(bit_offset_ty, bit_offset)), | 7228 | try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)), |
| 7164 | }); | 7229 | }); |
| 7165 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits); | 7230 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits); |
| 7166 | try writer.writeByte(')'); | 7231 | try writer.writeByte(')'); |
| 7167 | if (!empty) try writer.writeByte(')'); | 7232 | if (!empty) try writer.writeByte(')'); |
| 7168 | 7233 | ||
| 7169 | bit_offset += field_ty.bitSize(zcu); | 7234 | bit_offset += field_ty.bitSize(pt); |
| 7170 | empty = false; | 7235 | empty = false; |
| 7171 | } | 7236 | } |
| 7172 | try writer.writeAll(";\n"); | 7237 | try writer.writeAll(";\n"); |
| ... | @@ -7176,7 +7241,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7176,7 +7241,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7176 | .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| { | 7241 | .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| { |
| 7177 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; | 7242 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; |
| 7178 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); | 7243 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); |
| 7179 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 7244 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 7180 | 7245 | ||
| 7181 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); | 7246 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); |
| 7182 | try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| | 7247 | try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | @@ -7194,7 +7259,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7194,7 +7259,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7194 | } | 7259 | } |
| 7195 | 7260 | ||
| 7196 | fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | 7261 | fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7197 | const zcu = f.object.dg.zcu; | 7262 | const pt = f.object.dg.pt; |
| 7263 | const zcu = pt.zcu; | ||
| 7198 | const ip = &zcu.intern_pool; | 7264 | const ip = &zcu.intern_pool; |
| 7199 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 7265 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7200 | const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data; | 7266 | const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| ... | @@ -7211,15 +7277,15 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7211,15 +7277,15 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7211 | if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload); | 7277 | if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload); |
| 7212 | 7278 | ||
| 7213 | const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: { | 7279 | const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: { |
| 7214 | const layout = union_ty.unionGetLayout(zcu); | 7280 | const layout = union_ty.unionGetLayout(pt); |
| 7215 | if (layout.tag_size != 0) { | 7281 | if (layout.tag_size != 0) { |
| 7216 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; | 7282 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; |
| 7217 | const tag_val = try zcu.enumValueFieldIndex(tag_ty, field_index); | 7283 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 7218 | 7284 | ||
| 7219 | const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete)); | 7285 | const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete)); |
| 7220 | try f.writeCValueMember(writer, local, .{ .identifier = "tag" }); | 7286 | try f.writeCValueMember(writer, local, .{ .identifier = "tag" }); |
| 7221 | try a.assign(f, writer); | 7287 | try a.assign(f, writer); |
| 7222 | try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, zcu))}); | 7288 | try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))}); |
| 7223 | try a.end(f, writer); | 7289 | try a.end(f, writer); |
| 7224 | } | 7290 | } |
| 7225 | break :field .{ .payload_identifier = field_name.toSlice(ip) }; | 7291 | break :field .{ .payload_identifier = field_name.toSlice(ip) }; |
| ... | @@ -7234,7 +7300,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7234,7 +7300,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7234 | } | 7300 | } |
| 7235 | 7301 | ||
| 7236 | fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { | 7302 | fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7237 | const zcu = f.object.dg.zcu; | 7303 | const pt = f.object.dg.pt; |
| 7304 | const zcu = pt.zcu; | ||
| 7238 | const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; | 7305 | const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; |
| 7239 | 7306 | ||
| 7240 | const ptr_ty = f.typeOf(prefetch.ptr); | 7307 | const ptr_ty = f.typeOf(prefetch.ptr); |
| ... | @@ -7291,7 +7358,8 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7291,7 +7358,8 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7291 | } | 7358 | } |
| 7292 | 7359 | ||
| 7293 | fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { | 7360 | fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7294 | const zcu = f.object.dg.zcu; | 7361 | const pt = f.object.dg.pt; |
| 7362 | const zcu = pt.zcu; | ||
| 7295 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 7363 | const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 7296 | const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data; | 7364 | const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data; |
| 7297 | 7365 | ||
| ... | @@ -7326,7 +7394,8 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7326,7 +7394,8 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7326 | } | 7394 | } |
| 7327 | 7395 | ||
| 7328 | fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue { | 7396 | fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7329 | const zcu = f.object.dg.zcu; | 7397 | const pt = f.object.dg.pt; |
| 7398 | const zcu = pt.zcu; | ||
| 7330 | const inst_ty = f.typeOfIndex(inst); | 7399 | const inst_ty = f.typeOfIndex(inst); |
| 7331 | const decl_index = f.object.dg.pass.decl; | 7400 | const decl_index = f.object.dg.pass.decl; |
| 7332 | const decl = zcu.declPtr(decl_index); | 7401 | const decl = zcu.declPtr(decl_index); |
| ... | @@ -7699,7 +7768,8 @@ fn formatIntLiteral( | ... | @@ -7699,7 +7768,8 @@ fn formatIntLiteral( |
| 7699 | options: std.fmt.FormatOptions, | 7768 | options: std.fmt.FormatOptions, |
| 7700 | writer: anytype, | 7769 | writer: anytype, |
| 7701 | ) @TypeOf(writer).Error!void { | 7770 | ) @TypeOf(writer).Error!void { |
| 7702 | const zcu = data.dg.zcu; | 7771 | const pt = data.dg.pt; |
| 7772 | const zcu = pt.zcu; | ||
| 7703 | const target = &data.dg.mod.resolved_target.result; | 7773 | const target = &data.dg.mod.resolved_target.result; |
| 7704 | const ctype_pool = &data.dg.ctype_pool; | 7774 | const ctype_pool = &data.dg.ctype_pool; |
| 7705 | 7775 | ||
| ... | @@ -7732,7 +7802,7 @@ fn formatIntLiteral( | ... | @@ -7732,7 +7802,7 @@ fn formatIntLiteral( |
| 7732 | }; | 7802 | }; |
| 7733 | undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits); | 7803 | undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits); |
| 7734 | break :blk undef_int.toConst(); | 7804 | break :blk undef_int.toConst(); |
| 7735 | } else data.val.toBigInt(&int_buf, zcu); | 7805 | } else data.val.toBigInt(&int_buf, pt); |
| 7736 | assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits)); | 7806 | assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits)); |
| 7737 | 7807 | ||
| 7738 | const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8); | 7808 | const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8); |
| ... | @@ -7866,7 +7936,7 @@ fn formatIntLiteral( | ... | @@ -7866,7 +7936,7 @@ fn formatIntLiteral( |
| 7866 | .int_info = c_limb_int_info, | 7936 | .int_info = c_limb_int_info, |
| 7867 | .kind = data.kind, | 7937 | .kind = data.kind, |
| 7868 | .ctype = c_limb_ctype, | 7938 | .ctype = c_limb_ctype, |
| 7869 | .val = try zcu.intValue_big(Type.comptime_int, c_limb_mut.toConst()), | 7939 | .val = try pt.intValue_big(Type.comptime_int, c_limb_mut.toConst()), |
| 7870 | }, fmt, options, writer); | 7940 | }, fmt, options, writer); |
| 7871 | } | 7941 | } |
| 7872 | } | 7942 | } |
| ... | @@ -7940,17 +8010,18 @@ const Vectorize = struct { | ... | @@ -7940,17 +8010,18 @@ const Vectorize = struct { |
| 7940 | index: CValue = .none, | 8010 | index: CValue = .none, |
| 7941 | 8011 | ||
| 7942 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize { | 8012 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize { |
| 7943 | const zcu = f.object.dg.zcu; | 8013 | const pt = f.object.dg.pt; |
| 8014 | const zcu = pt.zcu; | ||
| 7944 | return if (ty.zigTypeTag(zcu) == .Vector) index: { | 8015 | return if (ty.zigTypeTag(zcu) == .Vector) index: { |
| 7945 | const local = try f.allocLocal(inst, Type.usize); | 8016 | const local = try f.allocLocal(inst, Type.usize); |
| 7946 | 8017 | ||
| 7947 | try writer.writeAll("for ("); | 8018 | try writer.writeAll("for ("); |
| 7948 | try f.writeCValue(writer, local, .Other); | 8019 | try f.writeCValue(writer, local, .Other); |
| 7949 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 0))}); | 8020 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 0))}); |
| 7950 | try f.writeCValue(writer, local, .Other); | 8021 | try f.writeCValue(writer, local, .Other); |
| 7951 | try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, ty.vectorLen(zcu)))}); | 8022 | try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, ty.vectorLen(zcu)))}); |
| 7952 | try f.writeCValue(writer, local, .Other); | 8023 | try f.writeCValue(writer, local, .Other); |
| 7953 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try zcu.intValue(Type.usize, 1))}); | 8024 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(try pt.intValue(Type.usize, 1))}); |
| 7954 | f.object.indent_writer.pushIndent(); | 8025 | f.object.indent_writer.pushIndent(); |
| 7955 | 8026 | ||
| 7956 | break :index .{ .index = local }; | 8027 | break :index .{ .index = local }; |
| ... | @@ -7974,10 +8045,10 @@ const Vectorize = struct { | ... | @@ -7974,10 +8045,10 @@ const Vectorize = struct { |
| 7974 | } | 8045 | } |
| 7975 | }; | 8046 | }; |
| 7976 | 8047 | ||
| 7977 | fn lowersToArray(ty: Type, zcu: *Zcu) bool { | 8048 | fn lowersToArray(ty: Type, pt: Zcu.PerThread) bool { |
| 7978 | return switch (ty.zigTypeTag(zcu)) { | 8049 | return switch (ty.zigTypeTag(pt.zcu)) { |
| 7979 | .Array, .Vector => return true, | 8050 | .Array, .Vector => return true, |
| 7980 | else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null, | 8051 | else => return ty.isAbiInt(pt.zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(pt)))) == null, |
| 7981 | }; | 8052 | }; |
| 7982 | } | 8053 | } |
| 7983 | 8054 |
src/codegen/c/Type.zig+33-33| ... | @@ -1339,11 +1339,11 @@ pub const Pool = struct { | ... | @@ -1339,11 +1339,11 @@ pub const Pool = struct { |
| 1339 | allocator: std.mem.Allocator, | 1339 | allocator: std.mem.Allocator, |
| 1340 | scratch: *std.ArrayListUnmanaged(u32), | 1340 | scratch: *std.ArrayListUnmanaged(u32), |
| 1341 | ty: Type, | 1341 | ty: Type, |
| 1342 | zcu: *Zcu, | 1342 | pt: Zcu.PerThread, |
| 1343 | mod: *Module, | 1343 | mod: *Module, |
| 1344 | kind: Kind, | 1344 | kind: Kind, |
| 1345 | ) !CType { | 1345 | ) !CType { |
| 1346 | const ip = &zcu.intern_pool; | 1346 | const ip = &pt.zcu.intern_pool; |
| 1347 | switch (ty.toIntern()) { | 1347 | switch (ty.toIntern()) { |
| 1348 | .u0_type, | 1348 | .u0_type, |
| 1349 | .i0_type, | 1349 | .i0_type, |
| ... | @@ -1400,7 +1400,7 @@ pub const Pool = struct { | ... | @@ -1400,7 +1400,7 @@ pub const Pool = struct { |
| 1400 | allocator, | 1400 | allocator, |
| 1401 | scratch, | 1401 | scratch, |
| 1402 | Type.fromInterned(ip.loadEnumType(ip_index).tag_ty), | 1402 | Type.fromInterned(ip.loadEnumType(ip_index).tag_ty), |
| 1403 | zcu, | 1403 | pt, |
| 1404 | mod, | 1404 | mod, |
| 1405 | kind, | 1405 | kind, |
| 1406 | ), | 1406 | ), |
| ... | @@ -1409,7 +1409,7 @@ pub const Pool = struct { | ... | @@ -1409,7 +1409,7 @@ pub const Pool = struct { |
| 1409 | .adhoc_inferred_error_set_type, | 1409 | .adhoc_inferred_error_set_type, |
| 1410 | => return pool.fromIntInfo(allocator, .{ | 1410 | => return pool.fromIntInfo(allocator, .{ |
| 1411 | .signedness = .unsigned, | 1411 | .signedness = .unsigned, |
| 1412 | .bits = zcu.errorSetBits(), | 1412 | .bits = pt.zcu.errorSetBits(), |
| 1413 | }, mod, kind), | 1413 | }, mod, kind), |
| 1414 | .manyptr_u8_type, | 1414 | .manyptr_u8_type, |
| 1415 | => return pool.getPointer(allocator, .{ | 1415 | => return pool.getPointer(allocator, .{ |
| ... | @@ -1492,13 +1492,13 @@ pub const Pool = struct { | ... | @@ -1492,13 +1492,13 @@ pub const Pool = struct { |
| 1492 | allocator, | 1492 | allocator, |
| 1493 | scratch, | 1493 | scratch, |
| 1494 | Type.fromInterned(ptr_info.child), | 1494 | Type.fromInterned(ptr_info.child), |
| 1495 | zcu, | 1495 | pt, |
| 1496 | mod, | 1496 | mod, |
| 1497 | .forward, | 1497 | .forward, |
| 1498 | ), | 1498 | ), |
| 1499 | .alignas = AlignAs.fromAlignment(.{ | 1499 | .alignas = AlignAs.fromAlignment(.{ |
| 1500 | .@"align" = ptr_info.flags.alignment, | 1500 | .@"align" = ptr_info.flags.alignment, |
| 1501 | .abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu), | 1501 | .abi = Type.fromInterned(ptr_info.child).abiAlignment(pt), |
| 1502 | }), | 1502 | }), |
| 1503 | }; | 1503 | }; |
| 1504 | break :elem_ctype if (elem.alignas.abiOrder().compare(.gte)) | 1504 | break :elem_ctype if (elem.alignas.abiOrder().compare(.gte)) |
| ... | @@ -1535,7 +1535,7 @@ pub const Pool = struct { | ... | @@ -1535,7 +1535,7 @@ pub const Pool = struct { |
| 1535 | allocator, | 1535 | allocator, |
| 1536 | scratch, | 1536 | scratch, |
| 1537 | Type.fromInterned(ip.slicePtrType(ip_index)), | 1537 | Type.fromInterned(ip.slicePtrType(ip_index)), |
| 1538 | zcu, | 1538 | pt, |
| 1539 | mod, | 1539 | mod, |
| 1540 | kind, | 1540 | kind, |
| 1541 | ), | 1541 | ), |
| ... | @@ -1560,7 +1560,7 @@ pub const Pool = struct { | ... | @@ -1560,7 +1560,7 @@ pub const Pool = struct { |
| 1560 | allocator, | 1560 | allocator, |
| 1561 | scratch, | 1561 | scratch, |
| 1562 | elem_type, | 1562 | elem_type, |
| 1563 | zcu, | 1563 | pt, |
| 1564 | mod, | 1564 | mod, |
| 1565 | kind.noParameter(), | 1565 | kind.noParameter(), |
| 1566 | ); | 1566 | ); |
| ... | @@ -1574,7 +1574,7 @@ pub const Pool = struct { | ... | @@ -1574,7 +1574,7 @@ pub const Pool = struct { |
| 1574 | .{ | 1574 | .{ |
| 1575 | .name = .{ .index = .array }, | 1575 | .name = .{ .index = .array }, |
| 1576 | .ctype = array_ctype, | 1576 | .ctype = array_ctype, |
| 1577 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)), | 1577 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)), |
| 1578 | }, | 1578 | }, |
| 1579 | }; | 1579 | }; |
| 1580 | return pool.fromFields(allocator, .@"struct", &fields, kind); | 1580 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | @@ -1586,7 +1586,7 @@ pub const Pool = struct { | ... | @@ -1586,7 +1586,7 @@ pub const Pool = struct { |
| 1586 | allocator, | 1586 | allocator, |
| 1587 | scratch, | 1587 | scratch, |
| 1588 | elem_type, | 1588 | elem_type, |
| 1589 | zcu, | 1589 | pt, |
| 1590 | mod, | 1590 | mod, |
| 1591 | kind.noParameter(), | 1591 | kind.noParameter(), |
| 1592 | ); | 1592 | ); |
| ... | @@ -1600,7 +1600,7 @@ pub const Pool = struct { | ... | @@ -1600,7 +1600,7 @@ pub const Pool = struct { |
| 1600 | .{ | 1600 | .{ |
| 1601 | .name = .{ .index = .array }, | 1601 | .name = .{ .index = .array }, |
| 1602 | .ctype = vector_ctype, | 1602 | .ctype = vector_ctype, |
| 1603 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)), | 1603 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)), |
| 1604 | }, | 1604 | }, |
| 1605 | }; | 1605 | }; |
| 1606 | return pool.fromFields(allocator, .@"struct", &fields, kind); | 1606 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | @@ -1611,7 +1611,7 @@ pub const Pool = struct { | ... | @@ -1611,7 +1611,7 @@ pub const Pool = struct { |
| 1611 | allocator, | 1611 | allocator, |
| 1612 | scratch, | 1612 | scratch, |
| 1613 | Type.fromInterned(payload_type), | 1613 | Type.fromInterned(payload_type), |
| 1614 | zcu, | 1614 | pt, |
| 1615 | mod, | 1615 | mod, |
| 1616 | kind.noParameter(), | 1616 | kind.noParameter(), |
| 1617 | ); | 1617 | ); |
| ... | @@ -1635,7 +1635,7 @@ pub const Pool = struct { | ... | @@ -1635,7 +1635,7 @@ pub const Pool = struct { |
| 1635 | .name = .{ .index = .payload }, | 1635 | .name = .{ .index = .payload }, |
| 1636 | .ctype = payload_ctype, | 1636 | .ctype = payload_ctype, |
| 1637 | .alignas = AlignAs.fromAbiAlignment( | 1637 | .alignas = AlignAs.fromAbiAlignment( |
| 1638 | Type.fromInterned(payload_type).abiAlignment(zcu), | 1638 | Type.fromInterned(payload_type).abiAlignment(pt), |
| 1639 | ), | 1639 | ), |
| 1640 | }, | 1640 | }, |
| 1641 | }; | 1641 | }; |
| ... | @@ -1643,7 +1643,7 @@ pub const Pool = struct { | ... | @@ -1643,7 +1643,7 @@ pub const Pool = struct { |
| 1643 | }, | 1643 | }, |
| 1644 | .anyframe_type => unreachable, | 1644 | .anyframe_type => unreachable, |
| 1645 | .error_union_type => |error_union_info| { | 1645 | .error_union_type => |error_union_info| { |
| 1646 | const error_set_bits = zcu.errorSetBits(); | 1646 | const error_set_bits = pt.zcu.errorSetBits(); |
| 1647 | const error_set_ctype = try pool.fromIntInfo(allocator, .{ | 1647 | const error_set_ctype = try pool.fromIntInfo(allocator, .{ |
| 1648 | .signedness = .unsigned, | 1648 | .signedness = .unsigned, |
| 1649 | .bits = error_set_bits, | 1649 | .bits = error_set_bits, |
| ... | @@ -1654,7 +1654,7 @@ pub const Pool = struct { | ... | @@ -1654,7 +1654,7 @@ pub const Pool = struct { |
| 1654 | allocator, | 1654 | allocator, |
| 1655 | scratch, | 1655 | scratch, |
| 1656 | payload_type, | 1656 | payload_type, |
| 1657 | zcu, | 1657 | pt, |
| 1658 | mod, | 1658 | mod, |
| 1659 | kind.noParameter(), | 1659 | kind.noParameter(), |
| 1660 | ); | 1660 | ); |
| ... | @@ -1671,7 +1671,7 @@ pub const Pool = struct { | ... | @@ -1671,7 +1671,7 @@ pub const Pool = struct { |
| 1671 | .{ | 1671 | .{ |
| 1672 | .name = .{ .index = .payload }, | 1672 | .name = .{ .index = .payload }, |
| 1673 | .ctype = payload_ctype, | 1673 | .ctype = payload_ctype, |
| 1674 | .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)), | 1674 | .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(pt)), |
| 1675 | }, | 1675 | }, |
| 1676 | }; | 1676 | }; |
| 1677 | return pool.fromFields(allocator, .@"struct", &fields, kind); | 1677 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | @@ -1685,7 +1685,7 @@ pub const Pool = struct { | ... | @@ -1685,7 +1685,7 @@ pub const Pool = struct { |
| 1685 | .tag = .@"struct", | 1685 | .tag = .@"struct", |
| 1686 | .name = .{ .owner_decl = loaded_struct.decl.unwrap().? }, | 1686 | .name = .{ .owner_decl = loaded_struct.decl.unwrap().? }, |
| 1687 | }); | 1687 | }); |
| 1688 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu)) | 1688 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 1689 | fwd_decl | 1689 | fwd_decl |
| 1690 | else | 1690 | else |
| 1691 | CType.void; | 1691 | CType.void; |
| ... | @@ -1706,7 +1706,7 @@ pub const Pool = struct { | ... | @@ -1706,7 +1706,7 @@ pub const Pool = struct { |
| 1706 | allocator, | 1706 | allocator, |
| 1707 | scratch, | 1707 | scratch, |
| 1708 | field_type, | 1708 | field_type, |
| 1709 | zcu, | 1709 | pt, |
| 1710 | mod, | 1710 | mod, |
| 1711 | kind.noParameter(), | 1711 | kind.noParameter(), |
| 1712 | ); | 1712 | ); |
| ... | @@ -1718,7 +1718,7 @@ pub const Pool = struct { | ... | @@ -1718,7 +1718,7 @@ pub const Pool = struct { |
| 1718 | String.fromUnnamed(@intCast(field_index)); | 1718 | String.fromUnnamed(@intCast(field_index)); |
| 1719 | const field_alignas = AlignAs.fromAlignment(.{ | 1719 | const field_alignas = AlignAs.fromAlignment(.{ |
| 1720 | .@"align" = loaded_struct.fieldAlign(ip, field_index), | 1720 | .@"align" = loaded_struct.fieldAlign(ip, field_index), |
| 1721 | .abi = field_type.abiAlignment(zcu), | 1721 | .abi = field_type.abiAlignment(pt), |
| 1722 | }); | 1722 | }); |
| 1723 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ | 1723 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ |
| 1724 | .name = field_name.index, | 1724 | .name = field_name.index, |
| ... | @@ -1745,7 +1745,7 @@ pub const Pool = struct { | ... | @@ -1745,7 +1745,7 @@ pub const Pool = struct { |
| 1745 | allocator, | 1745 | allocator, |
| 1746 | scratch, | 1746 | scratch, |
| 1747 | Type.fromInterned(loaded_struct.backingIntType(ip).*), | 1747 | Type.fromInterned(loaded_struct.backingIntType(ip).*), |
| 1748 | zcu, | 1748 | pt, |
| 1749 | mod, | 1749 | mod, |
| 1750 | kind, | 1750 | kind, |
| 1751 | ), | 1751 | ), |
| ... | @@ -1766,7 +1766,7 @@ pub const Pool = struct { | ... | @@ -1766,7 +1766,7 @@ pub const Pool = struct { |
| 1766 | allocator, | 1766 | allocator, |
| 1767 | scratch, | 1767 | scratch, |
| 1768 | field_type, | 1768 | field_type, |
| 1769 | zcu, | 1769 | pt, |
| 1770 | mod, | 1770 | mod, |
| 1771 | kind.noParameter(), | 1771 | kind.noParameter(), |
| 1772 | ); | 1772 | ); |
| ... | @@ -1780,7 +1780,7 @@ pub const Pool = struct { | ... | @@ -1780,7 +1780,7 @@ pub const Pool = struct { |
| 1780 | .name = field_name.index, | 1780 | .name = field_name.index, |
| 1781 | .ctype = field_ctype.index, | 1781 | .ctype = field_ctype.index, |
| 1782 | .flags = .{ .alignas = AlignAs.fromAbiAlignment( | 1782 | .flags = .{ .alignas = AlignAs.fromAbiAlignment( |
| 1783 | field_type.abiAlignment(zcu), | 1783 | field_type.abiAlignment(pt), |
| 1784 | ) }, | 1784 | ) }, |
| 1785 | }); | 1785 | }); |
| 1786 | } | 1786 | } |
| ... | @@ -1806,7 +1806,7 @@ pub const Pool = struct { | ... | @@ -1806,7 +1806,7 @@ pub const Pool = struct { |
| 1806 | extra_index, | 1806 | extra_index, |
| 1807 | ); | 1807 | ); |
| 1808 | } | 1808 | } |
| 1809 | const fwd_decl = try pool.fromType(allocator, scratch, ty, zcu, mod, .forward); | 1809 | const fwd_decl = try pool.fromType(allocator, scratch, ty, pt, mod, .forward); |
| 1810 | try pool.ensureUnusedCapacity(allocator, 1); | 1810 | try pool.ensureUnusedCapacity(allocator, 1); |
| 1811 | const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{ | 1811 | const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{ |
| 1812 | .fwd_decl = fwd_decl.index, | 1812 | .fwd_decl = fwd_decl.index, |
| ... | @@ -1824,7 +1824,7 @@ pub const Pool = struct { | ... | @@ -1824,7 +1824,7 @@ pub const Pool = struct { |
| 1824 | .tag = if (has_tag) .@"struct" else .@"union", | 1824 | .tag = if (has_tag) .@"struct" else .@"union", |
| 1825 | .name = .{ .owner_decl = loaded_union.decl }, | 1825 | .name = .{ .owner_decl = loaded_union.decl }, |
| 1826 | }); | 1826 | }); |
| 1827 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu)) | 1827 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 1828 | fwd_decl | 1828 | fwd_decl |
| 1829 | else | 1829 | else |
| 1830 | CType.void; | 1830 | CType.void; |
| ... | @@ -1847,7 +1847,7 @@ pub const Pool = struct { | ... | @@ -1847,7 +1847,7 @@ pub const Pool = struct { |
| 1847 | allocator, | 1847 | allocator, |
| 1848 | scratch, | 1848 | scratch, |
| 1849 | field_type, | 1849 | field_type, |
| 1850 | zcu, | 1850 | pt, |
| 1851 | mod, | 1851 | mod, |
| 1852 | kind.noParameter(), | 1852 | kind.noParameter(), |
| 1853 | ); | 1853 | ); |
| ... | @@ -1858,7 +1858,7 @@ pub const Pool = struct { | ... | @@ -1858,7 +1858,7 @@ pub const Pool = struct { |
| 1858 | ); | 1858 | ); |
| 1859 | const field_alignas = AlignAs.fromAlignment(.{ | 1859 | const field_alignas = AlignAs.fromAlignment(.{ |
| 1860 | .@"align" = loaded_union.fieldAlign(ip, field_index), | 1860 | .@"align" = loaded_union.fieldAlign(ip, field_index), |
| 1861 | .abi = field_type.abiAlignment(zcu), | 1861 | .abi = field_type.abiAlignment(pt), |
| 1862 | }); | 1862 | }); |
| 1863 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ | 1863 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ |
| 1864 | .name = field_name.index, | 1864 | .name = field_name.index, |
| ... | @@ -1895,7 +1895,7 @@ pub const Pool = struct { | ... | @@ -1895,7 +1895,7 @@ pub const Pool = struct { |
| 1895 | allocator, | 1895 | allocator, |
| 1896 | scratch, | 1896 | scratch, |
| 1897 | tag_type, | 1897 | tag_type, |
| 1898 | zcu, | 1898 | pt, |
| 1899 | mod, | 1899 | mod, |
| 1900 | kind.noParameter(), | 1900 | kind.noParameter(), |
| 1901 | ); | 1901 | ); |
| ... | @@ -1903,7 +1903,7 @@ pub const Pool = struct { | ... | @@ -1903,7 +1903,7 @@ pub const Pool = struct { |
| 1903 | struct_fields[struct_fields_len] = .{ | 1903 | struct_fields[struct_fields_len] = .{ |
| 1904 | .name = .{ .index = .tag }, | 1904 | .name = .{ .index = .tag }, |
| 1905 | .ctype = tag_ctype, | 1905 | .ctype = tag_ctype, |
| 1906 | .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)), | 1906 | .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(pt)), |
| 1907 | }; | 1907 | }; |
| 1908 | struct_fields_len += 1; | 1908 | struct_fields_len += 1; |
| 1909 | } | 1909 | } |
| ... | @@ -1951,7 +1951,7 @@ pub const Pool = struct { | ... | @@ -1951,7 +1951,7 @@ pub const Pool = struct { |
| 1951 | }, | 1951 | }, |
| 1952 | .@"packed" => return pool.fromIntInfo(allocator, .{ | 1952 | .@"packed" => return pool.fromIntInfo(allocator, .{ |
| 1953 | .signedness = .unsigned, | 1953 | .signedness = .unsigned, |
| 1954 | .bits = @intCast(ty.bitSize(zcu)), | 1954 | .bits = @intCast(ty.bitSize(pt)), |
| 1955 | }, mod, kind), | 1955 | }, mod, kind), |
| 1956 | } | 1956 | } |
| 1957 | }, | 1957 | }, |
| ... | @@ -1960,7 +1960,7 @@ pub const Pool = struct { | ... | @@ -1960,7 +1960,7 @@ pub const Pool = struct { |
| 1960 | allocator, | 1960 | allocator, |
| 1961 | scratch, | 1961 | scratch, |
| 1962 | Type.fromInterned(ip.loadEnumType(ip_index).tag_ty), | 1962 | Type.fromInterned(ip.loadEnumType(ip_index).tag_ty), |
| 1963 | zcu, | 1963 | pt, |
| 1964 | mod, | 1964 | mod, |
| 1965 | kind, | 1965 | kind, |
| 1966 | ), | 1966 | ), |
| ... | @@ -1975,7 +1975,7 @@ pub const Pool = struct { | ... | @@ -1975,7 +1975,7 @@ pub const Pool = struct { |
| 1975 | allocator, | 1975 | allocator, |
| 1976 | scratch, | 1976 | scratch, |
| 1977 | return_type, | 1977 | return_type, |
| 1978 | zcu, | 1978 | pt, |
| 1979 | mod, | 1979 | mod, |
| 1980 | kind.asParameter(), | 1980 | kind.asParameter(), |
| 1981 | ) else CType.void; | 1981 | ) else CType.void; |
| ... | @@ -1987,7 +1987,7 @@ pub const Pool = struct { | ... | @@ -1987,7 +1987,7 @@ pub const Pool = struct { |
| 1987 | allocator, | 1987 | allocator, |
| 1988 | scratch, | 1988 | scratch, |
| 1989 | param_type, | 1989 | param_type, |
| 1990 | zcu, | 1990 | pt, |
| 1991 | mod, | 1991 | mod, |
| 1992 | kind.asParameter(), | 1992 | kind.asParameter(), |
| 1993 | ); | 1993 | ); |
| ... | @@ -2011,7 +2011,7 @@ pub const Pool = struct { | ... | @@ -2011,7 +2011,7 @@ pub const Pool = struct { |
| 2011 | .inferred_error_set_type, | 2011 | .inferred_error_set_type, |
| 2012 | => return pool.fromIntInfo(allocator, .{ | 2012 | => return pool.fromIntInfo(allocator, .{ |
| 2013 | .signedness = .unsigned, | 2013 | .signedness = .unsigned, |
| 2014 | .bits = zcu.errorSetBits(), | 2014 | .bits = pt.zcu.errorSetBits(), |
| 2015 | }, mod, kind), | 2015 | }, mod, kind), |
| 2016 | 2016 | ||
| 2017 | .undef, | 2017 | .undef, |
src/codegen/llvm.zig+751-680| ... | @@ -15,8 +15,6 @@ const link = @import("../link.zig"); | ... | @@ -15,8 +15,6 @@ const link = @import("../link.zig"); |
| 15 | const Compilation = @import("../Compilation.zig"); | 15 | const Compilation = @import("../Compilation.zig"); |
| 16 | const build_options = @import("build_options"); | 16 | const build_options = @import("build_options"); |
| 17 | const Zcu = @import("../Zcu.zig"); | 17 | const Zcu = @import("../Zcu.zig"); |
| 18 | /// Deprecated. | ||
| 19 | const Module = Zcu; | ||
| 20 | const InternPool = @import("../InternPool.zig"); | 18 | const InternPool = @import("../InternPool.zig"); |
| 21 | const Package = @import("../Package.zig"); | 19 | const Package = @import("../Package.zig"); |
| 22 | const Air = @import("../Air.zig"); | 20 | const Air = @import("../Air.zig"); |
| ... | @@ -810,7 +808,7 @@ pub const Object = struct { | ... | @@ -810,7 +808,7 @@ pub const Object = struct { |
| 810 | gpa: Allocator, | 808 | gpa: Allocator, |
| 811 | builder: Builder, | 809 | builder: Builder, |
| 812 | 810 | ||
| 813 | module: *Module, | 811 | pt: Zcu.PerThread, |
| 814 | 812 | ||
| 815 | debug_compile_unit: Builder.Metadata, | 813 | debug_compile_unit: Builder.Metadata, |
| 816 | 814 | ||
| ... | @@ -820,7 +818,7 @@ pub const Object = struct { | ... | @@ -820,7 +818,7 @@ pub const Object = struct { |
| 820 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), | 818 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), |
| 821 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), | 819 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), |
| 822 | 820 | ||
| 823 | debug_file_map: std.AutoHashMapUnmanaged(*const Module.File, Builder.Metadata), | 821 | debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata), |
| 824 | debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), | 822 | debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata), |
| 825 | 823 | ||
| 826 | debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata), | 824 | debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata), |
| ... | @@ -992,7 +990,10 @@ pub const Object = struct { | ... | @@ -992,7 +990,10 @@ pub const Object = struct { |
| 992 | obj.* = .{ | 990 | obj.* = .{ |
| 993 | .gpa = gpa, | 991 | .gpa = gpa, |
| 994 | .builder = builder, | 992 | .builder = builder, |
| 995 | .module = comp.module.?, | 993 | .pt = .{ |
| 994 | .zcu = comp.module.?, | ||
| 995 | .tid = .main, | ||
| 996 | }, | ||
| 996 | .debug_compile_unit = debug_compile_unit, | 997 | .debug_compile_unit = debug_compile_unit, |
| 997 | .debug_enums_fwd_ref = debug_enums_fwd_ref, | 998 | .debug_enums_fwd_ref = debug_enums_fwd_ref, |
| 998 | .debug_globals_fwd_ref = debug_globals_fwd_ref, | 999 | .debug_globals_fwd_ref = debug_globals_fwd_ref, |
| ... | @@ -1033,7 +1034,8 @@ pub const Object = struct { | ... | @@ -1033,7 +1034,8 @@ pub const Object = struct { |
| 1033 | // If o.error_name_table is null, then it was not referenced by any instructions. | 1034 | // If o.error_name_table is null, then it was not referenced by any instructions. |
| 1034 | if (o.error_name_table == .none) return; | 1035 | if (o.error_name_table == .none) return; |
| 1035 | 1036 | ||
| 1036 | const mod = o.module; | 1037 | const pt = o.pt; |
| 1038 | const mod = pt.zcu; | ||
| 1037 | 1039 | ||
| 1038 | const error_name_list = mod.global_error_set.keys(); | 1040 | const error_name_list = mod.global_error_set.keys(); |
| 1039 | const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len); | 1041 | const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len); |
| ... | @@ -1072,7 +1074,7 @@ pub const Object = struct { | ... | @@ -1072,7 +1074,7 @@ pub const Object = struct { |
| 1072 | table_variable_index.setMutability(.constant, &o.builder); | 1074 | table_variable_index.setMutability(.constant, &o.builder); |
| 1073 | table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 1075 | table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 1074 | table_variable_index.setAlignment( | 1076 | table_variable_index.setAlignment( |
| 1075 | slice_ty.abiAlignment(mod).toLlvm(), | 1077 | slice_ty.abiAlignment(pt).toLlvm(), |
| 1076 | &o.builder, | 1078 | &o.builder, |
| 1077 | ); | 1079 | ); |
| 1078 | 1080 | ||
| ... | @@ -1083,8 +1085,7 @@ pub const Object = struct { | ... | @@ -1083,8 +1085,7 @@ pub const Object = struct { |
| 1083 | // If there is no such function in the module, it means the source code does not need it. | 1085 | // If there is no such function in the module, it means the source code does not need it. |
| 1084 | const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return; | 1086 | const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return; |
| 1085 | const llvm_fn = o.builder.getGlobal(name) orelse return; | 1087 | const llvm_fn = o.builder.getGlobal(name) orelse return; |
| 1086 | const mod = o.module; | 1088 | const errors_len = o.pt.zcu.global_error_set.count(); |
| 1087 | const errors_len = mod.global_error_set.count(); | ||
| 1088 | 1089 | ||
| 1089 | var wip = try Builder.WipFunction.init(&o.builder, .{ | 1090 | var wip = try Builder.WipFunction.init(&o.builder, .{ |
| 1090 | .function = llvm_fn.ptrConst(&o.builder).kind.function, | 1091 | .function = llvm_fn.ptrConst(&o.builder).kind.function, |
| ... | @@ -1106,10 +1107,8 @@ pub const Object = struct { | ... | @@ -1106,10 +1107,8 @@ pub const Object = struct { |
| 1106 | } | 1107 | } |
| 1107 | 1108 | ||
| 1108 | fn genModuleLevelAssembly(object: *Object) !void { | 1109 | fn genModuleLevelAssembly(object: *Object) !void { |
| 1109 | const mod = object.module; | ||
| 1110 | |||
| 1111 | const writer = object.builder.setModuleAsm(); | 1110 | const writer = object.builder.setModuleAsm(); |
| 1112 | for (mod.global_assembly.values()) |assembly| { | 1111 | for (object.pt.zcu.global_assembly.values()) |assembly| { |
| 1113 | try writer.print("{s}\n", .{assembly}); | 1112 | try writer.print("{s}\n", .{assembly}); |
| 1114 | } | 1113 | } |
| 1115 | try object.builder.finishModuleAsm(); | 1114 | try object.builder.finishModuleAsm(); |
| ... | @@ -1131,6 +1130,9 @@ pub const Object = struct { | ... | @@ -1131,6 +1130,9 @@ pub const Object = struct { |
| 1131 | }; | 1130 | }; |
| 1132 | 1131 | ||
| 1133 | pub fn emit(self: *Object, options: EmitOptions) !void { | 1132 | pub fn emit(self: *Object, options: EmitOptions) !void { |
| 1133 | const zcu = self.pt.zcu; | ||
| 1134 | const comp = zcu.comp; | ||
| 1135 | |||
| 1134 | { | 1136 | { |
| 1135 | try self.genErrorNameTable(); | 1137 | try self.genErrorNameTable(); |
| 1136 | try self.genCmpLtErrorsLenFunction(); | 1138 | try self.genCmpLtErrorsLenFunction(); |
| ... | @@ -1143,8 +1145,8 @@ pub const Object = struct { | ... | @@ -1143,8 +1145,8 @@ pub const Object = struct { |
| 1143 | const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i]; | 1145 | const namespace_index = self.debug_unresolved_namespace_scopes.keys()[i]; |
| 1144 | const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i]; | 1146 | const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i]; |
| 1145 | 1147 | ||
| 1146 | const namespace = self.module.namespacePtr(namespace_index); | 1148 | const namespace = zcu.namespacePtr(namespace_index); |
| 1147 | const debug_type = try self.lowerDebugType(namespace.getType(self.module)); | 1149 | const debug_type = try self.lowerDebugType(namespace.getType(zcu)); |
| 1148 | 1150 | ||
| 1149 | self.builder.debugForwardReferenceSetType(fwd_ref, debug_type); | 1151 | self.builder.debugForwardReferenceSetType(fwd_ref, debug_type); |
| 1150 | } | 1152 | } |
| ... | @@ -1206,12 +1208,12 @@ pub const Object = struct { | ... | @@ -1206,12 +1208,12 @@ pub const Object = struct { |
| 1206 | try file.writeAll(ptr[0..(bitcode.len * 4)]); | 1208 | try file.writeAll(ptr[0..(bitcode.len * 4)]); |
| 1207 | } | 1209 | } |
| 1208 | 1210 | ||
| 1209 | if (!build_options.have_llvm or !self.module.comp.config.use_lib_llvm) { | 1211 | if (!build_options.have_llvm or !comp.config.use_lib_llvm) { |
| 1210 | log.err("emitting without libllvm not implemented", .{}); | 1212 | log.err("emitting without libllvm not implemented", .{}); |
| 1211 | return error.FailedToEmit; | 1213 | return error.FailedToEmit; |
| 1212 | } | 1214 | } |
| 1213 | 1215 | ||
| 1214 | initializeLLVMTarget(self.module.comp.root_mod.resolved_target.result.cpu.arch); | 1216 | initializeLLVMTarget(comp.root_mod.resolved_target.result.cpu.arch); |
| 1215 | 1217 | ||
| 1216 | const context: *llvm.Context = llvm.Context.create(); | 1218 | const context: *llvm.Context = llvm.Context.create(); |
| 1217 | errdefer context.dispose(); | 1219 | errdefer context.dispose(); |
| ... | @@ -1247,8 +1249,8 @@ pub const Object = struct { | ... | @@ -1247,8 +1249,8 @@ pub const Object = struct { |
| 1247 | @panic("Invalid LLVM triple"); | 1249 | @panic("Invalid LLVM triple"); |
| 1248 | } | 1250 | } |
| 1249 | 1251 | ||
| 1250 | const optimize_mode = self.module.comp.root_mod.optimize_mode; | 1252 | const optimize_mode = comp.root_mod.optimize_mode; |
| 1251 | const pic = self.module.comp.root_mod.pic; | 1253 | const pic = comp.root_mod.pic; |
| 1252 | 1254 | ||
| 1253 | const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug) | 1255 | const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug) |
| 1254 | .None | 1256 | .None |
| ... | @@ -1257,12 +1259,12 @@ pub const Object = struct { | ... | @@ -1257,12 +1259,12 @@ pub const Object = struct { |
| 1257 | 1259 | ||
| 1258 | const reloc_mode: llvm.RelocMode = if (pic) | 1260 | const reloc_mode: llvm.RelocMode = if (pic) |
| 1259 | .PIC | 1261 | .PIC |
| 1260 | else if (self.module.comp.config.link_mode == .dynamic) | 1262 | else if (comp.config.link_mode == .dynamic) |
| 1261 | llvm.RelocMode.DynamicNoPIC | 1263 | llvm.RelocMode.DynamicNoPIC |
| 1262 | else | 1264 | else |
| 1263 | .Static; | 1265 | .Static; |
| 1264 | 1266 | ||
| 1265 | const code_model: llvm.CodeModel = switch (self.module.comp.root_mod.code_model) { | 1267 | const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) { |
| 1266 | .default => .Default, | 1268 | .default => .Default, |
| 1267 | .tiny => .Tiny, | 1269 | .tiny => .Tiny, |
| 1268 | .small => .Small, | 1270 | .small => .Small, |
| ... | @@ -1277,24 +1279,24 @@ pub const Object = struct { | ... | @@ -1277,24 +1279,24 @@ pub const Object = struct { |
| 1277 | var target_machine = llvm.TargetMachine.create( | 1279 | var target_machine = llvm.TargetMachine.create( |
| 1278 | target, | 1280 | target, |
| 1279 | target_triple_sentinel, | 1281 | target_triple_sentinel, |
| 1280 | if (self.module.comp.root_mod.resolved_target.result.cpu.model.llvm_name) |s| s.ptr else null, | 1282 | if (comp.root_mod.resolved_target.result.cpu.model.llvm_name) |s| s.ptr else null, |
| 1281 | self.module.comp.root_mod.resolved_target.llvm_cpu_features.?, | 1283 | comp.root_mod.resolved_target.llvm_cpu_features.?, |
| 1282 | opt_level, | 1284 | opt_level, |
| 1283 | reloc_mode, | 1285 | reloc_mode, |
| 1284 | code_model, | 1286 | code_model, |
| 1285 | self.module.comp.function_sections, | 1287 | comp.function_sections, |
| 1286 | self.module.comp.data_sections, | 1288 | comp.data_sections, |
| 1287 | float_abi, | 1289 | float_abi, |
| 1288 | if (target_util.llvmMachineAbi(self.module.comp.root_mod.resolved_target.result)) |s| s.ptr else null, | 1290 | if (target_util.llvmMachineAbi(comp.root_mod.resolved_target.result)) |s| s.ptr else null, |
| 1289 | ); | 1291 | ); |
| 1290 | errdefer target_machine.dispose(); | 1292 | errdefer target_machine.dispose(); |
| 1291 | 1293 | ||
| 1292 | if (pic) module.setModulePICLevel(); | 1294 | if (pic) module.setModulePICLevel(); |
| 1293 | if (self.module.comp.config.pie) module.setModulePIELevel(); | 1295 | if (comp.config.pie) module.setModulePIELevel(); |
| 1294 | if (code_model != .Default) module.setModuleCodeModel(code_model); | 1296 | if (code_model != .Default) module.setModuleCodeModel(code_model); |
| 1295 | 1297 | ||
| 1296 | if (self.module.comp.llvm_opt_bisect_limit >= 0) { | 1298 | if (comp.llvm_opt_bisect_limit >= 0) { |
| 1297 | context.setOptBisectLimit(self.module.comp.llvm_opt_bisect_limit); | 1299 | context.setOptBisectLimit(comp.llvm_opt_bisect_limit); |
| 1298 | } | 1300 | } |
| 1299 | 1301 | ||
| 1300 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. | 1302 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. |
| ... | @@ -1352,11 +1354,13 @@ pub const Object = struct { | ... | @@ -1352,11 +1354,13 @@ pub const Object = struct { |
| 1352 | 1354 | ||
| 1353 | pub fn updateFunc( | 1355 | pub fn updateFunc( |
| 1354 | o: *Object, | 1356 | o: *Object, |
| 1355 | zcu: *Module, | 1357 | pt: Zcu.PerThread, |
| 1356 | func_index: InternPool.Index, | 1358 | func_index: InternPool.Index, |
| 1357 | air: Air, | 1359 | air: Air, |
| 1358 | liveness: Liveness, | 1360 | liveness: Liveness, |
| 1359 | ) !void { | 1361 | ) !void { |
| 1362 | assert(std.meta.eql(pt, o.pt)); | ||
| 1363 | const zcu = pt.zcu; | ||
| 1360 | const comp = zcu.comp; | 1364 | const comp = zcu.comp; |
| 1361 | const func = zcu.funcInfo(func_index); | 1365 | const func = zcu.funcInfo(func_index); |
| 1362 | const decl_index = func.owner_decl; | 1366 | const decl_index = func.owner_decl; |
| ... | @@ -1437,7 +1441,7 @@ pub const Object = struct { | ... | @@ -1437,7 +1441,7 @@ pub const Object = struct { |
| 1437 | var llvm_arg_i: u32 = 0; | 1441 | var llvm_arg_i: u32 = 0; |
| 1438 | 1442 | ||
| 1439 | // This gets the LLVM values from the function and stores them in `dg.args`. | 1443 | // This gets the LLVM values from the function and stores them in `dg.args`. |
| 1440 | const sret = firstParamSRet(fn_info, zcu, target); | 1444 | const sret = firstParamSRet(fn_info, pt, target); |
| 1441 | const ret_ptr: Builder.Value = if (sret) param: { | 1445 | const ret_ptr: Builder.Value = if (sret) param: { |
| 1442 | const param = wip.arg(llvm_arg_i); | 1446 | const param = wip.arg(llvm_arg_i); |
| 1443 | llvm_arg_i += 1; | 1447 | llvm_arg_i += 1; |
| ... | @@ -1478,8 +1482,8 @@ pub const Object = struct { | ... | @@ -1478,8 +1482,8 @@ pub const Object = struct { |
| 1478 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 1482 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 1479 | const param = wip.arg(llvm_arg_i); | 1483 | const param = wip.arg(llvm_arg_i); |
| 1480 | 1484 | ||
| 1481 | if (isByRef(param_ty, zcu)) { | 1485 | if (isByRef(param_ty, pt)) { |
| 1482 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1486 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1483 | const param_llvm_ty = param.typeOfWip(&wip); | 1487 | const param_llvm_ty = param.typeOfWip(&wip); |
| 1484 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); | 1488 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1485 | _ = try wip.store(.normal, param, arg_ptr, alignment); | 1489 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| ... | @@ -1495,12 +1499,12 @@ pub const Object = struct { | ... | @@ -1495,12 +1499,12 @@ pub const Object = struct { |
| 1495 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 1499 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1496 | const param_llvm_ty = try o.lowerType(param_ty); | 1500 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1497 | const param = wip.arg(llvm_arg_i); | 1501 | const param = wip.arg(llvm_arg_i); |
| 1498 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1502 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1499 | 1503 | ||
| 1500 | try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty); | 1504 | try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty); |
| 1501 | llvm_arg_i += 1; | 1505 | llvm_arg_i += 1; |
| 1502 | 1506 | ||
| 1503 | if (isByRef(param_ty, zcu)) { | 1507 | if (isByRef(param_ty, pt)) { |
| 1504 | args.appendAssumeCapacity(param); | 1508 | args.appendAssumeCapacity(param); |
| 1505 | } else { | 1509 | } else { |
| 1506 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); | 1510 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | @@ -1510,12 +1514,12 @@ pub const Object = struct { | ... | @@ -1510,12 +1514,12 @@ pub const Object = struct { |
| 1510 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 1514 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1511 | const param_llvm_ty = try o.lowerType(param_ty); | 1515 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1512 | const param = wip.arg(llvm_arg_i); | 1516 | const param = wip.arg(llvm_arg_i); |
| 1513 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1517 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1514 | 1518 | ||
| 1515 | try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder); | 1519 | try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder); |
| 1516 | llvm_arg_i += 1; | 1520 | llvm_arg_i += 1; |
| 1517 | 1521 | ||
| 1518 | if (isByRef(param_ty, zcu)) { | 1522 | if (isByRef(param_ty, pt)) { |
| 1519 | args.appendAssumeCapacity(param); | 1523 | args.appendAssumeCapacity(param); |
| 1520 | } else { | 1524 | } else { |
| 1521 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); | 1525 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | @@ -1528,11 +1532,11 @@ pub const Object = struct { | ... | @@ -1528,11 +1532,11 @@ pub const Object = struct { |
| 1528 | llvm_arg_i += 1; | 1532 | llvm_arg_i += 1; |
| 1529 | 1533 | ||
| 1530 | const param_llvm_ty = try o.lowerType(param_ty); | 1534 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1531 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1535 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1532 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); | 1536 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1533 | _ = try wip.store(.normal, param, arg_ptr, alignment); | 1537 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1534 | 1538 | ||
| 1535 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | 1539 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) |
| 1536 | arg_ptr | 1540 | arg_ptr |
| 1537 | else | 1541 | else |
| 1538 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); | 1542 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | @@ -1556,7 +1560,7 @@ pub const Object = struct { | ... | @@ -1556,7 +1560,7 @@ pub const Object = struct { |
| 1556 | const elem_align = (if (ptr_info.flags.alignment != .none) | 1560 | const elem_align = (if (ptr_info.flags.alignment != .none) |
| 1557 | @as(InternPool.Alignment, ptr_info.flags.alignment) | 1561 | @as(InternPool.Alignment, ptr_info.flags.alignment) |
| 1558 | else | 1562 | else |
| 1559 | Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm(); | 1563 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm(); |
| 1560 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); | 1564 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); |
| 1561 | const ptr_param = wip.arg(llvm_arg_i); | 1565 | const ptr_param = wip.arg(llvm_arg_i); |
| 1562 | llvm_arg_i += 1; | 1566 | llvm_arg_i += 1; |
| ... | @@ -1573,7 +1577,7 @@ pub const Object = struct { | ... | @@ -1573,7 +1577,7 @@ pub const Object = struct { |
| 1573 | const field_types = it.types_buffer[0..it.types_len]; | 1577 | const field_types = it.types_buffer[0..it.types_len]; |
| 1574 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 1578 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1575 | const param_llvm_ty = try o.lowerType(param_ty); | 1579 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1576 | const param_alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1580 | const param_alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1577 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target); | 1581 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target); |
| 1578 | const llvm_ty = try o.builder.structType(.normal, field_types); | 1582 | const llvm_ty = try o.builder.structType(.normal, field_types); |
| 1579 | for (0..field_types.len) |field_i| { | 1583 | for (0..field_types.len) |field_i| { |
| ... | @@ -1585,7 +1589,7 @@ pub const Object = struct { | ... | @@ -1585,7 +1589,7 @@ pub const Object = struct { |
| 1585 | _ = try wip.store(.normal, param, field_ptr, alignment); | 1589 | _ = try wip.store(.normal, param, field_ptr, alignment); |
| 1586 | } | 1590 | } |
| 1587 | 1591 | ||
| 1588 | const is_by_ref = isByRef(param_ty, zcu); | 1592 | const is_by_ref = isByRef(param_ty, pt); |
| 1589 | args.appendAssumeCapacity(if (is_by_ref) | 1593 | args.appendAssumeCapacity(if (is_by_ref) |
| 1590 | arg_ptr | 1594 | arg_ptr |
| 1591 | else | 1595 | else |
| ... | @@ -1603,11 +1607,11 @@ pub const Object = struct { | ... | @@ -1603,11 +1607,11 @@ pub const Object = struct { |
| 1603 | const param = wip.arg(llvm_arg_i); | 1607 | const param = wip.arg(llvm_arg_i); |
| 1604 | llvm_arg_i += 1; | 1608 | llvm_arg_i += 1; |
| 1605 | 1609 | ||
| 1606 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1610 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1607 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); | 1611 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1608 | _ = try wip.store(.normal, param, arg_ptr, alignment); | 1612 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1609 | 1613 | ||
| 1610 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | 1614 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) |
| 1611 | arg_ptr | 1615 | arg_ptr |
| 1612 | else | 1616 | else |
| 1613 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); | 1617 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | @@ -1618,11 +1622,11 @@ pub const Object = struct { | ... | @@ -1618,11 +1622,11 @@ pub const Object = struct { |
| 1618 | const param = wip.arg(llvm_arg_i); | 1622 | const param = wip.arg(llvm_arg_i); |
| 1619 | llvm_arg_i += 1; | 1623 | llvm_arg_i += 1; |
| 1620 | 1624 | ||
| 1621 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 1625 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 1622 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); | 1626 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1623 | _ = try wip.store(.normal, param, arg_ptr, alignment); | 1627 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1624 | 1628 | ||
| 1625 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | 1629 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) |
| 1626 | arg_ptr | 1630 | arg_ptr |
| 1627 | else | 1631 | else |
| 1628 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); | 1632 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | @@ -1700,8 +1704,9 @@ pub const Object = struct { | ... | @@ -1700,8 +1704,9 @@ pub const Object = struct { |
| 1700 | try fg.wip.finish(); | 1704 | try fg.wip.finish(); |
| 1701 | } | 1705 | } |
| 1702 | 1706 | ||
| 1703 | pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void { | 1707 | pub fn updateDecl(self: *Object, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 1704 | const decl = module.declPtr(decl_index); | 1708 | assert(std.meta.eql(pt, self.pt)); |
| 1709 | const decl = pt.zcu.declPtr(decl_index); | ||
| 1705 | var dg: DeclGen = .{ | 1710 | var dg: DeclGen = .{ |
| 1706 | .object = self, | 1711 | .object = self, |
| 1707 | .decl = decl, | 1712 | .decl = decl, |
| ... | @@ -1711,7 +1716,7 @@ pub const Object = struct { | ... | @@ -1711,7 +1716,7 @@ pub const Object = struct { |
| 1711 | dg.genDecl() catch |err| switch (err) { | 1716 | dg.genDecl() catch |err| switch (err) { |
| 1712 | error.CodegenFail => { | 1717 | error.CodegenFail => { |
| 1713 | decl.analysis = .codegen_failure; | 1718 | decl.analysis = .codegen_failure; |
| 1714 | try module.failed_analysis.put(module.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?); | 1719 | try pt.zcu.failed_analysis.put(pt.zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?); |
| 1715 | dg.err_msg = null; | 1720 | dg.err_msg = null; |
| 1716 | return; | 1721 | return; |
| 1717 | }, | 1722 | }, |
| ... | @@ -1721,10 +1726,12 @@ pub const Object = struct { | ... | @@ -1721,10 +1726,12 @@ pub const Object = struct { |
| 1721 | 1726 | ||
| 1722 | pub fn updateExports( | 1727 | pub fn updateExports( |
| 1723 | self: *Object, | 1728 | self: *Object, |
| 1724 | zcu: *Zcu, | 1729 | pt: Zcu.PerThread, |
| 1725 | exported: Module.Exported, | 1730 | exported: Zcu.Exported, |
| 1726 | export_indices: []const u32, | 1731 | export_indices: []const u32, |
| 1727 | ) link.File.UpdateExportsError!void { | 1732 | ) link.File.UpdateExportsError!void { |
| 1733 | assert(std.meta.eql(pt, self.pt)); | ||
| 1734 | const zcu = pt.zcu; | ||
| 1728 | const decl_index = switch (exported) { | 1735 | const decl_index = switch (exported) { |
| 1729 | .decl_index => |i| i, | 1736 | .decl_index => |i| i, |
| 1730 | .value => |val| return updateExportedValue(self, zcu, val, export_indices), | 1737 | .value => |val| return updateExportedValue(self, zcu, val, export_indices), |
| ... | @@ -1748,7 +1755,7 @@ pub const Object = struct { | ... | @@ -1748,7 +1755,7 @@ pub const Object = struct { |
| 1748 | 1755 | ||
| 1749 | fn updateExportedValue( | 1756 | fn updateExportedValue( |
| 1750 | o: *Object, | 1757 | o: *Object, |
| 1751 | mod: *Module, | 1758 | mod: *Zcu, |
| 1752 | exported_value: InternPool.Index, | 1759 | exported_value: InternPool.Index, |
| 1753 | export_indices: []const u32, | 1760 | export_indices: []const u32, |
| 1754 | ) link.File.UpdateExportsError!void { | 1761 | ) link.File.UpdateExportsError!void { |
| ... | @@ -1783,7 +1790,7 @@ pub const Object = struct { | ... | @@ -1783,7 +1790,7 @@ pub const Object = struct { |
| 1783 | 1790 | ||
| 1784 | fn updateExportedGlobal( | 1791 | fn updateExportedGlobal( |
| 1785 | o: *Object, | 1792 | o: *Object, |
| 1786 | mod: *Module, | 1793 | mod: *Zcu, |
| 1787 | global_index: Builder.Global.Index, | 1794 | global_index: Builder.Global.Index, |
| 1788 | export_indices: []const u32, | 1795 | export_indices: []const u32, |
| 1789 | ) link.File.UpdateExportsError!void { | 1796 | ) link.File.UpdateExportsError!void { |
| ... | @@ -1879,7 +1886,7 @@ pub const Object = struct { | ... | @@ -1879,7 +1886,7 @@ pub const Object = struct { |
| 1879 | global.delete(&self.builder); | 1886 | global.delete(&self.builder); |
| 1880 | } | 1887 | } |
| 1881 | 1888 | ||
| 1882 | fn getDebugFile(o: *Object, file: *const Module.File) Allocator.Error!Builder.Metadata { | 1889 | fn getDebugFile(o: *Object, file: *const Zcu.File) Allocator.Error!Builder.Metadata { |
| 1883 | const gpa = o.gpa; | 1890 | const gpa = o.gpa; |
| 1884 | const gop = try o.debug_file_map.getOrPut(gpa, file); | 1891 | const gop = try o.debug_file_map.getOrPut(gpa, file); |
| 1885 | errdefer assert(o.debug_file_map.remove(file)); | 1892 | errdefer assert(o.debug_file_map.remove(file)); |
| ... | @@ -1909,7 +1916,8 @@ pub const Object = struct { | ... | @@ -1909,7 +1916,8 @@ pub const Object = struct { |
| 1909 | 1916 | ||
| 1910 | const gpa = o.gpa; | 1917 | const gpa = o.gpa; |
| 1911 | const target = o.target; | 1918 | const target = o.target; |
| 1912 | const zcu = o.module; | 1919 | const pt = o.pt; |
| 1920 | const zcu = pt.zcu; | ||
| 1913 | const ip = &zcu.intern_pool; | 1921 | const ip = &zcu.intern_pool; |
| 1914 | 1922 | ||
| 1915 | if (o.debug_type_map.get(ty)) |debug_type| return debug_type; | 1923 | if (o.debug_type_map.get(ty)) |debug_type| return debug_type; |
| ... | @@ -1931,7 +1939,7 @@ pub const Object = struct { | ... | @@ -1931,7 +1939,7 @@ pub const Object = struct { |
| 1931 | const name = try o.allocTypeName(ty); | 1939 | const name = try o.allocTypeName(ty); |
| 1932 | defer gpa.free(name); | 1940 | defer gpa.free(name); |
| 1933 | const builder_name = try o.builder.metadataString(name); | 1941 | const builder_name = try o.builder.metadataString(name); |
| 1934 | const debug_bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types | 1942 | const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types |
| 1935 | const debug_int_type = switch (info.signedness) { | 1943 | const debug_int_type = switch (info.signedness) { |
| 1936 | .signed => try o.builder.debugSignedType(builder_name, debug_bits), | 1944 | .signed => try o.builder.debugSignedType(builder_name, debug_bits), |
| 1937 | .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits), | 1945 | .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits), |
| ... | @@ -1941,9 +1949,9 @@ pub const Object = struct { | ... | @@ -1941,9 +1949,9 @@ pub const Object = struct { |
| 1941 | }, | 1949 | }, |
| 1942 | .Enum => { | 1950 | .Enum => { |
| 1943 | const owner_decl_index = ty.getOwnerDecl(zcu); | 1951 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| 1944 | const owner_decl = o.module.declPtr(owner_decl_index); | 1952 | const owner_decl = zcu.declPtr(owner_decl_index); |
| 1945 | 1953 | ||
| 1946 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 1954 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1947 | const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); | 1955 | const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| 1948 | try o.debug_type_map.put(gpa, ty, debug_enum_type); | 1956 | try o.debug_type_map.put(gpa, ty, debug_enum_type); |
| 1949 | return debug_enum_type; | 1957 | return debug_enum_type; |
| ... | @@ -1961,7 +1969,7 @@ pub const Object = struct { | ... | @@ -1961,7 +1969,7 @@ pub const Object = struct { |
| 1961 | for (enum_type.names.get(ip), 0..) |field_name_ip, i| { | 1969 | for (enum_type.names.get(ip), 0..) |field_name_ip, i| { |
| 1962 | var bigint_space: Value.BigIntSpace = undefined; | 1970 | var bigint_space: Value.BigIntSpace = undefined; |
| 1963 | const bigint = if (enum_type.values.len != 0) | 1971 | const bigint = if (enum_type.values.len != 0) |
| 1964 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, zcu) | 1972 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) |
| 1965 | else | 1973 | else |
| 1966 | std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); | 1974 | std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); |
| 1967 | 1975 | ||
| ... | @@ -1986,8 +1994,8 @@ pub const Object = struct { | ... | @@ -1986,8 +1994,8 @@ pub const Object = struct { |
| 1986 | scope, | 1994 | scope, |
| 1987 | owner_decl.typeSrcLine(zcu) + 1, // Line | 1995 | owner_decl.typeSrcLine(zcu) + 1, // Line |
| 1988 | try o.lowerDebugType(int_ty), | 1996 | try o.lowerDebugType(int_ty), |
| 1989 | ty.abiSize(zcu) * 8, | 1997 | ty.abiSize(pt) * 8, |
| 1990 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 1998 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 1991 | try o.builder.debugTuple(enumerators), | 1999 | try o.builder.debugTuple(enumerators), |
| 1992 | ); | 2000 | ); |
| 1993 | 2001 | ||
| ... | @@ -2027,10 +2035,10 @@ pub const Object = struct { | ... | @@ -2027,10 +2035,10 @@ pub const Object = struct { |
| 2027 | ptr_info.flags.is_const or | 2035 | ptr_info.flags.is_const or |
| 2028 | ptr_info.flags.is_volatile or | 2036 | ptr_info.flags.is_volatile or |
| 2029 | ptr_info.flags.size == .Many or ptr_info.flags.size == .C or | 2037 | ptr_info.flags.size == .Many or ptr_info.flags.size == .C or |
| 2030 | !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) | 2038 | !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt)) |
| 2031 | { | 2039 | { |
| 2032 | const bland_ptr_ty = try zcu.ptrType(.{ | 2040 | const bland_ptr_ty = try pt.ptrType(.{ |
| 2033 | .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) | 2041 | .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt)) |
| 2034 | .anyopaque_type | 2042 | .anyopaque_type |
| 2035 | else | 2043 | else |
| 2036 | ptr_info.child, | 2044 | ptr_info.child, |
| ... | @@ -2060,10 +2068,10 @@ pub const Object = struct { | ... | @@ -2060,10 +2068,10 @@ pub const Object = struct { |
| 2060 | defer gpa.free(name); | 2068 | defer gpa.free(name); |
| 2061 | const line = 0; | 2069 | const line = 0; |
| 2062 | 2070 | ||
| 2063 | const ptr_size = ptr_ty.abiSize(zcu); | 2071 | const ptr_size = ptr_ty.abiSize(pt); |
| 2064 | const ptr_align = ptr_ty.abiAlignment(zcu); | 2072 | const ptr_align = ptr_ty.abiAlignment(pt); |
| 2065 | const len_size = len_ty.abiSize(zcu); | 2073 | const len_size = len_ty.abiSize(pt); |
| 2066 | const len_align = len_ty.abiAlignment(zcu); | 2074 | const len_align = len_ty.abiAlignment(pt); |
| 2067 | 2075 | ||
| 2068 | const len_offset = len_align.forward(ptr_size); | 2076 | const len_offset = len_align.forward(ptr_size); |
| 2069 | 2077 | ||
| ... | @@ -2095,8 +2103,8 @@ pub const Object = struct { | ... | @@ -2095,8 +2103,8 @@ pub const Object = struct { |
| 2095 | o.debug_compile_unit, // Scope | 2103 | o.debug_compile_unit, // Scope |
| 2096 | line, | 2104 | line, |
| 2097 | .none, // Underlying type | 2105 | .none, // Underlying type |
| 2098 | ty.abiSize(zcu) * 8, | 2106 | ty.abiSize(pt) * 8, |
| 2099 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2107 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2100 | try o.builder.debugTuple(&.{ | 2108 | try o.builder.debugTuple(&.{ |
| 2101 | debug_ptr_type, | 2109 | debug_ptr_type, |
| 2102 | debug_len_type, | 2110 | debug_len_type, |
| ... | @@ -2124,7 +2132,7 @@ pub const Object = struct { | ... | @@ -2124,7 +2132,7 @@ pub const Object = struct { |
| 2124 | 0, // Line | 2132 | 0, // Line |
| 2125 | debug_elem_ty, | 2133 | debug_elem_ty, |
| 2126 | target.ptrBitWidth(), | 2134 | target.ptrBitWidth(), |
| 2127 | (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8, | 2135 | (ty.ptrAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2128 | 0, // Offset | 2136 | 0, // Offset |
| 2129 | ); | 2137 | ); |
| 2130 | 2138 | ||
| ... | @@ -2149,7 +2157,7 @@ pub const Object = struct { | ... | @@ -2149,7 +2157,7 @@ pub const Object = struct { |
| 2149 | const name = try o.allocTypeName(ty); | 2157 | const name = try o.allocTypeName(ty); |
| 2150 | defer gpa.free(name); | 2158 | defer gpa.free(name); |
| 2151 | const owner_decl_index = ty.getOwnerDecl(zcu); | 2159 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| 2152 | const owner_decl = o.module.declPtr(owner_decl_index); | 2160 | const owner_decl = zcu.declPtr(owner_decl_index); |
| 2153 | const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); | 2161 | const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); |
| 2154 | const debug_opaque_type = try o.builder.debugStructType( | 2162 | const debug_opaque_type = try o.builder.debugStructType( |
| 2155 | try o.builder.metadataString(name), | 2163 | try o.builder.metadataString(name), |
| ... | @@ -2171,8 +2179,8 @@ pub const Object = struct { | ... | @@ -2171,8 +2179,8 @@ pub const Object = struct { |
| 2171 | .none, // Scope | 2179 | .none, // Scope |
| 2172 | 0, // Line | 2180 | 0, // Line |
| 2173 | try o.lowerDebugType(ty.childType(zcu)), | 2181 | try o.lowerDebugType(ty.childType(zcu)), |
| 2174 | ty.abiSize(zcu) * 8, | 2182 | ty.abiSize(pt) * 8, |
| 2175 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2183 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2176 | try o.builder.debugTuple(&.{ | 2184 | try o.builder.debugTuple(&.{ |
| 2177 | try o.builder.debugSubrange( | 2185 | try o.builder.debugSubrange( |
| 2178 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), | 2186 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), |
| ... | @@ -2214,8 +2222,8 @@ pub const Object = struct { | ... | @@ -2214,8 +2222,8 @@ pub const Object = struct { |
| 2214 | .none, // Scope | 2222 | .none, // Scope |
| 2215 | 0, // Line | 2223 | 0, // Line |
| 2216 | debug_elem_type, | 2224 | debug_elem_type, |
| 2217 | ty.abiSize(zcu) * 8, | 2225 | ty.abiSize(pt) * 8, |
| 2218 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2226 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2219 | try o.builder.debugTuple(&.{ | 2227 | try o.builder.debugTuple(&.{ |
| 2220 | try o.builder.debugSubrange( | 2228 | try o.builder.debugSubrange( |
| 2221 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), | 2229 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), |
| ... | @@ -2231,7 +2239,7 @@ pub const Object = struct { | ... | @@ -2231,7 +2239,7 @@ pub const Object = struct { |
| 2231 | const name = try o.allocTypeName(ty); | 2239 | const name = try o.allocTypeName(ty); |
| 2232 | defer gpa.free(name); | 2240 | defer gpa.free(name); |
| 2233 | const child_ty = ty.optionalChild(zcu); | 2241 | const child_ty = ty.optionalChild(zcu); |
| 2234 | if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 2242 | if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2235 | const debug_bool_type = try o.builder.debugBoolType( | 2243 | const debug_bool_type = try o.builder.debugBoolType( |
| 2236 | try o.builder.metadataString(name), | 2244 | try o.builder.metadataString(name), |
| 2237 | 8, | 2245 | 8, |
| ... | @@ -2258,10 +2266,10 @@ pub const Object = struct { | ... | @@ -2258,10 +2266,10 @@ pub const Object = struct { |
| 2258 | } | 2266 | } |
| 2259 | 2267 | ||
| 2260 | const non_null_ty = Type.u8; | 2268 | const non_null_ty = Type.u8; |
| 2261 | const payload_size = child_ty.abiSize(zcu); | 2269 | const payload_size = child_ty.abiSize(pt); |
| 2262 | const payload_align = child_ty.abiAlignment(zcu); | 2270 | const payload_align = child_ty.abiAlignment(pt); |
| 2263 | const non_null_size = non_null_ty.abiSize(zcu); | 2271 | const non_null_size = non_null_ty.abiSize(pt); |
| 2264 | const non_null_align = non_null_ty.abiAlignment(zcu); | 2272 | const non_null_align = non_null_ty.abiAlignment(pt); |
| 2265 | const non_null_offset = non_null_align.forward(payload_size); | 2273 | const non_null_offset = non_null_align.forward(payload_size); |
| 2266 | 2274 | ||
| 2267 | const debug_data_type = try o.builder.debugMemberType( | 2275 | const debug_data_type = try o.builder.debugMemberType( |
| ... | @@ -2292,8 +2300,8 @@ pub const Object = struct { | ... | @@ -2292,8 +2300,8 @@ pub const Object = struct { |
| 2292 | o.debug_compile_unit, // Scope | 2300 | o.debug_compile_unit, // Scope |
| 2293 | 0, // Line | 2301 | 0, // Line |
| 2294 | .none, // Underlying type | 2302 | .none, // Underlying type |
| 2295 | ty.abiSize(zcu) * 8, | 2303 | ty.abiSize(pt) * 8, |
| 2296 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2304 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2297 | try o.builder.debugTuple(&.{ | 2305 | try o.builder.debugTuple(&.{ |
| 2298 | debug_data_type, | 2306 | debug_data_type, |
| 2299 | debug_some_type, | 2307 | debug_some_type, |
| ... | @@ -2310,7 +2318,7 @@ pub const Object = struct { | ... | @@ -2310,7 +2318,7 @@ pub const Object = struct { |
| 2310 | }, | 2318 | }, |
| 2311 | .ErrorUnion => { | 2319 | .ErrorUnion => { |
| 2312 | const payload_ty = ty.errorUnionPayload(zcu); | 2320 | const payload_ty = ty.errorUnionPayload(zcu); |
| 2313 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 2321 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2314 | // TODO: Maybe remove? | 2322 | // TODO: Maybe remove? |
| 2315 | const debug_error_union_type = try o.lowerDebugType(Type.anyerror); | 2323 | const debug_error_union_type = try o.lowerDebugType(Type.anyerror); |
| 2316 | try o.debug_type_map.put(gpa, ty, debug_error_union_type); | 2324 | try o.debug_type_map.put(gpa, ty, debug_error_union_type); |
| ... | @@ -2320,10 +2328,10 @@ pub const Object = struct { | ... | @@ -2320,10 +2328,10 @@ pub const Object = struct { |
| 2320 | const name = try o.allocTypeName(ty); | 2328 | const name = try o.allocTypeName(ty); |
| 2321 | defer gpa.free(name); | 2329 | defer gpa.free(name); |
| 2322 | 2330 | ||
| 2323 | const error_size = Type.anyerror.abiSize(zcu); | 2331 | const error_size = Type.anyerror.abiSize(pt); |
| 2324 | const error_align = Type.anyerror.abiAlignment(zcu); | 2332 | const error_align = Type.anyerror.abiAlignment(pt); |
| 2325 | const payload_size = payload_ty.abiSize(zcu); | 2333 | const payload_size = payload_ty.abiSize(pt); |
| 2326 | const payload_align = payload_ty.abiAlignment(zcu); | 2334 | const payload_align = payload_ty.abiAlignment(pt); |
| 2327 | 2335 | ||
| 2328 | var error_index: u32 = undefined; | 2336 | var error_index: u32 = undefined; |
| 2329 | var payload_index: u32 = undefined; | 2337 | var payload_index: u32 = undefined; |
| ... | @@ -2371,8 +2379,8 @@ pub const Object = struct { | ... | @@ -2371,8 +2379,8 @@ pub const Object = struct { |
| 2371 | o.debug_compile_unit, // Sope | 2379 | o.debug_compile_unit, // Sope |
| 2372 | 0, // Line | 2380 | 0, // Line |
| 2373 | .none, // Underlying type | 2381 | .none, // Underlying type |
| 2374 | ty.abiSize(zcu) * 8, | 2382 | ty.abiSize(pt) * 8, |
| 2375 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2383 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2376 | try o.builder.debugTuple(&fields), | 2384 | try o.builder.debugTuple(&fields), |
| 2377 | ); | 2385 | ); |
| 2378 | 2386 | ||
| ... | @@ -2399,8 +2407,8 @@ pub const Object = struct { | ... | @@ -2399,8 +2407,8 @@ pub const Object = struct { |
| 2399 | const info = Type.fromInterned(backing_int_ty).intInfo(zcu); | 2407 | const info = Type.fromInterned(backing_int_ty).intInfo(zcu); |
| 2400 | const builder_name = try o.builder.metadataString(name); | 2408 | const builder_name = try o.builder.metadataString(name); |
| 2401 | const debug_int_type = switch (info.signedness) { | 2409 | const debug_int_type = switch (info.signedness) { |
| 2402 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8), | 2410 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), |
| 2403 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8), | 2411 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), |
| 2404 | }; | 2412 | }; |
| 2405 | try o.debug_type_map.put(gpa, ty, debug_int_type); | 2413 | try o.debug_type_map.put(gpa, ty, debug_int_type); |
| 2406 | return debug_int_type; | 2414 | return debug_int_type; |
| ... | @@ -2420,10 +2428,10 @@ pub const Object = struct { | ... | @@ -2420,10 +2428,10 @@ pub const Object = struct { |
| 2420 | const debug_fwd_ref = try o.builder.debugForwardReference(); | 2428 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2421 | 2429 | ||
| 2422 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { | 2430 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 2423 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | 2431 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 2424 | 2432 | ||
| 2425 | const field_size = Type.fromInterned(field_ty).abiSize(zcu); | 2433 | const field_size = Type.fromInterned(field_ty).abiSize(pt); |
| 2426 | const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); | 2434 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); |
| 2427 | const field_offset = field_align.forward(offset); | 2435 | const field_offset = field_align.forward(offset); |
| 2428 | offset = field_offset + field_size; | 2436 | offset = field_offset + field_size; |
| 2429 | 2437 | ||
| ... | @@ -2451,8 +2459,8 @@ pub const Object = struct { | ... | @@ -2451,8 +2459,8 @@ pub const Object = struct { |
| 2451 | o.debug_compile_unit, // Scope | 2459 | o.debug_compile_unit, // Scope |
| 2452 | 0, // Line | 2460 | 0, // Line |
| 2453 | .none, // Underlying type | 2461 | .none, // Underlying type |
| 2454 | ty.abiSize(zcu) * 8, | 2462 | ty.abiSize(pt) * 8, |
| 2455 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2463 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2456 | try o.builder.debugTuple(fields.items), | 2464 | try o.builder.debugTuple(fields.items), |
| 2457 | ); | 2465 | ); |
| 2458 | 2466 | ||
| ... | @@ -2479,7 +2487,7 @@ pub const Object = struct { | ... | @@ -2479,7 +2487,7 @@ pub const Object = struct { |
| 2479 | else => {}, | 2487 | else => {}, |
| 2480 | } | 2488 | } |
| 2481 | 2489 | ||
| 2482 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 2490 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 2483 | const owner_decl_index = ty.getOwnerDecl(zcu); | 2491 | const owner_decl_index = ty.getOwnerDecl(zcu); |
| 2484 | const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); | 2492 | const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| 2485 | try o.debug_type_map.put(gpa, ty, debug_struct_type); | 2493 | try o.debug_type_map.put(gpa, ty, debug_struct_type); |
| ... | @@ -2502,14 +2510,14 @@ pub const Object = struct { | ... | @@ -2502,14 +2510,14 @@ pub const Object = struct { |
| 2502 | var it = struct_type.iterateRuntimeOrder(ip); | 2510 | var it = struct_type.iterateRuntimeOrder(ip); |
| 2503 | while (it.next()) |field_index| { | 2511 | while (it.next()) |field_index| { |
| 2504 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 2512 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 2505 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 2513 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2506 | const field_size = field_ty.abiSize(zcu); | 2514 | const field_size = field_ty.abiSize(pt); |
| 2507 | const field_align = zcu.structFieldAlignment( | 2515 | const field_align = pt.structFieldAlignment( |
| 2508 | struct_type.fieldAlign(ip, field_index), | 2516 | struct_type.fieldAlign(ip, field_index), |
| 2509 | field_ty, | 2517 | field_ty, |
| 2510 | struct_type.layout, | 2518 | struct_type.layout, |
| 2511 | ); | 2519 | ); |
| 2512 | const field_offset = ty.structFieldOffset(field_index, zcu); | 2520 | const field_offset = ty.structFieldOffset(field_index, pt); |
| 2513 | 2521 | ||
| 2514 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse | 2522 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse |
| 2515 | try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls); | 2523 | try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls); |
| ... | @@ -2532,8 +2540,8 @@ pub const Object = struct { | ... | @@ -2532,8 +2540,8 @@ pub const Object = struct { |
| 2532 | o.debug_compile_unit, // Scope | 2540 | o.debug_compile_unit, // Scope |
| 2533 | 0, // Line | 2541 | 0, // Line |
| 2534 | .none, // Underlying type | 2542 | .none, // Underlying type |
| 2535 | ty.abiSize(zcu) * 8, | 2543 | ty.abiSize(pt) * 8, |
| 2536 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2544 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2537 | try o.builder.debugTuple(fields.items), | 2545 | try o.builder.debugTuple(fields.items), |
| 2538 | ); | 2546 | ); |
| 2539 | 2547 | ||
| ... | @@ -2553,7 +2561,7 @@ pub const Object = struct { | ... | @@ -2553,7 +2561,7 @@ pub const Object = struct { |
| 2553 | 2561 | ||
| 2554 | const union_type = ip.loadUnionType(ty.toIntern()); | 2562 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 2555 | if (!union_type.haveFieldTypes(ip) or | 2563 | if (!union_type.haveFieldTypes(ip) or |
| 2556 | !ty.hasRuntimeBitsIgnoreComptime(zcu) or | 2564 | !ty.hasRuntimeBitsIgnoreComptime(pt) or |
| 2557 | !union_type.haveLayout(ip)) | 2565 | !union_type.haveLayout(ip)) |
| 2558 | { | 2566 | { |
| 2559 | const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); | 2567 | const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); |
| ... | @@ -2561,7 +2569,7 @@ pub const Object = struct { | ... | @@ -2561,7 +2569,7 @@ pub const Object = struct { |
| 2561 | return debug_union_type; | 2569 | return debug_union_type; |
| 2562 | } | 2570 | } |
| 2563 | 2571 | ||
| 2564 | const layout = zcu.getUnionLayout(union_type); | 2572 | const layout = pt.getUnionLayout(union_type); |
| 2565 | 2573 | ||
| 2566 | const debug_fwd_ref = try o.builder.debugForwardReference(); | 2574 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2567 | 2575 | ||
| ... | @@ -2575,8 +2583,8 @@ pub const Object = struct { | ... | @@ -2575,8 +2583,8 @@ pub const Object = struct { |
| 2575 | o.debug_compile_unit, // Scope | 2583 | o.debug_compile_unit, // Scope |
| 2576 | 0, // Line | 2584 | 0, // Line |
| 2577 | .none, // Underlying type | 2585 | .none, // Underlying type |
| 2578 | ty.abiSize(zcu) * 8, | 2586 | ty.abiSize(pt) * 8, |
| 2579 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2587 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2580 | try o.builder.debugTuple( | 2588 | try o.builder.debugTuple( |
| 2581 | &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, | 2589 | &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, |
| 2582 | ), | 2590 | ), |
| ... | @@ -2603,12 +2611,12 @@ pub const Object = struct { | ... | @@ -2603,12 +2611,12 @@ pub const Object = struct { |
| 2603 | 2611 | ||
| 2604 | for (0..tag_type.names.len) |field_index| { | 2612 | for (0..tag_type.names.len) |field_index| { |
| 2605 | const field_ty = union_type.field_types.get(ip)[field_index]; | 2613 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| 2606 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; | 2614 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2607 | 2615 | ||
| 2608 | const field_size = Type.fromInterned(field_ty).abiSize(zcu); | 2616 | const field_size = Type.fromInterned(field_ty).abiSize(pt); |
| 2609 | const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) { | 2617 | const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) { |
| 2610 | .@"packed" => .none, | 2618 | .@"packed" => .none, |
| 2611 | .auto, .@"extern" => zcu.unionFieldNormalAlignment(union_type, @intCast(field_index)), | 2619 | .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), |
| 2612 | }; | 2620 | }; |
| 2613 | 2621 | ||
| 2614 | const field_name = tag_type.names.get(ip)[field_index]; | 2622 | const field_name = tag_type.names.get(ip)[field_index]; |
| ... | @@ -2637,8 +2645,8 @@ pub const Object = struct { | ... | @@ -2637,8 +2645,8 @@ pub const Object = struct { |
| 2637 | o.debug_compile_unit, // Scope | 2645 | o.debug_compile_unit, // Scope |
| 2638 | 0, // Line | 2646 | 0, // Line |
| 2639 | .none, // Underlying type | 2647 | .none, // Underlying type |
| 2640 | ty.abiSize(zcu) * 8, | 2648 | ty.abiSize(pt) * 8, |
| 2641 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2649 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2642 | try o.builder.debugTuple(fields.items), | 2650 | try o.builder.debugTuple(fields.items), |
| 2643 | ); | 2651 | ); |
| 2644 | 2652 | ||
| ... | @@ -2696,8 +2704,8 @@ pub const Object = struct { | ... | @@ -2696,8 +2704,8 @@ pub const Object = struct { |
| 2696 | o.debug_compile_unit, // Scope | 2704 | o.debug_compile_unit, // Scope |
| 2697 | 0, // Line | 2705 | 0, // Line |
| 2698 | .none, // Underlying type | 2706 | .none, // Underlying type |
| 2699 | ty.abiSize(zcu) * 8, | 2707 | ty.abiSize(pt) * 8, |
| 2700 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2708 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, |
| 2701 | try o.builder.debugTuple(&full_fields), | 2709 | try o.builder.debugTuple(&full_fields), |
| 2702 | ); | 2710 | ); |
| 2703 | 2711 | ||
| ... | @@ -2718,13 +2726,13 @@ pub const Object = struct { | ... | @@ -2718,13 +2726,13 @@ pub const Object = struct { |
| 2718 | try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); | 2726 | try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); |
| 2719 | 2727 | ||
| 2720 | // Return type goes first. | 2728 | // Return type goes first. |
| 2721 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) { | 2729 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) { |
| 2722 | const sret = firstParamSRet(fn_info, zcu, target); | 2730 | const sret = firstParamSRet(fn_info, pt, target); |
| 2723 | const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); | 2731 | const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); |
| 2724 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); | 2732 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); |
| 2725 | 2733 | ||
| 2726 | if (sret) { | 2734 | if (sret) { |
| 2727 | const ptr_ty = try zcu.singleMutPtrType(Type.fromInterned(fn_info.return_type)); | 2735 | const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type)); |
| 2728 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); | 2736 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2729 | } | 2737 | } |
| 2730 | } else { | 2738 | } else { |
| ... | @@ -2732,18 +2740,18 @@ pub const Object = struct { | ... | @@ -2732,18 +2740,18 @@ pub const Object = struct { |
| 2732 | } | 2740 | } |
| 2733 | 2741 | ||
| 2734 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and | 2742 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and |
| 2735 | o.module.comp.config.any_error_tracing) | 2743 | zcu.comp.config.any_error_tracing) |
| 2736 | { | 2744 | { |
| 2737 | const ptr_ty = try zcu.singleMutPtrType(try o.getStackTraceType()); | 2745 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 2738 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); | 2746 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2739 | } | 2747 | } |
| 2740 | 2748 | ||
| 2741 | for (0..fn_info.param_types.len) |i| { | 2749 | for (0..fn_info.param_types.len) |i| { |
| 2742 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); | 2750 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); |
| 2743 | if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 2751 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2744 | 2752 | ||
| 2745 | if (isByRef(param_ty, zcu)) { | 2753 | if (isByRef(param_ty, pt)) { |
| 2746 | const ptr_ty = try zcu.singleMutPtrType(param_ty); | 2754 | const ptr_ty = try pt.singleMutPtrType(param_ty); |
| 2747 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); | 2755 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2748 | } else { | 2756 | } else { |
| 2749 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty)); | 2757 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty)); |
| ... | @@ -2770,7 +2778,7 @@ pub const Object = struct { | ... | @@ -2770,7 +2778,7 @@ pub const Object = struct { |
| 2770 | } | 2778 | } |
| 2771 | 2779 | ||
| 2772 | fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata { | 2780 | fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata { |
| 2773 | const zcu = o.module; | 2781 | const zcu = o.pt.zcu; |
| 2774 | const namespace = zcu.namespacePtr(namespace_index); | 2782 | const namespace = zcu.namespacePtr(namespace_index); |
| 2775 | const file_scope = namespace.fileScope(zcu); | 2783 | const file_scope = namespace.fileScope(zcu); |
| 2776 | if (namespace.parent == .none) return try o.getDebugFile(file_scope); | 2784 | if (namespace.parent == .none) return try o.getDebugFile(file_scope); |
| ... | @@ -2783,7 +2791,7 @@ pub const Object = struct { | ... | @@ -2783,7 +2791,7 @@ pub const Object = struct { |
| 2783 | } | 2791 | } |
| 2784 | 2792 | ||
| 2785 | fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata { | 2793 | fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata { |
| 2786 | const zcu = o.module; | 2794 | const zcu = o.pt.zcu; |
| 2787 | const decl = zcu.declPtr(decl_index); | 2795 | const decl = zcu.declPtr(decl_index); |
| 2788 | const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); | 2796 | const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); |
| 2789 | return o.builder.debugStructType( | 2797 | return o.builder.debugStructType( |
| ... | @@ -2799,7 +2807,7 @@ pub const Object = struct { | ... | @@ -2799,7 +2807,7 @@ pub const Object = struct { |
| 2799 | } | 2807 | } |
| 2800 | 2808 | ||
| 2801 | fn getStackTraceType(o: *Object) Allocator.Error!Type { | 2809 | fn getStackTraceType(o: *Object) Allocator.Error!Type { |
| 2802 | const zcu = o.module; | 2810 | const zcu = o.pt.zcu; |
| 2803 | 2811 | ||
| 2804 | const std_mod = zcu.std_mod; | 2812 | const std_mod = zcu.std_mod; |
| 2805 | const std_file_imported = zcu.importPkg(std_mod) catch unreachable; | 2813 | const std_file_imported = zcu.importPkg(std_mod) catch unreachable; |
| ... | @@ -2807,13 +2815,13 @@ pub const Object = struct { | ... | @@ -2807,13 +2815,13 @@ pub const Object = struct { |
| 2807 | const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls); | 2815 | const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls); |
| 2808 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index); | 2816 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index); |
| 2809 | const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace); | 2817 | const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace); |
| 2810 | const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = zcu }).?; | 2818 | const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }).?; |
| 2811 | 2819 | ||
| 2812 | const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls); | 2820 | const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls); |
| 2813 | // buffer is only used for int_type, `builtin` is a struct. | 2821 | // buffer is only used for int_type, `builtin` is a struct. |
| 2814 | const builtin_ty = zcu.declPtr(builtin_decl).val.toType(); | 2822 | const builtin_ty = zcu.declPtr(builtin_decl).val.toType(); |
| 2815 | const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?; | 2823 | const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?; |
| 2816 | const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = zcu }).?; | 2824 | const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Zcu.DeclAdapter{ .zcu = zcu }).?; |
| 2817 | const stack_trace_decl = zcu.declPtr(stack_trace_decl_index); | 2825 | const stack_trace_decl = zcu.declPtr(stack_trace_decl_index); |
| 2818 | 2826 | ||
| 2819 | // Sema should have ensured that StackTrace was analyzed. | 2827 | // Sema should have ensured that StackTrace was analyzed. |
| ... | @@ -2824,7 +2832,7 @@ pub const Object = struct { | ... | @@ -2824,7 +2832,7 @@ pub const Object = struct { |
| 2824 | fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 { | 2832 | fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 { |
| 2825 | var buffer = std.ArrayList(u8).init(o.gpa); | 2833 | var buffer = std.ArrayList(u8).init(o.gpa); |
| 2826 | errdefer buffer.deinit(); | 2834 | errdefer buffer.deinit(); |
| 2827 | try ty.print(buffer.writer(), o.module); | 2835 | try ty.print(buffer.writer(), o.pt); |
| 2828 | return buffer.toOwnedSliceSentinel(0); | 2836 | return buffer.toOwnedSliceSentinel(0); |
| 2829 | } | 2837 | } |
| 2830 | 2838 | ||
| ... | @@ -2835,7 +2843,8 @@ pub const Object = struct { | ... | @@ -2835,7 +2843,8 @@ pub const Object = struct { |
| 2835 | o: *Object, | 2843 | o: *Object, |
| 2836 | decl_index: InternPool.DeclIndex, | 2844 | decl_index: InternPool.DeclIndex, |
| 2837 | ) Allocator.Error!Builder.Function.Index { | 2845 | ) Allocator.Error!Builder.Function.Index { |
| 2838 | const zcu = o.module; | 2846 | const pt = o.pt; |
| 2847 | const zcu = pt.zcu; | ||
| 2839 | const ip = &zcu.intern_pool; | 2848 | const ip = &zcu.intern_pool; |
| 2840 | const gpa = o.gpa; | 2849 | const gpa = o.gpa; |
| 2841 | const decl = zcu.declPtr(decl_index); | 2850 | const decl = zcu.declPtr(decl_index); |
| ... | @@ -2848,7 +2857,7 @@ pub const Object = struct { | ... | @@ -2848,7 +2857,7 @@ pub const Object = struct { |
| 2848 | assert(decl.has_tv); | 2857 | assert(decl.has_tv); |
| 2849 | const fn_info = zcu.typeToFunc(zig_fn_type).?; | 2858 | const fn_info = zcu.typeToFunc(zig_fn_type).?; |
| 2850 | const target = owner_mod.resolved_target.result; | 2859 | const target = owner_mod.resolved_target.result; |
| 2851 | const sret = firstParamSRet(fn_info, zcu, target); | 2860 | const sret = firstParamSRet(fn_info, pt, target); |
| 2852 | 2861 | ||
| 2853 | const is_extern = decl.isExtern(zcu); | 2862 | const is_extern = decl.isExtern(zcu); |
| 2854 | const function_index = try o.builder.addFunction( | 2863 | const function_index = try o.builder.addFunction( |
| ... | @@ -2929,14 +2938,14 @@ pub const Object = struct { | ... | @@ -2929,14 +2938,14 @@ pub const Object = struct { |
| 2929 | .byval => { | 2938 | .byval => { |
| 2930 | const param_index = it.zig_index - 1; | 2939 | const param_index = it.zig_index - 1; |
| 2931 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 2940 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 2932 | if (!isByRef(param_ty, zcu)) { | 2941 | if (!isByRef(param_ty, pt)) { |
| 2933 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); | 2942 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 2934 | } | 2943 | } |
| 2935 | }, | 2944 | }, |
| 2936 | .byref => { | 2945 | .byref => { |
| 2937 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 2946 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 2938 | const param_llvm_ty = try o.lowerType(param_ty); | 2947 | const param_llvm_ty = try o.lowerType(param_ty); |
| 2939 | const alignment = param_ty.abiAlignment(zcu); | 2948 | const alignment = param_ty.abiAlignment(pt); |
| 2940 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty); | 2949 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty); |
| 2941 | }, | 2950 | }, |
| 2942 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), | 2951 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | @@ -2964,7 +2973,7 @@ pub const Object = struct { | ... | @@ -2964,7 +2973,7 @@ pub const Object = struct { |
| 2964 | attributes: *Builder.FunctionAttributes.Wip, | 2973 | attributes: *Builder.FunctionAttributes.Wip, |
| 2965 | owner_mod: *Package.Module, | 2974 | owner_mod: *Package.Module, |
| 2966 | ) Allocator.Error!void { | 2975 | ) Allocator.Error!void { |
| 2967 | const comp = o.module.comp; | 2976 | const comp = o.pt.zcu.comp; |
| 2968 | 2977 | ||
| 2969 | if (!owner_mod.red_zone) { | 2978 | if (!owner_mod.red_zone) { |
| 2970 | try attributes.addFnAttr(.noredzone, &o.builder); | 2979 | try attributes.addFnAttr(.noredzone, &o.builder); |
| ... | @@ -3039,7 +3048,7 @@ pub const Object = struct { | ... | @@ -3039,7 +3048,7 @@ pub const Object = struct { |
| 3039 | } | 3048 | } |
| 3040 | errdefer assert(o.anon_decl_map.remove(decl_val)); | 3049 | errdefer assert(o.anon_decl_map.remove(decl_val)); |
| 3041 | 3050 | ||
| 3042 | const mod = o.module; | 3051 | const mod = o.pt.zcu; |
| 3043 | const decl_ty = mod.intern_pool.typeOf(decl_val); | 3052 | const decl_ty = mod.intern_pool.typeOf(decl_val); |
| 3044 | 3053 | ||
| 3045 | const variable_index = try o.builder.addVariable( | 3054 | const variable_index = try o.builder.addVariable( |
| ... | @@ -3065,7 +3074,7 @@ pub const Object = struct { | ... | @@ -3065,7 +3074,7 @@ pub const Object = struct { |
| 3065 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable; | 3074 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable; |
| 3066 | errdefer assert(o.decl_map.remove(decl_index)); | 3075 | errdefer assert(o.decl_map.remove(decl_index)); |
| 3067 | 3076 | ||
| 3068 | const zcu = o.module; | 3077 | const zcu = o.pt.zcu; |
| 3069 | const decl = zcu.declPtr(decl_index); | 3078 | const decl = zcu.declPtr(decl_index); |
| 3070 | const is_extern = decl.isExtern(zcu); | 3079 | const is_extern = decl.isExtern(zcu); |
| 3071 | 3080 | ||
| ... | @@ -3100,11 +3109,12 @@ pub const Object = struct { | ... | @@ -3100,11 +3109,12 @@ pub const Object = struct { |
| 3100 | } | 3109 | } |
| 3101 | 3110 | ||
| 3102 | fn errorIntType(o: *Object) Allocator.Error!Builder.Type { | 3111 | fn errorIntType(o: *Object) Allocator.Error!Builder.Type { |
| 3103 | return o.builder.intType(o.module.errorSetBits()); | 3112 | return o.builder.intType(o.pt.zcu.errorSetBits()); |
| 3104 | } | 3113 | } |
| 3105 | 3114 | ||
| 3106 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { | 3115 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { |
| 3107 | const mod = o.module; | 3116 | const pt = o.pt; |
| 3117 | const mod = pt.zcu; | ||
| 3108 | const target = mod.getTarget(); | 3118 | const target = mod.getTarget(); |
| 3109 | const ip = &mod.intern_pool; | 3119 | const ip = &mod.intern_pool; |
| 3110 | return switch (t.toIntern()) { | 3120 | return switch (t.toIntern()) { |
| ... | @@ -3230,7 +3240,7 @@ pub const Object = struct { | ... | @@ -3230,7 +3240,7 @@ pub const Object = struct { |
| 3230 | ), | 3240 | ), |
| 3231 | .opt_type => |child_ty| { | 3241 | .opt_type => |child_ty| { |
| 3232 | // Must stay in sync with `opt_payload` logic in `lowerPtr`. | 3242 | // Must stay in sync with `opt_payload` logic in `lowerPtr`. |
| 3233 | if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(mod)) return .i8; | 3243 | if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(pt)) return .i8; |
| 3234 | 3244 | ||
| 3235 | const payload_ty = try o.lowerType(Type.fromInterned(child_ty)); | 3245 | const payload_ty = try o.lowerType(Type.fromInterned(child_ty)); |
| 3236 | if (t.optionalReprIsPayload(mod)) return payload_ty; | 3246 | if (t.optionalReprIsPayload(mod)) return payload_ty; |
| ... | @@ -3238,8 +3248,8 @@ pub const Object = struct { | ... | @@ -3238,8 +3248,8 @@ pub const Object = struct { |
| 3238 | comptime assert(optional_layout_version == 3); | 3248 | comptime assert(optional_layout_version == 3); |
| 3239 | var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined }; | 3249 | var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined }; |
| 3240 | var fields_len: usize = 2; | 3250 | var fields_len: usize = 2; |
| 3241 | const offset = Type.fromInterned(child_ty).abiSize(mod) + 1; | 3251 | const offset = Type.fromInterned(child_ty).abiSize(pt) + 1; |
| 3242 | const abi_size = t.abiSize(mod); | 3252 | const abi_size = t.abiSize(pt); |
| 3243 | const padding_len = abi_size - offset; | 3253 | const padding_len = abi_size - offset; |
| 3244 | if (padding_len > 0) { | 3254 | if (padding_len > 0) { |
| 3245 | fields[2] = try o.builder.arrayType(padding_len, .i8); | 3255 | fields[2] = try o.builder.arrayType(padding_len, .i8); |
| ... | @@ -3252,16 +3262,16 @@ pub const Object = struct { | ... | @@ -3252,16 +3262,16 @@ pub const Object = struct { |
| 3252 | // Must stay in sync with `codegen.errUnionPayloadOffset`. | 3262 | // Must stay in sync with `codegen.errUnionPayloadOffset`. |
| 3253 | // See logic in `lowerPtr`. | 3263 | // See logic in `lowerPtr`. |
| 3254 | const error_type = try o.errorIntType(); | 3264 | const error_type = try o.errorIntType(); |
| 3255 | if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(mod)) | 3265 | if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(pt)) |
| 3256 | return error_type; | 3266 | return error_type; |
| 3257 | const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type)); | 3267 | const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type)); |
| 3258 | const err_int_ty = try mod.errorIntType(); | 3268 | const err_int_ty = try o.pt.errorIntType(); |
| 3259 | 3269 | ||
| 3260 | const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(mod); | 3270 | const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(pt); |
| 3261 | const error_align = err_int_ty.abiAlignment(mod); | 3271 | const error_align = err_int_ty.abiAlignment(pt); |
| 3262 | 3272 | ||
| 3263 | const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(mod); | 3273 | const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(pt); |
| 3264 | const error_size = err_int_ty.abiSize(mod); | 3274 | const error_size = err_int_ty.abiSize(pt); |
| 3265 | 3275 | ||
| 3266 | var fields: [3]Builder.Type = undefined; | 3276 | var fields: [3]Builder.Type = undefined; |
| 3267 | var fields_len: usize = 2; | 3277 | var fields_len: usize = 2; |
| ... | @@ -3317,12 +3327,12 @@ pub const Object = struct { | ... | @@ -3317,12 +3327,12 @@ pub const Object = struct { |
| 3317 | var it = struct_type.iterateRuntimeOrder(ip); | 3327 | var it = struct_type.iterateRuntimeOrder(ip); |
| 3318 | while (it.next()) |field_index| { | 3328 | while (it.next()) |field_index| { |
| 3319 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 3329 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 3320 | const field_align = mod.structFieldAlignment( | 3330 | const field_align = pt.structFieldAlignment( |
| 3321 | struct_type.fieldAlign(ip, field_index), | 3331 | struct_type.fieldAlign(ip, field_index), |
| 3322 | field_ty, | 3332 | field_ty, |
| 3323 | struct_type.layout, | 3333 | struct_type.layout, |
| 3324 | ); | 3334 | ); |
| 3325 | const field_ty_align = field_ty.abiAlignment(mod); | 3335 | const field_ty_align = field_ty.abiAlignment(pt); |
| 3326 | if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed"; | 3336 | if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed"; |
| 3327 | big_align = big_align.max(field_align); | 3337 | big_align = big_align.max(field_align); |
| 3328 | const prev_offset = offset; | 3338 | const prev_offset = offset; |
| ... | @@ -3334,7 +3344,7 @@ pub const Object = struct { | ... | @@ -3334,7 +3344,7 @@ pub const Object = struct { |
| 3334 | try o.builder.arrayType(padding_len, .i8), | 3344 | try o.builder.arrayType(padding_len, .i8), |
| 3335 | ); | 3345 | ); |
| 3336 | 3346 | ||
| 3337 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3347 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3338 | // This is a zero-bit field. If there are runtime bits after this field, | 3348 | // This is a zero-bit field. If there are runtime bits after this field, |
| 3339 | // map to the next LLVM field (which we know exists): otherwise, don't | 3349 | // map to the next LLVM field (which we know exists): otherwise, don't |
| 3340 | // map the field, indicating it's at the end of the struct. | 3350 | // map the field, indicating it's at the end of the struct. |
| ... | @@ -3353,7 +3363,7 @@ pub const Object = struct { | ... | @@ -3353,7 +3363,7 @@ pub const Object = struct { |
| 3353 | }, @intCast(llvm_field_types.items.len)); | 3363 | }, @intCast(llvm_field_types.items.len)); |
| 3354 | try llvm_field_types.append(o.gpa, try o.lowerType(field_ty)); | 3364 | try llvm_field_types.append(o.gpa, try o.lowerType(field_ty)); |
| 3355 | 3365 | ||
| 3356 | offset += field_ty.abiSize(mod); | 3366 | offset += field_ty.abiSize(pt); |
| 3357 | } | 3367 | } |
| 3358 | { | 3368 | { |
| 3359 | const prev_offset = offset; | 3369 | const prev_offset = offset; |
| ... | @@ -3386,7 +3396,7 @@ pub const Object = struct { | ... | @@ -3386,7 +3396,7 @@ pub const Object = struct { |
| 3386 | var offset: u64 = 0; | 3396 | var offset: u64 = 0; |
| 3387 | var big_align: InternPool.Alignment = .none; | 3397 | var big_align: InternPool.Alignment = .none; |
| 3388 | 3398 | ||
| 3389 | const struct_size = t.abiSize(mod); | 3399 | const struct_size = t.abiSize(pt); |
| 3390 | 3400 | ||
| 3391 | for ( | 3401 | for ( |
| 3392 | anon_struct_type.types.get(ip), | 3402 | anon_struct_type.types.get(ip), |
| ... | @@ -3395,7 +3405,7 @@ pub const Object = struct { | ... | @@ -3395,7 +3405,7 @@ pub const Object = struct { |
| 3395 | ) |field_ty, field_val, field_index| { | 3405 | ) |field_ty, field_val, field_index| { |
| 3396 | if (field_val != .none) continue; | 3406 | if (field_val != .none) continue; |
| 3397 | 3407 | ||
| 3398 | const field_align = Type.fromInterned(field_ty).abiAlignment(mod); | 3408 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); |
| 3399 | big_align = big_align.max(field_align); | 3409 | big_align = big_align.max(field_align); |
| 3400 | const prev_offset = offset; | 3410 | const prev_offset = offset; |
| 3401 | offset = field_align.forward(offset); | 3411 | offset = field_align.forward(offset); |
| ... | @@ -3405,7 +3415,7 @@ pub const Object = struct { | ... | @@ -3405,7 +3415,7 @@ pub const Object = struct { |
| 3405 | o.gpa, | 3415 | o.gpa, |
| 3406 | try o.builder.arrayType(padding_len, .i8), | 3416 | try o.builder.arrayType(padding_len, .i8), |
| 3407 | ); | 3417 | ); |
| 3408 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) { | 3418 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) { |
| 3409 | // This is a zero-bit field. If there are runtime bits after this field, | 3419 | // This is a zero-bit field. If there are runtime bits after this field, |
| 3410 | // map to the next LLVM field (which we know exists): otherwise, don't | 3420 | // map to the next LLVM field (which we know exists): otherwise, don't |
| 3411 | // map the field, indicating it's at the end of the struct. | 3421 | // map the field, indicating it's at the end of the struct. |
| ... | @@ -3423,7 +3433,7 @@ pub const Object = struct { | ... | @@ -3423,7 +3433,7 @@ pub const Object = struct { |
| 3423 | }, @intCast(llvm_field_types.items.len)); | 3433 | }, @intCast(llvm_field_types.items.len)); |
| 3424 | try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty))); | 3434 | try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty))); |
| 3425 | 3435 | ||
| 3426 | offset += Type.fromInterned(field_ty).abiSize(mod); | 3436 | offset += Type.fromInterned(field_ty).abiSize(pt); |
| 3427 | } | 3437 | } |
| 3428 | { | 3438 | { |
| 3429 | const prev_offset = offset; | 3439 | const prev_offset = offset; |
| ... | @@ -3440,10 +3450,10 @@ pub const Object = struct { | ... | @@ -3440,10 +3450,10 @@ pub const Object = struct { |
| 3440 | if (o.type_map.get(t.toIntern())) |value| return value; | 3450 | if (o.type_map.get(t.toIntern())) |value| return value; |
| 3441 | 3451 | ||
| 3442 | const union_obj = ip.loadUnionType(t.toIntern()); | 3452 | const union_obj = ip.loadUnionType(t.toIntern()); |
| 3443 | const layout = mod.getUnionLayout(union_obj); | 3453 | const layout = pt.getUnionLayout(union_obj); |
| 3444 | 3454 | ||
| 3445 | if (union_obj.flagsPtr(ip).layout == .@"packed") { | 3455 | if (union_obj.flagsPtr(ip).layout == .@"packed") { |
| 3446 | const int_ty = try o.builder.intType(@intCast(t.bitSize(mod))); | 3456 | const int_ty = try o.builder.intType(@intCast(t.bitSize(pt))); |
| 3447 | try o.type_map.put(o.gpa, t.toIntern(), int_ty); | 3457 | try o.type_map.put(o.gpa, t.toIntern(), int_ty); |
| 3448 | return int_ty; | 3458 | return int_ty; |
| 3449 | } | 3459 | } |
| ... | @@ -3552,18 +3562,20 @@ pub const Object = struct { | ... | @@ -3552,18 +3562,20 @@ pub const Object = struct { |
| 3552 | /// being a zero bit type, but it should still be lowered as an i8 in such case. | 3562 | /// being a zero bit type, but it should still be lowered as an i8 in such case. |
| 3553 | /// There are other similar cases handled here as well. | 3563 | /// There are other similar cases handled here as well. |
| 3554 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type { | 3564 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type { |
| 3555 | const mod = o.module; | 3565 | const pt = o.pt; |
| 3566 | const mod = pt.zcu; | ||
| 3556 | const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { | 3567 | const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { |
| 3557 | .Opaque => true, | 3568 | .Opaque => true, |
| 3558 | .Fn => !mod.typeToFunc(elem_ty).?.is_generic, | 3569 | .Fn => !mod.typeToFunc(elem_ty).?.is_generic, |
| 3559 | .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod), | 3570 | .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(pt), |
| 3560 | else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), | 3571 | else => elem_ty.hasRuntimeBitsIgnoreComptime(pt), |
| 3561 | }; | 3572 | }; |
| 3562 | return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8; | 3573 | return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8; |
| 3563 | } | 3574 | } |
| 3564 | 3575 | ||
| 3565 | fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { | 3576 | fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 3566 | const mod = o.module; | 3577 | const pt = o.pt; |
| 3578 | const mod = pt.zcu; | ||
| 3567 | const ip = &mod.intern_pool; | 3579 | const ip = &mod.intern_pool; |
| 3568 | const target = mod.getTarget(); | 3580 | const target = mod.getTarget(); |
| 3569 | const ret_ty = try lowerFnRetTy(o, fn_info); | 3581 | const ret_ty = try lowerFnRetTy(o, fn_info); |
| ... | @@ -3571,14 +3583,14 @@ pub const Object = struct { | ... | @@ -3571,14 +3583,14 @@ pub const Object = struct { |
| 3571 | var llvm_params = std.ArrayListUnmanaged(Builder.Type){}; | 3583 | var llvm_params = std.ArrayListUnmanaged(Builder.Type){}; |
| 3572 | defer llvm_params.deinit(o.gpa); | 3584 | defer llvm_params.deinit(o.gpa); |
| 3573 | 3585 | ||
| 3574 | if (firstParamSRet(fn_info, mod, target)) { | 3586 | if (firstParamSRet(fn_info, pt, target)) { |
| 3575 | try llvm_params.append(o.gpa, .ptr); | 3587 | try llvm_params.append(o.gpa, .ptr); |
| 3576 | } | 3588 | } |
| 3577 | 3589 | ||
| 3578 | if (Type.fromInterned(fn_info.return_type).isError(mod) and | 3590 | if (Type.fromInterned(fn_info.return_type).isError(mod) and |
| 3579 | mod.comp.config.any_error_tracing) | 3591 | mod.comp.config.any_error_tracing) |
| 3580 | { | 3592 | { |
| 3581 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); | 3593 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 3582 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); | 3594 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); |
| 3583 | } | 3595 | } |
| 3584 | 3596 | ||
| ... | @@ -3595,7 +3607,7 @@ pub const Object = struct { | ... | @@ -3595,7 +3607,7 @@ pub const Object = struct { |
| 3595 | .abi_sized_int => { | 3607 | .abi_sized_int => { |
| 3596 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 3608 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 3597 | try llvm_params.append(o.gpa, try o.builder.intType( | 3609 | try llvm_params.append(o.gpa, try o.builder.intType( |
| 3598 | @intCast(param_ty.abiSize(mod) * 8), | 3610 | @intCast(param_ty.abiSize(pt) * 8), |
| 3599 | )); | 3611 | )); |
| 3600 | }, | 3612 | }, |
| 3601 | .slice => { | 3613 | .slice => { |
| ... | @@ -3633,7 +3645,8 @@ pub const Object = struct { | ... | @@ -3633,7 +3645,8 @@ pub const Object = struct { |
| 3633 | } | 3645 | } |
| 3634 | 3646 | ||
| 3635 | fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant { | 3647 | fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant { |
| 3636 | const mod = o.module; | 3648 | const pt = o.pt; |
| 3649 | const mod = pt.zcu; | ||
| 3637 | const ip = &mod.intern_pool; | 3650 | const ip = &mod.intern_pool; |
| 3638 | const target = mod.getTarget(); | 3651 | const target = mod.getTarget(); |
| 3639 | 3652 | ||
| ... | @@ -3666,15 +3679,15 @@ pub const Object = struct { | ... | @@ -3666,15 +3679,15 @@ pub const Object = struct { |
| 3666 | var running_int = try o.builder.intConst(llvm_int_ty, 0); | 3679 | var running_int = try o.builder.intConst(llvm_int_ty, 0); |
| 3667 | var running_bits: u16 = 0; | 3680 | var running_bits: u16 = 0; |
| 3668 | for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| { | 3681 | for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| { |
| 3669 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue; | 3682 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 3670 | 3683 | ||
| 3671 | const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits); | 3684 | const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits); |
| 3672 | const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(mod, field_index)).toIntern()); | 3685 | const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(pt, field_index)).toIntern()); |
| 3673 | const shifted = try o.builder.binConst(.shl, field_val, shift_rhs); | 3686 | const shifted = try o.builder.binConst(.shl, field_val, shift_rhs); |
| 3674 | 3687 | ||
| 3675 | running_int = try o.builder.binConst(.xor, running_int, shifted); | 3688 | running_int = try o.builder.binConst(.xor, running_int, shifted); |
| 3676 | 3689 | ||
| 3677 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod)); | 3690 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt)); |
| 3678 | running_bits += ty_bit_size; | 3691 | running_bits += ty_bit_size; |
| 3679 | } | 3692 | } |
| 3680 | return running_int; | 3693 | return running_int; |
| ... | @@ -3683,7 +3696,7 @@ pub const Object = struct { | ... | @@ -3683,7 +3696,7 @@ pub const Object = struct { |
| 3683 | else => unreachable, | 3696 | else => unreachable, |
| 3684 | }, | 3697 | }, |
| 3685 | .un => |un| { | 3698 | .un => |un| { |
| 3686 | const layout = ty.unionGetLayout(mod); | 3699 | const layout = ty.unionGetLayout(pt); |
| 3687 | if (layout.payload_size == 0) return o.lowerValue(un.tag); | 3700 | if (layout.payload_size == 0) return o.lowerValue(un.tag); |
| 3688 | 3701 | ||
| 3689 | const union_obj = mod.typeToUnion(ty).?; | 3702 | const union_obj = mod.typeToUnion(ty).?; |
| ... | @@ -3701,7 +3714,7 @@ pub const Object = struct { | ... | @@ -3701,7 +3714,7 @@ pub const Object = struct { |
| 3701 | } | 3714 | } |
| 3702 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | 3715 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| 3703 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 3716 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3704 | if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(llvm_int_ty, 0); | 3717 | if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(llvm_int_ty, 0); |
| 3705 | return o.lowerValueToInt(llvm_int_ty, un.val); | 3718 | return o.lowerValueToInt(llvm_int_ty, un.val); |
| 3706 | }, | 3719 | }, |
| 3707 | .simple_value => |simple_value| switch (simple_value) { | 3720 | .simple_value => |simple_value| switch (simple_value) { |
| ... | @@ -3715,7 +3728,7 @@ pub const Object = struct { | ... | @@ -3715,7 +3728,7 @@ pub const Object = struct { |
| 3715 | .opt => {}, // pointer like optional expected | 3728 | .opt => {}, // pointer like optional expected |
| 3716 | else => unreachable, | 3729 | else => unreachable, |
| 3717 | } | 3730 | } |
| 3718 | const bits = ty.bitSize(mod); | 3731 | const bits = ty.bitSize(pt); |
| 3719 | const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8); | 3732 | const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8); |
| 3720 | 3733 | ||
| 3721 | var stack = std.heap.stackFallback(32, o.gpa); | 3734 | var stack = std.heap.stackFallback(32, o.gpa); |
| ... | @@ -3729,12 +3742,7 @@ pub const Object = struct { | ... | @@ -3729,12 +3742,7 @@ pub const Object = struct { |
| 3729 | defer allocator.free(limbs); | 3742 | defer allocator.free(limbs); |
| 3730 | @memset(limbs, 0); | 3743 | @memset(limbs, 0); |
| 3731 | 3744 | ||
| 3732 | val.writeToPackedMemory( | 3745 | val.writeToPackedMemory(ty, pt, std.mem.sliceAsBytes(limbs)[0..bytes], 0) catch unreachable; |
| 3733 | ty, | ||
| 3734 | mod, | ||
| 3735 | std.mem.sliceAsBytes(limbs)[0..bytes], | ||
| 3736 | 0, | ||
| 3737 | ) catch unreachable; | ||
| 3738 | 3746 | ||
| 3739 | if (builtin.target.cpu.arch.endian() == .little) { | 3747 | if (builtin.target.cpu.arch.endian() == .little) { |
| 3740 | if (target.cpu.arch.endian() == .big) | 3748 | if (target.cpu.arch.endian() == .big) |
| ... | @@ -3752,7 +3760,8 @@ pub const Object = struct { | ... | @@ -3752,7 +3760,8 @@ pub const Object = struct { |
| 3752 | } | 3760 | } |
| 3753 | 3761 | ||
| 3754 | fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant { | 3762 | fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant { |
| 3755 | const mod = o.module; | 3763 | const pt = o.pt; |
| 3764 | const mod = pt.zcu; | ||
| 3756 | const ip = &mod.intern_pool; | 3765 | const ip = &mod.intern_pool; |
| 3757 | const target = mod.getTarget(); | 3766 | const target = mod.getTarget(); |
| 3758 | 3767 | ||
| ... | @@ -3811,7 +3820,7 @@ pub const Object = struct { | ... | @@ -3811,7 +3820,7 @@ pub const Object = struct { |
| 3811 | }, | 3820 | }, |
| 3812 | .int => { | 3821 | .int => { |
| 3813 | var bigint_space: Value.BigIntSpace = undefined; | 3822 | var bigint_space: Value.BigIntSpace = undefined; |
| 3814 | const bigint = val.toBigInt(&bigint_space, mod); | 3823 | const bigint = val.toBigInt(&bigint_space, pt); |
| 3815 | return lowerBigInt(o, ty, bigint); | 3824 | return lowerBigInt(o, ty, bigint); |
| 3816 | }, | 3825 | }, |
| 3817 | .err => |err| { | 3826 | .err => |err| { |
| ... | @@ -3821,24 +3830,24 @@ pub const Object = struct { | ... | @@ -3821,24 +3830,24 @@ pub const Object = struct { |
| 3821 | }, | 3830 | }, |
| 3822 | .error_union => |error_union| { | 3831 | .error_union => |error_union| { |
| 3823 | const err_val = switch (error_union.val) { | 3832 | const err_val = switch (error_union.val) { |
| 3824 | .err_name => |err_name| try mod.intern(.{ .err = .{ | 3833 | .err_name => |err_name| try pt.intern(.{ .err = .{ |
| 3825 | .ty = ty.errorUnionSet(mod).toIntern(), | 3834 | .ty = ty.errorUnionSet(mod).toIntern(), |
| 3826 | .name = err_name, | 3835 | .name = err_name, |
| 3827 | } }), | 3836 | } }), |
| 3828 | .payload => (try mod.intValue(try mod.errorIntType(), 0)).toIntern(), | 3837 | .payload => (try pt.intValue(try pt.errorIntType(), 0)).toIntern(), |
| 3829 | }; | 3838 | }; |
| 3830 | const err_int_ty = try mod.errorIntType(); | 3839 | const err_int_ty = try pt.errorIntType(); |
| 3831 | const payload_type = ty.errorUnionPayload(mod); | 3840 | const payload_type = ty.errorUnionPayload(mod); |
| 3832 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3841 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3833 | // We use the error type directly as the type. | 3842 | // We use the error type directly as the type. |
| 3834 | return o.lowerValue(err_val); | 3843 | return o.lowerValue(err_val); |
| 3835 | } | 3844 | } |
| 3836 | 3845 | ||
| 3837 | const payload_align = payload_type.abiAlignment(mod); | 3846 | const payload_align = payload_type.abiAlignment(pt); |
| 3838 | const error_align = err_int_ty.abiAlignment(mod); | 3847 | const error_align = err_int_ty.abiAlignment(pt); |
| 3839 | const llvm_error_value = try o.lowerValue(err_val); | 3848 | const llvm_error_value = try o.lowerValue(err_val); |
| 3840 | const llvm_payload_value = try o.lowerValue(switch (error_union.val) { | 3849 | const llvm_payload_value = try o.lowerValue(switch (error_union.val) { |
| 3841 | .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }), | 3850 | .err_name => try pt.intern(.{ .undef = payload_type.toIntern() }), |
| 3842 | .payload => |payload| payload, | 3851 | .payload => |payload| payload, |
| 3843 | }); | 3852 | }); |
| 3844 | 3853 | ||
| ... | @@ -3869,16 +3878,16 @@ pub const Object = struct { | ... | @@ -3869,16 +3878,16 @@ pub const Object = struct { |
| 3869 | .enum_tag => |enum_tag| o.lowerValue(enum_tag.int), | 3878 | .enum_tag => |enum_tag| o.lowerValue(enum_tag.int), |
| 3870 | .float => switch (ty.floatBits(target)) { | 3879 | .float => switch (ty.floatBits(target)) { |
| 3871 | 16 => if (backendSupportsF16(target)) | 3880 | 16 => if (backendSupportsF16(target)) |
| 3872 | try o.builder.halfConst(val.toFloat(f16, mod)) | 3881 | try o.builder.halfConst(val.toFloat(f16, pt)) |
| 3873 | else | 3882 | else |
| 3874 | try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, mod)))), | 3883 | try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, pt)))), |
| 3875 | 32 => try o.builder.floatConst(val.toFloat(f32, mod)), | 3884 | 32 => try o.builder.floatConst(val.toFloat(f32, pt)), |
| 3876 | 64 => try o.builder.doubleConst(val.toFloat(f64, mod)), | 3885 | 64 => try o.builder.doubleConst(val.toFloat(f64, pt)), |
| 3877 | 80 => if (backendSupportsF80(target)) | 3886 | 80 => if (backendSupportsF80(target)) |
| 3878 | try o.builder.x86_fp80Const(val.toFloat(f80, mod)) | 3887 | try o.builder.x86_fp80Const(val.toFloat(f80, pt)) |
| 3879 | else | 3888 | else |
| 3880 | try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, mod)))), | 3889 | try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, pt)))), |
| 3881 | 128 => try o.builder.fp128Const(val.toFloat(f128, mod)), | 3890 | 128 => try o.builder.fp128Const(val.toFloat(f128, pt)), |
| 3882 | else => unreachable, | 3891 | else => unreachable, |
| 3883 | }, | 3892 | }, |
| 3884 | .ptr => try o.lowerPtr(arg_val, 0), | 3893 | .ptr => try o.lowerPtr(arg_val, 0), |
| ... | @@ -3891,7 +3900,7 @@ pub const Object = struct { | ... | @@ -3891,7 +3900,7 @@ pub const Object = struct { |
| 3891 | const payload_ty = ty.optionalChild(mod); | 3900 | const payload_ty = ty.optionalChild(mod); |
| 3892 | 3901 | ||
| 3893 | const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none)); | 3902 | const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none)); |
| 3894 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3903 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 3895 | return non_null_bit; | 3904 | return non_null_bit; |
| 3896 | } | 3905 | } |
| 3897 | const llvm_ty = try o.lowerType(ty); | 3906 | const llvm_ty = try o.lowerType(ty); |
| ... | @@ -3909,7 +3918,7 @@ pub const Object = struct { | ... | @@ -3909,7 +3918,7 @@ pub const Object = struct { |
| 3909 | var fields: [3]Builder.Type = undefined; | 3918 | var fields: [3]Builder.Type = undefined; |
| 3910 | var vals: [3]Builder.Constant = undefined; | 3919 | var vals: [3]Builder.Constant = undefined; |
| 3911 | vals[0] = try o.lowerValue(switch (opt.val) { | 3920 | vals[0] = try o.lowerValue(switch (opt.val) { |
| 3912 | .none => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 3921 | .none => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 3913 | else => |payload| payload, | 3922 | else => |payload| payload, |
| 3914 | }); | 3923 | }); |
| 3915 | vals[1] = non_null_bit; | 3924 | vals[1] = non_null_bit; |
| ... | @@ -4058,9 +4067,9 @@ pub const Object = struct { | ... | @@ -4058,9 +4067,9 @@ pub const Object = struct { |
| 4058 | 0.., | 4067 | 0.., |
| 4059 | ) |field_ty, field_val, field_index| { | 4068 | ) |field_ty, field_val, field_index| { |
| 4060 | if (field_val != .none) continue; | 4069 | if (field_val != .none) continue; |
| 4061 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue; | 4070 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 4062 | 4071 | ||
| 4063 | const field_align = Type.fromInterned(field_ty).abiAlignment(mod); | 4072 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); |
| 4064 | big_align = big_align.max(field_align); | 4073 | big_align = big_align.max(field_align); |
| 4065 | const prev_offset = offset; | 4074 | const prev_offset = offset; |
| 4066 | offset = field_align.forward(offset); | 4075 | offset = field_align.forward(offset); |
| ... | @@ -4076,13 +4085,13 @@ pub const Object = struct { | ... | @@ -4076,13 +4085,13 @@ pub const Object = struct { |
| 4076 | } | 4085 | } |
| 4077 | 4086 | ||
| 4078 | vals[llvm_index] = | 4087 | vals[llvm_index] = |
| 4079 | try o.lowerValue((try val.fieldValue(mod, field_index)).toIntern()); | 4088 | try o.lowerValue((try val.fieldValue(pt, field_index)).toIntern()); |
| 4080 | fields[llvm_index] = vals[llvm_index].typeOf(&o.builder); | 4089 | fields[llvm_index] = vals[llvm_index].typeOf(&o.builder); |
| 4081 | if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index]) | 4090 | if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index]) |
| 4082 | need_unnamed = true; | 4091 | need_unnamed = true; |
| 4083 | llvm_index += 1; | 4092 | llvm_index += 1; |
| 4084 | 4093 | ||
| 4085 | offset += Type.fromInterned(field_ty).abiSize(mod); | 4094 | offset += Type.fromInterned(field_ty).abiSize(pt); |
| 4086 | } | 4095 | } |
| 4087 | { | 4096 | { |
| 4088 | const prev_offset = offset; | 4097 | const prev_offset = offset; |
| ... | @@ -4109,7 +4118,7 @@ pub const Object = struct { | ... | @@ -4109,7 +4118,7 @@ pub const Object = struct { |
| 4109 | if (struct_type.layout == .@"packed") { | 4118 | if (struct_type.layout == .@"packed") { |
| 4110 | comptime assert(Type.packed_struct_layout_version == 2); | 4119 | comptime assert(Type.packed_struct_layout_version == 2); |
| 4111 | 4120 | ||
| 4112 | const bits = ty.bitSize(mod); | 4121 | const bits = ty.bitSize(pt); |
| 4113 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); | 4122 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4114 | 4123 | ||
| 4115 | return o.lowerValueToInt(llvm_int_ty, arg_val); | 4124 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | @@ -4138,7 +4147,7 @@ pub const Object = struct { | ... | @@ -4138,7 +4147,7 @@ pub const Object = struct { |
| 4138 | var field_it = struct_type.iterateRuntimeOrder(ip); | 4147 | var field_it = struct_type.iterateRuntimeOrder(ip); |
| 4139 | while (field_it.next()) |field_index| { | 4148 | while (field_it.next()) |field_index| { |
| 4140 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 4149 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 4141 | const field_align = mod.structFieldAlignment( | 4150 | const field_align = pt.structFieldAlignment( |
| 4142 | struct_type.fieldAlign(ip, field_index), | 4151 | struct_type.fieldAlign(ip, field_index), |
| 4143 | field_ty, | 4152 | field_ty, |
| 4144 | struct_type.layout, | 4153 | struct_type.layout, |
| ... | @@ -4158,20 +4167,20 @@ pub const Object = struct { | ... | @@ -4158,20 +4167,20 @@ pub const Object = struct { |
| 4158 | llvm_index += 1; | 4167 | llvm_index += 1; |
| 4159 | } | 4168 | } |
| 4160 | 4169 | ||
| 4161 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4170 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4162 | // This is a zero-bit field - we only needed it for the alignment. | 4171 | // This is a zero-bit field - we only needed it for the alignment. |
| 4163 | continue; | 4172 | continue; |
| 4164 | } | 4173 | } |
| 4165 | 4174 | ||
| 4166 | vals[llvm_index] = try o.lowerValue( | 4175 | vals[llvm_index] = try o.lowerValue( |
| 4167 | (try val.fieldValue(mod, field_index)).toIntern(), | 4176 | (try val.fieldValue(pt, field_index)).toIntern(), |
| 4168 | ); | 4177 | ); |
| 4169 | fields[llvm_index] = vals[llvm_index].typeOf(&o.builder); | 4178 | fields[llvm_index] = vals[llvm_index].typeOf(&o.builder); |
| 4170 | if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index]) | 4179 | if (fields[llvm_index] != struct_ty.structFields(&o.builder)[llvm_index]) |
| 4171 | need_unnamed = true; | 4180 | need_unnamed = true; |
| 4172 | llvm_index += 1; | 4181 | llvm_index += 1; |
| 4173 | 4182 | ||
| 4174 | offset += field_ty.abiSize(mod); | 4183 | offset += field_ty.abiSize(pt); |
| 4175 | } | 4184 | } |
| 4176 | { | 4185 | { |
| 4177 | const prev_offset = offset; | 4186 | const prev_offset = offset; |
| ... | @@ -4195,7 +4204,7 @@ pub const Object = struct { | ... | @@ -4195,7 +4204,7 @@ pub const Object = struct { |
| 4195 | }, | 4204 | }, |
| 4196 | .un => |un| { | 4205 | .un => |un| { |
| 4197 | const union_ty = try o.lowerType(ty); | 4206 | const union_ty = try o.lowerType(ty); |
| 4198 | const layout = ty.unionGetLayout(mod); | 4207 | const layout = ty.unionGetLayout(pt); |
| 4199 | if (layout.payload_size == 0) return o.lowerValue(un.tag); | 4208 | if (layout.payload_size == 0) return o.lowerValue(un.tag); |
| 4200 | 4209 | ||
| 4201 | const union_obj = mod.typeToUnion(ty).?; | 4210 | const union_obj = mod.typeToUnion(ty).?; |
| ... | @@ -4206,8 +4215,8 @@ pub const Object = struct { | ... | @@ -4206,8 +4215,8 @@ pub const Object = struct { |
| 4206 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | 4215 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| 4207 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 4216 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 4208 | if (container_layout == .@"packed") { | 4217 | if (container_layout == .@"packed") { |
| 4209 | if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(union_ty, 0); | 4218 | if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(union_ty, 0); |
| 4210 | const bits = ty.bitSize(mod); | 4219 | const bits = ty.bitSize(pt); |
| 4211 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); | 4220 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4212 | 4221 | ||
| 4213 | return o.lowerValueToInt(llvm_int_ty, arg_val); | 4222 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | @@ -4219,7 +4228,7 @@ pub const Object = struct { | ... | @@ -4219,7 +4228,7 @@ pub const Object = struct { |
| 4219 | // must pointer cast to the expected type before accessing the union. | 4228 | // must pointer cast to the expected type before accessing the union. |
| 4220 | need_unnamed = layout.most_aligned_field != field_index; | 4229 | need_unnamed = layout.most_aligned_field != field_index; |
| 4221 | 4230 | ||
| 4222 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4231 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4223 | const padding_len = layout.payload_size; | 4232 | const padding_len = layout.payload_size; |
| 4224 | break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8)); | 4233 | break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8)); |
| 4225 | } | 4234 | } |
| ... | @@ -4228,7 +4237,7 @@ pub const Object = struct { | ... | @@ -4228,7 +4237,7 @@ pub const Object = struct { |
| 4228 | if (payload_ty != union_ty.structFields(&o.builder)[ | 4237 | if (payload_ty != union_ty.structFields(&o.builder)[ |
| 4229 | @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)) | 4238 | @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)) |
| 4230 | ]) need_unnamed = true; | 4239 | ]) need_unnamed = true; |
| 4231 | const field_size = field_ty.abiSize(mod); | 4240 | const field_size = field_ty.abiSize(pt); |
| 4232 | if (field_size == layout.payload_size) break :p payload; | 4241 | if (field_size == layout.payload_size) break :p payload; |
| 4233 | const padding_len = layout.payload_size - field_size; | 4242 | const padding_len = layout.payload_size - field_size; |
| 4234 | const padding_ty = try o.builder.arrayType(padding_len, .i8); | 4243 | const padding_ty = try o.builder.arrayType(padding_len, .i8); |
| ... | @@ -4239,7 +4248,7 @@ pub const Object = struct { | ... | @@ -4239,7 +4248,7 @@ pub const Object = struct { |
| 4239 | } else p: { | 4248 | } else p: { |
| 4240 | assert(layout.tag_size == 0); | 4249 | assert(layout.tag_size == 0); |
| 4241 | if (container_layout == .@"packed") { | 4250 | if (container_layout == .@"packed") { |
| 4242 | const bits = ty.bitSize(mod); | 4251 | const bits = ty.bitSize(pt); |
| 4243 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); | 4252 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4244 | 4253 | ||
| 4245 | return o.lowerValueToInt(llvm_int_ty, arg_val); | 4254 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | @@ -4286,7 +4295,7 @@ pub const Object = struct { | ... | @@ -4286,7 +4295,7 @@ pub const Object = struct { |
| 4286 | ty: Type, | 4295 | ty: Type, |
| 4287 | bigint: std.math.big.int.Const, | 4296 | bigint: std.math.big.int.Const, |
| 4288 | ) Allocator.Error!Builder.Constant { | 4297 | ) Allocator.Error!Builder.Constant { |
| 4289 | const mod = o.module; | 4298 | const mod = o.pt.zcu; |
| 4290 | return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint); | 4299 | return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint); |
| 4291 | } | 4300 | } |
| 4292 | 4301 | ||
| ... | @@ -4295,7 +4304,8 @@ pub const Object = struct { | ... | @@ -4295,7 +4304,8 @@ pub const Object = struct { |
| 4295 | ptr_val: InternPool.Index, | 4304 | ptr_val: InternPool.Index, |
| 4296 | prev_offset: u64, | 4305 | prev_offset: u64, |
| 4297 | ) Error!Builder.Constant { | 4306 | ) Error!Builder.Constant { |
| 4298 | const zcu = o.module; | 4307 | const pt = o.pt; |
| 4308 | const zcu = pt.zcu; | ||
| 4299 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 4309 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 4300 | const offset: u64 = prev_offset + ptr.byte_offset; | 4310 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 4301 | return switch (ptr.base_addr) { | 4311 | return switch (ptr.base_addr) { |
| ... | @@ -4320,7 +4330,7 @@ pub const Object = struct { | ... | @@ -4320,7 +4330,7 @@ pub const Object = struct { |
| 4320 | eu_ptr, | 4330 | eu_ptr, |
| 4321 | offset + @import("../codegen.zig").errUnionPayloadOffset( | 4331 | offset + @import("../codegen.zig").errUnionPayloadOffset( |
| 4322 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu), | 4332 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu), |
| 4323 | zcu, | 4333 | pt, |
| 4324 | ), | 4334 | ), |
| 4325 | ), | 4335 | ), |
| 4326 | .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset), | 4336 | .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset), |
| ... | @@ -4336,7 +4346,7 @@ pub const Object = struct { | ... | @@ -4336,7 +4346,7 @@ pub const Object = struct { |
| 4336 | }; | 4346 | }; |
| 4337 | }, | 4347 | }, |
| 4338 | .Struct, .Union => switch (agg_ty.containerLayout(zcu)) { | 4348 | .Struct, .Union => switch (agg_ty.containerLayout(zcu)) { |
| 4339 | .auto => agg_ty.structFieldOffset(@intCast(field.index), zcu), | 4349 | .auto => agg_ty.structFieldOffset(@intCast(field.index), pt), |
| 4340 | .@"extern", .@"packed" => unreachable, | 4350 | .@"extern", .@"packed" => unreachable, |
| 4341 | }, | 4351 | }, |
| 4342 | else => unreachable, | 4352 | else => unreachable, |
| ... | @@ -4353,7 +4363,8 @@ pub const Object = struct { | ... | @@ -4353,7 +4363,8 @@ pub const Object = struct { |
| 4353 | o: *Object, | 4363 | o: *Object, |
| 4354 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, | 4364 | anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl, |
| 4355 | ) Error!Builder.Constant { | 4365 | ) Error!Builder.Constant { |
| 4356 | const mod = o.module; | 4366 | const pt = o.pt; |
| 4367 | const mod = pt.zcu; | ||
| 4357 | const ip = &mod.intern_pool; | 4368 | const ip = &mod.intern_pool; |
| 4358 | const decl_val = anon_decl.val; | 4369 | const decl_val = anon_decl.val; |
| 4359 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); | 4370 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); |
| ... | @@ -4370,14 +4381,14 @@ pub const Object = struct { | ... | @@ -4370,14 +4381,14 @@ pub const Object = struct { |
| 4370 | const ptr_ty = Type.fromInterned(anon_decl.orig_ty); | 4381 | const ptr_ty = Type.fromInterned(anon_decl.orig_ty); |
| 4371 | 4382 | ||
| 4372 | const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; | 4383 | const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; |
| 4373 | if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or | 4384 | if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or |
| 4374 | (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty); | 4385 | (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty); |
| 4375 | 4386 | ||
| 4376 | if (is_fn_body) | 4387 | if (is_fn_body) |
| 4377 | @panic("TODO"); | 4388 | @panic("TODO"); |
| 4378 | 4389 | ||
| 4379 | const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target); | 4390 | const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target); |
| 4380 | const alignment = ptr_ty.ptrAlignment(mod); | 4391 | const alignment = ptr_ty.ptrAlignment(pt); |
| 4381 | const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global; | 4392 | const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global; |
| 4382 | 4393 | ||
| 4383 | const llvm_val = try o.builder.convConst( | 4394 | const llvm_val = try o.builder.convConst( |
| ... | @@ -4389,7 +4400,8 @@ pub const Object = struct { | ... | @@ -4389,7 +4400,8 @@ pub const Object = struct { |
| 4389 | } | 4400 | } |
| 4390 | 4401 | ||
| 4391 | fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant { | 4402 | fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant { |
| 4392 | const mod = o.module; | 4403 | const pt = o.pt; |
| 4404 | const mod = pt.zcu; | ||
| 4393 | 4405 | ||
| 4394 | // In the case of something like: | 4406 | // In the case of something like: |
| 4395 | // fn foo() void {} | 4407 | // fn foo() void {} |
| ... | @@ -4408,10 +4420,10 @@ pub const Object = struct { | ... | @@ -4408,10 +4420,10 @@ pub const Object = struct { |
| 4408 | } | 4420 | } |
| 4409 | 4421 | ||
| 4410 | const decl_ty = decl.typeOf(mod); | 4422 | const decl_ty = decl.typeOf(mod); |
| 4411 | const ptr_ty = try decl.declPtrType(mod); | 4423 | const ptr_ty = try decl.declPtrType(pt); |
| 4412 | 4424 | ||
| 4413 | const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; | 4425 | const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; |
| 4414 | if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or | 4426 | if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or |
| 4415 | (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) | 4427 | (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) |
| 4416 | { | 4428 | { |
| 4417 | return o.lowerPtrToVoid(ptr_ty); | 4429 | return o.lowerPtrToVoid(ptr_ty); |
| ... | @@ -4431,7 +4443,7 @@ pub const Object = struct { | ... | @@ -4431,7 +4443,7 @@ pub const Object = struct { |
| 4431 | } | 4443 | } |
| 4432 | 4444 | ||
| 4433 | fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant { | 4445 | fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant { |
| 4434 | const mod = o.module; | 4446 | const mod = o.pt.zcu; |
| 4435 | // Even though we are pointing at something which has zero bits (e.g. `void`), | 4447 | // Even though we are pointing at something which has zero bits (e.g. `void`), |
| 4436 | // Pointers are defined to have bits. So we must return something here. | 4448 | // Pointers are defined to have bits. So we must return something here. |
| 4437 | // The value cannot be undefined, because we use the `nonnull` annotation | 4449 | // The value cannot be undefined, because we use the `nonnull` annotation |
| ... | @@ -4459,20 +4471,21 @@ pub const Object = struct { | ... | @@ -4459,20 +4471,21 @@ pub const Object = struct { |
| 4459 | /// RMW exchange of floating-point values is bitcasted to same-sized integer | 4471 | /// RMW exchange of floating-point values is bitcasted to same-sized integer |
| 4460 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. | 4472 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. |
| 4461 | fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type { | 4473 | fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type { |
| 4462 | const mod = o.module; | 4474 | const pt = o.pt; |
| 4475 | const mod = pt.zcu; | ||
| 4463 | const int_ty = switch (ty.zigTypeTag(mod)) { | 4476 | const int_ty = switch (ty.zigTypeTag(mod)) { |
| 4464 | .Int => ty, | 4477 | .Int => ty, |
| 4465 | .Enum => ty.intTagType(mod), | 4478 | .Enum => ty.intTagType(mod), |
| 4466 | .Float => { | 4479 | .Float => { |
| 4467 | if (!is_rmw_xchg) return .none; | 4480 | if (!is_rmw_xchg) return .none; |
| 4468 | return o.builder.intType(@intCast(ty.abiSize(mod) * 8)); | 4481 | return o.builder.intType(@intCast(ty.abiSize(pt) * 8)); |
| 4469 | }, | 4482 | }, |
| 4470 | .Bool => return .i8, | 4483 | .Bool => return .i8, |
| 4471 | else => return .none, | 4484 | else => return .none, |
| 4472 | }; | 4485 | }; |
| 4473 | const bit_count = int_ty.intInfo(mod).bits; | 4486 | const bit_count = int_ty.intInfo(mod).bits; |
| 4474 | if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) { | 4487 | if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) { |
| 4475 | return o.builder.intType(@intCast(int_ty.abiSize(mod) * 8)); | 4488 | return o.builder.intType(@intCast(int_ty.abiSize(pt) * 8)); |
| 4476 | } else { | 4489 | } else { |
| 4477 | return .none; | 4490 | return .none; |
| 4478 | } | 4491 | } |
| ... | @@ -4486,7 +4499,8 @@ pub const Object = struct { | ... | @@ -4486,7 +4499,8 @@ pub const Object = struct { |
| 4486 | fn_info: InternPool.Key.FuncType, | 4499 | fn_info: InternPool.Key.FuncType, |
| 4487 | llvm_arg_i: u32, | 4500 | llvm_arg_i: u32, |
| 4488 | ) Allocator.Error!void { | 4501 | ) Allocator.Error!void { |
| 4489 | const mod = o.module; | 4502 | const pt = o.pt; |
| 4503 | const mod = pt.zcu; | ||
| 4490 | if (param_ty.isPtrAtRuntime(mod)) { | 4504 | if (param_ty.isPtrAtRuntime(mod)) { |
| 4491 | const ptr_info = param_ty.ptrInfo(mod); | 4505 | const ptr_info = param_ty.ptrInfo(mod); |
| 4492 | if (math.cast(u5, param_index)) |i| { | 4506 | if (math.cast(u5, param_index)) |i| { |
| ... | @@ -4507,7 +4521,7 @@ pub const Object = struct { | ... | @@ -4507,7 +4521,7 @@ pub const Object = struct { |
| 4507 | const elem_align = if (ptr_info.flags.alignment != .none) | 4521 | const elem_align = if (ptr_info.flags.alignment != .none) |
| 4508 | ptr_info.flags.alignment | 4522 | ptr_info.flags.alignment |
| 4509 | else | 4523 | else |
| 4510 | Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1"); | 4524 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1"); |
| 4511 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder); | 4525 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder); |
| 4512 | } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) { | 4526 | } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) { |
| 4513 | .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder), | 4527 | .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder), |
| ... | @@ -4540,7 +4554,7 @@ pub const Object = struct { | ... | @@ -4540,7 +4554,7 @@ pub const Object = struct { |
| 4540 | const name = try o.builder.strtabString(lt_errors_fn_name); | 4554 | const name = try o.builder.strtabString(lt_errors_fn_name); |
| 4541 | if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function; | 4555 | if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function; |
| 4542 | 4556 | ||
| 4543 | const zcu = o.module; | 4557 | const zcu = o.pt.zcu; |
| 4544 | const target = zcu.root_mod.resolved_target.result; | 4558 | const target = zcu.root_mod.resolved_target.result; |
| 4545 | const function_index = try o.builder.addFunction( | 4559 | const function_index = try o.builder.addFunction( |
| 4546 | try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal), | 4560 | try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal), |
| ... | @@ -4559,7 +4573,8 @@ pub const Object = struct { | ... | @@ -4559,7 +4573,8 @@ pub const Object = struct { |
| 4559 | } | 4573 | } |
| 4560 | 4574 | ||
| 4561 | fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index { | 4575 | fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index { |
| 4562 | const zcu = o.module; | 4576 | const pt = o.pt; |
| 4577 | const zcu = pt.zcu; | ||
| 4563 | const ip = &zcu.intern_pool; | 4578 | const ip = &zcu.intern_pool; |
| 4564 | const enum_type = ip.loadEnumType(enum_ty.toIntern()); | 4579 | const enum_type = ip.loadEnumType(enum_ty.toIntern()); |
| 4565 | 4580 | ||
| ... | @@ -4618,7 +4633,7 @@ pub const Object = struct { | ... | @@ -4618,7 +4633,7 @@ pub const Object = struct { |
| 4618 | 4633 | ||
| 4619 | const return_block = try wip.block(1, "Name"); | 4634 | const return_block = try wip.block(1, "Name"); |
| 4620 | const this_tag_int_value = try o.lowerValue( | 4635 | const this_tag_int_value = try o.lowerValue( |
| 4621 | (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(), | 4636 | (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(), |
| 4622 | ); | 4637 | ); |
| 4623 | try wip_switch.addCase(this_tag_int_value, return_block, &wip); | 4638 | try wip_switch.addCase(this_tag_int_value, return_block, &wip); |
| 4624 | 4639 | ||
| ... | @@ -4636,13 +4651,13 @@ pub const Object = struct { | ... | @@ -4636,13 +4651,13 @@ pub const Object = struct { |
| 4636 | 4651 | ||
| 4637 | pub const DeclGen = struct { | 4652 | pub const DeclGen = struct { |
| 4638 | object: *Object, | 4653 | object: *Object, |
| 4639 | decl: *Module.Decl, | 4654 | decl: *Zcu.Decl, |
| 4640 | decl_index: InternPool.DeclIndex, | 4655 | decl_index: InternPool.DeclIndex, |
| 4641 | err_msg: ?*Module.ErrorMsg, | 4656 | err_msg: ?*Zcu.ErrorMsg, |
| 4642 | 4657 | ||
| 4643 | fn ownerModule(dg: DeclGen) *Package.Module { | 4658 | fn ownerModule(dg: DeclGen) *Package.Module { |
| 4644 | const o = dg.object; | 4659 | const o = dg.object; |
| 4645 | const zcu = o.module; | 4660 | const zcu = o.pt.zcu; |
| 4646 | const namespace = zcu.namespacePtr(dg.decl.src_namespace); | 4661 | const namespace = zcu.namespacePtr(dg.decl.src_namespace); |
| 4647 | const file_scope = namespace.fileScope(zcu); | 4662 | const file_scope = namespace.fileScope(zcu); |
| 4648 | return file_scope.mod; | 4663 | return file_scope.mod; |
| ... | @@ -4653,15 +4668,15 @@ pub const DeclGen = struct { | ... | @@ -4653,15 +4668,15 @@ pub const DeclGen = struct { |
| 4653 | assert(dg.err_msg == null); | 4668 | assert(dg.err_msg == null); |
| 4654 | const o = dg.object; | 4669 | const o = dg.object; |
| 4655 | const gpa = o.gpa; | 4670 | const gpa = o.gpa; |
| 4656 | const mod = o.module; | 4671 | const src_loc = dg.decl.navSrcLoc(o.pt.zcu); |
| 4657 | const src_loc = dg.decl.navSrcLoc(mod); | 4672 | dg.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args); |
| 4658 | dg.err_msg = try Module.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args); | ||
| 4659 | return error.CodegenFail; | 4673 | return error.CodegenFail; |
| 4660 | } | 4674 | } |
| 4661 | 4675 | ||
| 4662 | fn genDecl(dg: *DeclGen) !void { | 4676 | fn genDecl(dg: *DeclGen) !void { |
| 4663 | const o = dg.object; | 4677 | const o = dg.object; |
| 4664 | const zcu = o.module; | 4678 | const pt = o.pt; |
| 4679 | const zcu = pt.zcu; | ||
| 4665 | const ip = &zcu.intern_pool; | 4680 | const ip = &zcu.intern_pool; |
| 4666 | const decl = dg.decl; | 4681 | const decl = dg.decl; |
| 4667 | const decl_index = dg.decl_index; | 4682 | const decl_index = dg.decl_index; |
| ... | @@ -4672,7 +4687,7 @@ pub const DeclGen = struct { | ... | @@ -4672,7 +4687,7 @@ pub const DeclGen = struct { |
| 4672 | } else { | 4687 | } else { |
| 4673 | const variable_index = try o.resolveGlobalDecl(decl_index); | 4688 | const variable_index = try o.resolveGlobalDecl(decl_index); |
| 4674 | variable_index.setAlignment( | 4689 | variable_index.setAlignment( |
| 4675 | decl.getAlignment(zcu).toLlvm(), | 4690 | decl.getAlignment(pt).toLlvm(), |
| 4676 | &o.builder, | 4691 | &o.builder, |
| 4677 | ); | 4692 | ); |
| 4678 | if (decl.@"linksection".toSlice(ip)) |section| | 4693 | if (decl.@"linksection".toSlice(ip)) |section| |
| ... | @@ -4833,23 +4848,21 @@ pub const FuncGen = struct { | ... | @@ -4833,23 +4848,21 @@ pub const FuncGen = struct { |
| 4833 | const gop = try self.func_inst_table.getOrPut(gpa, inst); | 4848 | const gop = try self.func_inst_table.getOrPut(gpa, inst); |
| 4834 | if (gop.found_existing) return gop.value_ptr.*; | 4849 | if (gop.found_existing) return gop.value_ptr.*; |
| 4835 | 4850 | ||
| 4836 | const o = self.dg.object; | 4851 | const llvm_val = try self.resolveValue((try self.air.value(inst, self.dg.object.pt)).?); |
| 4837 | const mod = o.module; | ||
| 4838 | const llvm_val = try self.resolveValue((try self.air.value(inst, mod)).?); | ||
| 4839 | gop.value_ptr.* = llvm_val.toValue(); | 4852 | gop.value_ptr.* = llvm_val.toValue(); |
| 4840 | return llvm_val.toValue(); | 4853 | return llvm_val.toValue(); |
| 4841 | } | 4854 | } |
| 4842 | 4855 | ||
| 4843 | fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant { | 4856 | fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant { |
| 4844 | const o = self.dg.object; | 4857 | const o = self.dg.object; |
| 4845 | const mod = o.module; | 4858 | const pt = o.pt; |
| 4846 | const ty = val.typeOf(mod); | 4859 | const ty = val.typeOf(pt.zcu); |
| 4847 | const llvm_val = try o.lowerValue(val.toIntern()); | 4860 | const llvm_val = try o.lowerValue(val.toIntern()); |
| 4848 | if (!isByRef(ty, mod)) return llvm_val; | 4861 | if (!isByRef(ty, pt)) return llvm_val; |
| 4849 | 4862 | ||
| 4850 | // We have an LLVM value but we need to create a global constant and | 4863 | // We have an LLVM value but we need to create a global constant and |
| 4851 | // set the value as its initializer, and then return a pointer to the global. | 4864 | // set the value as its initializer, and then return a pointer to the global. |
| 4852 | const target = mod.getTarget(); | 4865 | const target = pt.zcu.getTarget(); |
| 4853 | const variable_index = try o.builder.addVariable( | 4866 | const variable_index = try o.builder.addVariable( |
| 4854 | .empty, | 4867 | .empty, |
| 4855 | llvm_val.typeOf(&o.builder), | 4868 | llvm_val.typeOf(&o.builder), |
| ... | @@ -4859,7 +4872,7 @@ pub const FuncGen = struct { | ... | @@ -4859,7 +4872,7 @@ pub const FuncGen = struct { |
| 4859 | variable_index.setLinkage(.private, &o.builder); | 4872 | variable_index.setLinkage(.private, &o.builder); |
| 4860 | variable_index.setMutability(.constant, &o.builder); | 4873 | variable_index.setMutability(.constant, &o.builder); |
| 4861 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 4874 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 4862 | variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder); | 4875 | variable_index.setAlignment(ty.abiAlignment(pt).toLlvm(), &o.builder); |
| 4863 | return o.builder.convConst( | 4876 | return o.builder.convConst( |
| 4864 | variable_index.toConst(&o.builder), | 4877 | variable_index.toConst(&o.builder), |
| 4865 | try o.builder.ptrType(toLlvmAddressSpace(.generic, target)), | 4878 | try o.builder.ptrType(toLlvmAddressSpace(.generic, target)), |
| ... | @@ -4868,10 +4881,10 @@ pub const FuncGen = struct { | ... | @@ -4868,10 +4881,10 @@ pub const FuncGen = struct { |
| 4868 | 4881 | ||
| 4869 | fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant { | 4882 | fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant { |
| 4870 | const o = self.dg.object; | 4883 | const o = self.dg.object; |
| 4871 | const mod = o.module; | 4884 | const pt = o.pt; |
| 4872 | if (o.null_opt_usize == .no_init) { | 4885 | if (o.null_opt_usize == .no_init) { |
| 4873 | o.null_opt_usize = try self.resolveValue(Value.fromInterned(try mod.intern(.{ .opt = .{ | 4886 | o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 4874 | .ty = try mod.intern(.{ .opt_type = .usize_type }), | 4887 | .ty = try pt.intern(.{ .opt_type = .usize_type }), |
| 4875 | .val = .none, | 4888 | .val = .none, |
| 4876 | } }))); | 4889 | } }))); |
| 4877 | } | 4890 | } |
| ... | @@ -4880,7 +4893,7 @@ pub const FuncGen = struct { | ... | @@ -4880,7 +4893,7 @@ pub const FuncGen = struct { |
| 4880 | 4893 | ||
| 4881 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { | 4894 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { |
| 4882 | const o = self.dg.object; | 4895 | const o = self.dg.object; |
| 4883 | const mod = o.module; | 4896 | const mod = o.pt.zcu; |
| 4884 | const ip = &mod.intern_pool; | 4897 | const ip = &mod.intern_pool; |
| 4885 | const air_tags = self.air.instructions.items(.tag); | 4898 | const air_tags = self.air.instructions.items(.tag); |
| 4886 | for (body, 0..) |inst, i| { | 4899 | for (body, 0..) |inst, i| { |
| ... | @@ -5145,7 +5158,8 @@ pub const FuncGen = struct { | ... | @@ -5145,7 +5158,8 @@ pub const FuncGen = struct { |
| 5145 | 5158 | ||
| 5146 | if (maybe_inline_func) |inline_func| { | 5159 | if (maybe_inline_func) |inline_func| { |
| 5147 | const o = self.dg.object; | 5160 | const o = self.dg.object; |
| 5148 | const zcu = o.module; | 5161 | const pt = o.pt; |
| 5162 | const zcu = pt.zcu; | ||
| 5149 | 5163 | ||
| 5150 | const func = zcu.funcInfo(inline_func); | 5164 | const func = zcu.funcInfo(inline_func); |
| 5151 | const decl_index = func.owner_decl; | 5165 | const decl_index = func.owner_decl; |
| ... | @@ -5161,7 +5175,7 @@ pub const FuncGen = struct { | ... | @@ -5161,7 +5175,7 @@ pub const FuncGen = struct { |
| 5161 | 5175 | ||
| 5162 | const fqn = try decl.fullyQualifiedName(zcu); | 5176 | const fqn = try decl.fullyQualifiedName(zcu); |
| 5163 | 5177 | ||
| 5164 | const fn_ty = try zcu.funcType(.{ | 5178 | const fn_ty = try pt.funcType(.{ |
| 5165 | .param_types = &.{}, | 5179 | .param_types = &.{}, |
| 5166 | .return_type = .void_type, | 5180 | .return_type = .void_type, |
| 5167 | }); | 5181 | }); |
| ... | @@ -5228,7 +5242,8 @@ pub const FuncGen = struct { | ... | @@ -5228,7 +5242,8 @@ pub const FuncGen = struct { |
| 5228 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 5242 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 5229 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); | 5243 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 5230 | const o = self.dg.object; | 5244 | const o = self.dg.object; |
| 5231 | const mod = o.module; | 5245 | const pt = o.pt; |
| 5246 | const mod = pt.zcu; | ||
| 5232 | const ip = &mod.intern_pool; | 5247 | const ip = &mod.intern_pool; |
| 5233 | const callee_ty = self.typeOf(pl_op.operand); | 5248 | const callee_ty = self.typeOf(pl_op.operand); |
| 5234 | const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { | 5249 | const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { |
| ... | @@ -5240,7 +5255,7 @@ pub const FuncGen = struct { | ... | @@ -5240,7 +5255,7 @@ pub const FuncGen = struct { |
| 5240 | const return_type = Type.fromInterned(fn_info.return_type); | 5255 | const return_type = Type.fromInterned(fn_info.return_type); |
| 5241 | const llvm_fn = try self.resolveInst(pl_op.operand); | 5256 | const llvm_fn = try self.resolveInst(pl_op.operand); |
| 5242 | const target = mod.getTarget(); | 5257 | const target = mod.getTarget(); |
| 5243 | const sret = firstParamSRet(fn_info, mod, target); | 5258 | const sret = firstParamSRet(fn_info, pt, target); |
| 5244 | 5259 | ||
| 5245 | var llvm_args = std.ArrayList(Builder.Value).init(self.gpa); | 5260 | var llvm_args = std.ArrayList(Builder.Value).init(self.gpa); |
| 5246 | defer llvm_args.deinit(); | 5261 | defer llvm_args.deinit(); |
| ... | @@ -5258,14 +5273,13 @@ pub const FuncGen = struct { | ... | @@ -5258,14 +5273,13 @@ pub const FuncGen = struct { |
| 5258 | const llvm_ret_ty = try o.lowerType(return_type); | 5273 | const llvm_ret_ty = try o.lowerType(return_type); |
| 5259 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); | 5274 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); |
| 5260 | 5275 | ||
| 5261 | const alignment = return_type.abiAlignment(mod).toLlvm(); | 5276 | const alignment = return_type.abiAlignment(pt).toLlvm(); |
| 5262 | const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment); | 5277 | const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment); |
| 5263 | try llvm_args.append(ret_ptr); | 5278 | try llvm_args.append(ret_ptr); |
| 5264 | break :blk ret_ptr; | 5279 | break :blk ret_ptr; |
| 5265 | }; | 5280 | }; |
| 5266 | 5281 | ||
| 5267 | const err_return_tracing = return_type.isError(mod) and | 5282 | const err_return_tracing = return_type.isError(mod) and mod.comp.config.any_error_tracing; |
| 5268 | o.module.comp.config.any_error_tracing; | ||
| 5269 | if (err_return_tracing) { | 5283 | if (err_return_tracing) { |
| 5270 | assert(self.err_ret_trace != .none); | 5284 | assert(self.err_ret_trace != .none); |
| 5271 | try llvm_args.append(self.err_ret_trace); | 5285 | try llvm_args.append(self.err_ret_trace); |
| ... | @@ -5279,8 +5293,8 @@ pub const FuncGen = struct { | ... | @@ -5279,8 +5293,8 @@ pub const FuncGen = struct { |
| 5279 | const param_ty = self.typeOf(arg); | 5293 | const param_ty = self.typeOf(arg); |
| 5280 | const llvm_arg = try self.resolveInst(arg); | 5294 | const llvm_arg = try self.resolveInst(arg); |
| 5281 | const llvm_param_ty = try o.lowerType(param_ty); | 5295 | const llvm_param_ty = try o.lowerType(param_ty); |
| 5282 | if (isByRef(param_ty, mod)) { | 5296 | if (isByRef(param_ty, pt)) { |
| 5283 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5297 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5284 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); | 5298 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); |
| 5285 | try llvm_args.append(loaded); | 5299 | try llvm_args.append(loaded); |
| 5286 | } else { | 5300 | } else { |
| ... | @@ -5291,10 +5305,10 @@ pub const FuncGen = struct { | ... | @@ -5291,10 +5305,10 @@ pub const FuncGen = struct { |
| 5291 | const arg = args[it.zig_index - 1]; | 5305 | const arg = args[it.zig_index - 1]; |
| 5292 | const param_ty = self.typeOf(arg); | 5306 | const param_ty = self.typeOf(arg); |
| 5293 | const llvm_arg = try self.resolveInst(arg); | 5307 | const llvm_arg = try self.resolveInst(arg); |
| 5294 | if (isByRef(param_ty, mod)) { | 5308 | if (isByRef(param_ty, pt)) { |
| 5295 | try llvm_args.append(llvm_arg); | 5309 | try llvm_args.append(llvm_arg); |
| 5296 | } else { | 5310 | } else { |
| 5297 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5311 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5298 | const param_llvm_ty = llvm_arg.typeOfWip(&self.wip); | 5312 | const param_llvm_ty = llvm_arg.typeOfWip(&self.wip); |
| 5299 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); | 5313 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); |
| 5300 | _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment); | 5314 | _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment); |
| ... | @@ -5306,10 +5320,10 @@ pub const FuncGen = struct { | ... | @@ -5306,10 +5320,10 @@ pub const FuncGen = struct { |
| 5306 | const param_ty = self.typeOf(arg); | 5320 | const param_ty = self.typeOf(arg); |
| 5307 | const llvm_arg = try self.resolveInst(arg); | 5321 | const llvm_arg = try self.resolveInst(arg); |
| 5308 | 5322 | ||
| 5309 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5323 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5310 | const param_llvm_ty = try o.lowerType(param_ty); | 5324 | const param_llvm_ty = try o.lowerType(param_ty); |
| 5311 | const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment); | 5325 | const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment); |
| 5312 | if (isByRef(param_ty, mod)) { | 5326 | if (isByRef(param_ty, pt)) { |
| 5313 | const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, ""); | 5327 | const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, ""); |
| 5314 | _ = try self.wip.store(.normal, loaded, arg_ptr, alignment); | 5328 | _ = try self.wip.store(.normal, loaded, arg_ptr, alignment); |
| 5315 | } else { | 5329 | } else { |
| ... | @@ -5321,16 +5335,16 @@ pub const FuncGen = struct { | ... | @@ -5321,16 +5335,16 @@ pub const FuncGen = struct { |
| 5321 | const arg = args[it.zig_index - 1]; | 5335 | const arg = args[it.zig_index - 1]; |
| 5322 | const param_ty = self.typeOf(arg); | 5336 | const param_ty = self.typeOf(arg); |
| 5323 | const llvm_arg = try self.resolveInst(arg); | 5337 | const llvm_arg = try self.resolveInst(arg); |
| 5324 | const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(mod) * 8)); | 5338 | const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(pt) * 8)); |
| 5325 | 5339 | ||
| 5326 | if (isByRef(param_ty, mod)) { | 5340 | if (isByRef(param_ty, pt)) { |
| 5327 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5341 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5328 | const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, ""); | 5342 | const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, ""); |
| 5329 | try llvm_args.append(loaded); | 5343 | try llvm_args.append(loaded); |
| 5330 | } else { | 5344 | } else { |
| 5331 | // LLVM does not allow bitcasting structs so we must allocate | 5345 | // LLVM does not allow bitcasting structs so we must allocate |
| 5332 | // a local, store as one type, and then load as another type. | 5346 | // a local, store as one type, and then load as another type. |
| 5333 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5347 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5334 | const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment); | 5348 | const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment); |
| 5335 | _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment); | 5349 | _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment); |
| 5336 | const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, ""); | 5350 | const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, ""); |
| ... | @@ -5349,9 +5363,9 @@ pub const FuncGen = struct { | ... | @@ -5349,9 +5363,9 @@ pub const FuncGen = struct { |
| 5349 | const param_ty = self.typeOf(arg); | 5363 | const param_ty = self.typeOf(arg); |
| 5350 | const llvm_types = it.types_buffer[0..it.types_len]; | 5364 | const llvm_types = it.types_buffer[0..it.types_len]; |
| 5351 | const llvm_arg = try self.resolveInst(arg); | 5365 | const llvm_arg = try self.resolveInst(arg); |
| 5352 | const is_by_ref = isByRef(param_ty, mod); | 5366 | const is_by_ref = isByRef(param_ty, pt); |
| 5353 | const arg_ptr = if (is_by_ref) llvm_arg else ptr: { | 5367 | const arg_ptr = if (is_by_ref) llvm_arg else ptr: { |
| 5354 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5368 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5355 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); | 5369 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5356 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); | 5370 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5357 | break :ptr ptr; | 5371 | break :ptr ptr; |
| ... | @@ -5377,8 +5391,8 @@ pub const FuncGen = struct { | ... | @@ -5377,8 +5391,8 @@ pub const FuncGen = struct { |
| 5377 | const arg = args[it.zig_index - 1]; | 5391 | const arg = args[it.zig_index - 1]; |
| 5378 | const arg_ty = self.typeOf(arg); | 5392 | const arg_ty = self.typeOf(arg); |
| 5379 | var llvm_arg = try self.resolveInst(arg); | 5393 | var llvm_arg = try self.resolveInst(arg); |
| 5380 | const alignment = arg_ty.abiAlignment(mod).toLlvm(); | 5394 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); |
| 5381 | if (!isByRef(arg_ty, mod)) { | 5395 | if (!isByRef(arg_ty, pt)) { |
| 5382 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); | 5396 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5383 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); | 5397 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5384 | llvm_arg = ptr; | 5398 | llvm_arg = ptr; |
| ... | @@ -5395,8 +5409,8 @@ pub const FuncGen = struct { | ... | @@ -5395,8 +5409,8 @@ pub const FuncGen = struct { |
| 5395 | const arg = args[it.zig_index - 1]; | 5409 | const arg = args[it.zig_index - 1]; |
| 5396 | const arg_ty = self.typeOf(arg); | 5410 | const arg_ty = self.typeOf(arg); |
| 5397 | var llvm_arg = try self.resolveInst(arg); | 5411 | var llvm_arg = try self.resolveInst(arg); |
| 5398 | const alignment = arg_ty.abiAlignment(mod).toLlvm(); | 5412 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); |
| 5399 | if (!isByRef(arg_ty, mod)) { | 5413 | if (!isByRef(arg_ty, pt)) { |
| 5400 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); | 5414 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5401 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); | 5415 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5402 | llvm_arg = ptr; | 5416 | llvm_arg = ptr; |
| ... | @@ -5418,7 +5432,7 @@ pub const FuncGen = struct { | ... | @@ -5418,7 +5432,7 @@ pub const FuncGen = struct { |
| 5418 | .byval => { | 5432 | .byval => { |
| 5419 | const param_index = it.zig_index - 1; | 5433 | const param_index = it.zig_index - 1; |
| 5420 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 5434 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 5421 | if (!isByRef(param_ty, mod)) { | 5435 | if (!isByRef(param_ty, pt)) { |
| 5422 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); | 5436 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 5423 | } | 5437 | } |
| 5424 | }, | 5438 | }, |
| ... | @@ -5426,7 +5440,7 @@ pub const FuncGen = struct { | ... | @@ -5426,7 +5440,7 @@ pub const FuncGen = struct { |
| 5426 | const param_index = it.zig_index - 1; | 5440 | const param_index = it.zig_index - 1; |
| 5427 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 5441 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 5428 | const param_llvm_ty = try o.lowerType(param_ty); | 5442 | const param_llvm_ty = try o.lowerType(param_ty); |
| 5429 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | 5443 | const alignment = param_ty.abiAlignment(pt).toLlvm(); |
| 5430 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 5444 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 5431 | }, | 5445 | }, |
| 5432 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), | 5446 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | @@ -5460,7 +5474,7 @@ pub const FuncGen = struct { | ... | @@ -5460,7 +5474,7 @@ pub const FuncGen = struct { |
| 5460 | const elem_align = (if (ptr_info.flags.alignment != .none) | 5474 | const elem_align = (if (ptr_info.flags.alignment != .none) |
| 5461 | @as(InternPool.Alignment, ptr_info.flags.alignment) | 5475 | @as(InternPool.Alignment, ptr_info.flags.alignment) |
| 5462 | else | 5476 | else |
| 5463 | Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm(); | 5477 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm(); |
| 5464 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); | 5478 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); |
| 5465 | }, | 5479 | }, |
| 5466 | }; | 5480 | }; |
| ... | @@ -5485,17 +5499,17 @@ pub const FuncGen = struct { | ... | @@ -5485,17 +5499,17 @@ pub const FuncGen = struct { |
| 5485 | return .none; | 5499 | return .none; |
| 5486 | } | 5500 | } |
| 5487 | 5501 | ||
| 5488 | if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) { | 5502 | if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5489 | return .none; | 5503 | return .none; |
| 5490 | } | 5504 | } |
| 5491 | 5505 | ||
| 5492 | const llvm_ret_ty = try o.lowerType(return_type); | 5506 | const llvm_ret_ty = try o.lowerType(return_type); |
| 5493 | if (ret_ptr) |rp| { | 5507 | if (ret_ptr) |rp| { |
| 5494 | if (isByRef(return_type, mod)) { | 5508 | if (isByRef(return_type, pt)) { |
| 5495 | return rp; | 5509 | return rp; |
| 5496 | } else { | 5510 | } else { |
| 5497 | // our by-ref status disagrees with sret so we must load. | 5511 | // our by-ref status disagrees with sret so we must load. |
| 5498 | const return_alignment = return_type.abiAlignment(mod).toLlvm(); | 5512 | const return_alignment = return_type.abiAlignment(pt).toLlvm(); |
| 5499 | return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, ""); | 5513 | return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, ""); |
| 5500 | } | 5514 | } |
| 5501 | } | 5515 | } |
| ... | @@ -5506,19 +5520,19 @@ pub const FuncGen = struct { | ... | @@ -5506,19 +5520,19 @@ pub const FuncGen = struct { |
| 5506 | // In this case the function return type is honoring the calling convention by having | 5520 | // In this case the function return type is honoring the calling convention by having |
| 5507 | // a different LLVM type than the usual one. We solve this here at the callsite | 5521 | // a different LLVM type than the usual one. We solve this here at the callsite |
| 5508 | // by using our canonical type, then loading it if necessary. | 5522 | // by using our canonical type, then loading it if necessary. |
| 5509 | const alignment = return_type.abiAlignment(mod).toLlvm(); | 5523 | const alignment = return_type.abiAlignment(pt).toLlvm(); |
| 5510 | const rp = try self.buildAlloca(abi_ret_ty, alignment); | 5524 | const rp = try self.buildAlloca(abi_ret_ty, alignment); |
| 5511 | _ = try self.wip.store(.normal, call, rp, alignment); | 5525 | _ = try self.wip.store(.normal, call, rp, alignment); |
| 5512 | return if (isByRef(return_type, mod)) | 5526 | return if (isByRef(return_type, pt)) |
| 5513 | rp | 5527 | rp |
| 5514 | else | 5528 | else |
| 5515 | try self.wip.load(.normal, llvm_ret_ty, rp, alignment, ""); | 5529 | try self.wip.load(.normal, llvm_ret_ty, rp, alignment, ""); |
| 5516 | } | 5530 | } |
| 5517 | 5531 | ||
| 5518 | if (isByRef(return_type, mod)) { | 5532 | if (isByRef(return_type, pt)) { |
| 5519 | // our by-ref status disagrees with sret so we must allocate, store, | 5533 | // our by-ref status disagrees with sret so we must allocate, store, |
| 5520 | // and return the allocation pointer. | 5534 | // and return the allocation pointer. |
| 5521 | const alignment = return_type.abiAlignment(mod).toLlvm(); | 5535 | const alignment = return_type.abiAlignment(pt).toLlvm(); |
| 5522 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); | 5536 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| 5523 | _ = try self.wip.store(.normal, call, rp, alignment); | 5537 | _ = try self.wip.store(.normal, call, rp, alignment); |
| 5524 | return rp; | 5538 | return rp; |
| ... | @@ -5527,9 +5541,9 @@ pub const FuncGen = struct { | ... | @@ -5527,9 +5541,9 @@ pub const FuncGen = struct { |
| 5527 | } | 5541 | } |
| 5528 | } | 5542 | } |
| 5529 | 5543 | ||
| 5530 | fn buildSimplePanic(fg: *FuncGen, panic_id: Module.PanicId) !void { | 5544 | fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void { |
| 5531 | const o = fg.dg.object; | 5545 | const o = fg.dg.object; |
| 5532 | const mod = o.module; | 5546 | const mod = o.pt.zcu; |
| 5533 | const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?; | 5547 | const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?; |
| 5534 | const msg_decl = mod.declPtr(msg_decl_index); | 5548 | const msg_decl = mod.declPtr(msg_decl_index); |
| 5535 | const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod); | 5549 | const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod); |
| ... | @@ -5567,15 +5581,16 @@ pub const FuncGen = struct { | ... | @@ -5567,15 +5581,16 @@ pub const FuncGen = struct { |
| 5567 | 5581 | ||
| 5568 | fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | 5582 | fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 5569 | const o = self.dg.object; | 5583 | const o = self.dg.object; |
| 5570 | const mod = o.module; | 5584 | const pt = o.pt; |
| 5585 | const mod = pt.zcu; | ||
| 5571 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5586 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5572 | const ret_ty = self.typeOf(un_op); | 5587 | const ret_ty = self.typeOf(un_op); |
| 5573 | 5588 | ||
| 5574 | if (self.ret_ptr != .none) { | 5589 | if (self.ret_ptr != .none) { |
| 5575 | const ptr_ty = try mod.singleMutPtrType(ret_ty); | 5590 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 5576 | 5591 | ||
| 5577 | const operand = try self.resolveInst(un_op); | 5592 | const operand = try self.resolveInst(un_op); |
| 5578 | const val_is_undef = if (try self.air.value(un_op, mod)) |val| val.isUndefDeep(mod) else false; | 5593 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false; |
| 5579 | if (val_is_undef and safety) undef: { | 5594 | if (val_is_undef and safety) undef: { |
| 5580 | const ptr_info = ptr_ty.ptrInfo(mod); | 5595 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 5581 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); | 5596 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); |
| ... | @@ -5585,10 +5600,10 @@ pub const FuncGen = struct { | ... | @@ -5585,10 +5600,10 @@ pub const FuncGen = struct { |
| 5585 | // https://github.com/ziglang/zig/issues/15337 | 5600 | // https://github.com/ziglang/zig/issues/15337 |
| 5586 | break :undef; | 5601 | break :undef; |
| 5587 | } | 5602 | } |
| 5588 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(mod)); | 5603 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt)); |
| 5589 | _ = try self.wip.callMemSet( | 5604 | _ = try self.wip.callMemSet( |
| 5590 | self.ret_ptr, | 5605 | self.ret_ptr, |
| 5591 | ptr_ty.ptrAlignment(mod).toLlvm(), | 5606 | ptr_ty.ptrAlignment(pt).toLlvm(), |
| 5592 | try o.builder.intValue(.i8, 0xaa), | 5607 | try o.builder.intValue(.i8, 0xaa), |
| 5593 | len, | 5608 | len, |
| 5594 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, | 5609 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, |
| ... | @@ -5615,7 +5630,7 @@ pub const FuncGen = struct { | ... | @@ -5615,7 +5630,7 @@ pub const FuncGen = struct { |
| 5615 | return .none; | 5630 | return .none; |
| 5616 | } | 5631 | } |
| 5617 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; | 5632 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; |
| 5618 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5633 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5619 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5634 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 5620 | // Functions with an empty error set are emitted with an error code | 5635 | // Functions with an empty error set are emitted with an error code |
| 5621 | // return type and return zero so they can be function pointers coerced | 5636 | // return type and return zero so they can be function pointers coerced |
| ... | @@ -5629,13 +5644,13 @@ pub const FuncGen = struct { | ... | @@ -5629,13 +5644,13 @@ pub const FuncGen = struct { |
| 5629 | 5644 | ||
| 5630 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); | 5645 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); |
| 5631 | const operand = try self.resolveInst(un_op); | 5646 | const operand = try self.resolveInst(un_op); |
| 5632 | const val_is_undef = if (try self.air.value(un_op, mod)) |val| val.isUndefDeep(mod) else false; | 5647 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false; |
| 5633 | const alignment = ret_ty.abiAlignment(mod).toLlvm(); | 5648 | const alignment = ret_ty.abiAlignment(pt).toLlvm(); |
| 5634 | 5649 | ||
| 5635 | if (val_is_undef and safety) { | 5650 | if (val_is_undef and safety) { |
| 5636 | const llvm_ret_ty = operand.typeOfWip(&self.wip); | 5651 | const llvm_ret_ty = operand.typeOfWip(&self.wip); |
| 5637 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); | 5652 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| 5638 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(mod)); | 5653 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt)); |
| 5639 | _ = try self.wip.callMemSet( | 5654 | _ = try self.wip.callMemSet( |
| 5640 | rp, | 5655 | rp, |
| 5641 | alignment, | 5656 | alignment, |
| ... | @@ -5651,7 +5666,7 @@ pub const FuncGen = struct { | ... | @@ -5651,7 +5666,7 @@ pub const FuncGen = struct { |
| 5651 | return .none; | 5666 | return .none; |
| 5652 | } | 5667 | } |
| 5653 | 5668 | ||
| 5654 | if (isByRef(ret_ty, mod)) { | 5669 | if (isByRef(ret_ty, pt)) { |
| 5655 | // operand is a pointer however self.ret_ptr is null so that means | 5670 | // operand is a pointer however self.ret_ptr is null so that means |
| 5656 | // we need to return a value. | 5671 | // we need to return a value. |
| 5657 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, "")); | 5672 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, "")); |
| ... | @@ -5672,12 +5687,13 @@ pub const FuncGen = struct { | ... | @@ -5672,12 +5687,13 @@ pub const FuncGen = struct { |
| 5672 | 5687 | ||
| 5673 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 5688 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5674 | const o = self.dg.object; | 5689 | const o = self.dg.object; |
| 5675 | const mod = o.module; | 5690 | const pt = o.pt; |
| 5691 | const mod = pt.zcu; | ||
| 5676 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5692 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5677 | const ptr_ty = self.typeOf(un_op); | 5693 | const ptr_ty = self.typeOf(un_op); |
| 5678 | const ret_ty = ptr_ty.childType(mod); | 5694 | const ret_ty = ptr_ty.childType(mod); |
| 5679 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; | 5695 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; |
| 5680 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5696 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5681 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5697 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 5682 | // Functions with an empty error set are emitted with an error code | 5698 | // Functions with an empty error set are emitted with an error code |
| 5683 | // return type and return zero so they can be function pointers coerced | 5699 | // return type and return zero so they can be function pointers coerced |
| ... | @@ -5694,7 +5710,7 @@ pub const FuncGen = struct { | ... | @@ -5694,7 +5710,7 @@ pub const FuncGen = struct { |
| 5694 | } | 5710 | } |
| 5695 | const ptr = try self.resolveInst(un_op); | 5711 | const ptr = try self.resolveInst(un_op); |
| 5696 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); | 5712 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); |
| 5697 | const alignment = ret_ty.abiAlignment(mod).toLlvm(); | 5713 | const alignment = ret_ty.abiAlignment(pt).toLlvm(); |
| 5698 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, "")); | 5714 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, "")); |
| 5699 | return .none; | 5715 | return .none; |
| 5700 | } | 5716 | } |
| ... | @@ -5711,17 +5727,17 @@ pub const FuncGen = struct { | ... | @@ -5711,17 +5727,17 @@ pub const FuncGen = struct { |
| 5711 | 5727 | ||
| 5712 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 5728 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5713 | const o = self.dg.object; | 5729 | const o = self.dg.object; |
| 5730 | const pt = o.pt; | ||
| 5714 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5731 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5715 | const src_list = try self.resolveInst(ty_op.operand); | 5732 | const src_list = try self.resolveInst(ty_op.operand); |
| 5716 | const va_list_ty = ty_op.ty.toType(); | 5733 | const va_list_ty = ty_op.ty.toType(); |
| 5717 | const llvm_va_list_ty = try o.lowerType(va_list_ty); | 5734 | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5718 | const mod = o.module; | ||
| 5719 | 5735 | ||
| 5720 | const result_alignment = va_list_ty.abiAlignment(mod).toLlvm(); | 5736 | const result_alignment = va_list_ty.abiAlignment(pt).toLlvm(); |
| 5721 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); | 5737 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); |
| 5722 | 5738 | ||
| 5723 | _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, ""); | 5739 | _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, ""); |
| 5724 | return if (isByRef(va_list_ty, mod)) | 5740 | return if (isByRef(va_list_ty, pt)) |
| 5725 | dest_list | 5741 | dest_list |
| 5726 | else | 5742 | else |
| 5727 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); | 5743 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); |
| ... | @@ -5737,15 +5753,15 @@ pub const FuncGen = struct { | ... | @@ -5737,15 +5753,15 @@ pub const FuncGen = struct { |
| 5737 | 5753 | ||
| 5738 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 5754 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5739 | const o = self.dg.object; | 5755 | const o = self.dg.object; |
| 5740 | const mod = o.module; | 5756 | const pt = o.pt; |
| 5741 | const va_list_ty = self.typeOfIndex(inst); | 5757 | const va_list_ty = self.typeOfIndex(inst); |
| 5742 | const llvm_va_list_ty = try o.lowerType(va_list_ty); | 5758 | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5743 | 5759 | ||
| 5744 | const result_alignment = va_list_ty.abiAlignment(mod).toLlvm(); | 5760 | const result_alignment = va_list_ty.abiAlignment(pt).toLlvm(); |
| 5745 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); | 5761 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); |
| 5746 | 5762 | ||
| 5747 | _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, ""); | 5763 | _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, ""); |
| 5748 | return if (isByRef(va_list_ty, mod)) | 5764 | return if (isByRef(va_list_ty, pt)) |
| 5749 | dest_list | 5765 | dest_list |
| 5750 | else | 5766 | else |
| 5751 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); | 5767 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); |
| ... | @@ -5802,21 +5818,22 @@ pub const FuncGen = struct { | ... | @@ -5802,21 +5818,22 @@ pub const FuncGen = struct { |
| 5802 | rhs: Builder.Value, | 5818 | rhs: Builder.Value, |
| 5803 | ) Allocator.Error!Builder.Value { | 5819 | ) Allocator.Error!Builder.Value { |
| 5804 | const o = self.dg.object; | 5820 | const o = self.dg.object; |
| 5805 | const mod = o.module; | 5821 | const pt = o.pt; |
| 5822 | const mod = pt.zcu; | ||
| 5806 | const scalar_ty = operand_ty.scalarType(mod); | 5823 | const scalar_ty = operand_ty.scalarType(mod); |
| 5807 | const int_ty = switch (scalar_ty.zigTypeTag(mod)) { | 5824 | const int_ty = switch (scalar_ty.zigTypeTag(mod)) { |
| 5808 | .Enum => scalar_ty.intTagType(mod), | 5825 | .Enum => scalar_ty.intTagType(mod), |
| 5809 | .Int, .Bool, .Pointer, .ErrorSet => scalar_ty, | 5826 | .Int, .Bool, .Pointer, .ErrorSet => scalar_ty, |
| 5810 | .Optional => blk: { | 5827 | .Optional => blk: { |
| 5811 | const payload_ty = operand_ty.optionalChild(mod); | 5828 | const payload_ty = operand_ty.optionalChild(mod); |
| 5812 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or | 5829 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or |
| 5813 | operand_ty.optionalReprIsPayload(mod)) | 5830 | operand_ty.optionalReprIsPayload(mod)) |
| 5814 | { | 5831 | { |
| 5815 | break :blk operand_ty; | 5832 | break :blk operand_ty; |
| 5816 | } | 5833 | } |
| 5817 | // We need to emit instructions to check for equality/inequality | 5834 | // We need to emit instructions to check for equality/inequality |
| 5818 | // of optionals that are not pointers. | 5835 | // of optionals that are not pointers. |
| 5819 | const is_by_ref = isByRef(scalar_ty, mod); | 5836 | const is_by_ref = isByRef(scalar_ty, pt); |
| 5820 | const opt_llvm_ty = try o.lowerType(scalar_ty); | 5837 | const opt_llvm_ty = try o.lowerType(scalar_ty); |
| 5821 | const lhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, lhs, is_by_ref); | 5838 | const lhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, lhs, is_by_ref); |
| 5822 | const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref); | 5839 | const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref); |
| ... | @@ -5908,7 +5925,8 @@ pub const FuncGen = struct { | ... | @@ -5908,7 +5925,8 @@ pub const FuncGen = struct { |
| 5908 | body: []const Air.Inst.Index, | 5925 | body: []const Air.Inst.Index, |
| 5909 | ) !Builder.Value { | 5926 | ) !Builder.Value { |
| 5910 | const o = self.dg.object; | 5927 | const o = self.dg.object; |
| 5911 | const mod = o.module; | 5928 | const pt = o.pt; |
| 5929 | const mod = pt.zcu; | ||
| 5912 | const inst_ty = self.typeOfIndex(inst); | 5930 | const inst_ty = self.typeOfIndex(inst); |
| 5913 | 5931 | ||
| 5914 | if (inst_ty.isNoReturn(mod)) { | 5932 | if (inst_ty.isNoReturn(mod)) { |
| ... | @@ -5916,7 +5934,7 @@ pub const FuncGen = struct { | ... | @@ -5916,7 +5934,7 @@ pub const FuncGen = struct { |
| 5916 | return .none; | 5934 | return .none; |
| 5917 | } | 5935 | } |
| 5918 | 5936 | ||
| 5919 | const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod); | 5937 | const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt); |
| 5920 | 5938 | ||
| 5921 | var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 }; | 5939 | var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 }; |
| 5922 | defer if (have_block_result) breaks.list.deinit(self.gpa); | 5940 | defer if (have_block_result) breaks.list.deinit(self.gpa); |
| ... | @@ -5940,7 +5958,7 @@ pub const FuncGen = struct { | ... | @@ -5940,7 +5958,7 @@ pub const FuncGen = struct { |
| 5940 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead | 5958 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead |
| 5941 | // of function pointers, however the phi makes it a runtime value and therefore | 5959 | // of function pointers, however the phi makes it a runtime value and therefore |
| 5942 | // the LLVM type has to be wrapped in a pointer. | 5960 | // the LLVM type has to be wrapped in a pointer. |
| 5943 | if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, mod)) { | 5961 | if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, pt)) { |
| 5944 | break :ty .ptr; | 5962 | break :ty .ptr; |
| 5945 | } | 5963 | } |
| 5946 | break :ty raw_llvm_ty; | 5964 | break :ty raw_llvm_ty; |
| ... | @@ -5958,13 +5976,13 @@ pub const FuncGen = struct { | ... | @@ -5958,13 +5976,13 @@ pub const FuncGen = struct { |
| 5958 | 5976 | ||
| 5959 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 5977 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5960 | const o = self.dg.object; | 5978 | const o = self.dg.object; |
| 5979 | const pt = o.pt; | ||
| 5961 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 5980 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5962 | const block = self.blocks.get(branch.block_inst).?; | 5981 | const block = self.blocks.get(branch.block_inst).?; |
| 5963 | 5982 | ||
| 5964 | // Add the values to the lists only if the break provides a value. | 5983 | // Add the values to the lists only if the break provides a value. |
| 5965 | const operand_ty = self.typeOf(branch.operand); | 5984 | const operand_ty = self.typeOf(branch.operand); |
| 5966 | const mod = o.module; | 5985 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 5967 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | ||
| 5968 | const val = try self.resolveInst(branch.operand); | 5986 | const val = try self.resolveInst(branch.operand); |
| 5969 | 5987 | ||
| 5970 | // For the phi node, we need the basic blocks and the values of the | 5988 | // For the phi node, we need the basic blocks and the values of the |
| ... | @@ -5998,7 +6016,7 @@ pub const FuncGen = struct { | ... | @@ -5998,7 +6016,7 @@ pub const FuncGen = struct { |
| 5998 | 6016 | ||
| 5999 | fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6017 | fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6000 | const o = self.dg.object; | 6018 | const o = self.dg.object; |
| 6001 | const mod = o.module; | 6019 | const pt = o.pt; |
| 6002 | const inst = body_tail[0]; | 6020 | const inst = body_tail[0]; |
| 6003 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6021 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6004 | const err_union = try self.resolveInst(pl_op.operand); | 6022 | const err_union = try self.resolveInst(pl_op.operand); |
| ... | @@ -6006,14 +6024,14 @@ pub const FuncGen = struct { | ... | @@ -6006,14 +6024,14 @@ pub const FuncGen = struct { |
| 6006 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | 6024 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 6007 | const err_union_ty = self.typeOf(pl_op.operand); | 6025 | const err_union_ty = self.typeOf(pl_op.operand); |
| 6008 | const payload_ty = self.typeOfIndex(inst); | 6026 | const payload_ty = self.typeOfIndex(inst); |
| 6009 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; | 6027 | const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false; |
| 6010 | const is_unused = self.liveness.isUnused(inst); | 6028 | const is_unused = self.liveness.isUnused(inst); |
| 6011 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused); | 6029 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused); |
| 6012 | } | 6030 | } |
| 6013 | 6031 | ||
| 6014 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6032 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6015 | const o = self.dg.object; | 6033 | const o = self.dg.object; |
| 6016 | const mod = o.module; | 6034 | const mod = o.pt.zcu; |
| 6017 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6035 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6018 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); | 6036 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); |
| 6019 | const err_union_ptr = try self.resolveInst(extra.data.ptr); | 6037 | const err_union_ptr = try self.resolveInst(extra.data.ptr); |
| ... | @@ -6033,9 +6051,10 @@ pub const FuncGen = struct { | ... | @@ -6033,9 +6051,10 @@ pub const FuncGen = struct { |
| 6033 | is_unused: bool, | 6051 | is_unused: bool, |
| 6034 | ) !Builder.Value { | 6052 | ) !Builder.Value { |
| 6035 | const o = fg.dg.object; | 6053 | const o = fg.dg.object; |
| 6036 | const mod = o.module; | 6054 | const pt = o.pt; |
| 6055 | const mod = pt.zcu; | ||
| 6037 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 6056 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 6038 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod); | 6057 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt); |
| 6039 | const err_union_llvm_ty = try o.lowerType(err_union_ty); | 6058 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6040 | const error_type = try o.errorIntType(); | 6059 | const error_type = try o.errorIntType(); |
| 6041 | 6060 | ||
| ... | @@ -6048,8 +6067,8 @@ pub const FuncGen = struct { | ... | @@ -6048,8 +6067,8 @@ pub const FuncGen = struct { |
| 6048 | else | 6067 | else |
| 6049 | err_union; | 6068 | err_union; |
| 6050 | } | 6069 | } |
| 6051 | const err_field_index = try errUnionErrorOffset(payload_ty, mod); | 6070 | const err_field_index = try errUnionErrorOffset(payload_ty, pt); |
| 6052 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 6071 | if (operand_is_ptr or isByRef(err_union_ty, pt)) { |
| 6053 | const err_field_ptr = | 6072 | const err_field_ptr = |
| 6054 | try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, ""); | 6073 | try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, ""); |
| 6055 | // TODO add alignment to this load | 6074 | // TODO add alignment to this load |
| ... | @@ -6077,13 +6096,13 @@ pub const FuncGen = struct { | ... | @@ -6077,13 +6096,13 @@ pub const FuncGen = struct { |
| 6077 | } | 6096 | } |
| 6078 | if (is_unused) return .none; | 6097 | if (is_unused) return .none; |
| 6079 | if (!payload_has_bits) return if (operand_is_ptr) err_union else .none; | 6098 | if (!payload_has_bits) return if (operand_is_ptr) err_union else .none; |
| 6080 | const offset = try errUnionPayloadOffset(payload_ty, mod); | 6099 | const offset = try errUnionPayloadOffset(payload_ty, pt); |
| 6081 | if (operand_is_ptr) { | 6100 | if (operand_is_ptr) { |
| 6082 | return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); | 6101 | return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); |
| 6083 | } else if (isByRef(err_union_ty, mod)) { | 6102 | } else if (isByRef(err_union_ty, pt)) { |
| 6084 | const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); | 6103 | const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); |
| 6085 | const payload_alignment = payload_ty.abiAlignment(mod).toLlvm(); | 6104 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); |
| 6086 | if (isByRef(payload_ty, mod)) { | 6105 | if (isByRef(payload_ty, pt)) { |
| 6087 | if (can_elide_load) | 6106 | if (can_elide_load) |
| 6088 | return payload_ptr; | 6107 | return payload_ptr; |
| 6089 | 6108 | ||
| ... | @@ -6161,7 +6180,7 @@ pub const FuncGen = struct { | ... | @@ -6161,7 +6180,7 @@ pub const FuncGen = struct { |
| 6161 | 6180 | ||
| 6162 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6181 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6163 | const o = self.dg.object; | 6182 | const o = self.dg.object; |
| 6164 | const mod = o.module; | 6183 | const mod = o.pt.zcu; |
| 6165 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6184 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6166 | const loop = self.air.extraData(Air.Block, ty_pl.payload); | 6185 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 6167 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]); | 6186 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]); |
| ... | @@ -6185,7 +6204,8 @@ pub const FuncGen = struct { | ... | @@ -6185,7 +6204,8 @@ pub const FuncGen = struct { |
| 6185 | 6204 | ||
| 6186 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6205 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6187 | const o = self.dg.object; | 6206 | const o = self.dg.object; |
| 6188 | const mod = o.module; | 6207 | const pt = o.pt; |
| 6208 | const mod = pt.zcu; | ||
| 6189 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6209 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6190 | const operand_ty = self.typeOf(ty_op.operand); | 6210 | const operand_ty = self.typeOf(ty_op.operand); |
| 6191 | const array_ty = operand_ty.childType(mod); | 6211 | const array_ty = operand_ty.childType(mod); |
| ... | @@ -6193,7 +6213,7 @@ pub const FuncGen = struct { | ... | @@ -6193,7 +6213,7 @@ pub const FuncGen = struct { |
| 6193 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod)); | 6213 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod)); |
| 6194 | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); | 6214 | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); |
| 6195 | const operand = try self.resolveInst(ty_op.operand); | 6215 | const operand = try self.resolveInst(ty_op.operand); |
| 6196 | if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) | 6216 | if (!array_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 6197 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); | 6217 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); |
| 6198 | const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{ | 6218 | const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{ |
| 6199 | try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0), | 6219 | try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0), |
| ... | @@ -6203,7 +6223,8 @@ pub const FuncGen = struct { | ... | @@ -6203,7 +6223,8 @@ pub const FuncGen = struct { |
| 6203 | 6223 | ||
| 6204 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6224 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6205 | const o = self.dg.object; | 6225 | const o = self.dg.object; |
| 6206 | const mod = o.module; | 6226 | const pt = o.pt; |
| 6227 | const mod = pt.zcu; | ||
| 6207 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6228 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6208 | 6229 | ||
| 6209 | const workaround_operand = try self.resolveInst(ty_op.operand); | 6230 | const workaround_operand = try self.resolveInst(ty_op.operand); |
| ... | @@ -6213,7 +6234,7 @@ pub const FuncGen = struct { | ... | @@ -6213,7 +6234,7 @@ pub const FuncGen = struct { |
| 6213 | 6234 | ||
| 6214 | const operand = o: { | 6235 | const operand = o: { |
| 6215 | // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381. | 6236 | // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381. |
| 6216 | const bit_size = operand_scalar_ty.bitSize(mod); | 6237 | const bit_size = operand_scalar_ty.bitSize(pt); |
| 6217 | for ([_]u8{ 8, 16, 32, 64, 128 }) |b| { | 6238 | for ([_]u8{ 8, 16, 32, 64, 128 }) |b| { |
| 6218 | if (bit_size < b) { | 6239 | if (bit_size < b) { |
| 6219 | break :o try self.wip.cast( | 6240 | break :o try self.wip.cast( |
| ... | @@ -6241,7 +6262,7 @@ pub const FuncGen = struct { | ... | @@ -6241,7 +6262,7 @@ pub const FuncGen = struct { |
| 6241 | "", | 6262 | "", |
| 6242 | ); | 6263 | ); |
| 6243 | 6264 | ||
| 6244 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod))); | 6265 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(pt))); |
| 6245 | const rt_int_ty = try o.builder.intType(rt_int_bits); | 6266 | const rt_int_ty = try o.builder.intType(rt_int_bits); |
| 6246 | var extended = try self.wip.conv( | 6267 | var extended = try self.wip.conv( |
| 6247 | if (is_signed_int) .signed else .unsigned, | 6268 | if (is_signed_int) .signed else .unsigned, |
| ... | @@ -6287,7 +6308,8 @@ pub const FuncGen = struct { | ... | @@ -6287,7 +6308,8 @@ pub const FuncGen = struct { |
| 6287 | _ = fast; | 6308 | _ = fast; |
| 6288 | 6309 | ||
| 6289 | const o = self.dg.object; | 6310 | const o = self.dg.object; |
| 6290 | const mod = o.module; | 6311 | const pt = o.pt; |
| 6312 | const mod = pt.zcu; | ||
| 6291 | const target = mod.getTarget(); | 6313 | const target = mod.getTarget(); |
| 6292 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6314 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6293 | 6315 | ||
| ... | @@ -6309,7 +6331,7 @@ pub const FuncGen = struct { | ... | @@ -6309,7 +6331,7 @@ pub const FuncGen = struct { |
| 6309 | ); | 6331 | ); |
| 6310 | } | 6332 | } |
| 6311 | 6333 | ||
| 6312 | const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(mod))); | 6334 | const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(pt))); |
| 6313 | const ret_ty = try o.builder.intType(rt_int_bits); | 6335 | const ret_ty = try o.builder.intType(rt_int_bits); |
| 6314 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { | 6336 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { |
| 6315 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | 6337 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard |
| ... | @@ -6348,19 +6370,20 @@ pub const FuncGen = struct { | ... | @@ -6348,19 +6370,20 @@ pub const FuncGen = struct { |
| 6348 | 6370 | ||
| 6349 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 6371 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 6350 | const o = fg.dg.object; | 6372 | const o = fg.dg.object; |
| 6351 | const mod = o.module; | 6373 | const mod = o.pt.zcu; |
| 6352 | return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr; | 6374 | return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr; |
| 6353 | } | 6375 | } |
| 6354 | 6376 | ||
| 6355 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 6377 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 6356 | const o = fg.dg.object; | 6378 | const o = fg.dg.object; |
| 6357 | const mod = o.module; | 6379 | const pt = o.pt; |
| 6380 | const mod = pt.zcu; | ||
| 6358 | const llvm_usize = try o.lowerType(Type.usize); | 6381 | const llvm_usize = try o.lowerType(Type.usize); |
| 6359 | switch (ty.ptrSize(mod)) { | 6382 | switch (ty.ptrSize(mod)) { |
| 6360 | .Slice => { | 6383 | .Slice => { |
| 6361 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); | 6384 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); |
| 6362 | const elem_ty = ty.childType(mod); | 6385 | const elem_ty = ty.childType(mod); |
| 6363 | const abi_size = elem_ty.abiSize(mod); | 6386 | const abi_size = elem_ty.abiSize(pt); |
| 6364 | if (abi_size == 1) return len; | 6387 | if (abi_size == 1) return len; |
| 6365 | const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size); | 6388 | const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size); |
| 6366 | return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, ""); | 6389 | return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, ""); |
| ... | @@ -6368,7 +6391,7 @@ pub const FuncGen = struct { | ... | @@ -6368,7 +6391,7 @@ pub const FuncGen = struct { |
| 6368 | .One => { | 6391 | .One => { |
| 6369 | const array_ty = ty.childType(mod); | 6392 | const array_ty = ty.childType(mod); |
| 6370 | const elem_ty = array_ty.childType(mod); | 6393 | const elem_ty = array_ty.childType(mod); |
| 6371 | const abi_size = elem_ty.abiSize(mod); | 6394 | const abi_size = elem_ty.abiSize(pt); |
| 6372 | return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size); | 6395 | return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size); |
| 6373 | }, | 6396 | }, |
| 6374 | .Many, .C => unreachable, | 6397 | .Many, .C => unreachable, |
| ... | @@ -6383,7 +6406,7 @@ pub const FuncGen = struct { | ... | @@ -6383,7 +6406,7 @@ pub const FuncGen = struct { |
| 6383 | 6406 | ||
| 6384 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value { | 6407 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value { |
| 6385 | const o = self.dg.object; | 6408 | const o = self.dg.object; |
| 6386 | const mod = o.module; | 6409 | const mod = o.pt.zcu; |
| 6387 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6410 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6388 | const slice_ptr = try self.resolveInst(ty_op.operand); | 6411 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 6389 | const slice_ptr_ty = self.typeOf(ty_op.operand); | 6412 | const slice_ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -6394,7 +6417,8 @@ pub const FuncGen = struct { | ... | @@ -6394,7 +6417,8 @@ pub const FuncGen = struct { |
| 6394 | 6417 | ||
| 6395 | fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6418 | fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6396 | const o = self.dg.object; | 6419 | const o = self.dg.object; |
| 6397 | const mod = o.module; | 6420 | const pt = o.pt; |
| 6421 | const mod = pt.zcu; | ||
| 6398 | const inst = body_tail[0]; | 6422 | const inst = body_tail[0]; |
| 6399 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6423 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6400 | const slice_ty = self.typeOf(bin_op.lhs); | 6424 | const slice_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -6404,11 +6428,11 @@ pub const FuncGen = struct { | ... | @@ -6404,11 +6428,11 @@ pub const FuncGen = struct { |
| 6404 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); | 6428 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); |
| 6405 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); | 6429 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); |
| 6406 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); | 6430 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); |
| 6407 | if (isByRef(elem_ty, mod)) { | 6431 | if (isByRef(elem_ty, pt)) { |
| 6408 | if (self.canElideLoad(body_tail)) | 6432 | if (self.canElideLoad(body_tail)) |
| 6409 | return ptr; | 6433 | return ptr; |
| 6410 | 6434 | ||
| 6411 | const elem_alignment = elem_ty.abiAlignment(mod).toLlvm(); | 6435 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); |
| 6412 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); | 6436 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); |
| 6413 | } | 6437 | } |
| 6414 | 6438 | ||
| ... | @@ -6417,7 +6441,7 @@ pub const FuncGen = struct { | ... | @@ -6417,7 +6441,7 @@ pub const FuncGen = struct { |
| 6417 | 6441 | ||
| 6418 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6442 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6419 | const o = self.dg.object; | 6443 | const o = self.dg.object; |
| 6420 | const mod = o.module; | 6444 | const mod = o.pt.zcu; |
| 6421 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6445 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6422 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 6446 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6423 | const slice_ty = self.typeOf(bin_op.lhs); | 6447 | const slice_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -6431,7 +6455,8 @@ pub const FuncGen = struct { | ... | @@ -6431,7 +6455,8 @@ pub const FuncGen = struct { |
| 6431 | 6455 | ||
| 6432 | fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6456 | fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6433 | const o = self.dg.object; | 6457 | const o = self.dg.object; |
| 6434 | const mod = o.module; | 6458 | const pt = o.pt; |
| 6459 | const mod = pt.zcu; | ||
| 6435 | const inst = body_tail[0]; | 6460 | const inst = body_tail[0]; |
| 6436 | 6461 | ||
| 6437 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6462 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | @@ -6440,15 +6465,15 @@ pub const FuncGen = struct { | ... | @@ -6440,15 +6465,15 @@ pub const FuncGen = struct { |
| 6440 | const rhs = try self.resolveInst(bin_op.rhs); | 6465 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6441 | const array_llvm_ty = try o.lowerType(array_ty); | 6466 | const array_llvm_ty = try o.lowerType(array_ty); |
| 6442 | const elem_ty = array_ty.childType(mod); | 6467 | const elem_ty = array_ty.childType(mod); |
| 6443 | if (isByRef(array_ty, mod)) { | 6468 | if (isByRef(array_ty, pt)) { |
| 6444 | const indices: [2]Builder.Value = .{ | 6469 | const indices: [2]Builder.Value = .{ |
| 6445 | try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs, | 6470 | try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs, |
| 6446 | }; | 6471 | }; |
| 6447 | if (isByRef(elem_ty, mod)) { | 6472 | if (isByRef(elem_ty, pt)) { |
| 6448 | const elem_ptr = | 6473 | const elem_ptr = |
| 6449 | try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, ""); | 6474 | try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, ""); |
| 6450 | if (canElideLoad(self, body_tail)) return elem_ptr; | 6475 | if (canElideLoad(self, body_tail)) return elem_ptr; |
| 6451 | const elem_alignment = elem_ty.abiAlignment(mod).toLlvm(); | 6476 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); |
| 6452 | return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal); | 6477 | return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal); |
| 6453 | } else { | 6478 | } else { |
| 6454 | const elem_ptr = | 6479 | const elem_ptr = |
| ... | @@ -6463,7 +6488,8 @@ pub const FuncGen = struct { | ... | @@ -6463,7 +6488,8 @@ pub const FuncGen = struct { |
| 6463 | 6488 | ||
| 6464 | fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6489 | fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6465 | const o = self.dg.object; | 6490 | const o = self.dg.object; |
| 6466 | const mod = o.module; | 6491 | const pt = o.pt; |
| 6492 | const mod = pt.zcu; | ||
| 6467 | const inst = body_tail[0]; | 6493 | const inst = body_tail[0]; |
| 6468 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6494 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6469 | const ptr_ty = self.typeOf(bin_op.lhs); | 6495 | const ptr_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -6477,9 +6503,9 @@ pub const FuncGen = struct { | ... | @@ -6477,9 +6503,9 @@ pub const FuncGen = struct { |
| 6477 | &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs } | 6503 | &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs } |
| 6478 | else | 6504 | else |
| 6479 | &.{rhs}, ""); | 6505 | &.{rhs}, ""); |
| 6480 | if (isByRef(elem_ty, mod)) { | 6506 | if (isByRef(elem_ty, pt)) { |
| 6481 | if (self.canElideLoad(body_tail)) return ptr; | 6507 | if (self.canElideLoad(body_tail)) return ptr; |
| 6482 | const elem_alignment = elem_ty.abiAlignment(mod).toLlvm(); | 6508 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); |
| 6483 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); | 6509 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); |
| 6484 | } | 6510 | } |
| 6485 | 6511 | ||
| ... | @@ -6488,12 +6514,13 @@ pub const FuncGen = struct { | ... | @@ -6488,12 +6514,13 @@ pub const FuncGen = struct { |
| 6488 | 6514 | ||
| 6489 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6515 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6490 | const o = self.dg.object; | 6516 | const o = self.dg.object; |
| 6491 | const mod = o.module; | 6517 | const pt = o.pt; |
| 6518 | const mod = pt.zcu; | ||
| 6492 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6519 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6493 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 6520 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6494 | const ptr_ty = self.typeOf(bin_op.lhs); | 6521 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 6495 | const elem_ty = ptr_ty.childType(mod); | 6522 | const elem_ty = ptr_ty.childType(mod); |
| 6496 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.resolveInst(bin_op.lhs); | 6523 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return self.resolveInst(bin_op.lhs); |
| 6497 | 6524 | ||
| 6498 | const base_ptr = try self.resolveInst(bin_op.lhs); | 6525 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 6499 | const rhs = try self.resolveInst(bin_op.rhs); | 6526 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -6530,7 +6557,8 @@ pub const FuncGen = struct { | ... | @@ -6530,7 +6557,8 @@ pub const FuncGen = struct { |
| 6530 | 6557 | ||
| 6531 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6558 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6532 | const o = self.dg.object; | 6559 | const o = self.dg.object; |
| 6533 | const mod = o.module; | 6560 | const pt = o.pt; |
| 6561 | const mod = pt.zcu; | ||
| 6534 | const inst = body_tail[0]; | 6562 | const inst = body_tail[0]; |
| 6535 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6563 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6536 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 6564 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -6538,27 +6566,27 @@ pub const FuncGen = struct { | ... | @@ -6538,27 +6566,27 @@ pub const FuncGen = struct { |
| 6538 | const struct_llvm_val = try self.resolveInst(struct_field.struct_operand); | 6566 | const struct_llvm_val = try self.resolveInst(struct_field.struct_operand); |
| 6539 | const field_index = struct_field.field_index; | 6567 | const field_index = struct_field.field_index; |
| 6540 | const field_ty = struct_ty.structFieldType(field_index, mod); | 6568 | const field_ty = struct_ty.structFieldType(field_index, mod); |
| 6541 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 6569 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 6542 | 6570 | ||
| 6543 | if (!isByRef(struct_ty, mod)) { | 6571 | if (!isByRef(struct_ty, pt)) { |
| 6544 | assert(!isByRef(field_ty, mod)); | 6572 | assert(!isByRef(field_ty, pt)); |
| 6545 | switch (struct_ty.zigTypeTag(mod)) { | 6573 | switch (struct_ty.zigTypeTag(mod)) { |
| 6546 | .Struct => switch (struct_ty.containerLayout(mod)) { | 6574 | .Struct => switch (struct_ty.containerLayout(mod)) { |
| 6547 | .@"packed" => { | 6575 | .@"packed" => { |
| 6548 | const struct_type = mod.typeToStruct(struct_ty).?; | 6576 | const struct_type = mod.typeToStruct(struct_ty).?; |
| 6549 | const bit_offset = mod.structPackedFieldBitOffset(struct_type, field_index); | 6577 | const bit_offset = pt.structPackedFieldBitOffset(struct_type, field_index); |
| 6550 | const containing_int = struct_llvm_val; | 6578 | const containing_int = struct_llvm_val; |
| 6551 | const shift_amt = | 6579 | const shift_amt = |
| 6552 | try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset); | 6580 | try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset); |
| 6553 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); | 6581 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); |
| 6554 | const elem_llvm_ty = try o.lowerType(field_ty); | 6582 | const elem_llvm_ty = try o.lowerType(field_ty); |
| 6555 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 6583 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 6556 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod))); | 6584 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); |
| 6557 | const truncated_int = | 6585 | const truncated_int = |
| 6558 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); | 6586 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 6559 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); | 6587 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); |
| 6560 | } else if (field_ty.isPtrAtRuntime(mod)) { | 6588 | } else if (field_ty.isPtrAtRuntime(mod)) { |
| 6561 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod))); | 6589 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); |
| 6562 | const truncated_int = | 6590 | const truncated_int = |
| 6563 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); | 6591 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 6564 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); | 6592 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); |
| ... | @@ -6575,12 +6603,12 @@ pub const FuncGen = struct { | ... | @@ -6575,12 +6603,12 @@ pub const FuncGen = struct { |
| 6575 | const containing_int = struct_llvm_val; | 6603 | const containing_int = struct_llvm_val; |
| 6576 | const elem_llvm_ty = try o.lowerType(field_ty); | 6604 | const elem_llvm_ty = try o.lowerType(field_ty); |
| 6577 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | 6605 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { |
| 6578 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod))); | 6606 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); |
| 6579 | const truncated_int = | 6607 | const truncated_int = |
| 6580 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); | 6608 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); |
| 6581 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); | 6609 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); |
| 6582 | } else if (field_ty.isPtrAtRuntime(mod)) { | 6610 | } else if (field_ty.isPtrAtRuntime(mod)) { |
| 6583 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(mod))); | 6611 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); |
| 6584 | const truncated_int = | 6612 | const truncated_int = |
| 6585 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); | 6613 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); |
| 6586 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); | 6614 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); |
| ... | @@ -6599,12 +6627,12 @@ pub const FuncGen = struct { | ... | @@ -6599,12 +6627,12 @@ pub const FuncGen = struct { |
| 6599 | const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?; | 6627 | const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?; |
| 6600 | const field_ptr = | 6628 | const field_ptr = |
| 6601 | try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, ""); | 6629 | try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, ""); |
| 6602 | const alignment = struct_ty.structFieldAlign(field_index, mod); | 6630 | const alignment = struct_ty.structFieldAlign(field_index, pt); |
| 6603 | const field_ptr_ty = try mod.ptrType(.{ | 6631 | const field_ptr_ty = try pt.ptrType(.{ |
| 6604 | .child = field_ty.toIntern(), | 6632 | .child = field_ty.toIntern(), |
| 6605 | .flags = .{ .alignment = alignment }, | 6633 | .flags = .{ .alignment = alignment }, |
| 6606 | }); | 6634 | }); |
| 6607 | if (isByRef(field_ty, mod)) { | 6635 | if (isByRef(field_ty, pt)) { |
| 6608 | if (canElideLoad(self, body_tail)) | 6636 | if (canElideLoad(self, body_tail)) |
| 6609 | return field_ptr; | 6637 | return field_ptr; |
| 6610 | 6638 | ||
| ... | @@ -6617,12 +6645,12 @@ pub const FuncGen = struct { | ... | @@ -6617,12 +6645,12 @@ pub const FuncGen = struct { |
| 6617 | }, | 6645 | }, |
| 6618 | .Union => { | 6646 | .Union => { |
| 6619 | const union_llvm_ty = try o.lowerType(struct_ty); | 6647 | const union_llvm_ty = try o.lowerType(struct_ty); |
| 6620 | const layout = struct_ty.unionGetLayout(mod); | 6648 | const layout = struct_ty.unionGetLayout(pt); |
| 6621 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); | 6649 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 6622 | const field_ptr = | 6650 | const field_ptr = |
| 6623 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); | 6651 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 6624 | const payload_alignment = layout.payload_align.toLlvm(); | 6652 | const payload_alignment = layout.payload_align.toLlvm(); |
| 6625 | if (isByRef(field_ty, mod)) { | 6653 | if (isByRef(field_ty, pt)) { |
| 6626 | if (canElideLoad(self, body_tail)) return field_ptr; | 6654 | if (canElideLoad(self, body_tail)) return field_ptr; |
| 6627 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal); | 6655 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal); |
| 6628 | } else { | 6656 | } else { |
| ... | @@ -6635,14 +6663,15 @@ pub const FuncGen = struct { | ... | @@ -6635,14 +6663,15 @@ pub const FuncGen = struct { |
| 6635 | 6663 | ||
| 6636 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6664 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6637 | const o = self.dg.object; | 6665 | const o = self.dg.object; |
| 6638 | const mod = o.module; | 6666 | const pt = o.pt; |
| 6667 | const mod = pt.zcu; | ||
| 6639 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6668 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6640 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 6669 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 6641 | 6670 | ||
| 6642 | const field_ptr = try self.resolveInst(extra.field_ptr); | 6671 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 6643 | 6672 | ||
| 6644 | const parent_ty = ty_pl.ty.toType().childType(mod); | 6673 | const parent_ty = ty_pl.ty.toType().childType(mod); |
| 6645 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); | 6674 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); |
| 6646 | if (field_offset == 0) return field_ptr; | 6675 | if (field_offset == 0) return field_ptr; |
| 6647 | 6676 | ||
| 6648 | const res_ty = try o.lowerType(ty_pl.ty.toType()); | 6677 | const res_ty = try o.lowerType(ty_pl.ty.toType()); |
| ... | @@ -6696,7 +6725,7 @@ pub const FuncGen = struct { | ... | @@ -6696,7 +6725,7 @@ pub const FuncGen = struct { |
| 6696 | 6725 | ||
| 6697 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6726 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6698 | const o = self.dg.object; | 6727 | const o = self.dg.object; |
| 6699 | const mod = o.module; | 6728 | const mod = o.pt.zcu; |
| 6700 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6729 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6701 | const operand = try self.resolveInst(pl_op.operand); | 6730 | const operand = try self.resolveInst(pl_op.operand); |
| 6702 | const name = self.air.nullTerminatedString(pl_op.payload); | 6731 | const name = self.air.nullTerminatedString(pl_op.payload); |
| ... | @@ -6743,9 +6772,9 @@ pub const FuncGen = struct { | ... | @@ -6743,9 +6772,9 @@ pub const FuncGen = struct { |
| 6743 | try o.lowerDebugType(operand_ty), | 6772 | try o.lowerDebugType(operand_ty), |
| 6744 | ); | 6773 | ); |
| 6745 | 6774 | ||
| 6746 | const zcu = o.module; | 6775 | const pt = o.pt; |
| 6747 | const owner_mod = self.dg.ownerModule(); | 6776 | const owner_mod = self.dg.ownerModule(); |
| 6748 | if (isByRef(operand_ty, zcu)) { | 6777 | if (isByRef(operand_ty, pt)) { |
| 6749 | _ = try self.wip.callIntrinsic( | 6778 | _ = try self.wip.callIntrinsic( |
| 6750 | .normal, | 6779 | .normal, |
| 6751 | .none, | 6780 | .none, |
| ... | @@ -6759,7 +6788,7 @@ pub const FuncGen = struct { | ... | @@ -6759,7 +6788,7 @@ pub const FuncGen = struct { |
| 6759 | "", | 6788 | "", |
| 6760 | ); | 6789 | ); |
| 6761 | } else if (owner_mod.optimize_mode == .Debug) { | 6790 | } else if (owner_mod.optimize_mode == .Debug) { |
| 6762 | const alignment = operand_ty.abiAlignment(zcu).toLlvm(); | 6791 | const alignment = operand_ty.abiAlignment(pt).toLlvm(); |
| 6763 | const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment); | 6792 | const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment); |
| 6764 | _ = try self.wip.store(.normal, operand, alloca, alignment); | 6793 | _ = try self.wip.store(.normal, operand, alloca, alignment); |
| 6765 | _ = try self.wip.callIntrinsic( | 6794 | _ = try self.wip.callIntrinsic( |
| ... | @@ -6830,7 +6859,8 @@ pub const FuncGen = struct { | ... | @@ -6830,7 +6859,8 @@ pub const FuncGen = struct { |
| 6830 | // This stores whether we need to add an elementtype attribute and | 6859 | // This stores whether we need to add an elementtype attribute and |
| 6831 | // if so, the element type itself. | 6860 | // if so, the element type itself. |
| 6832 | const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count); | 6861 | const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count); |
| 6833 | const mod = o.module; | 6862 | const pt = o.pt; |
| 6863 | const mod = pt.zcu; | ||
| 6834 | const target = mod.getTarget(); | 6864 | const target = mod.getTarget(); |
| 6835 | 6865 | ||
| 6836 | var llvm_ret_i: usize = 0; | 6866 | var llvm_ret_i: usize = 0; |
| ... | @@ -6930,13 +6960,13 @@ pub const FuncGen = struct { | ... | @@ -6930,13 +6960,13 @@ pub const FuncGen = struct { |
| 6930 | 6960 | ||
| 6931 | const arg_llvm_value = try self.resolveInst(input); | 6961 | const arg_llvm_value = try self.resolveInst(input); |
| 6932 | const arg_ty = self.typeOf(input); | 6962 | const arg_ty = self.typeOf(input); |
| 6933 | const is_by_ref = isByRef(arg_ty, mod); | 6963 | const is_by_ref = isByRef(arg_ty, pt); |
| 6934 | if (is_by_ref) { | 6964 | if (is_by_ref) { |
| 6935 | if (constraintAllowsMemory(constraint)) { | 6965 | if (constraintAllowsMemory(constraint)) { |
| 6936 | llvm_param_values[llvm_param_i] = arg_llvm_value; | 6966 | llvm_param_values[llvm_param_i] = arg_llvm_value; |
| 6937 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); | 6967 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 6938 | } else { | 6968 | } else { |
| 6939 | const alignment = arg_ty.abiAlignment(mod).toLlvm(); | 6969 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); |
| 6940 | const arg_llvm_ty = try o.lowerType(arg_ty); | 6970 | const arg_llvm_ty = try o.lowerType(arg_ty); |
| 6941 | const load_inst = | 6971 | const load_inst = |
| 6942 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); | 6972 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); |
| ... | @@ -6948,7 +6978,7 @@ pub const FuncGen = struct { | ... | @@ -6948,7 +6978,7 @@ pub const FuncGen = struct { |
| 6948 | llvm_param_values[llvm_param_i] = arg_llvm_value; | 6978 | llvm_param_values[llvm_param_i] = arg_llvm_value; |
| 6949 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); | 6979 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 6950 | } else { | 6980 | } else { |
| 6951 | const alignment = arg_ty.abiAlignment(mod).toLlvm(); | 6981 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); |
| 6952 | const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment); | 6982 | const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment); |
| 6953 | _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment); | 6983 | _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment); |
| 6954 | llvm_param_values[llvm_param_i] = arg_ptr; | 6984 | llvm_param_values[llvm_param_i] = arg_ptr; |
| ... | @@ -7000,7 +7030,7 @@ pub const FuncGen = struct { | ... | @@ -7000,7 +7030,7 @@ pub const FuncGen = struct { |
| 7000 | llvm_param_values[llvm_param_i] = llvm_rw_val; | 7030 | llvm_param_values[llvm_param_i] = llvm_rw_val; |
| 7001 | llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip); | 7031 | llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip); |
| 7002 | } else { | 7032 | } else { |
| 7003 | const alignment = rw_ty.abiAlignment(mod).toLlvm(); | 7033 | const alignment = rw_ty.abiAlignment(pt).toLlvm(); |
| 7004 | const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, ""); | 7034 | const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, ""); |
| 7005 | llvm_param_values[llvm_param_i] = loaded; | 7035 | llvm_param_values[llvm_param_i] = loaded; |
| 7006 | llvm_param_types[llvm_param_i] = llvm_elem_ty; | 7036 | llvm_param_types[llvm_param_i] = llvm_elem_ty; |
| ... | @@ -7161,7 +7191,7 @@ pub const FuncGen = struct { | ... | @@ -7161,7 +7191,7 @@ pub const FuncGen = struct { |
| 7161 | const output_ptr = try self.resolveInst(output); | 7191 | const output_ptr = try self.resolveInst(output); |
| 7162 | const output_ptr_ty = self.typeOf(output); | 7192 | const output_ptr_ty = self.typeOf(output); |
| 7163 | 7193 | ||
| 7164 | const alignment = output_ptr_ty.ptrAlignment(mod).toLlvm(); | 7194 | const alignment = output_ptr_ty.ptrAlignment(pt).toLlvm(); |
| 7165 | _ = try self.wip.store(.normal, output_value, output_ptr, alignment); | 7195 | _ = try self.wip.store(.normal, output_value, output_ptr, alignment); |
| 7166 | } else { | 7196 | } else { |
| 7167 | ret_val = output_value; | 7197 | ret_val = output_value; |
| ... | @@ -7179,7 +7209,8 @@ pub const FuncGen = struct { | ... | @@ -7179,7 +7209,8 @@ pub const FuncGen = struct { |
| 7179 | cond: Builder.IntegerCondition, | 7209 | cond: Builder.IntegerCondition, |
| 7180 | ) !Builder.Value { | 7210 | ) !Builder.Value { |
| 7181 | const o = self.dg.object; | 7211 | const o = self.dg.object; |
| 7182 | const mod = o.module; | 7212 | const pt = o.pt; |
| 7213 | const mod = pt.zcu; | ||
| 7183 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 7214 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7184 | const operand = try self.resolveInst(un_op); | 7215 | const operand = try self.resolveInst(un_op); |
| 7185 | const operand_ty = self.typeOf(un_op); | 7216 | const operand_ty = self.typeOf(un_op); |
| ... | @@ -7204,7 +7235,7 @@ pub const FuncGen = struct { | ... | @@ -7204,7 +7235,7 @@ pub const FuncGen = struct { |
| 7204 | 7235 | ||
| 7205 | comptime assert(optional_layout_version == 3); | 7236 | comptime assert(optional_layout_version == 3); |
| 7206 | 7237 | ||
| 7207 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7238 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7208 | const loaded = if (operand_is_ptr) | 7239 | const loaded = if (operand_is_ptr) |
| 7209 | try self.wip.load(.normal, optional_llvm_ty, operand, .default, "") | 7240 | try self.wip.load(.normal, optional_llvm_ty, operand, .default, "") |
| 7210 | else | 7241 | else |
| ... | @@ -7212,7 +7243,7 @@ pub const FuncGen = struct { | ... | @@ -7212,7 +7243,7 @@ pub const FuncGen = struct { |
| 7212 | return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), ""); | 7243 | return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), ""); |
| 7213 | } | 7244 | } |
| 7214 | 7245 | ||
| 7215 | const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod); | 7246 | const is_by_ref = operand_is_ptr or isByRef(optional_ty, pt); |
| 7216 | return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref); | 7247 | return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref); |
| 7217 | } | 7248 | } |
| 7218 | 7249 | ||
| ... | @@ -7223,7 +7254,8 @@ pub const FuncGen = struct { | ... | @@ -7223,7 +7254,8 @@ pub const FuncGen = struct { |
| 7223 | operand_is_ptr: bool, | 7254 | operand_is_ptr: bool, |
| 7224 | ) !Builder.Value { | 7255 | ) !Builder.Value { |
| 7225 | const o = self.dg.object; | 7256 | const o = self.dg.object; |
| 7226 | const mod = o.module; | 7257 | const pt = o.pt; |
| 7258 | const mod = pt.zcu; | ||
| 7227 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 7259 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7228 | const operand = try self.resolveInst(un_op); | 7260 | const operand = try self.resolveInst(un_op); |
| 7229 | const operand_ty = self.typeOf(un_op); | 7261 | const operand_ty = self.typeOf(un_op); |
| ... | @@ -7241,7 +7273,7 @@ pub const FuncGen = struct { | ... | @@ -7241,7 +7273,7 @@ pub const FuncGen = struct { |
| 7241 | return val.toValue(); | 7273 | return val.toValue(); |
| 7242 | } | 7274 | } |
| 7243 | 7275 | ||
| 7244 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7276 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7245 | const loaded = if (operand_is_ptr) | 7277 | const loaded = if (operand_is_ptr) |
| 7246 | try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "") | 7278 | try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "") |
| 7247 | else | 7279 | else |
| ... | @@ -7249,9 +7281,9 @@ pub const FuncGen = struct { | ... | @@ -7249,9 +7281,9 @@ pub const FuncGen = struct { |
| 7249 | return self.wip.icmp(cond, loaded, zero, ""); | 7281 | return self.wip.icmp(cond, loaded, zero, ""); |
| 7250 | } | 7282 | } |
| 7251 | 7283 | ||
| 7252 | const err_field_index = try errUnionErrorOffset(payload_ty, mod); | 7284 | const err_field_index = try errUnionErrorOffset(payload_ty, pt); |
| 7253 | 7285 | ||
| 7254 | const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: { | 7286 | const loaded = if (operand_is_ptr or isByRef(err_union_ty, pt)) loaded: { |
| 7255 | const err_union_llvm_ty = try o.lowerType(err_union_ty); | 7287 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7256 | const err_field_ptr = | 7288 | const err_field_ptr = |
| 7257 | try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, ""); | 7289 | try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, ""); |
| ... | @@ -7262,12 +7294,13 @@ pub const FuncGen = struct { | ... | @@ -7262,12 +7294,13 @@ pub const FuncGen = struct { |
| 7262 | 7294 | ||
| 7263 | fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7295 | fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7264 | const o = self.dg.object; | 7296 | const o = self.dg.object; |
| 7265 | const mod = o.module; | 7297 | const pt = o.pt; |
| 7298 | const mod = pt.zcu; | ||
| 7266 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7299 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7267 | const operand = try self.resolveInst(ty_op.operand); | 7300 | const operand = try self.resolveInst(ty_op.operand); |
| 7268 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); | 7301 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); |
| 7269 | const payload_ty = optional_ty.optionalChild(mod); | 7302 | const payload_ty = optional_ty.optionalChild(mod); |
| 7270 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7303 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7271 | // We have a pointer to a zero-bit value and we need to return | 7304 | // We have a pointer to a zero-bit value and we need to return |
| 7272 | // a pointer to a zero-bit value. | 7305 | // a pointer to a zero-bit value. |
| 7273 | return operand; | 7306 | return operand; |
| ... | @@ -7283,13 +7316,14 @@ pub const FuncGen = struct { | ... | @@ -7283,13 +7316,14 @@ pub const FuncGen = struct { |
| 7283 | comptime assert(optional_layout_version == 3); | 7316 | comptime assert(optional_layout_version == 3); |
| 7284 | 7317 | ||
| 7285 | const o = self.dg.object; | 7318 | const o = self.dg.object; |
| 7286 | const mod = o.module; | 7319 | const pt = o.pt; |
| 7320 | const mod = pt.zcu; | ||
| 7287 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7321 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7288 | const operand = try self.resolveInst(ty_op.operand); | 7322 | const operand = try self.resolveInst(ty_op.operand); |
| 7289 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); | 7323 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); |
| 7290 | const payload_ty = optional_ty.optionalChild(mod); | 7324 | const payload_ty = optional_ty.optionalChild(mod); |
| 7291 | const non_null_bit = try o.builder.intValue(.i8, 1); | 7325 | const non_null_bit = try o.builder.intValue(.i8, 1); |
| 7292 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7326 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7293 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. | 7327 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. |
| 7294 | _ = try self.wip.store(.normal, non_null_bit, operand, .default); | 7328 | _ = try self.wip.store(.normal, non_null_bit, operand, .default); |
| 7295 | return operand; | 7329 | return operand; |
| ... | @@ -7314,13 +7348,14 @@ pub const FuncGen = struct { | ... | @@ -7314,13 +7348,14 @@ pub const FuncGen = struct { |
| 7314 | 7348 | ||
| 7315 | fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 7349 | fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7316 | const o = self.dg.object; | 7350 | const o = self.dg.object; |
| 7317 | const mod = o.module; | 7351 | const pt = o.pt; |
| 7352 | const mod = pt.zcu; | ||
| 7318 | const inst = body_tail[0]; | 7353 | const inst = body_tail[0]; |
| 7319 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7354 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7320 | const operand = try self.resolveInst(ty_op.operand); | 7355 | const operand = try self.resolveInst(ty_op.operand); |
| 7321 | const optional_ty = self.typeOf(ty_op.operand); | 7356 | const optional_ty = self.typeOf(ty_op.operand); |
| 7322 | const payload_ty = self.typeOfIndex(inst); | 7357 | const payload_ty = self.typeOfIndex(inst); |
| 7323 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 7358 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 7324 | 7359 | ||
| 7325 | if (optional_ty.optionalReprIsPayload(mod)) { | 7360 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 7326 | // Payload value is the same as the optional value. | 7361 | // Payload value is the same as the optional value. |
| ... | @@ -7328,7 +7363,7 @@ pub const FuncGen = struct { | ... | @@ -7328,7 +7363,7 @@ pub const FuncGen = struct { |
| 7328 | } | 7363 | } |
| 7329 | 7364 | ||
| 7330 | const opt_llvm_ty = try o.lowerType(optional_ty); | 7365 | const opt_llvm_ty = try o.lowerType(optional_ty); |
| 7331 | const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false; | 7366 | const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false; |
| 7332 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); | 7367 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); |
| 7333 | } | 7368 | } |
| 7334 | 7369 | ||
| ... | @@ -7338,7 +7373,8 @@ pub const FuncGen = struct { | ... | @@ -7338,7 +7373,8 @@ pub const FuncGen = struct { |
| 7338 | operand_is_ptr: bool, | 7373 | operand_is_ptr: bool, |
| 7339 | ) !Builder.Value { | 7374 | ) !Builder.Value { |
| 7340 | const o = self.dg.object; | 7375 | const o = self.dg.object; |
| 7341 | const mod = o.module; | 7376 | const pt = o.pt; |
| 7377 | const mod = pt.zcu; | ||
| 7342 | const inst = body_tail[0]; | 7378 | const inst = body_tail[0]; |
| 7343 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7379 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7344 | const operand = try self.resolveInst(ty_op.operand); | 7380 | const operand = try self.resolveInst(ty_op.operand); |
| ... | @@ -7347,17 +7383,17 @@ pub const FuncGen = struct { | ... | @@ -7347,17 +7383,17 @@ pub const FuncGen = struct { |
| 7347 | const result_ty = self.typeOfIndex(inst); | 7383 | const result_ty = self.typeOfIndex(inst); |
| 7348 | const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty; | 7384 | const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty; |
| 7349 | 7385 | ||
| 7350 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7386 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7351 | return if (operand_is_ptr) operand else .none; | 7387 | return if (operand_is_ptr) operand else .none; |
| 7352 | } | 7388 | } |
| 7353 | const offset = try errUnionPayloadOffset(payload_ty, mod); | 7389 | const offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7354 | const err_union_llvm_ty = try o.lowerType(err_union_ty); | 7390 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7355 | if (operand_is_ptr) { | 7391 | if (operand_is_ptr) { |
| 7356 | return self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); | 7392 | return self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7357 | } else if (isByRef(err_union_ty, mod)) { | 7393 | } else if (isByRef(err_union_ty, pt)) { |
| 7358 | const payload_alignment = payload_ty.abiAlignment(mod).toLlvm(); | 7394 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); |
| 7359 | const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); | 7395 | const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7360 | if (isByRef(payload_ty, mod)) { | 7396 | if (isByRef(payload_ty, pt)) { |
| 7361 | if (self.canElideLoad(body_tail)) return payload_ptr; | 7397 | if (self.canElideLoad(body_tail)) return payload_ptr; |
| 7362 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); | 7398 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); |
| 7363 | } | 7399 | } |
| ... | @@ -7373,7 +7409,8 @@ pub const FuncGen = struct { | ... | @@ -7373,7 +7409,8 @@ pub const FuncGen = struct { |
| 7373 | operand_is_ptr: bool, | 7409 | operand_is_ptr: bool, |
| 7374 | ) !Builder.Value { | 7410 | ) !Builder.Value { |
| 7375 | const o = self.dg.object; | 7411 | const o = self.dg.object; |
| 7376 | const mod = o.module; | 7412 | const pt = o.pt; |
| 7413 | const mod = pt.zcu; | ||
| 7377 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7414 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7378 | const operand = try self.resolveInst(ty_op.operand); | 7415 | const operand = try self.resolveInst(ty_op.operand); |
| 7379 | const operand_ty = self.typeOf(ty_op.operand); | 7416 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -7388,14 +7425,14 @@ pub const FuncGen = struct { | ... | @@ -7388,14 +7425,14 @@ pub const FuncGen = struct { |
| 7388 | } | 7425 | } |
| 7389 | 7426 | ||
| 7390 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 7427 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 7391 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7428 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7392 | if (!operand_is_ptr) return operand; | 7429 | if (!operand_is_ptr) return operand; |
| 7393 | return self.wip.load(.normal, error_type, operand, .default, ""); | 7430 | return self.wip.load(.normal, error_type, operand, .default, ""); |
| 7394 | } | 7431 | } |
| 7395 | 7432 | ||
| 7396 | const offset = try errUnionErrorOffset(payload_ty, mod); | 7433 | const offset = try errUnionErrorOffset(payload_ty, pt); |
| 7397 | 7434 | ||
| 7398 | if (operand_is_ptr or isByRef(err_union_ty, mod)) { | 7435 | if (operand_is_ptr or isByRef(err_union_ty, pt)) { |
| 7399 | const err_union_llvm_ty = try o.lowerType(err_union_ty); | 7436 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7400 | const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); | 7437 | const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7401 | return self.wip.load(.normal, error_type, err_field_ptr, .default, ""); | 7438 | return self.wip.load(.normal, error_type, err_field_ptr, .default, ""); |
| ... | @@ -7406,22 +7443,23 @@ pub const FuncGen = struct { | ... | @@ -7406,22 +7443,23 @@ pub const FuncGen = struct { |
| 7406 | 7443 | ||
| 7407 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7444 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7408 | const o = self.dg.object; | 7445 | const o = self.dg.object; |
| 7409 | const mod = o.module; | 7446 | const pt = o.pt; |
| 7447 | const mod = pt.zcu; | ||
| 7410 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7448 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7411 | const operand = try self.resolveInst(ty_op.operand); | 7449 | const operand = try self.resolveInst(ty_op.operand); |
| 7412 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); | 7450 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); |
| 7413 | 7451 | ||
| 7414 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 7452 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 7415 | const non_error_val = try o.builder.intValue(try o.errorIntType(), 0); | 7453 | const non_error_val = try o.builder.intValue(try o.errorIntType(), 0); |
| 7416 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7454 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7417 | _ = try self.wip.store(.normal, non_error_val, operand, .default); | 7455 | _ = try self.wip.store(.normal, non_error_val, operand, .default); |
| 7418 | return operand; | 7456 | return operand; |
| 7419 | } | 7457 | } |
| 7420 | const err_union_llvm_ty = try o.lowerType(err_union_ty); | 7458 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7421 | { | 7459 | { |
| 7422 | const err_int_ty = try mod.errorIntType(); | 7460 | const err_int_ty = try pt.errorIntType(); |
| 7423 | const error_alignment = err_int_ty.abiAlignment(mod).toLlvm(); | 7461 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); |
| 7424 | const error_offset = try errUnionErrorOffset(payload_ty, mod); | 7462 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7425 | // First set the non-error value. | 7463 | // First set the non-error value. |
| 7426 | const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, ""); | 7464 | const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, ""); |
| 7427 | _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment); | 7465 | _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment); |
| ... | @@ -7429,7 +7467,7 @@ pub const FuncGen = struct { | ... | @@ -7429,7 +7467,7 @@ pub const FuncGen = struct { |
| 7429 | // Then return the payload pointer (only if it is used). | 7467 | // Then return the payload pointer (only if it is used). |
| 7430 | if (self.liveness.isUnused(inst)) return .none; | 7468 | if (self.liveness.isUnused(inst)) return .none; |
| 7431 | 7469 | ||
| 7432 | const payload_offset = try errUnionPayloadOffset(payload_ty, mod); | 7470 | const payload_offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7433 | return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, ""); | 7471 | return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, ""); |
| 7434 | } | 7472 | } |
| 7435 | 7473 | ||
| ... | @@ -7446,19 +7484,21 @@ pub const FuncGen = struct { | ... | @@ -7446,19 +7484,21 @@ pub const FuncGen = struct { |
| 7446 | 7484 | ||
| 7447 | fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7485 | fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7448 | const o = self.dg.object; | 7486 | const o = self.dg.object; |
| 7487 | const pt = o.pt; | ||
| 7488 | const mod = pt.zcu; | ||
| 7489 | |||
| 7449 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 7490 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7450 | const struct_ty = ty_pl.ty.toType(); | 7491 | const struct_ty = ty_pl.ty.toType(); |
| 7451 | const field_index = ty_pl.payload; | 7492 | const field_index = ty_pl.payload; |
| 7452 | 7493 | ||
| 7453 | const mod = o.module; | ||
| 7454 | const struct_llvm_ty = try o.lowerType(struct_ty); | 7494 | const struct_llvm_ty = try o.lowerType(struct_ty); |
| 7455 | const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?; | 7495 | const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?; |
| 7456 | assert(self.err_ret_trace != .none); | 7496 | assert(self.err_ret_trace != .none); |
| 7457 | const field_ptr = | 7497 | const field_ptr = |
| 7458 | try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, ""); | 7498 | try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, ""); |
| 7459 | const field_alignment = struct_ty.structFieldAlign(field_index, mod); | 7499 | const field_alignment = struct_ty.structFieldAlign(field_index, pt); |
| 7460 | const field_ty = struct_ty.structFieldType(field_index, mod); | 7500 | const field_ty = struct_ty.structFieldType(field_index, mod); |
| 7461 | const field_ptr_ty = try mod.ptrType(.{ | 7501 | const field_ptr_ty = try pt.ptrType(.{ |
| 7462 | .child = field_ty.toIntern(), | 7502 | .child = field_ty.toIntern(), |
| 7463 | .flags = .{ .alignment = field_alignment }, | 7503 | .flags = .{ .alignment = field_alignment }, |
| 7464 | }); | 7504 | }); |
| ... | @@ -7490,29 +7530,30 @@ pub const FuncGen = struct { | ... | @@ -7490,29 +7530,30 @@ pub const FuncGen = struct { |
| 7490 | 7530 | ||
| 7491 | fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 7531 | fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7492 | const o = self.dg.object; | 7532 | const o = self.dg.object; |
| 7493 | const mod = o.module; | 7533 | const pt = o.pt; |
| 7534 | const mod = pt.zcu; | ||
| 7494 | const inst = body_tail[0]; | 7535 | const inst = body_tail[0]; |
| 7495 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7536 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7496 | const payload_ty = self.typeOf(ty_op.operand); | 7537 | const payload_ty = self.typeOf(ty_op.operand); |
| 7497 | const non_null_bit = try o.builder.intValue(.i8, 1); | 7538 | const non_null_bit = try o.builder.intValue(.i8, 1); |
| 7498 | comptime assert(optional_layout_version == 3); | 7539 | comptime assert(optional_layout_version == 3); |
| 7499 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit; | 7540 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return non_null_bit; |
| 7500 | const operand = try self.resolveInst(ty_op.operand); | 7541 | const operand = try self.resolveInst(ty_op.operand); |
| 7501 | const optional_ty = self.typeOfIndex(inst); | 7542 | const optional_ty = self.typeOfIndex(inst); |
| 7502 | if (optional_ty.optionalReprIsPayload(mod)) return operand; | 7543 | if (optional_ty.optionalReprIsPayload(mod)) return operand; |
| 7503 | const llvm_optional_ty = try o.lowerType(optional_ty); | 7544 | const llvm_optional_ty = try o.lowerType(optional_ty); |
| 7504 | if (isByRef(optional_ty, mod)) { | 7545 | if (isByRef(optional_ty, pt)) { |
| 7505 | const directReturn = self.isNextRet(body_tail); | 7546 | const directReturn = self.isNextRet(body_tail); |
| 7506 | const optional_ptr = if (directReturn) | 7547 | const optional_ptr = if (directReturn) |
| 7507 | self.ret_ptr | 7548 | self.ret_ptr |
| 7508 | else brk: { | 7549 | else brk: { |
| 7509 | const alignment = optional_ty.abiAlignment(mod).toLlvm(); | 7550 | const alignment = optional_ty.abiAlignment(pt).toLlvm(); |
| 7510 | const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment); | 7551 | const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment); |
| 7511 | break :brk optional_ptr; | 7552 | break :brk optional_ptr; |
| 7512 | }; | 7553 | }; |
| 7513 | 7554 | ||
| 7514 | const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, ""); | 7555 | const payload_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 0, ""); |
| 7515 | const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); | 7556 | const payload_ptr_ty = try pt.singleMutPtrType(payload_ty); |
| 7516 | try self.store(payload_ptr, payload_ptr_ty, operand, .none); | 7557 | try self.store(payload_ptr, payload_ptr_ty, operand, .none); |
| 7517 | const non_null_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 1, ""); | 7558 | const non_null_ptr = try self.wip.gepStruct(llvm_optional_ty, optional_ptr, 1, ""); |
| 7518 | _ = try self.wip.store(.normal, non_null_bit, non_null_ptr, .default); | 7559 | _ = try self.wip.store(.normal, non_null_bit, non_null_ptr, .default); |
| ... | @@ -7523,36 +7564,36 @@ pub const FuncGen = struct { | ... | @@ -7523,36 +7564,36 @@ pub const FuncGen = struct { |
| 7523 | 7564 | ||
| 7524 | fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 7565 | fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7525 | const o = self.dg.object; | 7566 | const o = self.dg.object; |
| 7526 | const mod = o.module; | 7567 | const pt = o.pt; |
| 7527 | const inst = body_tail[0]; | 7568 | const inst = body_tail[0]; |
| 7528 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7569 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7529 | const err_un_ty = self.typeOfIndex(inst); | 7570 | const err_un_ty = self.typeOfIndex(inst); |
| 7530 | const operand = try self.resolveInst(ty_op.operand); | 7571 | const operand = try self.resolveInst(ty_op.operand); |
| 7531 | const payload_ty = self.typeOf(ty_op.operand); | 7572 | const payload_ty = self.typeOf(ty_op.operand); |
| 7532 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 7573 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 7533 | return operand; | 7574 | return operand; |
| 7534 | } | 7575 | } |
| 7535 | const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0); | 7576 | const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0); |
| 7536 | const err_un_llvm_ty = try o.lowerType(err_un_ty); | 7577 | const err_un_llvm_ty = try o.lowerType(err_un_ty); |
| 7537 | 7578 | ||
| 7538 | const payload_offset = try errUnionPayloadOffset(payload_ty, mod); | 7579 | const payload_offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7539 | const error_offset = try errUnionErrorOffset(payload_ty, mod); | 7580 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7540 | if (isByRef(err_un_ty, mod)) { | 7581 | if (isByRef(err_un_ty, pt)) { |
| 7541 | const directReturn = self.isNextRet(body_tail); | 7582 | const directReturn = self.isNextRet(body_tail); |
| 7542 | const result_ptr = if (directReturn) | 7583 | const result_ptr = if (directReturn) |
| 7543 | self.ret_ptr | 7584 | self.ret_ptr |
| 7544 | else brk: { | 7585 | else brk: { |
| 7545 | const alignment = err_un_ty.abiAlignment(mod).toLlvm(); | 7586 | const alignment = err_un_ty.abiAlignment(pt).toLlvm(); |
| 7546 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); | 7587 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); |
| 7547 | break :brk result_ptr; | 7588 | break :brk result_ptr; |
| 7548 | }; | 7589 | }; |
| 7549 | 7590 | ||
| 7550 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); | 7591 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 7551 | const err_int_ty = try mod.errorIntType(); | 7592 | const err_int_ty = try pt.errorIntType(); |
| 7552 | const error_alignment = err_int_ty.abiAlignment(mod).toLlvm(); | 7593 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); |
| 7553 | _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment); | 7594 | _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment); |
| 7554 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); | 7595 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 7555 | const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); | 7596 | const payload_ptr_ty = try pt.singleMutPtrType(payload_ty); |
| 7556 | try self.store(payload_ptr, payload_ptr_ty, operand, .none); | 7597 | try self.store(payload_ptr, payload_ptr_ty, operand, .none); |
| 7557 | return result_ptr; | 7598 | return result_ptr; |
| 7558 | } | 7599 | } |
| ... | @@ -7564,33 +7605,34 @@ pub const FuncGen = struct { | ... | @@ -7564,33 +7605,34 @@ pub const FuncGen = struct { |
| 7564 | 7605 | ||
| 7565 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 7606 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7566 | const o = self.dg.object; | 7607 | const o = self.dg.object; |
| 7567 | const mod = o.module; | 7608 | const pt = o.pt; |
| 7609 | const mod = pt.zcu; | ||
| 7568 | const inst = body_tail[0]; | 7610 | const inst = body_tail[0]; |
| 7569 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7611 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7570 | const err_un_ty = self.typeOfIndex(inst); | 7612 | const err_un_ty = self.typeOfIndex(inst); |
| 7571 | const payload_ty = err_un_ty.errorUnionPayload(mod); | 7613 | const payload_ty = err_un_ty.errorUnionPayload(mod); |
| 7572 | const operand = try self.resolveInst(ty_op.operand); | 7614 | const operand = try self.resolveInst(ty_op.operand); |
| 7573 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand; | 7615 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return operand; |
| 7574 | const err_un_llvm_ty = try o.lowerType(err_un_ty); | 7616 | const err_un_llvm_ty = try o.lowerType(err_un_ty); |
| 7575 | 7617 | ||
| 7576 | const payload_offset = try errUnionPayloadOffset(payload_ty, mod); | 7618 | const payload_offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7577 | const error_offset = try errUnionErrorOffset(payload_ty, mod); | 7619 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7578 | if (isByRef(err_un_ty, mod)) { | 7620 | if (isByRef(err_un_ty, pt)) { |
| 7579 | const directReturn = self.isNextRet(body_tail); | 7621 | const directReturn = self.isNextRet(body_tail); |
| 7580 | const result_ptr = if (directReturn) | 7622 | const result_ptr = if (directReturn) |
| 7581 | self.ret_ptr | 7623 | self.ret_ptr |
| 7582 | else brk: { | 7624 | else brk: { |
| 7583 | const alignment = err_un_ty.abiAlignment(mod).toLlvm(); | 7625 | const alignment = err_un_ty.abiAlignment(pt).toLlvm(); |
| 7584 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); | 7626 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); |
| 7585 | break :brk result_ptr; | 7627 | break :brk result_ptr; |
| 7586 | }; | 7628 | }; |
| 7587 | 7629 | ||
| 7588 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); | 7630 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 7589 | const err_int_ty = try mod.errorIntType(); | 7631 | const err_int_ty = try pt.errorIntType(); |
| 7590 | const error_alignment = err_int_ty.abiAlignment(mod).toLlvm(); | 7632 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); |
| 7591 | _ = try self.wip.store(.normal, operand, err_ptr, error_alignment); | 7633 | _ = try self.wip.store(.normal, operand, err_ptr, error_alignment); |
| 7592 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); | 7634 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 7593 | const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); | 7635 | const payload_ptr_ty = try pt.singleMutPtrType(payload_ty); |
| 7594 | // TODO store undef to payload_ptr | 7636 | // TODO store undef to payload_ptr |
| 7595 | _ = payload_ptr; | 7637 | _ = payload_ptr; |
| 7596 | _ = payload_ptr_ty; | 7638 | _ = payload_ptr_ty; |
| ... | @@ -7624,7 +7666,8 @@ pub const FuncGen = struct { | ... | @@ -7624,7 +7666,8 @@ pub const FuncGen = struct { |
| 7624 | 7666 | ||
| 7625 | fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7667 | fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7626 | const o = self.dg.object; | 7668 | const o = self.dg.object; |
| 7627 | const mod = o.module; | 7669 | const pt = o.pt; |
| 7670 | const mod = pt.zcu; | ||
| 7628 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; | 7671 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; |
| 7629 | const extra = self.air.extraData(Air.Bin, data.payload).data; | 7672 | const extra = self.air.extraData(Air.Bin, data.payload).data; |
| 7630 | 7673 | ||
| ... | @@ -7636,7 +7679,7 @@ pub const FuncGen = struct { | ... | @@ -7636,7 +7679,7 @@ pub const FuncGen = struct { |
| 7636 | const access_kind: Builder.MemoryAccessKind = | 7679 | const access_kind: Builder.MemoryAccessKind = |
| 7637 | if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | 7680 | if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; |
| 7638 | const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod)); | 7681 | const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod)); |
| 7639 | const alignment = vector_ptr_ty.ptrAlignment(mod).toLlvm(); | 7682 | const alignment = vector_ptr_ty.ptrAlignment(pt).toLlvm(); |
| 7640 | const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, ""); | 7683 | const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, ""); |
| 7641 | 7684 | ||
| 7642 | const new_vector = try self.wip.insertElement(loaded, operand, index, ""); | 7685 | const new_vector = try self.wip.insertElement(loaded, operand, index, ""); |
| ... | @@ -7646,7 +7689,7 @@ pub const FuncGen = struct { | ... | @@ -7646,7 +7689,7 @@ pub const FuncGen = struct { |
| 7646 | 7689 | ||
| 7647 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7690 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7648 | const o = self.dg.object; | 7691 | const o = self.dg.object; |
| 7649 | const mod = o.module; | 7692 | const mod = o.pt.zcu; |
| 7650 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7693 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7651 | const lhs = try self.resolveInst(bin_op.lhs); | 7694 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7652 | const rhs = try self.resolveInst(bin_op.rhs); | 7695 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7666,7 +7709,7 @@ pub const FuncGen = struct { | ... | @@ -7666,7 +7709,7 @@ pub const FuncGen = struct { |
| 7666 | 7709 | ||
| 7667 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7710 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7668 | const o = self.dg.object; | 7711 | const o = self.dg.object; |
| 7669 | const mod = o.module; | 7712 | const mod = o.pt.zcu; |
| 7670 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7713 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7671 | const lhs = try self.resolveInst(bin_op.lhs); | 7714 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7672 | const rhs = try self.resolveInst(bin_op.rhs); | 7715 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7696,7 +7739,7 @@ pub const FuncGen = struct { | ... | @@ -7696,7 +7739,7 @@ pub const FuncGen = struct { |
| 7696 | 7739 | ||
| 7697 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7740 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7698 | const o = self.dg.object; | 7741 | const o = self.dg.object; |
| 7699 | const mod = o.module; | 7742 | const mod = o.pt.zcu; |
| 7700 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7743 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7701 | const lhs = try self.resolveInst(bin_op.lhs); | 7744 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7702 | const rhs = try self.resolveInst(bin_op.rhs); | 7745 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7714,7 +7757,7 @@ pub const FuncGen = struct { | ... | @@ -7714,7 +7757,7 @@ pub const FuncGen = struct { |
| 7714 | unsigned_intrinsic: Builder.Intrinsic, | 7757 | unsigned_intrinsic: Builder.Intrinsic, |
| 7715 | ) !Builder.Value { | 7758 | ) !Builder.Value { |
| 7716 | const o = fg.dg.object; | 7759 | const o = fg.dg.object; |
| 7717 | const mod = o.module; | 7760 | const mod = o.pt.zcu; |
| 7718 | 7761 | ||
| 7719 | const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7762 | const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7720 | const lhs = try fg.resolveInst(bin_op.lhs); | 7763 | const lhs = try fg.resolveInst(bin_op.lhs); |
| ... | @@ -7762,7 +7805,7 @@ pub const FuncGen = struct { | ... | @@ -7762,7 +7805,7 @@ pub const FuncGen = struct { |
| 7762 | 7805 | ||
| 7763 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7806 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7764 | const o = self.dg.object; | 7807 | const o = self.dg.object; |
| 7765 | const mod = o.module; | 7808 | const mod = o.pt.zcu; |
| 7766 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7809 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7767 | const lhs = try self.resolveInst(bin_op.lhs); | 7810 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7768 | const rhs = try self.resolveInst(bin_op.rhs); | 7811 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7782,7 +7825,7 @@ pub const FuncGen = struct { | ... | @@ -7782,7 +7825,7 @@ pub const FuncGen = struct { |
| 7782 | 7825 | ||
| 7783 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7826 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7784 | const o = self.dg.object; | 7827 | const o = self.dg.object; |
| 7785 | const mod = o.module; | 7828 | const mod = o.pt.zcu; |
| 7786 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7829 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7787 | const lhs = try self.resolveInst(bin_op.lhs); | 7830 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7788 | const rhs = try self.resolveInst(bin_op.rhs); | 7831 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7803,7 +7846,7 @@ pub const FuncGen = struct { | ... | @@ -7803,7 +7846,7 @@ pub const FuncGen = struct { |
| 7803 | 7846 | ||
| 7804 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7847 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7805 | const o = self.dg.object; | 7848 | const o = self.dg.object; |
| 7806 | const mod = o.module; | 7849 | const mod = o.pt.zcu; |
| 7807 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7850 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7808 | const lhs = try self.resolveInst(bin_op.lhs); | 7851 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7809 | const rhs = try self.resolveInst(bin_op.rhs); | 7852 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7823,7 +7866,7 @@ pub const FuncGen = struct { | ... | @@ -7823,7 +7866,7 @@ pub const FuncGen = struct { |
| 7823 | 7866 | ||
| 7824 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7867 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7825 | const o = self.dg.object; | 7868 | const o = self.dg.object; |
| 7826 | const mod = o.module; | 7869 | const mod = o.pt.zcu; |
| 7827 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7870 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7828 | const lhs = try self.resolveInst(bin_op.lhs); | 7871 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7829 | const rhs = try self.resolveInst(bin_op.rhs); | 7872 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7844,7 +7887,7 @@ pub const FuncGen = struct { | ... | @@ -7844,7 +7887,7 @@ pub const FuncGen = struct { |
| 7844 | 7887 | ||
| 7845 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 7888 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7846 | const o = self.dg.object; | 7889 | const o = self.dg.object; |
| 7847 | const mod = o.module; | 7890 | const mod = o.pt.zcu; |
| 7848 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7891 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7849 | const lhs = try self.resolveInst(bin_op.lhs); | 7892 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7850 | const rhs = try self.resolveInst(bin_op.rhs); | 7893 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7873,7 +7916,7 @@ pub const FuncGen = struct { | ... | @@ -7873,7 +7916,7 @@ pub const FuncGen = struct { |
| 7873 | 7916 | ||
| 7874 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7917 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7875 | const o = self.dg.object; | 7918 | const o = self.dg.object; |
| 7876 | const mod = o.module; | 7919 | const mod = o.pt.zcu; |
| 7877 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7920 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7878 | const lhs = try self.resolveInst(bin_op.lhs); | 7921 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7879 | const rhs = try self.resolveInst(bin_op.rhs); | 7922 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7889,7 +7932,7 @@ pub const FuncGen = struct { | ... | @@ -7889,7 +7932,7 @@ pub const FuncGen = struct { |
| 7889 | 7932 | ||
| 7890 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7933 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7891 | const o = self.dg.object; | 7934 | const o = self.dg.object; |
| 7892 | const mod = o.module; | 7935 | const mod = o.pt.zcu; |
| 7893 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7936 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7894 | const lhs = try self.resolveInst(bin_op.lhs); | 7937 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7895 | const rhs = try self.resolveInst(bin_op.rhs); | 7938 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7921,7 +7964,7 @@ pub const FuncGen = struct { | ... | @@ -7921,7 +7964,7 @@ pub const FuncGen = struct { |
| 7921 | 7964 | ||
| 7922 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7965 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7923 | const o = self.dg.object; | 7966 | const o = self.dg.object; |
| 7924 | const mod = o.module; | 7967 | const mod = o.pt.zcu; |
| 7925 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7968 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7926 | const lhs = try self.resolveInst(bin_op.lhs); | 7969 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7927 | const rhs = try self.resolveInst(bin_op.rhs); | 7970 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7939,7 +7982,7 @@ pub const FuncGen = struct { | ... | @@ -7939,7 +7982,7 @@ pub const FuncGen = struct { |
| 7939 | 7982 | ||
| 7940 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 7983 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7941 | const o = self.dg.object; | 7984 | const o = self.dg.object; |
| 7942 | const mod = o.module; | 7985 | const mod = o.pt.zcu; |
| 7943 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 7986 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7944 | const lhs = try self.resolveInst(bin_op.lhs); | 7987 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7945 | const rhs = try self.resolveInst(bin_op.rhs); | 7988 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7956,7 +7999,7 @@ pub const FuncGen = struct { | ... | @@ -7956,7 +7999,7 @@ pub const FuncGen = struct { |
| 7956 | 7999 | ||
| 7957 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 8000 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7958 | const o = self.dg.object; | 8001 | const o = self.dg.object; |
| 7959 | const mod = o.module; | 8002 | const mod = o.pt.zcu; |
| 7960 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 8003 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7961 | const lhs = try self.resolveInst(bin_op.lhs); | 8004 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7962 | const rhs = try self.resolveInst(bin_op.rhs); | 8005 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -7992,7 +8035,7 @@ pub const FuncGen = struct { | ... | @@ -7992,7 +8035,7 @@ pub const FuncGen = struct { |
| 7992 | 8035 | ||
| 7993 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8036 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7994 | const o = self.dg.object; | 8037 | const o = self.dg.object; |
| 7995 | const mod = o.module; | 8038 | const mod = o.pt.zcu; |
| 7996 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8039 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7997 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 8040 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 7998 | const ptr = try self.resolveInst(bin_op.lhs); | 8041 | const ptr = try self.resolveInst(bin_op.lhs); |
| ... | @@ -8014,7 +8057,7 @@ pub const FuncGen = struct { | ... | @@ -8014,7 +8057,7 @@ pub const FuncGen = struct { |
| 8014 | 8057 | ||
| 8015 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8058 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8016 | const o = self.dg.object; | 8059 | const o = self.dg.object; |
| 8017 | const mod = o.module; | 8060 | const mod = o.pt.zcu; |
| 8018 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8061 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8019 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 8062 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8020 | const ptr = try self.resolveInst(bin_op.lhs); | 8063 | const ptr = try self.resolveInst(bin_op.lhs); |
| ... | @@ -8042,7 +8085,8 @@ pub const FuncGen = struct { | ... | @@ -8042,7 +8085,8 @@ pub const FuncGen = struct { |
| 8042 | unsigned_intrinsic: Builder.Intrinsic, | 8085 | unsigned_intrinsic: Builder.Intrinsic, |
| 8043 | ) !Builder.Value { | 8086 | ) !Builder.Value { |
| 8044 | const o = self.dg.object; | 8087 | const o = self.dg.object; |
| 8045 | const mod = o.module; | 8088 | const pt = o.pt; |
| 8089 | const mod = pt.zcu; | ||
| 8046 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8090 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8047 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 8091 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8048 | 8092 | ||
| ... | @@ -8065,8 +8109,8 @@ pub const FuncGen = struct { | ... | @@ -8065,8 +8109,8 @@ pub const FuncGen = struct { |
| 8065 | const result_index = o.llvmFieldIndex(inst_ty, 0).?; | 8109 | const result_index = o.llvmFieldIndex(inst_ty, 0).?; |
| 8066 | const overflow_index = o.llvmFieldIndex(inst_ty, 1).?; | 8110 | const overflow_index = o.llvmFieldIndex(inst_ty, 1).?; |
| 8067 | 8111 | ||
| 8068 | if (isByRef(inst_ty, mod)) { | 8112 | if (isByRef(inst_ty, pt)) { |
| 8069 | const result_alignment = inst_ty.abiAlignment(mod).toLlvm(); | 8113 | const result_alignment = inst_ty.abiAlignment(pt).toLlvm(); |
| 8070 | const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment); | 8114 | const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment); |
| 8071 | { | 8115 | { |
| 8072 | const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, ""); | 8116 | const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, ""); |
| ... | @@ -8135,7 +8179,7 @@ pub const FuncGen = struct { | ... | @@ -8135,7 +8179,7 @@ pub const FuncGen = struct { |
| 8135 | return o.builder.addFunction( | 8179 | return o.builder.addFunction( |
| 8136 | try o.builder.fnType(return_type, param_types, .normal), | 8180 | try o.builder.fnType(return_type, param_types, .normal), |
| 8137 | fn_name, | 8181 | fn_name, |
| 8138 | toLlvmAddressSpace(.generic, o.module.getTarget()), | 8182 | toLlvmAddressSpace(.generic, o.pt.zcu.getTarget()), |
| 8139 | ); | 8183 | ); |
| 8140 | } | 8184 | } |
| 8141 | 8185 | ||
| ... | @@ -8149,8 +8193,8 @@ pub const FuncGen = struct { | ... | @@ -8149,8 +8193,8 @@ pub const FuncGen = struct { |
| 8149 | params: [2]Builder.Value, | 8193 | params: [2]Builder.Value, |
| 8150 | ) !Builder.Value { | 8194 | ) !Builder.Value { |
| 8151 | const o = self.dg.object; | 8195 | const o = self.dg.object; |
| 8152 | const mod = o.module; | 8196 | const mod = o.pt.zcu; |
| 8153 | const target = o.module.getTarget(); | 8197 | const target = mod.getTarget(); |
| 8154 | const scalar_ty = ty.scalarType(mod); | 8198 | const scalar_ty = ty.scalarType(mod); |
| 8155 | const scalar_llvm_ty = try o.lowerType(scalar_ty); | 8199 | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 8156 | 8200 | ||
| ... | @@ -8255,7 +8299,7 @@ pub const FuncGen = struct { | ... | @@ -8255,7 +8299,7 @@ pub const FuncGen = struct { |
| 8255 | params: [params_len]Builder.Value, | 8299 | params: [params_len]Builder.Value, |
| 8256 | ) !Builder.Value { | 8300 | ) !Builder.Value { |
| 8257 | const o = self.dg.object; | 8301 | const o = self.dg.object; |
| 8258 | const mod = o.module; | 8302 | const mod = o.pt.zcu; |
| 8259 | const target = mod.getTarget(); | 8303 | const target = mod.getTarget(); |
| 8260 | const scalar_ty = ty.scalarType(mod); | 8304 | const scalar_ty = ty.scalarType(mod); |
| 8261 | const llvm_ty = try o.lowerType(ty); | 8305 | const llvm_ty = try o.lowerType(ty); |
| ... | @@ -8396,7 +8440,8 @@ pub const FuncGen = struct { | ... | @@ -8396,7 +8440,8 @@ pub const FuncGen = struct { |
| 8396 | 8440 | ||
| 8397 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8441 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8398 | const o = self.dg.object; | 8442 | const o = self.dg.object; |
| 8399 | const mod = o.module; | 8443 | const pt = o.pt; |
| 8444 | const mod = pt.zcu; | ||
| 8400 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 8445 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8401 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 8446 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8402 | 8447 | ||
| ... | @@ -8422,8 +8467,8 @@ pub const FuncGen = struct { | ... | @@ -8422,8 +8467,8 @@ pub const FuncGen = struct { |
| 8422 | const result_index = o.llvmFieldIndex(dest_ty, 0).?; | 8467 | const result_index = o.llvmFieldIndex(dest_ty, 0).?; |
| 8423 | const overflow_index = o.llvmFieldIndex(dest_ty, 1).?; | 8468 | const overflow_index = o.llvmFieldIndex(dest_ty, 1).?; |
| 8424 | 8469 | ||
| 8425 | if (isByRef(dest_ty, mod)) { | 8470 | if (isByRef(dest_ty, pt)) { |
| 8426 | const result_alignment = dest_ty.abiAlignment(mod).toLlvm(); | 8471 | const result_alignment = dest_ty.abiAlignment(pt).toLlvm(); |
| 8427 | const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment); | 8472 | const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment); |
| 8428 | { | 8473 | { |
| 8429 | const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, ""); | 8474 | const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, ""); |
| ... | @@ -8466,7 +8511,7 @@ pub const FuncGen = struct { | ... | @@ -8466,7 +8511,7 @@ pub const FuncGen = struct { |
| 8466 | 8511 | ||
| 8467 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8512 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8468 | const o = self.dg.object; | 8513 | const o = self.dg.object; |
| 8469 | const mod = o.module; | 8514 | const mod = o.pt.zcu; |
| 8470 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 8515 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8471 | 8516 | ||
| 8472 | const lhs = try self.resolveInst(bin_op.lhs); | 8517 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | @@ -8497,7 +8542,8 @@ pub const FuncGen = struct { | ... | @@ -8497,7 +8542,8 @@ pub const FuncGen = struct { |
| 8497 | 8542 | ||
| 8498 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8543 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8499 | const o = self.dg.object; | 8544 | const o = self.dg.object; |
| 8500 | const mod = o.module; | 8545 | const pt = o.pt; |
| 8546 | const mod = pt.zcu; | ||
| 8501 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 8547 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8502 | 8548 | ||
| 8503 | const lhs = try self.resolveInst(bin_op.lhs); | 8549 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | @@ -8505,7 +8551,7 @@ pub const FuncGen = struct { | ... | @@ -8505,7 +8551,7 @@ pub const FuncGen = struct { |
| 8505 | 8551 | ||
| 8506 | const lhs_ty = self.typeOf(bin_op.lhs); | 8552 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 8507 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | 8553 | const lhs_scalar_ty = lhs_ty.scalarType(mod); |
| 8508 | const lhs_bits = lhs_scalar_ty.bitSize(mod); | 8554 | const lhs_bits = lhs_scalar_ty.bitSize(pt); |
| 8509 | 8555 | ||
| 8510 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); | 8556 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8511 | 8557 | ||
| ... | @@ -8539,7 +8585,7 @@ pub const FuncGen = struct { | ... | @@ -8539,7 +8585,7 @@ pub const FuncGen = struct { |
| 8539 | 8585 | ||
| 8540 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { | 8586 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 8541 | const o = self.dg.object; | 8587 | const o = self.dg.object; |
| 8542 | const mod = o.module; | 8588 | const mod = o.pt.zcu; |
| 8543 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 8589 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8544 | 8590 | ||
| 8545 | const lhs = try self.resolveInst(bin_op.lhs); | 8591 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | @@ -8558,7 +8604,7 @@ pub const FuncGen = struct { | ... | @@ -8558,7 +8604,7 @@ pub const FuncGen = struct { |
| 8558 | 8604 | ||
| 8559 | fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8605 | fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8560 | const o = self.dg.object; | 8606 | const o = self.dg.object; |
| 8561 | const mod = o.module; | 8607 | const mod = o.pt.zcu; |
| 8562 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 8608 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8563 | const operand = try self.resolveInst(ty_op.operand); | 8609 | const operand = try self.resolveInst(ty_op.operand); |
| 8564 | const operand_ty = self.typeOf(ty_op.operand); | 8610 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -8580,7 +8626,7 @@ pub const FuncGen = struct { | ... | @@ -8580,7 +8626,7 @@ pub const FuncGen = struct { |
| 8580 | 8626 | ||
| 8581 | fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8627 | fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8582 | const o = self.dg.object; | 8628 | const o = self.dg.object; |
| 8583 | const mod = o.module; | 8629 | const mod = o.pt.zcu; |
| 8584 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 8630 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8585 | const dest_ty = self.typeOfIndex(inst); | 8631 | const dest_ty = self.typeOfIndex(inst); |
| 8586 | const dest_llvm_ty = try o.lowerType(dest_ty); | 8632 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| ... | @@ -8604,7 +8650,7 @@ pub const FuncGen = struct { | ... | @@ -8604,7 +8650,7 @@ pub const FuncGen = struct { |
| 8604 | 8650 | ||
| 8605 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8651 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8606 | const o = self.dg.object; | 8652 | const o = self.dg.object; |
| 8607 | const mod = o.module; | 8653 | const mod = o.pt.zcu; |
| 8608 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 8654 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8609 | const operand = try self.resolveInst(ty_op.operand); | 8655 | const operand = try self.resolveInst(ty_op.operand); |
| 8610 | const operand_ty = self.typeOf(ty_op.operand); | 8656 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -8638,7 +8684,7 @@ pub const FuncGen = struct { | ... | @@ -8638,7 +8684,7 @@ pub const FuncGen = struct { |
| 8638 | 8684 | ||
| 8639 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8685 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8640 | const o = self.dg.object; | 8686 | const o = self.dg.object; |
| 8641 | const mod = o.module; | 8687 | const mod = o.pt.zcu; |
| 8642 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 8688 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8643 | const operand = try self.resolveInst(ty_op.operand); | 8689 | const operand = try self.resolveInst(ty_op.operand); |
| 8644 | const operand_ty = self.typeOf(ty_op.operand); | 8690 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -8696,9 +8742,10 @@ pub const FuncGen = struct { | ... | @@ -8696,9 +8742,10 @@ pub const FuncGen = struct { |
| 8696 | 8742 | ||
| 8697 | fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value { | 8743 | fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value { |
| 8698 | const o = self.dg.object; | 8744 | const o = self.dg.object; |
| 8699 | const mod = o.module; | 8745 | const pt = o.pt; |
| 8700 | const operand_is_ref = isByRef(operand_ty, mod); | 8746 | const mod = pt.zcu; |
| 8701 | const result_is_ref = isByRef(inst_ty, mod); | 8747 | const operand_is_ref = isByRef(operand_ty, pt); |
| 8748 | const result_is_ref = isByRef(inst_ty, pt); | ||
| 8702 | const llvm_dest_ty = try o.lowerType(inst_ty); | 8749 | const llvm_dest_ty = try o.lowerType(inst_ty); |
| 8703 | 8750 | ||
| 8704 | if (operand_is_ref and result_is_ref) { | 8751 | if (operand_is_ref and result_is_ref) { |
| ... | @@ -8721,9 +8768,9 @@ pub const FuncGen = struct { | ... | @@ -8721,9 +8768,9 @@ pub const FuncGen = struct { |
| 8721 | if (!result_is_ref) { | 8768 | if (!result_is_ref) { |
| 8722 | return self.dg.todo("implement bitcast vector to non-ref array", .{}); | 8769 | return self.dg.todo("implement bitcast vector to non-ref array", .{}); |
| 8723 | } | 8770 | } |
| 8724 | const alignment = inst_ty.abiAlignment(mod).toLlvm(); | 8771 | const alignment = inst_ty.abiAlignment(pt).toLlvm(); |
| 8725 | const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); | 8772 | const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8726 | const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8; | 8773 | const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8; |
| 8727 | if (bitcast_ok) { | 8774 | if (bitcast_ok) { |
| 8728 | _ = try self.wip.store(.normal, operand, array_ptr, alignment); | 8775 | _ = try self.wip.store(.normal, operand, array_ptr, alignment); |
| 8729 | } else { | 8776 | } else { |
| ... | @@ -8748,11 +8795,11 @@ pub const FuncGen = struct { | ... | @@ -8748,11 +8795,11 @@ pub const FuncGen = struct { |
| 8748 | const llvm_vector_ty = try o.lowerType(inst_ty); | 8795 | const llvm_vector_ty = try o.lowerType(inst_ty); |
| 8749 | if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{}); | 8796 | if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{}); |
| 8750 | 8797 | ||
| 8751 | const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8; | 8798 | const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8; |
| 8752 | if (bitcast_ok) { | 8799 | if (bitcast_ok) { |
| 8753 | // The array is aligned to the element's alignment, while the vector might have a completely | 8800 | // The array is aligned to the element's alignment, while the vector might have a completely |
| 8754 | // different alignment. This means we need to enforce the alignment of this load. | 8801 | // different alignment. This means we need to enforce the alignment of this load. |
| 8755 | const alignment = elem_ty.abiAlignment(mod).toLlvm(); | 8802 | const alignment = elem_ty.abiAlignment(pt).toLlvm(); |
| 8756 | return self.wip.load(.normal, llvm_vector_ty, operand, alignment, ""); | 8803 | return self.wip.load(.normal, llvm_vector_ty, operand, alignment, ""); |
| 8757 | } else { | 8804 | } else { |
| 8758 | // If the ABI size of the element type is not evenly divisible by size in bits; | 8805 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| ... | @@ -8777,24 +8824,25 @@ pub const FuncGen = struct { | ... | @@ -8777,24 +8824,25 @@ pub const FuncGen = struct { |
| 8777 | } | 8824 | } |
| 8778 | 8825 | ||
| 8779 | if (operand_is_ref) { | 8826 | if (operand_is_ref) { |
| 8780 | const alignment = operand_ty.abiAlignment(mod).toLlvm(); | 8827 | const alignment = operand_ty.abiAlignment(pt).toLlvm(); |
| 8781 | return self.wip.load(.normal, llvm_dest_ty, operand, alignment, ""); | 8828 | return self.wip.load(.normal, llvm_dest_ty, operand, alignment, ""); |
| 8782 | } | 8829 | } |
| 8783 | 8830 | ||
| 8784 | if (result_is_ref) { | 8831 | if (result_is_ref) { |
| 8785 | const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm(); | 8832 | const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm(); |
| 8786 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); | 8833 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8787 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); | 8834 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); |
| 8788 | return result_ptr; | 8835 | return result_ptr; |
| 8789 | } | 8836 | } |
| 8790 | 8837 | ||
| 8791 | if (llvm_dest_ty.isStruct(&o.builder) or | 8838 | if (llvm_dest_ty.isStruct(&o.builder) or |
| 8792 | ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and operand_ty.bitSize(mod) != inst_ty.bitSize(mod))) | 8839 | ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and |
| 8840 | operand_ty.bitSize(pt) != inst_ty.bitSize(pt))) | ||
| 8793 | { | 8841 | { |
| 8794 | // Both our operand and our result are values, not pointers, | 8842 | // Both our operand and our result are values, not pointers, |
| 8795 | // but LLVM won't let us bitcast struct values or vectors with padding bits. | 8843 | // but LLVM won't let us bitcast struct values or vectors with padding bits. |
| 8796 | // Therefore, we store operand to alloca, then load for result. | 8844 | // Therefore, we store operand to alloca, then load for result. |
| 8797 | const alignment = operand_ty.abiAlignment(mod).max(inst_ty.abiAlignment(mod)).toLlvm(); | 8845 | const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm(); |
| 8798 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); | 8846 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8799 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); | 8847 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); |
| 8800 | return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, ""); | 8848 | return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, ""); |
| ... | @@ -8811,7 +8859,8 @@ pub const FuncGen = struct { | ... | @@ -8811,7 +8859,8 @@ pub const FuncGen = struct { |
| 8811 | 8859 | ||
| 8812 | fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8860 | fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8813 | const o = self.dg.object; | 8861 | const o = self.dg.object; |
| 8814 | const mod = o.module; | 8862 | const pt = o.pt; |
| 8863 | const mod = pt.zcu; | ||
| 8815 | const arg_val = self.args[self.arg_index]; | 8864 | const arg_val = self.args[self.arg_index]; |
| 8816 | self.arg_index += 1; | 8865 | self.arg_index += 1; |
| 8817 | 8866 | ||
| ... | @@ -8847,7 +8896,7 @@ pub const FuncGen = struct { | ... | @@ -8847,7 +8896,7 @@ pub const FuncGen = struct { |
| 8847 | }; | 8896 | }; |
| 8848 | 8897 | ||
| 8849 | const owner_mod = self.dg.ownerModule(); | 8898 | const owner_mod = self.dg.ownerModule(); |
| 8850 | if (isByRef(inst_ty, mod)) { | 8899 | if (isByRef(inst_ty, pt)) { |
| 8851 | _ = try self.wip.callIntrinsic( | 8900 | _ = try self.wip.callIntrinsic( |
| 8852 | .normal, | 8901 | .normal, |
| 8853 | .none, | 8902 | .none, |
| ... | @@ -8861,7 +8910,7 @@ pub const FuncGen = struct { | ... | @@ -8861,7 +8910,7 @@ pub const FuncGen = struct { |
| 8861 | "", | 8910 | "", |
| 8862 | ); | 8911 | ); |
| 8863 | } else if (owner_mod.optimize_mode == .Debug) { | 8912 | } else if (owner_mod.optimize_mode == .Debug) { |
| 8864 | const alignment = inst_ty.abiAlignment(mod).toLlvm(); | 8913 | const alignment = inst_ty.abiAlignment(pt).toLlvm(); |
| 8865 | const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment); | 8914 | const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment); |
| 8866 | _ = try self.wip.store(.normal, arg_val, alloca, alignment); | 8915 | _ = try self.wip.store(.normal, arg_val, alloca, alignment); |
| 8867 | _ = try self.wip.callIntrinsic( | 8916 | _ = try self.wip.callIntrinsic( |
| ... | @@ -8897,27 +8946,29 @@ pub const FuncGen = struct { | ... | @@ -8897,27 +8946,29 @@ pub const FuncGen = struct { |
| 8897 | 8946 | ||
| 8898 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8947 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8899 | const o = self.dg.object; | 8948 | const o = self.dg.object; |
| 8900 | const mod = o.module; | 8949 | const pt = o.pt; |
| 8950 | const mod = pt.zcu; | ||
| 8901 | const ptr_ty = self.typeOfIndex(inst); | 8951 | const ptr_ty = self.typeOfIndex(inst); |
| 8902 | const pointee_type = ptr_ty.childType(mod); | 8952 | const pointee_type = ptr_ty.childType(mod); |
| 8903 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) | 8953 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(pt)) |
| 8904 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); | 8954 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); |
| 8905 | 8955 | ||
| 8906 | //const pointee_llvm_ty = try o.lowerType(pointee_type); | 8956 | //const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 8907 | const alignment = ptr_ty.ptrAlignment(mod).toLlvm(); | 8957 | const alignment = ptr_ty.ptrAlignment(pt).toLlvm(); |
| 8908 | return self.buildAllocaWorkaround(pointee_type, alignment); | 8958 | return self.buildAllocaWorkaround(pointee_type, alignment); |
| 8909 | } | 8959 | } |
| 8910 | 8960 | ||
| 8911 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 8961 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8912 | const o = self.dg.object; | 8962 | const o = self.dg.object; |
| 8913 | const mod = o.module; | 8963 | const pt = o.pt; |
| 8964 | const mod = pt.zcu; | ||
| 8914 | const ptr_ty = self.typeOfIndex(inst); | 8965 | const ptr_ty = self.typeOfIndex(inst); |
| 8915 | const ret_ty = ptr_ty.childType(mod); | 8966 | const ret_ty = ptr_ty.childType(mod); |
| 8916 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) | 8967 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) |
| 8917 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); | 8968 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); |
| 8918 | if (self.ret_ptr != .none) return self.ret_ptr; | 8969 | if (self.ret_ptr != .none) return self.ret_ptr; |
| 8919 | //const ret_llvm_ty = try o.lowerType(ret_ty); | 8970 | //const ret_llvm_ty = try o.lowerType(ret_ty); |
| 8920 | const alignment = ptr_ty.ptrAlignment(mod).toLlvm(); | 8971 | const alignment = ptr_ty.ptrAlignment(pt).toLlvm(); |
| 8921 | return self.buildAllocaWorkaround(ret_ty, alignment); | 8972 | return self.buildAllocaWorkaround(ret_ty, alignment); |
| 8922 | } | 8973 | } |
| 8923 | 8974 | ||
| ... | @@ -8928,7 +8979,7 @@ pub const FuncGen = struct { | ... | @@ -8928,7 +8979,7 @@ pub const FuncGen = struct { |
| 8928 | llvm_ty: Builder.Type, | 8979 | llvm_ty: Builder.Type, |
| 8929 | alignment: Builder.Alignment, | 8980 | alignment: Builder.Alignment, |
| 8930 | ) Allocator.Error!Builder.Value { | 8981 | ) Allocator.Error!Builder.Value { |
| 8931 | const target = self.dg.object.module.getTarget(); | 8982 | const target = self.dg.object.pt.zcu.getTarget(); |
| 8932 | return buildAllocaInner(&self.wip, llvm_ty, alignment, target); | 8983 | return buildAllocaInner(&self.wip, llvm_ty, alignment, target); |
| 8933 | } | 8984 | } |
| 8934 | 8985 | ||
| ... | @@ -8939,18 +8990,19 @@ pub const FuncGen = struct { | ... | @@ -8939,18 +8990,19 @@ pub const FuncGen = struct { |
| 8939 | alignment: Builder.Alignment, | 8990 | alignment: Builder.Alignment, |
| 8940 | ) Allocator.Error!Builder.Value { | 8991 | ) Allocator.Error!Builder.Value { |
| 8941 | const o = self.dg.object; | 8992 | const o = self.dg.object; |
| 8942 | return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.module), .i8), alignment); | 8993 | return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment); |
| 8943 | } | 8994 | } |
| 8944 | 8995 | ||
| 8945 | fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | 8996 | fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 8946 | const o = self.dg.object; | 8997 | const o = self.dg.object; |
| 8947 | const mod = o.module; | 8998 | const pt = o.pt; |
| 8999 | const mod = pt.zcu; | ||
| 8948 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9000 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8949 | const dest_ptr = try self.resolveInst(bin_op.lhs); | 9001 | const dest_ptr = try self.resolveInst(bin_op.lhs); |
| 8950 | const ptr_ty = self.typeOf(bin_op.lhs); | 9002 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8951 | const operand_ty = ptr_ty.childType(mod); | 9003 | const operand_ty = ptr_ty.childType(mod); |
| 8952 | 9004 | ||
| 8953 | const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep(mod) else false; | 9005 | const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false; |
| 8954 | if (val_is_undef) { | 9006 | if (val_is_undef) { |
| 8955 | const ptr_info = ptr_ty.ptrInfo(mod); | 9007 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 8956 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); | 9008 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); |
| ... | @@ -8964,10 +9016,10 @@ pub const FuncGen = struct { | ... | @@ -8964,10 +9016,10 @@ pub const FuncGen = struct { |
| 8964 | // Even if safety is disabled, we still emit a memset to undefined since it conveys | 9016 | // Even if safety is disabled, we still emit a memset to undefined since it conveys |
| 8965 | // extra information to LLVM. However, safety makes the difference between using | 9017 | // extra information to LLVM. However, safety makes the difference between using |
| 8966 | // 0xaa or actual undefined for the fill byte. | 9018 | // 0xaa or actual undefined for the fill byte. |
| 8967 | const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(mod)); | 9019 | const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(pt)); |
| 8968 | _ = try self.wip.callMemSet( | 9020 | _ = try self.wip.callMemSet( |
| 8969 | dest_ptr, | 9021 | dest_ptr, |
| 8970 | ptr_ty.ptrAlignment(mod).toLlvm(), | 9022 | ptr_ty.ptrAlignment(pt).toLlvm(), |
| 8971 | if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8), | 9023 | if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8), |
| 8972 | len, | 9024 | len, |
| 8973 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, | 9025 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, |
| ... | @@ -8992,7 +9044,7 @@ pub const FuncGen = struct { | ... | @@ -8992,7 +9044,7 @@ pub const FuncGen = struct { |
| 8992 | /// The first instruction of `body_tail` is the one whose copy we want to elide. | 9044 | /// The first instruction of `body_tail` is the one whose copy we want to elide. |
| 8993 | fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool { | 9045 | fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool { |
| 8994 | const o = fg.dg.object; | 9046 | const o = fg.dg.object; |
| 8995 | const mod = o.module; | 9047 | const mod = o.pt.zcu; |
| 8996 | const ip = &mod.intern_pool; | 9048 | const ip = &mod.intern_pool; |
| 8997 | for (body_tail[1..]) |body_inst| { | 9049 | for (body_tail[1..]) |body_inst| { |
| 8998 | switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) { | 9050 | switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) { |
| ... | @@ -9008,7 +9060,8 @@ pub const FuncGen = struct { | ... | @@ -9008,7 +9060,8 @@ pub const FuncGen = struct { |
| 9008 | 9060 | ||
| 9009 | fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 9061 | fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 9010 | const o = fg.dg.object; | 9062 | const o = fg.dg.object; |
| 9011 | const mod = o.module; | 9063 | const pt = o.pt; |
| 9064 | const mod = pt.zcu; | ||
| 9012 | const inst = body_tail[0]; | 9065 | const inst = body_tail[0]; |
| 9013 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 9066 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9014 | const ptr_ty = fg.typeOf(ty_op.operand); | 9067 | const ptr_ty = fg.typeOf(ty_op.operand); |
| ... | @@ -9016,7 +9069,7 @@ pub const FuncGen = struct { | ... | @@ -9016,7 +9069,7 @@ pub const FuncGen = struct { |
| 9016 | const ptr = try fg.resolveInst(ty_op.operand); | 9069 | const ptr = try fg.resolveInst(ty_op.operand); |
| 9017 | 9070 | ||
| 9018 | elide: { | 9071 | elide: { |
| 9019 | if (!isByRef(Type.fromInterned(ptr_info.child), mod)) break :elide; | 9072 | if (!isByRef(Type.fromInterned(ptr_info.child), pt)) break :elide; |
| 9020 | if (!canElideLoad(fg, body_tail)) break :elide; | 9073 | if (!canElideLoad(fg, body_tail)) break :elide; |
| 9021 | return ptr; | 9074 | return ptr; |
| 9022 | } | 9075 | } |
| ... | @@ -9040,7 +9093,7 @@ pub const FuncGen = struct { | ... | @@ -9040,7 +9093,7 @@ pub const FuncGen = struct { |
| 9040 | _ = inst; | 9093 | _ = inst; |
| 9041 | const o = self.dg.object; | 9094 | const o = self.dg.object; |
| 9042 | const llvm_usize = try o.lowerType(Type.usize); | 9095 | const llvm_usize = try o.lowerType(Type.usize); |
| 9043 | if (!target_util.supportsReturnAddress(o.module.getTarget())) { | 9096 | if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) { |
| 9044 | // https://github.com/ziglang/zig/issues/11946 | 9097 | // https://github.com/ziglang/zig/issues/11946 |
| 9045 | return o.builder.intValue(llvm_usize, 0); | 9098 | return o.builder.intValue(llvm_usize, 0); |
| 9046 | } | 9099 | } |
| ... | @@ -9068,7 +9121,8 @@ pub const FuncGen = struct { | ... | @@ -9068,7 +9121,8 @@ pub const FuncGen = struct { |
| 9068 | kind: Builder.Function.Instruction.CmpXchg.Kind, | 9121 | kind: Builder.Function.Instruction.CmpXchg.Kind, |
| 9069 | ) !Builder.Value { | 9122 | ) !Builder.Value { |
| 9070 | const o = self.dg.object; | 9123 | const o = self.dg.object; |
| 9071 | const mod = o.module; | 9124 | const pt = o.pt; |
| 9125 | const mod = pt.zcu; | ||
| 9072 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 9126 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 9073 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 9127 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 9074 | const ptr = try self.resolveInst(extra.ptr); | 9128 | const ptr = try self.resolveInst(extra.ptr); |
| ... | @@ -9095,7 +9149,7 @@ pub const FuncGen = struct { | ... | @@ -9095,7 +9149,7 @@ pub const FuncGen = struct { |
| 9095 | self.sync_scope, | 9149 | self.sync_scope, |
| 9096 | toLlvmAtomicOrdering(extra.successOrder()), | 9150 | toLlvmAtomicOrdering(extra.successOrder()), |
| 9097 | toLlvmAtomicOrdering(extra.failureOrder()), | 9151 | toLlvmAtomicOrdering(extra.failureOrder()), |
| 9098 | ptr_ty.ptrAlignment(mod).toLlvm(), | 9152 | ptr_ty.ptrAlignment(pt).toLlvm(), |
| 9099 | "", | 9153 | "", |
| 9100 | ); | 9154 | ); |
| 9101 | 9155 | ||
| ... | @@ -9118,7 +9172,8 @@ pub const FuncGen = struct { | ... | @@ -9118,7 +9172,8 @@ pub const FuncGen = struct { |
| 9118 | 9172 | ||
| 9119 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9173 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9120 | const o = self.dg.object; | 9174 | const o = self.dg.object; |
| 9121 | const mod = o.module; | 9175 | const pt = o.pt; |
| 9176 | const mod = pt.zcu; | ||
| 9122 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 9177 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 9123 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 9178 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 9124 | const ptr = try self.resolveInst(pl_op.operand); | 9179 | const ptr = try self.resolveInst(pl_op.operand); |
| ... | @@ -9134,7 +9189,7 @@ pub const FuncGen = struct { | ... | @@ -9134,7 +9189,7 @@ pub const FuncGen = struct { |
| 9134 | 9189 | ||
| 9135 | const access_kind: Builder.MemoryAccessKind = | 9190 | const access_kind: Builder.MemoryAccessKind = |
| 9136 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | 9191 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; |
| 9137 | const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm(); | 9192 | const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm(); |
| 9138 | 9193 | ||
| 9139 | if (llvm_abi_ty != .none) { | 9194 | if (llvm_abi_ty != .none) { |
| 9140 | // operand needs widening and truncating or bitcasting. | 9195 | // operand needs widening and truncating or bitcasting. |
| ... | @@ -9181,19 +9236,20 @@ pub const FuncGen = struct { | ... | @@ -9181,19 +9236,20 @@ pub const FuncGen = struct { |
| 9181 | 9236 | ||
| 9182 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9237 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9183 | const o = self.dg.object; | 9238 | const o = self.dg.object; |
| 9184 | const mod = o.module; | 9239 | const pt = o.pt; |
| 9240 | const mod = pt.zcu; | ||
| 9185 | const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; | 9241 | const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 9186 | const ptr = try self.resolveInst(atomic_load.ptr); | 9242 | const ptr = try self.resolveInst(atomic_load.ptr); |
| 9187 | const ptr_ty = self.typeOf(atomic_load.ptr); | 9243 | const ptr_ty = self.typeOf(atomic_load.ptr); |
| 9188 | const info = ptr_ty.ptrInfo(mod); | 9244 | const info = ptr_ty.ptrInfo(mod); |
| 9189 | const elem_ty = Type.fromInterned(info.child); | 9245 | const elem_ty = Type.fromInterned(info.child); |
| 9190 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 9246 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 9191 | const ordering = toLlvmAtomicOrdering(atomic_load.order); | 9247 | const ordering = toLlvmAtomicOrdering(atomic_load.order); |
| 9192 | const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false); | 9248 | const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false); |
| 9193 | const ptr_alignment = (if (info.flags.alignment != .none) | 9249 | const ptr_alignment = (if (info.flags.alignment != .none) |
| 9194 | @as(InternPool.Alignment, info.flags.alignment) | 9250 | @as(InternPool.Alignment, info.flags.alignment) |
| 9195 | else | 9251 | else |
| 9196 | Type.fromInterned(info.child).abiAlignment(mod)).toLlvm(); | 9252 | Type.fromInterned(info.child).abiAlignment(pt)).toLlvm(); |
| 9197 | const access_kind: Builder.MemoryAccessKind = | 9253 | const access_kind: Builder.MemoryAccessKind = |
| 9198 | if (info.flags.is_volatile) .@"volatile" else .normal; | 9254 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 9199 | const elem_llvm_ty = try o.lowerType(elem_ty); | 9255 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| ... | @@ -9228,11 +9284,12 @@ pub const FuncGen = struct { | ... | @@ -9228,11 +9284,12 @@ pub const FuncGen = struct { |
| 9228 | ordering: Builder.AtomicOrdering, | 9284 | ordering: Builder.AtomicOrdering, |
| 9229 | ) !Builder.Value { | 9285 | ) !Builder.Value { |
| 9230 | const o = self.dg.object; | 9286 | const o = self.dg.object; |
| 9231 | const mod = o.module; | 9287 | const pt = o.pt; |
| 9288 | const mod = pt.zcu; | ||
| 9232 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9289 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9233 | const ptr_ty = self.typeOf(bin_op.lhs); | 9290 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 9234 | const operand_ty = ptr_ty.childType(mod); | 9291 | const operand_ty = ptr_ty.childType(mod); |
| 9235 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .none; | 9292 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 9236 | const ptr = try self.resolveInst(bin_op.lhs); | 9293 | const ptr = try self.resolveInst(bin_op.lhs); |
| 9237 | var element = try self.resolveInst(bin_op.rhs); | 9294 | var element = try self.resolveInst(bin_op.rhs); |
| 9238 | const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false); | 9295 | const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false); |
| ... | @@ -9252,12 +9309,13 @@ pub const FuncGen = struct { | ... | @@ -9252,12 +9309,13 @@ pub const FuncGen = struct { |
| 9252 | 9309 | ||
| 9253 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | 9310 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 9254 | const o = self.dg.object; | 9311 | const o = self.dg.object; |
| 9255 | const mod = o.module; | 9312 | const pt = o.pt; |
| 9313 | const mod = pt.zcu; | ||
| 9256 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9314 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9257 | const dest_slice = try self.resolveInst(bin_op.lhs); | 9315 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 9258 | const ptr_ty = self.typeOf(bin_op.lhs); | 9316 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 9259 | const elem_ty = self.typeOf(bin_op.rhs); | 9317 | const elem_ty = self.typeOf(bin_op.rhs); |
| 9260 | const dest_ptr_align = ptr_ty.ptrAlignment(mod).toLlvm(); | 9318 | const dest_ptr_align = ptr_ty.ptrAlignment(pt).toLlvm(); |
| 9261 | const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty); | 9319 | const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty); |
| 9262 | const access_kind: Builder.MemoryAccessKind = | 9320 | const access_kind: Builder.MemoryAccessKind = |
| 9263 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | 9321 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; |
| ... | @@ -9270,7 +9328,7 @@ pub const FuncGen = struct { | ... | @@ -9270,7 +9328,7 @@ pub const FuncGen = struct { |
| 9270 | ptr_ty.isSlice(mod) and | 9328 | ptr_ty.isSlice(mod) and |
| 9271 | std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory); | 9329 | std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory); |
| 9272 | 9330 | ||
| 9273 | if (try self.air.value(bin_op.rhs, mod)) |elem_val| { | 9331 | if (try self.air.value(bin_op.rhs, pt)) |elem_val| { |
| 9274 | if (elem_val.isUndefDeep(mod)) { | 9332 | if (elem_val.isUndefDeep(mod)) { |
| 9275 | // Even if safety is disabled, we still emit a memset to undefined since it conveys | 9333 | // Even if safety is disabled, we still emit a memset to undefined since it conveys |
| 9276 | // extra information to LLVM. However, safety makes the difference between using | 9334 | // extra information to LLVM. However, safety makes the difference between using |
| ... | @@ -9296,7 +9354,7 @@ pub const FuncGen = struct { | ... | @@ -9296,7 +9354,7 @@ pub const FuncGen = struct { |
| 9296 | // repeating byte pattern, for example, `@as(u64, 0)` has a | 9354 | // repeating byte pattern, for example, `@as(u64, 0)` has a |
| 9297 | // repeating byte pattern of 0 bytes. In such case, the memset | 9355 | // repeating byte pattern of 0 bytes. In such case, the memset |
| 9298 | // intrinsic can be used. | 9356 | // intrinsic can be used. |
| 9299 | if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| { | 9357 | if (try elem_val.hasRepeatedByteRepr(elem_ty, pt)) |byte_val| { |
| 9300 | const fill_byte = try o.builder.intValue(.i8, byte_val); | 9358 | const fill_byte = try o.builder.intValue(.i8, byte_val); |
| 9301 | const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty); | 9359 | const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty); |
| 9302 | if (intrinsic_len0_traps) { | 9360 | if (intrinsic_len0_traps) { |
| ... | @@ -9309,7 +9367,7 @@ pub const FuncGen = struct { | ... | @@ -9309,7 +9367,7 @@ pub const FuncGen = struct { |
| 9309 | } | 9367 | } |
| 9310 | 9368 | ||
| 9311 | const value = try self.resolveInst(bin_op.rhs); | 9369 | const value = try self.resolveInst(bin_op.rhs); |
| 9312 | const elem_abi_size = elem_ty.abiSize(mod); | 9370 | const elem_abi_size = elem_ty.abiSize(pt); |
| 9313 | 9371 | ||
| 9314 | if (elem_abi_size == 1) { | 9372 | if (elem_abi_size == 1) { |
| 9315 | // In this case we can take advantage of LLVM's intrinsic. | 9373 | // In this case we can take advantage of LLVM's intrinsic. |
| ... | @@ -9361,9 +9419,9 @@ pub const FuncGen = struct { | ... | @@ -9361,9 +9419,9 @@ pub const FuncGen = struct { |
| 9361 | _ = try self.wip.brCond(end, body_block, end_block); | 9419 | _ = try self.wip.brCond(end, body_block, end_block); |
| 9362 | 9420 | ||
| 9363 | self.wip.cursor = .{ .block = body_block }; | 9421 | self.wip.cursor = .{ .block = body_block }; |
| 9364 | const elem_abi_align = elem_ty.abiAlignment(mod); | 9422 | const elem_abi_align = elem_ty.abiAlignment(pt); |
| 9365 | const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm(); | 9423 | const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm(); |
| 9366 | if (isByRef(elem_ty, mod)) { | 9424 | if (isByRef(elem_ty, pt)) { |
| 9367 | _ = try self.wip.callMemCpy( | 9425 | _ = try self.wip.callMemCpy( |
| 9368 | it_ptr.toValue(), | 9426 | it_ptr.toValue(), |
| 9369 | it_ptr_align, | 9427 | it_ptr_align, |
| ... | @@ -9405,7 +9463,8 @@ pub const FuncGen = struct { | ... | @@ -9405,7 +9463,8 @@ pub const FuncGen = struct { |
| 9405 | 9463 | ||
| 9406 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9464 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9407 | const o = self.dg.object; | 9465 | const o = self.dg.object; |
| 9408 | const mod = o.module; | 9466 | const pt = o.pt; |
| 9467 | const mod = pt.zcu; | ||
| 9409 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9468 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9410 | const dest_slice = try self.resolveInst(bin_op.lhs); | 9469 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 9411 | const dest_ptr_ty = self.typeOf(bin_op.lhs); | 9470 | const dest_ptr_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -9434,9 +9493,9 @@ pub const FuncGen = struct { | ... | @@ -9434,9 +9493,9 @@ pub const FuncGen = struct { |
| 9434 | self.wip.cursor = .{ .block = memcpy_block }; | 9493 | self.wip.cursor = .{ .block = memcpy_block }; |
| 9435 | _ = try self.wip.callMemCpy( | 9494 | _ = try self.wip.callMemCpy( |
| 9436 | dest_ptr, | 9495 | dest_ptr, |
| 9437 | dest_ptr_ty.ptrAlignment(mod).toLlvm(), | 9496 | dest_ptr_ty.ptrAlignment(pt).toLlvm(), |
| 9438 | src_ptr, | 9497 | src_ptr, |
| 9439 | src_ptr_ty.ptrAlignment(mod).toLlvm(), | 9498 | src_ptr_ty.ptrAlignment(pt).toLlvm(), |
| 9440 | len, | 9499 | len, |
| 9441 | access_kind, | 9500 | access_kind, |
| 9442 | ); | 9501 | ); |
| ... | @@ -9447,9 +9506,9 @@ pub const FuncGen = struct { | ... | @@ -9447,9 +9506,9 @@ pub const FuncGen = struct { |
| 9447 | 9506 | ||
| 9448 | _ = try self.wip.callMemCpy( | 9507 | _ = try self.wip.callMemCpy( |
| 9449 | dest_ptr, | 9508 | dest_ptr, |
| 9450 | dest_ptr_ty.ptrAlignment(mod).toLlvm(), | 9509 | dest_ptr_ty.ptrAlignment(pt).toLlvm(), |
| 9451 | src_ptr, | 9510 | src_ptr, |
| 9452 | src_ptr_ty.ptrAlignment(mod).toLlvm(), | 9511 | src_ptr_ty.ptrAlignment(pt).toLlvm(), |
| 9453 | len, | 9512 | len, |
| 9454 | access_kind, | 9513 | access_kind, |
| 9455 | ); | 9514 | ); |
| ... | @@ -9458,10 +9517,11 @@ pub const FuncGen = struct { | ... | @@ -9458,10 +9517,11 @@ pub const FuncGen = struct { |
| 9458 | 9517 | ||
| 9459 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9518 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9460 | const o = self.dg.object; | 9519 | const o = self.dg.object; |
| 9461 | const mod = o.module; | 9520 | const pt = o.pt; |
| 9521 | const mod = pt.zcu; | ||
| 9462 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 9522 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9463 | const un_ty = self.typeOf(bin_op.lhs).childType(mod); | 9523 | const un_ty = self.typeOf(bin_op.lhs).childType(mod); |
| 9464 | const layout = un_ty.unionGetLayout(mod); | 9524 | const layout = un_ty.unionGetLayout(pt); |
| 9465 | if (layout.tag_size == 0) return .none; | 9525 | if (layout.tag_size == 0) return .none; |
| 9466 | const union_ptr = try self.resolveInst(bin_op.lhs); | 9526 | const union_ptr = try self.resolveInst(bin_op.lhs); |
| 9467 | const new_tag = try self.resolveInst(bin_op.rhs); | 9527 | const new_tag = try self.resolveInst(bin_op.rhs); |
| ... | @@ -9479,13 +9539,13 @@ pub const FuncGen = struct { | ... | @@ -9479,13 +9539,13 @@ pub const FuncGen = struct { |
| 9479 | 9539 | ||
| 9480 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9540 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9481 | const o = self.dg.object; | 9541 | const o = self.dg.object; |
| 9482 | const mod = o.module; | 9542 | const pt = o.pt; |
| 9483 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 9543 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9484 | const un_ty = self.typeOf(ty_op.operand); | 9544 | const un_ty = self.typeOf(ty_op.operand); |
| 9485 | const layout = un_ty.unionGetLayout(mod); | 9545 | const layout = un_ty.unionGetLayout(pt); |
| 9486 | if (layout.tag_size == 0) return .none; | 9546 | if (layout.tag_size == 0) return .none; |
| 9487 | const union_handle = try self.resolveInst(ty_op.operand); | 9547 | const union_handle = try self.resolveInst(ty_op.operand); |
| 9488 | if (isByRef(un_ty, mod)) { | 9548 | if (isByRef(un_ty, pt)) { |
| 9489 | const llvm_un_ty = try o.lowerType(un_ty); | 9549 | const llvm_un_ty = try o.lowerType(un_ty); |
| 9490 | if (layout.payload_size == 0) | 9550 | if (layout.payload_size == 0) |
| 9491 | return self.wip.load(.normal, llvm_un_ty, union_handle, .default, ""); | 9551 | return self.wip.load(.normal, llvm_un_ty, union_handle, .default, ""); |
| ... | @@ -9554,7 +9614,7 @@ pub const FuncGen = struct { | ... | @@ -9554,7 +9614,7 @@ pub const FuncGen = struct { |
| 9554 | 9614 | ||
| 9555 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9615 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9556 | const o = self.dg.object; | 9616 | const o = self.dg.object; |
| 9557 | const mod = o.module; | 9617 | const mod = o.pt.zcu; |
| 9558 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 9618 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9559 | const operand_ty = self.typeOf(ty_op.operand); | 9619 | const operand_ty = self.typeOf(ty_op.operand); |
| 9560 | var bits = operand_ty.intInfo(mod).bits; | 9620 | var bits = operand_ty.intInfo(mod).bits; |
| ... | @@ -9588,7 +9648,7 @@ pub const FuncGen = struct { | ... | @@ -9588,7 +9648,7 @@ pub const FuncGen = struct { |
| 9588 | 9648 | ||
| 9589 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9649 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9590 | const o = self.dg.object; | 9650 | const o = self.dg.object; |
| 9591 | const mod = o.module; | 9651 | const mod = o.pt.zcu; |
| 9592 | const ip = &mod.intern_pool; | 9652 | const ip = &mod.intern_pool; |
| 9593 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 9653 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9594 | const operand = try self.resolveInst(ty_op.operand); | 9654 | const operand = try self.resolveInst(ty_op.operand); |
| ... | @@ -9638,7 +9698,8 @@ pub const FuncGen = struct { | ... | @@ -9638,7 +9698,8 @@ pub const FuncGen = struct { |
| 9638 | 9698 | ||
| 9639 | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index { | 9699 | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index { |
| 9640 | const o = self.dg.object; | 9700 | const o = self.dg.object; |
| 9641 | const zcu = o.module; | 9701 | const pt = o.pt; |
| 9702 | const zcu = pt.zcu; | ||
| 9642 | const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern()); | 9703 | const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern()); |
| 9643 | 9704 | ||
| 9644 | // TODO: detect when the type changes and re-emit this function. | 9705 | // TODO: detect when the type changes and re-emit this function. |
| ... | @@ -9678,7 +9739,7 @@ pub const FuncGen = struct { | ... | @@ -9678,7 +9739,7 @@ pub const FuncGen = struct { |
| 9678 | 9739 | ||
| 9679 | for (0..enum_type.names.len) |field_index| { | 9740 | for (0..enum_type.names.len) |field_index| { |
| 9680 | const this_tag_int_value = try o.lowerValue( | 9741 | const this_tag_int_value = try o.lowerValue( |
| 9681 | (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(), | 9742 | (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(), |
| 9682 | ); | 9743 | ); |
| 9683 | try wip_switch.addCase(this_tag_int_value, named_block, &wip); | 9744 | try wip_switch.addCase(this_tag_int_value, named_block, &wip); |
| 9684 | } | 9745 | } |
| ... | @@ -9745,7 +9806,8 @@ pub const FuncGen = struct { | ... | @@ -9745,7 +9806,8 @@ pub const FuncGen = struct { |
| 9745 | 9806 | ||
| 9746 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 9807 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9747 | const o = self.dg.object; | 9808 | const o = self.dg.object; |
| 9748 | const mod = o.module; | 9809 | const pt = o.pt; |
| 9810 | const mod = pt.zcu; | ||
| 9749 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 9811 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 9750 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 9812 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 9751 | const a = try self.resolveInst(extra.a); | 9813 | const a = try self.resolveInst(extra.a); |
| ... | @@ -9763,11 +9825,11 @@ pub const FuncGen = struct { | ... | @@ -9763,11 +9825,11 @@ pub const FuncGen = struct { |
| 9763 | defer self.gpa.free(values); | 9825 | defer self.gpa.free(values); |
| 9764 | 9826 | ||
| 9765 | for (values, 0..) |*val, i| { | 9827 | for (values, 0..) |*val, i| { |
| 9766 | const elem = try mask.elemValue(mod, i); | 9828 | const elem = try mask.elemValue(pt, i); |
| 9767 | if (elem.isUndef(mod)) { | 9829 | if (elem.isUndef(mod)) { |
| 9768 | val.* = try o.builder.undefConst(.i32); | 9830 | val.* = try o.builder.undefConst(.i32); |
| 9769 | } else { | 9831 | } else { |
| 9770 | const int = elem.toSignedInt(mod); | 9832 | const int = elem.toSignedInt(pt); |
| 9771 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len); | 9833 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len); |
| 9772 | val.* = try o.builder.intConst(.i32, unsigned); | 9834 | val.* = try o.builder.intConst(.i32, unsigned); |
| 9773 | } | 9835 | } |
| ... | @@ -9854,7 +9916,7 @@ pub const FuncGen = struct { | ... | @@ -9854,7 +9916,7 @@ pub const FuncGen = struct { |
| 9854 | 9916 | ||
| 9855 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { | 9917 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 9856 | const o = self.dg.object; | 9918 | const o = self.dg.object; |
| 9857 | const mod = o.module; | 9919 | const mod = o.pt.zcu; |
| 9858 | const target = mod.getTarget(); | 9920 | const target = mod.getTarget(); |
| 9859 | 9921 | ||
| 9860 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 9922 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| ... | @@ -9964,7 +10026,8 @@ pub const FuncGen = struct { | ... | @@ -9964,7 +10026,8 @@ pub const FuncGen = struct { |
| 9964 | 10026 | ||
| 9965 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10027 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9966 | const o = self.dg.object; | 10028 | const o = self.dg.object; |
| 9967 | const mod = o.module; | 10029 | const pt = o.pt; |
| 10030 | const mod = pt.zcu; | ||
| 9968 | const ip = &mod.intern_pool; | 10031 | const ip = &mod.intern_pool; |
| 9969 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 10032 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 9970 | const result_ty = self.typeOfIndex(inst); | 10033 | const result_ty = self.typeOfIndex(inst); |
| ... | @@ -9986,16 +10049,16 @@ pub const FuncGen = struct { | ... | @@ -9986,16 +10049,16 @@ pub const FuncGen = struct { |
| 9986 | if (mod.typeToPackedStruct(result_ty)) |struct_type| { | 10049 | if (mod.typeToPackedStruct(result_ty)) |struct_type| { |
| 9987 | const backing_int_ty = struct_type.backingIntType(ip).*; | 10050 | const backing_int_ty = struct_type.backingIntType(ip).*; |
| 9988 | assert(backing_int_ty != .none); | 10051 | assert(backing_int_ty != .none); |
| 9989 | const big_bits = Type.fromInterned(backing_int_ty).bitSize(mod); | 10052 | const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt); |
| 9990 | const int_ty = try o.builder.intType(@intCast(big_bits)); | 10053 | const int_ty = try o.builder.intType(@intCast(big_bits)); |
| 9991 | comptime assert(Type.packed_struct_layout_version == 2); | 10054 | comptime assert(Type.packed_struct_layout_version == 2); |
| 9992 | var running_int = try o.builder.intValue(int_ty, 0); | 10055 | var running_int = try o.builder.intValue(int_ty, 0); |
| 9993 | var running_bits: u16 = 0; | 10056 | var running_bits: u16 = 0; |
| 9994 | for (elements, struct_type.field_types.get(ip)) |elem, field_ty| { | 10057 | for (elements, struct_type.field_types.get(ip)) |elem, field_ty| { |
| 9995 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue; | 10058 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 9996 | 10059 | ||
| 9997 | const non_int_val = try self.resolveInst(elem); | 10060 | const non_int_val = try self.resolveInst(elem); |
| 9998 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod)); | 10061 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt)); |
| 9999 | const small_int_ty = try o.builder.intType(ty_bit_size); | 10062 | const small_int_ty = try o.builder.intType(ty_bit_size); |
| 10000 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod)) | 10063 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod)) |
| 10001 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") | 10064 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") |
| ... | @@ -10013,23 +10076,23 @@ pub const FuncGen = struct { | ... | @@ -10013,23 +10076,23 @@ pub const FuncGen = struct { |
| 10013 | 10076 | ||
| 10014 | assert(result_ty.containerLayout(mod) != .@"packed"); | 10077 | assert(result_ty.containerLayout(mod) != .@"packed"); |
| 10015 | 10078 | ||
| 10016 | if (isByRef(result_ty, mod)) { | 10079 | if (isByRef(result_ty, pt)) { |
| 10017 | // TODO in debug builds init to undef so that the padding will be 0xaa | 10080 | // TODO in debug builds init to undef so that the padding will be 0xaa |
| 10018 | // even if we fully populate the fields. | 10081 | // even if we fully populate the fields. |
| 10019 | const alignment = result_ty.abiAlignment(mod).toLlvm(); | 10082 | const alignment = result_ty.abiAlignment(pt).toLlvm(); |
| 10020 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); | 10083 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); |
| 10021 | 10084 | ||
| 10022 | for (elements, 0..) |elem, i| { | 10085 | for (elements, 0..) |elem, i| { |
| 10023 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; | 10086 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 10024 | 10087 | ||
| 10025 | const llvm_elem = try self.resolveInst(elem); | 10088 | const llvm_elem = try self.resolveInst(elem); |
| 10026 | const llvm_i = o.llvmFieldIndex(result_ty, i).?; | 10089 | const llvm_i = o.llvmFieldIndex(result_ty, i).?; |
| 10027 | const field_ptr = | 10090 | const field_ptr = |
| 10028 | try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, ""); | 10091 | try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, ""); |
| 10029 | const field_ptr_ty = try mod.ptrType(.{ | 10092 | const field_ptr_ty = try pt.ptrType(.{ |
| 10030 | .child = self.typeOf(elem).toIntern(), | 10093 | .child = self.typeOf(elem).toIntern(), |
| 10031 | .flags = .{ | 10094 | .flags = .{ |
| 10032 | .alignment = result_ty.structFieldAlign(i, mod), | 10095 | .alignment = result_ty.structFieldAlign(i, pt), |
| 10033 | }, | 10096 | }, |
| 10034 | }); | 10097 | }); |
| 10035 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .none); | 10098 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .none); |
| ... | @@ -10039,7 +10102,7 @@ pub const FuncGen = struct { | ... | @@ -10039,7 +10102,7 @@ pub const FuncGen = struct { |
| 10039 | } else { | 10102 | } else { |
| 10040 | var result = try o.builder.poisonValue(llvm_result_ty); | 10103 | var result = try o.builder.poisonValue(llvm_result_ty); |
| 10041 | for (elements, 0..) |elem, i| { | 10104 | for (elements, 0..) |elem, i| { |
| 10042 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; | 10105 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 10043 | 10106 | ||
| 10044 | const llvm_elem = try self.resolveInst(elem); | 10107 | const llvm_elem = try self.resolveInst(elem); |
| 10045 | const llvm_i = o.llvmFieldIndex(result_ty, i).?; | 10108 | const llvm_i = o.llvmFieldIndex(result_ty, i).?; |
| ... | @@ -10049,15 +10112,15 @@ pub const FuncGen = struct { | ... | @@ -10049,15 +10112,15 @@ pub const FuncGen = struct { |
| 10049 | } | 10112 | } |
| 10050 | }, | 10113 | }, |
| 10051 | .Array => { | 10114 | .Array => { |
| 10052 | assert(isByRef(result_ty, mod)); | 10115 | assert(isByRef(result_ty, pt)); |
| 10053 | 10116 | ||
| 10054 | const llvm_usize = try o.lowerType(Type.usize); | 10117 | const llvm_usize = try o.lowerType(Type.usize); |
| 10055 | const usize_zero = try o.builder.intValue(llvm_usize, 0); | 10118 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 10056 | const alignment = result_ty.abiAlignment(mod).toLlvm(); | 10119 | const alignment = result_ty.abiAlignment(pt).toLlvm(); |
| 10057 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); | 10120 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); |
| 10058 | 10121 | ||
| 10059 | const array_info = result_ty.arrayInfo(mod); | 10122 | const array_info = result_ty.arrayInfo(mod); |
| 10060 | const elem_ptr_ty = try mod.ptrType(.{ | 10123 | const elem_ptr_ty = try pt.ptrType(.{ |
| 10061 | .child = array_info.elem_type.toIntern(), | 10124 | .child = array_info.elem_type.toIntern(), |
| 10062 | }); | 10125 | }); |
| 10063 | 10126 | ||
| ... | @@ -10084,21 +10147,22 @@ pub const FuncGen = struct { | ... | @@ -10084,21 +10147,22 @@ pub const FuncGen = struct { |
| 10084 | 10147 | ||
| 10085 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10148 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10086 | const o = self.dg.object; | 10149 | const o = self.dg.object; |
| 10087 | const mod = o.module; | 10150 | const pt = o.pt; |
| 10151 | const mod = pt.zcu; | ||
| 10088 | const ip = &mod.intern_pool; | 10152 | const ip = &mod.intern_pool; |
| 10089 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 10153 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 10090 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 10154 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 10091 | const union_ty = self.typeOfIndex(inst); | 10155 | const union_ty = self.typeOfIndex(inst); |
| 10092 | const union_llvm_ty = try o.lowerType(union_ty); | 10156 | const union_llvm_ty = try o.lowerType(union_ty); |
| 10093 | const layout = union_ty.unionGetLayout(mod); | 10157 | const layout = union_ty.unionGetLayout(pt); |
| 10094 | const union_obj = mod.typeToUnion(union_ty).?; | 10158 | const union_obj = mod.typeToUnion(union_ty).?; |
| 10095 | 10159 | ||
| 10096 | if (union_obj.getLayout(ip) == .@"packed") { | 10160 | if (union_obj.getLayout(ip) == .@"packed") { |
| 10097 | const big_bits = union_ty.bitSize(mod); | 10161 | const big_bits = union_ty.bitSize(pt); |
| 10098 | const int_llvm_ty = try o.builder.intType(@intCast(big_bits)); | 10162 | const int_llvm_ty = try o.builder.intType(@intCast(big_bits)); |
| 10099 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); | 10163 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 10100 | const non_int_val = try self.resolveInst(extra.init); | 10164 | const non_int_val = try self.resolveInst(extra.init); |
| 10101 | const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(mod))); | 10165 | const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(pt))); |
| 10102 | const small_int_val = if (field_ty.isPtrAtRuntime(mod)) | 10166 | const small_int_val = if (field_ty.isPtrAtRuntime(mod)) |
| 10103 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") | 10167 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") |
| 10104 | else | 10168 | else |
| ... | @@ -10110,19 +10174,19 @@ pub const FuncGen = struct { | ... | @@ -10110,19 +10174,19 @@ pub const FuncGen = struct { |
| 10110 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | 10174 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); |
| 10111 | const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 10175 | const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 10112 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?; | 10176 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?; |
| 10113 | const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index); | 10177 | const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index); |
| 10114 | break :blk try tag_val.intFromEnum(tag_ty, mod); | 10178 | break :blk try tag_val.intFromEnum(tag_ty, pt); |
| 10115 | }; | 10179 | }; |
| 10116 | if (layout.payload_size == 0) { | 10180 | if (layout.payload_size == 0) { |
| 10117 | if (layout.tag_size == 0) { | 10181 | if (layout.tag_size == 0) { |
| 10118 | return .none; | 10182 | return .none; |
| 10119 | } | 10183 | } |
| 10120 | assert(!isByRef(union_ty, mod)); | 10184 | assert(!isByRef(union_ty, pt)); |
| 10121 | var big_int_space: Value.BigIntSpace = undefined; | 10185 | var big_int_space: Value.BigIntSpace = undefined; |
| 10122 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod); | 10186 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt); |
| 10123 | return try o.builder.bigIntValue(union_llvm_ty, tag_big_int); | 10187 | return try o.builder.bigIntValue(union_llvm_ty, tag_big_int); |
| 10124 | } | 10188 | } |
| 10125 | assert(isByRef(union_ty, mod)); | 10189 | assert(isByRef(union_ty, pt)); |
| 10126 | // The llvm type of the alloca will be the named LLVM union type, and will not | 10190 | // The llvm type of the alloca will be the named LLVM union type, and will not |
| 10127 | // necessarily match the format that we need, depending on which tag is active. | 10191 | // necessarily match the format that we need, depending on which tag is active. |
| 10128 | // We must construct the correct unnamed struct type here, in order to then set | 10192 | // We must construct the correct unnamed struct type here, in order to then set |
| ... | @@ -10132,14 +10196,14 @@ pub const FuncGen = struct { | ... | @@ -10132,14 +10196,14 @@ pub const FuncGen = struct { |
| 10132 | const llvm_payload = try self.resolveInst(extra.init); | 10196 | const llvm_payload = try self.resolveInst(extra.init); |
| 10133 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); | 10197 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 10134 | const field_llvm_ty = try o.lowerType(field_ty); | 10198 | const field_llvm_ty = try o.lowerType(field_ty); |
| 10135 | const field_size = field_ty.abiSize(mod); | 10199 | const field_size = field_ty.abiSize(pt); |
| 10136 | const field_align = mod.unionFieldNormalAlignment(union_obj, extra.field_index); | 10200 | const field_align = pt.unionFieldNormalAlignment(union_obj, extra.field_index); |
| 10137 | const llvm_usize = try o.lowerType(Type.usize); | 10201 | const llvm_usize = try o.lowerType(Type.usize); |
| 10138 | const usize_zero = try o.builder.intValue(llvm_usize, 0); | 10202 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 10139 | 10203 | ||
| 10140 | const llvm_union_ty = t: { | 10204 | const llvm_union_ty = t: { |
| 10141 | const payload_ty = p: { | 10205 | const payload_ty = p: { |
| 10142 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 10206 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 10143 | const padding_len = layout.payload_size; | 10207 | const padding_len = layout.payload_size; |
| 10144 | break :p try o.builder.arrayType(padding_len, .i8); | 10208 | break :p try o.builder.arrayType(padding_len, .i8); |
| 10145 | } | 10209 | } |
| ... | @@ -10169,7 +10233,7 @@ pub const FuncGen = struct { | ... | @@ -10169,7 +10233,7 @@ pub const FuncGen = struct { |
| 10169 | 10233 | ||
| 10170 | // Now we follow the layout as expressed above with GEP instructions to set the | 10234 | // Now we follow the layout as expressed above with GEP instructions to set the |
| 10171 | // tag and the payload. | 10235 | // tag and the payload. |
| 10172 | const field_ptr_ty = try mod.ptrType(.{ | 10236 | const field_ptr_ty = try pt.ptrType(.{ |
| 10173 | .child = field_ty.toIntern(), | 10237 | .child = field_ty.toIntern(), |
| 10174 | .flags = .{ .alignment = field_align }, | 10238 | .flags = .{ .alignment = field_align }, |
| 10175 | }); | 10239 | }); |
| ... | @@ -10195,9 +10259,9 @@ pub const FuncGen = struct { | ... | @@ -10195,9 +10259,9 @@ pub const FuncGen = struct { |
| 10195 | const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, ""); | 10259 | const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, ""); |
| 10196 | const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); | 10260 | const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); |
| 10197 | var big_int_space: Value.BigIntSpace = undefined; | 10261 | var big_int_space: Value.BigIntSpace = undefined; |
| 10198 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod); | 10262 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt); |
| 10199 | const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int); | 10263 | const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int); |
| 10200 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(mod).toLlvm(); | 10264 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(pt).toLlvm(); |
| 10201 | _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment); | 10265 | _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment); |
| 10202 | } | 10266 | } |
| 10203 | 10267 | ||
| ... | @@ -10223,7 +10287,7 @@ pub const FuncGen = struct { | ... | @@ -10223,7 +10287,7 @@ pub const FuncGen = struct { |
| 10223 | // by the target. | 10287 | // by the target. |
| 10224 | // To work around this, don't emit llvm.prefetch in this case. | 10288 | // To work around this, don't emit llvm.prefetch in this case. |
| 10225 | // See https://bugs.llvm.org/show_bug.cgi?id=21037 | 10289 | // See https://bugs.llvm.org/show_bug.cgi?id=21037 |
| 10226 | const mod = o.module; | 10290 | const mod = o.pt.zcu; |
| 10227 | const target = mod.getTarget(); | 10291 | const target = mod.getTarget(); |
| 10228 | switch (prefetch.cache) { | 10292 | switch (prefetch.cache) { |
| 10229 | .instruction => switch (target.cpu.arch) { | 10293 | .instruction => switch (target.cpu.arch) { |
| ... | @@ -10279,7 +10343,7 @@ pub const FuncGen = struct { | ... | @@ -10279,7 +10343,7 @@ pub const FuncGen = struct { |
| 10279 | 10343 | ||
| 10280 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10344 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10281 | const o = self.dg.object; | 10345 | const o = self.dg.object; |
| 10282 | const target = o.module.getTarget(); | 10346 | const target = o.pt.zcu.getTarget(); |
| 10283 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | 10347 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10284 | 10348 | ||
| 10285 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10349 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | @@ -10289,7 +10353,7 @@ pub const FuncGen = struct { | ... | @@ -10289,7 +10353,7 @@ pub const FuncGen = struct { |
| 10289 | 10353 | ||
| 10290 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10354 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10291 | const o = self.dg.object; | 10355 | const o = self.dg.object; |
| 10292 | const target = o.module.getTarget(); | 10356 | const target = o.pt.zcu.getTarget(); |
| 10293 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | 10357 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10294 | 10358 | ||
| 10295 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10359 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | @@ -10312,7 +10376,7 @@ pub const FuncGen = struct { | ... | @@ -10312,7 +10376,7 @@ pub const FuncGen = struct { |
| 10312 | 10376 | ||
| 10313 | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10377 | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10314 | const o = self.dg.object; | 10378 | const o = self.dg.object; |
| 10315 | const target = o.module.getTarget(); | 10379 | const target = o.pt.zcu.getTarget(); |
| 10316 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | 10380 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10317 | 10381 | ||
| 10318 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10382 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | @@ -10322,7 +10386,7 @@ pub const FuncGen = struct { | ... | @@ -10322,7 +10386,7 @@ pub const FuncGen = struct { |
| 10322 | 10386 | ||
| 10323 | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { | 10387 | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { |
| 10324 | const o = self.dg.object; | 10388 | const o = self.dg.object; |
| 10325 | const mod = o.module; | 10389 | const pt = o.pt; |
| 10326 | 10390 | ||
| 10327 | const table = o.error_name_table; | 10391 | const table = o.error_name_table; |
| 10328 | if (table != .none) return table; | 10392 | if (table != .none) return table; |
| ... | @@ -10334,7 +10398,7 @@ pub const FuncGen = struct { | ... | @@ -10334,7 +10398,7 @@ pub const FuncGen = struct { |
| 10334 | variable_index.setMutability(.constant, &o.builder); | 10398 | variable_index.setMutability(.constant, &o.builder); |
| 10335 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 10399 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 10336 | variable_index.setAlignment( | 10400 | variable_index.setAlignment( |
| 10337 | Type.slice_const_u8_sentinel_0.abiAlignment(mod).toLlvm(), | 10401 | Type.slice_const_u8_sentinel_0.abiAlignment(pt).toLlvm(), |
| 10338 | &o.builder, | 10402 | &o.builder, |
| 10339 | ); | 10403 | ); |
| 10340 | 10404 | ||
| ... | @@ -10372,15 +10436,16 @@ pub const FuncGen = struct { | ... | @@ -10372,15 +10436,16 @@ pub const FuncGen = struct { |
| 10372 | can_elide_load: bool, | 10436 | can_elide_load: bool, |
| 10373 | ) !Builder.Value { | 10437 | ) !Builder.Value { |
| 10374 | const o = fg.dg.object; | 10438 | const o = fg.dg.object; |
| 10375 | const mod = o.module; | 10439 | const pt = o.pt; |
| 10440 | const mod = pt.zcu; | ||
| 10376 | const payload_ty = opt_ty.optionalChild(mod); | 10441 | const payload_ty = opt_ty.optionalChild(mod); |
| 10377 | 10442 | ||
| 10378 | if (isByRef(opt_ty, mod)) { | 10443 | if (isByRef(opt_ty, pt)) { |
| 10379 | // We have a pointer and we need to return a pointer to the first field. | 10444 | // We have a pointer and we need to return a pointer to the first field. |
| 10380 | const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, ""); | 10445 | const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, ""); |
| 10381 | 10446 | ||
| 10382 | const payload_alignment = payload_ty.abiAlignment(mod).toLlvm(); | 10447 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); |
| 10383 | if (isByRef(payload_ty, mod)) { | 10448 | if (isByRef(payload_ty, pt)) { |
| 10384 | if (can_elide_load) | 10449 | if (can_elide_load) |
| 10385 | return payload_ptr; | 10450 | return payload_ptr; |
| 10386 | 10451 | ||
| ... | @@ -10389,7 +10454,7 @@ pub const FuncGen = struct { | ... | @@ -10389,7 +10454,7 @@ pub const FuncGen = struct { |
| 10389 | return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment); | 10454 | return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment); |
| 10390 | } | 10455 | } |
| 10391 | 10456 | ||
| 10392 | assert(!isByRef(payload_ty, mod)); | 10457 | assert(!isByRef(payload_ty, pt)); |
| 10393 | return fg.wip.extractValue(opt_handle, &.{0}, ""); | 10458 | return fg.wip.extractValue(opt_handle, &.{0}, ""); |
| 10394 | } | 10459 | } |
| 10395 | 10460 | ||
| ... | @@ -10400,12 +10465,12 @@ pub const FuncGen = struct { | ... | @@ -10400,12 +10465,12 @@ pub const FuncGen = struct { |
| 10400 | non_null_bit: Builder.Value, | 10465 | non_null_bit: Builder.Value, |
| 10401 | ) !Builder.Value { | 10466 | ) !Builder.Value { |
| 10402 | const o = self.dg.object; | 10467 | const o = self.dg.object; |
| 10468 | const pt = o.pt; | ||
| 10403 | const optional_llvm_ty = try o.lowerType(optional_ty); | 10469 | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 10404 | const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, ""); | 10470 | const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, ""); |
| 10405 | const mod = o.module; | ||
| 10406 | 10471 | ||
| 10407 | if (isByRef(optional_ty, mod)) { | 10472 | if (isByRef(optional_ty, pt)) { |
| 10408 | const payload_alignment = optional_ty.abiAlignment(mod).toLlvm(); | 10473 | const payload_alignment = optional_ty.abiAlignment(pt).toLlvm(); |
| 10409 | const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment); | 10474 | const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment); |
| 10410 | 10475 | ||
| 10411 | { | 10476 | { |
| ... | @@ -10432,7 +10497,8 @@ pub const FuncGen = struct { | ... | @@ -10432,7 +10497,8 @@ pub const FuncGen = struct { |
| 10432 | field_index: u32, | 10497 | field_index: u32, |
| 10433 | ) !Builder.Value { | 10498 | ) !Builder.Value { |
| 10434 | const o = self.dg.object; | 10499 | const o = self.dg.object; |
| 10435 | const mod = o.module; | 10500 | const pt = o.pt; |
| 10501 | const mod = pt.zcu; | ||
| 10436 | const struct_ty = struct_ptr_ty.childType(mod); | 10502 | const struct_ty = struct_ptr_ty.childType(mod); |
| 10437 | switch (struct_ty.zigTypeTag(mod)) { | 10503 | switch (struct_ty.zigTypeTag(mod)) { |
| 10438 | .Struct => switch (struct_ty.containerLayout(mod)) { | 10504 | .Struct => switch (struct_ty.containerLayout(mod)) { |
| ... | @@ -10452,7 +10518,7 @@ pub const FuncGen = struct { | ... | @@ -10452,7 +10518,7 @@ pub const FuncGen = struct { |
| 10452 | 10518 | ||
| 10453 | // We have a pointer to a packed struct field that happens to be byte-aligned. | 10519 | // We have a pointer to a packed struct field that happens to be byte-aligned. |
| 10454 | // Offset our operand pointer by the correct number of bytes. | 10520 | // Offset our operand pointer by the correct number of bytes. |
| 10455 | const byte_offset = @divExact(mod.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8); | 10521 | const byte_offset = @divExact(pt.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8); |
| 10456 | if (byte_offset == 0) return struct_ptr; | 10522 | if (byte_offset == 0) return struct_ptr; |
| 10457 | const usize_ty = try o.lowerType(Type.usize); | 10523 | const usize_ty = try o.lowerType(Type.usize); |
| 10458 | const llvm_index = try o.builder.intValue(usize_ty, byte_offset); | 10524 | const llvm_index = try o.builder.intValue(usize_ty, byte_offset); |
| ... | @@ -10470,14 +10536,14 @@ pub const FuncGen = struct { | ... | @@ -10470,14 +10536,14 @@ pub const FuncGen = struct { |
| 10470 | // the struct. | 10536 | // the struct. |
| 10471 | const llvm_index = try o.builder.intValue( | 10537 | const llvm_index = try o.builder.intValue( |
| 10472 | try o.lowerType(Type.usize), | 10538 | try o.lowerType(Type.usize), |
| 10473 | @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), | 10539 | @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(pt)), |
| 10474 | ); | 10540 | ); |
| 10475 | return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, ""); | 10541 | return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, ""); |
| 10476 | } | 10542 | } |
| 10477 | }, | 10543 | }, |
| 10478 | }, | 10544 | }, |
| 10479 | .Union => { | 10545 | .Union => { |
| 10480 | const layout = struct_ty.unionGetLayout(mod); | 10546 | const layout = struct_ty.unionGetLayout(pt); |
| 10481 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr; | 10547 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr; |
| 10482 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); | 10548 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 10483 | const union_llvm_ty = try o.lowerType(struct_ty); | 10549 | const union_llvm_ty = try o.lowerType(struct_ty); |
| ... | @@ -10500,9 +10566,10 @@ pub const FuncGen = struct { | ... | @@ -10500,9 +10566,10 @@ pub const FuncGen = struct { |
| 10500 | // => so load the byte aligned value and trunc the unwanted bits. | 10566 | // => so load the byte aligned value and trunc the unwanted bits. |
| 10501 | 10567 | ||
| 10502 | const o = fg.dg.object; | 10568 | const o = fg.dg.object; |
| 10503 | const mod = o.module; | 10569 | const pt = o.pt; |
| 10570 | const mod = pt.zcu; | ||
| 10504 | const payload_llvm_ty = try o.lowerType(payload_ty); | 10571 | const payload_llvm_ty = try o.lowerType(payload_ty); |
| 10505 | const abi_size = payload_ty.abiSize(mod); | 10572 | const abi_size = payload_ty.abiSize(pt); |
| 10506 | 10573 | ||
| 10507 | // llvm bug workarounds: | 10574 | // llvm bug workarounds: |
| 10508 | const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4; | 10575 | const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4; |
| ... | @@ -10522,7 +10589,7 @@ pub const FuncGen = struct { | ... | @@ -10522,7 +10589,7 @@ pub const FuncGen = struct { |
| 10522 | const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big) | 10589 | const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big) |
| 10523 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( | 10590 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( |
| 10524 | load_llvm_ty, | 10591 | load_llvm_ty, |
| 10525 | (payload_ty.abiSize(mod) - (std.math.divCeil(u64, payload_ty.bitSize(mod), 8) catch unreachable)) * 8, | 10592 | (payload_ty.abiSize(pt) - (std.math.divCeil(u64, payload_ty.bitSize(pt), 8) catch unreachable)) * 8, |
| 10526 | ), "") | 10593 | ), "") |
| 10527 | else | 10594 | else |
| 10528 | loaded; | 10595 | loaded; |
| ... | @@ -10546,11 +10613,11 @@ pub const FuncGen = struct { | ... | @@ -10546,11 +10613,11 @@ pub const FuncGen = struct { |
| 10546 | access_kind: Builder.MemoryAccessKind, | 10613 | access_kind: Builder.MemoryAccessKind, |
| 10547 | ) !Builder.Value { | 10614 | ) !Builder.Value { |
| 10548 | const o = fg.dg.object; | 10615 | const o = fg.dg.object; |
| 10549 | const mod = o.module; | 10616 | const pt = o.pt; |
| 10550 | //const pointee_llvm_ty = try o.lowerType(pointee_type); | 10617 | //const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 10551 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(mod)).toLlvm(); | 10618 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm(); |
| 10552 | const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align); | 10619 | const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align); |
| 10553 | const size_bytes = pointee_type.abiSize(mod); | 10620 | const size_bytes = pointee_type.abiSize(pt); |
| 10554 | _ = try fg.wip.callMemCpy( | 10621 | _ = try fg.wip.callMemCpy( |
| 10555 | result_ptr, | 10622 | result_ptr, |
| 10556 | result_align, | 10623 | result_align, |
| ... | @@ -10567,15 +10634,16 @@ pub const FuncGen = struct { | ... | @@ -10567,15 +10634,16 @@ pub const FuncGen = struct { |
| 10567 | /// For isByRef=false types, it creates a load instruction and returns it. | 10634 | /// For isByRef=false types, it creates a load instruction and returns it. |
| 10568 | fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { | 10635 | fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 10569 | const o = self.dg.object; | 10636 | const o = self.dg.object; |
| 10570 | const mod = o.module; | 10637 | const pt = o.pt; |
| 10638 | const mod = pt.zcu; | ||
| 10571 | const info = ptr_ty.ptrInfo(mod); | 10639 | const info = ptr_ty.ptrInfo(mod); |
| 10572 | const elem_ty = Type.fromInterned(info.child); | 10640 | const elem_ty = Type.fromInterned(info.child); |
| 10573 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return .none; | 10641 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; |
| 10574 | 10642 | ||
| 10575 | const ptr_alignment = (if (info.flags.alignment != .none) | 10643 | const ptr_alignment = (if (info.flags.alignment != .none) |
| 10576 | @as(InternPool.Alignment, info.flags.alignment) | 10644 | @as(InternPool.Alignment, info.flags.alignment) |
| 10577 | else | 10645 | else |
| 10578 | elem_ty.abiAlignment(mod)).toLlvm(); | 10646 | elem_ty.abiAlignment(pt)).toLlvm(); |
| 10579 | 10647 | ||
| 10580 | const access_kind: Builder.MemoryAccessKind = | 10648 | const access_kind: Builder.MemoryAccessKind = |
| 10581 | if (info.flags.is_volatile) .@"volatile" else .normal; | 10649 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| ... | @@ -10591,7 +10659,7 @@ pub const FuncGen = struct { | ... | @@ -10591,7 +10659,7 @@ pub const FuncGen = struct { |
| 10591 | } | 10659 | } |
| 10592 | 10660 | ||
| 10593 | if (info.packed_offset.host_size == 0) { | 10661 | if (info.packed_offset.host_size == 0) { |
| 10594 | if (isByRef(elem_ty, mod)) { | 10662 | if (isByRef(elem_ty, pt)) { |
| 10595 | return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind); | 10663 | return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind); |
| 10596 | } | 10664 | } |
| 10597 | return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment); | 10665 | return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment); |
| ... | @@ -10601,13 +10669,13 @@ pub const FuncGen = struct { | ... | @@ -10601,13 +10669,13 @@ pub const FuncGen = struct { |
| 10601 | const containing_int = | 10669 | const containing_int = |
| 10602 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); | 10670 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); |
| 10603 | 10671 | ||
| 10604 | const elem_bits = ptr_ty.childType(mod).bitSize(mod); | 10672 | const elem_bits = ptr_ty.childType(mod).bitSize(pt); |
| 10605 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); | 10673 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); |
| 10606 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); | 10674 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); |
| 10607 | const elem_llvm_ty = try o.lowerType(elem_ty); | 10675 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 10608 | 10676 | ||
| 10609 | if (isByRef(elem_ty, mod)) { | 10677 | if (isByRef(elem_ty, pt)) { |
| 10610 | const result_align = elem_ty.abiAlignment(mod).toLlvm(); | 10678 | const result_align = elem_ty.abiAlignment(pt).toLlvm(); |
| 10611 | const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align); | 10679 | const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align); |
| 10612 | 10680 | ||
| 10613 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); | 10681 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); |
| ... | @@ -10639,13 +10707,14 @@ pub const FuncGen = struct { | ... | @@ -10639,13 +10707,14 @@ pub const FuncGen = struct { |
| 10639 | ordering: Builder.AtomicOrdering, | 10707 | ordering: Builder.AtomicOrdering, |
| 10640 | ) !void { | 10708 | ) !void { |
| 10641 | const o = self.dg.object; | 10709 | const o = self.dg.object; |
| 10642 | const mod = o.module; | 10710 | const pt = o.pt; |
| 10711 | const mod = pt.zcu; | ||
| 10643 | const info = ptr_ty.ptrInfo(mod); | 10712 | const info = ptr_ty.ptrInfo(mod); |
| 10644 | const elem_ty = Type.fromInterned(info.child); | 10713 | const elem_ty = Type.fromInterned(info.child); |
| 10645 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 10714 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 10646 | return; | 10715 | return; |
| 10647 | } | 10716 | } |
| 10648 | const ptr_alignment = ptr_ty.ptrAlignment(mod).toLlvm(); | 10717 | const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm(); |
| 10649 | const access_kind: Builder.MemoryAccessKind = | 10718 | const access_kind: Builder.MemoryAccessKind = |
| 10650 | if (info.flags.is_volatile) .@"volatile" else .normal; | 10719 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 10651 | 10720 | ||
| ... | @@ -10669,7 +10738,7 @@ pub const FuncGen = struct { | ... | @@ -10669,7 +10738,7 @@ pub const FuncGen = struct { |
| 10669 | assert(ordering == .none); | 10738 | assert(ordering == .none); |
| 10670 | const containing_int = | 10739 | const containing_int = |
| 10671 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); | 10740 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); |
| 10672 | const elem_bits = ptr_ty.childType(mod).bitSize(mod); | 10741 | const elem_bits = ptr_ty.childType(mod).bitSize(pt); |
| 10673 | const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset); | 10742 | const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset); |
| 10674 | // Convert to equally-sized integer type in order to perform the bit | 10743 | // Convert to equally-sized integer type in order to perform the bit |
| 10675 | // operations on the value to store | 10744 | // operations on the value to store |
| ... | @@ -10704,7 +10773,7 @@ pub const FuncGen = struct { | ... | @@ -10704,7 +10773,7 @@ pub const FuncGen = struct { |
| 10704 | _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment); | 10773 | _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment); |
| 10705 | return; | 10774 | return; |
| 10706 | } | 10775 | } |
| 10707 | if (!isByRef(elem_ty, mod)) { | 10776 | if (!isByRef(elem_ty, pt)) { |
| 10708 | _ = try self.wip.storeAtomic( | 10777 | _ = try self.wip.storeAtomic( |
| 10709 | access_kind, | 10778 | access_kind, |
| 10710 | elem, | 10779 | elem, |
| ... | @@ -10720,8 +10789,8 @@ pub const FuncGen = struct { | ... | @@ -10720,8 +10789,8 @@ pub const FuncGen = struct { |
| 10720 | ptr, | 10789 | ptr, |
| 10721 | ptr_alignment, | 10790 | ptr_alignment, |
| 10722 | elem, | 10791 | elem, |
| 10723 | elem_ty.abiAlignment(mod).toLlvm(), | 10792 | elem_ty.abiAlignment(pt).toLlvm(), |
| 10724 | try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(mod)), | 10793 | try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(pt)), |
| 10725 | access_kind, | 10794 | access_kind, |
| 10726 | ); | 10795 | ); |
| 10727 | } | 10796 | } |
| ... | @@ -10747,12 +10816,13 @@ pub const FuncGen = struct { | ... | @@ -10747,12 +10816,13 @@ pub const FuncGen = struct { |
| 10747 | a5: Builder.Value, | 10816 | a5: Builder.Value, |
| 10748 | ) Allocator.Error!Builder.Value { | 10817 | ) Allocator.Error!Builder.Value { |
| 10749 | const o = fg.dg.object; | 10818 | const o = fg.dg.object; |
| 10750 | const mod = o.module; | 10819 | const pt = o.pt; |
| 10820 | const mod = pt.zcu; | ||
| 10751 | const target = mod.getTarget(); | 10821 | const target = mod.getTarget(); |
| 10752 | if (!target_util.hasValgrindSupport(target)) return default_value; | 10822 | if (!target_util.hasValgrindSupport(target)) return default_value; |
| 10753 | 10823 | ||
| 10754 | const llvm_usize = try o.lowerType(Type.usize); | 10824 | const llvm_usize = try o.lowerType(Type.usize); |
| 10755 | const usize_alignment = Type.usize.abiAlignment(mod).toLlvm(); | 10825 | const usize_alignment = Type.usize.abiAlignment(pt).toLlvm(); |
| 10756 | 10826 | ||
| 10757 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); | 10827 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); |
| 10758 | const array_ptr = if (fg.valgrind_client_request_array == .none) a: { | 10828 | const array_ptr = if (fg.valgrind_client_request_array == .none) a: { |
| ... | @@ -10813,13 +10883,13 @@ pub const FuncGen = struct { | ... | @@ -10813,13 +10883,13 @@ pub const FuncGen = struct { |
| 10813 | 10883 | ||
| 10814 | fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type { | 10884 | fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type { |
| 10815 | const o = fg.dg.object; | 10885 | const o = fg.dg.object; |
| 10816 | const mod = o.module; | 10886 | const mod = o.pt.zcu; |
| 10817 | return fg.air.typeOf(inst, &mod.intern_pool); | 10887 | return fg.air.typeOf(inst, &mod.intern_pool); |
| 10818 | } | 10888 | } |
| 10819 | 10889 | ||
| 10820 | fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type { | 10890 | fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type { |
| 10821 | const o = fg.dg.object; | 10891 | const o = fg.dg.object; |
| 10822 | const mod = o.module; | 10892 | const mod = o.pt.zcu; |
| 10823 | return fg.air.typeOfIndex(inst, &mod.intern_pool); | 10893 | return fg.air.typeOfIndex(inst, &mod.intern_pool); |
| 10824 | } | 10894 | } |
| 10825 | }; | 10895 | }; |
| ... | @@ -10990,12 +11060,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ | ... | @@ -10990,12 +11060,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ |
| 10990 | }; | 11060 | }; |
| 10991 | } | 11061 | } |
| 10992 | 11062 | ||
| 10993 | fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool { | 11063 | fn returnTypeByRef(pt: Zcu.PerThread, target: std.Target, ty: Type) bool { |
| 10994 | if (isByRef(ty, zcu)) { | 11064 | if (isByRef(ty, pt)) { |
| 10995 | return true; | 11065 | return true; |
| 10996 | } else if (target.cpu.arch.isX86() and | 11066 | } else if (target.cpu.arch.isX86() and |
| 10997 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and | 11067 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| 10998 | ty.totalVectorBits(zcu) >= 512) | 11068 | ty.totalVectorBits(pt) >= 512) |
| 10999 | { | 11069 | { |
| 11000 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns | 11070 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| 11001 | // "512-bit vector arguments require 'evex512' for AVX512" | 11071 | // "512-bit vector arguments require 'evex512' for AVX512" |
| ... | @@ -11005,38 +11075,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool { | ... | @@ -11005,38 +11075,38 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool { |
| 11005 | } | 11075 | } |
| 11006 | } | 11076 | } |
| 11007 | 11077 | ||
| 11008 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool { | 11078 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, pt: Zcu.PerThread, target: std.Target) bool { |
| 11009 | const return_type = Type.fromInterned(fn_info.return_type); | 11079 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11010 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; | 11080 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) return false; |
| 11011 | 11081 | ||
| 11012 | return switch (fn_info.cc) { | 11082 | return switch (fn_info.cc) { |
| 11013 | .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type), | 11083 | .Unspecified, .Inline => returnTypeByRef(pt, target, return_type), |
| 11014 | .C => switch (target.cpu.arch) { | 11084 | .C => switch (target.cpu.arch) { |
| 11015 | .mips, .mipsel => false, | 11085 | .mips, .mipsel => false, |
| 11016 | .x86 => isByRef(return_type, zcu), | 11086 | .x86 => isByRef(return_type, pt), |
| 11017 | .x86_64 => switch (target.os.tag) { | 11087 | .x86_64 => switch (target.os.tag) { |
| 11018 | .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | 11088 | .windows => x86_64_abi.classifyWindows(return_type, pt) == .memory, |
| 11019 | else => firstParamSRetSystemV(return_type, zcu, target), | 11089 | else => firstParamSRetSystemV(return_type, pt, target), |
| 11020 | }, | 11090 | }, |
| 11021 | .wasm32 => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect, | 11091 | .wasm32 => wasm_c_abi.classifyType(return_type, pt)[0] == .indirect, |
| 11022 | .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, zcu) == .memory, | 11092 | .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, pt) == .memory, |
| 11023 | .arm, .armeb => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { | 11093 | .arm, .armeb => switch (arm_c_abi.classifyType(return_type, pt, .ret)) { |
| 11024 | .memory, .i64_array => true, | 11094 | .memory, .i64_array => true, |
| 11025 | .i32_array => |size| size != 1, | 11095 | .i32_array => |size| size != 1, |
| 11026 | .byval => false, | 11096 | .byval => false, |
| 11027 | }, | 11097 | }, |
| 11028 | .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, zcu) == .memory, | 11098 | .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, pt) == .memory, |
| 11029 | else => false, // TODO investigate C ABI for other architectures | 11099 | else => false, // TODO investigate C ABI for other architectures |
| 11030 | }, | 11100 | }, |
| 11031 | .SysV => firstParamSRetSystemV(return_type, zcu, target), | 11101 | .SysV => firstParamSRetSystemV(return_type, pt, target), |
| 11032 | .Win64 => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | 11102 | .Win64 => x86_64_abi.classifyWindows(return_type, pt) == .memory, |
| 11033 | .Stdcall => !isScalar(zcu, return_type), | 11103 | .Stdcall => !isScalar(pt.zcu, return_type), |
| 11034 | else => false, | 11104 | else => false, |
| 11035 | }; | 11105 | }; |
| 11036 | } | 11106 | } |
| 11037 | 11107 | ||
| 11038 | fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool { | 11108 | fn firstParamSRetSystemV(ty: Type, pt: Zcu.PerThread, target: std.Target) bool { |
| 11039 | const class = x86_64_abi.classifySystemV(ty, zcu, target, .ret); | 11109 | const class = x86_64_abi.classifySystemV(ty, pt, target, .ret); |
| 11040 | if (class[0] == .memory) return true; | 11110 | if (class[0] == .memory) return true; |
| 11041 | if (class[0] == .x87 and class[2] != .none) return true; | 11111 | if (class[0] == .x87 and class[2] != .none) return true; |
| 11042 | return false; | 11112 | return false; |
| ... | @@ -11046,9 +11116,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool { | ... | @@ -11046,9 +11116,10 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool { |
| 11046 | /// completely differently in the function prototype to honor the C ABI, and then | 11116 | /// completely differently in the function prototype to honor the C ABI, and then |
| 11047 | /// be effectively bitcasted to the actual return type. | 11117 | /// be effectively bitcasted to the actual return type. |
| 11048 | fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { | 11118 | fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11049 | const mod = o.module; | 11119 | const pt = o.pt; |
| 11120 | const mod = pt.zcu; | ||
| 11050 | const return_type = Type.fromInterned(fn_info.return_type); | 11121 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11051 | if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) { | 11122 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) { |
| 11052 | // If the return type is an error set or an error union, then we make this | 11123 | // If the return type is an error set or an error union, then we make this |
| 11053 | // anyerror return type instead, so that it can be coerced into a function | 11124 | // anyerror return type instead, so that it can be coerced into a function |
| 11054 | // pointer type which has anyerror as the return type. | 11125 | // pointer type which has anyerror as the return type. |
| ... | @@ -11058,12 +11129,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11058,12 +11129,12 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11058 | switch (fn_info.cc) { | 11129 | switch (fn_info.cc) { |
| 11059 | .Unspecified, | 11130 | .Unspecified, |
| 11060 | .Inline, | 11131 | .Inline, |
| 11061 | => return if (returnTypeByRef(mod, target, return_type)) .void else o.lowerType(return_type), | 11132 | => return if (returnTypeByRef(pt, target, return_type)) .void else o.lowerType(return_type), |
| 11062 | 11133 | ||
| 11063 | .C => { | 11134 | .C => { |
| 11064 | switch (target.cpu.arch) { | 11135 | switch (target.cpu.arch) { |
| 11065 | .mips, .mipsel => return o.lowerType(return_type), | 11136 | .mips, .mipsel => return o.lowerType(return_type), |
| 11066 | .x86 => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type), | 11137 | .x86 => return if (isByRef(return_type, pt)) .void else o.lowerType(return_type), |
| 11067 | .x86_64 => switch (target.os.tag) { | 11138 | .x86_64 => switch (target.os.tag) { |
| 11068 | .windows => return lowerWin64FnRetTy(o, fn_info), | 11139 | .windows => return lowerWin64FnRetTy(o, fn_info), |
| 11069 | else => return lowerSystemVFnRetTy(o, fn_info), | 11140 | else => return lowerSystemVFnRetTy(o, fn_info), |
| ... | @@ -11072,36 +11143,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11072,36 +11143,36 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11072 | if (isScalar(mod, return_type)) { | 11143 | if (isScalar(mod, return_type)) { |
| 11073 | return o.lowerType(return_type); | 11144 | return o.lowerType(return_type); |
| 11074 | } | 11145 | } |
| 11075 | const classes = wasm_c_abi.classifyType(return_type, mod); | 11146 | const classes = wasm_c_abi.classifyType(return_type, pt); |
| 11076 | if (classes[0] == .indirect or classes[0] == .none) { | 11147 | if (classes[0] == .indirect or classes[0] == .none) { |
| 11077 | return .void; | 11148 | return .void; |
| 11078 | } | 11149 | } |
| 11079 | 11150 | ||
| 11080 | assert(classes[0] == .direct and classes[1] == .none); | 11151 | assert(classes[0] == .direct and classes[1] == .none); |
| 11081 | const scalar_type = wasm_c_abi.scalarType(return_type, mod); | 11152 | const scalar_type = wasm_c_abi.scalarType(return_type, pt); |
| 11082 | return o.builder.intType(@intCast(scalar_type.abiSize(mod) * 8)); | 11153 | return o.builder.intType(@intCast(scalar_type.abiSize(pt) * 8)); |
| 11083 | }, | 11154 | }, |
| 11084 | .aarch64, .aarch64_be => { | 11155 | .aarch64, .aarch64_be => { |
| 11085 | switch (aarch64_c_abi.classifyType(return_type, mod)) { | 11156 | switch (aarch64_c_abi.classifyType(return_type, pt)) { |
| 11086 | .memory => return .void, | 11157 | .memory => return .void, |
| 11087 | .float_array => return o.lowerType(return_type), | 11158 | .float_array => return o.lowerType(return_type), |
| 11088 | .byval => return o.lowerType(return_type), | 11159 | .byval => return o.lowerType(return_type), |
| 11089 | .integer => return o.builder.intType(@intCast(return_type.bitSize(mod))), | 11160 | .integer => return o.builder.intType(@intCast(return_type.bitSize(pt))), |
| 11090 | .double_integer => return o.builder.arrayType(2, .i64), | 11161 | .double_integer => return o.builder.arrayType(2, .i64), |
| 11091 | } | 11162 | } |
| 11092 | }, | 11163 | }, |
| 11093 | .arm, .armeb => { | 11164 | .arm, .armeb => { |
| 11094 | switch (arm_c_abi.classifyType(return_type, mod, .ret)) { | 11165 | switch (arm_c_abi.classifyType(return_type, pt, .ret)) { |
| 11095 | .memory, .i64_array => return .void, | 11166 | .memory, .i64_array => return .void, |
| 11096 | .i32_array => |len| return if (len == 1) .i32 else .void, | 11167 | .i32_array => |len| return if (len == 1) .i32 else .void, |
| 11097 | .byval => return o.lowerType(return_type), | 11168 | .byval => return o.lowerType(return_type), |
| 11098 | } | 11169 | } |
| 11099 | }, | 11170 | }, |
| 11100 | .riscv32, .riscv64 => { | 11171 | .riscv32, .riscv64 => { |
| 11101 | switch (riscv_c_abi.classifyType(return_type, mod)) { | 11172 | switch (riscv_c_abi.classifyType(return_type, pt)) { |
| 11102 | .memory => return .void, | 11173 | .memory => return .void, |
| 11103 | .integer => { | 11174 | .integer => { |
| 11104 | return o.builder.intType(@intCast(return_type.bitSize(mod))); | 11175 | return o.builder.intType(@intCast(return_type.bitSize(pt))); |
| 11105 | }, | 11176 | }, |
| 11106 | .double_integer => { | 11177 | .double_integer => { |
| 11107 | return o.builder.structType(.normal, &.{ .i64, .i64 }); | 11178 | return o.builder.structType(.normal, &.{ .i64, .i64 }); |
| ... | @@ -11112,7 +11183,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11112,7 +11183,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11112 | var types: [8]Builder.Type = undefined; | 11183 | var types: [8]Builder.Type = undefined; |
| 11113 | for (0..return_type.structFieldCount(mod)) |field_index| { | 11184 | for (0..return_type.structFieldCount(mod)) |field_index| { |
| 11114 | const field_ty = return_type.structFieldType(field_index, mod); | 11185 | const field_ty = return_type.structFieldType(field_index, mod); |
| 11115 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 11186 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 11116 | types[types_len] = try o.lowerType(field_ty); | 11187 | types[types_len] = try o.lowerType(field_ty); |
| 11117 | types_len += 1; | 11188 | types_len += 1; |
| 11118 | } | 11189 | } |
| ... | @@ -11132,14 +11203,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11132,14 +11203,14 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11132 | } | 11203 | } |
| 11133 | 11204 | ||
| 11134 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { | 11205 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11135 | const mod = o.module; | 11206 | const pt = o.pt; |
| 11136 | const return_type = Type.fromInterned(fn_info.return_type); | 11207 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11137 | switch (x86_64_abi.classifyWindows(return_type, mod)) { | 11208 | switch (x86_64_abi.classifyWindows(return_type, pt)) { |
| 11138 | .integer => { | 11209 | .integer => { |
| 11139 | if (isScalar(mod, return_type)) { | 11210 | if (isScalar(pt.zcu, return_type)) { |
| 11140 | return o.lowerType(return_type); | 11211 | return o.lowerType(return_type); |
| 11141 | } else { | 11212 | } else { |
| 11142 | return o.builder.intType(@intCast(return_type.abiSize(mod) * 8)); | 11213 | return o.builder.intType(@intCast(return_type.abiSize(pt) * 8)); |
| 11143 | } | 11214 | } |
| 11144 | }, | 11215 | }, |
| 11145 | .win_i128 => return o.builder.vectorType(.normal, 2, .i64), | 11216 | .win_i128 => return o.builder.vectorType(.normal, 2, .i64), |
| ... | @@ -11150,14 +11221,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err | ... | @@ -11150,14 +11221,15 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err |
| 11150 | } | 11221 | } |
| 11151 | 11222 | ||
| 11152 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { | 11223 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11153 | const mod = o.module; | 11224 | const pt = o.pt; |
| 11225 | const mod = pt.zcu; | ||
| 11154 | const ip = &mod.intern_pool; | 11226 | const ip = &mod.intern_pool; |
| 11155 | const return_type = Type.fromInterned(fn_info.return_type); | 11227 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11156 | if (isScalar(mod, return_type)) { | 11228 | if (isScalar(mod, return_type)) { |
| 11157 | return o.lowerType(return_type); | 11229 | return o.lowerType(return_type); |
| 11158 | } | 11230 | } |
| 11159 | const target = mod.getTarget(); | 11231 | const target = mod.getTarget(); |
| 11160 | const classes = x86_64_abi.classifySystemV(return_type, mod, target, .ret); | 11232 | const classes = x86_64_abi.classifySystemV(return_type, pt, target, .ret); |
| 11161 | if (classes[0] == .memory) return .void; | 11233 | if (classes[0] == .memory) return .void; |
| 11162 | var types_index: u32 = 0; | 11234 | var types_index: u32 = 0; |
| 11163 | var types_buffer: [8]Builder.Type = undefined; | 11235 | var types_buffer: [8]Builder.Type = undefined; |
| ... | @@ -11249,8 +11321,7 @@ const ParamTypeIterator = struct { | ... | @@ -11249,8 +11321,7 @@ const ParamTypeIterator = struct { |
| 11249 | 11321 | ||
| 11250 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { | 11322 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { |
| 11251 | if (it.zig_index >= it.fn_info.param_types.len) return null; | 11323 | if (it.zig_index >= it.fn_info.param_types.len) return null; |
| 11252 | const zcu = it.object.module; | 11324 | const ip = &it.object.pt.zcu.intern_pool; |
| 11253 | const ip = &zcu.intern_pool; | ||
| 11254 | const ty = it.fn_info.param_types.get(ip)[it.zig_index]; | 11325 | const ty = it.fn_info.param_types.get(ip)[it.zig_index]; |
| 11255 | it.byval_attr = false; | 11326 | it.byval_attr = false; |
| 11256 | return nextInner(it, Type.fromInterned(ty)); | 11327 | return nextInner(it, Type.fromInterned(ty)); |
| ... | @@ -11258,8 +11329,7 @@ const ParamTypeIterator = struct { | ... | @@ -11258,8 +11329,7 @@ const ParamTypeIterator = struct { |
| 11258 | 11329 | ||
| 11259 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. | 11330 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. |
| 11260 | pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering { | 11331 | pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering { |
| 11261 | const zcu = it.object.module; | 11332 | const ip = &it.object.pt.zcu.intern_pool; |
| 11262 | const ip = &zcu.intern_pool; | ||
| 11263 | if (it.zig_index >= it.fn_info.param_types.len) { | 11333 | if (it.zig_index >= it.fn_info.param_types.len) { |
| 11264 | if (it.zig_index >= args.len) { | 11334 | if (it.zig_index >= args.len) { |
| 11265 | return null; | 11335 | return null; |
| ... | @@ -11272,10 +11342,11 @@ const ParamTypeIterator = struct { | ... | @@ -11272,10 +11342,11 @@ const ParamTypeIterator = struct { |
| 11272 | } | 11342 | } |
| 11273 | 11343 | ||
| 11274 | fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { | 11344 | fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 11275 | const zcu = it.object.module; | 11345 | const pt = it.object.pt; |
| 11346 | const zcu = pt.zcu; | ||
| 11276 | const target = zcu.getTarget(); | 11347 | const target = zcu.getTarget(); |
| 11277 | 11348 | ||
| 11278 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 11349 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 11279 | it.zig_index += 1; | 11350 | it.zig_index += 1; |
| 11280 | return .no_bits; | 11351 | return .no_bits; |
| 11281 | } | 11352 | } |
| ... | @@ -11288,11 +11359,11 @@ const ParamTypeIterator = struct { | ... | @@ -11288,11 +11359,11 @@ const ParamTypeIterator = struct { |
| 11288 | { | 11359 | { |
| 11289 | it.llvm_index += 1; | 11360 | it.llvm_index += 1; |
| 11290 | return .slice; | 11361 | return .slice; |
| 11291 | } else if (isByRef(ty, zcu)) { | 11362 | } else if (isByRef(ty, pt)) { |
| 11292 | return .byref; | 11363 | return .byref; |
| 11293 | } else if (target.cpu.arch.isX86() and | 11364 | } else if (target.cpu.arch.isX86() and |
| 11294 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and | 11365 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| 11295 | ty.totalVectorBits(zcu) >= 512) | 11366 | ty.totalVectorBits(pt) >= 512) |
| 11296 | { | 11367 | { |
| 11297 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns | 11368 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| 11298 | // "512-bit vector arguments require 'evex512' for AVX512" | 11369 | // "512-bit vector arguments require 'evex512' for AVX512" |
| ... | @@ -11320,7 +11391,7 @@ const ParamTypeIterator = struct { | ... | @@ -11320,7 +11391,7 @@ const ParamTypeIterator = struct { |
| 11320 | if (isScalar(zcu, ty)) { | 11391 | if (isScalar(zcu, ty)) { |
| 11321 | return .byval; | 11392 | return .byval; |
| 11322 | } | 11393 | } |
| 11323 | const classes = wasm_c_abi.classifyType(ty, zcu); | 11394 | const classes = wasm_c_abi.classifyType(ty, pt); |
| 11324 | if (classes[0] == .indirect) { | 11395 | if (classes[0] == .indirect) { |
| 11325 | return .byref; | 11396 | return .byref; |
| 11326 | } | 11397 | } |
| ... | @@ -11329,7 +11400,7 @@ const ParamTypeIterator = struct { | ... | @@ -11329,7 +11400,7 @@ const ParamTypeIterator = struct { |
| 11329 | .aarch64, .aarch64_be => { | 11400 | .aarch64, .aarch64_be => { |
| 11330 | it.zig_index += 1; | 11401 | it.zig_index += 1; |
| 11331 | it.llvm_index += 1; | 11402 | it.llvm_index += 1; |
| 11332 | switch (aarch64_c_abi.classifyType(ty, zcu)) { | 11403 | switch (aarch64_c_abi.classifyType(ty, pt)) { |
| 11333 | .memory => return .byref_mut, | 11404 | .memory => return .byref_mut, |
| 11334 | .float_array => |len| return Lowering{ .float_array = len }, | 11405 | .float_array => |len| return Lowering{ .float_array = len }, |
| 11335 | .byval => return .byval, | 11406 | .byval => return .byval, |
| ... | @@ -11344,7 +11415,7 @@ const ParamTypeIterator = struct { | ... | @@ -11344,7 +11415,7 @@ const ParamTypeIterator = struct { |
| 11344 | .arm, .armeb => { | 11415 | .arm, .armeb => { |
| 11345 | it.zig_index += 1; | 11416 | it.zig_index += 1; |
| 11346 | it.llvm_index += 1; | 11417 | it.llvm_index += 1; |
| 11347 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { | 11418 | switch (arm_c_abi.classifyType(ty, pt, .arg)) { |
| 11348 | .memory => { | 11419 | .memory => { |
| 11349 | it.byval_attr = true; | 11420 | it.byval_attr = true; |
| 11350 | return .byref; | 11421 | return .byref; |
| ... | @@ -11359,7 +11430,7 @@ const ParamTypeIterator = struct { | ... | @@ -11359,7 +11430,7 @@ const ParamTypeIterator = struct { |
| 11359 | it.llvm_index += 1; | 11430 | it.llvm_index += 1; |
| 11360 | if (ty.toIntern() == .f16_type and | 11431 | if (ty.toIntern() == .f16_type and |
| 11361 | !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16; | 11432 | !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16; |
| 11362 | switch (riscv_c_abi.classifyType(ty, zcu)) { | 11433 | switch (riscv_c_abi.classifyType(ty, pt)) { |
| 11363 | .memory => return .byref_mut, | 11434 | .memory => return .byref_mut, |
| 11364 | .byval => return .byval, | 11435 | .byval => return .byval, |
| 11365 | .integer => return .abi_sized_int, | 11436 | .integer => return .abi_sized_int, |
| ... | @@ -11368,7 +11439,7 @@ const ParamTypeIterator = struct { | ... | @@ -11368,7 +11439,7 @@ const ParamTypeIterator = struct { |
| 11368 | it.types_len = 0; | 11439 | it.types_len = 0; |
| 11369 | for (0..ty.structFieldCount(zcu)) |field_index| { | 11440 | for (0..ty.structFieldCount(zcu)) |field_index| { |
| 11370 | const field_ty = ty.structFieldType(field_index, zcu); | 11441 | const field_ty = ty.structFieldType(field_index, zcu); |
| 11371 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 11442 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 11372 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty); | 11443 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty); |
| 11373 | it.types_len += 1; | 11444 | it.types_len += 1; |
| 11374 | } | 11445 | } |
| ... | @@ -11406,10 +11477,10 @@ const ParamTypeIterator = struct { | ... | @@ -11406,10 +11477,10 @@ const ParamTypeIterator = struct { |
| 11406 | } | 11477 | } |
| 11407 | 11478 | ||
| 11408 | fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { | 11479 | fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { |
| 11409 | const zcu = it.object.module; | 11480 | const pt = it.object.pt; |
| 11410 | switch (x86_64_abi.classifyWindows(ty, zcu)) { | 11481 | switch (x86_64_abi.classifyWindows(ty, pt)) { |
| 11411 | .integer => { | 11482 | .integer => { |
| 11412 | if (isScalar(zcu, ty)) { | 11483 | if (isScalar(pt.zcu, ty)) { |
| 11413 | it.zig_index += 1; | 11484 | it.zig_index += 1; |
| 11414 | it.llvm_index += 1; | 11485 | it.llvm_index += 1; |
| 11415 | return .byval; | 11486 | return .byval; |
| ... | @@ -11439,17 +11510,17 @@ const ParamTypeIterator = struct { | ... | @@ -11439,17 +11510,17 @@ const ParamTypeIterator = struct { |
| 11439 | } | 11510 | } |
| 11440 | 11511 | ||
| 11441 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { | 11512 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 11442 | const zcu = it.object.module; | 11513 | const pt = it.object.pt; |
| 11443 | const ip = &zcu.intern_pool; | 11514 | const ip = &pt.zcu.intern_pool; |
| 11444 | const target = zcu.getTarget(); | 11515 | const target = pt.zcu.getTarget(); |
| 11445 | const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg); | 11516 | const classes = x86_64_abi.classifySystemV(ty, pt, target, .arg); |
| 11446 | if (classes[0] == .memory) { | 11517 | if (classes[0] == .memory) { |
| 11447 | it.zig_index += 1; | 11518 | it.zig_index += 1; |
| 11448 | it.llvm_index += 1; | 11519 | it.llvm_index += 1; |
| 11449 | it.byval_attr = true; | 11520 | it.byval_attr = true; |
| 11450 | return .byref; | 11521 | return .byref; |
| 11451 | } | 11522 | } |
| 11452 | if (isScalar(zcu, ty)) { | 11523 | if (isScalar(pt.zcu, ty)) { |
| 11453 | it.zig_index += 1; | 11524 | it.zig_index += 1; |
| 11454 | it.llvm_index += 1; | 11525 | it.llvm_index += 1; |
| 11455 | return .byval; | 11526 | return .byval; |
| ... | @@ -11550,7 +11621,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp | ... | @@ -11550,7 +11621,7 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp |
| 11550 | 11621 | ||
| 11551 | fn ccAbiPromoteInt( | 11622 | fn ccAbiPromoteInt( |
| 11552 | cc: std.builtin.CallingConvention, | 11623 | cc: std.builtin.CallingConvention, |
| 11553 | mod: *Module, | 11624 | mod: *Zcu, |
| 11554 | ty: Type, | 11625 | ty: Type, |
| 11555 | ) ?std.builtin.Signedness { | 11626 | ) ?std.builtin.Signedness { |
| 11556 | const target = mod.getTarget(); | 11627 | const target = mod.getTarget(); |
| ... | @@ -11598,13 +11669,13 @@ fn ccAbiPromoteInt( | ... | @@ -11598,13 +11669,13 @@ fn ccAbiPromoteInt( |
| 11598 | 11669 | ||
| 11599 | /// This is the one source of truth for whether a type is passed around as an LLVM pointer, | 11670 | /// This is the one source of truth for whether a type is passed around as an LLVM pointer, |
| 11600 | /// or as an LLVM value. | 11671 | /// or as an LLVM value. |
| 11601 | fn isByRef(ty: Type, mod: *Module) bool { | 11672 | fn isByRef(ty: Type, pt: Zcu.PerThread) bool { |
| 11602 | // For tuples and structs, if there are more than this many non-void | 11673 | // For tuples and structs, if there are more than this many non-void |
| 11603 | // fields, then we make it byref, otherwise byval. | 11674 | // fields, then we make it byref, otherwise byval. |
| 11604 | const max_fields_byval = 0; | 11675 | const max_fields_byval = 0; |
| 11605 | const ip = &mod.intern_pool; | 11676 | const ip = &pt.zcu.intern_pool; |
| 11606 | 11677 | ||
| 11607 | switch (ty.zigTypeTag(mod)) { | 11678 | switch (ty.zigTypeTag(pt.zcu)) { |
| 11608 | .Type, | 11679 | .Type, |
| 11609 | .ComptimeInt, | 11680 | .ComptimeInt, |
| 11610 | .ComptimeFloat, | 11681 | .ComptimeFloat, |
| ... | @@ -11627,17 +11698,17 @@ fn isByRef(ty: Type, mod: *Module) bool { | ... | @@ -11627,17 +11698,17 @@ fn isByRef(ty: Type, mod: *Module) bool { |
| 11627 | .AnyFrame, | 11698 | .AnyFrame, |
| 11628 | => return false, | 11699 | => return false, |
| 11629 | 11700 | ||
| 11630 | .Array, .Frame => return ty.hasRuntimeBits(mod), | 11701 | .Array, .Frame => return ty.hasRuntimeBits(pt), |
| 11631 | .Struct => { | 11702 | .Struct => { |
| 11632 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { | 11703 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { |
| 11633 | .anon_struct_type => |tuple| { | 11704 | .anon_struct_type => |tuple| { |
| 11634 | var count: usize = 0; | 11705 | var count: usize = 0; |
| 11635 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { | 11706 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 11636 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 11707 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 11637 | 11708 | ||
| 11638 | count += 1; | 11709 | count += 1; |
| 11639 | if (count > max_fields_byval) return true; | 11710 | if (count > max_fields_byval) return true; |
| 11640 | if (isByRef(Type.fromInterned(field_ty), mod)) return true; | 11711 | if (isByRef(Type.fromInterned(field_ty), pt)) return true; |
| 11641 | } | 11712 | } |
| 11642 | return false; | 11713 | return false; |
| 11643 | }, | 11714 | }, |
| ... | @@ -11655,27 +11726,27 @@ fn isByRef(ty: Type, mod: *Module) bool { | ... | @@ -11655,27 +11726,27 @@ fn isByRef(ty: Type, mod: *Module) bool { |
| 11655 | count += 1; | 11726 | count += 1; |
| 11656 | if (count > max_fields_byval) return true; | 11727 | if (count > max_fields_byval) return true; |
| 11657 | const field_ty = Type.fromInterned(field_types[field_index]); | 11728 | const field_ty = Type.fromInterned(field_types[field_index]); |
| 11658 | if (isByRef(field_ty, mod)) return true; | 11729 | if (isByRef(field_ty, pt)) return true; |
| 11659 | } | 11730 | } |
| 11660 | return false; | 11731 | return false; |
| 11661 | }, | 11732 | }, |
| 11662 | .Union => switch (ty.containerLayout(mod)) { | 11733 | .Union => switch (ty.containerLayout(pt.zcu)) { |
| 11663 | .@"packed" => return false, | 11734 | .@"packed" => return false, |
| 11664 | else => return ty.hasRuntimeBits(mod), | 11735 | else => return ty.hasRuntimeBits(pt), |
| 11665 | }, | 11736 | }, |
| 11666 | .ErrorUnion => { | 11737 | .ErrorUnion => { |
| 11667 | const payload_ty = ty.errorUnionPayload(mod); | 11738 | const payload_ty = ty.errorUnionPayload(pt.zcu); |
| 11668 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 11739 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 11669 | return false; | 11740 | return false; |
| 11670 | } | 11741 | } |
| 11671 | return true; | 11742 | return true; |
| 11672 | }, | 11743 | }, |
| 11673 | .Optional => { | 11744 | .Optional => { |
| 11674 | const payload_ty = ty.optionalChild(mod); | 11745 | const payload_ty = ty.optionalChild(pt.zcu); |
| 11675 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 11746 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 11676 | return false; | 11747 | return false; |
| 11677 | } | 11748 | } |
| 11678 | if (ty.optionalReprIsPayload(mod)) { | 11749 | if (ty.optionalReprIsPayload(pt.zcu)) { |
| 11679 | return false; | 11750 | return false; |
| 11680 | } | 11751 | } |
| 11681 | return true; | 11752 | return true; |
| ... | @@ -11683,7 +11754,7 @@ fn isByRef(ty: Type, mod: *Module) bool { | ... | @@ -11683,7 +11754,7 @@ fn isByRef(ty: Type, mod: *Module) bool { |
| 11683 | } | 11754 | } |
| 11684 | } | 11755 | } |
| 11685 | 11756 | ||
| 11686 | fn isScalar(mod: *Module, ty: Type) bool { | 11757 | fn isScalar(mod: *Zcu, ty: Type) bool { |
| 11687 | return switch (ty.zigTypeTag(mod)) { | 11758 | return switch (ty.zigTypeTag(mod)) { |
| 11688 | .Void, | 11759 | .Void, |
| 11689 | .Bool, | 11760 | .Bool, |
| ... | @@ -11774,7 +11845,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len"; | ... | @@ -11774,7 +11845,7 @@ const lt_errors_fn_name = "__zig_lt_errors_len"; |
| 11774 | /// Without this workaround, LLVM crashes with "unknown codeview register H1" | 11845 | /// Without this workaround, LLVM crashes with "unknown codeview register H1" |
| 11775 | /// https://github.com/llvm/llvm-project/issues/56484 | 11846 | /// https://github.com/llvm/llvm-project/issues/56484 |
| 11776 | fn needDbgVarWorkaround(o: *Object) bool { | 11847 | fn needDbgVarWorkaround(o: *Object) bool { |
| 11777 | const target = o.module.getTarget(); | 11848 | const target = o.pt.zcu.getTarget(); |
| 11778 | if (target.os.tag == .windows and target.cpu.arch == .aarch64) { | 11849 | if (target.os.tag == .windows and target.cpu.arch == .aarch64) { |
| 11779 | return true; | 11850 | return true; |
| 11780 | } | 11851 | } |
| ... | @@ -11817,14 +11888,14 @@ fn buildAllocaInner( | ... | @@ -11817,14 +11888,14 @@ fn buildAllocaInner( |
| 11817 | return wip.conv(.unneeded, alloca, .ptr, ""); | 11888 | return wip.conv(.unneeded, alloca, .ptr, ""); |
| 11818 | } | 11889 | } |
| 11819 | 11890 | ||
| 11820 | fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) !u1 { | 11891 | fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 { |
| 11821 | const err_int_ty = try mod.errorIntType(); | 11892 | const err_int_ty = try pt.errorIntType(); |
| 11822 | return @intFromBool(err_int_ty.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod))); | 11893 | return @intFromBool(err_int_ty.abiAlignment(pt).compare(.gt, payload_ty.abiAlignment(pt))); |
| 11823 | } | 11894 | } |
| 11824 | 11895 | ||
| 11825 | fn errUnionErrorOffset(payload_ty: Type, mod: *Module) !u1 { | 11896 | fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 { |
| 11826 | const err_int_ty = try mod.errorIntType(); | 11897 | const err_int_ty = try pt.errorIntType(); |
| 11827 | return @intFromBool(err_int_ty.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod))); | 11898 | return @intFromBool(err_int_ty.abiAlignment(pt).compare(.lte, payload_ty.abiAlignment(pt))); |
| 11828 | } | 11899 | } |
| 11829 | 11900 | ||
| 11830 | /// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location | 11901 | /// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location |
src/codegen/spirv.zig+239-211| ... | @@ -6,9 +6,7 @@ const assert = std.debug.assert; | ... | @@ -6,9 +6,7 @@ const assert = std.debug.assert; |
| 6 | const Signedness = std.builtin.Signedness; | 6 | const Signedness = std.builtin.Signedness; |
| 7 | 7 | ||
| 8 | const Zcu = @import("../Zcu.zig"); | 8 | const Zcu = @import("../Zcu.zig"); |
| 9 | /// Deprecated. | 9 | const Decl = Zcu.Decl; |
| 10 | const Module = Zcu; | ||
| 11 | const Decl = Module.Decl; | ||
| 12 | const Type = @import("../Type.zig"); | 10 | const Type = @import("../Type.zig"); |
| 13 | const Value = @import("../Value.zig"); | 11 | const Value = @import("../Value.zig"); |
| 14 | const Air = @import("../Air.zig"); | 12 | const Air = @import("../Air.zig"); |
| ... | @@ -188,12 +186,13 @@ pub const Object = struct { | ... | @@ -188,12 +186,13 @@ pub const Object = struct { |
| 188 | 186 | ||
| 189 | fn genDecl( | 187 | fn genDecl( |
| 190 | self: *Object, | 188 | self: *Object, |
| 191 | zcu: *Zcu, | 189 | pt: Zcu.PerThread, |
| 192 | decl_index: InternPool.DeclIndex, | 190 | decl_index: InternPool.DeclIndex, |
| 193 | air: Air, | 191 | air: Air, |
| 194 | liveness: Liveness, | 192 | liveness: Liveness, |
| 195 | ) !void { | 193 | ) !void { |
| 196 | const gpa = self.gpa; | 194 | const zcu = pt.zcu; |
| 195 | const gpa = zcu.gpa; | ||
| 197 | const decl = zcu.declPtr(decl_index); | 196 | const decl = zcu.declPtr(decl_index); |
| 198 | const namespace = zcu.namespacePtr(decl.src_namespace); | 197 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 199 | const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg; | 198 | const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg; |
| ... | @@ -201,7 +200,7 @@ pub const Object = struct { | ... | @@ -201,7 +200,7 @@ pub const Object = struct { |
| 201 | var decl_gen = DeclGen{ | 200 | var decl_gen = DeclGen{ |
| 202 | .gpa = gpa, | 201 | .gpa = gpa, |
| 203 | .object = self, | 202 | .object = self, |
| 204 | .module = zcu, | 203 | .pt = pt, |
| 205 | .spv = &self.spv, | 204 | .spv = &self.spv, |
| 206 | .decl_index = decl_index, | 205 | .decl_index = decl_index, |
| 207 | .air = air, | 206 | .air = air, |
| ... | @@ -235,34 +234,34 @@ pub const Object = struct { | ... | @@ -235,34 +234,34 @@ pub const Object = struct { |
| 235 | 234 | ||
| 236 | pub fn updateFunc( | 235 | pub fn updateFunc( |
| 237 | self: *Object, | 236 | self: *Object, |
| 238 | mod: *Module, | 237 | pt: Zcu.PerThread, |
| 239 | func_index: InternPool.Index, | 238 | func_index: InternPool.Index, |
| 240 | air: Air, | 239 | air: Air, |
| 241 | liveness: Liveness, | 240 | liveness: Liveness, |
| 242 | ) !void { | 241 | ) !void { |
| 243 | const decl_index = mod.funcInfo(func_index).owner_decl; | 242 | const decl_index = pt.zcu.funcInfo(func_index).owner_decl; |
| 244 | // TODO: Separate types for generating decls and functions? | 243 | // TODO: Separate types for generating decls and functions? |
| 245 | try self.genDecl(mod, decl_index, air, liveness); | 244 | try self.genDecl(pt, decl_index, air, liveness); |
| 246 | } | 245 | } |
| 247 | 246 | ||
| 248 | pub fn updateDecl( | 247 | pub fn updateDecl( |
| 249 | self: *Object, | 248 | self: *Object, |
| 250 | mod: *Module, | 249 | pt: Zcu.PerThread, |
| 251 | decl_index: InternPool.DeclIndex, | 250 | decl_index: InternPool.DeclIndex, |
| 252 | ) !void { | 251 | ) !void { |
| 253 | try self.genDecl(mod, decl_index, undefined, undefined); | 252 | try self.genDecl(pt, decl_index, undefined, undefined); |
| 254 | } | 253 | } |
| 255 | 254 | ||
| 256 | /// Fetch or allocate a result id for decl index. This function also marks the decl as alive. | 255 | /// Fetch or allocate a result id for decl index. This function also marks the decl as alive. |
| 257 | /// Note: Function does not actually generate the decl, it just allocates an index. | 256 | /// Note: Function does not actually generate the decl, it just allocates an index. |
| 258 | pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index { | 257 | pub fn resolveDecl(self: *Object, zcu: *Zcu, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index { |
| 259 | const decl = mod.declPtr(decl_index); | 258 | const decl = zcu.declPtr(decl_index); |
| 260 | assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false? | 259 | assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false? |
| 261 | 260 | ||
| 262 | const entry = try self.decl_link.getOrPut(self.gpa, decl_index); | 261 | const entry = try self.decl_link.getOrPut(self.gpa, decl_index); |
| 263 | if (!entry.found_existing) { | 262 | if (!entry.found_existing) { |
| 264 | // TODO: Extern fn? | 263 | // TODO: Extern fn? |
| 265 | const kind: SpvModule.Decl.Kind = if (decl.val.isFuncBody(mod)) | 264 | const kind: SpvModule.Decl.Kind = if (decl.val.isFuncBody(zcu)) |
| 266 | .func | 265 | .func |
| 267 | else switch (decl.@"addrspace") { | 266 | else switch (decl.@"addrspace") { |
| 268 | .generic => .invocation_global, | 267 | .generic => .invocation_global, |
| ... | @@ -285,7 +284,7 @@ const DeclGen = struct { | ... | @@ -285,7 +284,7 @@ const DeclGen = struct { |
| 285 | object: *Object, | 284 | object: *Object, |
| 286 | 285 | ||
| 287 | /// The Zig module that we are generating decls for. | 286 | /// The Zig module that we are generating decls for. |
| 288 | module: *Module, | 287 | pt: Zcu.PerThread, |
| 289 | 288 | ||
| 290 | /// The SPIR-V module that instructions should be emitted into. | 289 | /// The SPIR-V module that instructions should be emitted into. |
| 291 | /// This is the same as `self.object.spv`, repeated here for brevity. | 290 | /// This is the same as `self.object.spv`, repeated here for brevity. |
| ... | @@ -333,7 +332,7 @@ const DeclGen = struct { | ... | @@ -333,7 +332,7 @@ const DeclGen = struct { |
| 333 | 332 | ||
| 334 | /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message. | 333 | /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message. |
| 335 | /// Memory is owned by `module.gpa`. | 334 | /// Memory is owned by `module.gpa`. |
| 336 | error_msg: ?*Module.ErrorMsg = null, | 335 | error_msg: ?*Zcu.ErrorMsg = null, |
| 337 | 336 | ||
| 338 | /// Possible errors the `genDecl` function may return. | 337 | /// Possible errors the `genDecl` function may return. |
| 339 | const Error = error{ CodegenFail, OutOfMemory }; | 338 | const Error = error{ CodegenFail, OutOfMemory }; |
| ... | @@ -410,15 +409,15 @@ const DeclGen = struct { | ... | @@ -410,15 +409,15 @@ const DeclGen = struct { |
| 410 | 409 | ||
| 411 | /// Return the target which we are currently compiling for. | 410 | /// Return the target which we are currently compiling for. |
| 412 | pub fn getTarget(self: *DeclGen) std.Target { | 411 | pub fn getTarget(self: *DeclGen) std.Target { |
| 413 | return self.module.getTarget(); | 412 | return self.pt.zcu.getTarget(); |
| 414 | } | 413 | } |
| 415 | 414 | ||
| 416 | pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error { | 415 | pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error { |
| 417 | @setCold(true); | 416 | @setCold(true); |
| 418 | const mod = self.module; | 417 | const zcu = self.pt.zcu; |
| 419 | const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod); | 418 | const src_loc = zcu.declPtr(self.decl_index).navSrcLoc(zcu); |
| 420 | assert(self.error_msg == null); | 419 | assert(self.error_msg == null); |
| 421 | self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args); | 420 | self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args); |
| 422 | return error.CodegenFail; | 421 | return error.CodegenFail; |
| 423 | } | 422 | } |
| 424 | 423 | ||
| ... | @@ -439,8 +438,9 @@ const DeclGen = struct { | ... | @@ -439,8 +438,9 @@ const DeclGen = struct { |
| 439 | 438 | ||
| 440 | /// Fetch the result-id for a previously generated instruction or constant. | 439 | /// Fetch the result-id for a previously generated instruction or constant. |
| 441 | fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef { | 440 | fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef { |
| 442 | const mod = self.module; | 441 | const pt = self.pt; |
| 443 | if (try self.air.value(inst, mod)) |val| { | 442 | const mod = pt.zcu; |
| 443 | if (try self.air.value(inst, pt)) |val| { | ||
| 444 | const ty = self.typeOf(inst); | 444 | const ty = self.typeOf(inst); |
| 445 | if (ty.zigTypeTag(mod) == .Fn) { | 445 | if (ty.zigTypeTag(mod) == .Fn) { |
| 446 | const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) { | 446 | const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| ... | @@ -462,7 +462,7 @@ const DeclGen = struct { | ... | @@ -462,7 +462,7 @@ const DeclGen = struct { |
| 462 | fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef { | 462 | fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef { |
| 463 | // TODO: This cannot be a function at this point, but it should probably be handled anyway. | 463 | // TODO: This cannot be a function at this point, but it should probably be handled anyway. |
| 464 | 464 | ||
| 465 | const mod = self.module; | 465 | const mod = self.pt.zcu; |
| 466 | const ty = Type.fromInterned(mod.intern_pool.typeOf(val)); | 466 | const ty = Type.fromInterned(mod.intern_pool.typeOf(val)); |
| 467 | const decl_ptr_ty_id = try self.ptrType(ty, .Generic); | 467 | const decl_ptr_ty_id = try self.ptrType(ty, .Generic); |
| 468 | 468 | ||
| ... | @@ -642,7 +642,7 @@ const DeclGen = struct { | ... | @@ -642,7 +642,7 @@ const DeclGen = struct { |
| 642 | 642 | ||
| 643 | /// Checks whether the type can be directly translated to SPIR-V vectors | 643 | /// Checks whether the type can be directly translated to SPIR-V vectors |
| 644 | fn isSpvVector(self: *DeclGen, ty: Type) bool { | 644 | fn isSpvVector(self: *DeclGen, ty: Type) bool { |
| 645 | const mod = self.module; | 645 | const mod = self.pt.zcu; |
| 646 | const target = self.getTarget(); | 646 | const target = self.getTarget(); |
| 647 | if (ty.zigTypeTag(mod) != .Vector) return false; | 647 | if (ty.zigTypeTag(mod) != .Vector) return false; |
| 648 | 648 | ||
| ... | @@ -668,7 +668,7 @@ const DeclGen = struct { | ... | @@ -668,7 +668,7 @@ const DeclGen = struct { |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo { | 670 | fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo { |
| 671 | const mod = self.module; | 671 | const mod = self.pt.zcu; |
| 672 | const target = self.getTarget(); | 672 | const target = self.getTarget(); |
| 673 | var scalar_ty = ty.scalarType(mod); | 673 | var scalar_ty = ty.scalarType(mod); |
| 674 | if (scalar_ty.zigTypeTag(mod) == .Enum) { | 674 | if (scalar_ty.zigTypeTag(mod) == .Enum) { |
| ... | @@ -744,7 +744,7 @@ const DeclGen = struct { | ... | @@ -744,7 +744,7 @@ const DeclGen = struct { |
| 744 | /// the value to an unsigned int first for Kernels. | 744 | /// the value to an unsigned int first for Kernels. |
| 745 | fn constInt(self: *DeclGen, ty: Type, value: anytype, repr: Repr) !IdRef { | 745 | fn constInt(self: *DeclGen, ty: Type, value: anytype, repr: Repr) !IdRef { |
| 746 | // TODO: Cache? | 746 | // TODO: Cache? |
| 747 | const mod = self.module; | 747 | const mod = self.pt.zcu; |
| 748 | const scalar_ty = ty.scalarType(mod); | 748 | const scalar_ty = ty.scalarType(mod); |
| 749 | const int_info = scalar_ty.intInfo(mod); | 749 | const int_info = scalar_ty.intInfo(mod); |
| 750 | // Use backing bits so that negatives are sign extended | 750 | // Use backing bits so that negatives are sign extended |
| ... | @@ -824,7 +824,7 @@ const DeclGen = struct { | ... | @@ -824,7 +824,7 @@ const DeclGen = struct { |
| 824 | /// Construct a vector at runtime. | 824 | /// Construct a vector at runtime. |
| 825 | /// ty must be an vector type. | 825 | /// ty must be an vector type. |
| 826 | fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | 826 | fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| 827 | const mod = self.module; | 827 | const mod = self.pt.zcu; |
| 828 | assert(ty.vectorLen(mod) == constituents.len); | 828 | assert(ty.vectorLen(mod) == constituents.len); |
| 829 | 829 | ||
| 830 | // Note: older versions of the Khronos SPRIV-LLVM translator crash on this instruction | 830 | // Note: older versions of the Khronos SPRIV-LLVM translator crash on this instruction |
| ... | @@ -848,7 +848,7 @@ const DeclGen = struct { | ... | @@ -848,7 +848,7 @@ const DeclGen = struct { |
| 848 | /// Construct a vector at runtime with all lanes set to the same value. | 848 | /// Construct a vector at runtime with all lanes set to the same value. |
| 849 | /// ty must be an vector type. | 849 | /// ty must be an vector type. |
| 850 | fn constructVectorSplat(self: *DeclGen, ty: Type, constituent: IdRef) !IdRef { | 850 | fn constructVectorSplat(self: *DeclGen, ty: Type, constituent: IdRef) !IdRef { |
| 851 | const mod = self.module; | 851 | const mod = self.pt.zcu; |
| 852 | const n = ty.vectorLen(mod); | 852 | const n = ty.vectorLen(mod); |
| 853 | 853 | ||
| 854 | const constituents = try self.gpa.alloc(IdRef, n); | 854 | const constituents = try self.gpa.alloc(IdRef, n); |
| ... | @@ -886,12 +886,13 @@ const DeclGen = struct { | ... | @@ -886,12 +886,13 @@ const DeclGen = struct { |
| 886 | return id; | 886 | return id; |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | const mod = self.module; | 889 | const pt = self.pt; |
| 890 | const mod = pt.zcu; | ||
| 890 | const target = self.getTarget(); | 891 | const target = self.getTarget(); |
| 891 | const result_ty_id = try self.resolveType(ty, repr); | 892 | const result_ty_id = try self.resolveType(ty, repr); |
| 892 | const ip = &mod.intern_pool; | 893 | const ip = &mod.intern_pool; |
| 893 | 894 | ||
| 894 | log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod, null) }); | 895 | log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(pt), val.fmtValue(pt, null) }); |
| 895 | if (val.isUndefDeep(mod)) { | 896 | if (val.isUndefDeep(mod)) { |
| 896 | return self.spv.constUndef(result_ty_id); | 897 | return self.spv.constUndef(result_ty_id); |
| 897 | } | 898 | } |
| ... | @@ -940,16 +941,16 @@ const DeclGen = struct { | ... | @@ -940,16 +941,16 @@ const DeclGen = struct { |
| 940 | }, | 941 | }, |
| 941 | .int => { | 942 | .int => { |
| 942 | if (ty.isSignedInt(mod)) { | 943 | if (ty.isSignedInt(mod)) { |
| 943 | break :cache try self.constInt(ty, val.toSignedInt(mod), repr); | 944 | break :cache try self.constInt(ty, val.toSignedInt(pt), repr); |
| 944 | } else { | 945 | } else { |
| 945 | break :cache try self.constInt(ty, val.toUnsignedInt(mod), repr); | 946 | break :cache try self.constInt(ty, val.toUnsignedInt(pt), repr); |
| 946 | } | 947 | } |
| 947 | }, | 948 | }, |
| 948 | .float => { | 949 | .float => { |
| 949 | const lit: spec.LiteralContextDependentNumber = switch (ty.floatBits(target)) { | 950 | const lit: spec.LiteralContextDependentNumber = switch (ty.floatBits(target)) { |
| 950 | 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, mod))) }, | 951 | 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, pt))) }, |
| 951 | 32 => .{ .float32 = val.toFloat(f32, mod) }, | 952 | 32 => .{ .float32 = val.toFloat(f32, pt) }, |
| 952 | 64 => .{ .float64 = val.toFloat(f64, mod) }, | 953 | 64 => .{ .float64 = val.toFloat(f64, pt) }, |
| 953 | 80, 128 => unreachable, // TODO | 954 | 80, 128 => unreachable, // TODO |
| 954 | else => unreachable, | 955 | else => unreachable, |
| 955 | }; | 956 | }; |
| ... | @@ -968,17 +969,17 @@ const DeclGen = struct { | ... | @@ -968,17 +969,17 @@ const DeclGen = struct { |
| 968 | .error_union => |error_union| { | 969 | .error_union => |error_union| { |
| 969 | // TODO: Error unions may be constructed with constant instructions if the payload type | 970 | // TODO: Error unions may be constructed with constant instructions if the payload type |
| 970 | // allows it. For now, just generate it here regardless. | 971 | // allows it. For now, just generate it here regardless. |
| 971 | const err_int_ty = try mod.errorIntType(); | 972 | const err_int_ty = try pt.errorIntType(); |
| 972 | const err_ty = switch (error_union.val) { | 973 | const err_ty = switch (error_union.val) { |
| 973 | .err_name => ty.errorUnionSet(mod), | 974 | .err_name => ty.errorUnionSet(mod), |
| 974 | .payload => err_int_ty, | 975 | .payload => err_int_ty, |
| 975 | }; | 976 | }; |
| 976 | const err_val = switch (error_union.val) { | 977 | const err_val = switch (error_union.val) { |
| 977 | .err_name => |err_name| Value.fromInterned((try mod.intern(.{ .err = .{ | 978 | .err_name => |err_name| Value.fromInterned(try pt.intern(.{ .err = .{ |
| 978 | .ty = ty.errorUnionSet(mod).toIntern(), | 979 | .ty = ty.errorUnionSet(mod).toIntern(), |
| 979 | .name = err_name, | 980 | .name = err_name, |
| 980 | } }))), | 981 | } })), |
| 981 | .payload => try mod.intValue(err_int_ty, 0), | 982 | .payload => try pt.intValue(err_int_ty, 0), |
| 982 | }; | 983 | }; |
| 983 | const payload_ty = ty.errorUnionPayload(mod); | 984 | const payload_ty = ty.errorUnionPayload(mod); |
| 984 | const eu_layout = self.errorUnionLayout(payload_ty); | 985 | const eu_layout = self.errorUnionLayout(payload_ty); |
| ... | @@ -988,7 +989,7 @@ const DeclGen = struct { | ... | @@ -988,7 +989,7 @@ const DeclGen = struct { |
| 988 | } | 989 | } |
| 989 | 990 | ||
| 990 | const payload_val = Value.fromInterned(switch (error_union.val) { | 991 | const payload_val = Value.fromInterned(switch (error_union.val) { |
| 991 | .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 992 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 992 | .payload => |payload| payload, | 993 | .payload => |payload| payload, |
| 993 | }); | 994 | }); |
| 994 | 995 | ||
| ... | @@ -1007,7 +1008,7 @@ const DeclGen = struct { | ... | @@ -1007,7 +1008,7 @@ const DeclGen = struct { |
| 1007 | return try self.constructStruct(ty, &types, &constituents); | 1008 | return try self.constructStruct(ty, &types, &constituents); |
| 1008 | }, | 1009 | }, |
| 1009 | .enum_tag => { | 1010 | .enum_tag => { |
| 1010 | const int_val = try val.intFromEnum(ty, mod); | 1011 | const int_val = try val.intFromEnum(ty, pt); |
| 1011 | const int_ty = ty.intTagType(mod); | 1012 | const int_ty = ty.intTagType(mod); |
| 1012 | break :cache try self.constant(int_ty, int_val, repr); | 1013 | break :cache try self.constant(int_ty, int_val, repr); |
| 1013 | }, | 1014 | }, |
| ... | @@ -1026,7 +1027,7 @@ const DeclGen = struct { | ... | @@ -1026,7 +1027,7 @@ const DeclGen = struct { |
| 1026 | const payload_ty = ty.optionalChild(mod); | 1027 | const payload_ty = ty.optionalChild(mod); |
| 1027 | const maybe_payload_val = val.optionalValue(mod); | 1028 | const maybe_payload_val = val.optionalValue(mod); |
| 1028 | 1029 | ||
| 1029 | if (!payload_ty.hasRuntimeBits(mod)) { | 1030 | if (!payload_ty.hasRuntimeBits(pt)) { |
| 1030 | break :cache try self.constBool(maybe_payload_val != null, .indirect); | 1031 | break :cache try self.constBool(maybe_payload_val != null, .indirect); |
| 1031 | } else if (ty.optionalReprIsPayload(mod)) { | 1032 | } else if (ty.optionalReprIsPayload(mod)) { |
| 1032 | // Optional representation is a nullable pointer or slice. | 1033 | // Optional representation is a nullable pointer or slice. |
| ... | @@ -1104,13 +1105,13 @@ const DeclGen = struct { | ... | @@ -1104,13 +1105,13 @@ const DeclGen = struct { |
| 1104 | var it = struct_type.iterateRuntimeOrder(ip); | 1105 | var it = struct_type.iterateRuntimeOrder(ip); |
| 1105 | while (it.next()) |field_index| { | 1106 | while (it.next()) |field_index| { |
| 1106 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 1107 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 1107 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1108 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1108 | // This is a zero-bit field - we only needed it for the alignment. | 1109 | // This is a zero-bit field - we only needed it for the alignment. |
| 1109 | continue; | 1110 | continue; |
| 1110 | } | 1111 | } |
| 1111 | 1112 | ||
| 1112 | // TODO: Padding? | 1113 | // TODO: Padding? |
| 1113 | const field_val = try val.fieldValue(mod, field_index); | 1114 | const field_val = try val.fieldValue(pt, field_index); |
| 1114 | const field_id = try self.constant(field_ty, field_val, .indirect); | 1115 | const field_id = try self.constant(field_ty, field_val, .indirect); |
| 1115 | 1116 | ||
| 1116 | try types.append(field_ty); | 1117 | try types.append(field_ty); |
| ... | @@ -1126,7 +1127,7 @@ const DeclGen = struct { | ... | @@ -1126,7 +1127,7 @@ const DeclGen = struct { |
| 1126 | const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; | 1127 | const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; |
| 1127 | const union_obj = mod.typeToUnion(ty).?; | 1128 | const union_obj = mod.typeToUnion(ty).?; |
| 1128 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[active_field]); | 1129 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[active_field]); |
| 1129 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(mod)) | 1130 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 1130 | try self.constant(field_ty, Value.fromInterned(un.val), .direct) | 1131 | try self.constant(field_ty, Value.fromInterned(un.val), .direct) |
| 1131 | else | 1132 | else |
| 1132 | null; | 1133 | null; |
| ... | @@ -1144,10 +1145,10 @@ const DeclGen = struct { | ... | @@ -1144,10 +1145,10 @@ const DeclGen = struct { |
| 1144 | fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef { | 1145 | fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef { |
| 1145 | // TODO: Caching?? | 1146 | // TODO: Caching?? |
| 1146 | 1147 | ||
| 1147 | const zcu = self.module; | 1148 | const pt = self.pt; |
| 1148 | 1149 | ||
| 1149 | if (ptr_val.isUndef(zcu)) { | 1150 | if (ptr_val.isUndef(pt.zcu)) { |
| 1150 | const result_ty = ptr_val.typeOf(zcu); | 1151 | const result_ty = ptr_val.typeOf(pt.zcu); |
| 1151 | const result_ty_id = try self.resolveType(result_ty, .direct); | 1152 | const result_ty_id = try self.resolveType(result_ty, .direct); |
| 1152 | return self.spv.constUndef(result_ty_id); | 1153 | return self.spv.constUndef(result_ty_id); |
| 1153 | } | 1154 | } |
| ... | @@ -1155,12 +1156,13 @@ const DeclGen = struct { | ... | @@ -1155,12 +1156,13 @@ const DeclGen = struct { |
| 1155 | var arena = std.heap.ArenaAllocator.init(self.gpa); | 1156 | var arena = std.heap.ArenaAllocator.init(self.gpa); |
| 1156 | defer arena.deinit(); | 1157 | defer arena.deinit(); |
| 1157 | 1158 | ||
| 1158 | const derivation = try ptr_val.pointerDerivation(arena.allocator(), zcu); | 1159 | const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt); |
| 1159 | return self.derivePtr(derivation); | 1160 | return self.derivePtr(derivation); |
| 1160 | } | 1161 | } |
| 1161 | 1162 | ||
| 1162 | fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef { | 1163 | fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef { |
| 1163 | const zcu = self.module; | 1164 | const pt = self.pt; |
| 1165 | const zcu = pt.zcu; | ||
| 1164 | switch (derivation) { | 1166 | switch (derivation) { |
| 1165 | .comptime_alloc_ptr, .comptime_field_ptr => unreachable, | 1167 | .comptime_alloc_ptr, .comptime_field_ptr => unreachable, |
| 1166 | .int => |int| { | 1168 | .int => |int| { |
| ... | @@ -1172,12 +1174,12 @@ const DeclGen = struct { | ... | @@ -1172,12 +1174,12 @@ const DeclGen = struct { |
| 1172 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ | 1174 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ |
| 1173 | .id_result_type = result_ty_id, | 1175 | .id_result_type = result_ty_id, |
| 1174 | .id_result = result_ptr_id, | 1176 | .id_result = result_ptr_id, |
| 1175 | .integer_value = try self.constant(Type.usize, try zcu.intValue(Type.usize, int.addr), .direct), | 1177 | .integer_value = try self.constant(Type.usize, try pt.intValue(Type.usize, int.addr), .direct), |
| 1176 | }); | 1178 | }); |
| 1177 | return result_ptr_id; | 1179 | return result_ptr_id; |
| 1178 | }, | 1180 | }, |
| 1179 | .decl_ptr => |decl| { | 1181 | .decl_ptr => |decl| { |
| 1180 | const result_ptr_ty = try zcu.declPtr(decl).declPtrType(zcu); | 1182 | const result_ptr_ty = try zcu.declPtr(decl).declPtrType(pt); |
| 1181 | return self.constantDeclRef(result_ptr_ty, decl); | 1183 | return self.constantDeclRef(result_ptr_ty, decl); |
| 1182 | }, | 1184 | }, |
| 1183 | .anon_decl_ptr => |ad| { | 1185 | .anon_decl_ptr => |ad| { |
| ... | @@ -1188,18 +1190,18 @@ const DeclGen = struct { | ... | @@ -1188,18 +1190,18 @@ const DeclGen = struct { |
| 1188 | .opt_payload_ptr => @panic("TODO"), | 1190 | .opt_payload_ptr => @panic("TODO"), |
| 1189 | .field_ptr => |field| { | 1191 | .field_ptr => |field| { |
| 1190 | const parent_ptr_id = try self.derivePtr(field.parent.*); | 1192 | const parent_ptr_id = try self.derivePtr(field.parent.*); |
| 1191 | const parent_ptr_ty = try field.parent.ptrType(zcu); | 1193 | const parent_ptr_ty = try field.parent.ptrType(pt); |
| 1192 | return self.structFieldPtr(field.result_ptr_ty, parent_ptr_ty, parent_ptr_id, field.field_idx); | 1194 | return self.structFieldPtr(field.result_ptr_ty, parent_ptr_ty, parent_ptr_id, field.field_idx); |
| 1193 | }, | 1195 | }, |
| 1194 | .elem_ptr => |elem| { | 1196 | .elem_ptr => |elem| { |
| 1195 | const parent_ptr_id = try self.derivePtr(elem.parent.*); | 1197 | const parent_ptr_id = try self.derivePtr(elem.parent.*); |
| 1196 | const parent_ptr_ty = try elem.parent.ptrType(zcu); | 1198 | const parent_ptr_ty = try elem.parent.ptrType(pt); |
| 1197 | const index_id = try self.constInt(Type.usize, elem.elem_idx, .direct); | 1199 | const index_id = try self.constInt(Type.usize, elem.elem_idx, .direct); |
| 1198 | return self.ptrElemPtr(parent_ptr_ty, parent_ptr_id, index_id); | 1200 | return self.ptrElemPtr(parent_ptr_ty, parent_ptr_id, index_id); |
| 1199 | }, | 1201 | }, |
| 1200 | .offset_and_cast => |oac| { | 1202 | .offset_and_cast => |oac| { |
| 1201 | const parent_ptr_id = try self.derivePtr(oac.parent.*); | 1203 | const parent_ptr_id = try self.derivePtr(oac.parent.*); |
| 1202 | const parent_ptr_ty = try oac.parent.ptrType(zcu); | 1204 | const parent_ptr_ty = try oac.parent.ptrType(pt); |
| 1203 | disallow: { | 1205 | disallow: { |
| 1204 | if (oac.byte_offset != 0) break :disallow; | 1206 | if (oac.byte_offset != 0) break :disallow; |
| 1205 | // Allow changing the pointer type child only to restructure arrays. | 1207 | // Allow changing the pointer type child only to restructure arrays. |
| ... | @@ -1218,8 +1220,8 @@ const DeclGen = struct { | ... | @@ -1218,8 +1220,8 @@ const DeclGen = struct { |
| 1218 | return result_ptr_id; | 1220 | return result_ptr_id; |
| 1219 | } | 1221 | } |
| 1220 | return self.fail("Cannot perform pointer cast: '{}' to '{}'", .{ | 1222 | return self.fail("Cannot perform pointer cast: '{}' to '{}'", .{ |
| 1221 | parent_ptr_ty.fmt(zcu), | 1223 | parent_ptr_ty.fmt(pt), |
| 1222 | oac.new_ptr_ty.fmt(zcu), | 1224 | oac.new_ptr_ty.fmt(pt), |
| 1223 | }); | 1225 | }); |
| 1224 | }, | 1226 | }, |
| 1225 | } | 1227 | } |
| ... | @@ -1232,7 +1234,8 @@ const DeclGen = struct { | ... | @@ -1232,7 +1234,8 @@ const DeclGen = struct { |
| 1232 | ) !IdRef { | 1234 | ) !IdRef { |
| 1233 | // TODO: Merge this function with constantDeclRef. | 1235 | // TODO: Merge this function with constantDeclRef. |
| 1234 | 1236 | ||
| 1235 | const mod = self.module; | 1237 | const pt = self.pt; |
| 1238 | const mod = pt.zcu; | ||
| 1236 | const ip = &mod.intern_pool; | 1239 | const ip = &mod.intern_pool; |
| 1237 | const ty_id = try self.resolveType(ty, .direct); | 1240 | const ty_id = try self.resolveType(ty, .direct); |
| 1238 | const decl_val = anon_decl.val; | 1241 | const decl_val = anon_decl.val; |
| ... | @@ -1247,7 +1250,7 @@ const DeclGen = struct { | ... | @@ -1247,7 +1250,7 @@ const DeclGen = struct { |
| 1247 | } | 1250 | } |
| 1248 | 1251 | ||
| 1249 | // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; | 1252 | // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; |
| 1250 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 1253 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 1251 | // Pointer to nothing - return undefoined | 1254 | // Pointer to nothing - return undefoined |
| 1252 | return self.spv.constUndef(ty_id); | 1255 | return self.spv.constUndef(ty_id); |
| 1253 | } | 1256 | } |
| ... | @@ -1276,7 +1279,8 @@ const DeclGen = struct { | ... | @@ -1276,7 +1279,8 @@ const DeclGen = struct { |
| 1276 | } | 1279 | } |
| 1277 | 1280 | ||
| 1278 | fn constantDeclRef(self: *DeclGen, ty: Type, decl_index: InternPool.DeclIndex) !IdRef { | 1281 | fn constantDeclRef(self: *DeclGen, ty: Type, decl_index: InternPool.DeclIndex) !IdRef { |
| 1279 | const mod = self.module; | 1282 | const pt = self.pt; |
| 1283 | const mod = pt.zcu; | ||
| 1280 | const ty_id = try self.resolveType(ty, .direct); | 1284 | const ty_id = try self.resolveType(ty, .direct); |
| 1281 | const decl = mod.declPtr(decl_index); | 1285 | const decl = mod.declPtr(decl_index); |
| 1282 | 1286 | ||
| ... | @@ -1290,7 +1294,7 @@ const DeclGen = struct { | ... | @@ -1290,7 +1294,7 @@ const DeclGen = struct { |
| 1290 | else => {}, | 1294 | else => {}, |
| 1291 | } | 1295 | } |
| 1292 | 1296 | ||
| 1293 | if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 1297 | if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 1294 | // Pointer to nothing - return undefined. | 1298 | // Pointer to nothing - return undefined. |
| 1295 | return self.spv.constUndef(ty_id); | 1299 | return self.spv.constUndef(ty_id); |
| 1296 | } | 1300 | } |
| ... | @@ -1331,7 +1335,7 @@ const DeclGen = struct { | ... | @@ -1331,7 +1335,7 @@ const DeclGen = struct { |
| 1331 | fn resolveTypeName(self: *DeclGen, ty: Type) ![]const u8 { | 1335 | fn resolveTypeName(self: *DeclGen, ty: Type) ![]const u8 { |
| 1332 | var name = std.ArrayList(u8).init(self.gpa); | 1336 | var name = std.ArrayList(u8).init(self.gpa); |
| 1333 | defer name.deinit(); | 1337 | defer name.deinit(); |
| 1334 | try ty.print(name.writer(), self.module); | 1338 | try ty.print(name.writer(), self.pt); |
| 1335 | return try name.toOwnedSlice(); | 1339 | return try name.toOwnedSlice(); |
| 1336 | } | 1340 | } |
| 1337 | 1341 | ||
| ... | @@ -1424,14 +1428,14 @@ const DeclGen = struct { | ... | @@ -1424,14 +1428,14 @@ const DeclGen = struct { |
| 1424 | } | 1428 | } |
| 1425 | 1429 | ||
| 1426 | fn zigScalarOrVectorTypeLike(self: *DeclGen, new_ty: Type, base_ty: Type) !Type { | 1430 | fn zigScalarOrVectorTypeLike(self: *DeclGen, new_ty: Type, base_ty: Type) !Type { |
| 1427 | const mod = self.module; | 1431 | const pt = self.pt; |
| 1428 | const new_scalar_ty = new_ty.scalarType(mod); | 1432 | const new_scalar_ty = new_ty.scalarType(pt.zcu); |
| 1429 | if (!base_ty.isVector(mod)) { | 1433 | if (!base_ty.isVector(pt.zcu)) { |
| 1430 | return new_scalar_ty; | 1434 | return new_scalar_ty; |
| 1431 | } | 1435 | } |
| 1432 | 1436 | ||
| 1433 | return try mod.vectorType(.{ | 1437 | return try pt.vectorType(.{ |
| 1434 | .len = base_ty.vectorLen(mod), | 1438 | .len = base_ty.vectorLen(pt.zcu), |
| 1435 | .child = new_scalar_ty.toIntern(), | 1439 | .child = new_scalar_ty.toIntern(), |
| 1436 | }); | 1440 | }); |
| 1437 | } | 1441 | } |
| ... | @@ -1455,7 +1459,7 @@ const DeclGen = struct { | ... | @@ -1455,7 +1459,7 @@ const DeclGen = struct { |
| 1455 | /// } | 1459 | /// } |
| 1456 | /// If any of the fields' size is 0, it will be omitted. | 1460 | /// If any of the fields' size is 0, it will be omitted. |
| 1457 | fn resolveUnionType(self: *DeclGen, ty: Type) !IdRef { | 1461 | fn resolveUnionType(self: *DeclGen, ty: Type) !IdRef { |
| 1458 | const mod = self.module; | 1462 | const mod = self.pt.zcu; |
| 1459 | const ip = &mod.intern_pool; | 1463 | const ip = &mod.intern_pool; |
| 1460 | const union_obj = mod.typeToUnion(ty).?; | 1464 | const union_obj = mod.typeToUnion(ty).?; |
| 1461 | 1465 | ||
| ... | @@ -1506,12 +1510,12 @@ const DeclGen = struct { | ... | @@ -1506,12 +1510,12 @@ const DeclGen = struct { |
| 1506 | } | 1510 | } |
| 1507 | 1511 | ||
| 1508 | fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef { | 1512 | fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef { |
| 1509 | const mod = self.module; | 1513 | const pt = self.pt; |
| 1510 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1514 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1511 | // If the return type is an error set or an error union, then we make this | 1515 | // If the return type is an error set or an error union, then we make this |
| 1512 | // anyerror return type instead, so that it can be coerced into a function | 1516 | // anyerror return type instead, so that it can be coerced into a function |
| 1513 | // pointer type which has anyerror as the return type. | 1517 | // pointer type which has anyerror as the return type. |
| 1514 | if (ret_ty.isError(mod)) { | 1518 | if (ret_ty.isError(pt.zcu)) { |
| 1515 | return self.resolveType(Type.anyerror, .direct); | 1519 | return self.resolveType(Type.anyerror, .direct); |
| 1516 | } else { | 1520 | } else { |
| 1517 | return self.resolveType(Type.void, .direct); | 1521 | return self.resolveType(Type.void, .direct); |
| ... | @@ -1533,9 +1537,10 @@ const DeclGen = struct { | ... | @@ -1533,9 +1537,10 @@ const DeclGen = struct { |
| 1533 | } | 1537 | } |
| 1534 | 1538 | ||
| 1535 | fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef { | 1539 | fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef { |
| 1536 | const mod = self.module; | 1540 | const pt = self.pt; |
| 1541 | const mod = pt.zcu; | ||
| 1537 | const ip = &mod.intern_pool; | 1542 | const ip = &mod.intern_pool; |
| 1538 | log.debug("resolveType: ty = {}", .{ty.fmt(mod)}); | 1543 | log.debug("resolveType: ty = {}", .{ty.fmt(pt)}); |
| 1539 | const target = self.getTarget(); | 1544 | const target = self.getTarget(); |
| 1540 | 1545 | ||
| 1541 | const section = &self.spv.sections.types_globals_constants; | 1546 | const section = &self.spv.sections.types_globals_constants; |
| ... | @@ -1607,7 +1612,7 @@ const DeclGen = struct { | ... | @@ -1607,7 +1612,7 @@ const DeclGen = struct { |
| 1607 | return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)}); | 1612 | return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)}); |
| 1608 | }; | 1613 | }; |
| 1609 | 1614 | ||
| 1610 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1615 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1611 | // The size of the array would be 0, but that is not allowed in SPIR-V. | 1616 | // The size of the array would be 0, but that is not allowed in SPIR-V. |
| 1612 | // This path can be reached when the backend is asked to generate a pointer to | 1617 | // This path can be reached when the backend is asked to generate a pointer to |
| 1613 | // an array of some zero-bit type. This should always be an indirect path. | 1618 | // an array of some zero-bit type. This should always be an indirect path. |
| ... | @@ -1655,7 +1660,7 @@ const DeclGen = struct { | ... | @@ -1655,7 +1660,7 @@ const DeclGen = struct { |
| 1655 | var param_index: usize = 0; | 1660 | var param_index: usize = 0; |
| 1656 | for (fn_info.param_types.get(ip)) |param_ty_index| { | 1661 | for (fn_info.param_types.get(ip)) |param_ty_index| { |
| 1657 | const param_ty = Type.fromInterned(param_ty_index); | 1662 | const param_ty = Type.fromInterned(param_ty_index); |
| 1658 | if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 1663 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 1659 | 1664 | ||
| 1660 | param_ty_ids[param_index] = try self.resolveType(param_ty, .direct); | 1665 | param_ty_ids[param_index] = try self.resolveType(param_ty, .direct); |
| 1661 | param_index += 1; | 1666 | param_index += 1; |
| ... | @@ -1713,7 +1718,7 @@ const DeclGen = struct { | ... | @@ -1713,7 +1718,7 @@ const DeclGen = struct { |
| 1713 | 1718 | ||
| 1714 | var member_index: usize = 0; | 1719 | var member_index: usize = 0; |
| 1715 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { | 1720 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 1716 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 1721 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 1717 | 1722 | ||
| 1718 | member_types[member_index] = try self.resolveType(Type.fromInterned(field_ty), .indirect); | 1723 | member_types[member_index] = try self.resolveType(Type.fromInterned(field_ty), .indirect); |
| 1719 | member_index += 1; | 1724 | member_index += 1; |
| ... | @@ -1742,7 +1747,7 @@ const DeclGen = struct { | ... | @@ -1742,7 +1747,7 @@ const DeclGen = struct { |
| 1742 | var it = struct_type.iterateRuntimeOrder(ip); | 1747 | var it = struct_type.iterateRuntimeOrder(ip); |
| 1743 | while (it.next()) |field_index| { | 1748 | while (it.next()) |field_index| { |
| 1744 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 1749 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 1745 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1750 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1746 | // This is a zero-bit field - we only needed it for the alignment. | 1751 | // This is a zero-bit field - we only needed it for the alignment. |
| 1747 | continue; | 1752 | continue; |
| 1748 | } | 1753 | } |
| ... | @@ -1761,7 +1766,7 @@ const DeclGen = struct { | ... | @@ -1761,7 +1766,7 @@ const DeclGen = struct { |
| 1761 | }, | 1766 | }, |
| 1762 | .Optional => { | 1767 | .Optional => { |
| 1763 | const payload_ty = ty.optionalChild(mod); | 1768 | const payload_ty = ty.optionalChild(mod); |
| 1764 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1769 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 1765 | // Just use a bool. | 1770 | // Just use a bool. |
| 1766 | // Note: Always generate the bool with indirect format, to save on some sanity | 1771 | // Note: Always generate the bool with indirect format, to save on some sanity |
| 1767 | // Perform the conversion to a direct bool when the field is extracted. | 1772 | // Perform the conversion to a direct bool when the field is extracted. |
| ... | @@ -1878,14 +1883,14 @@ const DeclGen = struct { | ... | @@ -1878,14 +1883,14 @@ const DeclGen = struct { |
| 1878 | }; | 1883 | }; |
| 1879 | 1884 | ||
| 1880 | fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout { | 1885 | fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout { |
| 1881 | const mod = self.module; | 1886 | const pt = self.pt; |
| 1882 | 1887 | ||
| 1883 | const error_align = Type.anyerror.abiAlignment(mod); | 1888 | const error_align = Type.anyerror.abiAlignment(pt); |
| 1884 | const payload_align = payload_ty.abiAlignment(mod); | 1889 | const payload_align = payload_ty.abiAlignment(pt); |
| 1885 | 1890 | ||
| 1886 | const error_first = error_align.compare(.gt, payload_align); | 1891 | const error_first = error_align.compare(.gt, payload_align); |
| 1887 | return .{ | 1892 | return .{ |
| 1888 | .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod), | 1893 | .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt), |
| 1889 | .error_first = error_first, | 1894 | .error_first = error_first, |
| 1890 | }; | 1895 | }; |
| 1891 | } | 1896 | } |
| ... | @@ -1909,9 +1914,10 @@ const DeclGen = struct { | ... | @@ -1909,9 +1914,10 @@ const DeclGen = struct { |
| 1909 | }; | 1914 | }; |
| 1910 | 1915 | ||
| 1911 | fn unionLayout(self: *DeclGen, ty: Type) UnionLayout { | 1916 | fn unionLayout(self: *DeclGen, ty: Type) UnionLayout { |
| 1912 | const mod = self.module; | 1917 | const pt = self.pt; |
| 1918 | const mod = pt.zcu; | ||
| 1913 | const ip = &mod.intern_pool; | 1919 | const ip = &mod.intern_pool; |
| 1914 | const layout = ty.unionGetLayout(self.module); | 1920 | const layout = ty.unionGetLayout(pt); |
| 1915 | const union_obj = mod.typeToUnion(ty).?; | 1921 | const union_obj = mod.typeToUnion(ty).?; |
| 1916 | 1922 | ||
| 1917 | var union_layout = UnionLayout{ | 1923 | var union_layout = UnionLayout{ |
| ... | @@ -1932,7 +1938,7 @@ const DeclGen = struct { | ... | @@ -1932,7 +1938,7 @@ const DeclGen = struct { |
| 1932 | const most_aligned_field = layout.most_aligned_field; | 1938 | const most_aligned_field = layout.most_aligned_field; |
| 1933 | const most_aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[most_aligned_field]); | 1939 | const most_aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[most_aligned_field]); |
| 1934 | union_layout.payload_ty = most_aligned_field_ty; | 1940 | union_layout.payload_ty = most_aligned_field_ty; |
| 1935 | union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(mod)); | 1941 | union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(pt)); |
| 1936 | } else { | 1942 | } else { |
| 1937 | union_layout.payload_size = 0; | 1943 | union_layout.payload_size = 0; |
| 1938 | } | 1944 | } |
| ... | @@ -1999,7 +2005,7 @@ const DeclGen = struct { | ... | @@ -1999,7 +2005,7 @@ const DeclGen = struct { |
| 1999 | } | 2005 | } |
| 2000 | 2006 | ||
| 2001 | fn materialize(self: Temporary, dg: *DeclGen) !IdResult { | 2007 | fn materialize(self: Temporary, dg: *DeclGen) !IdResult { |
| 2002 | const mod = dg.module; | 2008 | const mod = dg.pt.zcu; |
| 2003 | switch (self.value) { | 2009 | switch (self.value) { |
| 2004 | .singleton => |id| return id, | 2010 | .singleton => |id| return id, |
| 2005 | .exploded_vector => |range| { | 2011 | .exploded_vector => |range| { |
| ... | @@ -2029,12 +2035,12 @@ const DeclGen = struct { | ... | @@ -2029,12 +2035,12 @@ const DeclGen = struct { |
| 2029 | /// 'Explode' a temporary into separate elements. This turns a vector | 2035 | /// 'Explode' a temporary into separate elements. This turns a vector |
| 2030 | /// into a bag of elements. | 2036 | /// into a bag of elements. |
| 2031 | fn explode(self: Temporary, dg: *DeclGen) !IdRange { | 2037 | fn explode(self: Temporary, dg: *DeclGen) !IdRange { |
| 2032 | const mod = dg.module; | 2038 | const mod = dg.pt.zcu; |
| 2033 | 2039 | ||
| 2034 | // If the value is a scalar, then this is a no-op. | 2040 | // If the value is a scalar, then this is a no-op. |
| 2035 | if (!self.ty.isVector(mod)) { | 2041 | if (!self.ty.isVector(mod)) { |
| 2036 | return switch (self.value) { | 2042 | return switch (self.value) { |
| 2037 | .singleton => |id| IdRange{ .base = @intFromEnum(id), .len = 1 }, | 2043 | .singleton => |id| .{ .base = @intFromEnum(id), .len = 1 }, |
| 2038 | .exploded_vector => |range| range, | 2044 | .exploded_vector => |range| range, |
| 2039 | }; | 2045 | }; |
| 2040 | } | 2046 | } |
| ... | @@ -2088,7 +2094,7 @@ const DeclGen = struct { | ... | @@ -2088,7 +2094,7 @@ const DeclGen = struct { |
| 2088 | /// only checks the size, but the source-of-truth is implemented | 2094 | /// only checks the size, but the source-of-truth is implemented |
| 2089 | /// by `isSpvVector()`. | 2095 | /// by `isSpvVector()`. |
| 2090 | fn fromType(ty: Type, dg: *DeclGen) Vectorization { | 2096 | fn fromType(ty: Type, dg: *DeclGen) Vectorization { |
| 2091 | const mod = dg.module; | 2097 | const mod = dg.pt.zcu; |
| 2092 | if (!ty.isVector(mod)) { | 2098 | if (!ty.isVector(mod)) { |
| 2093 | return .scalar; | 2099 | return .scalar; |
| 2094 | } else if (dg.isSpvVector(ty)) { | 2100 | } else if (dg.isSpvVector(ty)) { |
| ... | @@ -2164,11 +2170,11 @@ const DeclGen = struct { | ... | @@ -2164,11 +2170,11 @@ const DeclGen = struct { |
| 2164 | /// Turns `ty` into the result-type of an individual vector operation. | 2170 | /// Turns `ty` into the result-type of an individual vector operation. |
| 2165 | /// `ty` may be a scalar or vector, it doesn't matter. | 2171 | /// `ty` may be a scalar or vector, it doesn't matter. |
| 2166 | fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type { | 2172 | fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type { |
| 2167 | const mod = dg.module; | 2173 | const pt = dg.pt; |
| 2168 | const scalar_ty = ty.scalarType(mod); | 2174 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2169 | return switch (self) { | 2175 | return switch (self) { |
| 2170 | .scalar, .unrolled => scalar_ty, | 2176 | .scalar, .unrolled => scalar_ty, |
| 2171 | .spv_vectorized => |n| try mod.vectorType(.{ | 2177 | .spv_vectorized => |n| try pt.vectorType(.{ |
| 2172 | .len = n, | 2178 | .len = n, |
| 2173 | .child = scalar_ty.toIntern(), | 2179 | .child = scalar_ty.toIntern(), |
| 2174 | }), | 2180 | }), |
| ... | @@ -2178,11 +2184,11 @@ const DeclGen = struct { | ... | @@ -2178,11 +2184,11 @@ const DeclGen = struct { |
| 2178 | /// Turns `ty` into the result-type of the entire operation. | 2184 | /// Turns `ty` into the result-type of the entire operation. |
| 2179 | /// `ty` may be a scalar or vector, it doesn't matter. | 2185 | /// `ty` may be a scalar or vector, it doesn't matter. |
| 2180 | fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type { | 2186 | fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type { |
| 2181 | const mod = dg.module; | 2187 | const pt = dg.pt; |
| 2182 | const scalar_ty = ty.scalarType(mod); | 2188 | const scalar_ty = ty.scalarType(pt.zcu); |
| 2183 | return switch (self) { | 2189 | return switch (self) { |
| 2184 | .scalar => scalar_ty, | 2190 | .scalar => scalar_ty, |
| 2185 | .unrolled, .spv_vectorized => |n| try mod.vectorType(.{ | 2191 | .unrolled, .spv_vectorized => |n| try pt.vectorType(.{ |
| 2186 | .len = n, | 2192 | .len = n, |
| 2187 | .child = scalar_ty.toIntern(), | 2193 | .child = scalar_ty.toIntern(), |
| 2188 | }), | 2194 | }), |
| ... | @@ -2193,8 +2199,8 @@ const DeclGen = struct { | ... | @@ -2193,8 +2199,8 @@ const DeclGen = struct { |
| 2193 | /// this setup, and returns a new type that holds the relevant information on how to access | 2199 | /// this setup, and returns a new type that holds the relevant information on how to access |
| 2194 | /// elements of the input. | 2200 | /// elements of the input. |
| 2195 | fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand { | 2201 | fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand { |
| 2196 | const mod = dg.module; | 2202 | const pt = dg.pt; |
| 2197 | const is_vector = tmp.ty.isVector(mod); | 2203 | const is_vector = tmp.ty.isVector(pt.zcu); |
| 2198 | const is_spv_vector = dg.isSpvVector(tmp.ty); | 2204 | const is_spv_vector = dg.isSpvVector(tmp.ty); |
| 2199 | const value: PreparedOperand.Value = switch (tmp.value) { | 2205 | const value: PreparedOperand.Value = switch (tmp.value) { |
| 2200 | .singleton => |id| switch (self) { | 2206 | .singleton => |id| switch (self) { |
| ... | @@ -2209,7 +2215,7 @@ const DeclGen = struct { | ... | @@ -2209,7 +2215,7 @@ const DeclGen = struct { |
| 2209 | } | 2215 | } |
| 2210 | 2216 | ||
| 2211 | // Broadcast scalar into vector. | 2217 | // Broadcast scalar into vector. |
| 2212 | const vector_ty = try mod.vectorType(.{ | 2218 | const vector_ty = try pt.vectorType(.{ |
| 2213 | .len = self.components(), | 2219 | .len = self.components(), |
| 2214 | .child = tmp.ty.toIntern(), | 2220 | .child = tmp.ty.toIntern(), |
| 2215 | }); | 2221 | }); |
| ... | @@ -2340,7 +2346,7 @@ const DeclGen = struct { | ... | @@ -2340,7 +2346,7 @@ const DeclGen = struct { |
| 2340 | /// This function builds an OpSConvert of OpUConvert depending on the | 2346 | /// This function builds an OpSConvert of OpUConvert depending on the |
| 2341 | /// signedness of the types. | 2347 | /// signedness of the types. |
| 2342 | fn buildIntConvert(self: *DeclGen, dst_ty: Type, src: Temporary) !Temporary { | 2348 | fn buildIntConvert(self: *DeclGen, dst_ty: Type, src: Temporary) !Temporary { |
| 2343 | const mod = self.module; | 2349 | const mod = self.pt.zcu; |
| 2344 | 2350 | ||
| 2345 | const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct); | 2351 | const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct); |
| 2346 | const src_ty_id = try self.resolveType(src.ty.scalarType(mod), .direct); | 2352 | const src_ty_id = try self.resolveType(src.ty.scalarType(mod), .direct); |
| ... | @@ -2419,7 +2425,7 @@ const DeclGen = struct { | ... | @@ -2419,7 +2425,7 @@ const DeclGen = struct { |
| 2419 | } | 2425 | } |
| 2420 | 2426 | ||
| 2421 | fn buildSelect(self: *DeclGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary { | 2427 | fn buildSelect(self: *DeclGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary { |
| 2422 | const mod = self.module; | 2428 | const mod = self.pt.zcu; |
| 2423 | 2429 | ||
| 2424 | const v = self.vectorization(.{ condition, lhs, rhs }); | 2430 | const v = self.vectorization(.{ condition, lhs, rhs }); |
| 2425 | const ops = v.operations(); | 2431 | const ops = v.operations(); |
| ... | @@ -2764,7 +2770,8 @@ const DeclGen = struct { | ... | @@ -2764,7 +2770,8 @@ const DeclGen = struct { |
| 2764 | lhs: Temporary, | 2770 | lhs: Temporary, |
| 2765 | rhs: Temporary, | 2771 | rhs: Temporary, |
| 2766 | ) !struct { Temporary, Temporary } { | 2772 | ) !struct { Temporary, Temporary } { |
| 2767 | const mod = self.module; | 2773 | const pt = self.pt; |
| 2774 | const mod = pt.zcu; | ||
| 2768 | const target = self.getTarget(); | 2775 | const target = self.getTarget(); |
| 2769 | const ip = &mod.intern_pool; | 2776 | const ip = &mod.intern_pool; |
| 2770 | 2777 | ||
| ... | @@ -2814,7 +2821,7 @@ const DeclGen = struct { | ... | @@ -2814,7 +2821,7 @@ const DeclGen = struct { |
| 2814 | // where T is maybe vectorized. | 2821 | // where T is maybe vectorized. |
| 2815 | const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() }; | 2822 | const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() }; |
| 2816 | const values = [2]InternPool.Index{ .none, .none }; | 2823 | const values = [2]InternPool.Index{ .none, .none }; |
| 2817 | const index = try ip.getAnonStructType(mod.gpa, .{ | 2824 | const index = try ip.getAnonStructType(mod.gpa, pt.tid, .{ |
| 2818 | .types = &types, | 2825 | .types = &types, |
| 2819 | .values = &values, | 2826 | .values = &values, |
| 2820 | .names = &.{}, | 2827 | .names = &.{}, |
| ... | @@ -2888,7 +2895,7 @@ const DeclGen = struct { | ... | @@ -2888,7 +2895,7 @@ const DeclGen = struct { |
| 2888 | /// the name of an error in the text executor. | 2895 | /// the name of an error in the text executor. |
| 2889 | fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void { | 2896 | fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void { |
| 2890 | const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct); | 2897 | const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct); |
| 2891 | const ptr_anyerror_ty = try self.module.ptrType(.{ | 2898 | const ptr_anyerror_ty = try self.pt.ptrType(.{ |
| 2892 | .child = Type.anyerror.toIntern(), | 2899 | .child = Type.anyerror.toIntern(), |
| 2893 | .flags = .{ .address_space = .global }, | 2900 | .flags = .{ .address_space = .global }, |
| 2894 | }); | 2901 | }); |
| ... | @@ -2940,7 +2947,8 @@ const DeclGen = struct { | ... | @@ -2940,7 +2947,8 @@ const DeclGen = struct { |
| 2940 | } | 2947 | } |
| 2941 | 2948 | ||
| 2942 | fn genDecl(self: *DeclGen) !void { | 2949 | fn genDecl(self: *DeclGen) !void { |
| 2943 | const mod = self.module; | 2950 | const pt = self.pt; |
| 2951 | const mod = pt.zcu; | ||
| 2944 | const ip = &mod.intern_pool; | 2952 | const ip = &mod.intern_pool; |
| 2945 | const decl = mod.declPtr(self.decl_index); | 2953 | const decl = mod.declPtr(self.decl_index); |
| 2946 | const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index); | 2954 | const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index); |
| ... | @@ -2967,7 +2975,7 @@ const DeclGen = struct { | ... | @@ -2967,7 +2975,7 @@ const DeclGen = struct { |
| 2967 | try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len); | 2975 | try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len); |
| 2968 | for (fn_info.param_types.get(ip)) |param_ty_index| { | 2976 | for (fn_info.param_types.get(ip)) |param_ty_index| { |
| 2969 | const param_ty = Type.fromInterned(param_ty_index); | 2977 | const param_ty = Type.fromInterned(param_ty_index); |
| 2970 | if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 2978 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 2971 | 2979 | ||
| 2972 | const param_type_id = try self.resolveType(param_ty, .direct); | 2980 | const param_type_id = try self.resolveType(param_ty, .direct); |
| 2973 | const arg_result_id = self.spv.allocId(); | 2981 | const arg_result_id = self.spv.allocId(); |
| ... | @@ -3004,11 +3012,11 @@ const DeclGen = struct { | ... | @@ -3004,11 +3012,11 @@ const DeclGen = struct { |
| 3004 | // Append the actual code into the functions section. | 3012 | // Append the actual code into the functions section. |
| 3005 | try self.spv.addFunction(spv_decl_index, self.func); | 3013 | try self.spv.addFunction(spv_decl_index, self.func); |
| 3006 | 3014 | ||
| 3007 | const fqn = try decl.fullyQualifiedName(self.module); | 3015 | const fqn = try decl.fullyQualifiedName(self.pt.zcu); |
| 3008 | try self.spv.debugName(result_id, fqn.toSlice(ip)); | 3016 | try self.spv.debugName(result_id, fqn.toSlice(ip)); |
| 3009 | 3017 | ||
| 3010 | // Temporarily generate a test kernel declaration if this is a test function. | 3018 | // Temporarily generate a test kernel declaration if this is a test function. |
| 3011 | if (self.module.test_functions.contains(self.decl_index)) { | 3019 | if (self.pt.zcu.test_functions.contains(self.decl_index)) { |
| 3012 | try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index); | 3020 | try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index); |
| 3013 | } | 3021 | } |
| 3014 | }, | 3022 | }, |
| ... | @@ -3033,7 +3041,7 @@ const DeclGen = struct { | ... | @@ -3033,7 +3041,7 @@ const DeclGen = struct { |
| 3033 | .storage_class = final_storage_class, | 3041 | .storage_class = final_storage_class, |
| 3034 | }); | 3042 | }); |
| 3035 | 3043 | ||
| 3036 | const fqn = try decl.fullyQualifiedName(self.module); | 3044 | const fqn = try decl.fullyQualifiedName(self.pt.zcu); |
| 3037 | try self.spv.debugName(result_id, fqn.toSlice(ip)); | 3045 | try self.spv.debugName(result_id, fqn.toSlice(ip)); |
| 3038 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); | 3046 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); |
| 3039 | }, | 3047 | }, |
| ... | @@ -3078,7 +3086,7 @@ const DeclGen = struct { | ... | @@ -3078,7 +3086,7 @@ const DeclGen = struct { |
| 3078 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); | 3086 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); |
| 3079 | try self.spv.addFunction(spv_decl_index, self.func); | 3087 | try self.spv.addFunction(spv_decl_index, self.func); |
| 3080 | 3088 | ||
| 3081 | const fqn = try decl.fullyQualifiedName(self.module); | 3089 | const fqn = try decl.fullyQualifiedName(self.pt.zcu); |
| 3082 | try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)}); | 3090 | try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)}); |
| 3083 | 3091 | ||
| 3084 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{ | 3092 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{ |
| ... | @@ -3119,7 +3127,7 @@ const DeclGen = struct { | ... | @@ -3119,7 +3127,7 @@ const DeclGen = struct { |
| 3119 | /// Convert representation from indirect (in memory) to direct (in 'register') | 3127 | /// Convert representation from indirect (in memory) to direct (in 'register') |
| 3120 | /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct). | 3128 | /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct). |
| 3121 | fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef { | 3129 | fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef { |
| 3122 | const mod = self.module; | 3130 | const mod = self.pt.zcu; |
| 3123 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | 3131 | switch (ty.scalarType(mod).zigTypeTag(mod)) { |
| 3124 | .Bool => { | 3132 | .Bool => { |
| 3125 | const false_id = try self.constBool(false, .indirect); | 3133 | const false_id = try self.constBool(false, .indirect); |
| ... | @@ -3145,7 +3153,7 @@ const DeclGen = struct { | ... | @@ -3145,7 +3153,7 @@ const DeclGen = struct { |
| 3145 | /// Convert representation from direct (in 'register) to direct (in memory) | 3153 | /// Convert representation from direct (in 'register) to direct (in memory) |
| 3146 | /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect). | 3154 | /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect). |
| 3147 | fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef { | 3155 | fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef { |
| 3148 | const mod = self.module; | 3156 | const mod = self.pt.zcu; |
| 3149 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | 3157 | switch (ty.scalarType(mod).zigTypeTag(mod)) { |
| 3150 | .Bool => { | 3158 | .Bool => { |
| 3151 | const result = try self.intFromBool(Temporary.init(ty, operand_id)); | 3159 | const result = try self.intFromBool(Temporary.init(ty, operand_id)); |
| ... | @@ -3222,7 +3230,7 @@ const DeclGen = struct { | ... | @@ -3222,7 +3230,7 @@ const DeclGen = struct { |
| 3222 | } | 3230 | } |
| 3223 | 3231 | ||
| 3224 | fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void { | 3232 | fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 3225 | const mod = self.module; | 3233 | const mod = self.pt.zcu; |
| 3226 | const ip = &mod.intern_pool; | 3234 | const ip = &mod.intern_pool; |
| 3227 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) | 3235 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) |
| 3228 | return; | 3236 | return; |
| ... | @@ -3402,7 +3410,7 @@ const DeclGen = struct { | ... | @@ -3402,7 +3410,7 @@ const DeclGen = struct { |
| 3402 | } | 3410 | } |
| 3403 | 3411 | ||
| 3404 | fn airShift(self: *DeclGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef { | 3412 | fn airShift(self: *DeclGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef { |
| 3405 | const mod = self.module; | 3413 | const mod = self.pt.zcu; |
| 3406 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3414 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3407 | 3415 | ||
| 3408 | const base = try self.temporary(bin_op.lhs); | 3416 | const base = try self.temporary(bin_op.lhs); |
| ... | @@ -3480,7 +3488,7 @@ const DeclGen = struct { | ... | @@ -3480,7 +3488,7 @@ const DeclGen = struct { |
| 3480 | /// All other values are returned unmodified (this makes strange integer | 3488 | /// All other values are returned unmodified (this makes strange integer |
| 3481 | /// wrapping easier to use in generic operations). | 3489 | /// wrapping easier to use in generic operations). |
| 3482 | fn normalize(self: *DeclGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary { | 3490 | fn normalize(self: *DeclGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary { |
| 3483 | const mod = self.module; | 3491 | const mod = self.pt.zcu; |
| 3484 | const ty = value.ty; | 3492 | const ty = value.ty; |
| 3485 | switch (info.class) { | 3493 | switch (info.class) { |
| 3486 | .integer, .bool, .float => return value, | 3494 | .integer, .bool, .float => return value, |
| ... | @@ -3721,7 +3729,7 @@ const DeclGen = struct { | ... | @@ -3721,7 +3729,7 @@ const DeclGen = struct { |
| 3721 | 3729 | ||
| 3722 | fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3730 | fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3723 | const target = self.getTarget(); | 3731 | const target = self.getTarget(); |
| 3724 | const mod = self.module; | 3732 | const pt = self.pt; |
| 3725 | 3733 | ||
| 3726 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3734 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3727 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3735 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -3758,7 +3766,7 @@ const DeclGen = struct { | ... | @@ -3758,7 +3766,7 @@ const DeclGen = struct { |
| 3758 | const result, const overflowed = switch (info.signedness) { | 3766 | const result, const overflowed = switch (info.signedness) { |
| 3759 | .unsigned => blk: { | 3767 | .unsigned => blk: { |
| 3760 | if (maybe_op_ty_bits) |op_ty_bits| { | 3768 | if (maybe_op_ty_bits) |op_ty_bits| { |
| 3761 | const op_ty = try mod.intType(.unsigned, op_ty_bits); | 3769 | const op_ty = try pt.intType(.unsigned, op_ty_bits); |
| 3762 | const casted_lhs = try self.buildIntConvert(op_ty, lhs); | 3770 | const casted_lhs = try self.buildIntConvert(op_ty, lhs); |
| 3763 | const casted_rhs = try self.buildIntConvert(op_ty, rhs); | 3771 | const casted_rhs = try self.buildIntConvert(op_ty, rhs); |
| 3764 | 3772 | ||
| ... | @@ -3828,7 +3836,7 @@ const DeclGen = struct { | ... | @@ -3828,7 +3836,7 @@ const DeclGen = struct { |
| 3828 | ); | 3836 | ); |
| 3829 | 3837 | ||
| 3830 | if (maybe_op_ty_bits) |op_ty_bits| { | 3838 | if (maybe_op_ty_bits) |op_ty_bits| { |
| 3831 | const op_ty = try mod.intType(.signed, op_ty_bits); | 3839 | const op_ty = try pt.intType(.signed, op_ty_bits); |
| 3832 | // Assume normalized; sign bit is set. We want a sign extend. | 3840 | // Assume normalized; sign bit is set. We want a sign extend. |
| 3833 | const casted_lhs = try self.buildIntConvert(op_ty, lhs); | 3841 | const casted_lhs = try self.buildIntConvert(op_ty, lhs); |
| 3834 | const casted_rhs = try self.buildIntConvert(op_ty, rhs); | 3842 | const casted_rhs = try self.buildIntConvert(op_ty, rhs); |
| ... | @@ -3900,7 +3908,7 @@ const DeclGen = struct { | ... | @@ -3900,7 +3908,7 @@ const DeclGen = struct { |
| 3900 | } | 3908 | } |
| 3901 | 3909 | ||
| 3902 | fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3910 | fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3903 | const mod = self.module; | 3911 | const mod = self.pt.zcu; |
| 3904 | 3912 | ||
| 3905 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3913 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3906 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3914 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -3958,7 +3966,7 @@ const DeclGen = struct { | ... | @@ -3958,7 +3966,7 @@ const DeclGen = struct { |
| 3958 | fn airClzCtz(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef { | 3966 | fn airClzCtz(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef { |
| 3959 | if (self.liveness.isUnused(inst)) return null; | 3967 | if (self.liveness.isUnused(inst)) return null; |
| 3960 | 3968 | ||
| 3961 | const mod = self.module; | 3969 | const mod = self.pt.zcu; |
| 3962 | const target = self.getTarget(); | 3970 | const target = self.getTarget(); |
| 3963 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3971 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3964 | const operand = try self.temporary(ty_op.operand); | 3972 | const operand = try self.temporary(ty_op.operand); |
| ... | @@ -4007,7 +4015,7 @@ const DeclGen = struct { | ... | @@ -4007,7 +4015,7 @@ const DeclGen = struct { |
| 4007 | } | 4015 | } |
| 4008 | 4016 | ||
| 4009 | fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4017 | fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4010 | const mod = self.module; | 4018 | const mod = self.pt.zcu; |
| 4011 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 4019 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 4012 | const operand = try self.resolve(reduce.operand); | 4020 | const operand = try self.resolve(reduce.operand); |
| 4013 | const operand_ty = self.typeOf(reduce.operand); | 4021 | const operand_ty = self.typeOf(reduce.operand); |
| ... | @@ -4082,7 +4090,8 @@ const DeclGen = struct { | ... | @@ -4082,7 +4090,8 @@ const DeclGen = struct { |
| 4082 | } | 4090 | } |
| 4083 | 4091 | ||
| 4084 | fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4092 | fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4085 | const mod = self.module; | 4093 | const pt = self.pt; |
| 4094 | const mod = pt.zcu; | ||
| 4086 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4095 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4087 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 4096 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 4088 | const a = try self.resolve(extra.a); | 4097 | const a = try self.resolve(extra.a); |
| ... | @@ -4108,14 +4117,14 @@ const DeclGen = struct { | ... | @@ -4108,14 +4117,14 @@ const DeclGen = struct { |
| 4108 | const a_len = a_ty.vectorLen(mod); | 4117 | const a_len = a_ty.vectorLen(mod); |
| 4109 | 4118 | ||
| 4110 | for (components, 0..) |*component, i| { | 4119 | for (components, 0..) |*component, i| { |
| 4111 | const elem = try mask.elemValue(mod, i); | 4120 | const elem = try mask.elemValue(pt, i); |
| 4112 | if (elem.isUndef(mod)) { | 4121 | if (elem.isUndef(mod)) { |
| 4113 | // This is explicitly valid for OpVectorShuffle, it indicates undefined. | 4122 | // This is explicitly valid for OpVectorShuffle, it indicates undefined. |
| 4114 | component.* = 0xFFFF_FFFF; | 4123 | component.* = 0xFFFF_FFFF; |
| 4115 | continue; | 4124 | continue; |
| 4116 | } | 4125 | } |
| 4117 | 4126 | ||
| 4118 | const index = elem.toSignedInt(mod); | 4127 | const index = elem.toSignedInt(pt); |
| 4119 | if (index >= 0) { | 4128 | if (index >= 0) { |
| 4120 | component.* = @intCast(index); | 4129 | component.* = @intCast(index); |
| 4121 | } else { | 4130 | } else { |
| ... | @@ -4140,13 +4149,13 @@ const DeclGen = struct { | ... | @@ -4140,13 +4149,13 @@ const DeclGen = struct { |
| 4140 | defer self.gpa.free(components); | 4149 | defer self.gpa.free(components); |
| 4141 | 4150 | ||
| 4142 | for (components, 0..) |*id, i| { | 4151 | for (components, 0..) |*id, i| { |
| 4143 | const elem = try mask.elemValue(mod, i); | 4152 | const elem = try mask.elemValue(pt, i); |
| 4144 | if (elem.isUndef(mod)) { | 4153 | if (elem.isUndef(mod)) { |
| 4145 | id.* = try self.spv.constUndef(scalar_ty_id); | 4154 | id.* = try self.spv.constUndef(scalar_ty_id); |
| 4146 | continue; | 4155 | continue; |
| 4147 | } | 4156 | } |
| 4148 | 4157 | ||
| 4149 | const index = elem.toSignedInt(mod); | 4158 | const index = elem.toSignedInt(pt); |
| 4150 | if (index >= 0) { | 4159 | if (index >= 0) { |
| 4151 | id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index)); | 4160 | id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index)); |
| 4152 | } else { | 4161 | } else { |
| ... | @@ -4220,7 +4229,7 @@ const DeclGen = struct { | ... | @@ -4220,7 +4229,7 @@ const DeclGen = struct { |
| 4220 | } | 4229 | } |
| 4221 | 4230 | ||
| 4222 | fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef { | 4231 | fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef { |
| 4223 | const mod = self.module; | 4232 | const mod = self.pt.zcu; |
| 4224 | const result_ty_id = try self.resolveType(result_ty, .direct); | 4233 | const result_ty_id = try self.resolveType(result_ty, .direct); |
| 4225 | 4234 | ||
| 4226 | switch (ptr_ty.ptrSize(mod)) { | 4235 | switch (ptr_ty.ptrSize(mod)) { |
| ... | @@ -4276,7 +4285,8 @@ const DeclGen = struct { | ... | @@ -4276,7 +4285,8 @@ const DeclGen = struct { |
| 4276 | lhs: Temporary, | 4285 | lhs: Temporary, |
| 4277 | rhs: Temporary, | 4286 | rhs: Temporary, |
| 4278 | ) !Temporary { | 4287 | ) !Temporary { |
| 4279 | const mod = self.module; | 4288 | const pt = self.pt; |
| 4289 | const mod = pt.zcu; | ||
| 4280 | const scalar_ty = lhs.ty.scalarType(mod); | 4290 | const scalar_ty = lhs.ty.scalarType(mod); |
| 4281 | const is_vector = lhs.ty.isVector(mod); | 4291 | const is_vector = lhs.ty.isVector(mod); |
| 4282 | 4292 | ||
| ... | @@ -4324,7 +4334,7 @@ const DeclGen = struct { | ... | @@ -4324,7 +4334,7 @@ const DeclGen = struct { |
| 4324 | 4334 | ||
| 4325 | const payload_ty = ty.optionalChild(mod); | 4335 | const payload_ty = ty.optionalChild(mod); |
| 4326 | if (ty.optionalReprIsPayload(mod)) { | 4336 | if (ty.optionalReprIsPayload(mod)) { |
| 4327 | assert(payload_ty.hasRuntimeBitsIgnoreComptime(mod)); | 4337 | assert(payload_ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 4328 | assert(!payload_ty.isSlice(mod)); | 4338 | assert(!payload_ty.isSlice(mod)); |
| 4329 | 4339 | ||
| 4330 | return try self.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty)); | 4340 | return try self.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty)); |
| ... | @@ -4333,12 +4343,12 @@ const DeclGen = struct { | ... | @@ -4333,12 +4343,12 @@ const DeclGen = struct { |
| 4333 | const lhs_id = try lhs.materialize(self); | 4343 | const lhs_id = try lhs.materialize(self); |
| 4334 | const rhs_id = try rhs.materialize(self); | 4344 | const rhs_id = try rhs.materialize(self); |
| 4335 | 4345 | ||
| 4336 | const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 4346 | const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 4337 | try self.extractField(Type.bool, lhs_id, 1) | 4347 | try self.extractField(Type.bool, lhs_id, 1) |
| 4338 | else | 4348 | else |
| 4339 | try self.convertToDirect(Type.bool, lhs_id); | 4349 | try self.convertToDirect(Type.bool, lhs_id); |
| 4340 | 4350 | ||
| 4341 | const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 4351 | const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 4342 | try self.extractField(Type.bool, rhs_id, 1) | 4352 | try self.extractField(Type.bool, rhs_id, 1) |
| 4343 | else | 4353 | else |
| 4344 | try self.convertToDirect(Type.bool, rhs_id); | 4354 | try self.convertToDirect(Type.bool, rhs_id); |
| ... | @@ -4346,7 +4356,7 @@ const DeclGen = struct { | ... | @@ -4346,7 +4356,7 @@ const DeclGen = struct { |
| 4346 | const lhs_valid = Temporary.init(Type.bool, lhs_valid_id); | 4356 | const lhs_valid = Temporary.init(Type.bool, lhs_valid_id); |
| 4347 | const rhs_valid = Temporary.init(Type.bool, rhs_valid_id); | 4357 | const rhs_valid = Temporary.init(Type.bool, rhs_valid_id); |
| 4348 | 4358 | ||
| 4349 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4359 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4350 | return try self.cmp(op, lhs_valid, rhs_valid); | 4360 | return try self.cmp(op, lhs_valid, rhs_valid); |
| 4351 | } | 4361 | } |
| 4352 | 4362 | ||
| ... | @@ -4466,7 +4476,7 @@ const DeclGen = struct { | ... | @@ -4466,7 +4476,7 @@ const DeclGen = struct { |
| 4466 | src_ty: Type, | 4476 | src_ty: Type, |
| 4467 | src_id: IdRef, | 4477 | src_id: IdRef, |
| 4468 | ) !IdRef { | 4478 | ) !IdRef { |
| 4469 | const mod = self.module; | 4479 | const mod = self.pt.zcu; |
| 4470 | const src_ty_id = try self.resolveType(src_ty, .direct); | 4480 | const src_ty_id = try self.resolveType(src_ty, .direct); |
| 4471 | const dst_ty_id = try self.resolveType(dst_ty, .direct); | 4481 | const dst_ty_id = try self.resolveType(dst_ty, .direct); |
| 4472 | 4482 | ||
| ... | @@ -4675,7 +4685,8 @@ const DeclGen = struct { | ... | @@ -4675,7 +4685,8 @@ const DeclGen = struct { |
| 4675 | } | 4685 | } |
| 4676 | 4686 | ||
| 4677 | fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4687 | fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4678 | const mod = self.module; | 4688 | const pt = self.pt; |
| 4689 | const mod = pt.zcu; | ||
| 4679 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4690 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4680 | const array_ptr_ty = self.typeOf(ty_op.operand); | 4691 | const array_ptr_ty = self.typeOf(ty_op.operand); |
| 4681 | const array_ty = array_ptr_ty.childType(mod); | 4692 | const array_ty = array_ptr_ty.childType(mod); |
| ... | @@ -4687,7 +4698,7 @@ const DeclGen = struct { | ... | @@ -4687,7 +4698,7 @@ const DeclGen = struct { |
| 4687 | const array_ptr_id = try self.resolve(ty_op.operand); | 4698 | const array_ptr_id = try self.resolve(ty_op.operand); |
| 4688 | const len_id = try self.constInt(Type.usize, array_ty.arrayLen(mod), .direct); | 4699 | const len_id = try self.constInt(Type.usize, array_ty.arrayLen(mod), .direct); |
| 4689 | 4700 | ||
| 4690 | const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) | 4701 | const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 4691 | // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type. | 4702 | // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type. |
| 4692 | try self.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id) | 4703 | try self.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id) |
| 4693 | else | 4704 | else |
| ... | @@ -4719,7 +4730,8 @@ const DeclGen = struct { | ... | @@ -4719,7 +4730,8 @@ const DeclGen = struct { |
| 4719 | } | 4730 | } |
| 4720 | 4731 | ||
| 4721 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4732 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4722 | const mod = self.module; | 4733 | const pt = self.pt; |
| 4734 | const mod = pt.zcu; | ||
| 4723 | const ip = &mod.intern_pool; | 4735 | const ip = &mod.intern_pool; |
| 4724 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4736 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4725 | const result_ty = self.typeOfIndex(inst); | 4737 | const result_ty = self.typeOfIndex(inst); |
| ... | @@ -4742,8 +4754,8 @@ const DeclGen = struct { | ... | @@ -4742,8 +4754,8 @@ const DeclGen = struct { |
| 4742 | switch (ip.indexToKey(result_ty.toIntern())) { | 4754 | switch (ip.indexToKey(result_ty.toIntern())) { |
| 4743 | .anon_struct_type => |tuple| { | 4755 | .anon_struct_type => |tuple| { |
| 4744 | for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| { | 4756 | for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| { |
| 4745 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; | 4757 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 4746 | assert(Type.fromInterned(field_ty).hasRuntimeBits(mod)); | 4758 | assert(Type.fromInterned(field_ty).hasRuntimeBits(pt)); |
| 4747 | 4759 | ||
| 4748 | const id = try self.resolve(element); | 4760 | const id = try self.resolve(element); |
| 4749 | types[index] = Type.fromInterned(field_ty); | 4761 | types[index] = Type.fromInterned(field_ty); |
| ... | @@ -4756,9 +4768,9 @@ const DeclGen = struct { | ... | @@ -4756,9 +4768,9 @@ const DeclGen = struct { |
| 4756 | var it = struct_type.iterateRuntimeOrder(ip); | 4768 | var it = struct_type.iterateRuntimeOrder(ip); |
| 4757 | for (elements, 0..) |element, i| { | 4769 | for (elements, 0..) |element, i| { |
| 4758 | const field_index = it.next().?; | 4770 | const field_index = it.next().?; |
| 4759 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; | 4771 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 4760 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 4772 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 4761 | assert(field_ty.hasRuntimeBitsIgnoreComptime(mod)); | 4773 | assert(field_ty.hasRuntimeBitsIgnoreComptime(pt)); |
| 4762 | 4774 | ||
| 4763 | const id = try self.resolve(element); | 4775 | const id = try self.resolve(element); |
| 4764 | types[index] = field_ty; | 4776 | types[index] = field_ty; |
| ... | @@ -4808,13 +4820,14 @@ const DeclGen = struct { | ... | @@ -4808,13 +4820,14 @@ const DeclGen = struct { |
| 4808 | } | 4820 | } |
| 4809 | 4821 | ||
| 4810 | fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { | 4822 | fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { |
| 4811 | const mod = self.module; | 4823 | const pt = self.pt; |
| 4824 | const mod = pt.zcu; | ||
| 4812 | switch (ty.ptrSize(mod)) { | 4825 | switch (ty.ptrSize(mod)) { |
| 4813 | .Slice => return self.extractField(Type.usize, operand_id, 1), | 4826 | .Slice => return self.extractField(Type.usize, operand_id, 1), |
| 4814 | .One => { | 4827 | .One => { |
| 4815 | const array_ty = ty.childType(mod); | 4828 | const array_ty = ty.childType(mod); |
| 4816 | const elem_ty = array_ty.childType(mod); | 4829 | const elem_ty = array_ty.childType(mod); |
| 4817 | const abi_size = elem_ty.abiSize(mod); | 4830 | const abi_size = elem_ty.abiSize(pt); |
| 4818 | const size = array_ty.arrayLenIncludingSentinel(mod) * abi_size; | 4831 | const size = array_ty.arrayLenIncludingSentinel(mod) * abi_size; |
| 4819 | return try self.constInt(Type.usize, size, .direct); | 4832 | return try self.constInt(Type.usize, size, .direct); |
| 4820 | }, | 4833 | }, |
| ... | @@ -4823,7 +4836,7 @@ const DeclGen = struct { | ... | @@ -4823,7 +4836,7 @@ const DeclGen = struct { |
| 4823 | } | 4836 | } |
| 4824 | 4837 | ||
| 4825 | fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { | 4838 | fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { |
| 4826 | const mod = self.module; | 4839 | const mod = self.pt.zcu; |
| 4827 | if (ty.isSlice(mod)) { | 4840 | if (ty.isSlice(mod)) { |
| 4828 | const ptr_ty = ty.slicePtrFieldType(mod); | 4841 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 4829 | return self.extractField(ptr_ty, operand_id, 0); | 4842 | return self.extractField(ptr_ty, operand_id, 0); |
| ... | @@ -4855,7 +4868,7 @@ const DeclGen = struct { | ... | @@ -4855,7 +4868,7 @@ const DeclGen = struct { |
| 4855 | } | 4868 | } |
| 4856 | 4869 | ||
| 4857 | fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4870 | fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4858 | const mod = self.module; | 4871 | const mod = self.pt.zcu; |
| 4859 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4872 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4860 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4873 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4861 | const slice_ty = self.typeOf(bin_op.lhs); | 4874 | const slice_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -4872,7 +4885,7 @@ const DeclGen = struct { | ... | @@ -4872,7 +4885,7 @@ const DeclGen = struct { |
| 4872 | } | 4885 | } |
| 4873 | 4886 | ||
| 4874 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4887 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4875 | const mod = self.module; | 4888 | const mod = self.pt.zcu; |
| 4876 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4889 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4877 | const slice_ty = self.typeOf(bin_op.lhs); | 4890 | const slice_ty = self.typeOf(bin_op.lhs); |
| 4878 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | 4891 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; |
| ... | @@ -4889,7 +4902,7 @@ const DeclGen = struct { | ... | @@ -4889,7 +4902,7 @@ const DeclGen = struct { |
| 4889 | } | 4902 | } |
| 4890 | 4903 | ||
| 4891 | fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef { | 4904 | fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef { |
| 4892 | const mod = self.module; | 4905 | const mod = self.pt.zcu; |
| 4893 | // Construct new pointer type for the resulting pointer | 4906 | // Construct new pointer type for the resulting pointer |
| 4894 | const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. | 4907 | const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. |
| 4895 | const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod))); | 4908 | const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod))); |
| ... | @@ -4904,14 +4917,15 @@ const DeclGen = struct { | ... | @@ -4904,14 +4917,15 @@ const DeclGen = struct { |
| 4904 | } | 4917 | } |
| 4905 | 4918 | ||
| 4906 | fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4919 | fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4907 | const mod = self.module; | 4920 | const pt = self.pt; |
| 4921 | const mod = pt.zcu; | ||
| 4908 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 4922 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4909 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4923 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4910 | const src_ptr_ty = self.typeOf(bin_op.lhs); | 4924 | const src_ptr_ty = self.typeOf(bin_op.lhs); |
| 4911 | const elem_ty = src_ptr_ty.childType(mod); | 4925 | const elem_ty = src_ptr_ty.childType(mod); |
| 4912 | const ptr_id = try self.resolve(bin_op.lhs); | 4926 | const ptr_id = try self.resolve(bin_op.lhs); |
| 4913 | 4927 | ||
| 4914 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4928 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 4915 | const dst_ptr_ty = self.typeOfIndex(inst); | 4929 | const dst_ptr_ty = self.typeOfIndex(inst); |
| 4916 | return try self.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id); | 4930 | return try self.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id); |
| 4917 | } | 4931 | } |
| ... | @@ -4921,7 +4935,7 @@ const DeclGen = struct { | ... | @@ -4921,7 +4935,7 @@ const DeclGen = struct { |
| 4921 | } | 4935 | } |
| 4922 | 4936 | ||
| 4923 | fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4937 | fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4924 | const mod = self.module; | 4938 | const mod = self.pt.zcu; |
| 4925 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4939 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4926 | const array_ty = self.typeOf(bin_op.lhs); | 4940 | const array_ty = self.typeOf(bin_op.lhs); |
| 4927 | const elem_ty = array_ty.childType(mod); | 4941 | const elem_ty = array_ty.childType(mod); |
| ... | @@ -4982,7 +4996,7 @@ const DeclGen = struct { | ... | @@ -4982,7 +4996,7 @@ const DeclGen = struct { |
| 4982 | } | 4996 | } |
| 4983 | 4997 | ||
| 4984 | fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4998 | fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4985 | const mod = self.module; | 4999 | const mod = self.pt.zcu; |
| 4986 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5000 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4987 | const ptr_ty = self.typeOf(bin_op.lhs); | 5001 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 4988 | const elem_ty = self.typeOfIndex(inst); | 5002 | const elem_ty = self.typeOfIndex(inst); |
| ... | @@ -4993,7 +5007,7 @@ const DeclGen = struct { | ... | @@ -4993,7 +5007,7 @@ const DeclGen = struct { |
| 4993 | } | 5007 | } |
| 4994 | 5008 | ||
| 4995 | fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void { | 5009 | fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 4996 | const mod = self.module; | 5010 | const mod = self.pt.zcu; |
| 4997 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; | 5011 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; |
| 4998 | const extra = self.air.extraData(Air.Bin, data.payload).data; | 5012 | const extra = self.air.extraData(Air.Bin, data.payload).data; |
| 4999 | 5013 | ||
| ... | @@ -5015,7 +5029,7 @@ const DeclGen = struct { | ... | @@ -5015,7 +5029,7 @@ const DeclGen = struct { |
| 5015 | } | 5029 | } |
| 5016 | 5030 | ||
| 5017 | fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void { | 5031 | fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5018 | const mod = self.module; | 5032 | const mod = self.pt.zcu; |
| 5019 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5033 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5020 | const un_ptr_ty = self.typeOf(bin_op.lhs); | 5034 | const un_ptr_ty = self.typeOf(bin_op.lhs); |
| 5021 | const un_ty = un_ptr_ty.childType(mod); | 5035 | const un_ty = un_ptr_ty.childType(mod); |
| ... | @@ -5041,7 +5055,7 @@ const DeclGen = struct { | ... | @@ -5041,7 +5055,7 @@ const DeclGen = struct { |
| 5041 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5055 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5042 | const un_ty = self.typeOf(ty_op.operand); | 5056 | const un_ty = self.typeOf(ty_op.operand); |
| 5043 | 5057 | ||
| 5044 | const mod = self.module; | 5058 | const mod = self.pt.zcu; |
| 5045 | const layout = self.unionLayout(un_ty); | 5059 | const layout = self.unionLayout(un_ty); |
| 5046 | if (layout.tag_size == 0) return null; | 5060 | if (layout.tag_size == 0) return null; |
| 5047 | 5061 | ||
| ... | @@ -5064,7 +5078,8 @@ const DeclGen = struct { | ... | @@ -5064,7 +5078,8 @@ const DeclGen = struct { |
| 5064 | 5078 | ||
| 5065 | // Note: The result here is not cached, because it generates runtime code. | 5079 | // Note: The result here is not cached, because it generates runtime code. |
| 5066 | 5080 | ||
| 5067 | const mod = self.module; | 5081 | const pt = self.pt; |
| 5082 | const mod = pt.zcu; | ||
| 5068 | const ip = &mod.intern_pool; | 5083 | const ip = &mod.intern_pool; |
| 5069 | const union_ty = mod.typeToUnion(ty).?; | 5084 | const union_ty = mod.typeToUnion(ty).?; |
| 5070 | const tag_ty = Type.fromInterned(union_ty.enum_tag_ty); | 5085 | const tag_ty = Type.fromInterned(union_ty.enum_tag_ty); |
| ... | @@ -5076,9 +5091,9 @@ const DeclGen = struct { | ... | @@ -5076,9 +5091,9 @@ const DeclGen = struct { |
| 5076 | const layout = self.unionLayout(ty); | 5091 | const layout = self.unionLayout(ty); |
| 5077 | 5092 | ||
| 5078 | const tag_int = if (layout.tag_size != 0) blk: { | 5093 | const tag_int = if (layout.tag_size != 0) blk: { |
| 5079 | const tag_val = try mod.enumValueFieldIndex(tag_ty, active_field); | 5094 | const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field); |
| 5080 | const tag_int_val = try tag_val.intFromEnum(tag_ty, mod); | 5095 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| 5081 | break :blk tag_int_val.toUnsignedInt(mod); | 5096 | break :blk tag_int_val.toUnsignedInt(pt); |
| 5082 | } else 0; | 5097 | } else 0; |
| 5083 | 5098 | ||
| 5084 | if (!layout.has_payload) { | 5099 | if (!layout.has_payload) { |
| ... | @@ -5095,7 +5110,7 @@ const DeclGen = struct { | ... | @@ -5095,7 +5110,7 @@ const DeclGen = struct { |
| 5095 | } | 5110 | } |
| 5096 | 5111 | ||
| 5097 | const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]); | 5112 | const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]); |
| 5098 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5113 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5099 | const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function); | 5114 | const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function); |
| 5100 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index}); | 5115 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index}); |
| 5101 | const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function); | 5116 | const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function); |
| ... | @@ -5118,7 +5133,8 @@ const DeclGen = struct { | ... | @@ -5118,7 +5133,8 @@ const DeclGen = struct { |
| 5118 | } | 5133 | } |
| 5119 | 5134 | ||
| 5120 | fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5135 | fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5121 | const mod = self.module; | 5136 | const pt = self.pt; |
| 5137 | const mod = pt.zcu; | ||
| 5122 | const ip = &mod.intern_pool; | 5138 | const ip = &mod.intern_pool; |
| 5123 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5139 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5124 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 5140 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| ... | @@ -5126,7 +5142,7 @@ const DeclGen = struct { | ... | @@ -5126,7 +5142,7 @@ const DeclGen = struct { |
| 5126 | 5142 | ||
| 5127 | const union_obj = mod.typeToUnion(ty).?; | 5143 | const union_obj = mod.typeToUnion(ty).?; |
| 5128 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); | 5144 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 5129 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(mod)) | 5145 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 5130 | try self.resolve(extra.init) | 5146 | try self.resolve(extra.init) |
| 5131 | else | 5147 | else |
| 5132 | null; | 5148 | null; |
| ... | @@ -5134,7 +5150,8 @@ const DeclGen = struct { | ... | @@ -5134,7 +5150,8 @@ const DeclGen = struct { |
| 5134 | } | 5150 | } |
| 5135 | 5151 | ||
| 5136 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5152 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5137 | const mod = self.module; | 5153 | const pt = self.pt; |
| 5154 | const mod = pt.zcu; | ||
| 5138 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5155 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5139 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 5156 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5140 | 5157 | ||
| ... | @@ -5143,7 +5160,7 @@ const DeclGen = struct { | ... | @@ -5143,7 +5160,7 @@ const DeclGen = struct { |
| 5143 | const field_index = struct_field.field_index; | 5160 | const field_index = struct_field.field_index; |
| 5144 | const field_ty = object_ty.structFieldType(field_index, mod); | 5161 | const field_ty = object_ty.structFieldType(field_index, mod); |
| 5145 | 5162 | ||
| 5146 | if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; | 5163 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return null; |
| 5147 | 5164 | ||
| 5148 | switch (object_ty.zigTypeTag(mod)) { | 5165 | switch (object_ty.zigTypeTag(mod)) { |
| 5149 | .Struct => switch (object_ty.containerLayout(mod)) { | 5166 | .Struct => switch (object_ty.containerLayout(mod)) { |
| ... | @@ -5178,7 +5195,8 @@ const DeclGen = struct { | ... | @@ -5178,7 +5195,8 @@ const DeclGen = struct { |
| 5178 | } | 5195 | } |
| 5179 | 5196 | ||
| 5180 | fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5197 | fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5181 | const mod = self.module; | 5198 | const pt = self.pt; |
| 5199 | const mod = pt.zcu; | ||
| 5182 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5200 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5183 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 5201 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5184 | 5202 | ||
| ... | @@ -5187,7 +5205,7 @@ const DeclGen = struct { | ... | @@ -5187,7 +5205,7 @@ const DeclGen = struct { |
| 5187 | 5205 | ||
| 5188 | const field_ptr = try self.resolve(extra.field_ptr); | 5206 | const field_ptr = try self.resolve(extra.field_ptr); |
| 5189 | const field_ptr_int = try self.intFromPtr(field_ptr); | 5207 | const field_ptr_int = try self.intFromPtr(field_ptr); |
| 5190 | const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); | 5208 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); |
| 5191 | 5209 | ||
| 5192 | const base_ptr_int = base_ptr_int: { | 5210 | const base_ptr_int = base_ptr_int: { |
| 5193 | if (field_offset == 0) break :base_ptr_int field_ptr_int; | 5211 | if (field_offset == 0) break :base_ptr_int field_ptr_int; |
| ... | @@ -5218,7 +5236,7 @@ const DeclGen = struct { | ... | @@ -5218,7 +5236,7 @@ const DeclGen = struct { |
| 5218 | ) !IdRef { | 5236 | ) !IdRef { |
| 5219 | const result_ty_id = try self.resolveType(result_ptr_ty, .direct); | 5237 | const result_ty_id = try self.resolveType(result_ptr_ty, .direct); |
| 5220 | 5238 | ||
| 5221 | const zcu = self.module; | 5239 | const zcu = self.pt.zcu; |
| 5222 | const object_ty = object_ptr_ty.childType(zcu); | 5240 | const object_ty = object_ptr_ty.childType(zcu); |
| 5223 | switch (object_ty.zigTypeTag(zcu)) { | 5241 | switch (object_ty.zigTypeTag(zcu)) { |
| 5224 | .Pointer => { | 5242 | .Pointer => { |
| ... | @@ -5312,7 +5330,7 @@ const DeclGen = struct { | ... | @@ -5312,7 +5330,7 @@ const DeclGen = struct { |
| 5312 | } | 5330 | } |
| 5313 | 5331 | ||
| 5314 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5332 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5315 | const mod = self.module; | 5333 | const mod = self.pt.zcu; |
| 5316 | const ptr_ty = self.typeOfIndex(inst); | 5334 | const ptr_ty = self.typeOfIndex(inst); |
| 5317 | assert(ptr_ty.ptrAddressSpace(mod) == .generic); | 5335 | assert(ptr_ty.ptrAddressSpace(mod) == .generic); |
| 5318 | const child_ty = ptr_ty.childType(mod); | 5336 | const child_ty = ptr_ty.childType(mod); |
| ... | @@ -5486,9 +5504,10 @@ const DeclGen = struct { | ... | @@ -5486,9 +5504,10 @@ const DeclGen = struct { |
| 5486 | // of the block, then a label, and then generate the rest of the current | 5504 | // of the block, then a label, and then generate the rest of the current |
| 5487 | // ir.Block in a different SPIR-V block. | 5505 | // ir.Block in a different SPIR-V block. |
| 5488 | 5506 | ||
| 5489 | const mod = self.module; | 5507 | const pt = self.pt; |
| 5508 | const mod = pt.zcu; | ||
| 5490 | const ty = self.typeOfIndex(inst); | 5509 | const ty = self.typeOfIndex(inst); |
| 5491 | const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod); | 5510 | const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(pt); |
| 5492 | 5511 | ||
| 5493 | const cf = switch (self.control_flow) { | 5512 | const cf = switch (self.control_flow) { |
| 5494 | .structured => |*cf| cf, | 5513 | .structured => |*cf| cf, |
| ... | @@ -5618,13 +5637,13 @@ const DeclGen = struct { | ... | @@ -5618,13 +5637,13 @@ const DeclGen = struct { |
| 5618 | } | 5637 | } |
| 5619 | 5638 | ||
| 5620 | fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void { | 5639 | fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5621 | const mod = self.module; | 5640 | const pt = self.pt; |
| 5622 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 5641 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5623 | const operand_ty = self.typeOf(br.operand); | 5642 | const operand_ty = self.typeOf(br.operand); |
| 5624 | 5643 | ||
| 5625 | switch (self.control_flow) { | 5644 | switch (self.control_flow) { |
| 5626 | .structured => |*cf| { | 5645 | .structured => |*cf| { |
| 5627 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 5646 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 5628 | const operand_id = try self.resolve(br.operand); | 5647 | const operand_id = try self.resolve(br.operand); |
| 5629 | const block_result_var_id = cf.block_results.get(br.block_inst).?; | 5648 | const block_result_var_id = cf.block_results.get(br.block_inst).?; |
| 5630 | try self.store(operand_ty, block_result_var_id, operand_id, .{}); | 5649 | try self.store(operand_ty, block_result_var_id, operand_id, .{}); |
| ... | @@ -5635,7 +5654,7 @@ const DeclGen = struct { | ... | @@ -5635,7 +5654,7 @@ const DeclGen = struct { |
| 5635 | }, | 5654 | }, |
| 5636 | .unstructured => |cf| { | 5655 | .unstructured => |cf| { |
| 5637 | const block = cf.blocks.get(br.block_inst).?; | 5656 | const block = cf.blocks.get(br.block_inst).?; |
| 5638 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 5657 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { |
| 5639 | const operand_id = try self.resolve(br.operand); | 5658 | const operand_id = try self.resolve(br.operand); |
| 5640 | // current_block_label should not be undefined here, lest there | 5659 | // current_block_label should not be undefined here, lest there |
| 5641 | // is a br or br_void in the function's body. | 5660 | // is a br or br_void in the function's body. |
| ... | @@ -5762,7 +5781,7 @@ const DeclGen = struct { | ... | @@ -5762,7 +5781,7 @@ const DeclGen = struct { |
| 5762 | } | 5781 | } |
| 5763 | 5782 | ||
| 5764 | fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5783 | fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5765 | const mod = self.module; | 5784 | const mod = self.pt.zcu; |
| 5766 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5785 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5767 | const ptr_ty = self.typeOf(ty_op.operand); | 5786 | const ptr_ty = self.typeOf(ty_op.operand); |
| 5768 | const elem_ty = self.typeOfIndex(inst); | 5787 | const elem_ty = self.typeOfIndex(inst); |
| ... | @@ -5773,20 +5792,22 @@ const DeclGen = struct { | ... | @@ -5773,20 +5792,22 @@ const DeclGen = struct { |
| 5773 | } | 5792 | } |
| 5774 | 5793 | ||
| 5775 | fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void { | 5794 | fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5795 | const mod = self.pt.zcu; | ||
| 5776 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5796 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5777 | const ptr_ty = self.typeOf(bin_op.lhs); | 5797 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 5778 | const elem_ty = ptr_ty.childType(self.module); | 5798 | const elem_ty = ptr_ty.childType(mod); |
| 5779 | const ptr = try self.resolve(bin_op.lhs); | 5799 | const ptr = try self.resolve(bin_op.lhs); |
| 5780 | const value = try self.resolve(bin_op.rhs); | 5800 | const value = try self.resolve(bin_op.rhs); |
| 5781 | 5801 | ||
| 5782 | try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(self.module) }); | 5802 | try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) }); |
| 5783 | } | 5803 | } |
| 5784 | 5804 | ||
| 5785 | fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void { | 5805 | fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5806 | const pt = self.pt; | ||
| 5807 | const mod = pt.zcu; | ||
| 5786 | const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5808 | const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5787 | const ret_ty = self.typeOf(operand); | 5809 | const ret_ty = self.typeOf(operand); |
| 5788 | const mod = self.module; | 5810 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5789 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | ||
| 5790 | const decl = mod.declPtr(self.decl_index); | 5811 | const decl = mod.declPtr(self.decl_index); |
| 5791 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; | 5812 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; |
| 5792 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5813 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| ... | @@ -5805,12 +5826,13 @@ const DeclGen = struct { | ... | @@ -5805,12 +5826,13 @@ const DeclGen = struct { |
| 5805 | } | 5826 | } |
| 5806 | 5827 | ||
| 5807 | fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void { | 5828 | fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5808 | const mod = self.module; | 5829 | const pt = self.pt; |
| 5830 | const mod = pt.zcu; | ||
| 5809 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5831 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5810 | const ptr_ty = self.typeOf(un_op); | 5832 | const ptr_ty = self.typeOf(un_op); |
| 5811 | const ret_ty = ptr_ty.childType(mod); | 5833 | const ret_ty = ptr_ty.childType(mod); |
| 5812 | 5834 | ||
| 5813 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5835 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 5814 | const decl = mod.declPtr(self.decl_index); | 5836 | const decl = mod.declPtr(self.decl_index); |
| 5815 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; | 5837 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; |
| 5816 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5838 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| ... | @@ -5832,7 +5854,7 @@ const DeclGen = struct { | ... | @@ -5832,7 +5854,7 @@ const DeclGen = struct { |
| 5832 | } | 5854 | } |
| 5833 | 5855 | ||
| 5834 | fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5856 | fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5835 | const mod = self.module; | 5857 | const mod = self.pt.zcu; |
| 5836 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 5858 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5837 | const err_union_id = try self.resolve(pl_op.operand); | 5859 | const err_union_id = try self.resolve(pl_op.operand); |
| 5838 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 5860 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| ... | @@ -5902,7 +5924,7 @@ const DeclGen = struct { | ... | @@ -5902,7 +5924,7 @@ const DeclGen = struct { |
| 5902 | } | 5924 | } |
| 5903 | 5925 | ||
| 5904 | fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5926 | fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5905 | const mod = self.module; | 5927 | const mod = self.pt.zcu; |
| 5906 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5928 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5907 | const operand_id = try self.resolve(ty_op.operand); | 5929 | const operand_id = try self.resolve(ty_op.operand); |
| 5908 | const err_union_ty = self.typeOf(ty_op.operand); | 5930 | const err_union_ty = self.typeOf(ty_op.operand); |
| ... | @@ -5938,7 +5960,7 @@ const DeclGen = struct { | ... | @@ -5938,7 +5960,7 @@ const DeclGen = struct { |
| 5938 | } | 5960 | } |
| 5939 | 5961 | ||
| 5940 | fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 5962 | fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 5941 | const mod = self.module; | 5963 | const mod = self.pt.zcu; |
| 5942 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5964 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5943 | const err_union_ty = self.typeOfIndex(inst); | 5965 | const err_union_ty = self.typeOfIndex(inst); |
| 5944 | const payload_ty = err_union_ty.errorUnionPayload(mod); | 5966 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| ... | @@ -5985,7 +6007,8 @@ const DeclGen = struct { | ... | @@ -5985,7 +6007,8 @@ const DeclGen = struct { |
| 5985 | } | 6007 | } |
| 5986 | 6008 | ||
| 5987 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { | 6009 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { |
| 5988 | const mod = self.module; | 6010 | const pt = self.pt; |
| 6011 | const mod = pt.zcu; | ||
| 5989 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6012 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5990 | const operand_id = try self.resolve(un_op); | 6013 | const operand_id = try self.resolve(un_op); |
| 5991 | const operand_ty = self.typeOf(un_op); | 6014 | const operand_ty = self.typeOf(un_op); |
| ... | @@ -6026,7 +6049,7 @@ const DeclGen = struct { | ... | @@ -6026,7 +6049,7 @@ const DeclGen = struct { |
| 6026 | 6049 | ||
| 6027 | const is_non_null_id = blk: { | 6050 | const is_non_null_id = blk: { |
| 6028 | if (is_pointer) { | 6051 | if (is_pointer) { |
| 6029 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6052 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6030 | const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod)); | 6053 | const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod)); |
| 6031 | const bool_ptr_ty_id = try self.ptrType(Type.bool, storage_class); | 6054 | const bool_ptr_ty_id = try self.ptrType(Type.bool, storage_class); |
| 6032 | const tag_ptr_id = try self.accessChain(bool_ptr_ty_id, operand_id, &.{1}); | 6055 | const tag_ptr_id = try self.accessChain(bool_ptr_ty_id, operand_id, &.{1}); |
| ... | @@ -6036,7 +6059,7 @@ const DeclGen = struct { | ... | @@ -6036,7 +6059,7 @@ const DeclGen = struct { |
| 6036 | break :blk try self.load(Type.bool, operand_id, .{}); | 6059 | break :blk try self.load(Type.bool, operand_id, .{}); |
| 6037 | } | 6060 | } |
| 6038 | 6061 | ||
| 6039 | break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 6062 | break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) |
| 6040 | try self.extractField(Type.bool, operand_id, 1) | 6063 | try self.extractField(Type.bool, operand_id, 1) |
| 6041 | else | 6064 | else |
| 6042 | // Optional representation is bool indicating whether the optional is set | 6065 | // Optional representation is bool indicating whether the optional is set |
| ... | @@ -6061,7 +6084,7 @@ const DeclGen = struct { | ... | @@ -6061,7 +6084,7 @@ const DeclGen = struct { |
| 6061 | } | 6084 | } |
| 6062 | 6085 | ||
| 6063 | fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { | 6086 | fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { |
| 6064 | const mod = self.module; | 6087 | const mod = self.pt.zcu; |
| 6065 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 6088 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6066 | const operand_id = try self.resolve(un_op); | 6089 | const operand_id = try self.resolve(un_op); |
| 6067 | const err_union_ty = self.typeOf(un_op); | 6090 | const err_union_ty = self.typeOf(un_op); |
| ... | @@ -6094,13 +6117,14 @@ const DeclGen = struct { | ... | @@ -6094,13 +6117,14 @@ const DeclGen = struct { |
| 6094 | } | 6117 | } |
| 6095 | 6118 | ||
| 6096 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 6119 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 6097 | const mod = self.module; | 6120 | const pt = self.pt; |
| 6121 | const mod = pt.zcu; | ||
| 6098 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6122 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6099 | const operand_id = try self.resolve(ty_op.operand); | 6123 | const operand_id = try self.resolve(ty_op.operand); |
| 6100 | const optional_ty = self.typeOf(ty_op.operand); | 6124 | const optional_ty = self.typeOf(ty_op.operand); |
| 6101 | const payload_ty = self.typeOfIndex(inst); | 6125 | const payload_ty = self.typeOfIndex(inst); |
| 6102 | 6126 | ||
| 6103 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; | 6127 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return null; |
| 6104 | 6128 | ||
| 6105 | if (optional_ty.optionalReprIsPayload(mod)) { | 6129 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 6106 | return operand_id; | 6130 | return operand_id; |
| ... | @@ -6110,7 +6134,8 @@ const DeclGen = struct { | ... | @@ -6110,7 +6134,8 @@ const DeclGen = struct { |
| 6110 | } | 6134 | } |
| 6111 | 6135 | ||
| 6112 | fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 6136 | fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 6113 | const mod = self.module; | 6137 | const pt = self.pt; |
| 6138 | const mod = pt.zcu; | ||
| 6114 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6139 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6115 | const operand_id = try self.resolve(ty_op.operand); | 6140 | const operand_id = try self.resolve(ty_op.operand); |
| 6116 | const operand_ty = self.typeOf(ty_op.operand); | 6141 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -6119,7 +6144,7 @@ const DeclGen = struct { | ... | @@ -6119,7 +6144,7 @@ const DeclGen = struct { |
| 6119 | const result_ty = self.typeOfIndex(inst); | 6144 | const result_ty = self.typeOfIndex(inst); |
| 6120 | const result_ty_id = try self.resolveType(result_ty, .direct); | 6145 | const result_ty_id = try self.resolveType(result_ty, .direct); |
| 6121 | 6146 | ||
| 6122 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6147 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6123 | // There is no payload, but we still need to return a valid pointer. | 6148 | // There is no payload, but we still need to return a valid pointer. |
| 6124 | // We can just return anything here, so just return a pointer to the operand. | 6149 | // We can just return anything here, so just return a pointer to the operand. |
| 6125 | return try self.bitCast(result_ty, operand_ty, operand_id); | 6150 | return try self.bitCast(result_ty, operand_ty, operand_id); |
| ... | @@ -6134,11 +6159,12 @@ const DeclGen = struct { | ... | @@ -6134,11 +6159,12 @@ const DeclGen = struct { |
| 6134 | } | 6159 | } |
| 6135 | 6160 | ||
| 6136 | fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 6161 | fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 6137 | const mod = self.module; | 6162 | const pt = self.pt; |
| 6163 | const mod = pt.zcu; | ||
| 6138 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6164 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6139 | const payload_ty = self.typeOf(ty_op.operand); | 6165 | const payload_ty = self.typeOf(ty_op.operand); |
| 6140 | 6166 | ||
| 6141 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6167 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { |
| 6142 | return try self.constBool(true, .indirect); | 6168 | return try self.constBool(true, .indirect); |
| 6143 | } | 6169 | } |
| 6144 | 6170 | ||
| ... | @@ -6156,7 +6182,8 @@ const DeclGen = struct { | ... | @@ -6156,7 +6182,8 @@ const DeclGen = struct { |
| 6156 | } | 6182 | } |
| 6157 | 6183 | ||
| 6158 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { | 6184 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 6159 | const mod = self.module; | 6185 | const pt = self.pt; |
| 6186 | const mod = pt.zcu; | ||
| 6160 | const target = self.getTarget(); | 6187 | const target = self.getTarget(); |
| 6161 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6188 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6162 | const cond_ty = self.typeOf(pl_op.operand); | 6189 | const cond_ty = self.typeOf(pl_op.operand); |
| ... | @@ -6240,15 +6267,15 @@ const DeclGen = struct { | ... | @@ -6240,15 +6267,15 @@ const DeclGen = struct { |
| 6240 | const label = case_labels.at(case_i); | 6267 | const label = case_labels.at(case_i); |
| 6241 | 6268 | ||
| 6242 | for (items) |item| { | 6269 | for (items) |item| { |
| 6243 | const value = (try self.air.value(item, mod)) orelse unreachable; | 6270 | const value = (try self.air.value(item, pt)) orelse unreachable; |
| 6244 | const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) { | 6271 | const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) { |
| 6245 | .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(mod)) else value.toUnsignedInt(mod), | 6272 | .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(pt)) else value.toUnsignedInt(pt), |
| 6246 | .Enum => blk: { | 6273 | .Enum => blk: { |
| 6247 | // TODO: figure out of cond_ty is correct (something with enum literals) | 6274 | // TODO: figure out of cond_ty is correct (something with enum literals) |
| 6248 | break :blk (try value.intFromEnum(cond_ty, mod)).toUnsignedInt(mod); // TODO: composite integer constants | 6275 | break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(pt); // TODO: composite integer constants |
| 6249 | }, | 6276 | }, |
| 6250 | .ErrorSet => value.getErrorInt(mod), | 6277 | .ErrorSet => value.getErrorInt(mod), |
| 6251 | .Pointer => value.toUnsignedInt(mod), | 6278 | .Pointer => value.toUnsignedInt(pt), |
| 6252 | else => unreachable, | 6279 | else => unreachable, |
| 6253 | }; | 6280 | }; |
| 6254 | const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) { | 6281 | const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) { |
| ... | @@ -6328,8 +6355,9 @@ const DeclGen = struct { | ... | @@ -6328,8 +6355,9 @@ const DeclGen = struct { |
| 6328 | } | 6355 | } |
| 6329 | 6356 | ||
| 6330 | fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void { | 6357 | fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 6358 | const pt = self.pt; | ||
| 6359 | const mod = pt.zcu; | ||
| 6331 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; | 6360 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 6332 | const mod = self.module; | ||
| 6333 | const decl = mod.declPtr(self.decl_index); | 6361 | const decl = mod.declPtr(self.decl_index); |
| 6334 | const path = decl.getFileScope(mod).sub_file_path; | 6362 | const path = decl.getFileScope(mod).sub_file_path; |
| 6335 | try self.func.body.emit(self.spv.gpa, .OpLine, .{ | 6363 | try self.func.body.emit(self.spv.gpa, .OpLine, .{ |
| ... | @@ -6340,7 +6368,7 @@ const DeclGen = struct { | ... | @@ -6340,7 +6368,7 @@ const DeclGen = struct { |
| 6340 | } | 6368 | } |
| 6341 | 6369 | ||
| 6342 | fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 6370 | fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 6343 | const mod = self.module; | 6371 | const mod = self.pt.zcu; |
| 6344 | const inst_datas = self.air.instructions.items(.data); | 6372 | const inst_datas = self.air.instructions.items(.data); |
| 6345 | const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload); | 6373 | const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload); |
| 6346 | const decl = mod.funcOwnerDeclPtr(extra.data.func); | 6374 | const decl = mod.funcOwnerDeclPtr(extra.data.func); |
| ... | @@ -6358,7 +6386,7 @@ const DeclGen = struct { | ... | @@ -6358,7 +6386,7 @@ const DeclGen = struct { |
| 6358 | } | 6386 | } |
| 6359 | 6387 | ||
| 6360 | fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 6388 | fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 6361 | const mod = self.module; | 6389 | const mod = self.pt.zcu; |
| 6362 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6390 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6363 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); | 6391 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 6364 | 6392 | ||
| ... | @@ -6440,20 +6468,20 @@ const DeclGen = struct { | ... | @@ -6440,20 +6468,20 @@ const DeclGen = struct { |
| 6440 | // TODO: Translate proper error locations. | 6468 | // TODO: Translate proper error locations. |
| 6441 | assert(as.errors.items.len != 0); | 6469 | assert(as.errors.items.len != 0); |
| 6442 | assert(self.error_msg == null); | 6470 | assert(self.error_msg == null); |
| 6443 | const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod); | 6471 | const src_loc = mod.declPtr(self.decl_index).navSrcLoc(mod); |
| 6444 | self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); | 6472 | self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); |
| 6445 | const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len); | 6473 | const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len); |
| 6446 | 6474 | ||
| 6447 | // Sub-scope to prevent `return error.CodegenFail` from running the errdefers. | 6475 | // Sub-scope to prevent `return error.CodegenFail` from running the errdefers. |
| 6448 | { | 6476 | { |
| 6449 | errdefer self.module.gpa.free(notes); | 6477 | errdefer mod.gpa.free(notes); |
| 6450 | var i: usize = 0; | 6478 | var i: usize = 0; |
| 6451 | errdefer for (notes[0..i]) |*note| { | 6479 | errdefer for (notes[0..i]) |*note| { |
| 6452 | note.deinit(self.module.gpa); | 6480 | note.deinit(mod.gpa); |
| 6453 | }; | 6481 | }; |
| 6454 | 6482 | ||
| 6455 | while (i < as.errors.items.len) : (i += 1) { | 6483 | while (i < as.errors.items.len) : (i += 1) { |
| 6456 | notes[i] = try Module.ErrorMsg.init(self.module.gpa, src_loc, "{s}", .{as.errors.items[i].msg}); | 6484 | notes[i] = try Zcu.ErrorMsg.init(mod.gpa, src_loc, "{s}", .{as.errors.items[i].msg}); |
| 6457 | } | 6485 | } |
| 6458 | } | 6486 | } |
| 6459 | self.error_msg.?.notes = notes; | 6487 | self.error_msg.?.notes = notes; |
| ... | @@ -6489,7 +6517,8 @@ const DeclGen = struct { | ... | @@ -6489,7 +6517,8 @@ const DeclGen = struct { |
| 6489 | fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef { | 6517 | fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef { |
| 6490 | _ = modifier; | 6518 | _ = modifier; |
| 6491 | 6519 | ||
| 6492 | const mod = self.module; | 6520 | const pt = self.pt; |
| 6521 | const mod = pt.zcu; | ||
| 6493 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6522 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6494 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 6523 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 6495 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); | 6524 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| ... | @@ -6515,7 +6544,7 @@ const DeclGen = struct { | ... | @@ -6515,7 +6544,7 @@ const DeclGen = struct { |
| 6515 | // before starting to emit OpFunctionCall instructions. Hence the | 6544 | // before starting to emit OpFunctionCall instructions. Hence the |
| 6516 | // temporary params buffer. | 6545 | // temporary params buffer. |
| 6517 | const arg_ty = self.typeOf(arg); | 6546 | const arg_ty = self.typeOf(arg); |
| 6518 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; | 6547 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; |
| 6519 | const arg_id = try self.resolve(arg); | 6548 | const arg_id = try self.resolve(arg); |
| 6520 | 6549 | ||
| 6521 | params[n_params] = arg_id; | 6550 | params[n_params] = arg_id; |
| ... | @@ -6533,7 +6562,7 @@ const DeclGen = struct { | ... | @@ -6533,7 +6562,7 @@ const DeclGen = struct { |
| 6533 | try self.func.body.emit(self.spv.gpa, .OpUnreachable, {}); | 6562 | try self.func.body.emit(self.spv.gpa, .OpUnreachable, {}); |
| 6534 | } | 6563 | } |
| 6535 | 6564 | ||
| 6536 | if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(mod)) { | 6565 | if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(pt)) { |
| 6537 | return null; | 6566 | return null; |
| 6538 | } | 6567 | } |
| 6539 | 6568 | ||
| ... | @@ -6541,11 +6570,10 @@ const DeclGen = struct { | ... | @@ -6541,11 +6570,10 @@ const DeclGen = struct { |
| 6541 | } | 6570 | } |
| 6542 | 6571 | ||
| 6543 | fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef { | 6572 | fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef { |
| 6544 | const mod = self.module; | ||
| 6545 | if (dimension >= 3) { | 6573 | if (dimension >= 3) { |
| 6546 | return try self.constInt(result_ty, out_of_range_value, .direct); | 6574 | return try self.constInt(result_ty, out_of_range_value, .direct); |
| 6547 | } | 6575 | } |
| 6548 | const vec_ty = try mod.vectorType(.{ | 6576 | const vec_ty = try self.pt.vectorType(.{ |
| 6549 | .len = 3, | 6577 | .len = 3, |
| 6550 | .child = result_ty.toIntern(), | 6578 | .child = result_ty.toIntern(), |
| 6551 | }); | 6579 | }); |
| ... | @@ -6591,12 +6619,12 @@ const DeclGen = struct { | ... | @@ -6591,12 +6619,12 @@ const DeclGen = struct { |
| 6591 | } | 6619 | } |
| 6592 | 6620 | ||
| 6593 | fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type { | 6621 | fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type { |
| 6594 | const mod = self.module; | 6622 | const mod = self.pt.zcu; |
| 6595 | return self.air.typeOf(inst, &mod.intern_pool); | 6623 | return self.air.typeOf(inst, &mod.intern_pool); |
| 6596 | } | 6624 | } |
| 6597 | 6625 | ||
| 6598 | fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type { | 6626 | fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type { |
| 6599 | const mod = self.module; | 6627 | const mod = self.pt.zcu; |
| 6600 | return self.air.typeOfIndex(inst, &mod.intern_pool); | 6628 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 6601 | } | 6629 | } |
| 6602 | }; | 6630 | }; |
src/crash_report.zig+3-3| ... | @@ -76,9 +76,9 @@ fn dumpStatusReport() !void { | ... | @@ -76,9 +76,9 @@ fn dumpStatusReport() !void { |
| 76 | 76 | ||
| 77 | const stderr = io.getStdErr().writer(); | 77 | const stderr = io.getStdErr().writer(); |
| 78 | const block: *Sema.Block = anal.block; | 78 | const block: *Sema.Block = anal.block; |
| 79 | const mod = anal.sema.mod; | 79 | const zcu = anal.sema.pt.zcu; |
| 80 | 80 | ||
| 81 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod); | 81 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu); |
| 82 | 82 | ||
| 83 | try stderr.writeAll("Analyzing "); | 83 | try stderr.writeAll("Analyzing "); |
| 84 | try writeFilePath(file, stderr); | 84 | try writeFilePath(file, stderr); |
| ... | @@ -104,7 +104,7 @@ fn dumpStatusReport() !void { | ... | @@ -104,7 +104,7 @@ fn dumpStatusReport() !void { |
| 104 | while (parent) |curr| { | 104 | while (parent) |curr| { |
| 105 | fba.reset(); | 105 | fba.reset(); |
| 106 | try stderr.writeAll(" in "); | 106 | try stderr.writeAll(" in "); |
| 107 | const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, mod); | 107 | const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu); |
| 108 | try writeFilePath(cur_block_file, stderr); | 108 | try writeFilePath(cur_block_file, stderr); |
| 109 | try stderr.writeAll("\n > "); | 109 | try stderr.writeAll("\n > "); |
| 110 | print_zir.renderSingleInstruction( | 110 | print_zir.renderSingleInstruction( |
src/link.zig+24-25| ... | @@ -15,8 +15,6 @@ const Compilation = @import("Compilation.zig"); | ... | @@ -15,8 +15,6 @@ const Compilation = @import("Compilation.zig"); |
| 15 | const LibCInstallation = std.zig.LibCInstallation; | 15 | const LibCInstallation = std.zig.LibCInstallation; |
| 16 | const Liveness = @import("Liveness.zig"); | 16 | const Liveness = @import("Liveness.zig"); |
| 17 | const Zcu = @import("Zcu.zig"); | 17 | const Zcu = @import("Zcu.zig"); |
| 18 | /// Deprecated. | ||
| 19 | const Module = Zcu; | ||
| 20 | const InternPool = @import("InternPool.zig"); | 18 | const InternPool = @import("InternPool.zig"); |
| 21 | const Type = @import("Type.zig"); | 19 | const Type = @import("Type.zig"); |
| 22 | const Value = @import("Value.zig"); | 20 | const Value = @import("Value.zig"); |
| ... | @@ -367,14 +365,14 @@ pub const File = struct { | ... | @@ -367,14 +365,14 @@ pub const File = struct { |
| 367 | /// Called from within the CodeGen to lower a local variable instantion as an unnamed | 365 | /// Called from within the CodeGen to lower a local variable instantion as an unnamed |
| 368 | /// constant. Returns the symbol index of the lowered constant in the read-only section | 366 | /// constant. Returns the symbol index of the lowered constant in the read-only section |
| 369 | /// of the final binary. | 367 | /// of the final binary. |
| 370 | pub fn lowerUnnamedConst(base: *File, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { | 368 | pub fn lowerUnnamedConst(base: *File, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { |
| 371 | if (build_options.only_c) @compileError("unreachable"); | 369 | if (build_options.only_c) @compileError("unreachable"); |
| 372 | switch (base.tag) { | 370 | switch (base.tag) { |
| 373 | .spirv => unreachable, | 371 | .spirv => unreachable, |
| 374 | .c => unreachable, | 372 | .c => unreachable, |
| 375 | .nvptx => unreachable, | 373 | .nvptx => unreachable, |
| 376 | inline else => |t| { | 374 | inline else => |t| { |
| 377 | return @as(*t.Type(), @fieldParentPtr("base", base)).lowerUnnamedConst(val, decl_index); | 375 | return @as(*t.Type(), @fieldParentPtr("base", base)).lowerUnnamedConst(pt, val, decl_index); |
| 378 | }, | 376 | }, |
| 379 | } | 377 | } |
| 380 | } | 378 | } |
| ... | @@ -399,13 +397,13 @@ pub const File = struct { | ... | @@ -399,13 +397,13 @@ pub const File = struct { |
| 399 | } | 397 | } |
| 400 | 398 | ||
| 401 | /// May be called before or after updateExports for any given Decl. | 399 | /// May be called before or after updateExports for any given Decl. |
| 402 | pub fn updateDecl(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { | 400 | pub fn updateDecl(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 403 | const decl = module.declPtr(decl_index); | 401 | const decl = pt.zcu.declPtr(decl_index); |
| 404 | assert(decl.has_tv); | 402 | assert(decl.has_tv); |
| 405 | switch (base.tag) { | 403 | switch (base.tag) { |
| 406 | inline else => |tag| { | 404 | inline else => |tag| { |
| 407 | if (tag != .c and build_options.only_c) unreachable; | 405 | if (tag != .c and build_options.only_c) unreachable; |
| 408 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDecl(module, decl_index); | 406 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDecl(pt, decl_index); |
| 409 | }, | 407 | }, |
| 410 | } | 408 | } |
| 411 | } | 409 | } |
| ... | @@ -413,7 +411,7 @@ pub const File = struct { | ... | @@ -413,7 +411,7 @@ pub const File = struct { |
| 413 | /// May be called before or after updateExports for any given Decl. | 411 | /// May be called before or after updateExports for any given Decl. |
| 414 | pub fn updateFunc( | 412 | pub fn updateFunc( |
| 415 | base: *File, | 413 | base: *File, |
| 416 | module: *Module, | 414 | pt: Zcu.PerThread, |
| 417 | func_index: InternPool.Index, | 415 | func_index: InternPool.Index, |
| 418 | air: Air, | 416 | air: Air, |
| 419 | liveness: Liveness, | 417 | liveness: Liveness, |
| ... | @@ -421,12 +419,12 @@ pub const File = struct { | ... | @@ -421,12 +419,12 @@ pub const File = struct { |
| 421 | switch (base.tag) { | 419 | switch (base.tag) { |
| 422 | inline else => |tag| { | 420 | inline else => |tag| { |
| 423 | if (tag != .c and build_options.only_c) unreachable; | 421 | if (tag != .c and build_options.only_c) unreachable; |
| 424 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(module, func_index, air, liveness); | 422 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, air, liveness); |
| 425 | }, | 423 | }, |
| 426 | } | 424 | } |
| 427 | } | 425 | } |
| 428 | 426 | ||
| 429 | pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { | 427 | pub fn updateDeclLineNumber(base: *File, module: *Zcu, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 430 | const decl = module.declPtr(decl_index); | 428 | const decl = module.declPtr(decl_index); |
| 431 | assert(decl.has_tv); | 429 | assert(decl.has_tv); |
| 432 | switch (base.tag) { | 430 | switch (base.tag) { |
| ... | @@ -537,7 +535,7 @@ pub const File = struct { | ... | @@ -537,7 +535,7 @@ pub const File = struct { |
| 537 | /// Commit pending changes and write headers. Takes into account final output mode | 535 | /// Commit pending changes and write headers. Takes into account final output mode |
| 538 | /// and `use_lld`, not only `effectiveOutputMode`. | 536 | /// and `use_lld`, not only `effectiveOutputMode`. |
| 539 | /// `arena` has the lifetime of the call to `Compilation.update`. | 537 | /// `arena` has the lifetime of the call to `Compilation.update`. |
| 540 | pub fn flush(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { | 538 | pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { |
| 541 | if (build_options.only_c) { | 539 | if (build_options.only_c) { |
| 542 | assert(base.tag == .c); | 540 | assert(base.tag == .c); |
| 543 | return @as(*C, @fieldParentPtr("base", base)).flush(arena, prog_node); | 541 | return @as(*C, @fieldParentPtr("base", base)).flush(arena, prog_node); |
| ... | @@ -563,27 +561,27 @@ pub const File = struct { | ... | @@ -563,27 +561,27 @@ pub const File = struct { |
| 563 | const output_mode = comp.config.output_mode; | 561 | const output_mode = comp.config.output_mode; |
| 564 | const link_mode = comp.config.link_mode; | 562 | const link_mode = comp.config.link_mode; |
| 565 | if (use_lld and output_mode == .Lib and link_mode == .static) { | 563 | if (use_lld and output_mode == .Lib and link_mode == .static) { |
| 566 | return base.linkAsArchive(arena, prog_node); | 564 | return base.linkAsArchive(arena, tid, prog_node); |
| 567 | } | 565 | } |
| 568 | switch (base.tag) { | 566 | switch (base.tag) { |
| 569 | inline else => |tag| { | 567 | inline else => |tag| { |
| 570 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flush(arena, prog_node); | 568 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flush(arena, tid, prog_node); |
| 571 | }, | 569 | }, |
| 572 | } | 570 | } |
| 573 | } | 571 | } |
| 574 | 572 | ||
| 575 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` | 573 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 576 | /// rather than final output mode. | 574 | /// rather than final output mode. |
| 577 | pub fn flushModule(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { | 575 | pub fn flushModule(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { |
| 578 | switch (base.tag) { | 576 | switch (base.tag) { |
| 579 | inline else => |tag| { | 577 | inline else => |tag| { |
| 580 | if (tag != .c and build_options.only_c) unreachable; | 578 | if (tag != .c and build_options.only_c) unreachable; |
| 581 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, prog_node); | 579 | return @as(*tag.Type(), @fieldParentPtr("base", base)).flushModule(arena, tid, prog_node); |
| 582 | }, | 580 | }, |
| 583 | } | 581 | } |
| 584 | } | 582 | } |
| 585 | 583 | ||
| 586 | /// Called when a Decl is deleted from the Module. | 584 | /// Called when a Decl is deleted from the Zcu. |
| 587 | pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void { | 585 | pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void { |
| 588 | switch (base.tag) { | 586 | switch (base.tag) { |
| 589 | inline else => |tag| { | 587 | inline else => |tag| { |
| ... | @@ -604,14 +602,14 @@ pub const File = struct { | ... | @@ -604,14 +602,14 @@ pub const File = struct { |
| 604 | /// May be called before or after updateDecl for any given Decl. | 602 | /// May be called before or after updateDecl for any given Decl. |
| 605 | pub fn updateExports( | 603 | pub fn updateExports( |
| 606 | base: *File, | 604 | base: *File, |
| 607 | module: *Module, | 605 | pt: Zcu.PerThread, |
| 608 | exported: Module.Exported, | 606 | exported: Zcu.Exported, |
| 609 | export_indices: []const u32, | 607 | export_indices: []const u32, |
| 610 | ) UpdateExportsError!void { | 608 | ) UpdateExportsError!void { |
| 611 | switch (base.tag) { | 609 | switch (base.tag) { |
| 612 | inline else => |tag| { | 610 | inline else => |tag| { |
| 613 | if (tag != .c and build_options.only_c) unreachable; | 611 | if (tag != .c and build_options.only_c) unreachable; |
| 614 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(module, exported, export_indices); | 612 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateExports(pt, exported, export_indices); |
| 615 | }, | 613 | }, |
| 616 | } | 614 | } |
| 617 | } | 615 | } |
| ... | @@ -644,9 +642,10 @@ pub const File = struct { | ... | @@ -644,9 +642,10 @@ pub const File = struct { |
| 644 | 642 | ||
| 645 | pub fn lowerAnonDecl( | 643 | pub fn lowerAnonDecl( |
| 646 | base: *File, | 644 | base: *File, |
| 645 | pt: Zcu.PerThread, | ||
| 647 | decl_val: InternPool.Index, | 646 | decl_val: InternPool.Index, |
| 648 | decl_align: InternPool.Alignment, | 647 | decl_align: InternPool.Alignment, |
| 649 | src_loc: Module.LazySrcLoc, | 648 | src_loc: Zcu.LazySrcLoc, |
| 650 | ) !LowerResult { | 649 | ) !LowerResult { |
| 651 | if (build_options.only_c) @compileError("unreachable"); | 650 | if (build_options.only_c) @compileError("unreachable"); |
| 652 | switch (base.tag) { | 651 | switch (base.tag) { |
| ... | @@ -654,7 +653,7 @@ pub const File = struct { | ... | @@ -654,7 +653,7 @@ pub const File = struct { |
| 654 | .spirv => unreachable, | 653 | .spirv => unreachable, |
| 655 | .nvptx => unreachable, | 654 | .nvptx => unreachable, |
| 656 | inline else => |tag| { | 655 | inline else => |tag| { |
| 657 | return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerAnonDecl(decl_val, decl_align, src_loc); | 656 | return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerAnonDecl(pt, decl_val, decl_align, src_loc); |
| 658 | }, | 657 | }, |
| 659 | } | 658 | } |
| 660 | } | 659 | } |
| ... | @@ -689,7 +688,7 @@ pub const File = struct { | ... | @@ -689,7 +688,7 @@ pub const File = struct { |
| 689 | } | 688 | } |
| 690 | } | 689 | } |
| 691 | 690 | ||
| 692 | pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { | 691 | pub fn linkAsArchive(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void { |
| 693 | const tracy = trace(@src()); | 692 | const tracy = trace(@src()); |
| 694 | defer tracy.end(); | 693 | defer tracy.end(); |
| 695 | 694 | ||
| ... | @@ -704,7 +703,7 @@ pub const File = struct { | ... | @@ -704,7 +703,7 @@ pub const File = struct { |
| 704 | // If there is no Zig code to compile, then we should skip flushing the output file | 703 | // If there is no Zig code to compile, then we should skip flushing the output file |
| 705 | // because it will not be part of the linker line anyway. | 704 | // because it will not be part of the linker line anyway. |
| 706 | const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: { | 705 | const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: { |
| 707 | try base.flushModule(arena, prog_node); | 706 | try base.flushModule(arena, tid, prog_node); |
| 708 | 707 | ||
| 709 | const dirname = fs.path.dirname(full_out_path_z) orelse "."; | 708 | const dirname = fs.path.dirname(full_out_path_z) orelse "."; |
| 710 | break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? }); | 709 | break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? }); |
| ... | @@ -896,14 +895,14 @@ pub const File = struct { | ... | @@ -896,14 +895,14 @@ pub const File = struct { |
| 896 | kind: Kind, | 895 | kind: Kind, |
| 897 | ty: Type, | 896 | ty: Type, |
| 898 | 897 | ||
| 899 | pub fn initDecl(kind: Kind, decl: ?InternPool.DeclIndex, mod: *Module) LazySymbol { | 898 | pub fn initDecl(kind: Kind, decl: ?InternPool.DeclIndex, mod: *Zcu) LazySymbol { |
| 900 | return .{ .kind = kind, .ty = if (decl) |decl_index| | 899 | return .{ .kind = kind, .ty = if (decl) |decl_index| |
| 901 | mod.declPtr(decl_index).val.toType() | 900 | mod.declPtr(decl_index).val.toType() |
| 902 | else | 901 | else |
| 903 | Type.anyerror }; | 902 | Type.anyerror }; |
| 904 | } | 903 | } |
| 905 | 904 | ||
| 906 | pub fn getDecl(self: LazySymbol, mod: *Module) InternPool.OptionalDeclIndex { | 905 | pub fn getDecl(self: LazySymbol, mod: *Zcu) InternPool.OptionalDeclIndex { |
| 907 | return InternPool.OptionalDeclIndex.init(self.ty.getOwnerDeclOrNull(mod)); | 906 | return InternPool.OptionalDeclIndex.init(self.ty.getOwnerDeclOrNull(mod)); |
| 908 | } | 907 | } |
| 909 | }; | 908 | }; |
src/link/C.zig+31-28| ... | @@ -186,13 +186,13 @@ pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void { | ... | @@ -186,13 +186,13 @@ pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void { |
| 186 | 186 | ||
| 187 | pub fn updateFunc( | 187 | pub fn updateFunc( |
| 188 | self: *C, | 188 | self: *C, |
| 189 | zcu: *Zcu, | 189 | pt: Zcu.PerThread, |
| 190 | func_index: InternPool.Index, | 190 | func_index: InternPool.Index, |
| 191 | air: Air, | 191 | air: Air, |
| 192 | liveness: Liveness, | 192 | liveness: Liveness, |
| 193 | ) !void { | 193 | ) !void { |
| 194 | const gpa = self.base.comp.gpa; | 194 | const zcu = pt.zcu; |
| 195 | 195 | const gpa = zcu.gpa; | |
| 196 | const func = zcu.funcInfo(func_index); | 196 | const func = zcu.funcInfo(func_index); |
| 197 | const decl_index = func.owner_decl; | 197 | const decl_index = func.owner_decl; |
| 198 | const decl = zcu.declPtr(decl_index); | 198 | const decl = zcu.declPtr(decl_index); |
| ... | @@ -218,7 +218,7 @@ pub fn updateFunc( | ... | @@ -218,7 +218,7 @@ pub fn updateFunc( |
| 218 | .object = .{ | 218 | .object = .{ |
| 219 | .dg = .{ | 219 | .dg = .{ |
| 220 | .gpa = gpa, | 220 | .gpa = gpa, |
| 221 | .zcu = zcu, | 221 | .pt = pt, |
| 222 | .mod = file_scope.mod, | 222 | .mod = file_scope.mod, |
| 223 | .error_msg = null, | 223 | .error_msg = null, |
| 224 | .pass = .{ .decl = decl_index }, | 224 | .pass = .{ .decl = decl_index }, |
| ... | @@ -263,7 +263,7 @@ pub fn updateFunc( | ... | @@ -263,7 +263,7 @@ pub fn updateFunc( |
| 263 | gop.value_ptr.code = try self.addString(function.object.code.items); | 263 | gop.value_ptr.code = try self.addString(function.object.code.items); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void { | 266 | fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void { |
| 267 | const gpa = self.base.comp.gpa; | 267 | const gpa = self.base.comp.gpa; |
| 268 | const anon_decl = self.anon_decls.keys()[i]; | 268 | const anon_decl = self.anon_decls.keys()[i]; |
| 269 | 269 | ||
| ... | @@ -275,8 +275,8 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void { | ... | @@ -275,8 +275,8 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void { |
| 275 | var object: codegen.Object = .{ | 275 | var object: codegen.Object = .{ |
| 276 | .dg = .{ | 276 | .dg = .{ |
| 277 | .gpa = gpa, | 277 | .gpa = gpa, |
| 278 | .zcu = zcu, | 278 | .pt = pt, |
| 279 | .mod = zcu.root_mod, | 279 | .mod = pt.zcu.root_mod, |
| 280 | .error_msg = null, | 280 | .error_msg = null, |
| 281 | .pass = .{ .anon = anon_decl }, | 281 | .pass = .{ .anon = anon_decl }, |
| 282 | .is_naked_fn = false, | 282 | .is_naked_fn = false, |
| ... | @@ -319,12 +319,13 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void { | ... | @@ -319,12 +319,13 @@ fn updateAnonDecl(self: *C, zcu: *Zcu, i: usize) !void { |
| 319 | }; | 319 | }; |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { | 322 | pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 323 | const tracy = trace(@src()); | 323 | const tracy = trace(@src()); |
| 324 | defer tracy.end(); | 324 | defer tracy.end(); |
| 325 | 325 | ||
| 326 | const gpa = self.base.comp.gpa; | 326 | const gpa = self.base.comp.gpa; |
| 327 | 327 | ||
| 328 | const zcu = pt.zcu; | ||
| 328 | const decl = zcu.declPtr(decl_index); | 329 | const decl = zcu.declPtr(decl_index); |
| 329 | const gop = try self.decl_table.getOrPut(gpa, decl_index); | 330 | const gop = try self.decl_table.getOrPut(gpa, decl_index); |
| 330 | errdefer _ = self.decl_table.pop(); | 331 | errdefer _ = self.decl_table.pop(); |
| ... | @@ -342,7 +343,7 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { | ... | @@ -342,7 +343,7 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { |
| 342 | var object: codegen.Object = .{ | 343 | var object: codegen.Object = .{ |
| 343 | .dg = .{ | 344 | .dg = .{ |
| 344 | .gpa = gpa, | 345 | .gpa = gpa, |
| 345 | .zcu = zcu, | 346 | .pt = pt, |
| 346 | .mod = file_scope.mod, | 347 | .mod = file_scope.mod, |
| 347 | .error_msg = null, | 348 | .error_msg = null, |
| 348 | .pass = .{ .decl = decl_index }, | 349 | .pass = .{ .decl = decl_index }, |
| ... | @@ -390,8 +391,8 @@ pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclInde | ... | @@ -390,8 +391,8 @@ pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclInde |
| 390 | _ = decl_index; | 391 | _ = decl_index; |
| 391 | } | 392 | } |
| 392 | 393 | ||
| 393 | pub fn flush(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void { | 394 | pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 394 | return self.flushModule(arena, prog_node); | 395 | return self.flushModule(arena, tid, prog_node); |
| 395 | } | 396 | } |
| 396 | 397 | ||
| 397 | fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { | 398 | fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { |
| ... | @@ -409,7 +410,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { | ... | @@ -409,7 +410,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { |
| 409 | return defines; | 410 | return defines; |
| 410 | } | 411 | } |
| 411 | 412 | ||
| 412 | pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void { | 413 | pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 413 | _ = arena; // Has the same lifetime as the call to Compilation.update. | 414 | _ = arena; // Has the same lifetime as the call to Compilation.update. |
| 414 | 415 | ||
| 415 | const tracy = trace(@src()); | 416 | const tracy = trace(@src()); |
| ... | @@ -421,11 +422,12 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo | ... | @@ -421,11 +422,12 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo |
| 421 | const comp = self.base.comp; | 422 | const comp = self.base.comp; |
| 422 | const gpa = comp.gpa; | 423 | const gpa = comp.gpa; |
| 423 | const zcu = self.base.comp.module.?; | 424 | const zcu = self.base.comp.module.?; |
| 425 | const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = tid }; | ||
| 424 | 426 | ||
| 425 | { | 427 | { |
| 426 | var i: usize = 0; | 428 | var i: usize = 0; |
| 427 | while (i < self.anon_decls.count()) : (i += 1) { | 429 | while (i < self.anon_decls.count()) : (i += 1) { |
| 428 | try updateAnonDecl(self, zcu, i); | 430 | try updateAnonDecl(self, pt, i); |
| 429 | } | 431 | } |
| 430 | } | 432 | } |
| 431 | 433 | ||
| ... | @@ -463,7 +465,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo | ... | @@ -463,7 +465,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo |
| 463 | self.lazy_fwd_decl_buf.clearRetainingCapacity(); | 465 | self.lazy_fwd_decl_buf.clearRetainingCapacity(); |
| 464 | self.lazy_code_buf.clearRetainingCapacity(); | 466 | self.lazy_code_buf.clearRetainingCapacity(); |
| 465 | try f.lazy_ctype_pool.init(gpa); | 467 | try f.lazy_ctype_pool.init(gpa); |
| 466 | try self.flushErrDecls(zcu, &f.lazy_ctype_pool); | 468 | try self.flushErrDecls(pt, &f.lazy_ctype_pool); |
| 467 | 469 | ||
| 468 | // Unlike other backends, the .c code we are emitting has order-dependent decls. | 470 | // Unlike other backends, the .c code we are emitting has order-dependent decls. |
| 469 | // `CType`s, forward decls, and non-functions first. | 471 | // `CType`s, forward decls, and non-functions first. |
| ... | @@ -483,7 +485,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo | ... | @@ -483,7 +485,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo |
| 483 | } | 485 | } |
| 484 | 486 | ||
| 485 | for (self.anon_decls.keys(), self.anon_decls.values()) |value, *decl_block| try self.flushDeclBlock( | 487 | for (self.anon_decls.keys(), self.anon_decls.values()) |value, *decl_block| try self.flushDeclBlock( |
| 486 | zcu, | 488 | pt, |
| 487 | zcu.root_mod, | 489 | zcu.root_mod, |
| 488 | &f, | 490 | &f, |
| 489 | decl_block, | 491 | decl_block, |
| ... | @@ -497,7 +499,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo | ... | @@ -497,7 +499,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo |
| 497 | const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none; | 499 | const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none; |
| 498 | const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod; | 500 | const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod; |
| 499 | try self.flushDeclBlock( | 501 | try self.flushDeclBlock( |
| 500 | zcu, | 502 | pt, |
| 501 | mod, | 503 | mod, |
| 502 | &f, | 504 | &f, |
| 503 | decl_block, | 505 | decl_block, |
| ... | @@ -670,7 +672,7 @@ fn flushCTypes( | ... | @@ -670,7 +672,7 @@ fn flushCTypes( |
| 670 | } | 672 | } |
| 671 | } | 673 | } |
| 672 | 674 | ||
| 673 | fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDeclError!void { | 675 | fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) FlushDeclError!void { |
| 674 | const gpa = self.base.comp.gpa; | 676 | const gpa = self.base.comp.gpa; |
| 675 | 677 | ||
| 676 | const fwd_decl = &self.lazy_fwd_decl_buf; | 678 | const fwd_decl = &self.lazy_fwd_decl_buf; |
| ... | @@ -679,8 +681,8 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl | ... | @@ -679,8 +681,8 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl |
| 679 | var object = codegen.Object{ | 681 | var object = codegen.Object{ |
| 680 | .dg = .{ | 682 | .dg = .{ |
| 681 | .gpa = gpa, | 683 | .gpa = gpa, |
| 682 | .zcu = zcu, | 684 | .pt = pt, |
| 683 | .mod = zcu.root_mod, | 685 | .mod = pt.zcu.root_mod, |
| 684 | .error_msg = null, | 686 | .error_msg = null, |
| 685 | .pass = .flush, | 687 | .pass = .flush, |
| 686 | .is_naked_fn = false, | 688 | .is_naked_fn = false, |
| ... | @@ -712,7 +714,7 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl | ... | @@ -712,7 +714,7 @@ fn flushErrDecls(self: *C, zcu: *Zcu, ctype_pool: *codegen.CType.Pool) FlushDecl |
| 712 | 714 | ||
| 713 | fn flushLazyFn( | 715 | fn flushLazyFn( |
| 714 | self: *C, | 716 | self: *C, |
| 715 | zcu: *Zcu, | 717 | pt: Zcu.PerThread, |
| 716 | mod: *Module, | 718 | mod: *Module, |
| 717 | ctype_pool: *codegen.CType.Pool, | 719 | ctype_pool: *codegen.CType.Pool, |
| 718 | lazy_ctype_pool: *const codegen.CType.Pool, | 720 | lazy_ctype_pool: *const codegen.CType.Pool, |
| ... | @@ -726,7 +728,7 @@ fn flushLazyFn( | ... | @@ -726,7 +728,7 @@ fn flushLazyFn( |
| 726 | var object = codegen.Object{ | 728 | var object = codegen.Object{ |
| 727 | .dg = .{ | 729 | .dg = .{ |
| 728 | .gpa = gpa, | 730 | .gpa = gpa, |
| 729 | .zcu = zcu, | 731 | .pt = pt, |
| 730 | .mod = mod, | 732 | .mod = mod, |
| 731 | .error_msg = null, | 733 | .error_msg = null, |
| 732 | .pass = .flush, | 734 | .pass = .flush, |
| ... | @@ -761,7 +763,7 @@ fn flushLazyFn( | ... | @@ -761,7 +763,7 @@ fn flushLazyFn( |
| 761 | 763 | ||
| 762 | fn flushLazyFns( | 764 | fn flushLazyFns( |
| 763 | self: *C, | 765 | self: *C, |
| 764 | zcu: *Zcu, | 766 | pt: Zcu.PerThread, |
| 765 | mod: *Module, | 767 | mod: *Module, |
| 766 | f: *Flush, | 768 | f: *Flush, |
| 767 | lazy_ctype_pool: *const codegen.CType.Pool, | 769 | lazy_ctype_pool: *const codegen.CType.Pool, |
| ... | @@ -775,13 +777,13 @@ fn flushLazyFns( | ... | @@ -775,13 +777,13 @@ fn flushLazyFns( |
| 775 | const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*); | 777 | const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*); |
| 776 | if (gop.found_existing) continue; | 778 | if (gop.found_existing) continue; |
| 777 | gop.value_ptr.* = {}; | 779 | gop.value_ptr.* = {}; |
| 778 | try self.flushLazyFn(zcu, mod, &f.lazy_ctype_pool, lazy_ctype_pool, entry); | 780 | try self.flushLazyFn(pt, mod, &f.lazy_ctype_pool, lazy_ctype_pool, entry); |
| 779 | } | 781 | } |
| 780 | } | 782 | } |
| 781 | 783 | ||
| 782 | fn flushDeclBlock( | 784 | fn flushDeclBlock( |
| 783 | self: *C, | 785 | self: *C, |
| 784 | zcu: *Zcu, | 786 | pt: Zcu.PerThread, |
| 785 | mod: *Module, | 787 | mod: *Module, |
| 786 | f: *Flush, | 788 | f: *Flush, |
| 787 | decl_block: *const DeclBlock, | 789 | decl_block: *const DeclBlock, |
| ... | @@ -790,7 +792,7 @@ fn flushDeclBlock( | ... | @@ -790,7 +792,7 @@ fn flushDeclBlock( |
| 790 | extern_name: InternPool.OptionalNullTerminatedString, | 792 | extern_name: InternPool.OptionalNullTerminatedString, |
| 791 | ) FlushDeclError!void { | 793 | ) FlushDeclError!void { |
| 792 | const gpa = self.base.comp.gpa; | 794 | const gpa = self.base.comp.gpa; |
| 793 | try self.flushLazyFns(zcu, mod, f, &decl_block.ctype_pool, decl_block.lazy_fns); | 795 | try self.flushLazyFns(pt, mod, f, &decl_block.ctype_pool, decl_block.lazy_fns); |
| 794 | try f.all_buffers.ensureUnusedCapacity(gpa, 1); | 796 | try f.all_buffers.ensureUnusedCapacity(gpa, 1); |
| 795 | // avoid emitting extern decls that are already exported | 797 | // avoid emitting extern decls that are already exported |
| 796 | if (extern_name.unwrap()) |name| if (export_names.contains(name)) return; | 798 | if (extern_name.unwrap()) |name| if (export_names.contains(name)) return; |
| ... | @@ -845,11 +847,12 @@ pub fn flushEmitH(zcu: *Zcu) !void { | ... | @@ -845,11 +847,12 @@ pub fn flushEmitH(zcu: *Zcu) !void { |
| 845 | 847 | ||
| 846 | pub fn updateExports( | 848 | pub fn updateExports( |
| 847 | self: *C, | 849 | self: *C, |
| 848 | zcu: *Zcu, | 850 | pt: Zcu.PerThread, |
| 849 | exported: Zcu.Exported, | 851 | exported: Zcu.Exported, |
| 850 | export_indices: []const u32, | 852 | export_indices: []const u32, |
| 851 | ) !void { | 853 | ) !void { |
| 852 | const gpa = self.base.comp.gpa; | 854 | const zcu = pt.zcu; |
| 855 | const gpa = zcu.gpa; | ||
| 853 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { | 856 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { |
| 854 | .decl_index => |decl_index| .{ | 857 | .decl_index => |decl_index| .{ |
| 855 | zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod, | 858 | zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod, |
| ... | @@ -869,7 +872,7 @@ pub fn updateExports( | ... | @@ -869,7 +872,7 @@ pub fn updateExports( |
| 869 | fwd_decl.clearRetainingCapacity(); | 872 | fwd_decl.clearRetainingCapacity(); |
| 870 | var dg: codegen.DeclGen = .{ | 873 | var dg: codegen.DeclGen = .{ |
| 871 | .gpa = gpa, | 874 | .gpa = gpa, |
| 872 | .zcu = zcu, | 875 | .pt = pt, |
| 873 | .mod = mod, | 876 | .mod = mod, |
| 874 | .error_msg = null, | 877 | .error_msg = null, |
| 875 | .pass = pass, | 878 | .pass = pass, |
src/link/Coff.zig+53-32| ... | @@ -1120,16 +1120,17 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void { | ... | @@ -1120,16 +1120,17 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void { |
| 1120 | self.getAtomPtr(atom_index).sym_index = 0; | 1120 | self.getAtomPtr(atom_index).sym_index = 0; |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 1123 | pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 1124 | if (build_options.skip_non_native and builtin.object_format != .coff) { | 1124 | if (build_options.skip_non_native and builtin.object_format != .coff) { |
| 1125 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1125 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1126 | } | 1126 | } |
| 1127 | if (self.llvm_object) |llvm_object| { | 1127 | if (self.llvm_object) |llvm_object| { |
| 1128 | return llvm_object.updateFunc(mod, func_index, air, liveness); | 1128 | return llvm_object.updateFunc(pt, func_index, air, liveness); |
| 1129 | } | 1129 | } |
| 1130 | const tracy = trace(@src()); | 1130 | const tracy = trace(@src()); |
| 1131 | defer tracy.end(); | 1131 | defer tracy.end(); |
| 1132 | 1132 | ||
| 1133 | const mod = pt.zcu; | ||
| 1133 | const func = mod.funcInfo(func_index); | 1134 | const func = mod.funcInfo(func_index); |
| 1134 | const decl_index = func.owner_decl; | 1135 | const decl_index = func.owner_decl; |
| 1135 | const decl = mod.declPtr(decl_index); | 1136 | const decl = mod.declPtr(decl_index); |
| ... | @@ -1144,6 +1145,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -1144,6 +1145,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: |
| 1144 | 1145 | ||
| 1145 | const res = try codegen.generateFunction( | 1146 | const res = try codegen.generateFunction( |
| 1146 | &self.base, | 1147 | &self.base, |
| 1148 | pt, | ||
| 1147 | decl.navSrcLoc(mod), | 1149 | decl.navSrcLoc(mod), |
| 1148 | func_index, | 1150 | func_index, |
| 1149 | air, | 1151 | air, |
| ... | @@ -1160,14 +1162,14 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -1160,14 +1162,14 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: |
| 1160 | }, | 1162 | }, |
| 1161 | }; | 1163 | }; |
| 1162 | 1164 | ||
| 1163 | try self.updateDeclCode(decl_index, code, .FUNCTION); | 1165 | try self.updateDeclCode(pt, decl_index, code, .FUNCTION); |
| 1164 | 1166 | ||
| 1165 | // Exports will be updated by `Zcu.processExports` after the update. | 1167 | // Exports will be updated by `Zcu.processExports` after the update. |
| 1166 | } | 1168 | } |
| 1167 | 1169 | ||
| 1168 | pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 1170 | pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 1169 | const gpa = self.base.comp.gpa; | 1171 | const mod = pt.zcu; |
| 1170 | const mod = self.base.comp.module.?; | 1172 | const gpa = mod.gpa; |
| 1171 | const decl = mod.declPtr(decl_index); | 1173 | const decl = mod.declPtr(decl_index); |
| 1172 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); | 1174 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); |
| 1173 | if (!gop.found_existing) { | 1175 | if (!gop.found_existing) { |
| ... | @@ -1179,7 +1181,7 @@ pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclInd | ... | @@ -1179,7 +1181,7 @@ pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclInd |
| 1179 | const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index }); | 1181 | const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index }); |
| 1180 | defer gpa.free(sym_name); | 1182 | defer gpa.free(sym_name); |
| 1181 | const ty = val.typeOf(mod); | 1183 | const ty = val.typeOf(mod); |
| 1182 | const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.navSrcLoc(mod))) { | 1184 | const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) { |
| 1183 | .ok => |atom_index| atom_index, | 1185 | .ok => |atom_index| atom_index, |
| 1184 | .fail => |em| { | 1186 | .fail => |em| { |
| 1185 | decl.analysis = .codegen_failure; | 1187 | decl.analysis = .codegen_failure; |
| ... | @@ -1197,7 +1199,15 @@ const LowerConstResult = union(enum) { | ... | @@ -1197,7 +1199,15 @@ const LowerConstResult = union(enum) { |
| 1197 | fail: *Module.ErrorMsg, | 1199 | fail: *Module.ErrorMsg, |
| 1198 | }; | 1200 | }; |
| 1199 | 1201 | ||
| 1200 | fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.LazySrcLoc) !LowerConstResult { | 1202 | fn lowerConst( |
| 1203 | self: *Coff, | ||
| 1204 | pt: Zcu.PerThread, | ||
| 1205 | name: []const u8, | ||
| 1206 | val: Value, | ||
| 1207 | required_alignment: InternPool.Alignment, | ||
| 1208 | sect_id: u16, | ||
| 1209 | src_loc: Module.LazySrcLoc, | ||
| 1210 | ) !LowerConstResult { | ||
| 1201 | const gpa = self.base.comp.gpa; | 1211 | const gpa = self.base.comp.gpa; |
| 1202 | 1212 | ||
| 1203 | var code_buffer = std.ArrayList(u8).init(gpa); | 1213 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1208,7 +1218,7 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int | ... | @@ -1208,7 +1218,7 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int |
| 1208 | try self.setSymbolName(sym, name); | 1218 | try self.setSymbolName(sym, name); |
| 1209 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1)); | 1219 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1)); |
| 1210 | 1220 | ||
| 1211 | const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .none, .{ | 1221 | const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .none, .{ |
| 1212 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, | 1222 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, |
| 1213 | }); | 1223 | }); |
| 1214 | const code = switch (res) { | 1224 | const code = switch (res) { |
| ... | @@ -1235,13 +1245,14 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int | ... | @@ -1235,13 +1245,14 @@ fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: Int |
| 1235 | 1245 | ||
| 1236 | pub fn updateDecl( | 1246 | pub fn updateDecl( |
| 1237 | self: *Coff, | 1247 | self: *Coff, |
| 1238 | mod: *Module, | 1248 | pt: Zcu.PerThread, |
| 1239 | decl_index: InternPool.DeclIndex, | 1249 | decl_index: InternPool.DeclIndex, |
| 1240 | ) link.File.UpdateDeclError!void { | 1250 | ) link.File.UpdateDeclError!void { |
| 1251 | const mod = pt.zcu; | ||
| 1241 | if (build_options.skip_non_native and builtin.object_format != .coff) { | 1252 | if (build_options.skip_non_native and builtin.object_format != .coff) { |
| 1242 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1253 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1243 | } | 1254 | } |
| 1244 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); | 1255 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index); |
| 1245 | const tracy = trace(@src()); | 1256 | const tracy = trace(@src()); |
| 1246 | defer tracy.end(); | 1257 | defer tracy.end(); |
| 1247 | 1258 | ||
| ... | @@ -1270,7 +1281,7 @@ pub fn updateDecl( | ... | @@ -1270,7 +1281,7 @@ pub fn updateDecl( |
| 1270 | defer code_buffer.deinit(); | 1281 | defer code_buffer.deinit(); |
| 1271 | 1282 | ||
| 1272 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 1283 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 1273 | const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{ | 1284 | const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{ |
| 1274 | .parent_atom_index = atom.getSymbolIndex().?, | 1285 | .parent_atom_index = atom.getSymbolIndex().?, |
| 1275 | }); | 1286 | }); |
| 1276 | const code = switch (res) { | 1287 | const code = switch (res) { |
| ... | @@ -1282,19 +1293,20 @@ pub fn updateDecl( | ... | @@ -1282,19 +1293,20 @@ pub fn updateDecl( |
| 1282 | }, | 1293 | }, |
| 1283 | }; | 1294 | }; |
| 1284 | 1295 | ||
| 1285 | try self.updateDeclCode(decl_index, code, .NULL); | 1296 | try self.updateDeclCode(pt, decl_index, code, .NULL); |
| 1286 | 1297 | ||
| 1287 | // Exports will be updated by `Zcu.processExports` after the update. | 1298 | // Exports will be updated by `Zcu.processExports` after the update. |
| 1288 | } | 1299 | } |
| 1289 | 1300 | ||
| 1290 | fn updateLazySymbolAtom( | 1301 | fn updateLazySymbolAtom( |
| 1291 | self: *Coff, | 1302 | self: *Coff, |
| 1303 | pt: Zcu.PerThread, | ||
| 1292 | sym: link.File.LazySymbol, | 1304 | sym: link.File.LazySymbol, |
| 1293 | atom_index: Atom.Index, | 1305 | atom_index: Atom.Index, |
| 1294 | section_index: u16, | 1306 | section_index: u16, |
| 1295 | ) !void { | 1307 | ) !void { |
| 1296 | const gpa = self.base.comp.gpa; | 1308 | const mod = pt.zcu; |
| 1297 | const mod = self.base.comp.module.?; | 1309 | const gpa = mod.gpa; |
| 1298 | 1310 | ||
| 1299 | var required_alignment: InternPool.Alignment = .none; | 1311 | var required_alignment: InternPool.Alignment = .none; |
| 1300 | var code_buffer = std.ArrayList(u8).init(gpa); | 1312 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1302,7 +1314,7 @@ fn updateLazySymbolAtom( | ... | @@ -1302,7 +1314,7 @@ fn updateLazySymbolAtom( |
| 1302 | 1314 | ||
| 1303 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ | 1315 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ |
| 1304 | @tagName(sym.kind), | 1316 | @tagName(sym.kind), |
| 1305 | sym.ty.fmt(mod), | 1317 | sym.ty.fmt(pt), |
| 1306 | }); | 1318 | }); |
| 1307 | defer gpa.free(name); | 1319 | defer gpa.free(name); |
| 1308 | 1320 | ||
| ... | @@ -1312,6 +1324,7 @@ fn updateLazySymbolAtom( | ... | @@ -1312,6 +1324,7 @@ fn updateLazySymbolAtom( |
| 1312 | const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; | 1324 | const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; |
| 1313 | const res = try codegen.generateLazySymbol( | 1325 | const res = try codegen.generateLazySymbol( |
| 1314 | &self.base, | 1326 | &self.base, |
| 1327 | pt, | ||
| 1315 | src, | 1328 | src, |
| 1316 | sym, | 1329 | sym, |
| 1317 | &required_alignment, | 1330 | &required_alignment, |
| ... | @@ -1346,7 +1359,7 @@ fn updateLazySymbolAtom( | ... | @@ -1346,7 +1359,7 @@ fn updateLazySymbolAtom( |
| 1346 | try self.writeAtom(atom_index, code); | 1359 | try self.writeAtom(atom_index, code); |
| 1347 | } | 1360 | } |
| 1348 | 1361 | ||
| 1349 | pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index { | 1362 | pub fn getOrCreateAtomForLazySymbol(self: *Coff, pt: Zcu.PerThread, sym: link.File.LazySymbol) !Atom.Index { |
| 1350 | const gpa = self.base.comp.gpa; | 1363 | const gpa = self.base.comp.gpa; |
| 1351 | const mod = self.base.comp.module.?; | 1364 | const mod = self.base.comp.module.?; |
| 1352 | const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod)); | 1365 | const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod)); |
| ... | @@ -1364,7 +1377,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato | ... | @@ -1364,7 +1377,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato |
| 1364 | metadata.state.* = .pending_flush; | 1377 | metadata.state.* = .pending_flush; |
| 1365 | const atom = metadata.atom.*; | 1378 | const atom = metadata.atom.*; |
| 1366 | // anyerror needs to be deferred until flushModule | 1379 | // anyerror needs to be deferred until flushModule |
| 1367 | if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) { | 1380 | if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(pt, sym, atom, switch (sym.kind) { |
| 1368 | .code => self.text_section_index.?, | 1381 | .code => self.text_section_index.?, |
| 1369 | .const_data => self.rdata_section_index.?, | 1382 | .const_data => self.rdata_section_index.?, |
| 1370 | }); | 1383 | }); |
| ... | @@ -1410,14 +1423,14 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { | ... | @@ -1410,14 +1423,14 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { |
| 1410 | return index; | 1423 | return index; |
| 1411 | } | 1424 | } |
| 1412 | 1425 | ||
| 1413 | fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void { | 1426 | fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void { |
| 1414 | const mod = self.base.comp.module.?; | 1427 | const mod = pt.zcu; |
| 1415 | const decl = mod.declPtr(decl_index); | 1428 | const decl = mod.declPtr(decl_index); |
| 1416 | 1429 | ||
| 1417 | const decl_name = try decl.fullyQualifiedName(mod); | 1430 | const decl_name = try decl.fullyQualifiedName(mod); |
| 1418 | 1431 | ||
| 1419 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | 1432 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); |
| 1420 | const required_alignment: u32 = @intCast(decl.getAlignment(mod).toByteUnits() orelse 0); | 1433 | const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0); |
| 1421 | 1434 | ||
| 1422 | const decl_metadata = self.decls.get(decl_index).?; | 1435 | const decl_metadata = self.decls.get(decl_index).?; |
| 1423 | const atom_index = decl_metadata.atom; | 1436 | const atom_index = decl_metadata.atom; |
| ... | @@ -1496,7 +1509,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void { | ... | @@ -1496,7 +1509,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void { |
| 1496 | 1509 | ||
| 1497 | pub fn updateExports( | 1510 | pub fn updateExports( |
| 1498 | self: *Coff, | 1511 | self: *Coff, |
| 1499 | mod: *Module, | 1512 | pt: Zcu.PerThread, |
| 1500 | exported: Module.Exported, | 1513 | exported: Module.Exported, |
| 1501 | export_indices: []const u32, | 1514 | export_indices: []const u32, |
| 1502 | ) link.File.UpdateExportsError!void { | 1515 | ) link.File.UpdateExportsError!void { |
| ... | @@ -1504,6 +1517,7 @@ pub fn updateExports( | ... | @@ -1504,6 +1517,7 @@ pub fn updateExports( |
| 1504 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1517 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1505 | } | 1518 | } |
| 1506 | 1519 | ||
| 1520 | const mod = pt.zcu; | ||
| 1507 | const ip = &mod.intern_pool; | 1521 | const ip = &mod.intern_pool; |
| 1508 | const comp = self.base.comp; | 1522 | const comp = self.base.comp; |
| 1509 | const target = comp.root_mod.resolved_target.result; | 1523 | const target = comp.root_mod.resolved_target.result; |
| ... | @@ -1542,7 +1556,7 @@ pub fn updateExports( | ... | @@ -1542,7 +1556,7 @@ pub fn updateExports( |
| 1542 | } | 1556 | } |
| 1543 | } | 1557 | } |
| 1544 | 1558 | ||
| 1545 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices); | 1559 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); |
| 1546 | 1560 | ||
| 1547 | const gpa = comp.gpa; | 1561 | const gpa = comp.gpa; |
| 1548 | 1562 | ||
| ... | @@ -1553,7 +1567,7 @@ pub fn updateExports( | ... | @@ -1553,7 +1567,7 @@ pub fn updateExports( |
| 1553 | }, | 1567 | }, |
| 1554 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { | 1568 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { |
| 1555 | const first_exp = mod.all_exports.items[export_indices[0]]; | 1569 | const first_exp = mod.all_exports.items[export_indices[0]]; |
| 1556 | const res = try self.lowerAnonDecl(value, .none, first_exp.src); | 1570 | const res = try self.lowerAnonDecl(pt, value, .none, first_exp.src); |
| 1557 | switch (res) { | 1571 | switch (res) { |
| 1558 | .ok => {}, | 1572 | .ok => {}, |
| 1559 | .fail => |em| { | 1573 | .fail => |em| { |
| ... | @@ -1696,19 +1710,19 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { | ... | @@ -1696,19 +1710,19 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| 1696 | gop.value_ptr.* = current; | 1710 | gop.value_ptr.* = current; |
| 1697 | } | 1711 | } |
| 1698 | 1712 | ||
| 1699 | pub fn flush(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 1713 | pub fn flush(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 1700 | const comp = self.base.comp; | 1714 | const comp = self.base.comp; |
| 1701 | const use_lld = build_options.have_llvm and comp.config.use_lld; | 1715 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 1702 | if (use_lld) { | 1716 | if (use_lld) { |
| 1703 | return lld.linkWithLLD(self, arena, prog_node); | 1717 | return lld.linkWithLLD(self, arena, tid, prog_node); |
| 1704 | } | 1718 | } |
| 1705 | switch (comp.config.output_mode) { | 1719 | switch (comp.config.output_mode) { |
| 1706 | .Exe, .Obj => return self.flushModule(arena, prog_node), | 1720 | .Exe, .Obj => return self.flushModule(arena, tid, prog_node), |
| 1707 | .Lib => return error.TODOImplementWritingLibFiles, | 1721 | .Lib => return error.TODOImplementWritingLibFiles, |
| 1708 | } | 1722 | } |
| 1709 | } | 1723 | } |
| 1710 | 1724 | ||
| 1711 | pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 1725 | pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 1712 | const tracy = trace(@src()); | 1726 | const tracy = trace(@src()); |
| 1713 | defer tracy.end(); | 1727 | defer tracy.end(); |
| 1714 | 1728 | ||
| ... | @@ -1723,13 +1737,17 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -1723,13 +1737,17 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) |
| 1723 | const sub_prog_node = prog_node.start("COFF Flush", 0); | 1737 | const sub_prog_node = prog_node.start("COFF Flush", 0); |
| 1724 | defer sub_prog_node.end(); | 1738 | defer sub_prog_node.end(); |
| 1725 | 1739 | ||
| 1726 | const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 1740 | const pt: Zcu.PerThread = .{ |
| 1741 | .zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented, | ||
| 1742 | .tid = tid, | ||
| 1743 | }; | ||
| 1727 | 1744 | ||
| 1728 | if (self.lazy_syms.getPtr(.none)) |metadata| { | 1745 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 1729 | // Most lazy symbols can be updated on first use, but | 1746 | // Most lazy symbols can be updated on first use, but |
| 1730 | // anyerror needs to wait for everything to be flushed. | 1747 | // anyerror needs to wait for everything to be flushed. |
| 1731 | if (metadata.text_state != .unused) self.updateLazySymbolAtom( | 1748 | if (metadata.text_state != .unused) self.updateLazySymbolAtom( |
| 1732 | link.File.LazySymbol.initDecl(.code, null, module), | 1749 | pt, |
| 1750 | link.File.LazySymbol.initDecl(.code, null, pt.zcu), | ||
| 1733 | metadata.text_atom, | 1751 | metadata.text_atom, |
| 1734 | self.text_section_index.?, | 1752 | self.text_section_index.?, |
| 1735 | ) catch |err| return switch (err) { | 1753 | ) catch |err| return switch (err) { |
| ... | @@ -1737,7 +1755,8 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -1737,7 +1755,8 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) |
| 1737 | else => |e| e, | 1755 | else => |e| e, |
| 1738 | }; | 1756 | }; |
| 1739 | if (metadata.rdata_state != .unused) self.updateLazySymbolAtom( | 1757 | if (metadata.rdata_state != .unused) self.updateLazySymbolAtom( |
| 1740 | link.File.LazySymbol.initDecl(.const_data, null, module), | 1758 | pt, |
| 1759 | link.File.LazySymbol.initDecl(.const_data, null, pt.zcu), | ||
| 1741 | metadata.rdata_atom, | 1760 | metadata.rdata_atom, |
| 1742 | self.rdata_section_index.?, | 1761 | self.rdata_section_index.?, |
| 1743 | ) catch |err| return switch (err) { | 1762 | ) catch |err| return switch (err) { |
| ... | @@ -1858,6 +1877,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: l | ... | @@ -1858,6 +1877,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: InternPool.DeclIndex, reloc_info: l |
| 1858 | 1877 | ||
| 1859 | pub fn lowerAnonDecl( | 1878 | pub fn lowerAnonDecl( |
| 1860 | self: *Coff, | 1879 | self: *Coff, |
| 1880 | pt: Zcu.PerThread, | ||
| 1861 | decl_val: InternPool.Index, | 1881 | decl_val: InternPool.Index, |
| 1862 | explicit_alignment: InternPool.Alignment, | 1882 | explicit_alignment: InternPool.Alignment, |
| 1863 | src_loc: Module.LazySrcLoc, | 1883 | src_loc: Module.LazySrcLoc, |
| ... | @@ -1866,7 +1886,7 @@ pub fn lowerAnonDecl( | ... | @@ -1866,7 +1886,7 @@ pub fn lowerAnonDecl( |
| 1866 | const mod = self.base.comp.module.?; | 1886 | const mod = self.base.comp.module.?; |
| 1867 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | 1887 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1868 | const decl_alignment = switch (explicit_alignment) { | 1888 | const decl_alignment = switch (explicit_alignment) { |
| 1869 | .none => ty.abiAlignment(mod), | 1889 | .none => ty.abiAlignment(pt), |
| 1870 | else => explicit_alignment, | 1890 | else => explicit_alignment, |
| 1871 | }; | 1891 | }; |
| 1872 | if (self.anon_decls.get(decl_val)) |metadata| { | 1892 | if (self.anon_decls.get(decl_val)) |metadata| { |
| ... | @@ -1881,6 +1901,7 @@ pub fn lowerAnonDecl( | ... | @@ -1881,6 +1901,7 @@ pub fn lowerAnonDecl( |
| 1881 | @intFromEnum(decl_val), | 1901 | @intFromEnum(decl_val), |
| 1882 | }) catch unreachable; | 1902 | }) catch unreachable; |
| 1883 | const res = self.lowerConst( | 1903 | const res = self.lowerConst( |
| 1904 | pt, | ||
| 1884 | name, | 1905 | name, |
| 1885 | val, | 1906 | val, |
| 1886 | decl_alignment, | 1907 | decl_alignment, |
src/link/Coff/lld.zig+3-2| ... | @@ -15,8 +15,9 @@ const Allocator = mem.Allocator; | ... | @@ -15,8 +15,9 @@ const Allocator = mem.Allocator; |
| 15 | 15 | ||
| 16 | const Coff = @import("../Coff.zig"); | 16 | const Coff = @import("../Coff.zig"); |
| 17 | const Compilation = @import("../../Compilation.zig"); | 17 | const Compilation = @import("../../Compilation.zig"); |
| 18 | const Zcu = @import("../../Zcu.zig"); | ||
| 18 | 19 | ||
| 19 | pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) !void { | 20 | pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 20 | const tracy = trace(@src()); | 21 | const tracy = trace(@src()); |
| 21 | defer tracy.end(); | 22 | defer tracy.end(); |
| 22 | 23 | ||
| ... | @@ -29,7 +30,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -29,7 +30,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) |
| 29 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 30 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 30 | // will not be part of the linker line anyway. | 31 | // will not be part of the linker line anyway. |
| 31 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { | 32 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { |
| 32 | try self.flushModule(arena, prog_node); | 33 | try self.flushModule(arena, tid, prog_node); |
| 33 | 34 | ||
| 34 | if (fs.path.dirname(full_out_path)) |dirname| { | 35 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 35 | break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? }); | 36 | break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? }); |
src/link/Dwarf.zig+112-110| ... | @@ -31,7 +31,7 @@ strtab: StringTable = .{}, | ... | @@ -31,7 +31,7 @@ strtab: StringTable = .{}, |
| 31 | /// They will end up in the DWARF debug_line header as two lists: | 31 | /// They will end up in the DWARF debug_line header as two lists: |
| 32 | /// * []include_directory | 32 | /// * []include_directory |
| 33 | /// * []file_names | 33 | /// * []file_names |
| 34 | di_files: std.AutoArrayHashMapUnmanaged(*const Module.File, void) = .{}, | 34 | di_files: std.AutoArrayHashMapUnmanaged(*const Zcu.File, void) = .{}, |
| 35 | 35 | ||
| 36 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, | 36 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, |
| 37 | 37 | ||
| ... | @@ -67,7 +67,7 @@ const DbgLineHeader = struct { | ... | @@ -67,7 +67,7 @@ const DbgLineHeader = struct { |
| 67 | /// Decl's inner Atom is assigned an offset within the DWARF section. | 67 | /// Decl's inner Atom is assigned an offset within the DWARF section. |
| 68 | pub const DeclState = struct { | 68 | pub const DeclState = struct { |
| 69 | dwarf: *Dwarf, | 69 | dwarf: *Dwarf, |
| 70 | mod: *Module, | 70 | pt: Zcu.PerThread, |
| 71 | di_atom_decls: *const AtomTable, | 71 | di_atom_decls: *const AtomTable, |
| 72 | dbg_line_func: InternPool.Index, | 72 | dbg_line_func: InternPool.Index, |
| 73 | dbg_line: std.ArrayList(u8), | 73 | dbg_line: std.ArrayList(u8), |
| ... | @@ -113,7 +113,7 @@ pub const DeclState = struct { | ... | @@ -113,7 +113,7 @@ pub const DeclState = struct { |
| 113 | .type = ty, | 113 | .type = ty, |
| 114 | .offset = undefined, | 114 | .offset = undefined, |
| 115 | }); | 115 | }); |
| 116 | log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.mod) }); | 116 | log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.pt) }); |
| 117 | try self.abbrev_resolver.putNoClobber(gpa, ty.toIntern(), sym_index); | 117 | try self.abbrev_resolver.putNoClobber(gpa, ty.toIntern(), sym_index); |
| 118 | break :blk sym_index; | 118 | break :blk sym_index; |
| 119 | }; | 119 | }; |
| ... | @@ -128,16 +128,17 @@ pub const DeclState = struct { | ... | @@ -128,16 +128,17 @@ pub const DeclState = struct { |
| 128 | 128 | ||
| 129 | fn addDbgInfoType( | 129 | fn addDbgInfoType( |
| 130 | self: *DeclState, | 130 | self: *DeclState, |
| 131 | mod: *Module, | 131 | pt: Zcu.PerThread, |
| 132 | atom_index: Atom.Index, | 132 | atom_index: Atom.Index, |
| 133 | ty: Type, | 133 | ty: Type, |
| 134 | ) error{OutOfMemory}!void { | 134 | ) error{OutOfMemory}!void { |
| 135 | const zcu = pt.zcu; | ||
| 135 | const dbg_info_buffer = &self.dbg_info; | 136 | const dbg_info_buffer = &self.dbg_info; |
| 136 | const target = mod.getTarget(); | 137 | const target = zcu.getTarget(); |
| 137 | const target_endian = target.cpu.arch.endian(); | 138 | const target_endian = target.cpu.arch.endian(); |
| 138 | const ip = &mod.intern_pool; | 139 | const ip = &zcu.intern_pool; |
| 139 | 140 | ||
| 140 | switch (ty.zigTypeTag(mod)) { | 141 | switch (ty.zigTypeTag(zcu)) { |
| 141 | .NoReturn => unreachable, | 142 | .NoReturn => unreachable, |
| 142 | .Void => { | 143 | .Void => { |
| 143 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type)); | 144 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type)); |
| ... | @@ -148,12 +149,12 @@ pub const DeclState = struct { | ... | @@ -148,12 +149,12 @@ pub const DeclState = struct { |
| 148 | // DW.AT.encoding, DW.FORM.data1 | 149 | // DW.AT.encoding, DW.FORM.data1 |
| 149 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean); | 150 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean); |
| 150 | // DW.AT.byte_size, DW.FORM.udata | 151 | // DW.AT.byte_size, DW.FORM.udata |
| 151 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 152 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 152 | // DW.AT.name, DW.FORM.string | 153 | // DW.AT.name, DW.FORM.string |
| 153 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 154 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 154 | }, | 155 | }, |
| 155 | .Int => { | 156 | .Int => { |
| 156 | const info = ty.intInfo(mod); | 157 | const info = ty.intInfo(zcu); |
| 157 | try dbg_info_buffer.ensureUnusedCapacity(12); | 158 | try dbg_info_buffer.ensureUnusedCapacity(12); |
| 158 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type)); | 159 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type)); |
| 159 | // DW.AT.encoding, DW.FORM.data1 | 160 | // DW.AT.encoding, DW.FORM.data1 |
| ... | @@ -162,30 +163,30 @@ pub const DeclState = struct { | ... | @@ -162,30 +163,30 @@ pub const DeclState = struct { |
| 162 | .unsigned => DW.ATE.unsigned, | 163 | .unsigned => DW.ATE.unsigned, |
| 163 | }); | 164 | }); |
| 164 | // DW.AT.byte_size, DW.FORM.udata | 165 | // DW.AT.byte_size, DW.FORM.udata |
| 165 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 166 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 166 | // DW.AT.name, DW.FORM.string | 167 | // DW.AT.name, DW.FORM.string |
| 167 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 168 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 168 | }, | 169 | }, |
| 169 | .Optional => { | 170 | .Optional => { |
| 170 | if (ty.isPtrLikeOptional(mod)) { | 171 | if (ty.isPtrLikeOptional(zcu)) { |
| 171 | try dbg_info_buffer.ensureUnusedCapacity(12); | 172 | try dbg_info_buffer.ensureUnusedCapacity(12); |
| 172 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type)); | 173 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.base_type)); |
| 173 | // DW.AT.encoding, DW.FORM.data1 | 174 | // DW.AT.encoding, DW.FORM.data1 |
| 174 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); | 175 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); |
| 175 | // DW.AT.byte_size, DW.FORM.udata | 176 | // DW.AT.byte_size, DW.FORM.udata |
| 176 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 177 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 177 | // DW.AT.name, DW.FORM.string | 178 | // DW.AT.name, DW.FORM.string |
| 178 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 179 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 179 | } else { | 180 | } else { |
| 180 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } | 181 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } |
| 181 | const payload_ty = ty.optionalChild(mod); | 182 | const payload_ty = ty.optionalChild(zcu); |
| 182 | // DW.AT.structure_type | 183 | // DW.AT.structure_type |
| 183 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); | 184 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); |
| 184 | // DW.AT.byte_size, DW.FORM.udata | 185 | // DW.AT.byte_size, DW.FORM.udata |
| 185 | const abi_size = ty.abiSize(mod); | 186 | const abi_size = ty.abiSize(pt); |
| 186 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); | 187 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); |
| 187 | // DW.AT.name, DW.FORM.string | 188 | // DW.AT.name, DW.FORM.string |
| 188 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 189 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 189 | // DW.AT.member | 190 | // DW.AT.member |
| 190 | try dbg_info_buffer.ensureUnusedCapacity(21); | 191 | try dbg_info_buffer.ensureUnusedCapacity(21); |
| 191 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); | 192 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); |
| ... | @@ -208,14 +209,14 @@ pub const DeclState = struct { | ... | @@ -208,14 +209,14 @@ pub const DeclState = struct { |
| 208 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); | 209 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); |
| 209 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index)); | 210 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(index)); |
| 210 | // DW.AT.data_member_location, DW.FORM.udata | 211 | // DW.AT.data_member_location, DW.FORM.udata |
| 211 | const offset = abi_size - payload_ty.abiSize(mod); | 212 | const offset = abi_size - payload_ty.abiSize(pt); |
| 212 | try leb128.writeUleb128(dbg_info_buffer.writer(), offset); | 213 | try leb128.writeUleb128(dbg_info_buffer.writer(), offset); |
| 213 | // DW.AT.structure_type delimit children | 214 | // DW.AT.structure_type delimit children |
| 214 | try dbg_info_buffer.append(0); | 215 | try dbg_info_buffer.append(0); |
| 215 | } | 216 | } |
| 216 | }, | 217 | }, |
| 217 | .Pointer => { | 218 | .Pointer => { |
| 218 | if (ty.isSlice(mod)) { | 219 | if (ty.isSlice(zcu)) { |
| 219 | // Slices are structs: struct { .ptr = *, .len = N } | 220 | // Slices are structs: struct { .ptr = *, .len = N } |
| 220 | const ptr_bits = target.ptrBitWidth(); | 221 | const ptr_bits = target.ptrBitWidth(); |
| 221 | const ptr_bytes: u8 = @intCast(@divExact(ptr_bits, 8)); | 222 | const ptr_bytes: u8 = @intCast(@divExact(ptr_bits, 8)); |
| ... | @@ -223,9 +224,9 @@ pub const DeclState = struct { | ... | @@ -223,9 +224,9 @@ pub const DeclState = struct { |
| 223 | try dbg_info_buffer.ensureUnusedCapacity(2); | 224 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 224 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_type)); | 225 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_type)); |
| 225 | // DW.AT.byte_size, DW.FORM.udata | 226 | // DW.AT.byte_size, DW.FORM.udata |
| 226 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 227 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 227 | // DW.AT.name, DW.FORM.string | 228 | // DW.AT.name, DW.FORM.string |
| 228 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 229 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 229 | // DW.AT.member | 230 | // DW.AT.member |
| 230 | try dbg_info_buffer.ensureUnusedCapacity(21); | 231 | try dbg_info_buffer.ensureUnusedCapacity(21); |
| 231 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); | 232 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); |
| ... | @@ -235,7 +236,7 @@ pub const DeclState = struct { | ... | @@ -235,7 +236,7 @@ pub const DeclState = struct { |
| 235 | // DW.AT.type, DW.FORM.ref4 | 236 | // DW.AT.type, DW.FORM.ref4 |
| 236 | var index = dbg_info_buffer.items.len; | 237 | var index = dbg_info_buffer.items.len; |
| 237 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); | 238 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); |
| 238 | const ptr_ty = ty.slicePtrFieldType(mod); | 239 | const ptr_ty = ty.slicePtrFieldType(zcu); |
| 239 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(index)); | 240 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(index)); |
| 240 | // DW.AT.data_member_location, DW.FORM.udata | 241 | // DW.AT.data_member_location, DW.FORM.udata |
| 241 | dbg_info_buffer.appendAssumeCapacity(0); | 242 | dbg_info_buffer.appendAssumeCapacity(0); |
| ... | @@ -258,19 +259,19 @@ pub const DeclState = struct { | ... | @@ -258,19 +259,19 @@ pub const DeclState = struct { |
| 258 | // DW.AT.type, DW.FORM.ref4 | 259 | // DW.AT.type, DW.FORM.ref4 |
| 259 | const index = dbg_info_buffer.items.len; | 260 | const index = dbg_info_buffer.items.len; |
| 260 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); | 261 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); |
| 261 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index)); | 262 | try self.addTypeRelocGlobal(atom_index, ty.childType(zcu), @intCast(index)); |
| 262 | } | 263 | } |
| 263 | }, | 264 | }, |
| 264 | .Array => { | 265 | .Array => { |
| 265 | // DW.AT.array_type | 266 | // DW.AT.array_type |
| 266 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.array_type)); | 267 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.array_type)); |
| 267 | // DW.AT.name, DW.FORM.string | 268 | // DW.AT.name, DW.FORM.string |
| 268 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 269 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 269 | // DW.AT.type, DW.FORM.ref4 | 270 | // DW.AT.type, DW.FORM.ref4 |
| 270 | var index = dbg_info_buffer.items.len; | 271 | var index = dbg_info_buffer.items.len; |
| 271 | try dbg_info_buffer.ensureUnusedCapacity(9); | 272 | try dbg_info_buffer.ensureUnusedCapacity(9); |
| 272 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); | 273 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); |
| 273 | try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(index)); | 274 | try self.addTypeRelocGlobal(atom_index, ty.childType(zcu), @intCast(index)); |
| 274 | // DW.AT.subrange_type | 275 | // DW.AT.subrange_type |
| 275 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.array_dim)); | 276 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.array_dim)); |
| 276 | // DW.AT.type, DW.FORM.ref4 | 277 | // DW.AT.type, DW.FORM.ref4 |
| ... | @@ -278,7 +279,7 @@ pub const DeclState = struct { | ... | @@ -278,7 +279,7 @@ pub const DeclState = struct { |
| 278 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); | 279 | dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); |
| 279 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index)); | 280 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(index)); |
| 280 | // DW.AT.count, DW.FORM.udata | 281 | // DW.AT.count, DW.FORM.udata |
| 281 | const len = ty.arrayLenIncludingSentinel(mod); | 282 | const len = ty.arrayLenIncludingSentinel(pt.zcu); |
| 282 | try leb128.writeUleb128(dbg_info_buffer.writer(), len); | 283 | try leb128.writeUleb128(dbg_info_buffer.writer(), len); |
| 283 | // DW.AT.array_type delimit children | 284 | // DW.AT.array_type delimit children |
| 284 | try dbg_info_buffer.append(0); | 285 | try dbg_info_buffer.append(0); |
| ... | @@ -287,13 +288,13 @@ pub const DeclState = struct { | ... | @@ -287,13 +288,13 @@ pub const DeclState = struct { |
| 287 | // DW.AT.structure_type | 288 | // DW.AT.structure_type |
| 288 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); | 289 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); |
| 289 | // DW.AT.byte_size, DW.FORM.udata | 290 | // DW.AT.byte_size, DW.FORM.udata |
| 290 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 291 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 291 | 292 | ||
| 292 | blk: { | 293 | blk: { |
| 293 | switch (ip.indexToKey(ty.ip_index)) { | 294 | switch (ip.indexToKey(ty.ip_index)) { |
| 294 | .anon_struct_type => |fields| { | 295 | .anon_struct_type => |fields| { |
| 295 | // DW.AT.name, DW.FORM.string | 296 | // DW.AT.name, DW.FORM.string |
| 296 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 297 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(pt)}); |
| 297 | 298 | ||
| 298 | for (fields.types.get(ip), 0..) |field_ty, field_index| { | 299 | for (fields.types.get(ip), 0..) |field_ty, field_index| { |
| 299 | // DW.AT.member | 300 | // DW.AT.member |
| ... | @@ -305,14 +306,14 @@ pub const DeclState = struct { | ... | @@ -305,14 +306,14 @@ pub const DeclState = struct { |
| 305 | try dbg_info_buffer.appendNTimes(0, 4); | 306 | try dbg_info_buffer.appendNTimes(0, 4); |
| 306 | try self.addTypeRelocGlobal(atom_index, Type.fromInterned(field_ty), @intCast(index)); | 307 | try self.addTypeRelocGlobal(atom_index, Type.fromInterned(field_ty), @intCast(index)); |
| 307 | // DW.AT.data_member_location, DW.FORM.udata | 308 | // DW.AT.data_member_location, DW.FORM.udata |
| 308 | const field_off = ty.structFieldOffset(field_index, mod); | 309 | const field_off = ty.structFieldOffset(field_index, pt); |
| 309 | try leb128.writeUleb128(dbg_info_buffer.writer(), field_off); | 310 | try leb128.writeUleb128(dbg_info_buffer.writer(), field_off); |
| 310 | } | 311 | } |
| 311 | }, | 312 | }, |
| 312 | .struct_type => { | 313 | .struct_type => { |
| 313 | const struct_type = ip.loadStructType(ty.toIntern()); | 314 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 314 | // DW.AT.name, DW.FORM.string | 315 | // DW.AT.name, DW.FORM.string |
| 315 | try ty.print(dbg_info_buffer.writer(), mod); | 316 | try ty.print(dbg_info_buffer.writer(), pt); |
| 316 | try dbg_info_buffer.append(0); | 317 | try dbg_info_buffer.append(0); |
| 317 | 318 | ||
| 318 | if (struct_type.layout == .@"packed") { | 319 | if (struct_type.layout == .@"packed") { |
| ... | @@ -322,7 +323,7 @@ pub const DeclState = struct { | ... | @@ -322,7 +323,7 @@ pub const DeclState = struct { |
| 322 | 323 | ||
| 323 | if (struct_type.isTuple(ip)) { | 324 | if (struct_type.isTuple(ip)) { |
| 324 | for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| { | 325 | for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| { |
| 325 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 326 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 326 | // DW.AT.member | 327 | // DW.AT.member |
| 327 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member)); | 328 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member)); |
| 328 | // DW.AT.name, DW.FORM.string | 329 | // DW.AT.name, DW.FORM.string |
| ... | @@ -340,7 +341,7 @@ pub const DeclState = struct { | ... | @@ -340,7 +341,7 @@ pub const DeclState = struct { |
| 340 | struct_type.field_types.get(ip), | 341 | struct_type.field_types.get(ip), |
| 341 | struct_type.offsets.get(ip), | 342 | struct_type.offsets.get(ip), |
| 342 | ) |field_name, field_ty, field_off| { | 343 | ) |field_name, field_ty, field_off| { |
| 343 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 344 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 344 | const field_name_slice = field_name.toSlice(ip); | 345 | const field_name_slice = field_name.toSlice(ip); |
| 345 | // DW.AT.member | 346 | // DW.AT.member |
| 346 | try dbg_info_buffer.ensureUnusedCapacity(field_name_slice.len + 2); | 347 | try dbg_info_buffer.ensureUnusedCapacity(field_name_slice.len + 2); |
| ... | @@ -367,9 +368,9 @@ pub const DeclState = struct { | ... | @@ -367,9 +368,9 @@ pub const DeclState = struct { |
| 367 | // DW.AT.enumeration_type | 368 | // DW.AT.enumeration_type |
| 368 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type)); | 369 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type)); |
| 369 | // DW.AT.byte_size, DW.FORM.udata | 370 | // DW.AT.byte_size, DW.FORM.udata |
| 370 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(mod)); | 371 | try leb128.writeUleb128(dbg_info_buffer.writer(), ty.abiSize(pt)); |
| 371 | // DW.AT.name, DW.FORM.string | 372 | // DW.AT.name, DW.FORM.string |
| 372 | try ty.print(dbg_info_buffer.writer(), mod); | 373 | try ty.print(dbg_info_buffer.writer(), pt); |
| 373 | try dbg_info_buffer.append(0); | 374 | try dbg_info_buffer.append(0); |
| 374 | 375 | ||
| 375 | const enum_type = ip.loadEnumType(ty.ip_index); | 376 | const enum_type = ip.loadEnumType(ty.ip_index); |
| ... | @@ -386,8 +387,8 @@ pub const DeclState = struct { | ... | @@ -386,8 +387,8 @@ pub const DeclState = struct { |
| 386 | const value = enum_type.values.get(ip)[field_i]; | 387 | const value = enum_type.values.get(ip)[field_i]; |
| 387 | // TODO do not assume a 64bit enum value - could be bigger. | 388 | // TODO do not assume a 64bit enum value - could be bigger. |
| 388 | // See https://github.com/ziglang/zig/issues/645 | 389 | // See https://github.com/ziglang/zig/issues/645 |
| 389 | const field_int_val = try Value.fromInterned(value).intFromEnum(ty, mod); | 390 | const field_int_val = try Value.fromInterned(value).intFromEnum(ty, pt); |
| 390 | break :value @bitCast(field_int_val.toSignedInt(mod)); | 391 | break :value @bitCast(field_int_val.toSignedInt(pt)); |
| 391 | }; | 392 | }; |
| 392 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian); | 393 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian); |
| 393 | } | 394 | } |
| ... | @@ -396,8 +397,8 @@ pub const DeclState = struct { | ... | @@ -396,8 +397,8 @@ pub const DeclState = struct { |
| 396 | try dbg_info_buffer.append(0); | 397 | try dbg_info_buffer.append(0); |
| 397 | }, | 398 | }, |
| 398 | .Union => { | 399 | .Union => { |
| 399 | const union_obj = mod.typeToUnion(ty).?; | 400 | const union_obj = zcu.typeToUnion(ty).?; |
| 400 | const layout = mod.getUnionLayout(union_obj); | 401 | const layout = pt.getUnionLayout(union_obj); |
| 401 | const payload_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) layout.tag_size else 0; | 402 | const payload_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) layout.tag_size else 0; |
| 402 | const tag_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) 0 else layout.payload_size; | 403 | const tag_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) 0 else layout.payload_size; |
| 403 | // TODO this is temporary to match current state of unions in Zig - we don't yet have | 404 | // TODO this is temporary to match current state of unions in Zig - we don't yet have |
| ... | @@ -410,7 +411,7 @@ pub const DeclState = struct { | ... | @@ -410,7 +411,7 @@ pub const DeclState = struct { |
| 410 | // DW.AT.byte_size, DW.FORM.udata | 411 | // DW.AT.byte_size, DW.FORM.udata |
| 411 | try leb128.writeUleb128(dbg_info_buffer.writer(), layout.abi_size); | 412 | try leb128.writeUleb128(dbg_info_buffer.writer(), layout.abi_size); |
| 412 | // DW.AT.name, DW.FORM.string | 413 | // DW.AT.name, DW.FORM.string |
| 413 | try ty.print(dbg_info_buffer.writer(), mod); | 414 | try ty.print(dbg_info_buffer.writer(), pt); |
| 414 | try dbg_info_buffer.append(0); | 415 | try dbg_info_buffer.append(0); |
| 415 | 416 | ||
| 416 | // DW.AT.member | 417 | // DW.AT.member |
| ... | @@ -435,12 +436,12 @@ pub const DeclState = struct { | ... | @@ -435,12 +436,12 @@ pub const DeclState = struct { |
| 435 | if (is_tagged) { | 436 | if (is_tagged) { |
| 436 | try dbg_info_buffer.writer().print("AnonUnion\x00", .{}); | 437 | try dbg_info_buffer.writer().print("AnonUnion\x00", .{}); |
| 437 | } else { | 438 | } else { |
| 438 | try ty.print(dbg_info_buffer.writer(), mod); | 439 | try ty.print(dbg_info_buffer.writer(), pt); |
| 439 | try dbg_info_buffer.append(0); | 440 | try dbg_info_buffer.append(0); |
| 440 | } | 441 | } |
| 441 | 442 | ||
| 442 | for (union_obj.field_types.get(ip), union_obj.loadTagType(ip).names.get(ip)) |field_ty, field_name| { | 443 | for (union_obj.field_types.get(ip), union_obj.loadTagType(ip).names.get(ip)) |field_ty, field_name| { |
| 443 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 444 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; |
| 444 | const field_name_slice = field_name.toSlice(ip); | 445 | const field_name_slice = field_name.toSlice(ip); |
| 445 | // DW.AT.member | 446 | // DW.AT.member |
| 446 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member)); | 447 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_member)); |
| ... | @@ -474,25 +475,25 @@ pub const DeclState = struct { | ... | @@ -474,25 +475,25 @@ pub const DeclState = struct { |
| 474 | try dbg_info_buffer.append(0); | 475 | try dbg_info_buffer.append(0); |
| 475 | } | 476 | } |
| 476 | }, | 477 | }, |
| 477 | .ErrorSet => try addDbgInfoErrorSet(mod, ty, target, &self.dbg_info), | 478 | .ErrorSet => try addDbgInfoErrorSet(pt, ty, target, &self.dbg_info), |
| 478 | .ErrorUnion => { | 479 | .ErrorUnion => { |
| 479 | const error_ty = ty.errorUnionSet(mod); | 480 | const error_ty = ty.errorUnionSet(zcu); |
| 480 | const payload_ty = ty.errorUnionPayload(mod); | 481 | const payload_ty = ty.errorUnionPayload(zcu); |
| 481 | const payload_align = if (payload_ty.isNoReturn(mod)) .none else payload_ty.abiAlignment(mod); | 482 | const payload_align = if (payload_ty.isNoReturn(zcu)) .none else payload_ty.abiAlignment(pt); |
| 482 | const error_align = Type.anyerror.abiAlignment(mod); | 483 | const error_align = Type.anyerror.abiAlignment(pt); |
| 483 | const abi_size = ty.abiSize(mod); | 484 | const abi_size = ty.abiSize(pt); |
| 484 | const payload_off = if (error_align.compare(.gte, payload_align)) Type.anyerror.abiSize(mod) else 0; | 485 | const payload_off = if (error_align.compare(.gte, payload_align)) Type.anyerror.abiSize(pt) else 0; |
| 485 | const error_off = if (error_align.compare(.gte, payload_align)) 0 else payload_ty.abiSize(mod); | 486 | const error_off = if (error_align.compare(.gte, payload_align)) 0 else payload_ty.abiSize(pt); |
| 486 | 487 | ||
| 487 | // DW.AT.structure_type | 488 | // DW.AT.structure_type |
| 488 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); | 489 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.struct_type)); |
| 489 | // DW.AT.byte_size, DW.FORM.udata | 490 | // DW.AT.byte_size, DW.FORM.udata |
| 490 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); | 491 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); |
| 491 | // DW.AT.name, DW.FORM.string | 492 | // DW.AT.name, DW.FORM.string |
| 492 | try ty.print(dbg_info_buffer.writer(), mod); | 493 | try ty.print(dbg_info_buffer.writer(), pt); |
| 493 | try dbg_info_buffer.append(0); | 494 | try dbg_info_buffer.append(0); |
| 494 | 495 | ||
| 495 | if (!payload_ty.isNoReturn(mod)) { | 496 | if (!payload_ty.isNoReturn(zcu)) { |
| 496 | // DW.AT.member | 497 | // DW.AT.member |
| 497 | try dbg_info_buffer.ensureUnusedCapacity(11); | 498 | try dbg_info_buffer.ensureUnusedCapacity(11); |
| 498 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); | 499 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.struct_member)); |
| ... | @@ -526,7 +527,7 @@ pub const DeclState = struct { | ... | @@ -526,7 +527,7 @@ pub const DeclState = struct { |
| 526 | try dbg_info_buffer.append(0); | 527 | try dbg_info_buffer.append(0); |
| 527 | }, | 528 | }, |
| 528 | else => { | 529 | else => { |
| 529 | log.debug("TODO implement .debug_info for type '{}'", .{ty.fmt(self.mod)}); | 530 | log.debug("TODO implement .debug_info for type '{}'", .{ty.fmt(pt)}); |
| 530 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type)); | 531 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.zero_bit_type)); |
| 531 | }, | 532 | }, |
| 532 | } | 533 | } |
| ... | @@ -555,6 +556,7 @@ pub const DeclState = struct { | ... | @@ -555,6 +556,7 @@ pub const DeclState = struct { |
| 555 | owner_decl: InternPool.DeclIndex, | 556 | owner_decl: InternPool.DeclIndex, |
| 556 | loc: DbgInfoLoc, | 557 | loc: DbgInfoLoc, |
| 557 | ) error{OutOfMemory}!void { | 558 | ) error{OutOfMemory}!void { |
| 559 | const pt = self.pt; | ||
| 558 | const dbg_info = &self.dbg_info; | 560 | const dbg_info = &self.dbg_info; |
| 559 | const atom_index = self.di_atom_decls.get(owner_decl).?; | 561 | const atom_index = self.di_atom_decls.get(owner_decl).?; |
| 560 | const name_with_null = name.ptr[0 .. name.len + 1]; | 562 | const name_with_null = name.ptr[0 .. name.len + 1]; |
| ... | @@ -580,9 +582,9 @@ pub const DeclState = struct { | ... | @@ -580,9 +582,9 @@ pub const DeclState = struct { |
| 580 | } | 582 | } |
| 581 | }, | 583 | }, |
| 582 | .register_pair => |regs| { | 584 | .register_pair => |regs| { |
| 583 | const reg_bits = self.mod.getTarget().ptrBitWidth(); | 585 | const reg_bits = pt.zcu.getTarget().ptrBitWidth(); |
| 584 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); | 586 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); |
| 585 | const abi_size = ty.abiSize(self.mod); | 587 | const abi_size = ty.abiSize(pt); |
| 586 | try dbg_info.ensureUnusedCapacity(10); | 588 | try dbg_info.ensureUnusedCapacity(10); |
| 587 | dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevCode.parameter)); | 589 | dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevCode.parameter)); |
| 588 | // DW.AT.location, DW.FORM.exprloc | 590 | // DW.AT.location, DW.FORM.exprloc |
| ... | @@ -675,10 +677,10 @@ pub const DeclState = struct { | ... | @@ -675,10 +677,10 @@ pub const DeclState = struct { |
| 675 | const name_with_null = name.ptr[0 .. name.len + 1]; | 677 | const name_with_null = name.ptr[0 .. name.len + 1]; |
| 676 | try dbg_info.append(@intFromEnum(AbbrevCode.variable)); | 678 | try dbg_info.append(@intFromEnum(AbbrevCode.variable)); |
| 677 | const gpa = self.dwarf.allocator; | 679 | const gpa = self.dwarf.allocator; |
| 678 | const mod = self.mod; | 680 | const pt = self.pt; |
| 679 | const target = mod.getTarget(); | 681 | const target = pt.zcu.getTarget(); |
| 680 | const endian = target.cpu.arch.endian(); | 682 | const endian = target.cpu.arch.endian(); |
| 681 | const child_ty = if (is_ptr) ty.childType(mod) else ty; | 683 | const child_ty = if (is_ptr) ty.childType(pt.zcu) else ty; |
| 682 | 684 | ||
| 683 | switch (loc) { | 685 | switch (loc) { |
| 684 | .register => |reg| { | 686 | .register => |reg| { |
| ... | @@ -701,9 +703,9 @@ pub const DeclState = struct { | ... | @@ -701,9 +703,9 @@ pub const DeclState = struct { |
| 701 | }, | 703 | }, |
| 702 | 704 | ||
| 703 | .register_pair => |regs| { | 705 | .register_pair => |regs| { |
| 704 | const reg_bits = self.mod.getTarget().ptrBitWidth(); | 706 | const reg_bits = pt.zcu.getTarget().ptrBitWidth(); |
| 705 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); | 707 | const reg_bytes: u8 = @intCast(@divExact(reg_bits, 8)); |
| 706 | const abi_size = child_ty.abiSize(self.mod); | 708 | const abi_size = child_ty.abiSize(pt); |
| 707 | try dbg_info.ensureUnusedCapacity(9); | 709 | try dbg_info.ensureUnusedCapacity(9); |
| 708 | // DW.AT.location, DW.FORM.exprloc | 710 | // DW.AT.location, DW.FORM.exprloc |
| 709 | var expr_len = std.io.countingWriter(std.io.null_writer); | 711 | var expr_len = std.io.countingWriter(std.io.null_writer); |
| ... | @@ -829,9 +831,9 @@ pub const DeclState = struct { | ... | @@ -829,9 +831,9 @@ pub const DeclState = struct { |
| 829 | const fixup = dbg_info.items.len; | 831 | const fixup = dbg_info.items.len; |
| 830 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 832 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 831 | 1, | 833 | 1, |
| 832 | if (child_ty.isSignedInt(mod)) DW.OP.consts else DW.OP.constu, | 834 | if (child_ty.isSignedInt(pt.zcu)) DW.OP.consts else DW.OP.constu, |
| 833 | }); | 835 | }); |
| 834 | if (child_ty.isSignedInt(mod)) { | 836 | if (child_ty.isSignedInt(pt.zcu)) { |
| 835 | try leb128.writeIleb128(dbg_info.writer(), @as(i64, @bitCast(x))); | 837 | try leb128.writeIleb128(dbg_info.writer(), @as(i64, @bitCast(x))); |
| 836 | } else { | 838 | } else { |
| 837 | try leb128.writeUleb128(dbg_info.writer(), x); | 839 | try leb128.writeUleb128(dbg_info.writer(), x); |
| ... | @@ -844,7 +846,7 @@ pub const DeclState = struct { | ... | @@ -844,7 +846,7 @@ pub const DeclState = struct { |
| 844 | // DW.AT.location, DW.FORM.exprloc | 846 | // DW.AT.location, DW.FORM.exprloc |
| 845 | // uleb128(exprloc_len) | 847 | // uleb128(exprloc_len) |
| 846 | // DW.OP.implicit_value uleb128(len_of_bytes) bytes | 848 | // DW.OP.implicit_value uleb128(len_of_bytes) bytes |
| 847 | const abi_size: u32 = @intCast(child_ty.abiSize(mod)); | 849 | const abi_size: u32 = @intCast(child_ty.abiSize(self.pt)); |
| 848 | var implicit_value_len = std.ArrayList(u8).init(gpa); | 850 | var implicit_value_len = std.ArrayList(u8).init(gpa); |
| 849 | defer implicit_value_len.deinit(); | 851 | defer implicit_value_len.deinit(); |
| 850 | try leb128.writeUleb128(implicit_value_len.writer(), abi_size); | 852 | try leb128.writeUleb128(implicit_value_len.writer(), abi_size); |
| ... | @@ -934,22 +936,23 @@ pub const DeclState = struct { | ... | @@ -934,22 +936,23 @@ pub const DeclState = struct { |
| 934 | } | 936 | } |
| 935 | 937 | ||
| 936 | pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void { | 938 | pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void { |
| 939 | const zcu = self.pt.zcu; | ||
| 937 | if (self.dbg_line_func == func) return; | 940 | if (self.dbg_line_func == func) return; |
| 938 | 941 | ||
| 939 | try self.dbg_line.ensureUnusedCapacity((1 + 4) + (1 + 5)); | 942 | try self.dbg_line.ensureUnusedCapacity((1 + 4) + (1 + 5)); |
| 940 | 943 | ||
| 941 | const old_func_info = self.mod.funcInfo(self.dbg_line_func); | 944 | const old_func_info = zcu.funcInfo(self.dbg_line_func); |
| 942 | const new_func_info = self.mod.funcInfo(func); | 945 | const new_func_info = zcu.funcInfo(func); |
| 943 | 946 | ||
| 944 | const old_file = try self.dwarf.addDIFile(self.mod, old_func_info.owner_decl); | 947 | const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_decl); |
| 945 | const new_file = try self.dwarf.addDIFile(self.mod, new_func_info.owner_decl); | 948 | const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_decl); |
| 946 | if (old_file != new_file) { | 949 | if (old_file != new_file) { |
| 947 | self.dbg_line.appendAssumeCapacity(DW.LNS.set_file); | 950 | self.dbg_line.appendAssumeCapacity(DW.LNS.set_file); |
| 948 | leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file); | 951 | leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file); |
| 949 | } | 952 | } |
| 950 | 953 | ||
| 951 | const old_src_line: i33 = self.mod.declPtr(old_func_info.owner_decl).navSrcLine(self.mod); | 954 | const old_src_line: i33 = zcu.declPtr(old_func_info.owner_decl).navSrcLine(zcu); |
| 952 | const new_src_line: i33 = self.mod.declPtr(new_func_info.owner_decl).navSrcLine(self.mod); | 955 | const new_src_line: i33 = zcu.declPtr(new_func_info.owner_decl).navSrcLine(zcu); |
| 953 | if (new_src_line != old_src_line) { | 956 | if (new_src_line != old_src_line) { |
| 954 | self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line); | 957 | self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line); |
| 955 | leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line); | 958 | leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line); |
| ... | @@ -1074,19 +1077,19 @@ pub fn deinit(self: *Dwarf) void { | ... | @@ -1074,19 +1077,19 @@ pub fn deinit(self: *Dwarf) void { |
| 1074 | 1077 | ||
| 1075 | /// Initializes Decl's state and its matching output buffers. | 1078 | /// Initializes Decl's state and its matching output buffers. |
| 1076 | /// Call this before `commitDeclState`. | 1079 | /// Call this before `commitDeclState`. |
| 1077 | pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !DeclState { | 1080 | pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !DeclState { |
| 1078 | const tracy = trace(@src()); | 1081 | const tracy = trace(@src()); |
| 1079 | defer tracy.end(); | 1082 | defer tracy.end(); |
| 1080 | 1083 | ||
| 1081 | const decl = mod.declPtr(decl_index); | 1084 | const decl = pt.zcu.declPtr(decl_index); |
| 1082 | const decl_linkage_name = try decl.fullyQualifiedName(mod); | 1085 | const decl_linkage_name = try decl.fullyQualifiedName(pt.zcu); |
| 1083 | 1086 | ||
| 1084 | log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&mod.intern_pool), decl }); | 1087 | log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl }); |
| 1085 | 1088 | ||
| 1086 | const gpa = self.allocator; | 1089 | const gpa = self.allocator; |
| 1087 | var decl_state: DeclState = .{ | 1090 | var decl_state: DeclState = .{ |
| 1088 | .dwarf = self, | 1091 | .dwarf = self, |
| 1089 | .mod = mod, | 1092 | .pt = pt, |
| 1090 | .di_atom_decls = &self.di_atom_decls, | 1093 | .di_atom_decls = &self.di_atom_decls, |
| 1091 | .dbg_line_func = undefined, | 1094 | .dbg_line_func = undefined, |
| 1092 | .dbg_line = std.ArrayList(u8).init(gpa), | 1095 | .dbg_line = std.ArrayList(u8).init(gpa), |
| ... | @@ -1105,7 +1108,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1105,7 +1108,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1105 | 1108 | ||
| 1106 | assert(decl.has_tv); | 1109 | assert(decl.has_tv); |
| 1107 | 1110 | ||
| 1108 | switch (decl.typeOf(mod).zigTypeTag(mod)) { | 1111 | switch (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu)) { |
| 1109 | .Fn => { | 1112 | .Fn => { |
| 1110 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); | 1113 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); |
| 1111 | 1114 | ||
| ... | @@ -1114,13 +1117,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1114,13 +1117,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1114 | try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1); | 1117 | try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1); |
| 1115 | 1118 | ||
| 1116 | decl_state.dbg_line_func = decl.val.toIntern(); | 1119 | decl_state.dbg_line_func = decl.val.toIntern(); |
| 1117 | const func = decl.val.getFunction(mod).?; | 1120 | const func = decl.val.getFunction(pt.zcu).?; |
| 1118 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ | 1121 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ |
| 1119 | decl.navSrcLine(mod), | 1122 | decl.navSrcLine(pt.zcu), |
| 1120 | func.lbrace_line, | 1123 | func.lbrace_line, |
| 1121 | func.rbrace_line, | 1124 | func.rbrace_line, |
| 1122 | }); | 1125 | }); |
| 1123 | const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line); | 1126 | const line: u28 = @intCast(decl.navSrcLine(pt.zcu) + func.lbrace_line); |
| 1124 | 1127 | ||
| 1125 | dbg_line_buffer.appendSliceAssumeCapacity(&.{ | 1128 | dbg_line_buffer.appendSliceAssumeCapacity(&.{ |
| 1126 | DW.LNS.extended_op, | 1129 | DW.LNS.extended_op, |
| ... | @@ -1142,7 +1145,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1142,7 +1145,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1142 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); | 1145 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); |
| 1143 | // Once we support more than one source file, this will have the ability to be more | 1146 | // Once we support more than one source file, this will have the ability to be more |
| 1144 | // than one possible value. | 1147 | // than one possible value. |
| 1145 | const file_index = try self.addDIFile(mod, decl_index); | 1148 | const file_index = try self.addDIFile(pt.zcu, decl_index); |
| 1146 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); | 1149 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); |
| 1147 | 1150 | ||
| 1148 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column); | 1151 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column); |
| ... | @@ -1153,13 +1156,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1153,13 +1156,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1153 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); | 1156 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); |
| 1154 | 1157 | ||
| 1155 | // .debug_info subprogram | 1158 | // .debug_info subprogram |
| 1156 | const decl_name_slice = decl.name.toSlice(&mod.intern_pool); | 1159 | const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool); |
| 1157 | const decl_linkage_name_slice = decl_linkage_name.toSlice(&mod.intern_pool); | 1160 | const decl_linkage_name_slice = decl_linkage_name.toSlice(&pt.zcu.intern_pool); |
| 1158 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + | 1161 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + |
| 1159 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); | 1162 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); |
| 1160 | 1163 | ||
| 1161 | const fn_ret_type = decl.typeOf(mod).fnReturnType(mod); | 1164 | const fn_ret_type = decl.typeOf(pt.zcu).fnReturnType(pt.zcu); |
| 1162 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod); | 1165 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(pt); |
| 1163 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum( | 1166 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum( |
| 1164 | @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid), | 1167 | @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid), |
| 1165 | )); | 1168 | )); |
| ... | @@ -1191,7 +1194,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1191,7 +1194,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1191 | 1194 | ||
| 1192 | pub fn commitDeclState( | 1195 | pub fn commitDeclState( |
| 1193 | self: *Dwarf, | 1196 | self: *Dwarf, |
| 1194 | zcu: *Module, | 1197 | pt: Zcu.PerThread, |
| 1195 | decl_index: InternPool.DeclIndex, | 1198 | decl_index: InternPool.DeclIndex, |
| 1196 | sym_addr: u64, | 1199 | sym_addr: u64, |
| 1197 | sym_size: u64, | 1200 | sym_size: u64, |
| ... | @@ -1201,6 +1204,7 @@ pub fn commitDeclState( | ... | @@ -1201,6 +1204,7 @@ pub fn commitDeclState( |
| 1201 | defer tracy.end(); | 1204 | defer tracy.end(); |
| 1202 | 1205 | ||
| 1203 | const gpa = self.allocator; | 1206 | const gpa = self.allocator; |
| 1207 | const zcu = pt.zcu; | ||
| 1204 | const decl = zcu.declPtr(decl_index); | 1208 | const decl = zcu.declPtr(decl_index); |
| 1205 | const ip = &zcu.intern_pool; | 1209 | const ip = &zcu.intern_pool; |
| 1206 | const namespace = zcu.namespacePtr(decl.src_namespace); | 1210 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| ... | @@ -1432,7 +1436,7 @@ pub fn commitDeclState( | ... | @@ -1432,7 +1436,7 @@ pub fn commitDeclState( |
| 1432 | if (ip.isErrorSetType(ty.toIntern())) continue; | 1436 | if (ip.isErrorSetType(ty.toIntern())) continue; |
| 1433 | 1437 | ||
| 1434 | symbol.offset = @intCast(dbg_info_buffer.items.len); | 1438 | symbol.offset = @intCast(dbg_info_buffer.items.len); |
| 1435 | try decl_state.addDbgInfoType(zcu, di_atom_index, ty); | 1439 | try decl_state.addDbgInfoType(pt, di_atom_index, ty); |
| 1436 | } | 1440 | } |
| 1437 | } | 1441 | } |
| 1438 | 1442 | ||
| ... | @@ -1457,7 +1461,7 @@ pub fn commitDeclState( | ... | @@ -1457,7 +1461,7 @@ pub fn commitDeclState( |
| 1457 | reloc.offset, | 1461 | reloc.offset, |
| 1458 | value, | 1462 | value, |
| 1459 | reloc_target, | 1463 | reloc_target, |
| 1460 | ty.fmt(zcu), | 1464 | ty.fmt(pt), |
| 1461 | }); | 1465 | }); |
| 1462 | mem.writeInt( | 1466 | mem.writeInt( |
| 1463 | u32, | 1467 | u32, |
| ... | @@ -1691,7 +1695,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons | ... | @@ -1691,7 +1695,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons |
| 1691 | } | 1695 | } |
| 1692 | } | 1696 | } |
| 1693 | 1697 | ||
| 1694 | pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 1698 | pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { |
| 1695 | const tracy = trace(@src()); | 1699 | const tracy = trace(@src()); |
| 1696 | defer tracy.end(); | 1700 | defer tracy.end(); |
| 1697 | 1701 | ||
| ... | @@ -1699,14 +1703,14 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D | ... | @@ -1699,14 +1703,14 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D |
| 1699 | const atom = self.getAtom(.src_fn, atom_index); | 1703 | const atom = self.getAtom(.src_fn, atom_index); |
| 1700 | if (atom.len == 0) return; | 1704 | if (atom.len == 0) return; |
| 1701 | 1705 | ||
| 1702 | const decl = mod.declPtr(decl_index); | 1706 | const decl = zcu.declPtr(decl_index); |
| 1703 | const func = decl.val.getFunction(mod).?; | 1707 | const func = decl.val.getFunction(zcu).?; |
| 1704 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ | 1708 | log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{ |
| 1705 | decl.navSrcLine(mod), | 1709 | decl.navSrcLine(zcu), |
| 1706 | func.lbrace_line, | 1710 | func.lbrace_line, |
| 1707 | func.rbrace_line, | 1711 | func.rbrace_line, |
| 1708 | }); | 1712 | }); |
| 1709 | const line: u28 = @intCast(decl.navSrcLine(mod) + func.lbrace_line); | 1713 | const line: u28 = @intCast(decl.navSrcLine(zcu) + func.lbrace_line); |
| 1710 | var data: [4]u8 = undefined; | 1714 | var data: [4]u8 = undefined; |
| 1711 | leb128.writeUnsignedFixed(4, &data, line); | 1715 | leb128.writeUnsignedFixed(4, &data, line); |
| 1712 | 1716 | ||
| ... | @@ -1969,7 +1973,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize { | ... | @@ -1969,7 +1973,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize { |
| 1969 | return 120; | 1973 | return 120; |
| 1970 | } | 1974 | } |
| 1971 | 1975 | ||
| 1972 | pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) !void { | 1976 | pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Zcu, low_pc: u64, high_pc: u64) !void { |
| 1973 | // If this value is null it means there is an error in the module; | 1977 | // If this value is null it means there is an error in the module; |
| 1974 | // leave debug_info_header_dirty=true. | 1978 | // leave debug_info_header_dirty=true. |
| 1975 | const first_dbg_info_off = self.getDebugInfoOff() orelse return; | 1979 | const first_dbg_info_off = self.getDebugInfoOff() orelse return; |
| ... | @@ -2058,14 +2062,14 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) | ... | @@ -2058,14 +2062,14 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) |
| 2058 | } | 2062 | } |
| 2059 | } | 2063 | } |
| 2060 | 2064 | ||
| 2061 | fn resolveCompilationDir(module: *Module, buffer: *[std.fs.max_path_bytes]u8) []const u8 { | 2065 | fn resolveCompilationDir(zcu: *Zcu, buffer: *[std.fs.max_path_bytes]u8) []const u8 { |
| 2062 | // We fully resolve all paths at this point to avoid lack of source line info in stack | 2066 | // We fully resolve all paths at this point to avoid lack of source line info in stack |
| 2063 | // traces or lack of debugging information which, if relative paths were used, would | 2067 | // traces or lack of debugging information which, if relative paths were used, would |
| 2064 | // be very location dependent. | 2068 | // be very location dependent. |
| 2065 | // TODO: the only concern I have with this is WASI as either host or target, should | 2069 | // TODO: the only concern I have with this is WASI as either host or target, should |
| 2066 | // we leave the paths as relative then? | 2070 | // we leave the paths as relative then? |
| 2067 | const root_dir_path = module.root_mod.root.root_dir.path orelse "."; | 2071 | const root_dir_path = zcu.root_mod.root.root_dir.path orelse "."; |
| 2068 | const sub_path = module.root_mod.root.sub_path; | 2072 | const sub_path = zcu.root_mod.root.sub_path; |
| 2069 | const realpath = if (std.fs.path.isAbsolute(root_dir_path)) r: { | 2073 | const realpath = if (std.fs.path.isAbsolute(root_dir_path)) r: { |
| 2070 | @memcpy(buffer[0..root_dir_path.len], root_dir_path); | 2074 | @memcpy(buffer[0..root_dir_path.len], root_dir_path); |
| 2071 | break :r root_dir_path; | 2075 | break :r root_dir_path; |
| ... | @@ -2682,7 +2686,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { | ... | @@ -2682,7 +2686,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 2682 | return actual_size +| (actual_size / ideal_factor); | 2686 | return actual_size +| (actual_size / ideal_factor); |
| 2683 | } | 2687 | } |
| 2684 | 2688 | ||
| 2685 | pub fn flushModule(self: *Dwarf, module: *Module) !void { | 2689 | pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void { |
| 2686 | const comp = self.bin_file.comp; | 2690 | const comp = self.bin_file.comp; |
| 2687 | const target = comp.root_mod.resolved_target.result; | 2691 | const target = comp.root_mod.resolved_target.result; |
| 2688 | 2692 | ||
| ... | @@ -2694,9 +2698,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { | ... | @@ -2694,9 +2698,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { |
| 2694 | 2698 | ||
| 2695 | var dbg_info_buffer = std.ArrayList(u8).init(arena); | 2699 | var dbg_info_buffer = std.ArrayList(u8).init(arena); |
| 2696 | try addDbgInfoErrorSetNames( | 2700 | try addDbgInfoErrorSetNames( |
| 2697 | module, | 2701 | pt, |
| 2698 | Type.anyerror, | 2702 | Type.anyerror, |
| 2699 | module.global_error_set.keys(), | 2703 | pt.zcu.global_error_set.keys(), |
| 2700 | target, | 2704 | target, |
| 2701 | &dbg_info_buffer, | 2705 | &dbg_info_buffer, |
| 2702 | ); | 2706 | ); |
| ... | @@ -2759,9 +2763,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { | ... | @@ -2759,9 +2763,9 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { |
| 2759 | } | 2763 | } |
| 2760 | } | 2764 | } |
| 2761 | 2765 | ||
| 2762 | fn addDIFile(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !u28 { | 2766 | fn addDIFile(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !u28 { |
| 2763 | const decl = mod.declPtr(decl_index); | 2767 | const decl = zcu.declPtr(decl_index); |
| 2764 | const file_scope = decl.getFileScope(mod); | 2768 | const file_scope = decl.getFileScope(zcu); |
| 2765 | const gop = try self.di_files.getOrPut(self.allocator, file_scope); | 2769 | const gop = try self.di_files.getOrPut(self.allocator, file_scope); |
| 2766 | if (!gop.found_existing) { | 2770 | if (!gop.found_existing) { |
| 2767 | switch (self.bin_file.tag) { | 2771 | switch (self.bin_file.tag) { |
| ... | @@ -2827,16 +2831,16 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { | ... | @@ -2827,16 +2831,16 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { |
| 2827 | } | 2831 | } |
| 2828 | 2832 | ||
| 2829 | fn addDbgInfoErrorSet( | 2833 | fn addDbgInfoErrorSet( |
| 2830 | mod: *Module, | 2834 | pt: Zcu.PerThread, |
| 2831 | ty: Type, | 2835 | ty: Type, |
| 2832 | target: std.Target, | 2836 | target: std.Target, |
| 2833 | dbg_info_buffer: *std.ArrayList(u8), | 2837 | dbg_info_buffer: *std.ArrayList(u8), |
| 2834 | ) !void { | 2838 | ) !void { |
| 2835 | return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod).get(&mod.intern_pool), target, dbg_info_buffer); | 2839 | return addDbgInfoErrorSetNames(pt, ty, ty.errorSetNames(pt.zcu).get(&pt.zcu.intern_pool), target, dbg_info_buffer); |
| 2836 | } | 2840 | } |
| 2837 | 2841 | ||
| 2838 | fn addDbgInfoErrorSetNames( | 2842 | fn addDbgInfoErrorSetNames( |
| 2839 | mod: *Module, | 2843 | pt: Zcu.PerThread, |
| 2840 | /// Used for printing the type name only. | 2844 | /// Used for printing the type name only. |
| 2841 | ty: Type, | 2845 | ty: Type, |
| 2842 | error_names: []const InternPool.NullTerminatedString, | 2846 | error_names: []const InternPool.NullTerminatedString, |
| ... | @@ -2848,10 +2852,10 @@ fn addDbgInfoErrorSetNames( | ... | @@ -2848,10 +2852,10 @@ fn addDbgInfoErrorSetNames( |
| 2848 | // DW.AT.enumeration_type | 2852 | // DW.AT.enumeration_type |
| 2849 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type)); | 2853 | try dbg_info_buffer.append(@intFromEnum(AbbrevCode.enum_type)); |
| 2850 | // DW.AT.byte_size, DW.FORM.udata | 2854 | // DW.AT.byte_size, DW.FORM.udata |
| 2851 | const abi_size = Type.anyerror.abiSize(mod); | 2855 | const abi_size = Type.anyerror.abiSize(pt); |
| 2852 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); | 2856 | try leb128.writeUleb128(dbg_info_buffer.writer(), abi_size); |
| 2853 | // DW.AT.name, DW.FORM.string | 2857 | // DW.AT.name, DW.FORM.string |
| 2854 | try ty.print(dbg_info_buffer.writer(), mod); | 2858 | try ty.print(dbg_info_buffer.writer(), pt); |
| 2855 | try dbg_info_buffer.append(0); | 2859 | try dbg_info_buffer.append(0); |
| 2856 | 2860 | ||
| 2857 | // DW.AT.enumerator | 2861 | // DW.AT.enumerator |
| ... | @@ -2865,8 +2869,8 @@ fn addDbgInfoErrorSetNames( | ... | @@ -2865,8 +2869,8 @@ fn addDbgInfoErrorSetNames( |
| 2865 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian); | 2869 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian); |
| 2866 | 2870 | ||
| 2867 | for (error_names) |error_name| { | 2871 | for (error_names) |error_name| { |
| 2868 | const int = try mod.getErrorValue(error_name); | 2872 | const int = try pt.zcu.getErrorValue(error_name); |
| 2869 | const error_name_slice = error_name.toSlice(&mod.intern_pool); | 2873 | const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool); |
| 2870 | // DW.AT.enumerator | 2874 | // DW.AT.enumerator |
| 2871 | try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64)); | 2875 | try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64)); |
| 2872 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.enum_variant)); | 2876 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevCode.enum_variant)); |
| ... | @@ -2965,8 +2969,6 @@ const LinkBlock = File.LinkBlock; | ... | @@ -2965,8 +2969,6 @@ const LinkBlock = File.LinkBlock; |
| 2965 | const LinkFn = File.LinkFn; | 2969 | const LinkFn = File.LinkFn; |
| 2966 | const LinkerLoad = @import("../codegen.zig").LinkerLoad; | 2970 | const LinkerLoad = @import("../codegen.zig").LinkerLoad; |
| 2967 | const Zcu = @import("../Zcu.zig"); | 2971 | const Zcu = @import("../Zcu.zig"); |
| 2968 | /// Deprecated. | ||
| 2969 | const Module = Zcu; | ||
| 2970 | const InternPool = @import("../InternPool.zig"); | 2972 | const InternPool = @import("../InternPool.zig"); |
| 2971 | const StringTable = @import("StringTable.zig"); | 2973 | const StringTable = @import("StringTable.zig"); |
| 2972 | const Type = @import("../Type.zig"); | 2974 | const Type = @import("../Type.zig"); |
src/link/Elf.zig+20-19| ... | @@ -550,11 +550,12 @@ pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: li | ... | @@ -550,11 +550,12 @@ pub fn getDeclVAddr(self: *Elf, decl_index: InternPool.DeclIndex, reloc_info: li |
| 550 | 550 | ||
| 551 | pub fn lowerAnonDecl( | 551 | pub fn lowerAnonDecl( |
| 552 | self: *Elf, | 552 | self: *Elf, |
| 553 | pt: Zcu.PerThread, | ||
| 553 | decl_val: InternPool.Index, | 554 | decl_val: InternPool.Index, |
| 554 | explicit_alignment: InternPool.Alignment, | 555 | explicit_alignment: InternPool.Alignment, |
| 555 | src_loc: Module.LazySrcLoc, | 556 | src_loc: Module.LazySrcLoc, |
| 556 | ) !codegen.Result { | 557 | ) !codegen.Result { |
| 557 | return self.zigObjectPtr().?.lowerAnonDecl(self, decl_val, explicit_alignment, src_loc); | 558 | return self.zigObjectPtr().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc); |
| 558 | } | 559 | } |
| 559 | 560 | ||
| 560 | pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 561 | pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| ... | @@ -1064,15 +1065,15 @@ pub fn markDirty(self: *Elf, shdr_index: u32) void { | ... | @@ -1064,15 +1065,15 @@ pub fn markDirty(self: *Elf, shdr_index: u32) void { |
| 1064 | } | 1065 | } |
| 1065 | } | 1066 | } |
| 1066 | 1067 | ||
| 1067 | pub fn flush(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 1068 | pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 1068 | const use_lld = build_options.have_llvm and self.base.comp.config.use_lld; | 1069 | const use_lld = build_options.have_llvm and self.base.comp.config.use_lld; |
| 1069 | if (use_lld) { | 1070 | if (use_lld) { |
| 1070 | return self.linkWithLLD(arena, prog_node); | 1071 | return self.linkWithLLD(arena, tid, prog_node); |
| 1071 | } | 1072 | } |
| 1072 | try self.flushModule(arena, prog_node); | 1073 | try self.flushModule(arena, tid, prog_node); |
| 1073 | } | 1074 | } |
| 1074 | 1075 | ||
| 1075 | pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 1076 | pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 1076 | const tracy = trace(@src()); | 1077 | const tracy = trace(@src()); |
| 1077 | defer tracy.end(); | 1078 | defer tracy.end(); |
| 1078 | 1079 | ||
| ... | @@ -1103,7 +1104,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) l | ... | @@ -1103,7 +1104,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) l |
| 1103 | // --verbose-link | 1104 | // --verbose-link |
| 1104 | if (comp.verbose_link) try self.dumpArgv(comp); | 1105 | if (comp.verbose_link) try self.dumpArgv(comp); |
| 1105 | 1106 | ||
| 1106 | if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self); | 1107 | if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self, tid); |
| 1107 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); | 1108 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); |
| 1108 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); | 1109 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); |
| 1109 | 1110 | ||
| ... | @@ -2146,7 +2147,7 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -2146,7 +2147,7 @@ fn scanRelocs(self: *Elf) !void { |
| 2146 | } | 2147 | } |
| 2147 | } | 2148 | } |
| 2148 | 2149 | ||
| 2149 | fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void { | 2150 | fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 2150 | const tracy = trace(@src()); | 2151 | const tracy = trace(@src()); |
| 2151 | defer tracy.end(); | 2152 | defer tracy.end(); |
| 2152 | 2153 | ||
| ... | @@ -2159,7 +2160,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void | ... | @@ -2159,7 +2160,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void |
| 2159 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 2160 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 2160 | // will not be part of the linker line anyway. | 2161 | // will not be part of the linker line anyway. |
| 2161 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { | 2162 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { |
| 2162 | try self.flushModule(arena, prog_node); | 2163 | try self.flushModule(arena, tid, prog_node); |
| 2163 | 2164 | ||
| 2164 | if (fs.path.dirname(full_out_path)) |dirname| { | 2165 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 2165 | break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? }); | 2166 | break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? }); |
| ... | @@ -2983,41 +2984,41 @@ pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void { | ... | @@ -2983,41 +2984,41 @@ pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void { |
| 2983 | return self.zigObjectPtr().?.freeDecl(self, decl_index); | 2984 | return self.zigObjectPtr().?.freeDecl(self, decl_index); |
| 2984 | } | 2985 | } |
| 2985 | 2986 | ||
| 2986 | pub fn updateFunc(self: *Elf, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 2987 | pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 2987 | if (build_options.skip_non_native and builtin.object_format != .elf) { | 2988 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2988 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 2989 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 2989 | } | 2990 | } |
| 2990 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness); | 2991 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); |
| 2991 | return self.zigObjectPtr().?.updateFunc(self, mod, func_index, air, liveness); | 2992 | return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness); |
| 2992 | } | 2993 | } |
| 2993 | 2994 | ||
| 2994 | pub fn updateDecl( | 2995 | pub fn updateDecl( |
| 2995 | self: *Elf, | 2996 | self: *Elf, |
| 2996 | mod: *Module, | 2997 | pt: Zcu.PerThread, |
| 2997 | decl_index: InternPool.DeclIndex, | 2998 | decl_index: InternPool.DeclIndex, |
| 2998 | ) link.File.UpdateDeclError!void { | 2999 | ) link.File.UpdateDeclError!void { |
| 2999 | if (build_options.skip_non_native and builtin.object_format != .elf) { | 3000 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 3000 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 3001 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3001 | } | 3002 | } |
| 3002 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); | 3003 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index); |
| 3003 | return self.zigObjectPtr().?.updateDecl(self, mod, decl_index); | 3004 | return self.zigObjectPtr().?.updateDecl(self, pt, decl_index); |
| 3004 | } | 3005 | } |
| 3005 | 3006 | ||
| 3006 | pub fn lowerUnnamedConst(self: *Elf, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 3007 | pub fn lowerUnnamedConst(self: *Elf, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 3007 | return self.zigObjectPtr().?.lowerUnnamedConst(self, val, decl_index); | 3008 | return self.zigObjectPtr().?.lowerUnnamedConst(self, pt, val, decl_index); |
| 3008 | } | 3009 | } |
| 3009 | 3010 | ||
| 3010 | pub fn updateExports( | 3011 | pub fn updateExports( |
| 3011 | self: *Elf, | 3012 | self: *Elf, |
| 3012 | mod: *Module, | 3013 | pt: Zcu.PerThread, |
| 3013 | exported: Module.Exported, | 3014 | exported: Module.Exported, |
| 3014 | export_indices: []const u32, | 3015 | export_indices: []const u32, |
| 3015 | ) link.File.UpdateExportsError!void { | 3016 | ) link.File.UpdateExportsError!void { |
| 3016 | if (build_options.skip_non_native and builtin.object_format != .elf) { | 3017 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 3017 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 3018 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3018 | } | 3019 | } |
| 3019 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices); | 3020 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); |
| 3020 | return self.zigObjectPtr().?.updateExports(self, mod, exported, export_indices); | 3021 | return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices); |
| 3021 | } | 3022 | } |
| 3022 | 3023 | ||
| 3023 | pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 3024 | pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: InternPool.DeclIndex) !void { |
src/link/Elf/ZigObject.zig+60-55| ... | @@ -158,16 +158,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { | ... | @@ -158,16 +158,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { | 161 | pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { |
| 162 | // Handle any lazy symbols that were emitted by incremental compilation. | 162 | // Handle any lazy symbols that were emitted by incremental compilation. |
| 163 | if (self.lazy_syms.getPtr(.none)) |metadata| { | 163 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 164 | const zcu = elf_file.base.comp.module.?; | 164 | const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; |
| 165 | 165 | ||
| 166 | // Most lazy symbols can be updated on first use, but | 166 | // Most lazy symbols can be updated on first use, but |
| 167 | // anyerror needs to wait for everything to be flushed. | 167 | // anyerror needs to wait for everything to be flushed. |
| 168 | if (metadata.text_state != .unused) self.updateLazySymbol( | 168 | if (metadata.text_state != .unused) self.updateLazySymbol( |
| 169 | elf_file, | 169 | elf_file, |
| 170 | link.File.LazySymbol.initDecl(.code, null, zcu), | 170 | pt, |
| 171 | link.File.LazySymbol.initDecl(.code, null, pt.zcu), | ||
| 171 | metadata.text_symbol_index, | 172 | metadata.text_symbol_index, |
| 172 | ) catch |err| return switch (err) { | 173 | ) catch |err| return switch (err) { |
| 173 | error.CodegenFail => error.FlushFailure, | 174 | error.CodegenFail => error.FlushFailure, |
| ... | @@ -175,7 +176,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -175,7 +176,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 175 | }; | 176 | }; |
| 176 | if (metadata.rodata_state != .unused) self.updateLazySymbol( | 177 | if (metadata.rodata_state != .unused) self.updateLazySymbol( |
| 177 | elf_file, | 178 | elf_file, |
| 178 | link.File.LazySymbol.initDecl(.const_data, null, zcu), | 179 | pt, |
| 180 | link.File.LazySymbol.initDecl(.const_data, null, pt.zcu), | ||
| 179 | metadata.rodata_symbol_index, | 181 | metadata.rodata_symbol_index, |
| 180 | ) catch |err| return switch (err) { | 182 | ) catch |err| return switch (err) { |
| 181 | error.CodegenFail => error.FlushFailure, | 183 | error.CodegenFail => error.FlushFailure, |
| ... | @@ -188,8 +190,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -188,8 +190,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 188 | } | 190 | } |
| 189 | 191 | ||
| 190 | if (self.dwarf) |*dw| { | 192 | if (self.dwarf) |*dw| { |
| 191 | const zcu = elf_file.base.comp.module.?; | 193 | const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; |
| 192 | try dw.flushModule(zcu); | 194 | try dw.flushModule(pt); |
| 193 | 195 | ||
| 194 | // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections | 196 | // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections |
| 195 | // extracted from input object files correctly. | 197 | // extracted from input object files correctly. |
| ... | @@ -202,7 +204,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -202,7 +204,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 202 | const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?]; | 204 | const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?]; |
| 203 | const low_pc = text_shdr.sh_addr; | 205 | const low_pc = text_shdr.sh_addr; |
| 204 | const high_pc = text_shdr.sh_addr + text_shdr.sh_size; | 206 | const high_pc = text_shdr.sh_addr + text_shdr.sh_size; |
| 205 | try dw.writeDbgInfoHeader(zcu, low_pc, high_pc); | 207 | try dw.writeDbgInfoHeader(pt.zcu, low_pc, high_pc); |
| 206 | self.debug_info_header_dirty = false; | 208 | self.debug_info_header_dirty = false; |
| 207 | } | 209 | } |
| 208 | 210 | ||
| ... | @@ -684,6 +686,7 @@ pub fn getAnonDeclVAddr( | ... | @@ -684,6 +686,7 @@ pub fn getAnonDeclVAddr( |
| 684 | pub fn lowerAnonDecl( | 686 | pub fn lowerAnonDecl( |
| 685 | self: *ZigObject, | 687 | self: *ZigObject, |
| 686 | elf_file: *Elf, | 688 | elf_file: *Elf, |
| 689 | pt: Zcu.PerThread, | ||
| 687 | decl_val: InternPool.Index, | 690 | decl_val: InternPool.Index, |
| 688 | explicit_alignment: InternPool.Alignment, | 691 | explicit_alignment: InternPool.Alignment, |
| 689 | src_loc: Module.LazySrcLoc, | 692 | src_loc: Module.LazySrcLoc, |
| ... | @@ -692,7 +695,7 @@ pub fn lowerAnonDecl( | ... | @@ -692,7 +695,7 @@ pub fn lowerAnonDecl( |
| 692 | const mod = elf_file.base.comp.module.?; | 695 | const mod = elf_file.base.comp.module.?; |
| 693 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | 696 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 694 | const decl_alignment = switch (explicit_alignment) { | 697 | const decl_alignment = switch (explicit_alignment) { |
| 695 | .none => ty.abiAlignment(mod), | 698 | .none => ty.abiAlignment(pt), |
| 696 | else => explicit_alignment, | 699 | else => explicit_alignment, |
| 697 | }; | 700 | }; |
| 698 | if (self.anon_decls.get(decl_val)) |metadata| { | 701 | if (self.anon_decls.get(decl_val)) |metadata| { |
| ... | @@ -708,6 +711,7 @@ pub fn lowerAnonDecl( | ... | @@ -708,6 +711,7 @@ pub fn lowerAnonDecl( |
| 708 | }) catch unreachable; | 711 | }) catch unreachable; |
| 709 | const res = self.lowerConst( | 712 | const res = self.lowerConst( |
| 710 | elf_file, | 713 | elf_file, |
| 714 | pt, | ||
| 711 | name, | 715 | name, |
| 712 | val, | 716 | val, |
| 713 | decl_alignment, | 717 | decl_alignment, |
| ... | @@ -733,10 +737,11 @@ pub fn lowerAnonDecl( | ... | @@ -733,10 +737,11 @@ pub fn lowerAnonDecl( |
| 733 | pub fn getOrCreateMetadataForLazySymbol( | 737 | pub fn getOrCreateMetadataForLazySymbol( |
| 734 | self: *ZigObject, | 738 | self: *ZigObject, |
| 735 | elf_file: *Elf, | 739 | elf_file: *Elf, |
| 740 | pt: Zcu.PerThread, | ||
| 736 | lazy_sym: link.File.LazySymbol, | 741 | lazy_sym: link.File.LazySymbol, |
| 737 | ) !Symbol.Index { | 742 | ) !Symbol.Index { |
| 738 | const gpa = elf_file.base.comp.gpa; | 743 | const mod = pt.zcu; |
| 739 | const mod = elf_file.base.comp.module.?; | 744 | const gpa = mod.gpa; |
| 740 | const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod)); | 745 | const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod)); |
| 741 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); | 746 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 742 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 747 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| ... | @@ -766,7 +771,7 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -766,7 +771,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 766 | metadata.state.* = .pending_flush; | 771 | metadata.state.* = .pending_flush; |
| 767 | const symbol_index = metadata.symbol_index.*; | 772 | const symbol_index = metadata.symbol_index.*; |
| 768 | // anyerror needs to be deferred until flushModule | 773 | // anyerror needs to be deferred until flushModule |
| 769 | if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(elf_file, lazy_sym, symbol_index); | 774 | if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index); |
| 770 | return symbol_index; | 775 | return symbol_index; |
| 771 | } | 776 | } |
| 772 | 777 | ||
| ... | @@ -893,6 +898,7 @@ fn getDeclShdrIndex( | ... | @@ -893,6 +898,7 @@ fn getDeclShdrIndex( |
| 893 | fn updateDeclCode( | 898 | fn updateDeclCode( |
| 894 | self: *ZigObject, | 899 | self: *ZigObject, |
| 895 | elf_file: *Elf, | 900 | elf_file: *Elf, |
| 901 | pt: Zcu.PerThread, | ||
| 896 | decl_index: InternPool.DeclIndex, | 902 | decl_index: InternPool.DeclIndex, |
| 897 | sym_index: Symbol.Index, | 903 | sym_index: Symbol.Index, |
| 898 | shdr_index: u32, | 904 | shdr_index: u32, |
| ... | @@ -900,13 +906,13 @@ fn updateDeclCode( | ... | @@ -900,13 +906,13 @@ fn updateDeclCode( |
| 900 | stt_bits: u8, | 906 | stt_bits: u8, |
| 901 | ) !void { | 907 | ) !void { |
| 902 | const gpa = elf_file.base.comp.gpa; | 908 | const gpa = elf_file.base.comp.gpa; |
| 903 | const mod = elf_file.base.comp.module.?; | 909 | const mod = pt.zcu; |
| 904 | const decl = mod.declPtr(decl_index); | 910 | const decl = mod.declPtr(decl_index); |
| 905 | const decl_name = try decl.fullyQualifiedName(mod); | 911 | const decl_name = try decl.fullyQualifiedName(mod); |
| 906 | 912 | ||
| 907 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | 913 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); |
| 908 | 914 | ||
| 909 | const required_alignment = decl.getAlignment(mod).max( | 915 | const required_alignment = decl.getAlignment(pt).max( |
| 910 | target_util.minFunctionAlignment(mod.getTarget()), | 916 | target_util.minFunctionAlignment(mod.getTarget()), |
| 911 | ); | 917 | ); |
| 912 | 918 | ||
| ... | @@ -994,19 +1000,20 @@ fn updateDeclCode( | ... | @@ -994,19 +1000,20 @@ fn updateDeclCode( |
| 994 | fn updateTlv( | 1000 | fn updateTlv( |
| 995 | self: *ZigObject, | 1001 | self: *ZigObject, |
| 996 | elf_file: *Elf, | 1002 | elf_file: *Elf, |
| 1003 | pt: Zcu.PerThread, | ||
| 997 | decl_index: InternPool.DeclIndex, | 1004 | decl_index: InternPool.DeclIndex, |
| 998 | sym_index: Symbol.Index, | 1005 | sym_index: Symbol.Index, |
| 999 | shndx: u32, | 1006 | shndx: u32, |
| 1000 | code: []const u8, | 1007 | code: []const u8, |
| 1001 | ) !void { | 1008 | ) !void { |
| 1002 | const gpa = elf_file.base.comp.gpa; | 1009 | const mod = pt.zcu; |
| 1003 | const mod = elf_file.base.comp.module.?; | 1010 | const gpa = mod.gpa; |
| 1004 | const decl = mod.declPtr(decl_index); | 1011 | const decl = mod.declPtr(decl_index); |
| 1005 | const decl_name = try decl.fullyQualifiedName(mod); | 1012 | const decl_name = try decl.fullyQualifiedName(mod); |
| 1006 | 1013 | ||
| 1007 | log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl }); | 1014 | log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl }); |
| 1008 | 1015 | ||
| 1009 | const required_alignment = decl.getAlignment(mod); | 1016 | const required_alignment = decl.getAlignment(pt); |
| 1010 | 1017 | ||
| 1011 | const sym = elf_file.symbol(sym_index); | 1018 | const sym = elf_file.symbol(sym_index); |
| 1012 | const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index]; | 1019 | const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index]; |
| ... | @@ -1048,7 +1055,7 @@ fn updateTlv( | ... | @@ -1048,7 +1055,7 @@ fn updateTlv( |
| 1048 | pub fn updateFunc( | 1055 | pub fn updateFunc( |
| 1049 | self: *ZigObject, | 1056 | self: *ZigObject, |
| 1050 | elf_file: *Elf, | 1057 | elf_file: *Elf, |
| 1051 | mod: *Module, | 1058 | pt: Zcu.PerThread, |
| 1052 | func_index: InternPool.Index, | 1059 | func_index: InternPool.Index, |
| 1053 | air: Air, | 1060 | air: Air, |
| 1054 | liveness: Liveness, | 1061 | liveness: Liveness, |
| ... | @@ -1056,6 +1063,7 @@ pub fn updateFunc( | ... | @@ -1056,6 +1063,7 @@ pub fn updateFunc( |
| 1056 | const tracy = trace(@src()); | 1063 | const tracy = trace(@src()); |
| 1057 | defer tracy.end(); | 1064 | defer tracy.end(); |
| 1058 | 1065 | ||
| 1066 | const mod = pt.zcu; | ||
| 1059 | const gpa = elf_file.base.comp.gpa; | 1067 | const gpa = elf_file.base.comp.gpa; |
| 1060 | const func = mod.funcInfo(func_index); | 1068 | const func = mod.funcInfo(func_index); |
| 1061 | const decl_index = func.owner_decl; | 1069 | const decl_index = func.owner_decl; |
| ... | @@ -1068,29 +1076,19 @@ pub fn updateFunc( | ... | @@ -1068,29 +1076,19 @@ pub fn updateFunc( |
| 1068 | var code_buffer = std.ArrayList(u8).init(gpa); | 1076 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1069 | defer code_buffer.deinit(); | 1077 | defer code_buffer.deinit(); |
| 1070 | 1078 | ||
| 1071 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; | 1079 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null; |
| 1072 | defer if (decl_state) |*ds| ds.deinit(); | 1080 | defer if (decl_state) |*ds| ds.deinit(); |
| 1073 | 1081 | ||
| 1074 | const res = if (decl_state) |*ds| | 1082 | const res = try codegen.generateFunction( |
| 1075 | try codegen.generateFunction( | 1083 | &elf_file.base, |
| 1076 | &elf_file.base, | 1084 | pt, |
| 1077 | decl.navSrcLoc(mod), | 1085 | decl.navSrcLoc(mod), |
| 1078 | func_index, | 1086 | func_index, |
| 1079 | air, | 1087 | air, |
| 1080 | liveness, | 1088 | liveness, |
| 1081 | &code_buffer, | 1089 | &code_buffer, |
| 1082 | .{ .dwarf = ds }, | 1090 | if (decl_state) |*ds| .{ .dwarf = ds } else .none, |
| 1083 | ) | 1091 | ); |
| 1084 | else | ||
| 1085 | try codegen.generateFunction( | ||
| 1086 | &elf_file.base, | ||
| 1087 | decl.navSrcLoc(mod), | ||
| 1088 | func_index, | ||
| 1089 | air, | ||
| 1090 | liveness, | ||
| 1091 | &code_buffer, | ||
| 1092 | .none, | ||
| 1093 | ); | ||
| 1094 | 1092 | ||
| 1095 | const code = switch (res) { | 1093 | const code = switch (res) { |
| 1096 | .ok => code_buffer.items, | 1094 | .ok => code_buffer.items, |
| ... | @@ -1102,12 +1100,12 @@ pub fn updateFunc( | ... | @@ -1102,12 +1100,12 @@ pub fn updateFunc( |
| 1102 | }; | 1100 | }; |
| 1103 | 1101 | ||
| 1104 | const shndx = try self.getDeclShdrIndex(elf_file, decl, code); | 1102 | const shndx = try self.getDeclShdrIndex(elf_file, decl, code); |
| 1105 | try self.updateDeclCode(elf_file, decl_index, sym_index, shndx, code, elf.STT_FUNC); | 1103 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC); |
| 1106 | 1104 | ||
| 1107 | if (decl_state) |*ds| { | 1105 | if (decl_state) |*ds| { |
| 1108 | const sym = elf_file.symbol(sym_index); | 1106 | const sym = elf_file.symbol(sym_index); |
| 1109 | try self.dwarf.?.commitDeclState( | 1107 | try self.dwarf.?.commitDeclState( |
| 1110 | mod, | 1108 | pt, |
| 1111 | decl_index, | 1109 | decl_index, |
| 1112 | @intCast(sym.address(.{}, elf_file)), | 1110 | @intCast(sym.address(.{}, elf_file)), |
| 1113 | sym.atom(elf_file).?.size, | 1111 | sym.atom(elf_file).?.size, |
| ... | @@ -1121,12 +1119,13 @@ pub fn updateFunc( | ... | @@ -1121,12 +1119,13 @@ pub fn updateFunc( |
| 1121 | pub fn updateDecl( | 1119 | pub fn updateDecl( |
| 1122 | self: *ZigObject, | 1120 | self: *ZigObject, |
| 1123 | elf_file: *Elf, | 1121 | elf_file: *Elf, |
| 1124 | mod: *Module, | 1122 | pt: Zcu.PerThread, |
| 1125 | decl_index: InternPool.DeclIndex, | 1123 | decl_index: InternPool.DeclIndex, |
| 1126 | ) link.File.UpdateDeclError!void { | 1124 | ) link.File.UpdateDeclError!void { |
| 1127 | const tracy = trace(@src()); | 1125 | const tracy = trace(@src()); |
| 1128 | defer tracy.end(); | 1126 | defer tracy.end(); |
| 1129 | 1127 | ||
| 1128 | const mod = pt.zcu; | ||
| 1130 | const decl = mod.declPtr(decl_index); | 1129 | const decl = mod.declPtr(decl_index); |
| 1131 | 1130 | ||
| 1132 | if (decl.val.getExternFunc(mod)) |_| { | 1131 | if (decl.val.getExternFunc(mod)) |_| { |
| ... | @@ -1150,19 +1149,19 @@ pub fn updateDecl( | ... | @@ -1150,19 +1149,19 @@ pub fn updateDecl( |
| 1150 | var code_buffer = std.ArrayList(u8).init(gpa); | 1149 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1151 | defer code_buffer.deinit(); | 1150 | defer code_buffer.deinit(); |
| 1152 | 1151 | ||
| 1153 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; | 1152 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null; |
| 1154 | defer if (decl_state) |*ds| ds.deinit(); | 1153 | defer if (decl_state) |*ds| ds.deinit(); |
| 1155 | 1154 | ||
| 1156 | // TODO implement .debug_info for global variables | 1155 | // TODO implement .debug_info for global variables |
| 1157 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 1156 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 1158 | const res = if (decl_state) |*ds| | 1157 | const res = if (decl_state) |*ds| |
| 1159 | try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ | 1158 | try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ |
| 1160 | .dwarf = ds, | 1159 | .dwarf = ds, |
| 1161 | }, .{ | 1160 | }, .{ |
| 1162 | .parent_atom_index = sym_index, | 1161 | .parent_atom_index = sym_index, |
| 1163 | }) | 1162 | }) |
| 1164 | else | 1163 | else |
| 1165 | try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{ | 1164 | try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{ |
| 1166 | .parent_atom_index = sym_index, | 1165 | .parent_atom_index = sym_index, |
| 1167 | }); | 1166 | }); |
| 1168 | 1167 | ||
| ... | @@ -1177,14 +1176,14 @@ pub fn updateDecl( | ... | @@ -1177,14 +1176,14 @@ pub fn updateDecl( |
| 1177 | 1176 | ||
| 1178 | const shndx = try self.getDeclShdrIndex(elf_file, decl, code); | 1177 | const shndx = try self.getDeclShdrIndex(elf_file, decl, code); |
| 1179 | if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0) | 1178 | if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0) |
| 1180 | try self.updateTlv(elf_file, decl_index, sym_index, shndx, code) | 1179 | try self.updateTlv(elf_file, pt, decl_index, sym_index, shndx, code) |
| 1181 | else | 1180 | else |
| 1182 | try self.updateDeclCode(elf_file, decl_index, sym_index, shndx, code, elf.STT_OBJECT); | 1181 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT); |
| 1183 | 1182 | ||
| 1184 | if (decl_state) |*ds| { | 1183 | if (decl_state) |*ds| { |
| 1185 | const sym = elf_file.symbol(sym_index); | 1184 | const sym = elf_file.symbol(sym_index); |
| 1186 | try self.dwarf.?.commitDeclState( | 1185 | try self.dwarf.?.commitDeclState( |
| 1187 | mod, | 1186 | pt, |
| 1188 | decl_index, | 1187 | decl_index, |
| 1189 | @intCast(sym.address(.{}, elf_file)), | 1188 | @intCast(sym.address(.{}, elf_file)), |
| 1190 | sym.atom(elf_file).?.size, | 1189 | sym.atom(elf_file).?.size, |
| ... | @@ -1198,11 +1197,12 @@ pub fn updateDecl( | ... | @@ -1198,11 +1197,12 @@ pub fn updateDecl( |
| 1198 | fn updateLazySymbol( | 1197 | fn updateLazySymbol( |
| 1199 | self: *ZigObject, | 1198 | self: *ZigObject, |
| 1200 | elf_file: *Elf, | 1199 | elf_file: *Elf, |
| 1200 | pt: Zcu.PerThread, | ||
| 1201 | sym: link.File.LazySymbol, | 1201 | sym: link.File.LazySymbol, |
| 1202 | symbol_index: Symbol.Index, | 1202 | symbol_index: Symbol.Index, |
| 1203 | ) !void { | 1203 | ) !void { |
| 1204 | const gpa = elf_file.base.comp.gpa; | 1204 | const mod = pt.zcu; |
| 1205 | const mod = elf_file.base.comp.module.?; | 1205 | const gpa = mod.gpa; |
| 1206 | 1206 | ||
| 1207 | var required_alignment: InternPool.Alignment = .none; | 1207 | var required_alignment: InternPool.Alignment = .none; |
| 1208 | var code_buffer = std.ArrayList(u8).init(gpa); | 1208 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1211,7 +1211,7 @@ fn updateLazySymbol( | ... | @@ -1211,7 +1211,7 @@ fn updateLazySymbol( |
| 1211 | const name_str_index = blk: { | 1211 | const name_str_index = blk: { |
| 1212 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ | 1212 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ |
| 1213 | @tagName(sym.kind), | 1213 | @tagName(sym.kind), |
| 1214 | sym.ty.fmt(mod), | 1214 | sym.ty.fmt(pt), |
| 1215 | }); | 1215 | }); |
| 1216 | defer gpa.free(name); | 1216 | defer gpa.free(name); |
| 1217 | break :blk try self.strtab.insert(gpa, name); | 1217 | break :blk try self.strtab.insert(gpa, name); |
| ... | @@ -1220,6 +1220,7 @@ fn updateLazySymbol( | ... | @@ -1220,6 +1220,7 @@ fn updateLazySymbol( |
| 1220 | const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; | 1220 | const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; |
| 1221 | const res = try codegen.generateLazySymbol( | 1221 | const res = try codegen.generateLazySymbol( |
| 1222 | &elf_file.base, | 1222 | &elf_file.base, |
| 1223 | pt, | ||
| 1223 | src, | 1224 | src, |
| 1224 | sym, | 1225 | sym, |
| 1225 | &required_alignment, | 1226 | &required_alignment, |
| ... | @@ -1273,6 +1274,7 @@ fn updateLazySymbol( | ... | @@ -1273,6 +1274,7 @@ fn updateLazySymbol( |
| 1273 | pub fn lowerUnnamedConst( | 1274 | pub fn lowerUnnamedConst( |
| 1274 | self: *ZigObject, | 1275 | self: *ZigObject, |
| 1275 | elf_file: *Elf, | 1276 | elf_file: *Elf, |
| 1277 | pt: Zcu.PerThread, | ||
| 1276 | val: Value, | 1278 | val: Value, |
| 1277 | decl_index: InternPool.DeclIndex, | 1279 | decl_index: InternPool.DeclIndex, |
| 1278 | ) !u32 { | 1280 | ) !u32 { |
| ... | @@ -1291,9 +1293,10 @@ pub fn lowerUnnamedConst( | ... | @@ -1291,9 +1293,10 @@ pub fn lowerUnnamedConst( |
| 1291 | const ty = val.typeOf(mod); | 1293 | const ty = val.typeOf(mod); |
| 1292 | const sym_index = switch (try self.lowerConst( | 1294 | const sym_index = switch (try self.lowerConst( |
| 1293 | elf_file, | 1295 | elf_file, |
| 1296 | pt, | ||
| 1294 | name, | 1297 | name, |
| 1295 | val, | 1298 | val, |
| 1296 | ty.abiAlignment(mod), | 1299 | ty.abiAlignment(pt), |
| 1297 | elf_file.zig_data_rel_ro_section_index.?, | 1300 | elf_file.zig_data_rel_ro_section_index.?, |
| 1298 | decl.navSrcLoc(mod), | 1301 | decl.navSrcLoc(mod), |
| 1299 | )) { | 1302 | )) { |
| ... | @@ -1318,20 +1321,21 @@ const LowerConstResult = union(enum) { | ... | @@ -1318,20 +1321,21 @@ const LowerConstResult = union(enum) { |
| 1318 | fn lowerConst( | 1321 | fn lowerConst( |
| 1319 | self: *ZigObject, | 1322 | self: *ZigObject, |
| 1320 | elf_file: *Elf, | 1323 | elf_file: *Elf, |
| 1324 | pt: Zcu.PerThread, | ||
| 1321 | name: []const u8, | 1325 | name: []const u8, |
| 1322 | val: Value, | 1326 | val: Value, |
| 1323 | required_alignment: InternPool.Alignment, | 1327 | required_alignment: InternPool.Alignment, |
| 1324 | output_section_index: u32, | 1328 | output_section_index: u32, |
| 1325 | src_loc: Module.LazySrcLoc, | 1329 | src_loc: Module.LazySrcLoc, |
| 1326 | ) !LowerConstResult { | 1330 | ) !LowerConstResult { |
| 1327 | const gpa = elf_file.base.comp.gpa; | 1331 | const gpa = pt.zcu.gpa; |
| 1328 | 1332 | ||
| 1329 | var code_buffer = std.ArrayList(u8).init(gpa); | 1333 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1330 | defer code_buffer.deinit(); | 1334 | defer code_buffer.deinit(); |
| 1331 | 1335 | ||
| 1332 | const sym_index = try self.addAtom(elf_file); | 1336 | const sym_index = try self.addAtom(elf_file); |
| 1333 | 1337 | ||
| 1334 | const res = try codegen.generateSymbol(&elf_file.base, src_loc, val, &code_buffer, .{ | 1338 | const res = try codegen.generateSymbol(&elf_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1335 | .none = {}, | 1339 | .none = {}, |
| 1336 | }, .{ | 1340 | }, .{ |
| 1337 | .parent_atom_index = sym_index, | 1341 | .parent_atom_index = sym_index, |
| ... | @@ -1373,13 +1377,14 @@ fn lowerConst( | ... | @@ -1373,13 +1377,14 @@ fn lowerConst( |
| 1373 | pub fn updateExports( | 1377 | pub fn updateExports( |
| 1374 | self: *ZigObject, | 1378 | self: *ZigObject, |
| 1375 | elf_file: *Elf, | 1379 | elf_file: *Elf, |
| 1376 | mod: *Module, | 1380 | pt: Zcu.PerThread, |
| 1377 | exported: Module.Exported, | 1381 | exported: Module.Exported, |
| 1378 | export_indices: []const u32, | 1382 | export_indices: []const u32, |
| 1379 | ) link.File.UpdateExportsError!void { | 1383 | ) link.File.UpdateExportsError!void { |
| 1380 | const tracy = trace(@src()); | 1384 | const tracy = trace(@src()); |
| 1381 | defer tracy.end(); | 1385 | defer tracy.end(); |
| 1382 | 1386 | ||
| 1387 | const mod = pt.zcu; | ||
| 1383 | const gpa = elf_file.base.comp.gpa; | 1388 | const gpa = elf_file.base.comp.gpa; |
| 1384 | const metadata = switch (exported) { | 1389 | const metadata = switch (exported) { |
| 1385 | .decl_index => |decl_index| blk: { | 1390 | .decl_index => |decl_index| blk: { |
| ... | @@ -1388,7 +1393,7 @@ pub fn updateExports( | ... | @@ -1388,7 +1393,7 @@ pub fn updateExports( |
| 1388 | }, | 1393 | }, |
| 1389 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { | 1394 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { |
| 1390 | const first_exp = mod.all_exports.items[export_indices[0]]; | 1395 | const first_exp = mod.all_exports.items[export_indices[0]]; |
| 1391 | const res = try self.lowerAnonDecl(elf_file, value, .none, first_exp.src); | 1396 | const res = try self.lowerAnonDecl(elf_file, pt, value, .none, first_exp.src); |
| 1392 | switch (res) { | 1397 | switch (res) { |
| 1393 | .ok => {}, | 1398 | .ok => {}, |
| 1394 | .fail => |em| { | 1399 | .fail => |em| { |
src/link/MachO.zig+17-16| ... | @@ -360,11 +360,11 @@ pub fn deinit(self: *MachO) void { | ... | @@ -360,11 +360,11 @@ pub fn deinit(self: *MachO) void { |
| 360 | self.unwind_records.deinit(gpa); | 360 | self.unwind_records.deinit(gpa); |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 363 | pub fn flush(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 364 | try self.flushModule(arena, prog_node); | 364 | try self.flushModule(arena, tid, prog_node); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 367 | pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 368 | const tracy = trace(@src()); | 368 | const tracy = trace(@src()); |
| 369 | defer tracy.end(); | 369 | defer tracy.end(); |
| 370 | 370 | ||
| ... | @@ -391,7 +391,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -391,7 +391,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) |
| 391 | // --verbose-link | 391 | // --verbose-link |
| 392 | if (comp.verbose_link) try self.dumpArgv(comp); | 392 | if (comp.verbose_link) try self.dumpArgv(comp); |
| 393 | 393 | ||
| 394 | if (self.getZigObject()) |zo| try zo.flushModule(self); | 394 | if (self.getZigObject()) |zo| try zo.flushModule(self, tid); |
| 395 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); | 395 | if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); |
| 396 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); | 396 | if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); |
| 397 | 397 | ||
| ... | @@ -3178,24 +3178,24 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void { | ... | @@ -3178,24 +3178,24 @@ pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void { |
| 3178 | try self.base.file.?.pwriteAll(buffer.items, offset); | 3178 | try self.base.file.?.pwriteAll(buffer.items, offset); |
| 3179 | } | 3179 | } |
| 3180 | 3180 | ||
| 3181 | pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 3181 | pub fn updateFunc(self: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 3182 | if (build_options.skip_non_native and builtin.object_format != .macho) { | 3182 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3183 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 3183 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3184 | } | 3184 | } |
| 3185 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness); | 3185 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); |
| 3186 | return self.getZigObject().?.updateFunc(self, mod, func_index, air, liveness); | 3186 | return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness); |
| 3187 | } | 3187 | } |
| 3188 | 3188 | ||
| 3189 | pub fn lowerUnnamedConst(self: *MachO, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 3189 | pub fn lowerUnnamedConst(self: *MachO, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 3190 | return self.getZigObject().?.lowerUnnamedConst(self, val, decl_index); | 3190 | return self.getZigObject().?.lowerUnnamedConst(self, pt, val, decl_index); |
| 3191 | } | 3191 | } |
| 3192 | 3192 | ||
| 3193 | pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 3193 | pub fn updateDecl(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 3194 | if (build_options.skip_non_native and builtin.object_format != .macho) { | 3194 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3195 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 3195 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3196 | } | 3196 | } |
| 3197 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); | 3197 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index); |
| 3198 | return self.getZigObject().?.updateDecl(self, mod, decl_index); | 3198 | return self.getZigObject().?.updateDecl(self, pt, decl_index); |
| 3199 | } | 3199 | } |
| 3200 | 3200 | ||
| 3201 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void { | 3201 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void { |
| ... | @@ -3205,15 +3205,15 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPoo | ... | @@ -3205,15 +3205,15 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPoo |
| 3205 | 3205 | ||
| 3206 | pub fn updateExports( | 3206 | pub fn updateExports( |
| 3207 | self: *MachO, | 3207 | self: *MachO, |
| 3208 | mod: *Module, | 3208 | pt: Zcu.PerThread, |
| 3209 | exported: Module.Exported, | 3209 | exported: Module.Exported, |
| 3210 | export_indices: []const u32, | 3210 | export_indices: []const u32, |
| 3211 | ) link.File.UpdateExportsError!void { | 3211 | ) link.File.UpdateExportsError!void { |
| 3212 | if (build_options.skip_non_native and builtin.object_format != .macho) { | 3212 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3213 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 3213 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3214 | } | 3214 | } |
| 3215 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices); | 3215 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); |
| 3216 | return self.getZigObject().?.updateExports(self, mod, exported, export_indices); | 3216 | return self.getZigObject().?.updateExports(self, pt, exported, export_indices); |
| 3217 | } | 3217 | } |
| 3218 | 3218 | ||
| 3219 | pub fn deleteExport( | 3219 | pub fn deleteExport( |
| ... | @@ -3237,11 +3237,12 @@ pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: | ... | @@ -3237,11 +3237,12 @@ pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: |
| 3237 | 3237 | ||
| 3238 | pub fn lowerAnonDecl( | 3238 | pub fn lowerAnonDecl( |
| 3239 | self: *MachO, | 3239 | self: *MachO, |
| 3240 | pt: Zcu.PerThread, | ||
| 3240 | decl_val: InternPool.Index, | 3241 | decl_val: InternPool.Index, |
| 3241 | explicit_alignment: InternPool.Alignment, | 3242 | explicit_alignment: InternPool.Alignment, |
| 3242 | src_loc: Module.LazySrcLoc, | 3243 | src_loc: Module.LazySrcLoc, |
| 3243 | ) !codegen.Result { | 3244 | ) !codegen.Result { |
| 3244 | return self.getZigObject().?.lowerAnonDecl(self, decl_val, explicit_alignment, src_loc); | 3245 | return self.getZigObject().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc); |
| 3245 | } | 3246 | } |
| 3246 | 3247 | ||
| 3247 | pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 3248 | pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
src/link/MachO/ZigObject.zig+49-33| ... | @@ -425,16 +425,17 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se | ... | @@ -425,16 +425,17 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se |
| 425 | return sect; | 425 | return sect; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { | 428 | pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void { |
| 429 | // Handle any lazy symbols that were emitted by incremental compilation. | 429 | // Handle any lazy symbols that were emitted by incremental compilation. |
| 430 | if (self.lazy_syms.getPtr(.none)) |metadata| { | 430 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 431 | const zcu = macho_file.base.comp.module.?; | 431 | const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid }; |
| 432 | 432 | ||
| 433 | // Most lazy symbols can be updated on first use, but | 433 | // Most lazy symbols can be updated on first use, but |
| 434 | // anyerror needs to wait for everything to be flushed. | 434 | // anyerror needs to wait for everything to be flushed. |
| 435 | if (metadata.text_state != .unused) self.updateLazySymbol( | 435 | if (metadata.text_state != .unused) self.updateLazySymbol( |
| 436 | macho_file, | 436 | macho_file, |
| 437 | link.File.LazySymbol.initDecl(.code, null, zcu), | 437 | pt, |
| 438 | link.File.LazySymbol.initDecl(.code, null, pt.zcu), | ||
| 438 | metadata.text_symbol_index, | 439 | metadata.text_symbol_index, |
| 439 | ) catch |err| return switch (err) { | 440 | ) catch |err| return switch (err) { |
| 440 | error.CodegenFail => error.FlushFailure, | 441 | error.CodegenFail => error.FlushFailure, |
| ... | @@ -442,7 +443,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -442,7 +443,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { |
| 442 | }; | 443 | }; |
| 443 | if (metadata.const_state != .unused) self.updateLazySymbol( | 444 | if (metadata.const_state != .unused) self.updateLazySymbol( |
| 444 | macho_file, | 445 | macho_file, |
| 445 | link.File.LazySymbol.initDecl(.const_data, null, zcu), | 446 | pt, |
| 447 | link.File.LazySymbol.initDecl(.const_data, null, pt.zcu), | ||
| 446 | metadata.const_symbol_index, | 448 | metadata.const_symbol_index, |
| 447 | ) catch |err| return switch (err) { | 449 | ) catch |err| return switch (err) { |
| 448 | error.CodegenFail => error.FlushFailure, | 450 | error.CodegenFail => error.FlushFailure, |
| ... | @@ -455,8 +457,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -455,8 +457,8 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { |
| 455 | } | 457 | } |
| 456 | 458 | ||
| 457 | if (self.dwarf) |*dw| { | 459 | if (self.dwarf) |*dw| { |
| 458 | const zcu = macho_file.base.comp.module.?; | 460 | const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid }; |
| 459 | try dw.flushModule(zcu); | 461 | try dw.flushModule(pt); |
| 460 | 462 | ||
| 461 | if (self.debug_abbrev_dirty) { | 463 | if (self.debug_abbrev_dirty) { |
| 462 | try dw.writeDbgAbbrev(); | 464 | try dw.writeDbgAbbrev(); |
| ... | @@ -469,7 +471,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -469,7 +471,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { |
| 469 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; | 471 | const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?]; |
| 470 | const low_pc = text_section.addr; | 472 | const low_pc = text_section.addr; |
| 471 | const high_pc = text_section.addr + text_section.size; | 473 | const high_pc = text_section.addr + text_section.size; |
| 472 | try dw.writeDbgInfoHeader(zcu, low_pc, high_pc); | 474 | try dw.writeDbgInfoHeader(pt.zcu, low_pc, high_pc); |
| 473 | self.debug_info_header_dirty = false; | 475 | self.debug_info_header_dirty = false; |
| 474 | } | 476 | } |
| 475 | 477 | ||
| ... | @@ -570,6 +572,7 @@ pub fn getAnonDeclVAddr( | ... | @@ -570,6 +572,7 @@ pub fn getAnonDeclVAddr( |
| 570 | pub fn lowerAnonDecl( | 572 | pub fn lowerAnonDecl( |
| 571 | self: *ZigObject, | 573 | self: *ZigObject, |
| 572 | macho_file: *MachO, | 574 | macho_file: *MachO, |
| 575 | pt: Zcu.PerThread, | ||
| 573 | decl_val: InternPool.Index, | 576 | decl_val: InternPool.Index, |
| 574 | explicit_alignment: Atom.Alignment, | 577 | explicit_alignment: Atom.Alignment, |
| 575 | src_loc: Module.LazySrcLoc, | 578 | src_loc: Module.LazySrcLoc, |
| ... | @@ -578,7 +581,7 @@ pub fn lowerAnonDecl( | ... | @@ -578,7 +581,7 @@ pub fn lowerAnonDecl( |
| 578 | const mod = macho_file.base.comp.module.?; | 581 | const mod = macho_file.base.comp.module.?; |
| 579 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | 582 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 580 | const decl_alignment = switch (explicit_alignment) { | 583 | const decl_alignment = switch (explicit_alignment) { |
| 581 | .none => ty.abiAlignment(mod), | 584 | .none => ty.abiAlignment(pt), |
| 582 | else => explicit_alignment, | 585 | else => explicit_alignment, |
| 583 | }; | 586 | }; |
| 584 | if (self.anon_decls.get(decl_val)) |metadata| { | 587 | if (self.anon_decls.get(decl_val)) |metadata| { |
| ... | @@ -593,6 +596,7 @@ pub fn lowerAnonDecl( | ... | @@ -593,6 +596,7 @@ pub fn lowerAnonDecl( |
| 593 | }) catch unreachable; | 596 | }) catch unreachable; |
| 594 | const res = self.lowerConst( | 597 | const res = self.lowerConst( |
| 595 | macho_file, | 598 | macho_file, |
| 599 | pt, | ||
| 596 | name, | 600 | name, |
| 597 | Value.fromInterned(decl_val), | 601 | Value.fromInterned(decl_val), |
| 598 | decl_alignment, | 602 | decl_alignment, |
| ... | @@ -656,7 +660,7 @@ pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.Dec | ... | @@ -656,7 +660,7 @@ pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.Dec |
| 656 | pub fn updateFunc( | 660 | pub fn updateFunc( |
| 657 | self: *ZigObject, | 661 | self: *ZigObject, |
| 658 | macho_file: *MachO, | 662 | macho_file: *MachO, |
| 659 | mod: *Module, | 663 | pt: Zcu.PerThread, |
| 660 | func_index: InternPool.Index, | 664 | func_index: InternPool.Index, |
| 661 | air: Air, | 665 | air: Air, |
| 662 | liveness: Liveness, | 666 | liveness: Liveness, |
| ... | @@ -664,7 +668,8 @@ pub fn updateFunc( | ... | @@ -664,7 +668,8 @@ pub fn updateFunc( |
| 664 | const tracy = trace(@src()); | 668 | const tracy = trace(@src()); |
| 665 | defer tracy.end(); | 669 | defer tracy.end(); |
| 666 | 670 | ||
| 667 | const gpa = macho_file.base.comp.gpa; | 671 | const mod = pt.zcu; |
| 672 | const gpa = mod.gpa; | ||
| 668 | const func = mod.funcInfo(func_index); | 673 | const func = mod.funcInfo(func_index); |
| 669 | const decl_index = func.owner_decl; | 674 | const decl_index = func.owner_decl; |
| 670 | const decl = mod.declPtr(decl_index); | 675 | const decl = mod.declPtr(decl_index); |
| ... | @@ -676,12 +681,13 @@ pub fn updateFunc( | ... | @@ -676,12 +681,13 @@ pub fn updateFunc( |
| 676 | var code_buffer = std.ArrayList(u8).init(gpa); | 681 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 677 | defer code_buffer.deinit(); | 682 | defer code_buffer.deinit(); |
| 678 | 683 | ||
| 679 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; | 684 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null; |
| 680 | defer if (decl_state) |*ds| ds.deinit(); | 685 | defer if (decl_state) |*ds| ds.deinit(); |
| 681 | 686 | ||
| 682 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; | 687 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| 683 | const res = try codegen.generateFunction( | 688 | const res = try codegen.generateFunction( |
| 684 | &macho_file.base, | 689 | &macho_file.base, |
| 690 | pt, | ||
| 685 | decl.navSrcLoc(mod), | 691 | decl.navSrcLoc(mod), |
| 686 | func_index, | 692 | func_index, |
| 687 | air, | 693 | air, |
| ... | @@ -700,12 +706,12 @@ pub fn updateFunc( | ... | @@ -700,12 +706,12 @@ pub fn updateFunc( |
| 700 | }; | 706 | }; |
| 701 | 707 | ||
| 702 | const sect_index = try self.getDeclOutputSection(macho_file, decl, code); | 708 | const sect_index = try self.getDeclOutputSection(macho_file, decl, code); |
| 703 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); | 709 | try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code); |
| 704 | 710 | ||
| 705 | if (decl_state) |*ds| { | 711 | if (decl_state) |*ds| { |
| 706 | const sym = macho_file.getSymbol(sym_index); | 712 | const sym = macho_file.getSymbol(sym_index); |
| 707 | try self.dwarf.?.commitDeclState( | 713 | try self.dwarf.?.commitDeclState( |
| 708 | mod, | 714 | pt, |
| 709 | decl_index, | 715 | decl_index, |
| 710 | sym.getAddress(.{}, macho_file), | 716 | sym.getAddress(.{}, macho_file), |
| 711 | sym.getAtom(macho_file).?.size, | 717 | sym.getAtom(macho_file).?.size, |
| ... | @@ -719,12 +725,13 @@ pub fn updateFunc( | ... | @@ -719,12 +725,13 @@ pub fn updateFunc( |
| 719 | pub fn updateDecl( | 725 | pub fn updateDecl( |
| 720 | self: *ZigObject, | 726 | self: *ZigObject, |
| 721 | macho_file: *MachO, | 727 | macho_file: *MachO, |
| 722 | mod: *Module, | 728 | pt: Zcu.PerThread, |
| 723 | decl_index: InternPool.DeclIndex, | 729 | decl_index: InternPool.DeclIndex, |
| 724 | ) link.File.UpdateDeclError!void { | 730 | ) link.File.UpdateDeclError!void { |
| 725 | const tracy = trace(@src()); | 731 | const tracy = trace(@src()); |
| 726 | defer tracy.end(); | 732 | defer tracy.end(); |
| 727 | 733 | ||
| 734 | const mod = pt.zcu; | ||
| 728 | const decl = mod.declPtr(decl_index); | 735 | const decl = mod.declPtr(decl_index); |
| 729 | 736 | ||
| 730 | if (decl.val.getExternFunc(mod)) |_| { | 737 | if (decl.val.getExternFunc(mod)) |_| { |
| ... | @@ -749,12 +756,12 @@ pub fn updateDecl( | ... | @@ -749,12 +756,12 @@ pub fn updateDecl( |
| 749 | var code_buffer = std.ArrayList(u8).init(gpa); | 756 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 750 | defer code_buffer.deinit(); | 757 | defer code_buffer.deinit(); |
| 751 | 758 | ||
| 752 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; | 759 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null; |
| 753 | defer if (decl_state) |*ds| ds.deinit(); | 760 | defer if (decl_state) |*ds| ds.deinit(); |
| 754 | 761 | ||
| 755 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 762 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 756 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; | 763 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| 757 | const res = try codegen.generateSymbol(&macho_file.base, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{ | 764 | const res = try codegen.generateSymbol(&macho_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{ |
| 758 | .parent_atom_index = sym_index, | 765 | .parent_atom_index = sym_index, |
| 759 | }); | 766 | }); |
| 760 | 767 | ||
| ... | @@ -772,15 +779,15 @@ pub fn updateDecl( | ... | @@ -772,15 +779,15 @@ pub fn updateDecl( |
| 772 | else => false, | 779 | else => false, |
| 773 | }; | 780 | }; |
| 774 | if (is_threadlocal) { | 781 | if (is_threadlocal) { |
| 775 | try self.updateTlv(macho_file, decl_index, sym_index, sect_index, code); | 782 | try self.updateTlv(macho_file, pt, decl_index, sym_index, sect_index, code); |
| 776 | } else { | 783 | } else { |
| 777 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); | 784 | try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code); |
| 778 | } | 785 | } |
| 779 | 786 | ||
| 780 | if (decl_state) |*ds| { | 787 | if (decl_state) |*ds| { |
| 781 | const sym = macho_file.getSymbol(sym_index); | 788 | const sym = macho_file.getSymbol(sym_index); |
| 782 | try self.dwarf.?.commitDeclState( | 789 | try self.dwarf.?.commitDeclState( |
| 783 | mod, | 790 | pt, |
| 784 | decl_index, | 791 | decl_index, |
| 785 | sym.getAddress(.{}, macho_file), | 792 | sym.getAddress(.{}, macho_file), |
| 786 | sym.getAtom(macho_file).?.size, | 793 | sym.getAtom(macho_file).?.size, |
| ... | @@ -794,19 +801,20 @@ pub fn updateDecl( | ... | @@ -794,19 +801,20 @@ pub fn updateDecl( |
| 794 | fn updateDeclCode( | 801 | fn updateDeclCode( |
| 795 | self: *ZigObject, | 802 | self: *ZigObject, |
| 796 | macho_file: *MachO, | 803 | macho_file: *MachO, |
| 804 | pt: Zcu.PerThread, | ||
| 797 | decl_index: InternPool.DeclIndex, | 805 | decl_index: InternPool.DeclIndex, |
| 798 | sym_index: Symbol.Index, | 806 | sym_index: Symbol.Index, |
| 799 | sect_index: u8, | 807 | sect_index: u8, |
| 800 | code: []const u8, | 808 | code: []const u8, |
| 801 | ) !void { | 809 | ) !void { |
| 802 | const gpa = macho_file.base.comp.gpa; | 810 | const gpa = macho_file.base.comp.gpa; |
| 803 | const mod = macho_file.base.comp.module.?; | 811 | const mod = pt.zcu; |
| 804 | const decl = mod.declPtr(decl_index); | 812 | const decl = mod.declPtr(decl_index); |
| 805 | const decl_name = try decl.fullyQualifiedName(mod); | 813 | const decl_name = try decl.fullyQualifiedName(mod); |
| 806 | 814 | ||
| 807 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | 815 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); |
| 808 | 816 | ||
| 809 | const required_alignment = decl.getAlignment(mod); | 817 | const required_alignment = decl.getAlignment(pt); |
| 810 | 818 | ||
| 811 | const sect = &macho_file.sections.items(.header)[sect_index]; | 819 | const sect = &macho_file.sections.items(.header)[sect_index]; |
| 812 | const sym = macho_file.getSymbol(sym_index); | 820 | const sym = macho_file.getSymbol(sym_index); |
| ... | @@ -879,19 +887,20 @@ fn updateDeclCode( | ... | @@ -879,19 +887,20 @@ fn updateDeclCode( |
| 879 | fn updateTlv( | 887 | fn updateTlv( |
| 880 | self: *ZigObject, | 888 | self: *ZigObject, |
| 881 | macho_file: *MachO, | 889 | macho_file: *MachO, |
| 890 | pt: Zcu.PerThread, | ||
| 882 | decl_index: InternPool.DeclIndex, | 891 | decl_index: InternPool.DeclIndex, |
| 883 | sym_index: Symbol.Index, | 892 | sym_index: Symbol.Index, |
| 884 | sect_index: u8, | 893 | sect_index: u8, |
| 885 | code: []const u8, | 894 | code: []const u8, |
| 886 | ) !void { | 895 | ) !void { |
| 887 | const mod = macho_file.base.comp.module.?; | 896 | const mod = pt.zcu; |
| 888 | const decl = mod.declPtr(decl_index); | 897 | const decl = mod.declPtr(decl_index); |
| 889 | const decl_name = try decl.fullyQualifiedName(mod); | 898 | const decl_name = try decl.fullyQualifiedName(mod); |
| 890 | 899 | ||
| 891 | log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl }); | 900 | log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl }); |
| 892 | 901 | ||
| 893 | const decl_name_slice = decl_name.toSlice(&mod.intern_pool); | 902 | const decl_name_slice = decl_name.toSlice(&mod.intern_pool); |
| 894 | const required_alignment = decl.getAlignment(mod); | 903 | const required_alignment = decl.getAlignment(pt); |
| 895 | 904 | ||
| 896 | // 1. Lower TLV initializer | 905 | // 1. Lower TLV initializer |
| 897 | const init_sym_index = try self.createTlvInitializer( | 906 | const init_sym_index = try self.createTlvInitializer( |
| ... | @@ -1079,11 +1088,12 @@ fn getDeclOutputSection( | ... | @@ -1079,11 +1088,12 @@ fn getDeclOutputSection( |
| 1079 | pub fn lowerUnnamedConst( | 1088 | pub fn lowerUnnamedConst( |
| 1080 | self: *ZigObject, | 1089 | self: *ZigObject, |
| 1081 | macho_file: *MachO, | 1090 | macho_file: *MachO, |
| 1091 | pt: Zcu.PerThread, | ||
| 1082 | val: Value, | 1092 | val: Value, |
| 1083 | decl_index: InternPool.DeclIndex, | 1093 | decl_index: InternPool.DeclIndex, |
| 1084 | ) !u32 { | 1094 | ) !u32 { |
| 1085 | const gpa = macho_file.base.comp.gpa; | 1095 | const mod = pt.zcu; |
| 1086 | const mod = macho_file.base.comp.module.?; | 1096 | const gpa = mod.gpa; |
| 1087 | const gop = try self.unnamed_consts.getOrPut(gpa, decl_index); | 1097 | const gop = try self.unnamed_consts.getOrPut(gpa, decl_index); |
| 1088 | if (!gop.found_existing) { | 1098 | if (!gop.found_existing) { |
| 1089 | gop.value_ptr.* = .{}; | 1099 | gop.value_ptr.* = .{}; |
| ... | @@ -1096,9 +1106,10 @@ pub fn lowerUnnamedConst( | ... | @@ -1096,9 +1106,10 @@ pub fn lowerUnnamedConst( |
| 1096 | defer gpa.free(name); | 1106 | defer gpa.free(name); |
| 1097 | const sym_index = switch (try self.lowerConst( | 1107 | const sym_index = switch (try self.lowerConst( |
| 1098 | macho_file, | 1108 | macho_file, |
| 1109 | pt, | ||
| 1099 | name, | 1110 | name, |
| 1100 | val, | 1111 | val, |
| 1101 | val.typeOf(mod).abiAlignment(mod), | 1112 | val.typeOf(mod).abiAlignment(pt), |
| 1102 | macho_file.zig_const_sect_index.?, | 1113 | macho_file.zig_const_sect_index.?, |
| 1103 | decl.navSrcLoc(mod), | 1114 | decl.navSrcLoc(mod), |
| 1104 | )) { | 1115 | )) { |
| ... | @@ -1123,6 +1134,7 @@ const LowerConstResult = union(enum) { | ... | @@ -1123,6 +1134,7 @@ const LowerConstResult = union(enum) { |
| 1123 | fn lowerConst( | 1134 | fn lowerConst( |
| 1124 | self: *ZigObject, | 1135 | self: *ZigObject, |
| 1125 | macho_file: *MachO, | 1136 | macho_file: *MachO, |
| 1137 | pt: Zcu.PerThread, | ||
| 1126 | name: []const u8, | 1138 | name: []const u8, |
| 1127 | val: Value, | 1139 | val: Value, |
| 1128 | required_alignment: Atom.Alignment, | 1140 | required_alignment: Atom.Alignment, |
| ... | @@ -1136,7 +1148,7 @@ fn lowerConst( | ... | @@ -1136,7 +1148,7 @@ fn lowerConst( |
| 1136 | 1148 | ||
| 1137 | const sym_index = try self.addAtom(macho_file); | 1149 | const sym_index = try self.addAtom(macho_file); |
| 1138 | 1150 | ||
| 1139 | const res = try codegen.generateSymbol(&macho_file.base, src_loc, val, &code_buffer, .{ | 1151 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1140 | .none = {}, | 1152 | .none = {}, |
| 1141 | }, .{ | 1153 | }, .{ |
| 1142 | .parent_atom_index = sym_index, | 1154 | .parent_atom_index = sym_index, |
| ... | @@ -1181,13 +1193,14 @@ fn lowerConst( | ... | @@ -1181,13 +1193,14 @@ fn lowerConst( |
| 1181 | pub fn updateExports( | 1193 | pub fn updateExports( |
| 1182 | self: *ZigObject, | 1194 | self: *ZigObject, |
| 1183 | macho_file: *MachO, | 1195 | macho_file: *MachO, |
| 1184 | mod: *Module, | 1196 | pt: Zcu.PerThread, |
| 1185 | exported: Module.Exported, | 1197 | exported: Module.Exported, |
| 1186 | export_indices: []const u32, | 1198 | export_indices: []const u32, |
| 1187 | ) link.File.UpdateExportsError!void { | 1199 | ) link.File.UpdateExportsError!void { |
| 1188 | const tracy = trace(@src()); | 1200 | const tracy = trace(@src()); |
| 1189 | defer tracy.end(); | 1201 | defer tracy.end(); |
| 1190 | 1202 | ||
| 1203 | const mod = pt.zcu; | ||
| 1191 | const gpa = macho_file.base.comp.gpa; | 1204 | const gpa = macho_file.base.comp.gpa; |
| 1192 | const metadata = switch (exported) { | 1205 | const metadata = switch (exported) { |
| 1193 | .decl_index => |decl_index| blk: { | 1206 | .decl_index => |decl_index| blk: { |
| ... | @@ -1196,7 +1209,7 @@ pub fn updateExports( | ... | @@ -1196,7 +1209,7 @@ pub fn updateExports( |
| 1196 | }, | 1209 | }, |
| 1197 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { | 1210 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { |
| 1198 | const first_exp = mod.all_exports.items[export_indices[0]]; | 1211 | const first_exp = mod.all_exports.items[export_indices[0]]; |
| 1199 | const res = try self.lowerAnonDecl(macho_file, value, .none, first_exp.src); | 1212 | const res = try self.lowerAnonDecl(macho_file, pt, value, .none, first_exp.src); |
| 1200 | switch (res) { | 1213 | switch (res) { |
| 1201 | .ok => {}, | 1214 | .ok => {}, |
| 1202 | .fail => |em| { | 1215 | .fail => |em| { |
| ... | @@ -1272,6 +1285,7 @@ pub fn updateExports( | ... | @@ -1272,6 +1285,7 @@ pub fn updateExports( |
| 1272 | fn updateLazySymbol( | 1285 | fn updateLazySymbol( |
| 1273 | self: *ZigObject, | 1286 | self: *ZigObject, |
| 1274 | macho_file: *MachO, | 1287 | macho_file: *MachO, |
| 1288 | pt: Zcu.PerThread, | ||
| 1275 | lazy_sym: link.File.LazySymbol, | 1289 | lazy_sym: link.File.LazySymbol, |
| 1276 | symbol_index: Symbol.Index, | 1290 | symbol_index: Symbol.Index, |
| 1277 | ) !void { | 1291 | ) !void { |
| ... | @@ -1285,7 +1299,7 @@ fn updateLazySymbol( | ... | @@ -1285,7 +1299,7 @@ fn updateLazySymbol( |
| 1285 | const name_str_index = blk: { | 1299 | const name_str_index = blk: { |
| 1286 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ | 1300 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ |
| 1287 | @tagName(lazy_sym.kind), | 1301 | @tagName(lazy_sym.kind), |
| 1288 | lazy_sym.ty.fmt(mod), | 1302 | lazy_sym.ty.fmt(pt), |
| 1289 | }); | 1303 | }); |
| 1290 | defer gpa.free(name); | 1304 | defer gpa.free(name); |
| 1291 | break :blk try self.strtab.insert(gpa, name); | 1305 | break :blk try self.strtab.insert(gpa, name); |
| ... | @@ -1294,6 +1308,7 @@ fn updateLazySymbol( | ... | @@ -1294,6 +1308,7 @@ fn updateLazySymbol( |
| 1294 | const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; | 1308 | const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; |
| 1295 | const res = try codegen.generateLazySymbol( | 1309 | const res = try codegen.generateLazySymbol( |
| 1296 | &macho_file.base, | 1310 | &macho_file.base, |
| 1311 | pt, | ||
| 1297 | src, | 1312 | src, |
| 1298 | lazy_sym, | 1313 | lazy_sym, |
| 1299 | &required_alignment, | 1314 | &required_alignment, |
| ... | @@ -1431,10 +1446,11 @@ pub fn getOrCreateMetadataForDecl( | ... | @@ -1431,10 +1446,11 @@ pub fn getOrCreateMetadataForDecl( |
| 1431 | pub fn getOrCreateMetadataForLazySymbol( | 1446 | pub fn getOrCreateMetadataForLazySymbol( |
| 1432 | self: *ZigObject, | 1447 | self: *ZigObject, |
| 1433 | macho_file: *MachO, | 1448 | macho_file: *MachO, |
| 1449 | pt: Zcu.PerThread, | ||
| 1434 | lazy_sym: link.File.LazySymbol, | 1450 | lazy_sym: link.File.LazySymbol, |
| 1435 | ) !Symbol.Index { | 1451 | ) !Symbol.Index { |
| 1436 | const gpa = macho_file.base.comp.gpa; | 1452 | const mod = pt.zcu; |
| 1437 | const mod = macho_file.base.comp.module.?; | 1453 | const gpa = mod.gpa; |
| 1438 | const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod)); | 1454 | const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod)); |
| 1439 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); | 1455 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 1440 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 1456 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| ... | @@ -1464,7 +1480,7 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -1464,7 +1480,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1464 | metadata.state.* = .pending_flush; | 1480 | metadata.state.* = .pending_flush; |
| 1465 | const symbol_index = metadata.symbol_index.*; | 1481 | const symbol_index = metadata.symbol_index.*; |
| 1466 | // anyerror needs to be deferred until flushModule | 1482 | // anyerror needs to be deferred until flushModule |
| 1467 | if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, lazy_sym, symbol_index); | 1483 | if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index); |
| 1468 | return symbol_index; | 1484 | return symbol_index; |
| 1469 | } | 1485 | } |
| 1470 | 1486 |
src/link/NvPtx.zig+11-12| ... | @@ -13,8 +13,6 @@ const assert = std.debug.assert; | ... | @@ -13,8 +13,6 @@ const assert = std.debug.assert; |
| 13 | const log = std.log.scoped(.link); | 13 | const log = std.log.scoped(.link); |
| 14 | 14 | ||
| 15 | const Zcu = @import("../Zcu.zig"); | 15 | const Zcu = @import("../Zcu.zig"); |
| 16 | /// Deprecated. | ||
| 17 | const Module = Zcu; | ||
| 18 | const InternPool = @import("../InternPool.zig"); | 16 | const InternPool = @import("../InternPool.zig"); |
| 19 | const Compilation = @import("../Compilation.zig"); | 17 | const Compilation = @import("../Compilation.zig"); |
| 20 | const link = @import("../link.zig"); | 18 | const link = @import("../link.zig"); |
| ... | @@ -84,35 +82,35 @@ pub fn deinit(self: *NvPtx) void { | ... | @@ -84,35 +82,35 @@ pub fn deinit(self: *NvPtx) void { |
| 84 | self.llvm_object.deinit(); | 82 | self.llvm_object.deinit(); |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | pub fn updateFunc(self: *NvPtx, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 85 | pub fn updateFunc(self: *NvPtx, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 88 | try self.llvm_object.updateFunc(module, func_index, air, liveness); | 86 | try self.llvm_object.updateFunc(pt, func_index, air, liveness); |
| 89 | } | 87 | } |
| 90 | 88 | ||
| 91 | pub fn updateDecl(self: *NvPtx, module: *Module, decl_index: InternPool.DeclIndex) !void { | 89 | pub fn updateDecl(self: *NvPtx, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 92 | return self.llvm_object.updateDecl(module, decl_index); | 90 | return self.llvm_object.updateDecl(pt, decl_index); |
| 93 | } | 91 | } |
| 94 | 92 | ||
| 95 | pub fn updateExports( | 93 | pub fn updateExports( |
| 96 | self: *NvPtx, | 94 | self: *NvPtx, |
| 97 | module: *Module, | 95 | pt: Zcu.PerThread, |
| 98 | exported: Module.Exported, | 96 | exported: Zcu.Exported, |
| 99 | export_indices: []const u32, | 97 | export_indices: []const u32, |
| 100 | ) !void { | 98 | ) !void { |
| 101 | if (build_options.skip_non_native and builtin.object_format != .nvptx) | 99 | if (build_options.skip_non_native and builtin.object_format != .nvptx) |
| 102 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 100 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 103 | 101 | ||
| 104 | return self.llvm_object.updateExports(module, exported, export_indices); | 102 | return self.llvm_object.updateExports(pt, exported, export_indices); |
| 105 | } | 103 | } |
| 106 | 104 | ||
| 107 | pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void { | 105 | pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void { |
| 108 | return self.llvm_object.freeDecl(decl_index); | 106 | return self.llvm_object.freeDecl(decl_index); |
| 109 | } | 107 | } |
| 110 | 108 | ||
| 111 | pub fn flush(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 109 | pub fn flush(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 112 | return self.flushModule(arena, prog_node); | 110 | return self.flushModule(arena, tid, prog_node); |
| 113 | } | 111 | } |
| 114 | 112 | ||
| 115 | pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 113 | pub fn flushModule(self: *NvPtx, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 116 | if (build_options.skip_non_native) | 114 | if (build_options.skip_non_native) |
| 117 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 115 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 118 | 116 | ||
| ... | @@ -121,5 +119,6 @@ pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -121,5 +119,6 @@ pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) |
| 121 | _ = arena; | 119 | _ = arena; |
| 122 | _ = self; | 120 | _ = self; |
| 123 | _ = prog_node; | 121 | _ = prog_node; |
| 122 | _ = tid; | ||
| 124 | @panic("TODO: rewrite the NvPtx.flushModule function"); | 123 | @panic("TODO: rewrite the NvPtx.flushModule function"); |
| 125 | } | 124 | } |
src/link/Plan9.zig+47-40| ... | @@ -4,8 +4,6 @@ | ... | @@ -4,8 +4,6 @@ |
| 4 | const Plan9 = @This(); | 4 | const Plan9 = @This(); |
| 5 | const link = @import("../link.zig"); | 5 | const link = @import("../link.zig"); |
| 6 | const Zcu = @import("../Zcu.zig"); | 6 | const Zcu = @import("../Zcu.zig"); |
| 7 | /// Deprecated. | ||
| 8 | const Module = Zcu; | ||
| 9 | const InternPool = @import("../InternPool.zig"); | 7 | const InternPool = @import("../InternPool.zig"); |
| 10 | const Compilation = @import("../Compilation.zig"); | 8 | const Compilation = @import("../Compilation.zig"); |
| 11 | const aout = @import("Plan9/aout.zig"); | 9 | const aout = @import("Plan9/aout.zig"); |
| ... | @@ -56,7 +54,7 @@ path_arena: std.heap.ArenaAllocator, | ... | @@ -56,7 +54,7 @@ path_arena: std.heap.ArenaAllocator, |
| 56 | /// of the function to know what file it came from. | 54 | /// of the function to know what file it came from. |
| 57 | /// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place) | 55 | /// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place) |
| 58 | fn_decl_table: std.AutoArrayHashMapUnmanaged( | 56 | fn_decl_table: std.AutoArrayHashMapUnmanaged( |
| 59 | *Module.File, | 57 | *Zcu.File, |
| 60 | struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} }, | 58 | struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} }, |
| 61 | ) = .{}, | 59 | ) = .{}, |
| 62 | /// the code is modified when relocated, so that is why it is mutable | 60 | /// the code is modified when relocated, so that is why it is mutable |
| ... | @@ -411,12 +409,13 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi | ... | @@ -411,12 +409,13 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi |
| 411 | } | 409 | } |
| 412 | } | 410 | } |
| 413 | 411 | ||
| 414 | pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 412 | pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 415 | if (build_options.skip_non_native and builtin.object_format != .plan9) { | 413 | if (build_options.skip_non_native and builtin.object_format != .plan9) { |
| 416 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 414 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 417 | } | 415 | } |
| 418 | 416 | ||
| 419 | const gpa = self.base.comp.gpa; | 417 | const mod = pt.zcu; |
| 418 | const gpa = mod.gpa; | ||
| 420 | const target = self.base.comp.root_mod.resolved_target.result; | 419 | const target = self.base.comp.root_mod.resolved_target.result; |
| 421 | const func = mod.funcInfo(func_index); | 420 | const func = mod.funcInfo(func_index); |
| 422 | const decl_index = func.owner_decl; | 421 | const decl_index = func.owner_decl; |
| ... | @@ -439,6 +438,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -439,6 +438,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 439 | 438 | ||
| 440 | const res = try codegen.generateFunction( | 439 | const res = try codegen.generateFunction( |
| 441 | &self.base, | 440 | &self.base, |
| 441 | pt, | ||
| 442 | decl.navSrcLoc(mod), | 442 | decl.navSrcLoc(mod), |
| 443 | func_index, | 443 | func_index, |
| 444 | air, | 444 | air, |
| ... | @@ -468,13 +468,13 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -468,13 +468,13 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 468 | return self.updateFinish(decl_index); | 468 | return self.updateFinish(decl_index); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 471 | pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 472 | const gpa = self.base.comp.gpa; | 472 | const mod = pt.zcu; |
| 473 | const gpa = mod.gpa; | ||
| 473 | _ = try self.seeDecl(decl_index); | 474 | _ = try self.seeDecl(decl_index); |
| 474 | var code_buffer = std.ArrayList(u8).init(gpa); | 475 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 475 | defer code_buffer.deinit(); | 476 | defer code_buffer.deinit(); |
| 476 | 477 | ||
| 477 | const mod = self.base.comp.module.?; | ||
| 478 | const decl = mod.declPtr(decl_index); | 478 | const decl = mod.declPtr(decl_index); |
| 479 | 479 | ||
| 480 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); | 480 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); |
| ... | @@ -505,7 +505,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn | ... | @@ -505,7 +505,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn |
| 505 | }; | 505 | }; |
| 506 | self.syms.items[info.sym_index.?] = sym; | 506 | self.syms.items[info.sym_index.?] = sym; |
| 507 | 507 | ||
| 508 | const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), val, &code_buffer, .{ | 508 | const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), val, &code_buffer, .{ |
| 509 | .none = {}, | 509 | .none = {}, |
| 510 | }, .{ | 510 | }, .{ |
| 511 | .parent_atom_index = new_atom_idx, | 511 | .parent_atom_index = new_atom_idx, |
| ... | @@ -530,8 +530,9 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn | ... | @@ -530,8 +530,9 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn |
| 530 | return new_atom_idx; | 530 | return new_atom_idx; |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 533 | pub fn updateDecl(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 534 | const gpa = self.base.comp.gpa; | 534 | const gpa = self.base.comp.gpa; |
| 535 | const mod = pt.zcu; | ||
| 535 | const decl = mod.declPtr(decl_index); | 536 | const decl = mod.declPtr(decl_index); |
| 536 | 537 | ||
| 537 | if (decl.isExtern(mod)) { | 538 | if (decl.isExtern(mod)) { |
| ... | @@ -544,7 +545,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) | ... | @@ -544,7 +545,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) |
| 544 | defer code_buffer.deinit(); | 545 | defer code_buffer.deinit(); |
| 545 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 546 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 546 | // TODO we need the symbol index for symbol in the table of locals for the containing atom | 547 | // TODO we need the symbol index for symbol in the table of locals for the containing atom |
| 547 | const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{ | 548 | const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{ |
| 548 | .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)), | 549 | .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)), |
| 549 | }); | 550 | }); |
| 550 | const code = switch (res) { | 551 | const code = switch (res) { |
| ... | @@ -610,7 +611,7 @@ fn allocateGotIndex(self: *Plan9) usize { | ... | @@ -610,7 +611,7 @@ fn allocateGotIndex(self: *Plan9) usize { |
| 610 | } | 611 | } |
| 611 | } | 612 | } |
| 612 | 613 | ||
| 613 | pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 614 | pub fn flush(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 614 | const comp = self.base.comp; | 615 | const comp = self.base.comp; |
| 615 | const use_lld = build_options.have_llvm and comp.config.use_lld; | 616 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 616 | assert(!use_lld); | 617 | assert(!use_lld); |
| ... | @@ -621,7 +622,7 @@ pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link. | ... | @@ -621,7 +622,7 @@ pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link. |
| 621 | .Obj => return error.TODOImplementPlan9Objs, | 622 | .Obj => return error.TODOImplementPlan9Objs, |
| 622 | .Lib => return error.TODOImplementWritingLibFiles, | 623 | .Lib => return error.TODOImplementWritingLibFiles, |
| 623 | } | 624 | } |
| 624 | return self.flushModule(arena, prog_node); | 625 | return self.flushModule(arena, tid, prog_node); |
| 625 | } | 626 | } |
| 626 | 627 | ||
| 627 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { | 628 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| ... | @@ -669,20 +670,20 @@ fn atomCount(self: *Plan9) usize { | ... | @@ -669,20 +670,20 @@ fn atomCount(self: *Plan9) usize { |
| 669 | return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count; | 670 | return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count; |
| 670 | } | 671 | } |
| 671 | 672 | ||
| 672 | pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 673 | pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 673 | if (build_options.skip_non_native and builtin.object_format != .plan9) { | 674 | if (build_options.skip_non_native and builtin.object_format != .plan9) { |
| 674 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 675 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 675 | } | 676 | } |
| 676 | 677 | ||
| 678 | const tracy = trace(@src()); | ||
| 679 | defer tracy.end(); | ||
| 680 | |||
| 677 | _ = arena; // Has the same lifetime as the call to Compilation.update. | 681 | _ = arena; // Has the same lifetime as the call to Compilation.update. |
| 678 | 682 | ||
| 679 | const comp = self.base.comp; | 683 | const comp = self.base.comp; |
| 680 | const gpa = comp.gpa; | 684 | const gpa = comp.gpa; |
| 681 | const target = comp.root_mod.resolved_target.result; | 685 | const target = comp.root_mod.resolved_target.result; |
| 682 | 686 | ||
| 683 | const tracy = trace(@src()); | ||
| 684 | defer tracy.end(); | ||
| 685 | |||
| 686 | const sub_prog_node = prog_node.start("Flush Module", 0); | 687 | const sub_prog_node = prog_node.start("Flush Module", 0); |
| 687 | defer sub_prog_node.end(); | 688 | defer sub_prog_node.end(); |
| 688 | 689 | ||
| ... | @@ -690,21 +691,26 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -690,21 +691,26 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 690 | 691 | ||
| 691 | defer assert(self.hdr.entry != 0x0); | 692 | defer assert(self.hdr.entry != 0x0); |
| 692 | 693 | ||
| 693 | const mod = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 694 | const pt: Zcu.PerThread = .{ |
| 695 | .zcu = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented, | ||
| 696 | .tid = tid, | ||
| 697 | }; | ||
| 694 | 698 | ||
| 695 | // finish up the lazy syms | 699 | // finish up the lazy syms |
| 696 | if (self.lazy_syms.getPtr(.none)) |metadata| { | 700 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 697 | // Most lazy symbols can be updated on first use, but | 701 | // Most lazy symbols can be updated on first use, but |
| 698 | // anyerror needs to wait for everything to be flushed. | 702 | // anyerror needs to wait for everything to be flushed. |
| 699 | if (metadata.text_state != .unused) self.updateLazySymbolAtom( | 703 | if (metadata.text_state != .unused) self.updateLazySymbolAtom( |
| 700 | File.LazySymbol.initDecl(.code, null, mod), | 704 | pt, |
| 705 | File.LazySymbol.initDecl(.code, null, pt.zcu), | ||
| 701 | metadata.text_atom, | 706 | metadata.text_atom, |
| 702 | ) catch |err| return switch (err) { | 707 | ) catch |err| return switch (err) { |
| 703 | error.CodegenFail => error.FlushFailure, | 708 | error.CodegenFail => error.FlushFailure, |
| 704 | else => |e| e, | 709 | else => |e| e, |
| 705 | }; | 710 | }; |
| 706 | if (metadata.rodata_state != .unused) self.updateLazySymbolAtom( | 711 | if (metadata.rodata_state != .unused) self.updateLazySymbolAtom( |
| 707 | File.LazySymbol.initDecl(.const_data, null, mod), | 712 | pt, |
| 713 | File.LazySymbol.initDecl(.const_data, null, pt.zcu), | ||
| 708 | metadata.rodata_atom, | 714 | metadata.rodata_atom, |
| 709 | ) catch |err| return switch (err) { | 715 | ) catch |err| return switch (err) { |
| 710 | error.CodegenFail => error.FlushFailure, | 716 | error.CodegenFail => error.FlushFailure, |
| ... | @@ -747,7 +753,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -747,7 +753,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 747 | var it = fentry.value_ptr.functions.iterator(); | 753 | var it = fentry.value_ptr.functions.iterator(); |
| 748 | while (it.next()) |entry| { | 754 | while (it.next()) |entry| { |
| 749 | const decl_index = entry.key_ptr.*; | 755 | const decl_index = entry.key_ptr.*; |
| 750 | const decl = mod.declPtr(decl_index); | 756 | const decl = pt.zcu.declPtr(decl_index); |
| 751 | const atom = self.getAtomPtr(self.decls.get(decl_index).?.index); | 757 | const atom = self.getAtomPtr(self.decls.get(decl_index).?.index); |
| 752 | const out = entry.value_ptr.*; | 758 | const out = entry.value_ptr.*; |
| 753 | { | 759 | { |
| ... | @@ -767,7 +773,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -767,7 +773,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 767 | const off = self.getAddr(text_i, .t); | 773 | const off = self.getAddr(text_i, .t); |
| 768 | text_i += out.code.len; | 774 | text_i += out.code.len; |
| 769 | atom.offset = off; | 775 | atom.offset = off; |
| 770 | log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off }); | 776 | log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off }); |
| 771 | if (!self.sixtyfour_bit) { | 777 | if (!self.sixtyfour_bit) { |
| 772 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | 778 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); |
| 773 | } else { | 779 | } else { |
| ... | @@ -775,7 +781,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -775,7 +781,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 775 | } | 781 | } |
| 776 | self.syms.items[atom.sym_index.?].value = off; | 782 | self.syms.items[atom.sym_index.?].value = off; |
| 777 | if (self.decl_exports.get(decl_index)) |export_indices| { | 783 | if (self.decl_exports.get(decl_index)) |export_indices| { |
| 778 | try self.addDeclExports(mod, decl_index, export_indices); | 784 | try self.addDeclExports(pt.zcu, decl_index, export_indices); |
| 779 | } | 785 | } |
| 780 | } | 786 | } |
| 781 | } | 787 | } |
| ... | @@ -841,7 +847,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -841,7 +847,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 841 | } | 847 | } |
| 842 | self.syms.items[atom.sym_index.?].value = off; | 848 | self.syms.items[atom.sym_index.?].value = off; |
| 843 | if (self.decl_exports.get(decl_index)) |export_indices| { | 849 | if (self.decl_exports.get(decl_index)) |export_indices| { |
| 844 | try self.addDeclExports(mod, decl_index, export_indices); | 850 | try self.addDeclExports(pt.zcu, decl_index, export_indices); |
| 845 | } | 851 | } |
| 846 | } | 852 | } |
| 847 | // write the unnamed constants after the other data decls | 853 | // write the unnamed constants after the other data decls |
| ... | @@ -1009,7 +1015,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -1009,7 +1015,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) |
| 1009 | } | 1015 | } |
| 1010 | fn addDeclExports( | 1016 | fn addDeclExports( |
| 1011 | self: *Plan9, | 1017 | self: *Plan9, |
| 1012 | mod: *Module, | 1018 | mod: *Zcu, |
| 1013 | decl_index: InternPool.DeclIndex, | 1019 | decl_index: InternPool.DeclIndex, |
| 1014 | export_indices: []const u32, | 1020 | export_indices: []const u32, |
| 1015 | ) !void { | 1021 | ) !void { |
| ... | @@ -1025,7 +1031,7 @@ fn addDeclExports( | ... | @@ -1025,7 +1031,7 @@ fn addDeclExports( |
| 1025 | if (!section_name.eqlSlice(".text", &mod.intern_pool) and | 1031 | if (!section_name.eqlSlice(".text", &mod.intern_pool) and |
| 1026 | !section_name.eqlSlice(".data", &mod.intern_pool)) | 1032 | !section_name.eqlSlice(".data", &mod.intern_pool)) |
| 1027 | { | 1033 | { |
| 1028 | try mod.failed_exports.put(mod.gpa, export_idx, try Module.ErrorMsg.create( | 1034 | try mod.failed_exports.put(mod.gpa, export_idx, try Zcu.ErrorMsg.create( |
| 1029 | gpa, | 1035 | gpa, |
| 1030 | mod.declPtr(decl_index).navSrcLoc(mod), | 1036 | mod.declPtr(decl_index).navSrcLoc(mod), |
| 1031 | "plan9 does not support extra sections", | 1037 | "plan9 does not support extra sections", |
| ... | @@ -1155,8 +1161,8 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index { | ... | @@ -1155,8 +1161,8 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index { |
| 1155 | 1161 | ||
| 1156 | pub fn updateExports( | 1162 | pub fn updateExports( |
| 1157 | self: *Plan9, | 1163 | self: *Plan9, |
| 1158 | module: *Module, | 1164 | pt: Zcu.PerThread, |
| 1159 | exported: Module.Exported, | 1165 | exported: Zcu.Exported, |
| 1160 | export_indices: []const u32, | 1166 | export_indices: []const u32, |
| 1161 | ) !void { | 1167 | ) !void { |
| 1162 | const gpa = self.base.comp.gpa; | 1168 | const gpa = self.base.comp.gpa; |
| ... | @@ -1173,11 +1179,11 @@ pub fn updateExports( | ... | @@ -1173,11 +1179,11 @@ pub fn updateExports( |
| 1173 | }, | 1179 | }, |
| 1174 | } | 1180 | } |
| 1175 | // all proper work is done in flush | 1181 | // all proper work is done in flush |
| 1176 | _ = module; | 1182 | _ = pt; |
| 1177 | } | 1183 | } |
| 1178 | 1184 | ||
| 1179 | pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.Index { | 1185 | pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol) !Atom.Index { |
| 1180 | const gpa = self.base.comp.gpa; | 1186 | const gpa = pt.zcu.gpa; |
| 1181 | const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?)); | 1187 | const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?)); |
| 1182 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); | 1188 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 1183 | 1189 | ||
| ... | @@ -1198,14 +1204,13 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In | ... | @@ -1198,14 +1204,13 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In |
| 1198 | _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self); | 1204 | _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self); |
| 1199 | // anyerror needs to be deferred until flushModule | 1205 | // anyerror needs to be deferred until flushModule |
| 1200 | if (sym.getDecl(self.base.comp.module.?) != .none) { | 1206 | if (sym.getDecl(self.base.comp.module.?) != .none) { |
| 1201 | try self.updateLazySymbolAtom(sym, atom); | 1207 | try self.updateLazySymbolAtom(pt, sym, atom); |
| 1202 | } | 1208 | } |
| 1203 | return atom; | 1209 | return atom; |
| 1204 | } | 1210 | } |
| 1205 | 1211 | ||
| 1206 | fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Index) !void { | 1212 | fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, atom_index: Atom.Index) !void { |
| 1207 | const gpa = self.base.comp.gpa; | 1213 | const gpa = pt.zcu.gpa; |
| 1208 | const mod = self.base.comp.module.?; | ||
| 1209 | 1214 | ||
| 1210 | var required_alignment: InternPool.Alignment = .none; | 1215 | var required_alignment: InternPool.Alignment = .none; |
| 1211 | var code_buffer = std.ArrayList(u8).init(gpa); | 1216 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1214,7 +1219,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind | ... | @@ -1214,7 +1219,7 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind |
| 1214 | // create the symbol for the name | 1219 | // create the symbol for the name |
| 1215 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ | 1220 | const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{ |
| 1216 | @tagName(sym.kind), | 1221 | @tagName(sym.kind), |
| 1217 | sym.ty.fmt(mod), | 1222 | sym.ty.fmt(pt), |
| 1218 | }); | 1223 | }); |
| 1219 | 1224 | ||
| 1220 | const symbol: aout.Sym = .{ | 1225 | const symbol: aout.Sym = .{ |
| ... | @@ -1225,9 +1230,10 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind | ... | @@ -1225,9 +1230,10 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind |
| 1225 | self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol; | 1230 | self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol; |
| 1226 | 1231 | ||
| 1227 | // generate the code | 1232 | // generate the code |
| 1228 | const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; | 1233 | const src = sym.ty.srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded; |
| 1229 | const res = try codegen.generateLazySymbol( | 1234 | const res = try codegen.generateLazySymbol( |
| 1230 | &self.base, | 1235 | &self.base, |
| 1236 | pt, | ||
| 1231 | src, | 1237 | src, |
| 1232 | sym, | 1238 | sym, |
| 1233 | &required_alignment, | 1239 | &required_alignment, |
| ... | @@ -1490,7 +1496,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { | ... | @@ -1490,7 +1496,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1490 | } | 1496 | } |
| 1491 | 1497 | ||
| 1492 | /// Must be called only after a successful call to `updateDecl`. | 1498 | /// Must be called only after a successful call to `updateDecl`. |
| 1493 | pub fn updateDeclLineNumber(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 1499 | pub fn updateDeclLineNumber(self: *Plan9, mod: *Zcu, decl_index: InternPool.DeclIndex) !void { |
| 1494 | _ = self; | 1500 | _ = self; |
| 1495 | _ = mod; | 1501 | _ = mod; |
| 1496 | _ = decl_index; | 1502 | _ = decl_index; |
| ... | @@ -1544,9 +1550,10 @@ pub fn getDeclVAddr( | ... | @@ -1544,9 +1550,10 @@ pub fn getDeclVAddr( |
| 1544 | 1550 | ||
| 1545 | pub fn lowerAnonDecl( | 1551 | pub fn lowerAnonDecl( |
| 1546 | self: *Plan9, | 1552 | self: *Plan9, |
| 1553 | pt: Zcu.PerThread, | ||
| 1547 | decl_val: InternPool.Index, | 1554 | decl_val: InternPool.Index, |
| 1548 | explicit_alignment: InternPool.Alignment, | 1555 | explicit_alignment: InternPool.Alignment, |
| 1549 | src_loc: Module.LazySrcLoc, | 1556 | src_loc: Zcu.LazySrcLoc, |
| 1550 | ) !codegen.Result { | 1557 | ) !codegen.Result { |
| 1551 | _ = explicit_alignment; | 1558 | _ = explicit_alignment; |
| 1552 | // This is basically the same as lowerUnnamedConst. | 1559 | // This is basically the same as lowerUnnamedConst. |
| ... | @@ -1569,7 +1576,7 @@ pub fn lowerAnonDecl( | ... | @@ -1569,7 +1576,7 @@ pub fn lowerAnonDecl( |
| 1569 | gop.value_ptr.* = index; | 1576 | gop.value_ptr.* = index; |
| 1570 | // we need to free name latex | 1577 | // we need to free name latex |
| 1571 | var code_buffer = std.ArrayList(u8).init(gpa); | 1578 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1572 | const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index }); | 1579 | const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index }); |
| 1573 | const code = switch (res) { | 1580 | const code = switch (res) { |
| 1574 | .ok => code_buffer.items, | 1581 | .ok => code_buffer.items, |
| 1575 | .fail => |em| return .{ .fail = em }, | 1582 | .fail => |em| return .{ .fail = em }, |
src/link/SpirV.zig+16-16| ... | @@ -28,8 +28,6 @@ const assert = std.debug.assert; | ... | @@ -28,8 +28,6 @@ const assert = std.debug.assert; |
| 28 | const log = std.log.scoped(.link); | 28 | const log = std.log.scoped(.link); |
| 29 | 29 | ||
| 30 | const Zcu = @import("../Zcu.zig"); | 30 | const Zcu = @import("../Zcu.zig"); |
| 31 | /// Deprecated. | ||
| 32 | const Module = Zcu; | ||
| 33 | const InternPool = @import("../InternPool.zig"); | 31 | const InternPool = @import("../InternPool.zig"); |
| 34 | const Compilation = @import("../Compilation.zig"); | 32 | const Compilation = @import("../Compilation.zig"); |
| 35 | const link = @import("../link.zig"); | 33 | const link = @import("../link.zig"); |
| ... | @@ -125,35 +123,36 @@ pub fn deinit(self: *SpirV) void { | ... | @@ -125,35 +123,36 @@ pub fn deinit(self: *SpirV) void { |
| 125 | self.object.deinit(); | 123 | self.object.deinit(); |
| 126 | } | 124 | } |
| 127 | 125 | ||
| 128 | pub fn updateFunc(self: *SpirV, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 126 | pub fn updateFunc(self: *SpirV, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 129 | if (build_options.skip_non_native) { | 127 | if (build_options.skip_non_native) { |
| 130 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 128 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 131 | } | 129 | } |
| 132 | 130 | ||
| 133 | const func = module.funcInfo(func_index); | 131 | const func = pt.zcu.funcInfo(func_index); |
| 134 | const decl = module.declPtr(func.owner_decl); | 132 | const decl = pt.zcu.declPtr(func.owner_decl); |
| 135 | log.debug("lowering function {}", .{decl.name.fmt(&module.intern_pool)}); | 133 | log.debug("lowering function {}", .{decl.name.fmt(&pt.zcu.intern_pool)}); |
| 136 | 134 | ||
| 137 | try self.object.updateFunc(module, func_index, air, liveness); | 135 | try self.object.updateFunc(pt, func_index, air, liveness); |
| 138 | } | 136 | } |
| 139 | 137 | ||
| 140 | pub fn updateDecl(self: *SpirV, module: *Module, decl_index: InternPool.DeclIndex) !void { | 138 | pub fn updateDecl(self: *SpirV, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 141 | if (build_options.skip_non_native) { | 139 | if (build_options.skip_non_native) { |
| 142 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 140 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | const decl = module.declPtr(decl_index); | 143 | const decl = pt.zcu.declPtr(decl_index); |
| 146 | log.debug("lowering declaration {}", .{decl.name.fmt(&module.intern_pool)}); | 144 | log.debug("lowering declaration {}", .{decl.name.fmt(&pt.zcu.intern_pool)}); |
| 147 | 145 | ||
| 148 | try self.object.updateDecl(module, decl_index); | 146 | try self.object.updateDecl(pt, decl_index); |
| 149 | } | 147 | } |
| 150 | 148 | ||
| 151 | pub fn updateExports( | 149 | pub fn updateExports( |
| 152 | self: *SpirV, | 150 | self: *SpirV, |
| 153 | mod: *Module, | 151 | pt: Zcu.PerThread, |
| 154 | exported: Module.Exported, | 152 | exported: Zcu.Exported, |
| 155 | export_indices: []const u32, | 153 | export_indices: []const u32, |
| 156 | ) !void { | 154 | ) !void { |
| 155 | const mod = pt.zcu; | ||
| 157 | const decl_index = switch (exported) { | 156 | const decl_index = switch (exported) { |
| 158 | .decl_index => |i| i, | 157 | .decl_index => |i| i, |
| 159 | .value => |val| { | 158 | .value => |val| { |
| ... | @@ -196,11 +195,11 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void { | ... | @@ -196,11 +195,11 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void { |
| 196 | _ = decl_index; | 195 | _ = decl_index; |
| 197 | } | 196 | } |
| 198 | 197 | ||
| 199 | pub fn flush(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 198 | pub fn flush(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 200 | return self.flushModule(arena, prog_node); | 199 | return self.flushModule(arena, tid, prog_node); |
| 201 | } | 200 | } |
| 202 | 201 | ||
| 203 | pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 202 | pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 204 | if (build_options.skip_non_native) { | 203 | if (build_options.skip_non_native) { |
| 205 | @panic("Attempted to compile for architecture that was disabled by build configuration"); | 204 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 206 | } | 205 | } |
| ... | @@ -216,6 +215,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -216,6 +215,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) |
| 216 | const comp = self.base.comp; | 215 | const comp = self.base.comp; |
| 217 | const gpa = comp.gpa; | 216 | const gpa = comp.gpa; |
| 218 | const target = comp.getTarget(); | 217 | const target = comp.getTarget(); |
| 218 | _ = tid; | ||
| 219 | 219 | ||
| 220 | try writeCapabilities(spv, target); | 220 | try writeCapabilities(spv, target); |
| 221 | try writeMemoryModel(spv, target); | 221 | try writeMemoryModel(spv, target); |
src/link/Wasm.zig+25-26| ... | @@ -29,8 +29,6 @@ const InternPool = @import("../InternPool.zig"); | ... | @@ -29,8 +29,6 @@ const InternPool = @import("../InternPool.zig"); |
| 29 | const Liveness = @import("../Liveness.zig"); | 29 | const Liveness = @import("../Liveness.zig"); |
| 30 | const LlvmObject = @import("../codegen/llvm.zig").Object; | 30 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 31 | const Zcu = @import("../Zcu.zig"); | 31 | const Zcu = @import("../Zcu.zig"); |
| 32 | /// Deprecated. | ||
| 33 | const Module = Zcu; | ||
| 34 | const Object = @import("Wasm/Object.zig"); | 32 | const Object = @import("Wasm/Object.zig"); |
| 35 | const Symbol = @import("Wasm/Symbol.zig"); | 33 | const Symbol = @import("Wasm/Symbol.zig"); |
| 36 | const Type = @import("../Type.zig"); | 34 | const Type = @import("../Type.zig"); |
| ... | @@ -1441,25 +1439,25 @@ pub fn deinit(wasm: *Wasm) void { | ... | @@ -1441,25 +1439,25 @@ pub fn deinit(wasm: *Wasm) void { |
| 1441 | wasm.files.deinit(gpa); | 1439 | wasm.files.deinit(gpa); |
| 1442 | } | 1440 | } |
| 1443 | 1441 | ||
| 1444 | pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 1442 | pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| 1445 | if (build_options.skip_non_native and builtin.object_format != .wasm) { | 1443 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 1446 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1444 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1447 | } | 1445 | } |
| 1448 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness); | 1446 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness); |
| 1449 | try wasm.zigObjectPtr().?.updateFunc(wasm, mod, func_index, air, liveness); | 1447 | try wasm.zigObjectPtr().?.updateFunc(wasm, pt, func_index, air, liveness); |
| 1450 | } | 1448 | } |
| 1451 | 1449 | ||
| 1452 | // Generate code for the Decl, storing it in memory to be later written to | 1450 | // Generate code for the Decl, storing it in memory to be later written to |
| 1453 | // the file on flush(). | 1451 | // the file on flush(). |
| 1454 | pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 1452 | pub fn updateDecl(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { |
| 1455 | if (build_options.skip_non_native and builtin.object_format != .wasm) { | 1453 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 1456 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1454 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1457 | } | 1455 | } |
| 1458 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); | 1456 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index); |
| 1459 | try wasm.zigObjectPtr().?.updateDecl(wasm, mod, decl_index); | 1457 | try wasm.zigObjectPtr().?.updateDecl(wasm, pt, decl_index); |
| 1460 | } | 1458 | } |
| 1461 | 1459 | ||
| 1462 | pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 1460 | pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Zcu, decl_index: InternPool.DeclIndex) !void { |
| 1463 | if (wasm.llvm_object) |_| return; | 1461 | if (wasm.llvm_object) |_| return; |
| 1464 | try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index); | 1462 | try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index); |
| 1465 | } | 1463 | } |
| ... | @@ -1506,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { | ... | @@ -1506,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { |
| 1506 | /// Lowers a constant typed value to a local symbol and atom. | 1504 | /// Lowers a constant typed value to a local symbol and atom. |
| 1507 | /// Returns the symbol index of the local | 1505 | /// Returns the symbol index of the local |
| 1508 | /// The given `decl` is the parent decl whom owns the constant. | 1506 | /// The given `decl` is the parent decl whom owns the constant. |
| 1509 | pub fn lowerUnnamedConst(wasm: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 1507 | pub fn lowerUnnamedConst(wasm: *Wasm, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 1510 | return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, val, decl_index); | 1508 | return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, pt, val, decl_index); |
| 1511 | } | 1509 | } |
| 1512 | 1510 | ||
| 1513 | /// Returns the symbol index from a symbol of which its flag is set global, | 1511 | /// Returns the symbol index from a symbol of which its flag is set global, |
| ... | @@ -1531,11 +1529,12 @@ pub fn getDeclVAddr( | ... | @@ -1531,11 +1529,12 @@ pub fn getDeclVAddr( |
| 1531 | 1529 | ||
| 1532 | pub fn lowerAnonDecl( | 1530 | pub fn lowerAnonDecl( |
| 1533 | wasm: *Wasm, | 1531 | wasm: *Wasm, |
| 1532 | pt: Zcu.PerThread, | ||
| 1534 | decl_val: InternPool.Index, | 1533 | decl_val: InternPool.Index, |
| 1535 | explicit_alignment: Alignment, | 1534 | explicit_alignment: Alignment, |
| 1536 | src_loc: Module.LazySrcLoc, | 1535 | src_loc: Zcu.LazySrcLoc, |
| 1537 | ) !codegen.Result { | 1536 | ) !codegen.Result { |
| 1538 | return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, decl_val, explicit_alignment, src_loc); | 1537 | return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, pt, decl_val, explicit_alignment, src_loc); |
| 1539 | } | 1538 | } |
| 1540 | 1539 | ||
| 1541 | pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1540 | pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| ... | @@ -1553,15 +1552,15 @@ pub fn deleteExport( | ... | @@ -1553,15 +1552,15 @@ pub fn deleteExport( |
| 1553 | 1552 | ||
| 1554 | pub fn updateExports( | 1553 | pub fn updateExports( |
| 1555 | wasm: *Wasm, | 1554 | wasm: *Wasm, |
| 1556 | mod: *Module, | 1555 | pt: Zcu.PerThread, |
| 1557 | exported: Module.Exported, | 1556 | exported: Zcu.Exported, |
| 1558 | export_indices: []const u32, | 1557 | export_indices: []const u32, |
| 1559 | ) !void { | 1558 | ) !void { |
| 1560 | if (build_options.skip_non_native and builtin.object_format != .wasm) { | 1559 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 1561 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1560 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 1562 | } | 1561 | } |
| 1563 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, export_indices); | 1562 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(pt, exported, export_indices); |
| 1564 | return wasm.zigObjectPtr().?.updateExports(wasm, mod, exported, export_indices); | 1563 | return wasm.zigObjectPtr().?.updateExports(wasm, pt, exported, export_indices); |
| 1565 | } | 1564 | } |
| 1566 | 1565 | ||
| 1567 | pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { | 1566 | pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { |
| ... | @@ -2466,18 +2465,18 @@ fn appendDummySegment(wasm: *Wasm) !void { | ... | @@ -2466,18 +2465,18 @@ fn appendDummySegment(wasm: *Wasm) !void { |
| 2466 | }); | 2465 | }); |
| 2467 | } | 2466 | } |
| 2468 | 2467 | ||
| 2469 | pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 2468 | pub fn flush(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 2470 | const comp = wasm.base.comp; | 2469 | const comp = wasm.base.comp; |
| 2471 | const use_lld = build_options.have_llvm and comp.config.use_lld; | 2470 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 2472 | 2471 | ||
| 2473 | if (use_lld) { | 2472 | if (use_lld) { |
| 2474 | return wasm.linkWithLLD(arena, prog_node); | 2473 | return wasm.linkWithLLD(arena, tid, prog_node); |
| 2475 | } | 2474 | } |
| 2476 | return wasm.flushModule(arena, prog_node); | 2475 | return wasm.flushModule(arena, tid, prog_node); |
| 2477 | } | 2476 | } |
| 2478 | 2477 | ||
| 2479 | /// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary. | 2478 | /// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary. |
| 2480 | pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { | 2479 | pub fn flushModule(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { |
| 2481 | const tracy = trace(@src()); | 2480 | const tracy = trace(@src()); |
| 2482 | defer tracy.end(); | 2481 | defer tracy.end(); |
| 2483 | 2482 | ||
| ... | @@ -2513,7 +2512,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) | ... | @@ -2513,7 +2512,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) |
| 2513 | const wasi_exec_model = comp.config.wasi_exec_model; | 2512 | const wasi_exec_model = comp.config.wasi_exec_model; |
| 2514 | 2513 | ||
| 2515 | if (wasm.zigObjectPtr()) |zig_object| { | 2514 | if (wasm.zigObjectPtr()) |zig_object| { |
| 2516 | try zig_object.flushModule(wasm); | 2515 | try zig_object.flushModule(wasm, tid); |
| 2517 | } | 2516 | } |
| 2518 | 2517 | ||
| 2519 | // When the target os is WASI, we allow linking with WASI-LIBC | 2518 | // When the target os is WASI, we allow linking with WASI-LIBC |
| ... | @@ -3324,7 +3323,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void { | ... | @@ -3324,7 +3323,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void { |
| 3324 | } | 3323 | } |
| 3325 | } | 3324 | } |
| 3326 | 3325 | ||
| 3327 | fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !void { | 3326 | fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 3328 | const tracy = trace(@src()); | 3327 | const tracy = trace(@src()); |
| 3329 | defer tracy.end(); | 3328 | defer tracy.end(); |
| 3330 | 3329 | ||
| ... | @@ -3342,7 +3341,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !voi | ... | @@ -3342,7 +3341,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !voi |
| 3342 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 3341 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 3343 | // will not be part of the linker line anyway. | 3342 | // will not be part of the linker line anyway. |
| 3344 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { | 3343 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { |
| 3345 | try wasm.flushModule(arena, prog_node); | 3344 | try wasm.flushModule(arena, tid, prog_node); |
| 3346 | 3345 | ||
| 3347 | if (fs.path.dirname(full_out_path)) |dirname| { | 3346 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 3348 | break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? }); | 3347 | break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? }); |
| ... | @@ -4009,8 +4008,8 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s | ... | @@ -4009,8 +4008,8 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s |
| 4009 | /// Returns the symbol index of the error name table. | 4008 | /// Returns the symbol index of the error name table. |
| 4010 | /// | 4009 | /// |
| 4011 | /// When the symbol does not yet exist, it will create a new one instead. | 4010 | /// When the symbol does not yet exist, it will create a new one instead. |
| 4012 | pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 { | 4011 | pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 { |
| 4013 | const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file); | 4012 | const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file, pt); |
| 4014 | return @intFromEnum(sym_index); | 4013 | return @intFromEnum(sym_index); |
| 4015 | } | 4014 | } |
| 4016 | 4015 |
src/link/Wasm/ZigObject.zig+59-41| ... | @@ -241,9 +241,10 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In | ... | @@ -241,9 +241,10 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In |
| 241 | pub fn updateDecl( | 241 | pub fn updateDecl( |
| 242 | zig_object: *ZigObject, | 242 | zig_object: *ZigObject, |
| 243 | wasm_file: *Wasm, | 243 | wasm_file: *Wasm, |
| 244 | mod: *Module, | 244 | pt: Zcu.PerThread, |
| 245 | decl_index: InternPool.DeclIndex, | 245 | decl_index: InternPool.DeclIndex, |
| 246 | ) !void { | 246 | ) !void { |
| 247 | const mod = pt.zcu; | ||
| 247 | const decl = mod.declPtr(decl_index); | 248 | const decl = mod.declPtr(decl_index); |
| 248 | if (decl.val.getFunction(mod)) |_| { | 249 | if (decl.val.getFunction(mod)) |_| { |
| 249 | return; | 250 | return; |
| ... | @@ -269,6 +270,7 @@ pub fn updateDecl( | ... | @@ -269,6 +270,7 @@ pub fn updateDecl( |
| 269 | 270 | ||
| 270 | const res = try codegen.generateSymbol( | 271 | const res = try codegen.generateSymbol( |
| 271 | &wasm_file.base, | 272 | &wasm_file.base, |
| 273 | pt, | ||
| 272 | decl.navSrcLoc(mod), | 274 | decl.navSrcLoc(mod), |
| 273 | val, | 275 | val, |
| 274 | &code_writer, | 276 | &code_writer, |
| ... | @@ -285,21 +287,21 @@ pub fn updateDecl( | ... | @@ -285,21 +287,21 @@ pub fn updateDecl( |
| 285 | }, | 287 | }, |
| 286 | }; | 288 | }; |
| 287 | 289 | ||
| 288 | return zig_object.finishUpdateDecl(wasm_file, decl_index, code); | 290 | return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code); |
| 289 | } | 291 | } |
| 290 | 292 | ||
| 291 | pub fn updateFunc( | 293 | pub fn updateFunc( |
| 292 | zig_object: *ZigObject, | 294 | zig_object: *ZigObject, |
| 293 | wasm_file: *Wasm, | 295 | wasm_file: *Wasm, |
| 294 | mod: *Module, | 296 | pt: Zcu.PerThread, |
| 295 | func_index: InternPool.Index, | 297 | func_index: InternPool.Index, |
| 296 | air: Air, | 298 | air: Air, |
| 297 | liveness: Liveness, | 299 | liveness: Liveness, |
| 298 | ) !void { | 300 | ) !void { |
| 299 | const gpa = wasm_file.base.comp.gpa; | 301 | const gpa = wasm_file.base.comp.gpa; |
| 300 | const func = mod.funcInfo(func_index); | 302 | const func = pt.zcu.funcInfo(func_index); |
| 301 | const decl_index = func.owner_decl; | 303 | const decl_index = func.owner_decl; |
| 302 | const decl = mod.declPtr(decl_index); | 304 | const decl = pt.zcu.declPtr(decl_index); |
| 303 | const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index); | 305 | const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index); |
| 304 | const atom = wasm_file.getAtomPtr(atom_index); | 306 | const atom = wasm_file.getAtomPtr(atom_index); |
| 305 | atom.clear(); | 307 | atom.clear(); |
| ... | @@ -308,7 +310,8 @@ pub fn updateFunc( | ... | @@ -308,7 +310,8 @@ pub fn updateFunc( |
| 308 | defer code_writer.deinit(); | 310 | defer code_writer.deinit(); |
| 309 | const result = try codegen.generateFunction( | 311 | const result = try codegen.generateFunction( |
| 310 | &wasm_file.base, | 312 | &wasm_file.base, |
| 311 | decl.navSrcLoc(mod), | 313 | pt, |
| 314 | decl.navSrcLoc(pt.zcu), | ||
| 312 | func_index, | 315 | func_index, |
| 313 | air, | 316 | air, |
| 314 | liveness, | 317 | liveness, |
| ... | @@ -320,29 +323,31 @@ pub fn updateFunc( | ... | @@ -320,29 +323,31 @@ pub fn updateFunc( |
| 320 | .ok => code_writer.items, | 323 | .ok => code_writer.items, |
| 321 | .fail => |em| { | 324 | .fail => |em| { |
| 322 | decl.analysis = .codegen_failure; | 325 | decl.analysis = .codegen_failure; |
| 323 | try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em); | 326 | try pt.zcu.failed_analysis.put(gpa, AnalUnit.wrap(.{ .decl = decl_index }), em); |
| 324 | return; | 327 | return; |
| 325 | }, | 328 | }, |
| 326 | }; | 329 | }; |
| 327 | 330 | ||
| 328 | return zig_object.finishUpdateDecl(wasm_file, decl_index, code); | 331 | return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code); |
| 329 | } | 332 | } |
| 330 | 333 | ||
| 331 | fn finishUpdateDecl( | 334 | fn finishUpdateDecl( |
| 332 | zig_object: *ZigObject, | 335 | zig_object: *ZigObject, |
| 333 | wasm_file: *Wasm, | 336 | wasm_file: *Wasm, |
| 337 | pt: Zcu.PerThread, | ||
| 334 | decl_index: InternPool.DeclIndex, | 338 | decl_index: InternPool.DeclIndex, |
| 335 | code: []const u8, | 339 | code: []const u8, |
| 336 | ) !void { | 340 | ) !void { |
| 337 | const gpa = wasm_file.base.comp.gpa; | 341 | const zcu = pt.zcu; |
| 338 | const zcu = wasm_file.base.comp.module.?; | 342 | const ip = &zcu.intern_pool; |
| 343 | const gpa = zcu.gpa; | ||
| 339 | const decl = zcu.declPtr(decl_index); | 344 | const decl = zcu.declPtr(decl_index); |
| 340 | const decl_info = zig_object.decls_map.get(decl_index).?; | 345 | const decl_info = zig_object.decls_map.get(decl_index).?; |
| 341 | const atom_index = decl_info.atom; | 346 | const atom_index = decl_info.atom; |
| 342 | const atom = wasm_file.getAtomPtr(atom_index); | 347 | const atom = wasm_file.getAtomPtr(atom_index); |
| 343 | const sym = zig_object.symbol(atom.sym_index); | 348 | const sym = zig_object.symbol(atom.sym_index); |
| 344 | const full_name = try decl.fullyQualifiedName(zcu); | 349 | const full_name = try decl.fullyQualifiedName(zcu); |
| 345 | sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&zcu.intern_pool)); | 350 | sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip)); |
| 346 | try atom.code.appendSlice(gpa, code); | 351 | try atom.code.appendSlice(gpa, code); |
| 347 | atom.size = @intCast(code.len); | 352 | atom.size = @intCast(code.len); |
| 348 | 353 | ||
| ... | @@ -382,7 +387,7 @@ fn finishUpdateDecl( | ... | @@ -382,7 +387,7 @@ fn finishUpdateDecl( |
| 382 | // Will be freed upon freeing of decl or after cleanup of Wasm binary. | 387 | // Will be freed upon freeing of decl or after cleanup of Wasm binary. |
| 383 | const full_segment_name = try std.mem.concat(gpa, u8, &.{ | 388 | const full_segment_name = try std.mem.concat(gpa, u8, &.{ |
| 384 | segment_name, | 389 | segment_name, |
| 385 | full_name.toSlice(&zcu.intern_pool), | 390 | full_name.toSlice(ip), |
| 386 | }); | 391 | }); |
| 387 | errdefer gpa.free(full_segment_name); | 392 | errdefer gpa.free(full_segment_name); |
| 388 | sym.tag = .data; | 393 | sym.tag = .data; |
| ... | @@ -390,7 +395,7 @@ fn finishUpdateDecl( | ... | @@ -390,7 +395,7 @@ fn finishUpdateDecl( |
| 390 | }, | 395 | }, |
| 391 | } | 396 | } |
| 392 | if (code.len == 0) return; | 397 | if (code.len == 0) return; |
| 393 | atom.alignment = decl.getAlignment(zcu); | 398 | atom.alignment = decl.getAlignment(pt); |
| 394 | } | 399 | } |
| 395 | 400 | ||
| 396 | /// Creates and initializes a new segment in the 'Data' section. | 401 | /// Creates and initializes a new segment in the 'Data' section. |
| ... | @@ -437,9 +442,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind | ... | @@ -437,9 +442,10 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind |
| 437 | pub fn lowerAnonDecl( | 442 | pub fn lowerAnonDecl( |
| 438 | zig_object: *ZigObject, | 443 | zig_object: *ZigObject, |
| 439 | wasm_file: *Wasm, | 444 | wasm_file: *Wasm, |
| 445 | pt: Zcu.PerThread, | ||
| 440 | decl_val: InternPool.Index, | 446 | decl_val: InternPool.Index, |
| 441 | explicit_alignment: InternPool.Alignment, | 447 | explicit_alignment: InternPool.Alignment, |
| 442 | src_loc: Module.LazySrcLoc, | 448 | src_loc: Zcu.LazySrcLoc, |
| 443 | ) !codegen.Result { | 449 | ) !codegen.Result { |
| 444 | const gpa = wasm_file.base.comp.gpa; | 450 | const gpa = wasm_file.base.comp.gpa; |
| 445 | const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val); | 451 | const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val); |
| ... | @@ -449,7 +455,7 @@ pub fn lowerAnonDecl( | ... | @@ -449,7 +455,7 @@ pub fn lowerAnonDecl( |
| 449 | @intFromEnum(decl_val), | 455 | @intFromEnum(decl_val), |
| 450 | }) catch unreachable; | 456 | }) catch unreachable; |
| 451 | 457 | ||
| 452 | switch (try zig_object.lowerConst(wasm_file, name, Value.fromInterned(decl_val), src_loc)) { | 458 | switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(decl_val), src_loc)) { |
| 453 | .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index, | 459 | .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index, |
| 454 | .fail => |em| return .{ .fail = em }, | 460 | .fail => |em| return .{ .fail = em }, |
| 455 | } | 461 | } |
| ... | @@ -469,9 +475,15 @@ pub fn lowerAnonDecl( | ... | @@ -469,9 +475,15 @@ pub fn lowerAnonDecl( |
| 469 | /// Lowers a constant typed value to a local symbol and atom. | 475 | /// Lowers a constant typed value to a local symbol and atom. |
| 470 | /// Returns the symbol index of the local | 476 | /// Returns the symbol index of the local |
| 471 | /// The given `decl` is the parent decl whom owns the constant. | 477 | /// The given `decl` is the parent decl whom owns the constant. |
| 472 | pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 478 | pub fn lowerUnnamedConst( |
| 473 | const gpa = wasm_file.base.comp.gpa; | 479 | zig_object: *ZigObject, |
| 474 | const mod = wasm_file.base.comp.module.?; | 480 | wasm_file: *Wasm, |
| 481 | pt: Zcu.PerThread, | ||
| 482 | val: Value, | ||
| 483 | decl_index: InternPool.DeclIndex, | ||
| 484 | ) !u32 { | ||
| 485 | const mod = pt.zcu; | ||
| 486 | const gpa = mod.gpa; | ||
| 475 | std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions | 487 | std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions |
| 476 | const decl = mod.declPtr(decl_index); | 488 | const decl = mod.declPtr(decl_index); |
| 477 | 489 | ||
| ... | @@ -494,7 +506,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d | ... | @@ -494,7 +506,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d |
| 494 | else | 506 | else |
| 495 | decl.navSrcLoc(mod); | 507 | decl.navSrcLoc(mod); |
| 496 | 508 | ||
| 497 | switch (try zig_object.lowerConst(wasm_file, name, val, decl_src)) { | 509 | switch (try zig_object.lowerConst(wasm_file, pt, name, val, decl_src)) { |
| 498 | .ok => |atom_index| { | 510 | .ok => |atom_index| { |
| 499 | try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index); | 511 | try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index); |
| 500 | return @intFromEnum(wasm_file.getAtom(atom_index).sym_index); | 512 | return @intFromEnum(wasm_file.getAtom(atom_index).sym_index); |
| ... | @@ -509,10 +521,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d | ... | @@ -509,10 +521,17 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d |
| 509 | 521 | ||
| 510 | const LowerConstResult = union(enum) { | 522 | const LowerConstResult = union(enum) { |
| 511 | ok: Atom.Index, | 523 | ok: Atom.Index, |
| 512 | fail: *Module.ErrorMsg, | 524 | fail: *Zcu.ErrorMsg, |
| 513 | }; | 525 | }; |
| 514 | 526 | ||
| 515 | fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: Value, src_loc: Module.LazySrcLoc) !LowerConstResult { | 527 | fn lowerConst( |
| 528 | zig_object: *ZigObject, | ||
| 529 | wasm_file: *Wasm, | ||
| 530 | pt: Zcu.PerThread, | ||
| 531 | name: []const u8, | ||
| 532 | val: Value, | ||
| 533 | src_loc: Zcu.LazySrcLoc, | ||
| 534 | ) !LowerConstResult { | ||
| 516 | const gpa = wasm_file.base.comp.gpa; | 535 | const gpa = wasm_file.base.comp.gpa; |
| 517 | const mod = wasm_file.base.comp.module.?; | 536 | const mod = wasm_file.base.comp.module.?; |
| 518 | 537 | ||
| ... | @@ -526,7 +545,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V | ... | @@ -526,7 +545,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V |
| 526 | 545 | ||
| 527 | const code = code: { | 546 | const code = code: { |
| 528 | const atom = wasm_file.getAtomPtr(atom_index); | 547 | const atom = wasm_file.getAtomPtr(atom_index); |
| 529 | atom.alignment = ty.abiAlignment(mod); | 548 | atom.alignment = ty.abiAlignment(pt); |
| 530 | const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name }); | 549 | const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name }); |
| 531 | errdefer gpa.free(segment_name); | 550 | errdefer gpa.free(segment_name); |
| 532 | zig_object.symbol(sym_index).* = .{ | 551 | zig_object.symbol(sym_index).* = .{ |
| ... | @@ -536,13 +555,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V | ... | @@ -536,13 +555,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V |
| 536 | .index = try zig_object.createDataSegment( | 555 | .index = try zig_object.createDataSegment( |
| 537 | gpa, | 556 | gpa, |
| 538 | segment_name, | 557 | segment_name, |
| 539 | ty.abiAlignment(mod), | 558 | ty.abiAlignment(pt), |
| 540 | ), | 559 | ), |
| 541 | .virtual_address = undefined, | 560 | .virtual_address = undefined, |
| 542 | }; | 561 | }; |
| 543 | 562 | ||
| 544 | const result = try codegen.generateSymbol( | 563 | const result = try codegen.generateSymbol( |
| 545 | &wasm_file.base, | 564 | &wasm_file.base, |
| 565 | pt, | ||
| 546 | src_loc, | 566 | src_loc, |
| 547 | val, | 567 | val, |
| 548 | &value_bytes, | 568 | &value_bytes, |
| ... | @@ -568,7 +588,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V | ... | @@ -568,7 +588,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: V |
| 568 | /// Returns the symbol index of the error name table. | 588 | /// Returns the symbol index of the error name table. |
| 569 | /// | 589 | /// |
| 570 | /// When the symbol does not yet exist, it will create a new one instead. | 590 | /// When the symbol does not yet exist, it will create a new one instead. |
| 571 | pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Index { | 591 | pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm, pt: Zcu.PerThread) !Symbol.Index { |
| 572 | if (zig_object.error_table_symbol != .null) { | 592 | if (zig_object.error_table_symbol != .null) { |
| 573 | return zig_object.error_table_symbol; | 593 | return zig_object.error_table_symbol; |
| 574 | } | 594 | } |
| ... | @@ -581,8 +601,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind | ... | @@ -581,8 +601,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind |
| 581 | const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); | 601 | const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); |
| 582 | const atom = wasm_file.getAtomPtr(atom_index); | 602 | const atom = wasm_file.getAtomPtr(atom_index); |
| 583 | const slice_ty = Type.slice_const_u8_sentinel_0; | 603 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 584 | const mod = wasm_file.base.comp.module.?; | 604 | atom.alignment = slice_ty.abiAlignment(pt); |
| 585 | atom.alignment = slice_ty.abiAlignment(mod); | ||
| 586 | 605 | ||
| 587 | const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table"); | 606 | const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table"); |
| 588 | const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table"); | 607 | const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table"); |
| ... | @@ -604,7 +623,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind | ... | @@ -604,7 +623,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Ind |
| 604 | /// | 623 | /// |
| 605 | /// This creates a table that consists of pointers and length to each error name. | 624 | /// This creates a table that consists of pointers and length to each error name. |
| 606 | /// The table is what is being pointed to within the runtime bodies that are generated. | 625 | /// The table is what is being pointed to within the runtime bodies that are generated. |
| 607 | fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { | 626 | fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void { |
| 608 | if (zig_object.error_table_symbol == .null) return; | 627 | if (zig_object.error_table_symbol == .null) return; |
| 609 | const gpa = wasm_file.base.comp.gpa; | 628 | const gpa = wasm_file.base.comp.gpa; |
| 610 | const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?; | 629 | const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?; |
| ... | @@ -631,11 +650,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { | ... | @@ -631,11 +650,11 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { |
| 631 | 650 | ||
| 632 | // Addend for each relocation to the table | 651 | // Addend for each relocation to the table |
| 633 | var addend: u32 = 0; | 652 | var addend: u32 = 0; |
| 634 | const mod = wasm_file.base.comp.module.?; | 653 | const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid }; |
| 635 | for (mod.global_error_set.keys()) |error_name| { | 654 | for (pt.zcu.global_error_set.keys()) |error_name| { |
| 636 | const atom = wasm_file.getAtomPtr(atom_index); | 655 | const atom = wasm_file.getAtomPtr(atom_index); |
| 637 | 656 | ||
| 638 | const error_name_slice = error_name.toSlice(&mod.intern_pool); | 657 | const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool); |
| 639 | const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated | 658 | const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated |
| 640 | 659 | ||
| 641 | const slice_ty = Type.slice_const_u8_sentinel_0; | 660 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| ... | @@ -650,14 +669,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { | ... | @@ -650,14 +669,14 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { |
| 650 | .offset = offset, | 669 | .offset = offset, |
| 651 | .addend = @intCast(addend), | 670 | .addend = @intCast(addend), |
| 652 | }); | 671 | }); |
| 653 | atom.size += @intCast(slice_ty.abiSize(mod)); | 672 | atom.size += @intCast(slice_ty.abiSize(pt)); |
| 654 | addend += len; | 673 | addend += len; |
| 655 | 674 | ||
| 656 | // as we updated the error name table, we now store the actual name within the names atom | 675 | // as we updated the error name table, we now store the actual name within the names atom |
| 657 | try names_atom.code.ensureUnusedCapacity(gpa, len); | 676 | try names_atom.code.ensureUnusedCapacity(gpa, len); |
| 658 | names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]); | 677 | names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]); |
| 659 | 678 | ||
| 660 | log.debug("Populated error name: '{}'", .{error_name.fmt(&mod.intern_pool)}); | 679 | log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)}); |
| 661 | } | 680 | } |
| 662 | names_atom.size = addend; | 681 | names_atom.size = addend; |
| 663 | zig_object.error_names_atom = names_atom_index; | 682 | zig_object.error_names_atom = names_atom_index; |
| ... | @@ -858,10 +877,11 @@ pub fn deleteExport( | ... | @@ -858,10 +877,11 @@ pub fn deleteExport( |
| 858 | pub fn updateExports( | 877 | pub fn updateExports( |
| 859 | zig_object: *ZigObject, | 878 | zig_object: *ZigObject, |
| 860 | wasm_file: *Wasm, | 879 | wasm_file: *Wasm, |
| 861 | mod: *Module, | 880 | pt: Zcu.PerThread, |
| 862 | exported: Module.Exported, | 881 | exported: Zcu.Exported, |
| 863 | export_indices: []const u32, | 882 | export_indices: []const u32, |
| 864 | ) !void { | 883 | ) !void { |
| 884 | const mod = pt.zcu; | ||
| 865 | const decl_index = switch (exported) { | 885 | const decl_index = switch (exported) { |
| 866 | .decl_index => |i| i, | 886 | .decl_index => |i| i, |
| 867 | .value => |val| { | 887 | .value => |val| { |
| ... | @@ -880,7 +900,7 @@ pub fn updateExports( | ... | @@ -880,7 +900,7 @@ pub fn updateExports( |
| 880 | for (export_indices) |export_idx| { | 900 | for (export_indices) |export_idx| { |
| 881 | const exp = mod.all_exports.items[export_idx]; | 901 | const exp = mod.all_exports.items[export_idx]; |
| 882 | if (exp.opts.section.toSlice(&mod.intern_pool)) |section| { | 902 | if (exp.opts.section.toSlice(&mod.intern_pool)) |section| { |
| 883 | try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create( | 903 | try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create( |
| 884 | gpa, | 904 | gpa, |
| 885 | decl.navSrcLoc(mod), | 905 | decl.navSrcLoc(mod), |
| 886 | "Unimplemented: ExportOptions.section '{s}'", | 906 | "Unimplemented: ExportOptions.section '{s}'", |
| ... | @@ -913,7 +933,7 @@ pub fn updateExports( | ... | @@ -913,7 +933,7 @@ pub fn updateExports( |
| 913 | }, | 933 | }, |
| 914 | .strong => {}, // symbols are strong by default | 934 | .strong => {}, // symbols are strong by default |
| 915 | .link_once => { | 935 | .link_once => { |
| 916 | try mod.failed_exports.putNoClobber(gpa, export_idx, try Module.ErrorMsg.create( | 936 | try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create( |
| 917 | gpa, | 937 | gpa, |
| 918 | decl.navSrcLoc(mod), | 938 | decl.navSrcLoc(mod), |
| 919 | "Unimplemented: LinkOnce", | 939 | "Unimplemented: LinkOnce", |
| ... | @@ -1096,7 +1116,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde | ... | @@ -1096,7 +1116,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde |
| 1096 | return atom_index; | 1116 | return atom_index; |
| 1097 | } | 1117 | } |
| 1098 | 1118 | ||
| 1099 | pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 1119 | pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Zcu, decl_index: InternPool.DeclIndex) !void { |
| 1100 | if (zig_object.dwarf) |*dw| { | 1120 | if (zig_object.dwarf) |*dw| { |
| 1101 | const decl = mod.declPtr(decl_index); | 1121 | const decl = mod.declPtr(decl_index); |
| 1102 | const decl_name = try decl.fullyQualifiedName(mod); | 1122 | const decl_name = try decl.fullyQualifiedName(mod); |
| ... | @@ -1228,8 +1248,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm | ... | @@ -1228,8 +1248,8 @@ fn appendFunction(zig_object: *ZigObject, gpa: std.mem.Allocator, func: std.wasm |
| 1228 | return index; | 1248 | return index; |
| 1229 | } | 1249 | } |
| 1230 | 1250 | ||
| 1231 | pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm) !void { | 1251 | pub fn flushModule(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.PerThread.Id) !void { |
| 1232 | try zig_object.populateErrorNameTable(wasm_file); | 1252 | try zig_object.populateErrorNameTable(wasm_file, tid); |
| 1233 | try zig_object.setupErrorsLen(wasm_file); | 1253 | try zig_object.setupErrorsLen(wasm_file); |
| 1234 | } | 1254 | } |
| 1235 | 1255 | ||
| ... | @@ -1248,8 +1268,6 @@ const File = @import("file.zig").File; | ... | @@ -1248,8 +1268,6 @@ const File = @import("file.zig").File; |
| 1248 | const InternPool = @import("../../InternPool.zig"); | 1268 | const InternPool = @import("../../InternPool.zig"); |
| 1249 | const Liveness = @import("../../Liveness.zig"); | 1269 | const Liveness = @import("../../Liveness.zig"); |
| 1250 | const Zcu = @import("../../Zcu.zig"); | 1270 | const Zcu = @import("../../Zcu.zig"); |
| 1251 | /// Deprecated. | ||
| 1252 | const Module = Zcu; | ||
| 1253 | const StringTable = @import("../StringTable.zig"); | 1271 | const StringTable = @import("../StringTable.zig"); |
| 1254 | const Symbol = @import("Symbol.zig"); | 1272 | const Symbol = @import("Symbol.zig"); |
| 1255 | const Type = @import("../../Type.zig"); | 1273 | const Type = @import("../../Type.zig"); |
src/main.zig+4-4| ... | @@ -172,7 +172,7 @@ pub fn main() anyerror!void { | ... | @@ -172,7 +172,7 @@ pub fn main() anyerror!void { |
| 172 | } | 172 | } |
| 173 | // We would prefer to use raw libc allocator here, but cannot | 173 | // We would prefer to use raw libc allocator here, but cannot |
| 174 | // use it if it won't support the alignment we need. | 174 | // use it if it won't support the alignment we need. |
| 175 | if (@alignOf(std.c.max_align_t) < @alignOf(i128)) { | 175 | if (@alignOf(std.c.max_align_t) < @max(@alignOf(i128), std.atomic.cache_line)) { |
| 176 | break :gpa std.heap.c_allocator; | 176 | break :gpa std.heap.c_allocator; |
| 177 | } | 177 | } |
| 178 | break :gpa std.heap.raw_c_allocator; | 178 | break :gpa std.heap.raw_c_allocator; |
| ... | @@ -3092,7 +3092,7 @@ fn buildOutputType( | ... | @@ -3092,7 +3092,7 @@ fn buildOutputType( |
| 3092 | defer emit_implib_resolved.deinit(); | 3092 | defer emit_implib_resolved.deinit(); |
| 3093 | 3093 | ||
| 3094 | var thread_pool: ThreadPool = undefined; | 3094 | var thread_pool: ThreadPool = undefined; |
| 3095 | try thread_pool.init(.{ .allocator = gpa }); | 3095 | try thread_pool.init(.{ .allocator = gpa, .track_ids = true }); |
| 3096 | defer thread_pool.deinit(); | 3096 | defer thread_pool.deinit(); |
| 3097 | 3097 | ||
| 3098 | var cleanup_local_cache_dir: ?fs.Dir = null; | 3098 | var cleanup_local_cache_dir: ?fs.Dir = null; |
| ... | @@ -4895,7 +4895,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4895,7 +4895,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4895 | child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path; | 4895 | child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path; |
| 4896 | 4896 | ||
| 4897 | var thread_pool: ThreadPool = undefined; | 4897 | var thread_pool: ThreadPool = undefined; |
| 4898 | try thread_pool.init(.{ .allocator = gpa }); | 4898 | try thread_pool.init(.{ .allocator = gpa, .track_ids = true }); |
| 4899 | defer thread_pool.deinit(); | 4899 | defer thread_pool.deinit(); |
| 4900 | 4900 | ||
| 4901 | // Dummy http client that is not actually used when only_core_functionality is enabled. | 4901 | // Dummy http client that is not actually used when only_core_functionality is enabled. |
| ... | @@ -5329,7 +5329,7 @@ fn jitCmd( | ... | @@ -5329,7 +5329,7 @@ fn jitCmd( |
| 5329 | defer global_cache_directory.handle.close(); | 5329 | defer global_cache_directory.handle.close(); |
| 5330 | 5330 | ||
| 5331 | var thread_pool: ThreadPool = undefined; | 5331 | var thread_pool: ThreadPool = undefined; |
| 5332 | try thread_pool.init(.{ .allocator = gpa }); | 5332 | try thread_pool.init(.{ .allocator = gpa, .track_ids = true }); |
| 5333 | defer thread_pool.deinit(); | 5333 | defer thread_pool.deinit(); |
| 5334 | 5334 | ||
| 5335 | var child_argv: std.ArrayListUnmanaged([]const u8) = .{}; | 5335 | var child_argv: std.ArrayListUnmanaged([]const u8) = .{}; |
src/mutable_value.zig+48-52| ... | @@ -54,46 +54,44 @@ pub const MutableValue = union(enum) { | ... | @@ -54,46 +54,44 @@ pub const MutableValue = union(enum) { |
| 54 | payload: *MutableValue, | 54 | payload: *MutableValue, |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | pub fn intern(mv: MutableValue, zcu: *Zcu, arena: Allocator) Allocator.Error!Value { | 57 | pub fn intern(mv: MutableValue, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value { |
| 58 | const ip = &zcu.intern_pool; | ||
| 59 | const gpa = zcu.gpa; | ||
| 60 | return Value.fromInterned(switch (mv) { | 58 | return Value.fromInterned(switch (mv) { |
| 61 | .interned => |ip_index| ip_index, | 59 | .interned => |ip_index| ip_index, |
| 62 | .eu_payload => |sv| try ip.get(gpa, .{ .error_union = .{ | 60 | .eu_payload => |sv| try pt.intern(.{ .error_union = .{ |
| 63 | .ty = sv.ty, | 61 | .ty = sv.ty, |
| 64 | .val = .{ .payload = (try sv.child.intern(zcu, arena)).toIntern() }, | 62 | .val = .{ .payload = (try sv.child.intern(pt, arena)).toIntern() }, |
| 65 | } }), | 63 | } }), |
| 66 | .opt_payload => |sv| try ip.get(gpa, .{ .opt = .{ | 64 | .opt_payload => |sv| try pt.intern(.{ .opt = .{ |
| 67 | .ty = sv.ty, | 65 | .ty = sv.ty, |
| 68 | .val = (try sv.child.intern(zcu, arena)).toIntern(), | 66 | .val = (try sv.child.intern(pt, arena)).toIntern(), |
| 69 | } }), | 67 | } }), |
| 70 | .repeated => |sv| try ip.get(gpa, .{ .aggregate = .{ | 68 | .repeated => |sv| try pt.intern(.{ .aggregate = .{ |
| 71 | .ty = sv.ty, | 69 | .ty = sv.ty, |
| 72 | .storage = .{ .repeated_elem = (try sv.child.intern(zcu, arena)).toIntern() }, | 70 | .storage = .{ .repeated_elem = (try sv.child.intern(pt, arena)).toIntern() }, |
| 73 | } }), | 71 | } }), |
| 74 | .bytes => |b| try ip.get(gpa, .{ .aggregate = .{ | 72 | .bytes => |b| try pt.intern(.{ .aggregate = .{ |
| 75 | .ty = b.ty, | 73 | .ty = b.ty, |
| 76 | .storage = .{ .bytes = try ip.getOrPutString(gpa, b.data, .maybe_embedded_nulls) }, | 74 | .storage = .{ .bytes = try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, b.data, .maybe_embedded_nulls) }, |
| 77 | } }), | 75 | } }), |
| 78 | .aggregate => |a| { | 76 | .aggregate => |a| { |
| 79 | const elems = try arena.alloc(InternPool.Index, a.elems.len); | 77 | const elems = try arena.alloc(InternPool.Index, a.elems.len); |
| 80 | for (a.elems, elems) |mut_elem, *interned_elem| { | 78 | for (a.elems, elems) |mut_elem, *interned_elem| { |
| 81 | interned_elem.* = (try mut_elem.intern(zcu, arena)).toIntern(); | 79 | interned_elem.* = (try mut_elem.intern(pt, arena)).toIntern(); |
| 82 | } | 80 | } |
| 83 | return Value.fromInterned(try ip.get(gpa, .{ .aggregate = .{ | 81 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 84 | .ty = a.ty, | 82 | .ty = a.ty, |
| 85 | .storage = .{ .elems = elems }, | 83 | .storage = .{ .elems = elems }, |
| 86 | } })); | 84 | } })); |
| 87 | }, | 85 | }, |
| 88 | .slice => |s| try ip.get(gpa, .{ .slice = .{ | 86 | .slice => |s| try pt.intern(.{ .slice = .{ |
| 89 | .ty = s.ty, | 87 | .ty = s.ty, |
| 90 | .ptr = (try s.ptr.intern(zcu, arena)).toIntern(), | 88 | .ptr = (try s.ptr.intern(pt, arena)).toIntern(), |
| 91 | .len = (try s.len.intern(zcu, arena)).toIntern(), | 89 | .len = (try s.len.intern(pt, arena)).toIntern(), |
| 92 | } }), | 90 | } }), |
| 93 | .un => |u| try ip.get(gpa, .{ .un = .{ | 91 | .un => |u| try pt.intern(.{ .un = .{ |
| 94 | .ty = u.ty, | 92 | .ty = u.ty, |
| 95 | .tag = u.tag, | 93 | .tag = u.tag, |
| 96 | .val = (try u.payload.intern(zcu, arena)).toIntern(), | 94 | .val = (try u.payload.intern(pt, arena)).toIntern(), |
| 97 | } }), | 95 | } }), |
| 98 | }); | 96 | }); |
| 99 | } | 97 | } |
| ... | @@ -108,13 +106,13 @@ pub const MutableValue = union(enum) { | ... | @@ -108,13 +106,13 @@ pub const MutableValue = union(enum) { |
| 108 | /// If `!allow_repeated`, the `repeated` representation will not be used. | 106 | /// If `!allow_repeated`, the `repeated` representation will not be used. |
| 109 | pub fn unintern( | 107 | pub fn unintern( |
| 110 | mv: *MutableValue, | 108 | mv: *MutableValue, |
| 111 | zcu: *Zcu, | 109 | pt: Zcu.PerThread, |
| 112 | arena: Allocator, | 110 | arena: Allocator, |
| 113 | allow_bytes: bool, | 111 | allow_bytes: bool, |
| 114 | allow_repeated: bool, | 112 | allow_repeated: bool, |
| 115 | ) Allocator.Error!void { | 113 | ) Allocator.Error!void { |
| 114 | const zcu = pt.zcu; | ||
| 116 | const ip = &zcu.intern_pool; | 115 | const ip = &zcu.intern_pool; |
| 117 | const gpa = zcu.gpa; | ||
| 118 | switch (mv.*) { | 116 | switch (mv.*) { |
| 119 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { | 117 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { |
| 120 | .opt => |opt| if (opt.val != .none) { | 118 | .opt => |opt| if (opt.val != .none) { |
| ... | @@ -170,7 +168,7 @@ pub const MutableValue = union(enum) { | ... | @@ -170,7 +168,7 @@ pub const MutableValue = union(enum) { |
| 170 | } else { | 168 | } else { |
| 171 | const mut_elems = try arena.alloc(MutableValue, len); | 169 | const mut_elems = try arena.alloc(MutableValue, len); |
| 172 | for (bytes.toSlice(len, ip), mut_elems) |b, *mut_elem| { | 170 | for (bytes.toSlice(len, ip), mut_elems) |b, *mut_elem| { |
| 173 | mut_elem.* = .{ .interned = try ip.get(gpa, .{ .int = .{ | 171 | mut_elem.* = .{ .interned = try pt.intern(.{ .int = .{ |
| 174 | .ty = .u8_type, | 172 | .ty = .u8_type, |
| 175 | .storage = .{ .u64 = b }, | 173 | .storage = .{ .u64 = b }, |
| 176 | } }) }; | 174 | } }) }; |
| ... | @@ -221,12 +219,12 @@ pub const MutableValue = union(enum) { | ... | @@ -221,12 +219,12 @@ pub const MutableValue = union(enum) { |
| 221 | switch (type_tag) { | 219 | switch (type_tag) { |
| 222 | .Array, .Vector => { | 220 | .Array, .Vector => { |
| 223 | const elem_ty = ip.childType(ty_ip); | 221 | const elem_ty = ip.childType(ty_ip); |
| 224 | const undef_elem = try ip.get(gpa, .{ .undef = elem_ty }); | 222 | const undef_elem = try pt.intern(.{ .undef = elem_ty }); |
| 225 | @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem }); | 223 | @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem }); |
| 226 | }, | 224 | }, |
| 227 | .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| { | 225 | .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| { |
| 228 | const field_ty = ty.structFieldType(i, zcu).toIntern(); | 226 | const field_ty = ty.structFieldType(i, zcu).toIntern(); |
| 229 | mut_elem.* = .{ .interned = try ip.get(gpa, .{ .undef = field_ty }) }; | 227 | mut_elem.* = .{ .interned = try pt.intern(.{ .undef = field_ty }) }; |
| 230 | }, | 228 | }, |
| 231 | else => unreachable, | 229 | else => unreachable, |
| 232 | } | 230 | } |
| ... | @@ -238,7 +236,7 @@ pub const MutableValue = union(enum) { | ... | @@ -238,7 +236,7 @@ pub const MutableValue = union(enum) { |
| 238 | } else { | 236 | } else { |
| 239 | const repeated_val = try arena.create(MutableValue); | 237 | const repeated_val = try arena.create(MutableValue); |
| 240 | repeated_val.* = .{ | 238 | repeated_val.* = .{ |
| 241 | .interned = try ip.get(gpa, .{ .undef = ip.childType(ty_ip) }), | 239 | .interned = try pt.intern(.{ .undef = ip.childType(ty_ip) }), |
| 242 | }; | 240 | }; |
| 243 | mv.* = .{ .repeated = .{ | 241 | mv.* = .{ .repeated = .{ |
| 244 | .ty = ty_ip, | 242 | .ty = ty_ip, |
| ... | @@ -248,11 +246,8 @@ pub const MutableValue = union(enum) { | ... | @@ -248,11 +246,8 @@ pub const MutableValue = union(enum) { |
| 248 | }, | 246 | }, |
| 249 | .Union => { | 247 | .Union => { |
| 250 | const payload = try arena.create(MutableValue); | 248 | const payload = try arena.create(MutableValue); |
| 251 | const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(zcu); | 249 | const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(pt); |
| 252 | payload.* = .{ .interned = try ip.get( | 250 | payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) }; |
| 253 | gpa, | ||
| 254 | .{ .undef = backing_ty.toIntern() }, | ||
| 255 | ) }; | ||
| 256 | mv.* = .{ .un = .{ | 251 | mv.* = .{ .un = .{ |
| 257 | .ty = ty_ip, | 252 | .ty = ty_ip, |
| 258 | .tag = .none, | 253 | .tag = .none, |
| ... | @@ -264,8 +259,8 @@ pub const MutableValue = union(enum) { | ... | @@ -264,8 +259,8 @@ pub const MutableValue = union(enum) { |
| 264 | if (ptr_ty.flags.size != .Slice) return; | 259 | if (ptr_ty.flags.size != .Slice) return; |
| 265 | const ptr = try arena.create(MutableValue); | 260 | const ptr = try arena.create(MutableValue); |
| 266 | const len = try arena.create(MutableValue); | 261 | const len = try arena.create(MutableValue); |
| 267 | ptr.* = .{ .interned = try ip.get(gpa, .{ .undef = ip.slicePtrType(ty_ip) }) }; | 262 | ptr.* = .{ .interned = try pt.intern(.{ .undef = ip.slicePtrType(ty_ip) }) }; |
| 268 | len.* = .{ .interned = try ip.get(gpa, .{ .undef = .usize_type }) }; | 263 | len.* = .{ .interned = try pt.intern(.{ .undef = .usize_type }) }; |
| 269 | mv.* = .{ .slice = .{ | 264 | mv.* = .{ .slice = .{ |
| 270 | .ty = ty_ip, | 265 | .ty = ty_ip, |
| 271 | .ptr = ptr, | 266 | .ptr = ptr, |
| ... | @@ -279,7 +274,7 @@ pub const MutableValue = union(enum) { | ... | @@ -279,7 +274,7 @@ pub const MutableValue = union(enum) { |
| 279 | .bytes => |bytes| if (!allow_bytes) { | 274 | .bytes => |bytes| if (!allow_bytes) { |
| 280 | const elems = try arena.alloc(MutableValue, bytes.data.len); | 275 | const elems = try arena.alloc(MutableValue, bytes.data.len); |
| 281 | for (bytes.data, elems) |byte, *interned_byte| { | 276 | for (bytes.data, elems) |byte, *interned_byte| { |
| 282 | interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{ | 277 | interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{ |
| 283 | .ty = .u8_type, | 278 | .ty = .u8_type, |
| 284 | .storage = .{ .u64 = byte }, | 279 | .storage = .{ .u64 = byte }, |
| 285 | } }) }; | 280 | } }) }; |
| ... | @@ -298,22 +293,22 @@ pub const MutableValue = union(enum) { | ... | @@ -298,22 +293,22 @@ pub const MutableValue = union(enum) { |
| 298 | /// The returned pointer is valid until the representation of `mv` changes. | 293 | /// The returned pointer is valid until the representation of `mv` changes. |
| 299 | pub fn elem( | 294 | pub fn elem( |
| 300 | mv: *MutableValue, | 295 | mv: *MutableValue, |
| 301 | zcu: *Zcu, | 296 | pt: Zcu.PerThread, |
| 302 | arena: Allocator, | 297 | arena: Allocator, |
| 303 | field_idx: usize, | 298 | field_idx: usize, |
| 304 | ) Allocator.Error!*MutableValue { | 299 | ) Allocator.Error!*MutableValue { |
| 300 | const zcu = pt.zcu; | ||
| 305 | const ip = &zcu.intern_pool; | 301 | const ip = &zcu.intern_pool; |
| 306 | const gpa = zcu.gpa; | ||
| 307 | // Convert to the `aggregate` representation. | 302 | // Convert to the `aggregate` representation. |
| 308 | switch (mv.*) { | 303 | switch (mv.*) { |
| 309 | .eu_payload, .opt_payload, .un => unreachable, | 304 | .eu_payload, .opt_payload, .un => unreachable, |
| 310 | .interned => { | 305 | .interned => { |
| 311 | try mv.unintern(zcu, arena, false, false); | 306 | try mv.unintern(pt, arena, false, false); |
| 312 | }, | 307 | }, |
| 313 | .bytes => |bytes| { | 308 | .bytes => |bytes| { |
| 314 | const elems = try arena.alloc(MutableValue, bytes.data.len); | 309 | const elems = try arena.alloc(MutableValue, bytes.data.len); |
| 315 | for (bytes.data, elems) |byte, *interned_byte| { | 310 | for (bytes.data, elems) |byte, *interned_byte| { |
| 316 | interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{ | 311 | interned_byte.* = .{ .interned = try pt.intern(.{ .int = .{ |
| 317 | .ty = .u8_type, | 312 | .ty = .u8_type, |
| 318 | .storage = .{ .u64 = byte }, | 313 | .storage = .{ .u64 = byte }, |
| 319 | } }) }; | 314 | } }) }; |
| ... | @@ -351,14 +346,15 @@ pub const MutableValue = union(enum) { | ... | @@ -351,14 +346,15 @@ pub const MutableValue = union(enum) { |
| 351 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. | 346 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. |
| 352 | pub fn setElem( | 347 | pub fn setElem( |
| 353 | mv: *MutableValue, | 348 | mv: *MutableValue, |
| 354 | zcu: *Zcu, | 349 | pt: Zcu.PerThread, |
| 355 | arena: Allocator, | 350 | arena: Allocator, |
| 356 | field_idx: usize, | 351 | field_idx: usize, |
| 357 | field_val: MutableValue, | 352 | field_val: MutableValue, |
| 358 | ) Allocator.Error!void { | 353 | ) Allocator.Error!void { |
| 354 | const zcu = pt.zcu; | ||
| 359 | const ip = &zcu.intern_pool; | 355 | const ip = &zcu.intern_pool; |
| 360 | const is_trivial_int = field_val.isTrivialInt(zcu); | 356 | const is_trivial_int = field_val.isTrivialInt(zcu); |
| 361 | try mv.unintern(zcu, arena, is_trivial_int, true); | 357 | try mv.unintern(pt, arena, is_trivial_int, true); |
| 362 | switch (mv.*) { | 358 | switch (mv.*) { |
| 363 | .interned, | 359 | .interned, |
| 364 | .eu_payload, | 360 | .eu_payload, |
| ... | @@ -373,7 +369,7 @@ pub const MutableValue = union(enum) { | ... | @@ -373,7 +369,7 @@ pub const MutableValue = union(enum) { |
| 373 | .bytes => |b| { | 369 | .bytes => |b| { |
| 374 | assert(is_trivial_int); | 370 | assert(is_trivial_int); |
| 375 | assert(field_val.typeOf(zcu).toIntern() == .u8_type); | 371 | assert(field_val.typeOf(zcu).toIntern() == .u8_type); |
| 376 | b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu)); | 372 | b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt)); |
| 377 | }, | 373 | }, |
| 378 | .repeated => |r| { | 374 | .repeated => |r| { |
| 379 | if (field_val.eqlTrivial(r.child.*)) return; | 375 | if (field_val.eqlTrivial(r.child.*)) return; |
| ... | @@ -386,9 +382,9 @@ pub const MutableValue = union(enum) { | ... | @@ -386,9 +382,9 @@ pub const MutableValue = union(enum) { |
| 386 | { | 382 | { |
| 387 | // We can use the `bytes` representation. | 383 | // We can use the `bytes` representation. |
| 388 | const bytes = try arena.alloc(u8, @intCast(len_inc_sent)); | 384 | const bytes = try arena.alloc(u8, @intCast(len_inc_sent)); |
| 389 | const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(zcu); | 385 | const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(pt); |
| 390 | @memset(bytes, @intCast(repeated_byte)); | 386 | @memset(bytes, @intCast(repeated_byte)); |
| 391 | bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu)); | 387 | bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt)); |
| 392 | mv.* = .{ .bytes = .{ | 388 | mv.* = .{ .bytes = .{ |
| 393 | .ty = r.ty, | 389 | .ty = r.ty, |
| 394 | .data = bytes, | 390 | .data = bytes, |
| ... | @@ -435,7 +431,7 @@ pub const MutableValue = union(enum) { | ... | @@ -435,7 +431,7 @@ pub const MutableValue = union(enum) { |
| 435 | } else { | 431 | } else { |
| 436 | const bytes = try arena.alloc(u8, a.elems.len); | 432 | const bytes = try arena.alloc(u8, a.elems.len); |
| 437 | for (a.elems, bytes) |elem_val, *b| { | 433 | for (a.elems, bytes) |elem_val, *b| { |
| 438 | b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(zcu)); | 434 | b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(pt)); |
| 439 | } | 435 | } |
| 440 | mv.* = .{ .bytes = .{ | 436 | mv.* = .{ .bytes = .{ |
| 441 | .ty = a.ty, | 437 | .ty = a.ty, |
| ... | @@ -451,7 +447,7 @@ pub const MutableValue = union(enum) { | ... | @@ -451,7 +447,7 @@ pub const MutableValue = union(enum) { |
| 451 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. | 447 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. |
| 452 | pub fn getElem( | 448 | pub fn getElem( |
| 453 | mv: MutableValue, | 449 | mv: MutableValue, |
| 454 | zcu: *Zcu, | 450 | pt: Zcu.PerThread, |
| 455 | field_idx: usize, | 451 | field_idx: usize, |
| 456 | ) Allocator.Error!MutableValue { | 452 | ) Allocator.Error!MutableValue { |
| 457 | return switch (mv) { | 453 | return switch (mv) { |
| ... | @@ -459,16 +455,16 @@ pub const MutableValue = union(enum) { | ... | @@ -459,16 +455,16 @@ pub const MutableValue = union(enum) { |
| 459 | .opt_payload, | 455 | .opt_payload, |
| 460 | => unreachable, | 456 | => unreachable, |
| 461 | .interned => |ip_index| { | 457 | .interned => |ip_index| { |
| 462 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(ip_index)); | 458 | const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(ip_index)); |
| 463 | switch (ty.zigTypeTag(zcu)) { | 459 | switch (ty.zigTypeTag(pt.zcu)) { |
| 464 | .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(zcu, field_idx)).toIntern() }, | 460 | .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(pt, field_idx)).toIntern() }, |
| 465 | .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(zcu, field_idx)).toIntern() }, | 461 | .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(pt, field_idx)).toIntern() }, |
| 466 | .Pointer => { | 462 | .Pointer => { |
| 467 | assert(ty.isSlice(zcu)); | 463 | assert(ty.isSlice(pt.zcu)); |
| 468 | return switch (field_idx) { | 464 | return switch (field_idx) { |
| 469 | Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(zcu).toIntern() }, | 465 | Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(pt.zcu).toIntern() }, |
| 470 | Value.slice_len_index => .{ .interned = switch (zcu.intern_pool.indexToKey(ip_index)) { | 466 | Value.slice_len_index => .{ .interned = switch (pt.zcu.intern_pool.indexToKey(ip_index)) { |
| 471 | .undef => try zcu.intern(.{ .undef = .usize_type }), | 467 | .undef => try pt.intern(.{ .undef = .usize_type }), |
| 472 | .slice => |s| s.len, | 468 | .slice => |s| s.len, |
| 473 | else => unreachable, | 469 | else => unreachable, |
| 474 | } }, | 470 | } }, |
| ... | @@ -487,7 +483,7 @@ pub const MutableValue = union(enum) { | ... | @@ -487,7 +483,7 @@ pub const MutableValue = union(enum) { |
| 487 | Value.slice_len_index => s.len.*, | 483 | Value.slice_len_index => s.len.*, |
| 488 | else => unreachable, | 484 | else => unreachable, |
| 489 | }, | 485 | }, |
| 490 | .bytes => |b| .{ .interned = try zcu.intern(.{ .int = .{ | 486 | .bytes => |b| .{ .interned = try pt.intern(.{ .int = .{ |
| 491 | .ty = .u8_type, | 487 | .ty = .u8_type, |
| 492 | .storage = .{ .u64 = b.data[field_idx] }, | 488 | .storage = .{ .u64 = b.data[field_idx] }, |
| 493 | } }) }, | 489 | } }) }, |
src/print_air.zig+19-19| ... | @@ -9,7 +9,7 @@ const Air = @import("Air.zig"); | ... | @@ -9,7 +9,7 @@ const Air = @import("Air.zig"); |
| 9 | const Liveness = @import("Liveness.zig"); | 9 | const Liveness = @import("Liveness.zig"); |
| 10 | const InternPool = @import("InternPool.zig"); | 10 | const InternPool = @import("InternPool.zig"); |
| 11 | 11 | ||
| 12 | pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void { | 12 | pub fn write(stream: anytype, pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void { |
| 13 | const instruction_bytes = air.instructions.len * | 13 | const instruction_bytes = air.instructions.len * |
| 14 | // Here we don't use @sizeOf(Air.Inst.Data) because it would include | 14 | // Here we don't use @sizeOf(Air.Inst.Data) because it would include |
| 15 | // the debug safety tag but we want to measure release size. | 15 | // the debug safety tag but we want to measure release size. |
| ... | @@ -42,8 +42,8 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void | ... | @@ -42,8 +42,8 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void |
| 42 | // zig fmt: on | 42 | // zig fmt: on |
| 43 | 43 | ||
| 44 | var writer: Writer = .{ | 44 | var writer: Writer = .{ |
| 45 | .module = module, | 45 | .pt = pt, |
| 46 | .gpa = module.gpa, | 46 | .gpa = pt.zcu.gpa, |
| 47 | .air = air, | 47 | .air = air, |
| 48 | .liveness = liveness, | 48 | .liveness = liveness, |
| 49 | .indent = 2, | 49 | .indent = 2, |
| ... | @@ -55,13 +55,13 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void | ... | @@ -55,13 +55,13 @@ pub fn write(stream: anytype, module: *Zcu, air: Air, liveness: ?Liveness) void |
| 55 | pub fn writeInst( | 55 | pub fn writeInst( |
| 56 | stream: anytype, | 56 | stream: anytype, |
| 57 | inst: Air.Inst.Index, | 57 | inst: Air.Inst.Index, |
| 58 | module: *Zcu, | 58 | pt: Zcu.PerThread, |
| 59 | air: Air, | 59 | air: Air, |
| 60 | liveness: ?Liveness, | 60 | liveness: ?Liveness, |
| 61 | ) void { | 61 | ) void { |
| 62 | var writer: Writer = .{ | 62 | var writer: Writer = .{ |
| 63 | .module = module, | 63 | .pt = pt, |
| 64 | .gpa = module.gpa, | 64 | .gpa = pt.zcu.gpa, |
| 65 | .air = air, | 65 | .air = air, |
| 66 | .liveness = liveness, | 66 | .liveness = liveness, |
| 67 | .indent = 2, | 67 | .indent = 2, |
| ... | @@ -70,16 +70,16 @@ pub fn writeInst( | ... | @@ -70,16 +70,16 @@ pub fn writeInst( |
| 70 | writer.writeInst(stream, inst) catch return; | 70 | writer.writeInst(stream, inst) catch return; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | pub fn dump(module: *Zcu, air: Air, liveness: ?Liveness) void { | 73 | pub fn dump(pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void { |
| 74 | write(std.io.getStdErr().writer(), module, air, liveness); | 74 | write(std.io.getStdErr().writer(), pt, air, liveness); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | pub fn dumpInst(inst: Air.Inst.Index, module: *Zcu, air: Air, liveness: ?Liveness) void { | 77 | pub fn dumpInst(inst: Air.Inst.Index, pt: Zcu.PerThread, air: Air, liveness: ?Liveness) void { |
| 78 | writeInst(std.io.getStdErr().writer(), inst, module, air, liveness); | 78 | writeInst(std.io.getStdErr().writer(), inst, pt, air, liveness); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | const Writer = struct { | 81 | const Writer = struct { |
| 82 | module: *Zcu, | 82 | pt: Zcu.PerThread, |
| 83 | gpa: Allocator, | 83 | gpa: Allocator, |
| 84 | air: Air, | 84 | air: Air, |
| 85 | liveness: ?Liveness, | 85 | liveness: ?Liveness, |
| ... | @@ -345,7 +345,7 @@ const Writer = struct { | ... | @@ -345,7 +345,7 @@ const Writer = struct { |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | fn writeType(w: *Writer, s: anytype, ty: Type) !void { | 347 | fn writeType(w: *Writer, s: anytype, ty: Type) !void { |
| 348 | return ty.print(s, w.module); | 348 | return ty.print(s, w.pt); |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 351 | fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| ... | @@ -424,7 +424,7 @@ const Writer = struct { | ... | @@ -424,7 +424,7 @@ const Writer = struct { |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 426 | fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 427 | const mod = w.module; | 427 | const mod = w.pt.zcu; |
| 428 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 428 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 429 | const vector_ty = ty_pl.ty.toType(); | 429 | const vector_ty = ty_pl.ty.toType(); |
| 430 | const len = @as(usize, @intCast(vector_ty.arrayLen(mod))); | 430 | const len = @as(usize, @intCast(vector_ty.arrayLen(mod))); |
| ... | @@ -504,7 +504,7 @@ const Writer = struct { | ... | @@ -504,7 +504,7 @@ const Writer = struct { |
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 506 | fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 507 | const mod = w.module; | 507 | const mod = w.pt.zcu; |
| 508 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 508 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 509 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; | 509 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; |
| 510 | 510 | ||
| ... | @@ -947,11 +947,11 @@ const Writer = struct { | ... | @@ -947,11 +947,11 @@ const Writer = struct { |
| 947 | if (@intFromEnum(operand) < InternPool.static_len) { | 947 | if (@intFromEnum(operand) < InternPool.static_len) { |
| 948 | return s.print("@{}", .{operand}); | 948 | return s.print("@{}", .{operand}); |
| 949 | } else if (operand.toInterned()) |ip_index| { | 949 | } else if (operand.toInterned()) |ip_index| { |
| 950 | const mod = w.module; | 950 | const pt = w.pt; |
| 951 | const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf()); | 951 | const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf()); |
| 952 | try s.print("<{}, {}>", .{ | 952 | try s.print("<{}, {}>", .{ |
| 953 | ty.fmt(mod), | 953 | ty.fmt(pt), |
| 954 | Value.fromInterned(ip_index).fmtValue(mod, null), | 954 | Value.fromInterned(ip_index).fmtValue(pt, null), |
| 955 | }); | 955 | }); |
| 956 | } else { | 956 | } else { |
| 957 | return w.writeInstIndex(s, operand.toIndex().?, dies); | 957 | return w.writeInstIndex(s, operand.toIndex().?, dies); |
| ... | @@ -970,7 +970,7 @@ const Writer = struct { | ... | @@ -970,7 +970,7 @@ const Writer = struct { |
| 970 | } | 970 | } |
| 971 | 971 | ||
| 972 | fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type { | 972 | fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type { |
| 973 | const mod = w.module; | 973 | const mod = w.pt.zcu; |
| 974 | return w.air.typeOfIndex(inst, &mod.intern_pool); | 974 | return w.air.typeOfIndex(inst, &mod.intern_pool); |
| 975 | } | 975 | } |
| 976 | }; | 976 | }; |
src/print_value.zig+53-52| ... | @@ -5,8 +5,6 @@ const std = @import("std"); | ... | @@ -5,8 +5,6 @@ const std = @import("std"); |
| 5 | const Type = @import("Type.zig"); | 5 | const Type = @import("Type.zig"); |
| 6 | const Value = @import("Value.zig"); | 6 | const Value = @import("Value.zig"); |
| 7 | const Zcu = @import("Zcu.zig"); | 7 | const Zcu = @import("Zcu.zig"); |
| 8 | /// Deprecated. | ||
| 9 | const Module = Zcu; | ||
| 10 | const Sema = @import("Sema.zig"); | 8 | const Sema = @import("Sema.zig"); |
| 11 | const InternPool = @import("InternPool.zig"); | 9 | const InternPool = @import("InternPool.zig"); |
| 12 | const Allocator = std.mem.Allocator; | 10 | const Allocator = std.mem.Allocator; |
| ... | @@ -17,7 +15,7 @@ const max_string_len = 256; | ... | @@ -17,7 +15,7 @@ const max_string_len = 256; |
| 17 | 15 | ||
| 18 | pub const FormatContext = struct { | 16 | pub const FormatContext = struct { |
| 19 | val: Value, | 17 | val: Value, |
| 20 | mod: *Module, | 18 | pt: Zcu.PerThread, |
| 21 | opt_sema: ?*Sema, | 19 | opt_sema: ?*Sema, |
| 22 | depth: u8, | 20 | depth: u8, |
| 23 | }; | 21 | }; |
| ... | @@ -30,7 +28,7 @@ pub fn format( | ... | @@ -30,7 +28,7 @@ pub fn format( |
| 30 | ) !void { | 28 | ) !void { |
| 31 | _ = options; | 29 | _ = options; |
| 32 | comptime std.debug.assert(fmt.len == 0); | 30 | comptime std.debug.assert(fmt.len == 0); |
| 33 | return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_sema) catch |err| switch (err) { | 31 | return print(ctx.val, writer, ctx.depth, ctx.pt, ctx.opt_sema) catch |err| switch (err) { |
| 34 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function | 32 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function |
| 35 | error.ComptimeBreak, error.ComptimeReturn => unreachable, | 33 | error.ComptimeBreak, error.ComptimeReturn => unreachable, |
| 36 | error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully | 34 | error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully |
| ... | @@ -42,10 +40,11 @@ pub fn print( | ... | @@ -42,10 +40,11 @@ pub fn print( |
| 42 | val: Value, | 40 | val: Value, |
| 43 | writer: anytype, | 41 | writer: anytype, |
| 44 | level: u8, | 42 | level: u8, |
| 45 | mod: *Module, | 43 | pt: Zcu.PerThread, |
| 46 | /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output. | 44 | /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output. |
| 47 | opt_sema: ?*Sema, | 45 | opt_sema: ?*Sema, |
| 48 | ) (@TypeOf(writer).Error || Module.CompileError)!void { | 46 | ) (@TypeOf(writer).Error || Zcu.CompileError)!void { |
| 47 | const mod = pt.zcu; | ||
| 49 | const ip = &mod.intern_pool; | 48 | const ip = &mod.intern_pool; |
| 50 | switch (ip.indexToKey(val.toIntern())) { | 49 | switch (ip.indexToKey(val.toIntern())) { |
| 51 | .int_type, | 50 | .int_type, |
| ... | @@ -64,7 +63,7 @@ pub fn print( | ... | @@ -64,7 +63,7 @@ pub fn print( |
| 64 | .func_type, | 63 | .func_type, |
| 65 | .error_set_type, | 64 | .error_set_type, |
| 66 | .inferred_error_set_type, | 65 | .inferred_error_set_type, |
| 67 | => try Type.print(val.toType(), writer, mod), | 66 | => try Type.print(val.toType(), writer, pt), |
| 68 | .undef => try writer.writeAll("undefined"), | 67 | .undef => try writer.writeAll("undefined"), |
| 69 | .simple_value => |simple_value| switch (simple_value) { | 68 | .simple_value => |simple_value| switch (simple_value) { |
| 70 | .void => try writer.writeAll("{}"), | 69 | .void => try writer.writeAll("{}"), |
| ... | @@ -82,13 +81,13 @@ pub fn print( | ... | @@ -82,13 +81,13 @@ pub fn print( |
| 82 | .int => |int| switch (int.storage) { | 81 | .int => |int| switch (int.storage) { |
| 83 | inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), | 82 | inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), |
| 84 | .lazy_align => |ty| if (opt_sema != null) { | 83 | .lazy_align => |ty| if (opt_sema != null) { |
| 85 | const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .sema)).scalar; | 84 | const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar; |
| 86 | try writer.print("{}", .{a.toByteUnits() orelse 0}); | 85 | try writer.print("{}", .{a.toByteUnits() orelse 0}); |
| 87 | } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}), | 86 | } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}), |
| 88 | .lazy_size => |ty| if (opt_sema != null) { | 87 | .lazy_size => |ty| if (opt_sema != null) { |
| 89 | const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .sema)).scalar; | 88 | const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar; |
| 90 | try writer.print("{}", .{s}); | 89 | try writer.print("{}", .{s}); |
| 91 | } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}), | 90 | } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}), |
| 92 | }, | 91 | }, |
| 93 | .err => |err| try writer.print("error.{}", .{ | 92 | .err => |err| try writer.print("error.{}", .{ |
| 94 | err.name.fmt(ip), | 93 | err.name.fmt(ip), |
| ... | @@ -97,7 +96,7 @@ pub fn print( | ... | @@ -97,7 +96,7 @@ pub fn print( |
| 97 | .err_name => |err_name| try writer.print("error.{}", .{ | 96 | .err_name => |err_name| try writer.print("error.{}", .{ |
| 98 | err_name.fmt(ip), | 97 | err_name.fmt(ip), |
| 99 | }), | 98 | }), |
| 100 | .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema), | 99 | .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), |
| 101 | }, | 100 | }, |
| 102 | .enum_literal => |enum_literal| try writer.print(".{}", .{ | 101 | .enum_literal => |enum_literal| try writer.print(".{}", .{ |
| 103 | enum_literal.fmt(ip), | 102 | enum_literal.fmt(ip), |
| ... | @@ -111,7 +110,7 @@ pub fn print( | ... | @@ -111,7 +110,7 @@ pub fn print( |
| 111 | return writer.writeAll("@enumFromInt(...)"); | 110 | return writer.writeAll("@enumFromInt(...)"); |
| 112 | } | 111 | } |
| 113 | try writer.writeAll("@enumFromInt("); | 112 | try writer.writeAll("@enumFromInt("); |
| 114 | try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema); | 113 | try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema); |
| 115 | try writer.writeAll(")"); | 114 | try writer.writeAll(")"); |
| 116 | }, | 115 | }, |
| 117 | .empty_enum_value => try writer.writeAll("(empty enum value)"), | 116 | .empty_enum_value => try writer.writeAll("(empty enum value)"), |
| ... | @@ -128,12 +127,12 @@ pub fn print( | ... | @@ -128,12 +127,12 @@ pub fn print( |
| 128 | // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's | 127 | // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's |
| 129 | // currently not possible without e.g. triggering compile errors. | 128 | // currently not possible without e.g. triggering compile errors. |
| 130 | } | 129 | } |
| 131 | try printPtr(Value.fromInterned(slice.ptr), writer, level, mod, opt_sema); | 130 | try printPtr(Value.fromInterned(slice.ptr), writer, level, pt, opt_sema); |
| 132 | try writer.writeAll("[0.."); | 131 | try writer.writeAll("[0.."); |
| 133 | if (level == 0) { | 132 | if (level == 0) { |
| 134 | try writer.writeAll("(...)"); | 133 | try writer.writeAll("(...)"); |
| 135 | } else { | 134 | } else { |
| 136 | try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema); | 135 | try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema); |
| 137 | } | 136 | } |
| 138 | try writer.writeAll("]"); | 137 | try writer.writeAll("]"); |
| 139 | }, | 138 | }, |
| ... | @@ -147,28 +146,28 @@ pub fn print( | ... | @@ -147,28 +146,28 @@ pub fn print( |
| 147 | // TODO: eventually we want to load the pointer with `opt_sema`, but that's | 146 | // TODO: eventually we want to load the pointer with `opt_sema`, but that's |
| 148 | // currently not possible without e.g. triggering compile errors. | 147 | // currently not possible without e.g. triggering compile errors. |
| 149 | } | 148 | } |
| 150 | try printPtr(val, writer, level, mod, opt_sema); | 149 | try printPtr(val, writer, level, pt, opt_sema); |
| 151 | }, | 150 | }, |
| 152 | .opt => |opt| switch (opt.val) { | 151 | .opt => |opt| switch (opt.val) { |
| 153 | .none => try writer.writeAll("null"), | 152 | .none => try writer.writeAll("null"), |
| 154 | else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema), | 153 | else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema), |
| 155 | }, | 154 | }, |
| 156 | .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, mod, opt_sema), | 155 | .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema), |
| 157 | .un => |un| { | 156 | .un => |un| { |
| 158 | if (level == 0) { | 157 | if (level == 0) { |
| 159 | try writer.writeAll(".{ ... }"); | 158 | try writer.writeAll(".{ ... }"); |
| 160 | return; | 159 | return; |
| 161 | } | 160 | } |
| 162 | if (un.tag == .none) { | 161 | if (un.tag == .none) { |
| 163 | const backing_ty = try val.typeOf(mod).unionBackingType(mod); | 162 | const backing_ty = try val.typeOf(mod).unionBackingType(pt); |
| 164 | try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)}); | 163 | try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(pt)}); |
| 165 | try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema); | 164 | try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); |
| 166 | try writer.writeAll("))"); | 165 | try writer.writeAll("))"); |
| 167 | } else { | 166 | } else { |
| 168 | try writer.writeAll(".{ "); | 167 | try writer.writeAll(".{ "); |
| 169 | try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema); | 168 | try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema); |
| 170 | try writer.writeAll(" = "); | 169 | try writer.writeAll(" = "); |
| 171 | try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema); | 170 | try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema); |
| 172 | try writer.writeAll(" }"); | 171 | try writer.writeAll(" }"); |
| 173 | } | 172 | } |
| 174 | }, | 173 | }, |
| ... | @@ -182,13 +181,14 @@ fn printAggregate( | ... | @@ -182,13 +181,14 @@ fn printAggregate( |
| 182 | is_ref: bool, | 181 | is_ref: bool, |
| 183 | writer: anytype, | 182 | writer: anytype, |
| 184 | level: u8, | 183 | level: u8, |
| 185 | zcu: *Zcu, | 184 | pt: Zcu.PerThread, |
| 186 | opt_sema: ?*Sema, | 185 | opt_sema: ?*Sema, |
| 187 | ) (@TypeOf(writer).Error || Module.CompileError)!void { | 186 | ) (@TypeOf(writer).Error || Zcu.CompileError)!void { |
| 188 | if (level == 0) { | 187 | if (level == 0) { |
| 189 | if (is_ref) try writer.writeByte('&'); | 188 | if (is_ref) try writer.writeByte('&'); |
| 190 | return writer.writeAll(".{ ... }"); | 189 | return writer.writeAll(".{ ... }"); |
| 191 | } | 190 | } |
| 191 | const zcu = pt.zcu; | ||
| 192 | const ip = &zcu.intern_pool; | 192 | const ip = &zcu.intern_pool; |
| 193 | const ty = Type.fromInterned(aggregate.ty); | 193 | const ty = Type.fromInterned(aggregate.ty); |
| 194 | switch (ty.zigTypeTag(zcu)) { | 194 | switch (ty.zigTypeTag(zcu)) { |
| ... | @@ -203,7 +203,7 @@ fn printAggregate( | ... | @@ -203,7 +203,7 @@ fn printAggregate( |
| 203 | if (i != 0) try writer.writeAll(", "); | 203 | if (i != 0) try writer.writeAll(", "); |
| 204 | const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; | 204 | const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; |
| 205 | try writer.print(".{i} = ", .{field_name.fmt(ip)}); | 205 | try writer.print(".{i} = ", .{field_name.fmt(ip)}); |
| 206 | try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema); | 206 | try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema); |
| 207 | } | 207 | } |
| 208 | try writer.writeAll(" }"); | 208 | try writer.writeAll(" }"); |
| 209 | return; | 209 | return; |
| ... | @@ -230,7 +230,7 @@ fn printAggregate( | ... | @@ -230,7 +230,7 @@ fn printAggregate( |
| 230 | if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str; | 230 | if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str; |
| 231 | const elem_val = Value.fromInterned(aggregate.storage.values()[0]); | 231 | const elem_val = Value.fromInterned(aggregate.storage.values()[0]); |
| 232 | if (elem_val.isUndef(zcu)) break :one_byte_str; | 232 | if (elem_val.isUndef(zcu)) break :one_byte_str; |
| 233 | const byte = elem_val.toUnsignedInt(zcu); | 233 | const byte = elem_val.toUnsignedInt(pt); |
| 234 | try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})}); | 234 | try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})}); |
| 235 | if (!is_ref) try writer.writeAll(".*"); | 235 | if (!is_ref) try writer.writeAll(".*"); |
| 236 | return; | 236 | return; |
| ... | @@ -253,7 +253,7 @@ fn printAggregate( | ... | @@ -253,7 +253,7 @@ fn printAggregate( |
| 253 | const max_len = @min(len, max_aggregate_items); | 253 | const max_len = @min(len, max_aggregate_items); |
| 254 | for (0..max_len) |i| { | 254 | for (0..max_len) |i| { |
| 255 | if (i != 0) try writer.writeAll(", "); | 255 | if (i != 0) try writer.writeAll(", "); |
| 256 | try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema); | 256 | try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema); |
| 257 | } | 257 | } |
| 258 | if (len > max_aggregate_items) { | 258 | if (len > max_aggregate_items) { |
| 259 | try writer.writeAll(", ..."); | 259 | try writer.writeAll(", ..."); |
| ... | @@ -261,8 +261,8 @@ fn printAggregate( | ... | @@ -261,8 +261,8 @@ fn printAggregate( |
| 261 | return writer.writeAll(" }"); | 261 | return writer.writeAll(" }"); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*Sema) (@TypeOf(writer).Error || Module.CompileError)!void { | 264 | fn printPtr(ptr_val: Value, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void { |
| 265 | const ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) { | 265 | const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) { |
| 266 | .undef => return writer.writeAll("undefined"), | 266 | .undef => return writer.writeAll("undefined"), |
| 267 | .ptr => |ptr| ptr, | 267 | .ptr => |ptr| ptr, |
| 268 | else => unreachable, | 268 | else => unreachable, |
| ... | @@ -270,32 +270,33 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*S | ... | @@ -270,32 +270,33 @@ fn printPtr(ptr_val: Value, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*S |
| 270 | 270 | ||
| 271 | if (ptr.base_addr == .anon_decl) { | 271 | if (ptr.base_addr == .anon_decl) { |
| 272 | // If the value is an aggregate, we can potentially print it more nicely. | 272 | // If the value is an aggregate, we can potentially print it more nicely. |
| 273 | switch (zcu.intern_pool.indexToKey(ptr.base_addr.anon_decl.val)) { | 273 | switch (pt.zcu.intern_pool.indexToKey(ptr.base_addr.anon_decl.val)) { |
| 274 | .aggregate => |agg| return printAggregate( | 274 | .aggregate => |agg| return printAggregate( |
| 275 | Value.fromInterned(ptr.base_addr.anon_decl.val), | 275 | Value.fromInterned(ptr.base_addr.anon_decl.val), |
| 276 | agg, | 276 | agg, |
| 277 | true, | 277 | true, |
| 278 | writer, | 278 | writer, |
| 279 | level, | 279 | level, |
| 280 | zcu, | 280 | pt, |
| 281 | opt_sema, | 281 | opt_sema, |
| 282 | ), | 282 | ), |
| 283 | else => {}, | 283 | else => {}, |
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | var arena = std.heap.ArenaAllocator.init(zcu.gpa); | 287 | var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa); |
| 288 | defer arena.deinit(); | 288 | defer arena.deinit(); |
| 289 | const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), zcu, opt_sema); | 289 | const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, opt_sema); |
| 290 | try printPtrDerivation(derivation, writer, level, zcu, opt_sema); | 290 | try printPtrDerivation(derivation, writer, level, pt, opt_sema); |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | /// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value. | 293 | /// Print `derivation` as an lvalue, i.e. such that writing `&` before this gives the pointer value. |
| 294 | fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, zcu: *Zcu, opt_sema: ?*Sema) (@TypeOf(writer).Error || Module.CompileError)!void { | 294 | fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, level: u8, pt: Zcu.PerThread, opt_sema: ?*Sema) (@TypeOf(writer).Error || Zcu.CompileError)!void { |
| 295 | const zcu = pt.zcu; | ||
| 295 | const ip = &zcu.intern_pool; | 296 | const ip = &zcu.intern_pool; |
| 296 | switch (derivation) { | 297 | switch (derivation) { |
| 297 | .int => |int| try writer.print("@as({}, @ptrFromInt({x})).*", .{ | 298 | .int => |int| try writer.print("@as({}, @ptrFromInt({x})).*", .{ |
| 298 | int.ptr_ty.fmt(zcu), | 299 | int.ptr_ty.fmt(pt), |
| 299 | int.addr, | 300 | int.addr, |
| 300 | }), | 301 | }), |
| 301 | .decl_ptr => |decl| { | 302 | .decl_ptr => |decl| { |
| ... | @@ -303,33 +304,33 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve | ... | @@ -303,33 +304,33 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve |
| 303 | }, | 304 | }, |
| 304 | .anon_decl_ptr => |anon| { | 305 | .anon_decl_ptr => |anon| { |
| 305 | const ty = Value.fromInterned(anon.val).typeOf(zcu); | 306 | const ty = Value.fromInterned(anon.val).typeOf(zcu); |
| 306 | try writer.print("@as({}, ", .{ty.fmt(zcu)}); | 307 | try writer.print("@as({}, ", .{ty.fmt(pt)}); |
| 307 | try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema); | 308 | try print(Value.fromInterned(anon.val), writer, level - 1, pt, opt_sema); |
| 308 | try writer.writeByte(')'); | 309 | try writer.writeByte(')'); |
| 309 | }, | 310 | }, |
| 310 | .comptime_alloc_ptr => |info| { | 311 | .comptime_alloc_ptr => |info| { |
| 311 | try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(zcu)}); | 312 | try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)}); |
| 312 | try print(info.val, writer, level - 1, zcu, opt_sema); | 313 | try print(info.val, writer, level - 1, pt, opt_sema); |
| 313 | try writer.writeByte(')'); | 314 | try writer.writeByte(')'); |
| 314 | }, | 315 | }, |
| 315 | .comptime_field_ptr => |val| { | 316 | .comptime_field_ptr => |val| { |
| 316 | const ty = val.typeOf(zcu); | 317 | const ty = val.typeOf(zcu); |
| 317 | try writer.print("@as({}, ", .{ty.fmt(zcu)}); | 318 | try writer.print("@as({}, ", .{ty.fmt(pt)}); |
| 318 | try print(val, writer, level - 1, zcu, opt_sema); | 319 | try print(val, writer, level - 1, pt, opt_sema); |
| 319 | try writer.writeByte(')'); | 320 | try writer.writeByte(')'); |
| 320 | }, | 321 | }, |
| 321 | .eu_payload_ptr => |info| { | 322 | .eu_payload_ptr => |info| { |
| 322 | try writer.writeByte('('); | 323 | try writer.writeByte('('); |
| 323 | try printPtrDerivation(info.parent.*, writer, level, zcu, opt_sema); | 324 | try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema); |
| 324 | try writer.writeAll(" catch unreachable)"); | 325 | try writer.writeAll(" catch unreachable)"); |
| 325 | }, | 326 | }, |
| 326 | .opt_payload_ptr => |info| { | 327 | .opt_payload_ptr => |info| { |
| 327 | try printPtrDerivation(info.parent.*, writer, level, zcu, opt_sema); | 328 | try printPtrDerivation(info.parent.*, writer, level, pt, opt_sema); |
| 328 | try writer.writeAll(".?"); | 329 | try writer.writeAll(".?"); |
| 329 | }, | 330 | }, |
| 330 | .field_ptr => |field| { | 331 | .field_ptr => |field| { |
| 331 | try printPtrDerivation(field.parent.*, writer, level, zcu, opt_sema); | 332 | try printPtrDerivation(field.parent.*, writer, level, pt, opt_sema); |
| 332 | const agg_ty = (try field.parent.ptrType(zcu)).childType(zcu); | 333 | const agg_ty = (try field.parent.ptrType(pt)).childType(zcu); |
| 333 | switch (agg_ty.zigTypeTag(zcu)) { | 334 | switch (agg_ty.zigTypeTag(zcu)) { |
| 334 | .Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| { | 335 | .Struct => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| { |
| 335 | try writer.print(".{i}", .{field_name.fmt(ip)}); | 336 | try writer.print(".{i}", .{field_name.fmt(ip)}); |
| ... | @@ -350,16 +351,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve | ... | @@ -350,16 +351,16 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve |
| 350 | } | 351 | } |
| 351 | }, | 352 | }, |
| 352 | .elem_ptr => |elem| { | 353 | .elem_ptr => |elem| { |
| 353 | try printPtrDerivation(elem.parent.*, writer, level, zcu, opt_sema); | 354 | try printPtrDerivation(elem.parent.*, writer, level, pt, opt_sema); |
| 354 | try writer.print("[{d}]", .{elem.elem_idx}); | 355 | try writer.print("[{d}]", .{elem.elem_idx}); |
| 355 | }, | 356 | }, |
| 356 | .offset_and_cast => |oac| if (oac.byte_offset == 0) { | 357 | .offset_and_cast => |oac| if (oac.byte_offset == 0) { |
| 357 | try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(zcu)}); | 358 | try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)}); |
| 358 | try printPtrDerivation(oac.parent.*, writer, level, zcu, opt_sema); | 359 | try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema); |
| 359 | try writer.writeAll("))"); | 360 | try writer.writeAll("))"); |
| 360 | } else { | 361 | } else { |
| 361 | try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(zcu)}); | 362 | try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)}); |
| 362 | try printPtrDerivation(oac.parent.*, writer, level, zcu, opt_sema); | 363 | try printPtrDerivation(oac.parent.*, writer, level, pt, opt_sema); |
| 363 | try writer.print(") + {d}))", .{oac.byte_offset}); | 364 | try writer.print(") + {d}))", .{oac.byte_offset}); |
| 364 | }, | 365 | }, |
| 365 | } | 366 | } |
src/print_zir.zig+4-5| ... | @@ -7,13 +7,12 @@ const InternPool = @import("InternPool.zig"); | ... | @@ -7,13 +7,12 @@ const InternPool = @import("InternPool.zig"); |
| 7 | 7 | ||
| 8 | const Zir = std.zig.Zir; | 8 | const Zir = std.zig.Zir; |
| 9 | const Zcu = @import("Zcu.zig"); | 9 | const Zcu = @import("Zcu.zig"); |
| 10 | const Module = Zcu; | ||
| 11 | const LazySrcLoc = Zcu.LazySrcLoc; | 10 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 12 | 11 | ||
| 13 | /// Write human-readable, debug formatted ZIR code to a file. | 12 | /// Write human-readable, debug formatted ZIR code to a file. |
| 14 | pub fn renderAsTextToFile( | 13 | pub fn renderAsTextToFile( |
| 15 | gpa: Allocator, | 14 | gpa: Allocator, |
| 16 | scope_file: *Module.File, | 15 | scope_file: *Zcu.File, |
| 17 | fs_file: std.fs.File, | 16 | fs_file: std.fs.File, |
| 18 | ) !void { | 17 | ) !void { |
| 19 | var arena = std.heap.ArenaAllocator.init(gpa); | 18 | var arena = std.heap.ArenaAllocator.init(gpa); |
| ... | @@ -64,7 +63,7 @@ pub fn renderInstructionContext( | ... | @@ -64,7 +63,7 @@ pub fn renderInstructionContext( |
| 64 | gpa: Allocator, | 63 | gpa: Allocator, |
| 65 | block: []const Zir.Inst.Index, | 64 | block: []const Zir.Inst.Index, |
| 66 | block_index: usize, | 65 | block_index: usize, |
| 67 | scope_file: *Module.File, | 66 | scope_file: *Zcu.File, |
| 68 | parent_decl_node: Ast.Node.Index, | 67 | parent_decl_node: Ast.Node.Index, |
| 69 | indent: u32, | 68 | indent: u32, |
| 70 | stream: anytype, | 69 | stream: anytype, |
| ... | @@ -96,7 +95,7 @@ pub fn renderInstructionContext( | ... | @@ -96,7 +95,7 @@ pub fn renderInstructionContext( |
| 96 | pub fn renderSingleInstruction( | 95 | pub fn renderSingleInstruction( |
| 97 | gpa: Allocator, | 96 | gpa: Allocator, |
| 98 | inst: Zir.Inst.Index, | 97 | inst: Zir.Inst.Index, |
| 99 | scope_file: *Module.File, | 98 | scope_file: *Zcu.File, |
| 100 | parent_decl_node: Ast.Node.Index, | 99 | parent_decl_node: Ast.Node.Index, |
| 101 | indent: u32, | 100 | indent: u32, |
| 102 | stream: anytype, | 101 | stream: anytype, |
| ... | @@ -122,7 +121,7 @@ pub fn renderSingleInstruction( | ... | @@ -122,7 +121,7 @@ pub fn renderSingleInstruction( |
| 122 | const Writer = struct { | 121 | const Writer = struct { |
| 123 | gpa: Allocator, | 122 | gpa: Allocator, |
| 124 | arena: Allocator, | 123 | arena: Allocator, |
| 125 | file: *Module.File, | 124 | file: *Zcu.File, |
| 126 | code: Zir, | 125 | code: Zir, |
| 127 | indent: u32, | 126 | indent: u32, |
| 128 | parent_decl_node: Ast.Node.Index, | 127 | parent_decl_node: Ast.Node.Index, |
src/register_manager.zig-2| ... | @@ -7,8 +7,6 @@ const Air = @import("Air.zig"); | ... | @@ -7,8 +7,6 @@ const Air = @import("Air.zig"); |
| 7 | const StaticBitSet = std.bit_set.StaticBitSet; | 7 | const StaticBitSet = std.bit_set.StaticBitSet; |
| 8 | const Type = @import("Type.zig"); | 8 | const Type = @import("Type.zig"); |
| 9 | const Zcu = @import("Zcu.zig"); | 9 | const Zcu = @import("Zcu.zig"); |
| 10 | /// Deprecated. | ||
| 11 | const Module = Zcu; | ||
| 12 | const expect = std.testing.expect; | 10 | const expect = std.testing.expect; |
| 13 | const expectEqual = std.testing.expectEqual; | 11 | const expectEqual = std.testing.expectEqual; |
| 14 | const expectEqualSlices = std.testing.expectEqualSlices; | 12 | const expectEqualSlices = std.testing.expectEqualSlices; |