diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-20 21:45:11 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-20 21:45:11 -0700 |
| commit | a0e195120dd3dd7919fd249a6ce2201da9395898 (patch) | |
| tree | 1f06851929602eb29932c60418e774f0cb1cab03 /src/value.zig | |
| parent | 3b2e25ed8718d8aee085497886967fa21a9697cc (diff) | |
| download | zig-a0e195120dd3dd7919fd249a6ce2201da9395898.tar.gz zig-a0e195120dd3dd7919fd249a6ce2201da9395898.zip | |
stage2: implement slicing
* New AIR instruction: slice, which constructs a slice out of a pointer
and a length.
* AstGen: use `coerced_ty` for start and end expressions, use `none`
for the sentinel, and don't try to load the result of the slice
operation because it returns a by-value result.
* Sema: pointer arithmetic is extracted into analyzePointerArithmetic
and it is used by the implementation of slice.
- Also I implemented comptime pointer addition.
* Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them
inside the slice semantic analysis.
- The approach in stage2 is much cleaner than stage1 because it uses
more granular analysis calls for obtaining the slice pointer, doing
arithmetic on it, and checking if the length is comptime-known.
* Sema: use the slice Value Tag for slices when doing coercion from
pointer-to-array.
* LLVM backend: detect when emitting a GEP instruction into a
pointer-to-array and add the extra index that is required.
* Type: ptrAlignment for c_void returns 0.
* Implement Value.hash and Value.eql for slices.
* Remove accidentally duplicated behavior test.
Diffstat (limited to 'src/value.zig')
| -rw-r--r-- | src/value.zig | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/value.zig b/src/value.zig index 7c24cdab81..f1ca384b75 100644 --- a/src/value.zig +++ b/src/value.zig @@ -761,6 +761,7 @@ pub const Value = extern union { return decl_val.toAllocatedBytes(decl.ty, allocator); }, .the_only_possible_value => return &[_]u8{}, + .slice => return toAllocatedBytes(val.castTag(.slice).?.data.ptr, ty, allocator), else => unreachable, } } @@ -1402,6 +1403,16 @@ pub const Value = extern union { var buffer: Type.Payload.ElemType = undefined; return eql(a_payload, b_payload, ty.optionalChild(&buffer)); }, + .slice => { + const a_payload = a.castTag(.slice).?.data; + const b_payload = b.castTag(.slice).?.data; + if (!eql(a_payload.len, b_payload.len, Type.usize)) return false; + + var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; + const ptr_ty = ty.slicePtrFieldType(&ptr_buf); + + return eql(a_payload.ptr, b_payload.ptr, ptr_ty); + }, .elem_ptr => @panic("TODO: Implement more pointer eql cases"), .field_ptr => @panic("TODO: Implement more pointer eql cases"), .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"), @@ -1475,6 +1486,14 @@ pub const Value = extern union { .variable, => std.hash.autoHash(hasher, val.pointerDecl().?), + .slice => { + const slice = val.castTag(.slice).?.data; + var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; + const ptr_ty = ty.slicePtrFieldType(&ptr_buf); + hash(slice.ptr, ptr_ty, hasher); + hash(slice.len, Type.usize, hasher); + }, + .elem_ptr => @panic("TODO: Implement more pointer hashing cases"), .field_ptr => @panic("TODO: Implement more pointer hashing cases"), .eu_payload_ptr => @panic("TODO: Implement more pointer hashing cases"), |
