| 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,7 +2298,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 2298 | ip.* = undefined; | 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 | assert(index != .none); | 2302 | assert(index != .none); |
| 2303 | const item = ip.items.get(@enumToInt(index)); | 2303 | const item = ip.items.get(@enumToInt(index)); |
| 2304 | const data = item.data; | 2304 | const data = item.data; |
| ... | @@ -2361,7 +2361,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -2361,7 +2361,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2361 | 2361 | ||
| 2362 | .type_slice => { | 2362 | .type_slice => { |
| 2363 | const ptr_type_index = @intToEnum(Index, data); | 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 | result.size = .Slice; | 2365 | result.size = .Slice; |
| 2366 | return .{ .ptr_type = result }; | 2366 | return .{ .ptr_type = result }; |
| 2367 | }, | 2367 | }, |
| ... | @@ -2454,9 +2454,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -2454,9 +2454,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2454 | .values_map = .none, | 2454 | .values_map = .none, |
| 2455 | } }; | 2455 | } }; |
| 2456 | }, | 2456 | }, |
| 2457 | .type_enum_explicit => indexToKeyEnum(ip, data, .explicit), | 2457 | .type_enum_explicit => ip.indexToKeyEnum(data, .explicit), |
| 2458 | .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive), | 2458 | .type_enum_nonexhaustive => ip.indexToKeyEnum(data, .nonexhaustive), |
| 2459 | .type_function => .{ .func_type = indexToKeyFuncType(ip, data) }, | 2459 | .type_function => .{ .func_type = ip.indexToKeyFuncType(data) }, |
| 2460 | 2460 | ||
| 2461 | .undef => .{ .undef = @intToEnum(Index, data) }, | 2461 | .undef => .{ .undef = @intToEnum(Index, data) }, |
| 2462 | .runtime_value => { | 2462 | .runtime_value => { |
| ... | @@ -2591,8 +2591,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -2591,8 +2591,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 2591 | .ty = .comptime_int_type, | 2591 | .ty = .comptime_int_type, |
| 2592 | .storage = .{ .i64 = @bitCast(i32, data) }, | 2592 | .storage = .{ .i64 = @bitCast(i32, data) }, |
| 2593 | } }, | 2593 | } }, |
| 2594 | .int_positive => indexToKeyBigInt(ip, data, true), | 2594 | .int_positive => ip.indexToKeyBigInt(data, true), |
| 2595 | .int_negative => indexToKeyBigInt(ip, data, false), | 2595 | .int_negative => ip.indexToKeyBigInt(data, false), |
| 2596 | .int_small => { | 2596 | .int_small => { |
| 2597 | const info = ip.extraData(IntSmall, data); | 2597 | const info = ip.extraData(IntSmall, data); |
| 2598 | return .{ .int = .{ | 2598 | return .{ .int = .{ |
| ... | @@ -3430,22 +3430,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3430,22 +3430,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3430 | .data = try ip.addExtra(gpa, err), | 3430 | .data = try ip.addExtra(gpa, err), |
| 3431 | }), | 3431 | }), |
| 3432 | 3432 | ||
| 3433 | .error_union => |error_union| ip.items.appendAssumeCapacity(switch (error_union.val) { | 3433 | .error_union => |error_union| { |
| 3434 | .err_name => |err_name| .{ | 3434 | assert(ip.indexToKey(error_union.ty) == .error_union_type); |
| 3435 | .tag = .error_union_error, | 3435 | ip.items.appendAssumeCapacity(switch (error_union.val) { |
| 3436 | .data = try ip.addExtra(gpa, Key.Error{ | 3436 | .err_name => |err_name| .{ |
| 3437 | .ty = error_union.ty, | 3437 | .tag = .error_union_error, |
| 3438 | .name = err_name, | 3438 | .data = try ip.addExtra(gpa, Key.Error{ |
| 3439 | }), | 3439 | .ty = error_union.ty, |
| 3440 | }, | 3440 | .name = err_name, |
| 3441 | .payload => |payload| .{ | 3441 | }), |
| 3442 | .tag = .error_union_payload, | 3442 | }, |
| 3443 | .data = try ip.addExtra(gpa, TypeValue{ | 3443 | .payload => |payload| .{ |
| 3444 | .ty = error_union.ty, | 3444 | .tag = .error_union_payload, |
| 3445 | .val = payload, | 3445 | .data = try ip.addExtra(gpa, TypeValue{ |
| 3446 | }), | 3446 | .ty = error_union.ty, |
| 3447 | }, | 3447 | .val = payload, |
| 3448 | }), | 3448 | }), |
| 3449 | }, | ||
| 3450 | }); | ||
| 3451 | }, | ||
| 3449 | 3452 | ||
| 3450 | .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{ | 3453 | .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{ |
| 3451 | .tag = .enum_literal, | 3454 | .tag = .enum_literal, |
| ... | @@ -4191,6 +4194,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index { | ... | @@ -4191,6 +4194,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index { |
| 4191 | /// * ptr <=> ptr | 4194 | /// * ptr <=> ptr |
| 4192 | /// * null_value => opt | 4195 | /// * null_value => opt |
| 4193 | /// * payload => opt | 4196 | /// * payload => opt |
| 4197 | /// * error set <=> error set | ||
| 4194 | pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { | 4198 | pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { |
| 4195 | const old_ty = ip.typeOf(val); | 4199 | const old_ty = ip.typeOf(val); |
| 4196 | if (old_ty == new_ty) return val; | 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,6 +4234,13 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 4230 | } }), | 4234 | } }), |
| 4231 | else => {}, | 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 | else => {}, | 4244 | else => {}, |
| 4234 | } | 4245 | } |
| 4235 | switch (ip.indexToKey(new_ty)) { | 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,10 +61,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 61 | .work_item_id, | 61 | .work_item_id, |
| 62 | .work_group_size, | 62 | .work_group_size, |
| 63 | .work_group_id, | 63 | .work_group_id, |
| 64 | => try self.verifyInst(inst, .{ .none, .none, .none }), | 64 | => try self.verifyInstOperands(inst, .{ .none, .none, .none }), |
| 65 | 65 | ||
| 66 | .trap, .unreach => { | 66 | .trap, .unreach => { |
| 67 | try self.verifyInst(inst, .{ .none, .none, .none }); | 67 | try self.verifyInstOperands(inst, .{ .none, .none, .none }); |
| 68 | // This instruction terminates the function, so everything should be dead | 68 | // This instruction terminates the function, so everything should be dead |
| 69 | if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst}); | 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,7 +113,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 113 | .c_va_copy, | 113 | .c_va_copy, |
| 114 | => { | 114 | => { |
| 115 | const ty_op = data[inst].ty_op; | 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 | .is_null, | 118 | .is_null, |
| 119 | .is_non_null, | 119 | .is_non_null, |
| ... | @@ -149,13 +149,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -149,13 +149,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 149 | .c_va_end, | 149 | .c_va_end, |
| 150 | => { | 150 | => { |
| 151 | const un_op = data[inst].un_op; | 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 | .ret, | 154 | .ret, |
| 155 | .ret_load, | 155 | .ret_load, |
| 156 | => { | 156 | => { |
| 157 | const un_op = data[inst].un_op; | 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 | // This instruction terminates the function, so everything should be dead | 159 | // This instruction terminates the function, so everything should be dead |
| 160 | if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst}); | 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,36 +164,36 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 164 | .wasm_memory_grow, | 164 | .wasm_memory_grow, |
| 165 | => { | 165 | => { |
| 166 | const pl_op = data[inst].pl_op; | 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 | .prefetch => { | 169 | .prefetch => { |
| 170 | const prefetch = data[inst].prefetch; | 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 | .reduce, | 173 | .reduce, |
| 174 | .reduce_optimized, | 174 | .reduce_optimized, |
| 175 | => { | 175 | => { |
| 176 | const reduce = data[inst].reduce; | 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 | .union_init => { | 179 | .union_init => { |
| 180 | const ty_pl = data[inst].ty_pl; | 180 | const ty_pl = data[inst].ty_pl; |
| 181 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 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 | .struct_field_ptr, .struct_field_val => { | 184 | .struct_field_ptr, .struct_field_val => { |
| 185 | const ty_pl = data[inst].ty_pl; | 185 | const ty_pl = data[inst].ty_pl; |
| 186 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 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 | .field_parent_ptr => { | 189 | .field_parent_ptr => { |
| 190 | const ty_pl = data[inst].ty_pl; | 190 | const ty_pl = data[inst].ty_pl; |
| 191 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 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 | .atomic_load => { | 194 | .atomic_load => { |
| 195 | const atomic_load = data[inst].atomic_load; | 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 | // binary | 199 | // binary |
| ... | @@ -263,7 +263,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -263,7 +263,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 263 | .memcpy, | 263 | .memcpy, |
| 264 | => { | 264 | => { |
| 265 | const bin_op = data[inst].bin_op; | 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 | .add_with_overflow, | 268 | .add_with_overflow, |
| 269 | .sub_with_overflow, | 269 | .sub_with_overflow, |
| ... | @@ -277,48 +277,48 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -277,48 +277,48 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 277 | => { | 277 | => { |
| 278 | const ty_pl = data[inst].ty_pl; | 278 | const ty_pl = data[inst].ty_pl; |
| 279 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 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 | .shuffle => { | 282 | .shuffle => { |
| 283 | const ty_pl = data[inst].ty_pl; | 283 | const ty_pl = data[inst].ty_pl; |
| 284 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 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 | .cmp_vector, | 287 | .cmp_vector, |
| 288 | .cmp_vector_optimized, | 288 | .cmp_vector_optimized, |
| 289 | => { | 289 | => { |
| 290 | const ty_pl = data[inst].ty_pl; | 290 | const ty_pl = data[inst].ty_pl; |
| 291 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; | 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 | .atomic_rmw => { | 294 | .atomic_rmw => { |
| 295 | const pl_op = data[inst].pl_op; | 295 | const pl_op = data[inst].pl_op; |
| 296 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 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 | // ternary | 300 | // ternary |
| 301 | .select => { | 301 | .select => { |
| 302 | const pl_op = data[inst].pl_op; | 302 | const pl_op = data[inst].pl_op; |
| 303 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 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 | .mul_add => { | 306 | .mul_add => { |
| 307 | const pl_op = data[inst].pl_op; | 307 | const pl_op = data[inst].pl_op; |
| 308 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 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 | .vector_store_elem => { | 311 | .vector_store_elem => { |
| 312 | const vector_store_elem = data[inst].vector_store_elem; | 312 | const vector_store_elem = data[inst].vector_store_elem; |
| 313 | const extra = self.air.extraData(Air.Bin, vector_store_elem.payload).data; | 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 | .cmpxchg_strong, | 316 | .cmpxchg_strong, |
| 317 | .cmpxchg_weak, | 317 | .cmpxchg_weak, |
| 318 | => { | 318 | => { |
| 319 | const ty_pl = data[inst].ty_pl; | 319 | const ty_pl = data[inst].ty_pl; |
| 320 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 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 | // big tombs | 324 | // big tombs |
| ... | @@ -332,7 +332,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -332,7 +332,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 332 | for (elements) |element| { | 332 | for (elements) |element| { |
| 333 | try self.verifyOperand(inst, element, bt.feed()); | 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 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { | 337 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { |
| 338 | const pl_op = data[inst].pl_op; | 338 | const pl_op = data[inst].pl_op; |
| ... | @@ -347,7 +347,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -347,7 +347,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 347 | for (args) |arg| { | 347 | for (args) |arg| { |
| 348 | try self.verifyOperand(inst, arg, bt.feed()); | 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 | .assembly => { | 352 | .assembly => { |
| 353 | const ty_pl = data[inst].ty_pl; | 353 | const ty_pl = data[inst].ty_pl; |
| ... | @@ -373,7 +373,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -373,7 +373,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 373 | for (inputs) |input| { | 373 | for (inputs) |input| { |
| 374 | try self.verifyOperand(inst, input, bt.feed()); | 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 | // control flow | 379 | // control flow |
| ... | @@ -397,7 +397,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -397,7 +397,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 397 | 397 | ||
| 398 | for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death); | 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 | .try_ptr => { | 402 | .try_ptr => { |
| 403 | const ty_pl = data[inst].ty_pl; | 403 | const ty_pl = data[inst].ty_pl; |
| ... | @@ -419,7 +419,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -419,7 +419,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 419 | 419 | ||
| 420 | for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death); | 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 | .br => { | 424 | .br => { |
| 425 | const br = data[inst].br; | 425 | const br = data[inst].br; |
| ... | @@ -431,7 +431,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -431,7 +431,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 431 | } else { | 431 | } else { |
| 432 | gop.value_ptr.* = try self.live.clone(self.gpa); | 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 | .block => { | 436 | .block => { |
| 437 | const ty_pl = data[inst].ty_pl; | 437 | const ty_pl = data[inst].ty_pl; |
| ... | @@ -462,7 +462,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -462,7 +462,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 462 | try self.verifyMatchingLiveness(inst, live); | 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 | .loop => { | 467 | .loop => { |
| 468 | const ty_pl = data[inst].ty_pl; | 468 | const ty_pl = data[inst].ty_pl; |
| ... | @@ -477,7 +477,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -477,7 +477,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 477 | // The same stuff should be alive after the loop as before it | 477 | // The same stuff should be alive after the loop as before it |
| 478 | try self.verifyMatchingLiveness(inst, live); | 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 | .cond_br => { | 482 | .cond_br => { |
| 483 | const pl_op = data[inst].pl_op; | 483 | const pl_op = data[inst].pl_op; |
| ... | @@ -500,7 +500,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -500,7 +500,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 500 | for (cond_br_liveness.else_deaths) |death| try self.verifyDeath(inst, death); | 500 | for (cond_br_liveness.else_deaths) |death| try self.verifyDeath(inst, death); |
| 501 | try self.verifyBody(else_body); | 501 | try self.verifyBody(else_body); |
| 502 | 502 | ||
| 503 | try self.verifyInst(inst, .{ .none, .none, .none }); | 503 | try self.verifyInst(inst); |
| 504 | }, | 504 | }, |
| 505 | .switch_br => { | 505 | .switch_br => { |
| 506 | const pl_op = data[inst].pl_op; | 506 | const pl_op = data[inst].pl_op; |
| ... | @@ -544,7 +544,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -544,7 +544,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 544 | try self.verifyBody(else_body); | 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,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 | self: *Verify, | 574 | self: *Verify, |
| 575 | inst: Air.Inst.Index, | 575 | inst: Air.Inst.Index, |
| 576 | operands: [Liveness.bpi - 1]Air.Inst.Ref, | 576 | operands: [Liveness.bpi - 1]Air.Inst.Ref, |
| ... | @@ -579,6 +579,10 @@ fn verifyInst( | ... | @@ -579,6 +579,10 @@ fn verifyInst( |
| 579 | const dies = self.liveness.operandDies(inst, @intCast(Liveness.OperandInt, operand_index)); | 579 | const dies = self.liveness.operandDies(inst, @intCast(Liveness.OperandInt, operand_index)); |
| 580 | try self.verifyOperand(inst, operand, dies); | 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 | if (self.air.instructions.items(.tag)[inst] == .interned) return; | 586 | if (self.air.instructions.items(.tag)[inst] == .interned) return; |
| 583 | if (self.liveness.isUnused(inst)) { | 587 | if (self.liveness.isUnused(inst)) { |
| 584 | assert(!self.live.contains(inst)); | 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,7 +16687,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16687 | const new_decl_ty = try mod.arrayType(.{ | 16687 | const new_decl_ty = try mod.arrayType(.{ |
| 16688 | .len = bytes.len, | 16688 | .len = bytes.len, |
| 16689 | .child = .u8_type, | 16689 | .child = .u8_type, |
| 16690 | .sentinel = .zero_u8, | ||
| 16691 | }); | 16690 | }); |
| 16692 | const new_decl = try anon_decl.finish( | 16691 | const new_decl = try anon_decl.finish( |
| 16693 | new_decl_ty, | 16692 | new_decl_ty, |
| ... | @@ -16698,7 +16697,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16698,7 +16697,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16698 | 0, // default alignment | 16697 | 0, // default alignment |
| 16699 | ); | 16698 | ); |
| 16700 | break :v try mod.intern(.{ .ptr = .{ | 16699 | break :v try mod.intern(.{ .ptr = .{ |
| 16701 | .ty = .slice_const_u8_sentinel_0_type, | 16700 | .ty = .slice_const_u8_type, |
| 16702 | .addr = .{ .decl = new_decl }, | 16701 | .addr = .{ .decl = new_decl }, |
| 16703 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), | 16702 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), |
| 16704 | } }); | 16703 | } }); |
| ... | @@ -23991,7 +23990,6 @@ fn panicWithMsg( | ... | @@ -23991,7 +23990,6 @@ fn panicWithMsg( |
| 23991 | msg_inst: Air.Inst.Ref, | 23990 | msg_inst: Air.Inst.Ref, |
| 23992 | ) !void { | 23991 | ) !void { |
| 23993 | const mod = sema.mod; | 23992 | const mod = sema.mod; |
| 23994 | const arena = sema.arena; | ||
| 23995 | 23993 | ||
| 23996 | if (!mod.backendSupportsFeature(.panic_fn)) { | 23994 | if (!mod.backendSupportsFeature(.panic_fn)) { |
| 23997 | _ = try block.addNoOp(.trap); | 23995 | _ = try block.addNoOp(.trap); |
| ... | @@ -24001,16 +23999,22 @@ fn panicWithMsg( | ... | @@ -24001,16 +23999,22 @@ fn panicWithMsg( |
| 24001 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); | 23999 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 24002 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); | 24000 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 24003 | const target = mod.getTarget(); | 24001 | const target = mod.getTarget(); |
| 24004 | const ptr_stack_trace_ty = try Type.ptr(arena, mod, .{ | 24002 | const ptr_stack_trace_ty = try mod.ptrType(.{ |
| 24005 | .pointee_type = stack_trace_ty, | 24003 | .elem_type = stack_trace_ty.toIntern(), |
| 24006 | .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic | 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( | 24006 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); |
| 24009 | try Type.optional(arena, ptr_stack_trace_ty, mod), | 24007 | const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{ |
| 24010 | Value.null, | 24008 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| 24011 | ); | 24009 | .val = .none, |
| 24012 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; | 24010 | } })).toValue()); |
| 24013 | try sema.callBuiltin(block, panic_fn, .auto, &args); | 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 | fn panicUnwrapError( | 24020 | fn panicUnwrapError( |
| ... | @@ -29395,13 +29399,10 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value { | ... | @@ -29395,13 +29399,10 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value { |
| 29395 | 29399 | ||
| 29396 | fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value { | 29400 | fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value { |
| 29397 | const mod = sema.mod; | 29401 | const mod = sema.mod; |
| 29398 | const val = opt_val orelse return Value.null; | 29402 | return (try mod.intern(.{ .opt = .{ |
| 29399 | const ptr_val = try sema.refValue(block, ty, val); | 29403 | .ty = (try mod.optionalType((try mod.singleConstPtrType(Type.anyopaque)).toIntern())).toIntern(), |
| 29400 | const result = try mod.intern(.{ .opt = .{ | 29404 | .val = if (opt_val) |val| (try sema.refValue(block, ty, val)).toIntern() else .none, |
| 29401 | .ty = (try mod.optionalType((try mod.singleConstPtrType(ty)).toIntern())).toIntern(), | 29405 | } })).toValue(); |
| 29402 | .val = ptr_val.toIntern(), | ||
| 29403 | } }); | ||
| 29404 | return result.toValue(); | ||
| 29405 | } | 29406 | } |
| 29406 | 29407 | ||
| 29407 | fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref { | 29408 | fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -30603,7 +30604,7 @@ fn wrapErrorUnionPayload( | ... | @@ -30603,7 +30604,7 @@ fn wrapErrorUnionPayload( |
| 30603 | if (try sema.resolveMaybeUndefVal(coerced)) |val| { | 30604 | if (try sema.resolveMaybeUndefVal(coerced)) |val| { |
| 30604 | return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{ | 30605 | return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{ |
| 30605 | .ty = dest_ty.toIntern(), | 30606 | .ty = dest_ty.toIntern(), |
| 30606 | .val = .{ .payload = val.toIntern() }, | 30607 | .val = .{ .payload = try val.intern(dest_payload_ty, mod) }, |
| 30607 | } })).toValue()); | 30608 | } })).toValue()); |
| 30608 | } | 30609 | } |
| 30609 | try sema.requireRuntimeBlock(block, inst_src, null); | 30610 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | @@ -30647,7 +30648,12 @@ fn wrapErrorUnionSet( | ... | @@ -30647,7 +30648,12 @@ fn wrapErrorUnionSet( |
| 30647 | else => unreachable, | 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 | try sema.requireRuntimeBlock(block, inst_src, null); | 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,7 +33331,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { |
| 33325 | } | 33331 | } |
| 33326 | 33332 | ||
| 33327 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { | 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 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { | 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,21 +3267,28 @@ pub const DeclGen = struct { |
| 3267 | return llvm_ty.constInt(kv.value, .False); | 3267 | return llvm_ty.constInt(kv.value, .False); |
| 3268 | }, | 3268 | }, |
| 3269 | .error_union => |error_union| { | 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 | const payload_type = tv.ty.errorUnionPayload(mod); | 3283 | const payload_type = tv.ty.errorUnionPayload(mod); |
| 3271 | const is_pl = tv.val.errorUnionIsPayload(mod); | ||
| 3272 | |||
| 3273 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3284 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3274 | // We use the error type directly as the type. | 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); | 3286 | return dg.lowerValue(err_tv); |
| 3276 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); | ||
| 3277 | } | 3287 | } |
| 3278 | 3288 | ||
| 3279 | const payload_align = payload_type.abiAlignment(mod); | 3289 | const payload_align = payload_type.abiAlignment(mod); |
| 3280 | const error_align = Type.anyerror.abiAlignment(mod); | 3290 | const error_align = err_tv.ty.abiAlignment(mod); |
| 3281 | const llvm_error_value = try dg.lowerValue(.{ | 3291 | const llvm_error_value = try dg.lowerValue(err_tv); |
| 3282 | .ty = Type.anyerror, | ||
| 3283 | .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val, | ||
| 3284 | }); | ||
| 3285 | const llvm_payload_value = try dg.lowerValue(.{ | 3292 | const llvm_payload_value = try dg.lowerValue(.{ |
| 3286 | .ty = payload_type, | 3293 | .ty = payload_type, |
| 3287 | .val = switch (error_union.val) { | 3294 | .val = switch (error_union.val) { |
src/print_air.zig+1-1| ... | @@ -703,7 +703,7 @@ const Writer = struct { | ... | @@ -703,7 +703,7 @@ const Writer = struct { |
| 703 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | 703 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; |
| 704 | try w.writeOperand(s, inst, 0, pl_op.operand); | 704 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 705 | const name = w.air.nullTerminatedString(pl_op.payload); | 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 | fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 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,6 +347,43 @@ pub const Value = struct { |
| 347 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { | 347 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { |
| 348 | if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern()); | 348 | if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern()); |
| 349 | switch (val.tag()) { | 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 | .aggregate => { | 387 | .aggregate => { |
| 351 | const old_elems = val.castTag(.aggregate).?.data; | 388 | const old_elems = val.castTag(.aggregate).?.data; |
| 352 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); | 389 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); |
| ... | @@ -372,24 +409,74 @@ pub const Value = struct { | ... | @@ -372,24 +409,74 @@ pub const Value = struct { |
| 372 | .val = try pl.val.intern(ty.unionFieldType(pl.tag, mod), mod), | 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 | pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value { | 415 | pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value { |
| 380 | if (val.ip_index == .none) return val; | 416 | return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 381 | 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 | .aggregate => |aggregate| switch (aggregate.storage) { | 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 | .elems => |old_elems| { | 467 | .elems => |old_elems| { |
| 385 | const new_elems = try arena.alloc(Value, old_elems.len); | 468 | const new_elems = try arena.alloc(Value, old_elems.len); |
| 386 | for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = old_elem.toValue(); | 469 | for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = old_elem.toValue(); |
| 387 | return Tag.aggregate.create(arena, new_elems); | 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, | 474 | |
| 392 | } | 475 | .un => |un| Tag.@"union".create(arena, .{ |
| 476 | .tag = un.tag.toValue(), | ||
| 477 | .val = un.val.toValue(), | ||
| 478 | }), | ||
| 479 | }; | ||
| 393 | } | 480 | } |
| 394 | 481 | ||
| 395 | pub fn toIntern(val: Value) InternPool.Index { | 482 | pub fn toIntern(val: Value) InternPool.Index { |
| ... | @@ -1896,7 +1983,7 @@ pub const Value = struct { | ... | @@ -1896,7 +1983,7 @@ pub const Value = struct { |
| 1896 | 1983 | ||
| 1897 | /// Returns true if a Value is backed by a variable | 1984 | /// Returns true if a Value is backed by a variable |
| 1898 | pub fn isVariable(val: Value, mod: *Module) bool { | 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 | .variable => true, | 1987 | .variable => true, |
| 1901 | .ptr => |ptr| switch (ptr.addr) { | 1988 | .ptr => |ptr| switch (ptr.addr) { |
| 1902 | .decl => |decl_index| { | 1989 | .decl => |decl_index| { |
| ... | @@ -1919,28 +2006,25 @@ pub const Value = struct { | ... | @@ -1919,28 +2006,25 @@ pub const Value = struct { |
| 1919 | } | 2006 | } |
| 1920 | 2007 | ||
| 1921 | pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool { | 2008 | pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool { |
| 1922 | return switch (val.ip_index) { | 2009 | return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1923 | .none => false, | 2010 | .variable => |variable| variable.is_threadlocal, |
| 1924 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 2011 | .ptr => |ptr| switch (ptr.addr) { |
| 1925 | .variable => |variable| variable.is_threadlocal, | 2012 | .decl => |decl_index| { |
| 1926 | .ptr => |ptr| switch (ptr.addr) { | 2013 | const decl = mod.declPtr(decl_index); |
| 1927 | .decl => |decl_index| { | 2014 | assert(decl.has_tv); |
| 1928 | const decl = mod.declPtr(decl_index); | 2015 | return decl.val.isPtrToThreadLocal(mod); |
| 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), | ||
| 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,6 +681,7 @@ def __lldb_init_module(debugger, _=None): |
| 681 | add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True) | 681 | add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True) |
| 682 | add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True) | 682 | add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True) |
| 683 | add(debugger, category='zig.stage2', type='Module.Decl::Module.Decl.Index', synth=True) | 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 | add(debugger, category='zig.stage2', type='InternPool.Index', synth=True) | 685 | add(debugger, category='zig.stage2', type='InternPool.Index', synth=True) |
| 685 | add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True) | 686 | add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True) |
| 686 | add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True) | 687 | add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True) |