| author | |
| committer | |
| log | 9afa97418350a51d8e27f1df903d8034507254ce |
| tree | 5ac1ff91beb66d9184a4cf1ab8485289e553f187 |
| parent | 9a738c0be54c9bda0e57de9da84f86fc73bd5198 |
7 files changed, 228 insertions(+), 115 deletions(-)
src/InternPool.zig+34-23| ... | ... | @@ -2298,7 +2298,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 2298 | 2298 | ip.* = undefined; |
| 2299 | 2299 | } |
| 2300 | 2300 | |
| 2301 | pub fn indexToKey(ip: InternPool, index: Index) Key { | |
| 2301 | pub fn indexToKey(ip: *const InternPool, index: Index) Key { | |
| 2302 | 2302 | assert(index != .none); |
| 2303 | 2303 | const item = ip.items.get(@enumToInt(index)); |
| 2304 | 2304 | const data = item.data; |
| ... | ... | @@ -2361,7 +2361,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2361 | 2361 | |
| 2362 | 2362 | .type_slice => { |
| 2363 | 2363 | const ptr_type_index = @intToEnum(Index, data); |
| 2364 | var result = indexToKey(ip, ptr_type_index).ptr_type; | |
| 2364 | var result = ip.indexToKey(ptr_type_index).ptr_type; | |
| 2365 | 2365 | result.size = .Slice; |
| 2366 | 2366 | return .{ .ptr_type = result }; |
| 2367 | 2367 | }, |
| ... | ... | @@ -2454,9 +2454,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2454 | 2454 | .values_map = .none, |
| 2455 | 2455 | } }; |
| 2456 | 2456 | }, |
| 2457 | .type_enum_explicit => indexToKeyEnum(ip, data, .explicit), | |
| 2458 | .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive), | |
| 2459 | .type_function => .{ .func_type = indexToKeyFuncType(ip, data) }, | |
| 2457 | .type_enum_explicit => ip.indexToKeyEnum(data, .explicit), | |
| 2458 | .type_enum_nonexhaustive => ip.indexToKeyEnum(data, .nonexhaustive), | |
| 2459 | .type_function => .{ .func_type = ip.indexToKeyFuncType(data) }, | |
| 2460 | 2460 | |
| 2461 | 2461 | .undef => .{ .undef = @intToEnum(Index, data) }, |
| 2462 | 2462 | .runtime_value => { |
| ... | ... | @@ -2591,8 +2591,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2591 | 2591 | .ty = .comptime_int_type, |
| 2592 | 2592 | .storage = .{ .i64 = @bitCast(i32, data) }, |
| 2593 | 2593 | } }, |
| 2594 | .int_positive => indexToKeyBigInt(ip, data, true), | |
| 2595 | .int_negative => indexToKeyBigInt(ip, data, false), | |
| 2594 | .int_positive => ip.indexToKeyBigInt(data, true), | |
| 2595 | .int_negative => ip.indexToKeyBigInt(data, false), | |
| 2596 | 2596 | .int_small => { |
| 2597 | 2597 | const info = ip.extraData(IntSmall, data); |
| 2598 | 2598 | return .{ .int = .{ |
| ... | ... | @@ -3430,22 +3430,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3430 | 3430 | .data = try ip.addExtra(gpa, err), |
| 3431 | 3431 | }), |
| 3432 | 3432 | |
| 3433 | .error_union => |error_union| ip.items.appendAssumeCapacity(switch (error_union.val) { | |
| 3434 | .err_name => |err_name| .{ | |
| 3435 | .tag = .error_union_error, | |
| 3436 | .data = try ip.addExtra(gpa, Key.Error{ | |
| 3437 | .ty = error_union.ty, | |
| 3438 | .name = err_name, | |
| 3439 | }), | |
| 3440 | }, | |
| 3441 | .payload => |payload| .{ | |
| 3442 | .tag = .error_union_payload, | |
| 3443 | .data = try ip.addExtra(gpa, TypeValue{ | |
| 3444 | .ty = error_union.ty, | |
| 3445 | .val = payload, | |
| 3446 | }), | |
| 3447 | }, | |
| 3448 | }), | |
| 3433 | .error_union => |error_union| { | |
| 3434 | assert(ip.indexToKey(error_union.ty) == .error_union_type); | |
| 3435 | ip.items.appendAssumeCapacity(switch (error_union.val) { | |
| 3436 | .err_name => |err_name| .{ | |
| 3437 | .tag = .error_union_error, | |
| 3438 | .data = try ip.addExtra(gpa, Key.Error{ | |
| 3439 | .ty = error_union.ty, | |
| 3440 | .name = err_name, | |
| 3441 | }), | |
| 3442 | }, | |
| 3443 | .payload => |payload| .{ | |
| 3444 | .tag = .error_union_payload, | |
| 3445 | .data = try ip.addExtra(gpa, TypeValue{ | |
| 3446 | .ty = error_union.ty, | |
| 3447 | .val = payload, | |
| 3448 | }), | |
| 3449 | }, | |
| 3450 | }); | |
| 3451 | }, | |
| 3449 | 3452 | |
| 3450 | 3453 | .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{ |
| 3451 | 3454 | .tag = .enum_literal, |
| ... | ... | @@ -4191,6 +4194,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index { |
| 4191 | 4194 | /// * ptr <=> ptr |
| 4192 | 4195 | /// * null_value => opt |
| 4193 | 4196 | /// * payload => opt |
| 4197 | /// * error set <=> error set | |
| 4194 | 4198 | pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { |
| 4195 | 4199 | const old_ty = ip.typeOf(val); |
| 4196 | 4200 | if (old_ty == new_ty) return val; |
| ... | ... | @@ -4230,6 +4234,13 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 4230 | 4234 | } }), |
| 4231 | 4235 | else => {}, |
| 4232 | 4236 | }, |
| 4237 | .err => |err| switch (ip.indexToKey(new_ty)) { | |
| 4238 | .error_set_type, .inferred_error_set_type => return ip.get(gpa, .{ .err = .{ | |
| 4239 | .ty = new_ty, | |
| 4240 | .name = err.name, | |
| 4241 | } }), | |
| 4242 | else => {}, | |
| 4243 | }, | |
| 4233 | 4244 | else => {}, |
| 4234 | 4245 | } |
| 4235 | 4246 | switch (ip.indexToKey(new_ty)) { |
src/Liveness/Verify.zig+36-32| ... | ... | @@ -61,10 +61,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 61 | 61 | .work_item_id, |
| 62 | 62 | .work_group_size, |
| 63 | 63 | .work_group_id, |
| 64 | => try self.verifyInst(inst, .{ .none, .none, .none }), | |
| 64 | => try self.verifyInstOperands(inst, .{ .none, .none, .none }), | |
| 65 | 65 | |
| 66 | 66 | .trap, .unreach => { |
| 67 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 67 | try self.verifyInstOperands(inst, .{ .none, .none, .none }); | |
| 68 | 68 | // This instruction terminates the function, so everything should be dead |
| 69 | 69 | if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst}); |
| 70 | 70 | }, |
| ... | ... | @@ -113,7 +113,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 113 | 113 | .c_va_copy, |
| 114 | 114 | => { |
| 115 | 115 | const ty_op = data[inst].ty_op; |
| 116 | try self.verifyInst(inst, .{ ty_op.operand, .none, .none }); | |
| 116 | try self.verifyInstOperands(inst, .{ ty_op.operand, .none, .none }); | |
| 117 | 117 | }, |
| 118 | 118 | .is_null, |
| 119 | 119 | .is_non_null, |
| ... | ... | @@ -149,13 +149,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 149 | 149 | .c_va_end, |
| 150 | 150 | => { |
| 151 | 151 | const un_op = data[inst].un_op; |
| 152 | try self.verifyInst(inst, .{ un_op, .none, .none }); | |
| 152 | try self.verifyInstOperands(inst, .{ un_op, .none, .none }); | |
| 153 | 153 | }, |
| 154 | 154 | .ret, |
| 155 | 155 | .ret_load, |
| 156 | 156 | => { |
| 157 | 157 | const un_op = data[inst].un_op; |
| 158 | try self.verifyInst(inst, .{ un_op, .none, .none }); | |
| 158 | try self.verifyInstOperands(inst, .{ un_op, .none, .none }); | |
| 159 | 159 | // This instruction terminates the function, so everything should be dead |
| 160 | 160 | if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst}); |
| 161 | 161 | }, |
| ... | ... | @@ -164,36 +164,36 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 164 | 164 | .wasm_memory_grow, |
| 165 | 165 | => { |
| 166 | 166 | const pl_op = data[inst].pl_op; |
| 167 | try self.verifyInst(inst, .{ pl_op.operand, .none, .none }); | |
| 167 | try self.verifyInstOperands(inst, .{ pl_op.operand, .none, .none }); | |
| 168 | 168 | }, |
| 169 | 169 | .prefetch => { |
| 170 | 170 | const prefetch = data[inst].prefetch; |
| 171 | try self.verifyInst(inst, .{ prefetch.ptr, .none, .none }); | |
| 171 | try self.verifyInstOperands(inst, .{ prefetch.ptr, .none, .none }); | |
| 172 | 172 | }, |
| 173 | 173 | .reduce, |
| 174 | 174 | .reduce_optimized, |
| 175 | 175 | => { |
| 176 | 176 | const reduce = data[inst].reduce; |
| 177 | try self.verifyInst(inst, .{ reduce.operand, .none, .none }); | |
| 177 | try self.verifyInstOperands(inst, .{ reduce.operand, .none, .none }); | |
| 178 | 178 | }, |
| 179 | 179 | .union_init => { |
| 180 | 180 | const ty_pl = data[inst].ty_pl; |
| 181 | 181 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 182 | try self.verifyInst(inst, .{ extra.init, .none, .none }); | |
| 182 | try self.verifyInstOperands(inst, .{ extra.init, .none, .none }); | |
| 183 | 183 | }, |
| 184 | 184 | .struct_field_ptr, .struct_field_val => { |
| 185 | 185 | const ty_pl = data[inst].ty_pl; |
| 186 | 186 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 187 | try self.verifyInst(inst, .{ extra.struct_operand, .none, .none }); | |
| 187 | try self.verifyInstOperands(inst, .{ extra.struct_operand, .none, .none }); | |
| 188 | 188 | }, |
| 189 | 189 | .field_parent_ptr => { |
| 190 | 190 | const ty_pl = data[inst].ty_pl; |
| 191 | 191 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 192 | try self.verifyInst(inst, .{ extra.field_ptr, .none, .none }); | |
| 192 | try self.verifyInstOperands(inst, .{ extra.field_ptr, .none, .none }); | |
| 193 | 193 | }, |
| 194 | 194 | .atomic_load => { |
| 195 | 195 | const atomic_load = data[inst].atomic_load; |
| 196 | try self.verifyInst(inst, .{ atomic_load.ptr, .none, .none }); | |
| 196 | try self.verifyInstOperands(inst, .{ atomic_load.ptr, .none, .none }); | |
| 197 | 197 | }, |
| 198 | 198 | |
| 199 | 199 | // binary |
| ... | ... | @@ -263,7 +263,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 263 | 263 | .memcpy, |
| 264 | 264 | => { |
| 265 | 265 | const bin_op = data[inst].bin_op; |
| 266 | try self.verifyInst(inst, .{ bin_op.lhs, bin_op.rhs, .none }); | |
| 266 | try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none }); | |
| 267 | 267 | }, |
| 268 | 268 | .add_with_overflow, |
| 269 | 269 | .sub_with_overflow, |
| ... | ... | @@ -277,48 +277,48 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 277 | 277 | => { |
| 278 | 278 | const ty_pl = data[inst].ty_pl; |
| 279 | 279 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 280 | try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none }); | |
| 280 | try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none }); | |
| 281 | 281 | }, |
| 282 | 282 | .shuffle => { |
| 283 | 283 | const ty_pl = data[inst].ty_pl; |
| 284 | 284 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 285 | try self.verifyInst(inst, .{ extra.a, extra.b, .none }); | |
| 285 | try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none }); | |
| 286 | 286 | }, |
| 287 | 287 | .cmp_vector, |
| 288 | 288 | .cmp_vector_optimized, |
| 289 | 289 | => { |
| 290 | 290 | const ty_pl = data[inst].ty_pl; |
| 291 | 291 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 292 | try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none }); | |
| 292 | try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none }); | |
| 293 | 293 | }, |
| 294 | 294 | .atomic_rmw => { |
| 295 | 295 | const pl_op = data[inst].pl_op; |
| 296 | 296 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 297 | try self.verifyInst(inst, .{ pl_op.operand, extra.operand, .none }); | |
| 297 | try self.verifyInstOperands(inst, .{ pl_op.operand, extra.operand, .none }); | |
| 298 | 298 | }, |
| 299 | 299 | |
| 300 | 300 | // ternary |
| 301 | 301 | .select => { |
| 302 | 302 | const pl_op = data[inst].pl_op; |
| 303 | 303 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 304 | try self.verifyInst(inst, .{ pl_op.operand, extra.lhs, extra.rhs }); | |
| 304 | try self.verifyInstOperands(inst, .{ pl_op.operand, extra.lhs, extra.rhs }); | |
| 305 | 305 | }, |
| 306 | 306 | .mul_add => { |
| 307 | 307 | const pl_op = data[inst].pl_op; |
| 308 | 308 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 309 | try self.verifyInst(inst, .{ extra.lhs, extra.rhs, pl_op.operand }); | |
| 309 | try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, pl_op.operand }); | |
| 310 | 310 | }, |
| 311 | 311 | .vector_store_elem => { |
| 312 | 312 | const vector_store_elem = data[inst].vector_store_elem; |
| 313 | 313 | const extra = self.air.extraData(Air.Bin, vector_store_elem.payload).data; |
| 314 | try self.verifyInst(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs }); | |
| 314 | try self.verifyInstOperands(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs }); | |
| 315 | 315 | }, |
| 316 | 316 | .cmpxchg_strong, |
| 317 | 317 | .cmpxchg_weak, |
| 318 | 318 | => { |
| 319 | 319 | const ty_pl = data[inst].ty_pl; |
| 320 | 320 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 321 | try self.verifyInst(inst, .{ extra.ptr, extra.expected_value, extra.new_value }); | |
| 321 | try self.verifyInstOperands(inst, .{ extra.ptr, extra.expected_value, extra.new_value }); | |
| 322 | 322 | }, |
| 323 | 323 | |
| 324 | 324 | // big tombs |
| ... | ... | @@ -332,7 +332,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 332 | 332 | for (elements) |element| { |
| 333 | 333 | try self.verifyOperand(inst, element, bt.feed()); |
| 334 | 334 | } |
| 335 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 335 | try self.verifyInst(inst); | |
| 336 | 336 | }, |
| 337 | 337 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { |
| 338 | 338 | const pl_op = data[inst].pl_op; |
| ... | ... | @@ -347,7 +347,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 347 | 347 | for (args) |arg| { |
| 348 | 348 | try self.verifyOperand(inst, arg, bt.feed()); |
| 349 | 349 | } |
| 350 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 350 | try self.verifyInst(inst); | |
| 351 | 351 | }, |
| 352 | 352 | .assembly => { |
| 353 | 353 | const ty_pl = data[inst].ty_pl; |
| ... | ... | @@ -373,7 +373,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 373 | 373 | for (inputs) |input| { |
| 374 | 374 | try self.verifyOperand(inst, input, bt.feed()); |
| 375 | 375 | } |
| 376 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 376 | try self.verifyInst(inst); | |
| 377 | 377 | }, |
| 378 | 378 | |
| 379 | 379 | // control flow |
| ... | ... | @@ -397,7 +397,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 397 | 397 | |
| 398 | 398 | for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death); |
| 399 | 399 | |
| 400 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 400 | try self.verifyInst(inst); | |
| 401 | 401 | }, |
| 402 | 402 | .try_ptr => { |
| 403 | 403 | const ty_pl = data[inst].ty_pl; |
| ... | ... | @@ -419,7 +419,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 419 | 419 | |
| 420 | 420 | for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death); |
| 421 | 421 | |
| 422 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 422 | try self.verifyInst(inst); | |
| 423 | 423 | }, |
| 424 | 424 | .br => { |
| 425 | 425 | const br = data[inst].br; |
| ... | ... | @@ -431,7 +431,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 431 | 431 | } else { |
| 432 | 432 | gop.value_ptr.* = try self.live.clone(self.gpa); |
| 433 | 433 | } |
| 434 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 434 | try self.verifyInst(inst); | |
| 435 | 435 | }, |
| 436 | 436 | .block => { |
| 437 | 437 | const ty_pl = data[inst].ty_pl; |
| ... | ... | @@ -462,7 +462,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 462 | 462 | try self.verifyMatchingLiveness(inst, live); |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 465 | try self.verifyInstOperands(inst, .{ .none, .none, .none }); | |
| 466 | 466 | }, |
| 467 | 467 | .loop => { |
| 468 | 468 | const ty_pl = data[inst].ty_pl; |
| ... | ... | @@ -477,7 +477,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 477 | 477 | // The same stuff should be alive after the loop as before it |
| 478 | 478 | try self.verifyMatchingLiveness(inst, live); |
| 479 | 479 | |
| 480 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 480 | try self.verifyInstOperands(inst, .{ .none, .none, .none }); | |
| 481 | 481 | }, |
| 482 | 482 | .cond_br => { |
| 483 | 483 | const pl_op = data[inst].pl_op; |
| ... | ... | @@ -500,7 +500,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 500 | 500 | for (cond_br_liveness.else_deaths) |death| try self.verifyDeath(inst, death); |
| 501 | 501 | try self.verifyBody(else_body); |
| 502 | 502 | |
| 503 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 503 | try self.verifyInst(inst); | |
| 504 | 504 | }, |
| 505 | 505 | .switch_br => { |
| 506 | 506 | const pl_op = data[inst].pl_op; |
| ... | ... | @@ -544,7 +544,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 544 | 544 | try self.verifyBody(else_body); |
| 545 | 545 | } |
| 546 | 546 | |
| 547 | try self.verifyInst(inst, .{ .none, .none, .none }); | |
| 547 | try self.verifyInst(inst); | |
| 548 | 548 | }, |
| 549 | 549 | } |
| 550 | 550 | } |
| ... | ... | @@ -570,7 +570,7 @@ fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies |
| 570 | 570 | } |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | fn verifyInst( | |
| 573 | fn verifyInstOperands( | |
| 574 | 574 | self: *Verify, |
| 575 | 575 | inst: Air.Inst.Index, |
| 576 | 576 | operands: [Liveness.bpi - 1]Air.Inst.Ref, |
| ... | ... | @@ -579,6 +579,10 @@ fn verifyInst( |
| 579 | 579 | const dies = self.liveness.operandDies(inst, @intCast(Liveness.OperandInt, operand_index)); |
| 580 | 580 | try self.verifyOperand(inst, operand, dies); |
| 581 | 581 | } |
| 582 | try self.verifyInst(inst); | |
| 583 | } | |
| 584 | ||
| 585 | fn verifyInst(self: *Verify, inst: Air.Inst.Index) Error!void { | |
| 582 | 586 | if (self.air.instructions.items(.tag)[inst] == .interned) return; |
| 583 | 587 | if (self.liveness.isUnused(inst)) { |
| 584 | 588 | assert(!self.live.contains(inst)); |
src/Sema.zig+28-22| ... | ... | @@ -16687,7 +16687,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16687 | 16687 | const new_decl_ty = try mod.arrayType(.{ |
| 16688 | 16688 | .len = bytes.len, |
| 16689 | 16689 | .child = .u8_type, |
| 16690 | .sentinel = .zero_u8, | |
| 16691 | 16690 | }); |
| 16692 | 16691 | const new_decl = try anon_decl.finish( |
| 16693 | 16692 | new_decl_ty, |
| ... | ... | @@ -16698,7 +16697,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16698 | 16697 | 0, // default alignment |
| 16699 | 16698 | ); |
| 16700 | 16699 | break :v try mod.intern(.{ .ptr = .{ |
| 16701 | .ty = .slice_const_u8_sentinel_0_type, | |
| 16700 | .ty = .slice_const_u8_type, | |
| 16702 | 16701 | .addr = .{ .decl = new_decl }, |
| 16703 | 16702 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), |
| 16704 | 16703 | } }); |
| ... | ... | @@ -23991,7 +23990,6 @@ fn panicWithMsg( |
| 23991 | 23990 | msg_inst: Air.Inst.Ref, |
| 23992 | 23991 | ) !void { |
| 23993 | 23992 | const mod = sema.mod; |
| 23994 | const arena = sema.arena; | |
| 23995 | 23993 | |
| 23996 | 23994 | if (!mod.backendSupportsFeature(.panic_fn)) { |
| 23997 | 23995 | _ = try block.addNoOp(.trap); |
| ... | ... | @@ -24001,16 +23999,22 @@ fn panicWithMsg( |
| 24001 | 23999 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 24002 | 24000 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 24003 | 24001 | const target = mod.getTarget(); |
| 24004 | const ptr_stack_trace_ty = try Type.ptr(arena, mod, .{ | |
| 24005 | .pointee_type = stack_trace_ty, | |
| 24006 | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic | |
| 24002 | const ptr_stack_trace_ty = try mod.ptrType(.{ | |
| 24003 | .elem_type = stack_trace_ty.toIntern(), | |
| 24004 | .address_space = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic | |
| 24007 | 24005 | }); |
| 24008 | const null_stack_trace = try sema.addConstant( | |
| 24009 | try Type.optional(arena, ptr_stack_trace_ty, mod), | |
| 24010 | Value.null, | |
| 24011 | ); | |
| 24012 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; | |
| 24013 | try sema.callBuiltin(block, panic_fn, .auto, &args); | |
| 24006 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); | |
| 24007 | const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{ | |
| 24008 | .ty = opt_ptr_stack_trace_ty.toIntern(), | |
| 24009 | .val = .none, | |
| 24010 | } })).toValue()); | |
| 24011 | ||
| 24012 | const opt_usize_ty = try mod.optionalType(.usize_type); | |
| 24013 | const null_ret_addr = try sema.addConstant(opt_usize_ty, (try mod.intern(.{ .opt = .{ | |
| 24014 | .ty = opt_usize_ty.toIntern(), | |
| 24015 | .val = .none, | |
| 24016 | } })).toValue()); | |
| 24017 | try sema.callBuiltin(block, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr }); | |
| 24014 | 24018 | } |
| 24015 | 24019 | |
| 24016 | 24020 | fn panicUnwrapError( |
| ... | ... | @@ -29395,13 +29399,10 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value { |
| 29395 | 29399 | |
| 29396 | 29400 | fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value { |
| 29397 | 29401 | const mod = sema.mod; |
| 29398 | const val = opt_val orelse return Value.null; | |
| 29399 | const ptr_val = try sema.refValue(block, ty, val); | |
| 29400 | const result = try mod.intern(.{ .opt = .{ | |
| 29401 | .ty = (try mod.optionalType((try mod.singleConstPtrType(ty)).toIntern())).toIntern(), | |
| 29402 | .val = ptr_val.toIntern(), | |
| 29403 | } }); | |
| 29404 | return result.toValue(); | |
| 29402 | return (try mod.intern(.{ .opt = .{ | |
| 29403 | .ty = (try mod.optionalType((try mod.singleConstPtrType(Type.anyopaque)).toIntern())).toIntern(), | |
| 29404 | .val = if (opt_val) |val| (try sema.refValue(block, ty, val)).toIntern() else .none, | |
| 29405 | } })).toValue(); | |
| 29405 | 29406 | } |
| 29406 | 29407 | |
| 29407 | 29408 | fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -30603,7 +30604,7 @@ fn wrapErrorUnionPayload( |
| 30603 | 30604 | if (try sema.resolveMaybeUndefVal(coerced)) |val| { |
| 30604 | 30605 | return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{ |
| 30605 | 30606 | .ty = dest_ty.toIntern(), |
| 30606 | .val = .{ .payload = val.toIntern() }, | |
| 30607 | .val = .{ .payload = try val.intern(dest_payload_ty, mod) }, | |
| 30607 | 30608 | } })).toValue()); |
| 30608 | 30609 | } |
| 30609 | 30610 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | ... | @@ -30647,7 +30648,12 @@ fn wrapErrorUnionSet( |
| 30647 | 30648 | else => unreachable, |
| 30648 | 30649 | }, |
| 30649 | 30650 | } |
| 30650 | return sema.addConstant(dest_ty, val); | |
| 30651 | return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{ | |
| 30652 | .ty = dest_ty.toIntern(), | |
| 30653 | .val = .{ | |
| 30654 | .err_name = mod.intern_pool.indexToKey(try val.intern(dest_err_set_ty, mod)).err.name, | |
| 30655 | }, | |
| 30656 | } })).toValue()); | |
| 30651 | 30657 | } |
| 30652 | 30658 | |
| 30653 | 30659 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | ... | @@ -33325,7 +33331,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { |
| 33325 | 33331 | } |
| 33326 | 33332 | |
| 33327 | 33333 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { |
| 33328 | return sema.addConstant(ty, Value.undef); | |
| 33334 | return sema.addConstant(ty, (try sema.mod.intern(.{ .undef = ty.toIntern() })).toValue()); | |
| 33329 | 33335 | } |
| 33330 | 33336 | |
| 33331 | 33337 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |
src/codegen/llvm.zig+16-9| ... | ... | @@ -3267,21 +3267,28 @@ pub const DeclGen = struct { |
| 3267 | 3267 | return llvm_ty.constInt(kv.value, .False); |
| 3268 | 3268 | }, |
| 3269 | 3269 | .error_union => |error_union| { |
| 3270 | const err_tv: TypedValue = switch (error_union.val) { | |
| 3271 | .err_name => |err_name| .{ | |
| 3272 | .ty = tv.ty.errorUnionSet(mod), | |
| 3273 | .val = (try mod.intern(.{ .err = .{ | |
| 3274 | .ty = tv.ty.errorUnionSet(mod).toIntern(), | |
| 3275 | .name = err_name, | |
| 3276 | } })).toValue(), | |
| 3277 | }, | |
| 3278 | .payload => .{ | |
| 3279 | .ty = Type.err_int, | |
| 3280 | .val = try mod.intValue(Type.err_int, 0), | |
| 3281 | }, | |
| 3282 | }; | |
| 3270 | 3283 | const payload_type = tv.ty.errorUnionPayload(mod); |
| 3271 | const is_pl = tv.val.errorUnionIsPayload(mod); | |
| 3272 | ||
| 3273 | 3284 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3274 | 3285 | // We use the error type directly as the type. |
| 3275 | const err_val = if (!is_pl) tv.val else try mod.intValue(Type.err_int, 0); | |
| 3276 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); | |
| 3286 | return dg.lowerValue(err_tv); | |
| 3277 | 3287 | } |
| 3278 | 3288 | |
| 3279 | 3289 | const payload_align = payload_type.abiAlignment(mod); |
| 3280 | const error_align = Type.anyerror.abiAlignment(mod); | |
| 3281 | const llvm_error_value = try dg.lowerValue(.{ | |
| 3282 | .ty = Type.anyerror, | |
| 3283 | .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val, | |
| 3284 | }); | |
| 3290 | const error_align = err_tv.ty.abiAlignment(mod); | |
| 3291 | const llvm_error_value = try dg.lowerValue(err_tv); | |
| 3285 | 3292 | const llvm_payload_value = try dg.lowerValue(.{ |
| 3286 | 3293 | .ty = payload_type, |
| 3287 | 3294 | .val = switch (error_union.val) { |
src/print_air.zig+1-1| ... | ... | @@ -703,7 +703,7 @@ const Writer = struct { |
| 703 | 703 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; |
| 704 | 704 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 705 | 705 | const name = w.air.nullTerminatedString(pl_op.payload); |
| 706 | try s.print(", {s}", .{name}); | |
| 706 | try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)}); | |
| 707 | 707 | } |
| 708 | 708 | |
| 709 | 709 | fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
src/value.zig+112-28| ... | ... | @@ -347,6 +347,43 @@ pub const Value = struct { |
| 347 | 347 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { |
| 348 | 348 | if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern()); |
| 349 | 349 | switch (val.tag()) { |
| 350 | .eu_payload => { | |
| 351 | const pl = val.castTag(.eu_payload).?.data; | |
| 352 | return mod.intern(.{ .error_union = .{ | |
| 353 | .ty = ty.toIntern(), | |
| 354 | .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) }, | |
| 355 | } }); | |
| 356 | }, | |
| 357 | .opt_payload => { | |
| 358 | const pl = val.castTag(.opt_payload).?.data; | |
| 359 | return mod.intern(.{ .opt = .{ | |
| 360 | .ty = ty.toIntern(), | |
| 361 | .val = try pl.intern(ty.optionalChild(mod), mod), | |
| 362 | } }); | |
| 363 | }, | |
| 364 | .slice => { | |
| 365 | const pl = val.castTag(.slice).?.data; | |
| 366 | const ptr = try pl.ptr.intern(ty.optionalChild(mod), mod); | |
| 367 | var ptr_key = mod.intern_pool.indexToKey(ptr).ptr; | |
| 368 | assert(ptr_key.len == .none); | |
| 369 | ptr_key.ty = ty.toIntern(); | |
| 370 | ptr_key.len = try pl.len.intern(Type.usize, mod); | |
| 371 | return mod.intern(.{ .ptr = ptr_key }); | |
| 372 | }, | |
| 373 | .bytes => { | |
| 374 | const pl = val.castTag(.bytes).?.data; | |
| 375 | return mod.intern(.{ .aggregate = .{ | |
| 376 | .ty = ty.toIntern(), | |
| 377 | .storage = .{ .bytes = pl }, | |
| 378 | } }); | |
| 379 | }, | |
| 380 | .repeated => { | |
| 381 | const pl = val.castTag(.repeated).?.data; | |
| 382 | return mod.intern(.{ .aggregate = .{ | |
| 383 | .ty = ty.toIntern(), | |
| 384 | .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) }, | |
| 385 | } }); | |
| 386 | }, | |
| 350 | 387 | .aggregate => { |
| 351 | 388 | const old_elems = val.castTag(.aggregate).?.data; |
| 352 | 389 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); |
| ... | ... | @@ -372,24 +409,74 @@ pub const Value = struct { |
| 372 | 409 | .val = try pl.val.intern(ty.unionFieldType(pl.tag, mod), mod), |
| 373 | 410 | } }); |
| 374 | 411 | }, |
| 375 | else => unreachable, | |
| 376 | 412 | } |
| 377 | 413 | } |
| 378 | 414 | |
| 379 | 415 | pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value { |
| 380 | if (val.ip_index == .none) return val; | |
| 381 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 416 | return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 417 | .int_type, | |
| 418 | .ptr_type, | |
| 419 | .array_type, | |
| 420 | .vector_type, | |
| 421 | .opt_type, | |
| 422 | .anyframe_type, | |
| 423 | .error_union_type, | |
| 424 | .simple_type, | |
| 425 | .struct_type, | |
| 426 | .anon_struct_type, | |
| 427 | .union_type, | |
| 428 | .opaque_type, | |
| 429 | .enum_type, | |
| 430 | .func_type, | |
| 431 | .error_set_type, | |
| 432 | .inferred_error_set_type, | |
| 433 | ||
| 434 | .undef, | |
| 435 | .runtime_value, | |
| 436 | .simple_value, | |
| 437 | .variable, | |
| 438 | .extern_func, | |
| 439 | .func, | |
| 440 | .int, | |
| 441 | .err, | |
| 442 | .enum_literal, | |
| 443 | .enum_tag, | |
| 444 | .float, | |
| 445 | => val, | |
| 446 | ||
| 447 | .error_union => |error_union| switch (error_union.val) { | |
| 448 | .err_name => val, | |
| 449 | .payload => |payload| Tag.eu_payload.create(arena, payload.toValue()), | |
| 450 | }, | |
| 451 | ||
| 452 | .ptr => |ptr| switch (ptr.len) { | |
| 453 | .none => val, | |
| 454 | else => |len| Tag.slice.create(arena, .{ | |
| 455 | .ptr = val.slicePtr(mod), | |
| 456 | .len = len.toValue(), | |
| 457 | }), | |
| 458 | }, | |
| 459 | ||
| 460 | .opt => |opt| switch (opt.val) { | |
| 461 | .none => val, | |
| 462 | else => |payload| Tag.opt_payload.create(arena, payload.toValue()), | |
| 463 | }, | |
| 464 | ||
| 382 | 465 | .aggregate => |aggregate| switch (aggregate.storage) { |
| 383 | .bytes => |bytes| return Tag.bytes.create(arena, try arena.dupe(u8, bytes)), | |
| 466 | .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)), | |
| 384 | 467 | .elems => |old_elems| { |
| 385 | 468 | const new_elems = try arena.alloc(Value, old_elems.len); |
| 386 | 469 | for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = old_elem.toValue(); |
| 387 | 470 | return Tag.aggregate.create(arena, new_elems); |
| 388 | 471 | }, |
| 389 | .repeated_elem => |elem| return Tag.repeated.create(arena, elem.toValue()), | |
| 472 | .repeated_elem => |elem| Tag.repeated.create(arena, elem.toValue()), | |
| 390 | 473 | }, |
| 391 | else => return val, | |
| 392 | } | |
| 474 | ||
| 475 | .un => |un| Tag.@"union".create(arena, .{ | |
| 476 | .tag = un.tag.toValue(), | |
| 477 | .val = un.val.toValue(), | |
| 478 | }), | |
| 479 | }; | |
| 393 | 480 | } |
| 394 | 481 | |
| 395 | 482 | pub fn toIntern(val: Value) InternPool.Index { |
| ... | ... | @@ -1896,7 +1983,7 @@ pub const Value = struct { |
| 1896 | 1983 | |
| 1897 | 1984 | /// Returns true if a Value is backed by a variable |
| 1898 | 1985 | pub fn isVariable(val: Value, mod: *Module) bool { |
| 1899 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1986 | return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1900 | 1987 | .variable => true, |
| 1901 | 1988 | .ptr => |ptr| switch (ptr.addr) { |
| 1902 | 1989 | .decl => |decl_index| { |
| ... | ... | @@ -1919,28 +2006,25 @@ pub const Value = struct { |
| 1919 | 2006 | } |
| 1920 | 2007 | |
| 1921 | 2008 | pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool { |
| 1922 | return switch (val.ip_index) { | |
| 1923 | .none => false, | |
| 1924 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1925 | .variable => |variable| variable.is_threadlocal, | |
| 1926 | .ptr => |ptr| switch (ptr.addr) { | |
| 1927 | .decl => |decl_index| { | |
| 1928 | const decl = mod.declPtr(decl_index); | |
| 1929 | assert(decl.has_tv); | |
| 1930 | return decl.val.isPtrToThreadLocal(mod); | |
| 1931 | }, | |
| 1932 | .mut_decl => |mut_decl| { | |
| 1933 | const decl = mod.declPtr(mut_decl.decl); | |
| 1934 | assert(decl.has_tv); | |
| 1935 | return decl.val.isPtrToThreadLocal(mod); | |
| 1936 | }, | |
| 1937 | .int => false, | |
| 1938 | .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod), | |
| 1939 | .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod), | |
| 1940 | .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod), | |
| 2009 | return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 2010 | .variable => |variable| variable.is_threadlocal, | |
| 2011 | .ptr => |ptr| switch (ptr.addr) { | |
| 2012 | .decl => |decl_index| { | |
| 2013 | const decl = mod.declPtr(decl_index); | |
| 2014 | assert(decl.has_tv); | |
| 2015 | return decl.val.isPtrToThreadLocal(mod); | |
| 1941 | 2016 | }, |
| 1942 | else => false, | |
| 2017 | .mut_decl => |mut_decl| { | |
| 2018 | const decl = mod.declPtr(mut_decl.decl); | |
| 2019 | assert(decl.has_tv); | |
| 2020 | return decl.val.isPtrToThreadLocal(mod); | |
| 2021 | }, | |
| 2022 | .int => false, | |
| 2023 | .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod), | |
| 2024 | .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod), | |
| 2025 | .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod), | |
| 1943 | 2026 | }, |
| 2027 | else => false, | |
| 1944 | 2028 | }; |
| 1945 | 2029 | } |
| 1946 | 2030 |
tools/lldb_pretty_printers.py+1| ... | ... | @@ -681,6 +681,7 @@ def __lldb_init_module(debugger, _=None): |
| 681 | 681 | add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True) |
| 682 | 682 | add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True) |
| 683 | 683 | add(debugger, category='zig.stage2', type='Module.Decl::Module.Decl.Index', synth=True) |
| 684 | add(debugger, category='zig.stage2', type='Module.LazySrcLoc', identifier='zig_TaggedUnion', synth=True) | |
| 684 | 685 | add(debugger, category='zig.stage2', type='InternPool.Index', synth=True) |
| 685 | 686 | add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True) |
| 686 | 687 | add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True) |