diff options
| author | Cody Tapscott <topolarity@tapscott.me> | 2022-03-10 18:10:41 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-14 21:42:42 -0700 |
| commit | bbd750ff05895f29be646bf51e8932c3c9fb14f3 (patch) | |
| tree | eb76c4342ad12581cbf84289a692de18ead005ab /src | |
| parent | a2a5d3c2885cacf16d55d7943d10a81a5dc31b8a (diff) | |
| download | zig-bbd750ff05895f29be646bf51e8932c3c9fb14f3.tar.gz zig-bbd750ff05895f29be646bf51e8932c3c9fb14f3.zip | |
stage2: Add container_ty/elem_ty to elem_ptr, field_ptr, *_payload_ptr Values
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 45 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 4 | ||||
| -rw-r--r-- | src/value.zig | 98 |
3 files changed, 92 insertions, 55 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index b339e4374d..5fa7866586 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5568,7 +5568,10 @@ fn analyzeOptionalPayloadPtr( } return sema.addConstant( child_pointer, - try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val), + try Value.Tag.opt_payload_ptr.create(sema.arena, .{ + .container_ptr = ptr_val, + .container_ty = optional_ptr_ty.childType(), + }), ); } if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| { @@ -5578,7 +5581,10 @@ fn analyzeOptionalPayloadPtr( // The same Value represents the pointer to the optional and the payload. return sema.addConstant( child_pointer, - try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val), + try Value.Tag.opt_payload_ptr.create(sema.arena, .{ + .container_ptr = ptr_val, + .container_ty = optional_ptr_ty.childType(), + }), ); } } @@ -5733,7 +5739,10 @@ fn analyzeErrUnionPayloadPtr( } return sema.addConstant( operand_pointer_ty, - try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val), + try Value.Tag.eu_payload_ptr.create(sema.arena, .{ + .container_ptr = ptr_val, + .container_ty = operand_ty.elemType(), + }), ); } if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| { @@ -5743,7 +5752,10 @@ fn analyzeErrUnionPayloadPtr( return sema.addConstant( operand_pointer_ty, - try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val), + try Value.Tag.eu_payload_ptr.create(sema.arena, .{ + .container_ptr = ptr_val, + .container_ty = operand_ty.elemType(), + }), ); } } @@ -6652,6 +6664,7 @@ fn zirSwitchCapture( field_ty_ptr, try Value.Tag.field_ptr.create(sema.arena, .{ .container_ptr = op_ptr_val, + .container_ty = operand_ty, .field_index = field_index, }), ); @@ -9638,7 +9651,7 @@ fn analyzePtrArithmetic( if (air_tag == .ptr_sub) { return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{}); } - const new_ptr_val = try ptr_val.elemPtr(sema.arena, offset_int); + const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int); return sema.addConstant(new_ptr_ty, new_ptr_val); } else break :rs offset_src; } else break :rs ptr_src; @@ -15903,6 +15916,7 @@ fn finishFieldCallBind( ptr_field_ty, try Value.Tag.field_ptr.create(arena, .{ .container_ptr = struct_ptr_val, + .container_ty = ptr_ty.childType(), .field_index = field_index, }), ); @@ -16065,6 +16079,7 @@ fn structFieldPtrByIndex( ptr_field_ty, try Value.Tag.field_ptr.create(sema.arena, .{ .container_ptr = struct_ptr_val, + .container_ty = struct_ptr_ty.childType(), .field_index = field_index, }), ); @@ -16241,6 +16256,7 @@ fn unionFieldPtr( ptr_field_ty, try Value.Tag.field_ptr.create(arena, .{ .container_ptr = union_ptr_val, + .container_ty = union_ty, .field_index = field_index, }), ); @@ -16333,7 +16349,7 @@ fn elemPtr( const runtime_src = if (maybe_slice_val) |slice_val| rs: { const index_val = maybe_index_val orelse break :rs elem_index_src; const index = @intCast(usize, index_val.toUnsignedInt()); - const elem_ptr = try slice_val.elemPtr(sema.arena, index); + const elem_ptr = try slice_val.elemPtr(array_ty, sema.arena, index); return sema.addConstant(result_ty, elem_ptr); } else array_ptr_src; @@ -16348,7 +16364,7 @@ fn elemPtr( const ptr_val = maybe_ptr_val orelse break :rs array_ptr_src; const index_val = maybe_index_val orelse break :rs elem_index_src; const index = @intCast(usize, index_val.toUnsignedInt()); - const elem_ptr = try ptr_val.elemPtr(sema.arena, index); + const elem_ptr = try ptr_val.elemPtr(array_ty, sema.arena, index); return sema.addConstant(result_ty, elem_ptr); }; @@ -16473,6 +16489,7 @@ fn tupleFieldPtr( ptr_field_ty, try Value.Tag.field_ptr.create(sema.arena, .{ .container_ptr = tuple_ptr_val, + .container_ty = tuple_ty, .field_index = field_index, }), ); @@ -16563,7 +16580,7 @@ fn elemPtrArray( const index_u64 = index_val.toUnsignedInt(); // @intCast here because it would have been impossible to construct a value that // required a larger index. - const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64)); + const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, @intCast(usize, index_u64)); return sema.addConstant(result_ty, elem_ptr); } } @@ -17757,8 +17774,8 @@ fn beginComptimePtrMutation( } }, .eu_payload_ptr => { - const eu_ptr_val = ptr_val.castTag(.eu_payload_ptr).?.data; - var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr_val); + const eu_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; + var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr.container_ptr); const payload_ty = parent.ty.errorUnionPayload(); switch (parent.val.tag()) { else => { @@ -17790,8 +17807,8 @@ fn beginComptimePtrMutation( } }, .opt_payload_ptr => { - const opt_ptr_val = ptr_val.castTag(.opt_payload_ptr).?.data; - var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr_val); + const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; + var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr.container_ptr); const payload_ty = try parent.ty.optionalChildAlloc(sema.arena); switch (parent.val.tag()) { .undef, .null_value => { @@ -17965,7 +17982,7 @@ fn beginComptimePtrLoad( }, .eu_payload_ptr => { const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; - const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr); + const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr.container_ptr); return ComptimePtrLoadKit{ .root_val = parent.root_val, .root_ty = parent.root_ty, @@ -17977,7 +17994,7 @@ fn beginComptimePtrLoad( }, .opt_payload_ptr => { const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; - const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr); + const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr.container_ptr); return ComptimePtrLoadKit{ .root_val = parent.root_val, .root_ty = parent.root_ty, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 7c4455f296..01f7d60a53 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2901,7 +2901,7 @@ pub const DeclGen = struct { }, .opt_payload_ptr => { const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; - const parent = try dg.lowerParentPtr(opt_payload_ptr, base_ty); + const parent = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, base_ty); var buf: Type.Payload.ElemType = undefined; const payload_ty = parent.ty.optionalChild(&buf); if (!payload_ty.hasRuntimeBitsIgnoreComptime() or parent.ty.isPtrLikeOptional()) { @@ -2925,7 +2925,7 @@ pub const DeclGen = struct { }, .eu_payload_ptr => { const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; - const parent = try dg.lowerParentPtr(eu_payload_ptr, base_ty); + const parent = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, base_ty); const payload_ty = parent.ty.errorUnionPayload(); if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { // In this case, we represent pointer to error union the same as pointer diff --git a/src/value.zig b/src/value.zig index c6e201d3f8..f997b554a3 100644 --- a/src/value.zig +++ b/src/value.zig @@ -268,12 +268,14 @@ pub const Value = extern union { .repeated, .eu_payload, - .eu_payload_ptr, .opt_payload, - .opt_payload_ptr, .empty_array_sentinel, => Payload.SubValue, + .eu_payload_ptr, + .opt_payload_ptr, + => Payload.PayloadPtr, + .bytes, .enum_literal, => Payload.Bytes, @@ -479,6 +481,20 @@ pub const Value = extern union { .variable => return self.copyPayloadShallow(arena, Payload.Variable), .decl_ref => return self.copyPayloadShallow(arena, Payload.Decl), .decl_ref_mut => return self.copyPayloadShallow(arena, Payload.DeclRefMut), + .eu_payload_ptr, + .opt_payload_ptr, + => { + const payload = self.cast(Payload.PayloadPtr).?; + const new_payload = try arena.create(Payload.PayloadPtr); + new_payload.* = .{ + .base = payload.base, + .data = .{ + .container_ptr = try payload.data.container_ptr.copy(arena), + .container_ty = try payload.data.container_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); @@ -486,6 +502,7 @@ pub const Value = extern union { .base = payload.base, .data = .{ .array_ptr = try payload.data.array_ptr.copy(arena), + .elem_ty = try payload.data.elem_ty.copy(arena), .index = payload.data.index, }, }; @@ -498,6 +515,7 @@ pub const Value = extern union { .base = payload.base, .data = .{ .container_ptr = try payload.data.container_ptr.copy(arena), + .container_ty = try payload.data.container_ty.copy(arena), .field_index = payload.data.field_index, }, }; @@ -506,9 +524,7 @@ pub const Value = extern union { .bytes => return self.copyPayloadShallow(arena, Payload.Bytes), .repeated, .eu_payload, - .eu_payload_ptr, .opt_payload, - .opt_payload_ptr, .empty_array_sentinel, => { const payload = self.cast(Payload.SubValue).?; @@ -740,11 +756,11 @@ pub const Value = extern union { .inferred_alloc_comptime => return out_stream.writeAll("(inferred comptime allocation value)"), .eu_payload_ptr => { try out_stream.writeAll("(eu_payload_ptr)"); - val = val.castTag(.eu_payload_ptr).?.data; + val = val.castTag(.eu_payload_ptr).?.data.container_ptr; }, .opt_payload_ptr => { try out_stream.writeAll("(opt_payload_ptr)"); - val = val.castTag(.opt_payload_ptr).?.data; + val = val.castTag(.opt_payload_ptr).?.data.container_ptr; }, .bound_fn => { const bound_func = val.castTag(.bound_fn).?.data; @@ -2162,8 +2178,8 @@ pub const Value = extern union { .decl_ref_mut => 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), - .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data), + .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr), + .opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data.container_ptr), else => false, }; @@ -2174,9 +2190,9 @@ pub const Value = extern union { switch (val.tag()) { .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(), .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(), - .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(), + .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(), .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(), - .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(), + .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(), .aggregate => { const fields = val.castTag(.aggregate).?.data; for (fields) |field| { @@ -2239,12 +2255,12 @@ pub const Value = extern union { .eu_payload_ptr => { const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr); - hashPtr(err_union_ptr, hasher); + hashPtr(err_union_ptr.container_ptr, hasher); }, .opt_payload_ptr => { const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr); - hashPtr(opt_ptr, hasher); + hashPtr(opt_ptr.container_ptr, hasher); }, .zero, @@ -2272,12 +2288,14 @@ pub const Value = extern union { .repeated, .eu_payload, - .eu_payload_ptr, .opt_payload, - .opt_payload_ptr, .empty_array_sentinel, => return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data), + .eu_payload_ptr, + .opt_payload_ptr, + => return markReferencedDeclsAlive(val.cast(Payload.PayloadPtr).?.data.container_ptr), + .slice => { const slice = val.cast(Payload.Slice).?.data; markReferencedDeclsAlive(slice.ptr); @@ -2422,36 +2440,28 @@ pub const Value = extern union { } /// Returns a pointer to the element value at the index. - pub fn elemPtr(val: Value, arena: Allocator, index: usize) Allocator.Error!Value { - switch (val.tag()) { - .elem_ptr => { - const elem_ptr = val.castTag(.elem_ptr).?.data; + pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value { + const elem_ty = ty.elemType2(); + const ptr_val = switch (val.tag()) { + .slice => val.slicePtr(), + else => val, + }; + + if (ptr_val.tag() == .elem_ptr) { + const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; + if (elem_ptr.elem_ty.eql(elem_ty)) { return Tag.elem_ptr.create(arena, .{ .array_ptr = elem_ptr.array_ptr, + .elem_ty = elem_ptr.elem_ty, .index = elem_ptr.index + index, }); - }, - .slice => { - const ptr_val = val.castTag(.slice).?.data.ptr; - switch (ptr_val.tag()) { - .elem_ptr => { - const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; - return Tag.elem_ptr.create(arena, .{ - .array_ptr = elem_ptr.array_ptr, - .index = elem_ptr.index + index, - }); - }, - else => return Tag.elem_ptr.create(arena, .{ - .array_ptr = ptr_val, - .index = index, - }), - } - }, - else => return Tag.elem_ptr.create(arena, .{ - .array_ptr = val, - .index = index, - }), + } } + return Tag.elem_ptr.create(arena, .{ + .array_ptr = ptr_val, + .elem_ty = elem_ty, + .index = index, + }); } pub fn isUndef(self: Value) bool { @@ -4144,12 +4154,21 @@ pub const Value = extern union { }; }; + pub const PayloadPtr = struct { + base: Payload, + data: struct { + container_ptr: Value, + container_ty: Type, + }, + }; + pub const ElemPtr = struct { pub const base_tag = Tag.elem_ptr; base: Payload = Payload{ .tag = base_tag }, data: struct { array_ptr: Value, + elem_ty: Type, index: usize, }, }; @@ -4160,6 +4179,7 @@ pub const Value = extern union { base: Payload = Payload{ .tag = base_tag }, data: struct { container_ptr: Value, + container_ty: Type, field_index: usize, }, }; |
