diff options
Diffstat (limited to 'src/value.zig')
| -rw-r--r-- | src/value.zig | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/src/value.zig b/src/value.zig index a80d788894..21fe52e706 100644 --- a/src/value.zig +++ b/src/value.zig @@ -30,6 +30,7 @@ pub const Value = extern union { i8_type, u16_type, i16_type, + u29_type, u32_type, i32_type, u64_type, @@ -120,6 +121,8 @@ pub const Value = extern union { /// This Tag will never be seen by machine codegen backends. It is changed into a /// `decl_ref` when a comptime variable goes out of scope. decl_ref_mut, + /// Behaves like `decl_ref_mut` but validates that the stored value matches the field value. + comptime_field_ptr, /// Pointer to a specific element of an array, vector or slice. elem_ptr, /// Pointer to a specific field of a struct or union. @@ -194,6 +197,7 @@ pub const Value = extern union { .i8_type, .u16_type, .i16_type, + .u29_type, .u32_type, .i32_type, .u64_type, @@ -316,6 +320,7 @@ pub const Value = extern union { .aggregate => Payload.Aggregate, .@"union" => Payload.Union, .bound_fn => Payload.BoundFn, + .comptime_field_ptr => Payload.ComptimeFieldPtr, }; } @@ -394,6 +399,7 @@ pub const Value = extern union { .i8_type, .u16_type, .i16_type, + .u29_type, .u32_type, .i32_type, .u64_type, @@ -506,6 +512,18 @@ pub const Value = extern union { }; return Value{ .ptr_otherwise = &new_payload.base }; }, + .comptime_field_ptr => { + const payload = self.cast(Payload.ComptimeFieldPtr).?; + const new_payload = try arena.create(Payload.ComptimeFieldPtr); + new_payload.* = .{ + .base = payload.base, + .data = .{ + .field_val = try payload.data.field_val.copy(arena), + .field_ty = try payload.data.field_ty.copy(arena), + }, + }; + return Value{ .ptr_otherwise = &new_payload.base }; + }, .elem_ptr => { const payload = self.castTag(.elem_ptr).?; const new_payload = try arena.create(Payload.ElemPtr); @@ -645,6 +663,7 @@ pub const Value = extern union { .u8_type => return out_stream.writeAll("u8"), .i8_type => return out_stream.writeAll("i8"), .u16_type => return out_stream.writeAll("u16"), + .u29_type => return out_stream.writeAll("u29"), .i16_type => return out_stream.writeAll("i16"), .u32_type => return out_stream.writeAll("u32"), .i32_type => return out_stream.writeAll("i32"), @@ -754,6 +773,9 @@ pub const Value = extern union { const decl_index = val.castTag(.decl_ref).?.data; return out_stream.print("(decl_ref {d})", .{decl_index}); }, + .comptime_field_ptr => { + return out_stream.writeAll("(comptime_field_ptr)"); + }, .elem_ptr => { const elem_ptr = val.castTag(.elem_ptr).?.data; try out_stream.print("&[{}] ", .{elem_ptr.index}); @@ -882,6 +904,7 @@ pub const Value = extern union { .i8_type => Type.initTag(.i8), .u16_type => Type.initTag(.u16), .i16_type => Type.initTag(.i16), + .u29_type => Type.initTag(.u29), .u32_type => Type.initTag(.u32), .i32_type => Type.initTag(.i32), .u64_type => Type.initTag(.u64), @@ -1706,6 +1729,7 @@ pub const Value = extern union { .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(), .decl_ref_mut, + .comptime_field_ptr, .extern_fn, .decl_ref, .function, @@ -1770,6 +1794,7 @@ pub const Value = extern union { .bool_true, .decl_ref, .decl_ref_mut, + .comptime_field_ptr, .extern_fn, .function, .variable, @@ -2362,7 +2387,7 @@ pub const Value = extern union { pub fn isComptimeMutablePtr(val: Value) bool { return switch (val.tag()) { - .decl_ref_mut => true, + .decl_ref_mut, .comptime_field_ptr => true, .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr), .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr), .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr), @@ -2426,6 +2451,9 @@ pub const Value = extern union { const decl: Module.Decl.Index = ptr_val.pointerDecl().?; std.hash.autoHash(hasher, decl); }, + .comptime_field_ptr => { + std.hash.autoHash(hasher, Value.Tag.comptime_field_ptr); + }, .elem_ptr => { const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; @@ -2471,7 +2499,7 @@ pub const Value = extern union { return switch (val.tag()) { .slice => val.castTag(.slice).?.data.ptr, // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc. - .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr => val, + .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr, .comptime_field_ptr => val, else => unreachable, }; } @@ -2497,6 +2525,14 @@ pub const Value = extern union { return 1; } }, + .comptime_field_ptr => { + const payload = val.castTag(.comptime_field_ptr).?.data; + if (payload.field_ty.zigTypeTag() == .Array) { + return payload.field_ty.arrayLen(); + } else { + return 1; + } + }, else => unreachable, }; } @@ -2587,6 +2623,7 @@ pub const Value = extern union { .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer), .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer), + .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer), .elem_ptr => { const data = val.castTag(.elem_ptr).?.data; return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer); @@ -2623,6 +2660,7 @@ pub const Value = extern union { .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end), .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end), + .comptime_field_ptr => sliceArray(val.castTag(.comptime_field_ptr).?.data.field_val, mod, arena, start, end), .elem_ptr => blk: { const elem_ptr = val.castTag(.elem_ptr).?.data; break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index); @@ -4742,6 +4780,14 @@ pub const Value = extern union { }, }; + pub const ComptimeFieldPtr = struct { + base: Payload, + data: struct { + field_val: Value, + field_ty: Type, + }, + }; + pub const ElemPtr = struct { pub const base_tag = Tag.elem_ptr; @@ -4864,7 +4910,7 @@ pub const Value = extern union { /// `Module.resolvePeerTypes`. stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{}, /// 0 means ABI-aligned. - alignment: u16, + alignment: u32, }, }; @@ -4875,7 +4921,7 @@ pub const Value = extern union { data: struct { decl_index: Module.Decl.Index, /// 0 means ABI-aligned. - alignment: u16, + alignment: u32, }, }; |
