authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-10 18:10:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-14 21:42:42-07:00
logbbd750ff05895f29be646bf51e8932c3c9fb14f3
treeeb76c4342ad12581cbf84289a692de18ead005ab
parenta2a5d3c2885cacf16d55d7943d10a81a5dc31b8a

stage2: Add container_ty/elem_ty to elem_ptr, field_ptr, *_payload_ptr Values


3 files changed, 92 insertions(+), 55 deletions(-)

src/Sema.zig+31-14
......@@ -5568,7 +5568,10 @@ fn analyzeOptionalPayloadPtr(
55685568 }
55695569 return sema.addConstant(
55705570 child_pointer,
5571 try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val),
5571 try Value.Tag.opt_payload_ptr.create(sema.arena, .{
5572 .container_ptr = ptr_val,
5573 .container_ty = optional_ptr_ty.childType(),
5574 }),
55725575 );
55735576 }
55745577 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
......@@ -5578,7 +5581,10 @@ fn analyzeOptionalPayloadPtr(
55785581 // The same Value represents the pointer to the optional and the payload.
55795582 return sema.addConstant(
55805583 child_pointer,
5581 try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val),
5584 try Value.Tag.opt_payload_ptr.create(sema.arena, .{
5585 .container_ptr = ptr_val,
5586 .container_ty = optional_ptr_ty.childType(),
5587 }),
55825588 );
55835589 }
55845590 }
......@@ -5733,7 +5739,10 @@ fn analyzeErrUnionPayloadPtr(
57335739 }
57345740 return sema.addConstant(
57355741 operand_pointer_ty,
5736 try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val),
5742 try Value.Tag.eu_payload_ptr.create(sema.arena, .{
5743 .container_ptr = ptr_val,
5744 .container_ty = operand_ty.elemType(),
5745 }),
57375746 );
57385747 }
57395748 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
......@@ -5743,7 +5752,10 @@ fn analyzeErrUnionPayloadPtr(
57435752
57445753 return sema.addConstant(
57455754 operand_pointer_ty,
5746 try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val),
5755 try Value.Tag.eu_payload_ptr.create(sema.arena, .{
5756 .container_ptr = ptr_val,
5757 .container_ty = operand_ty.elemType(),
5758 }),
57475759 );
57485760 }
57495761 }
......@@ -6652,6 +6664,7 @@ fn zirSwitchCapture(
66526664 field_ty_ptr,
66536665 try Value.Tag.field_ptr.create(sema.arena, .{
66546666 .container_ptr = op_ptr_val,
6667 .container_ty = operand_ty,
66556668 .field_index = field_index,
66566669 }),
66576670 );
......@@ -9638,7 +9651,7 @@ fn analyzePtrArithmetic(
96389651 if (air_tag == .ptr_sub) {
96399652 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
96409653 }
9641 const new_ptr_val = try ptr_val.elemPtr(sema.arena, offset_int);
9654 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int);
96429655 return sema.addConstant(new_ptr_ty, new_ptr_val);
96439656 } else break :rs offset_src;
96449657 } else break :rs ptr_src;
......@@ -15903,6 +15916,7 @@ fn finishFieldCallBind(
1590315916 ptr_field_ty,
1590415917 try Value.Tag.field_ptr.create(arena, .{
1590515918 .container_ptr = struct_ptr_val,
15919 .container_ty = ptr_ty.childType(),
1590615920 .field_index = field_index,
1590715921 }),
1590815922 );
......@@ -16065,6 +16079,7 @@ fn structFieldPtrByIndex(
1606516079 ptr_field_ty,
1606616080 try Value.Tag.field_ptr.create(sema.arena, .{
1606716081 .container_ptr = struct_ptr_val,
16082 .container_ty = struct_ptr_ty.childType(),
1606816083 .field_index = field_index,
1606916084 }),
1607016085 );
......@@ -16241,6 +16256,7 @@ fn unionFieldPtr(
1624116256 ptr_field_ty,
1624216257 try Value.Tag.field_ptr.create(arena, .{
1624316258 .container_ptr = union_ptr_val,
16259 .container_ty = union_ty,
1624416260 .field_index = field_index,
1624516261 }),
1624616262 );
......@@ -16333,7 +16349,7 @@ fn elemPtr(
1633316349 const runtime_src = if (maybe_slice_val) |slice_val| rs: {
1633416350 const index_val = maybe_index_val orelse break :rs elem_index_src;
1633516351 const index = @intCast(usize, index_val.toUnsignedInt());
16336 const elem_ptr = try slice_val.elemPtr(sema.arena, index);
16352 const elem_ptr = try slice_val.elemPtr(array_ty, sema.arena, index);
1633716353 return sema.addConstant(result_ty, elem_ptr);
1633816354 } else array_ptr_src;
1633916355
......@@ -16348,7 +16364,7 @@ fn elemPtr(
1634816364 const ptr_val = maybe_ptr_val orelse break :rs array_ptr_src;
1634916365 const index_val = maybe_index_val orelse break :rs elem_index_src;
1635016366 const index = @intCast(usize, index_val.toUnsignedInt());
16351 const elem_ptr = try ptr_val.elemPtr(sema.arena, index);
16367 const elem_ptr = try ptr_val.elemPtr(array_ty, sema.arena, index);
1635216368 return sema.addConstant(result_ty, elem_ptr);
1635316369 };
1635416370
......@@ -16473,6 +16489,7 @@ fn tupleFieldPtr(
1647316489 ptr_field_ty,
1647416490 try Value.Tag.field_ptr.create(sema.arena, .{
1647516491 .container_ptr = tuple_ptr_val,
16492 .container_ty = tuple_ty,
1647616493 .field_index = field_index,
1647716494 }),
1647816495 );
......@@ -16563,7 +16580,7 @@ fn elemPtrArray(
1656316580 const index_u64 = index_val.toUnsignedInt();
1656416581 // @intCast here because it would have been impossible to construct a value that
1656516582 // required a larger index.
16566 const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
16583 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, @intCast(usize, index_u64));
1656716584 return sema.addConstant(result_ty, elem_ptr);
1656816585 }
1656916586 }
......@@ -17757,8 +17774,8 @@ fn beginComptimePtrMutation(
1775717774 }
1775817775 },
1775917776 .eu_payload_ptr => {
17760 const eu_ptr_val = ptr_val.castTag(.eu_payload_ptr).?.data;
17761 var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr_val);
17777 const eu_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
17778 var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr.container_ptr);
1776217779 const payload_ty = parent.ty.errorUnionPayload();
1776317780 switch (parent.val.tag()) {
1776417781 else => {
......@@ -17790,8 +17807,8 @@ fn beginComptimePtrMutation(
1779017807 }
1779117808 },
1779217809 .opt_payload_ptr => {
17793 const opt_ptr_val = ptr_val.castTag(.opt_payload_ptr).?.data;
17794 var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr_val);
17810 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
17811 var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr.container_ptr);
1779517812 const payload_ty = try parent.ty.optionalChildAlloc(sema.arena);
1779617813 switch (parent.val.tag()) {
1779717814 .undef, .null_value => {
......@@ -17965,7 +17982,7 @@ fn beginComptimePtrLoad(
1796517982 },
1796617983 .eu_payload_ptr => {
1796717984 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
17968 const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr);
17985 const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr.container_ptr);
1796917986 return ComptimePtrLoadKit{
1797017987 .root_val = parent.root_val,
1797117988 .root_ty = parent.root_ty,
......@@ -17977,7 +17994,7 @@ fn beginComptimePtrLoad(
1797717994 },
1797817995 .opt_payload_ptr => {
1797917996 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
17980 const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr);
17997 const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr.container_ptr);
1798117998 return ComptimePtrLoadKit{
1798217999 .root_val = parent.root_val,
1798318000 .root_ty = parent.root_ty,
src/codegen/llvm.zig+2-2
......@@ -2901,7 +2901,7 @@ pub const DeclGen = struct {
29012901 },
29022902 .opt_payload_ptr => {
29032903 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
2904 const parent = try dg.lowerParentPtr(opt_payload_ptr, base_ty);
2904 const parent = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, base_ty);
29052905 var buf: Type.Payload.ElemType = undefined;
29062906 const payload_ty = parent.ty.optionalChild(&buf);
29072907 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or parent.ty.isPtrLikeOptional()) {
......@@ -2925,7 +2925,7 @@ pub const DeclGen = struct {
29252925 },
29262926 .eu_payload_ptr => {
29272927 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
2928 const parent = try dg.lowerParentPtr(eu_payload_ptr, base_ty);
2928 const parent = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, base_ty);
29292929 const payload_ty = parent.ty.errorUnionPayload();
29302930 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
29312931 // In this case, we represent pointer to error union the same as pointer
src/value.zig+59-39
......@@ -268,12 +268,14 @@ pub const Value = extern union {
268268
269269 .repeated,
270270 .eu_payload,
271 .eu_payload_ptr,
272271 .opt_payload,
273 .opt_payload_ptr,
274272 .empty_array_sentinel,
275273 => Payload.SubValue,
276274
275 .eu_payload_ptr,
276 .opt_payload_ptr,
277 => Payload.PayloadPtr,
278
277279 .bytes,
278280 .enum_literal,
279281 => Payload.Bytes,
......@@ -479,6 +481,20 @@ pub const Value = extern union {
479481 .variable => return self.copyPayloadShallow(arena, Payload.Variable),
480482 .decl_ref => return self.copyPayloadShallow(arena, Payload.Decl),
481483 .decl_ref_mut => return self.copyPayloadShallow(arena, Payload.DeclRefMut),
484 .eu_payload_ptr,
485 .opt_payload_ptr,
486 => {
487 const payload = self.cast(Payload.PayloadPtr).?;
488 const new_payload = try arena.create(Payload.PayloadPtr);
489 new_payload.* = .{
490 .base = payload.base,
491 .data = .{
492 .container_ptr = try payload.data.container_ptr.copy(arena),
493 .container_ty = try payload.data.container_ty.copy(arena),
494 },
495 };
496 return Value{ .ptr_otherwise = &new_payload.base };
497 },
482498 .elem_ptr => {
483499 const payload = self.castTag(.elem_ptr).?;
484500 const new_payload = try arena.create(Payload.ElemPtr);
......@@ -486,6 +502,7 @@ pub const Value = extern union {
486502 .base = payload.base,
487503 .data = .{
488504 .array_ptr = try payload.data.array_ptr.copy(arena),
505 .elem_ty = try payload.data.elem_ty.copy(arena),
489506 .index = payload.data.index,
490507 },
491508 };
......@@ -498,6 +515,7 @@ pub const Value = extern union {
498515 .base = payload.base,
499516 .data = .{
500517 .container_ptr = try payload.data.container_ptr.copy(arena),
518 .container_ty = try payload.data.container_ty.copy(arena),
501519 .field_index = payload.data.field_index,
502520 },
503521 };
......@@ -506,9 +524,7 @@ pub const Value = extern union {
506524 .bytes => return self.copyPayloadShallow(arena, Payload.Bytes),
507525 .repeated,
508526 .eu_payload,
509 .eu_payload_ptr,
510527 .opt_payload,
511 .opt_payload_ptr,
512528 .empty_array_sentinel,
513529 => {
514530 const payload = self.cast(Payload.SubValue).?;
......@@ -740,11 +756,11 @@ pub const Value = extern union {
740756 .inferred_alloc_comptime => return out_stream.writeAll("(inferred comptime allocation value)"),
741757 .eu_payload_ptr => {
742758 try out_stream.writeAll("(eu_payload_ptr)");
743 val = val.castTag(.eu_payload_ptr).?.data;
759 val = val.castTag(.eu_payload_ptr).?.data.container_ptr;
744760 },
745761 .opt_payload_ptr => {
746762 try out_stream.writeAll("(opt_payload_ptr)");
747 val = val.castTag(.opt_payload_ptr).?.data;
763 val = val.castTag(.opt_payload_ptr).?.data.container_ptr;
748764 },
749765 .bound_fn => {
750766 const bound_func = val.castTag(.bound_fn).?.data;
......@@ -2162,8 +2178,8 @@ pub const Value = extern union {
21622178 .decl_ref_mut => true,
21632179 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
21642180 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
2165 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data),
2166 .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data),
2181 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
2182 .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data.container_ptr),
21672183
21682184 else => false,
21692185 };
......@@ -2174,9 +2190,9 @@ pub const Value = extern union {
21742190 switch (val.tag()) {
21752191 .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
21762192 .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
2177 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(),
2193 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
21782194 .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
2179 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(),
2195 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
21802196 .aggregate => {
21812197 const fields = val.castTag(.aggregate).?.data;
21822198 for (fields) |field| {
......@@ -2239,12 +2255,12 @@ pub const Value = extern union {
22392255 .eu_payload_ptr => {
22402256 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
22412257 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2242 hashPtr(err_union_ptr, hasher);
2258 hashPtr(err_union_ptr.container_ptr, hasher);
22432259 },
22442260 .opt_payload_ptr => {
22452261 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
22462262 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2247 hashPtr(opt_ptr, hasher);
2263 hashPtr(opt_ptr.container_ptr, hasher);
22482264 },
22492265
22502266 .zero,
......@@ -2272,12 +2288,14 @@ pub const Value = extern union {
22722288
22732289 .repeated,
22742290 .eu_payload,
2275 .eu_payload_ptr,
22762291 .opt_payload,
2277 .opt_payload_ptr,
22782292 .empty_array_sentinel,
22792293 => return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
22802294
2295 .eu_payload_ptr,
2296 .opt_payload_ptr,
2297 => return markReferencedDeclsAlive(val.cast(Payload.PayloadPtr).?.data.container_ptr),
2298
22812299 .slice => {
22822300 const slice = val.cast(Payload.Slice).?.data;
22832301 markReferencedDeclsAlive(slice.ptr);
......@@ -2422,36 +2440,28 @@ pub const Value = extern union {
24222440 }
24232441
24242442 /// Returns a pointer to the element value at the index.
2425 pub fn elemPtr(val: Value, arena: Allocator, index: usize) Allocator.Error!Value {
2426 switch (val.tag()) {
2427 .elem_ptr => {
2428 const elem_ptr = val.castTag(.elem_ptr).?.data;
2443 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {
2444 const elem_ty = ty.elemType2();
2445 const ptr_val = switch (val.tag()) {
2446 .slice => val.slicePtr(),
2447 else => val,
2448 };
2449
2450 if (ptr_val.tag() == .elem_ptr) {
2451 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2452 if (elem_ptr.elem_ty.eql(elem_ty)) {
24292453 return Tag.elem_ptr.create(arena, .{
24302454 .array_ptr = elem_ptr.array_ptr,
2455 .elem_ty = elem_ptr.elem_ty,
24312456 .index = elem_ptr.index + index,
24322457 });
2433 },
2434 .slice => {
2435 const ptr_val = val.castTag(.slice).?.data.ptr;
2436 switch (ptr_val.tag()) {
2437 .elem_ptr => {
2438 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2439 return Tag.elem_ptr.create(arena, .{
2440 .array_ptr = elem_ptr.array_ptr,
2441 .index = elem_ptr.index + index,
2442 });
2443 },
2444 else => return Tag.elem_ptr.create(arena, .{
2445 .array_ptr = ptr_val,
2446 .index = index,
2447 }),
2448 }
2449 },
2450 else => return Tag.elem_ptr.create(arena, .{
2451 .array_ptr = val,
2452 .index = index,
2453 }),
2458 }
24542459 }
2460 return Tag.elem_ptr.create(arena, .{
2461 .array_ptr = ptr_val,
2462 .elem_ty = elem_ty,
2463 .index = index,
2464 });
24552465 }
24562466
24572467 pub fn isUndef(self: Value) bool {
......@@ -4144,12 +4154,21 @@ pub const Value = extern union {
41444154 };
41454155 };
41464156
4157 pub const PayloadPtr = struct {
4158 base: Payload,
4159 data: struct {
4160 container_ptr: Value,
4161 container_ty: Type,
4162 },
4163 };
4164
41474165 pub const ElemPtr = struct {
41484166 pub const base_tag = Tag.elem_ptr;
41494167
41504168 base: Payload = Payload{ .tag = base_tag },
41514169 data: struct {
41524170 array_ptr: Value,
4171 elem_ty: Type,
41534172 index: usize,
41544173 },
41554174 };
......@@ -4160,6 +4179,7 @@ pub const Value = extern union {
41604179 base: Payload = Payload{ .tag = base_tag },
41614180 data: struct {
41624181 container_ptr: Value,
4182 container_ty: Type,
41634183 field_index: usize,
41644184 },
41654185 };