| author | |
| committer | |
| log | 1d06c82c3bc44e808a3d7b4fe07e5c9fc492e8c3 |
| tree | ed247bb05f5a9b5855d931054eb6cd9da4f9f950 |
| parent | 5275b012020a7bb5de35120ca3e8f5d8d6ef2109 |
| parent | 9c35f680f73538b8c36121ff938cc0b19eadbb42 |
| signature |
remove @bytesToSlice, @sliceToBytes from the language28 files changed, 225 insertions(+), 589 deletions(-)
doc/langref.html.in+11-50| ... | ... | @@ -2025,7 +2025,8 @@ test "volatile" { |
| 2025 | 2025 | conversions are not possible. |
| 2026 | 2026 | </p> |
| 2027 | 2027 | {#code_begin|test#} |
| 2028 | const assert = @import("std").debug.assert; | |
| 2028 | const std = @import("std"); | |
| 2029 | const assert = std.debug.assert; | |
| 2029 | 2030 | |
| 2030 | 2031 | test "pointer casting" { |
| 2031 | 2032 | const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 }; |
| ... | ... | @@ -2034,7 +2035,7 @@ test "pointer casting" { |
| 2034 | 2035 | |
| 2035 | 2036 | // Even this example is contrived - there are better ways to do the above than |
| 2036 | 2037 | // pointer casting. For example, using a slice narrowing cast: |
| 2037 | const u32_value = @bytesToSlice(u32, bytes[0..])[0]; | |
| 2038 | const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0]; | |
| 2038 | 2039 | assert(u32_value == 0x12121212); |
| 2039 | 2040 | |
| 2040 | 2041 | // And even another way, the most straightforward way to do it: |
| ... | ... | @@ -2114,16 +2115,16 @@ test "function alignment" { |
| 2114 | 2115 | {#link|safety check|Incorrect Pointer Alignment#}: |
| 2115 | 2116 | </p> |
| 2116 | 2117 | {#code_begin|test_safety|incorrect alignment#} |
| 2117 | const assert = @import("std").debug.assert; | |
| 2118 | const std = @import("std"); | |
| 2118 | 2119 | |
| 2119 | 2120 | test "pointer alignment safety" { |
| 2120 | 2121 | var array align(4) = [_]u32{ 0x11111111, 0x11111111 }; |
| 2121 | const bytes = @sliceToBytes(array[0..]); | |
| 2122 | assert(foo(bytes) == 0x11111111); | |
| 2122 | const bytes = std.mem.sliceAsBytes(array[0..]); | |
| 2123 | std.debug.assert(foo(bytes) == 0x11111111); | |
| 2123 | 2124 | } |
| 2124 | 2125 | fn foo(bytes: []u8) u32 { |
| 2125 | 2126 | const slice4 = bytes[1..5]; |
| 2126 | const int_slice = @bytesToSlice(u32, @alignCast(4, slice4)); | |
| 2127 | const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4)); | |
| 2127 | 2128 | return int_slice[0]; |
| 2128 | 2129 | } |
| 2129 | 2130 | {#code_end#} |
| ... | ... | @@ -2249,7 +2250,7 @@ test "slice widening" { |
| 2249 | 2250 | // Zig supports slice widening and slice narrowing. Cast a slice of u8 |
| 2250 | 2251 | // to a slice of anything else, and Zig will perform the length conversion. |
| 2251 | 2252 | const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 }; |
| 2252 | const slice = @bytesToSlice(u32, array[0..]); | |
| 2253 | const slice = mem.bytesAsSlice(u32, array[0..]); | |
| 2253 | 2254 | assert(slice.len == 2); |
| 2254 | 2255 | assert(slice[0] == 0x12121212); |
| 2255 | 2256 | assert(slice[1] == 0x13131313); |
| ... | ... | @@ -5186,7 +5187,6 @@ test "coercion of zero bit types" { |
| 5186 | 5187 | <li>{#link|@bitCast#} - change type but maintain bit representation</li> |
| 5187 | 5188 | <li>{#link|@alignCast#} - make a pointer have more alignment</li> |
| 5188 | 5189 | <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li> |
| 5189 | <li>{#link|@bytesToSlice#} - convert a slice of bytes to a slice of another type</li> | |
| 5190 | 5190 | <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li> |
| 5191 | 5191 | <li>{#link|@errSetCast#} - convert to a smaller error set</li> |
| 5192 | 5192 | <li>{#link|@errorToInt#} - obtain the integer value of an error code</li> |
| ... | ... | @@ -5199,7 +5199,6 @@ test "coercion of zero bit types" { |
| 5199 | 5199 | <li>{#link|@intToPtr#} - convert an address to a pointer</li> |
| 5200 | 5200 | <li>{#link|@ptrCast#} - convert between pointer types</li> |
| 5201 | 5201 | <li>{#link|@ptrToInt#} - obtain the address of a pointer</li> |
| 5202 | <li>{#link|@sliceToBytes#} - convert a slice of anything to a slice of bytes</li> | |
| 5203 | 5202 | <li>{#link|@truncate#} - convert between integer types, chopping off bits</li> |
| 5204 | 5203 | </ul> |
| 5205 | 5204 | {#header_close#} |
| ... | ... | @@ -6929,18 +6928,6 @@ async fn func(y: *i32) void { |
| 6929 | 6928 | {#see_also|@bitOffsetOf#} |
| 6930 | 6929 | {#header_close#} |
| 6931 | 6930 | |
| 6932 | {#header_open|@bytesToSlice#} | |
| 6933 | <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre> | |
| 6934 | <p> | |
| 6935 | Converts a slice of bytes or array of bytes into a slice of {#syntax#}Element{#endsyntax#}. | |
| 6936 | The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter. | |
| 6937 | </p> | |
| 6938 | <p> | |
| 6939 | Attempting to convert a number of bytes with a length that does not evenly divide into a slice of | |
| 6940 | elements results in safety-protected {#link|Undefined Behavior#}. | |
| 6941 | </p> | |
| 6942 | {#header_close#} | |
| 6943 | ||
| 6944 | 6931 | {#header_open|@call#} |
| 6945 | 6932 | <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre> |
| 6946 | 6933 | <p> |
| ... | ... | @@ -8101,14 +8088,6 @@ test "@setRuntimeSafety" { |
| 8101 | 8088 | {#see_also|@bitSizeOf|@typeInfo#} |
| 8102 | 8089 | {#header_close#} |
| 8103 | 8090 | |
| 8104 | {#header_open|@sliceToBytes#} | |
| 8105 | <pre>{#syntax#}@sliceToBytes(value: var) []u8{#endsyntax#}</pre> | |
| 8106 | <p> | |
| 8107 | Converts a slice or array to a slice of {#syntax#}u8{#endsyntax#}. The resulting slice has the same | |
| 8108 | {#link|pointer|Pointers#} properties as the parameter. | |
| 8109 | </p> | |
| 8110 | {#header_close#} | |
| 8111 | ||
| 8112 | 8091 | {#header_open|@splat#} |
| 8113 | 8092 | <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre> |
| 8114 | 8093 | <p> |
| ... | ... | @@ -8919,25 +8898,6 @@ pub fn main() void { |
| 8919 | 8898 | var b: u32 = 3; |
| 8920 | 8899 | var c = @divExact(a, b); |
| 8921 | 8900 | std.debug.warn("value: {}\n", .{c}); |
| 8922 | } | |
| 8923 | {#code_end#} | |
| 8924 | {#header_close#} | |
| 8925 | {#header_open|Slice Widen Remainder#} | |
| 8926 | <p>At compile-time:</p> | |
| 8927 | {#code_begin|test_err|unable to convert#} | |
| 8928 | comptime { | |
| 8929 | var bytes = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 8930 | var slice = @bytesToSlice(u32, bytes[0..]); | |
| 8931 | } | |
| 8932 | {#code_end#} | |
| 8933 | <p>At runtime:</p> | |
| 8934 | {#code_begin|exe_err#} | |
| 8935 | const std = @import("std"); | |
| 8936 | ||
| 8937 | pub fn main() void { | |
| 8938 | var bytes = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 8939 | var slice = @bytesToSlice(u32, bytes[0..]); | |
| 8940 | std.debug.warn("value: {}\n", .{slice[0]}); | |
| 8941 | 8901 | } |
| 8942 | 8902 | {#code_end#} |
| 8943 | 8903 | {#header_close#} |
| ... | ... | @@ -9119,14 +9079,15 @@ comptime { |
| 9119 | 9079 | {#code_end#} |
| 9120 | 9080 | <p>At runtime:</p> |
| 9121 | 9081 | {#code_begin|exe_err#} |
| 9082 | const mem = @import("std").mem; | |
| 9122 | 9083 | pub fn main() !void { |
| 9123 | 9084 | var array align(4) = [_]u32{ 0x11111111, 0x11111111 }; |
| 9124 | const bytes = @sliceToBytes(array[0..]); | |
| 9085 | const bytes = mem.sliceAsBytes(array[0..]); | |
| 9125 | 9086 | if (foo(bytes) != 0x11111111) return error.Wrong; |
| 9126 | 9087 | } |
| 9127 | 9088 | fn foo(bytes: []u8) u32 { |
| 9128 | 9089 | const slice4 = bytes[1..5]; |
| 9129 | const int_slice = @bytesToSlice(u32, @alignCast(4, slice4)); | |
| 9090 | const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4)); | |
| 9130 | 9091 | return int_slice[0]; |
| 9131 | 9092 | } |
| 9132 | 9093 | {#code_end#} |
lib/std/crypto/gimli.zig+2-2| ... | ... | @@ -24,11 +24,11 @@ pub const State = struct { |
| 24 | 24 | const Self = @This(); |
| 25 | 25 | |
| 26 | 26 | pub fn toSlice(self: *Self) []u8 { |
| 27 | return @sliceToBytes(self.data[0..]); | |
| 27 | return mem.sliceAsBytes(self.data[0..]); | |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | 30 | pub fn toSliceConst(self: *Self) []const u8 { |
| 31 | return @sliceToBytes(self.data[0..]); | |
| 31 | return mem.sliceAsBytes(self.data[0..]); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | pub fn permute(self: *Self) void { |
lib/std/cstr.zig+1-1| ... | ... | @@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct { |
| 72 | 72 | errdefer allocator.free(buf); |
| 73 | 73 | |
| 74 | 74 | var write_index = index_size; |
| 75 | const index_buf = @bytesToSlice(?[*]u8, buf); | |
| 75 | const index_buf = mem.bytesAsSlice(?[*]u8, buf); | |
| 76 | 76 | |
| 77 | 77 | var i: usize = 0; |
| 78 | 78 | for (slices) |slice| { |
lib/std/fifo.zig+4-4| ... | ... | @@ -101,7 +101,7 @@ pub fn LinearFifo( |
| 101 | 101 | } |
| 102 | 102 | } |
| 103 | 103 | { // set unused area to undefined |
| 104 | const unused = @sliceToBytes(self.buf[self.count..]); | |
| 104 | const unused = mem.sliceAsBytes(self.buf[self.count..]); | |
| 105 | 105 | @memset(unused.ptr, undefined, unused.len); |
| 106 | 106 | } |
| 107 | 107 | } |
| ... | ... | @@ -166,12 +166,12 @@ pub fn LinearFifo( |
| 166 | 166 | { // set old range to undefined. Note: may be wrapped around |
| 167 | 167 | const slice = self.readableSliceMut(0); |
| 168 | 168 | if (slice.len >= count) { |
| 169 | const unused = @sliceToBytes(slice[0..count]); | |
| 169 | const unused = mem.sliceAsBytes(slice[0..count]); | |
| 170 | 170 | @memset(unused.ptr, undefined, unused.len); |
| 171 | 171 | } else { |
| 172 | const unused = @sliceToBytes(slice[0..]); | |
| 172 | const unused = mem.sliceAsBytes(slice[0..]); | |
| 173 | 173 | @memset(unused.ptr, undefined, unused.len); |
| 174 | const unused2 = @sliceToBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]); | |
| 174 | const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]); | |
| 175 | 175 | @memset(unused2.ptr, undefined, unused2.len); |
| 176 | 176 | } |
| 177 | 177 | } |
lib/std/fs/watch.zig+1-1| ... | ... | @@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool { |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | 28 | fn hashString(s: []const u16) u32 { |
| 29 | return @truncate(u32, std.hash.Wyhash.hash(0, @sliceToBytes(s))); | |
| 29 | return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceAsBytes(s))); | |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | const WatchEventError = error{ |
lib/std/heap.zig+3-3| ... | ... | @@ -283,14 +283,14 @@ const WasmPageAllocator = struct { |
| 283 | 283 | |
| 284 | 284 | fn getBit(self: FreeBlock, idx: usize) PageStatus { |
| 285 | 285 | const bit_offset = 0; |
| 286 | return @intToEnum(PageStatus, Io.get(@sliceToBytes(self.data), idx, bit_offset)); | |
| 286 | return @intToEnum(PageStatus, Io.get(mem.sliceAsBytes(self.data), idx, bit_offset)); | |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | 289 | fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void { |
| 290 | 290 | const bit_offset = 0; |
| 291 | 291 | var i: usize = 0; |
| 292 | 292 | while (i < len) : (i += 1) { |
| 293 | Io.set(@sliceToBytes(self.data), start_idx + i, bit_offset, @enumToInt(val)); | |
| 293 | Io.set(mem.sliceAsBytes(self.data), start_idx + i, bit_offset, @enumToInt(val)); | |
| 294 | 294 | } |
| 295 | 295 | } |
| 296 | 296 | |
| ... | ... | @@ -552,7 +552,7 @@ pub const ArenaAllocator = struct { |
| 552 | 552 | if (len >= actual_min_size) break; |
| 553 | 553 | } |
| 554 | 554 | const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len); |
| 555 | const buf_node_slice = @bytesToSlice(BufNode, buf[0..@sizeOf(BufNode)]); | |
| 555 | const buf_node_slice = mem.bytesAsSlice(BufNode, buf[0..@sizeOf(BufNode)]); | |
| 556 | 556 | const buf_node = &buf_node_slice[0]; |
| 557 | 557 | buf_node.* = BufNode{ |
| 558 | 558 | .data = buf, |
lib/std/io/in_stream.zig+1-1| ... | ... | @@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type { |
| 235 | 235 | // Only extern and packed structs have defined in-memory layout. |
| 236 | 236 | comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto); |
| 237 | 237 | var res: [1]T = undefined; |
| 238 | try self.readNoEof(@sliceToBytes(res[0..])); | |
| 238 | try self.readNoEof(mem.sliceAsBytes(res[0..])); | |
| 239 | 239 | return res[0]; |
| 240 | 240 | } |
| 241 | 241 |
lib/std/mem.zig+162-6| ... | ... | @@ -132,7 +132,7 @@ pub const Allocator = struct { |
| 132 | 132 | // their own frame with @Frame(func). |
| 133 | 133 | return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n]; |
| 134 | 134 | } else { |
| 135 | return @bytesToSlice(T, @alignCast(a, byte_slice)); | |
| 135 | return mem.bytesAsSlice(T, @alignCast(a, byte_slice)); | |
| 136 | 136 | } |
| 137 | 137 | } |
| 138 | 138 | |
| ... | ... | @@ -173,7 +173,7 @@ pub const Allocator = struct { |
| 173 | 173 | return @as([*]align(new_alignment) T, undefined)[0..0]; |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | const old_byte_slice = @sliceToBytes(old_mem); | |
| 176 | const old_byte_slice = mem.sliceAsBytes(old_mem); | |
| 177 | 177 | const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory; |
| 178 | 178 | // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure |
| 179 | 179 | const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment); |
| ... | ... | @@ -181,7 +181,7 @@ pub const Allocator = struct { |
| 181 | 181 | if (new_n > old_mem.len) { |
| 182 | 182 | @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len); |
| 183 | 183 | } |
| 184 | return @bytesToSlice(T, @alignCast(new_alignment, byte_slice)); | |
| 184 | return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice)); | |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | /// Prefer calling realloc to shrink if you can tolerate failure, such as |
| ... | ... | @@ -221,18 +221,18 @@ pub const Allocator = struct { |
| 221 | 221 | // new_n <= old_mem.len and the multiplication didn't overflow for that operation. |
| 222 | 222 | const byte_count = @sizeOf(T) * new_n; |
| 223 | 223 | |
| 224 | const old_byte_slice = @sliceToBytes(old_mem); | |
| 224 | const old_byte_slice = mem.sliceAsBytes(old_mem); | |
| 225 | 225 | @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count); |
| 226 | 226 | const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment); |
| 227 | 227 | assert(byte_slice.len == byte_count); |
| 228 | return @bytesToSlice(T, @alignCast(new_alignment, byte_slice)); | |
| 228 | return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice)); | |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | /// Free an array allocated with `alloc`. To free a single item, |
| 232 | 232 | /// see `destroy`. |
| 233 | 233 | pub fn free(self: *Allocator, memory: var) void { |
| 234 | 234 | const Slice = @typeInfo(@TypeOf(memory)).Pointer; |
| 235 | const bytes = @sliceToBytes(memory); | |
| 235 | const bytes = mem.sliceAsBytes(memory); | |
| 236 | 236 | const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0; |
| 237 | 237 | if (bytes_len == 0) return; |
| 238 | 238 | const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr)); |
| ... | ... | @@ -1486,6 +1486,162 @@ test "bytesToValue" { |
| 1486 | 1486 | testing.expect(deadbeef == @as(u32, 0xDEADBEEF)); |
| 1487 | 1487 | } |
| 1488 | 1488 | |
| 1489 | //TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues. | |
| 1490 | fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type { | |
| 1491 | if (!(trait.isSlice(bytesType) and meta.Child(bytesType) == u8) and !(trait.isPtrTo(.Array)(bytesType) and meta.Child(meta.Child(bytesType)) == u8)) { | |
| 1492 | @compileError("expected []u8 or *[_]u8, passed " ++ @typeName(bytesType)); | |
| 1493 | } | |
| 1494 | ||
| 1495 | if (trait.isPtrTo(.Array)(bytesType) and @typeInfo(meta.Child(bytesType)).Array.len % @sizeOf(T) != 0) { | |
| 1496 | @compileError("number of bytes in " ++ @typeName(bytesType) ++ " is not divisible by size of " ++ @typeName(T)); | |
| 1497 | } | |
| 1498 | ||
| 1499 | const alignment = meta.alignment(bytesType); | |
| 1500 | ||
| 1501 | return if (trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T; | |
| 1502 | } | |
| 1503 | ||
| 1504 | pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) { | |
| 1505 | const bytesSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(bytes))) bytes[0..] else bytes; | |
| 1506 | ||
| 1507 | // let's not give an undefined pointer to @ptrCast | |
| 1508 | // it may be equal to zero and fail a null check | |
| 1509 | if (bytesSlice.len == 0) { | |
| 1510 | return &[0]T{}; | |
| 1511 | } | |
| 1512 | ||
| 1513 | const bytesType = @TypeOf(bytesSlice); | |
| 1514 | const alignment = comptime meta.alignment(bytesType); | |
| 1515 | ||
| 1516 | const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T; | |
| 1517 | ||
| 1518 | return @ptrCast(castTarget, bytesSlice.ptr)[0..@divExact(bytes.len, @sizeOf(T))]; | |
| 1519 | } | |
| 1520 | ||
| 1521 | test "bytesAsSlice" { | |
| 1522 | const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF }; | |
| 1523 | const slice = bytesAsSlice(u16, bytes[0..]); | |
| 1524 | testing.expect(slice.len == 2); | |
| 1525 | testing.expect(bigToNative(u16, slice[0]) == 0xDEAD); | |
| 1526 | testing.expect(bigToNative(u16, slice[1]) == 0xBEEF); | |
| 1527 | } | |
| 1528 | ||
| 1529 | test "bytesAsSlice keeps pointer alignment" { | |
| 1530 | var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 }; | |
| 1531 | const numbers = bytesAsSlice(u32, bytes[0..]); | |
| 1532 | comptime testing.expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32); | |
| 1533 | } | |
| 1534 | ||
| 1535 | test "bytesAsSlice on a packed struct" { | |
| 1536 | const F = packed struct { | |
| 1537 | a: u8, | |
| 1538 | }; | |
| 1539 | ||
| 1540 | var b = [1]u8{9}; | |
| 1541 | var f = bytesAsSlice(F, &b); | |
| 1542 | testing.expect(f[0].a == 9); | |
| 1543 | } | |
| 1544 | ||
| 1545 | test "bytesAsSlice with specified alignment" { | |
| 1546 | var bytes align(4) = [_]u8{ | |
| 1547 | 0x33, | |
| 1548 | 0x33, | |
| 1549 | 0x33, | |
| 1550 | 0x33, | |
| 1551 | }; | |
| 1552 | const slice: []u32 = std.mem.bytesAsSlice(u32, bytes[0..]); | |
| 1553 | testing.expect(slice[0] == 0x33333333); | |
| 1554 | } | |
| 1555 | ||
| 1556 | //TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues. | |
| 1557 | fn SliceAsBytesReturnType(comptime sliceType: type) type { | |
| 1558 | if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) { | |
| 1559 | @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType)); | |
| 1560 | } | |
| 1561 | ||
| 1562 | const alignment = meta.alignment(sliceType); | |
| 1563 | ||
| 1564 | return if (trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8; | |
| 1565 | } | |
| 1566 | ||
| 1567 | pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) { | |
| 1568 | const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice; | |
| 1569 | ||
| 1570 | // let's not give an undefined pointer to @ptrCast | |
| 1571 | // it may be equal to zero and fail a null check | |
| 1572 | if (actualSlice.len == 0) { | |
| 1573 | return &[0]u8{}; | |
| 1574 | } | |
| 1575 | ||
| 1576 | const sliceType = @TypeOf(actualSlice); | |
| 1577 | const alignment = comptime meta.alignment(sliceType); | |
| 1578 | ||
| 1579 | const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8; | |
| 1580 | ||
| 1581 | return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))]; | |
| 1582 | } | |
| 1583 | ||
| 1584 | test "sliceAsBytes" { | |
| 1585 | const bytes = [_]u16{ 0xDEAD, 0xBEEF }; | |
| 1586 | const slice = sliceAsBytes(bytes[0..]); | |
| 1587 | testing.expect(slice.len == 4); | |
| 1588 | testing.expect(eql(u8, slice, switch (builtin.endian) { | |
| 1589 | .Big => "\xDE\xAD\xBE\xEF", | |
| 1590 | .Little => "\xAD\xDE\xEF\xBE", | |
| 1591 | })); | |
| 1592 | } | |
| 1593 | ||
| 1594 | test "sliceAsBytes packed struct at runtime and comptime" { | |
| 1595 | const Foo = packed struct { | |
| 1596 | a: u4, | |
| 1597 | b: u4, | |
| 1598 | }; | |
| 1599 | const S = struct { | |
| 1600 | fn doTheTest() void { | |
| 1601 | var foo: Foo = undefined; | |
| 1602 | var slice = sliceAsBytes(@as(*[1]Foo, &foo)[0..1]); | |
| 1603 | slice[0] = 0x13; | |
| 1604 | switch (builtin.endian) { | |
| 1605 | .Big => { | |
| 1606 | testing.expect(foo.a == 0x1); | |
| 1607 | testing.expect(foo.b == 0x3); | |
| 1608 | }, | |
| 1609 | .Little => { | |
| 1610 | testing.expect(foo.a == 0x3); | |
| 1611 | testing.expect(foo.b == 0x1); | |
| 1612 | }, | |
| 1613 | } | |
| 1614 | } | |
| 1615 | }; | |
| 1616 | S.doTheTest(); | |
| 1617 | comptime S.doTheTest(); | |
| 1618 | } | |
| 1619 | ||
| 1620 | test "sliceAsBytes and bytesAsSlice back" { | |
| 1621 | testing.expect(@sizeOf(i32) == 4); | |
| 1622 | ||
| 1623 | var big_thing_array = [_]i32{ 1, 2, 3, 4 }; | |
| 1624 | const big_thing_slice: []i32 = big_thing_array[0..]; | |
| 1625 | ||
| 1626 | const bytes = sliceAsBytes(big_thing_slice); | |
| 1627 | testing.expect(bytes.len == 4 * 4); | |
| 1628 | ||
| 1629 | bytes[4] = 0; | |
| 1630 | bytes[5] = 0; | |
| 1631 | bytes[6] = 0; | |
| 1632 | bytes[7] = 0; | |
| 1633 | testing.expect(big_thing_slice[1] == 0); | |
| 1634 | ||
| 1635 | const big_thing_again = bytesAsSlice(i32, bytes); | |
| 1636 | testing.expect(big_thing_again[2] == 3); | |
| 1637 | ||
| 1638 | big_thing_again[2] = -1; | |
| 1639 | testing.expect(bytes[8] == math.maxInt(u8)); | |
| 1640 | testing.expect(bytes[9] == math.maxInt(u8)); | |
| 1641 | testing.expect(bytes[10] == math.maxInt(u8)); | |
| 1642 | testing.expect(bytes[11] == math.maxInt(u8)); | |
| 1643 | } | |
| 1644 | ||
| 1489 | 1645 | fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type { |
| 1490 | 1646 | if (trait.isConstPtr(T)) |
| 1491 | 1647 | return *const [length]meta.Child(meta.Child(T)); |
lib/std/meta/trait.zig+16| ... | ... | @@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" { |
| 135 | 135 | testing.expect(!isPtrTo(.Struct)(**struct {})); |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | pub fn isSliceOf(comptime id: builtin.TypeId) TraitFn { | |
| 139 | const Closure = struct { | |
| 140 | pub fn trait(comptime T: type) bool { | |
| 141 | if (!comptime isSlice(T)) return false; | |
| 142 | return id == @typeId(meta.Child(T)); | |
| 143 | } | |
| 144 | }; | |
| 145 | return Closure.trait; | |
| 146 | } | |
| 147 | ||
| 148 | test "std.meta.trait.isSliceOf" { | |
| 149 | testing.expect(!isSliceOf(.Struct)(struct {})); | |
| 150 | testing.expect(isSliceOf(.Struct)([]struct {})); | |
| 151 | testing.expect(!isSliceOf(.Struct)([][]struct {})); | |
| 152 | } | |
| 153 | ||
| 138 | 154 | ///////////Strait trait Fns |
| 139 | 155 | |
| 140 | 156 | //@TODO: |
lib/std/net.zig+2-2| ... | ... | @@ -120,7 +120,7 @@ pub const Address = extern union { |
| 120 | 120 | ip_slice[10] = 0xff; |
| 121 | 121 | ip_slice[11] = 0xff; |
| 122 | 122 | |
| 123 | const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]); | |
| 123 | const ptr = mem.sliceAsBytes(@as(*const [1]u32, &addr)[0..]); | |
| 124 | 124 | |
| 125 | 125 | ip_slice[12] = ptr[0]; |
| 126 | 126 | ip_slice[13] = ptr[1]; |
| ... | ... | @@ -164,7 +164,7 @@ pub const Address = extern union { |
| 164 | 164 | .addr = undefined, |
| 165 | 165 | }, |
| 166 | 166 | }; |
| 167 | const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]); | |
| 167 | const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.in.addr)[0..]); | |
| 168 | 168 | |
| 169 | 169 | var x: u8 = 0; |
| 170 | 170 | var index: u8 = 0; |
lib/std/os.zig+1-1| ... | ... | @@ -1852,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool { |
| 1852 | 1852 | |
| 1853 | 1853 | const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]); |
| 1854 | 1854 | const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)]; |
| 1855 | const name_wide = @bytesToSlice(u16, name_bytes); | |
| 1855 | const name_wide = mem.bytesAsSlice(u16, name_bytes); | |
| 1856 | 1856 | return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or |
| 1857 | 1857 | mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; |
| 1858 | 1858 | } |
lib/std/process.zig+1-1| ... | ... | @@ -430,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { |
| 430 | 430 | const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes); |
| 431 | 431 | errdefer allocator.free(buf); |
| 432 | 432 | |
| 433 | const result_slice_list = @bytesToSlice([]u8, buf[0..slice_list_bytes]); | |
| 433 | const result_slice_list = mem.bytesAsSlice([]u8, buf[0..slice_list_bytes]); | |
| 434 | 434 | const result_contents = buf[slice_list_bytes..]; |
| 435 | 435 | mem.copy(u8, result_contents, contents_slice); |
| 436 | 436 |
lib/std/unicode.zig+6-6| ... | ... | @@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct { |
| 243 | 243 | |
| 244 | 244 | pub fn init(s: []const u16) Utf16LeIterator { |
| 245 | 245 | return Utf16LeIterator{ |
| 246 | .bytes = @sliceToBytes(s), | |
| 246 | .bytes = mem.sliceAsBytes(s), | |
| 247 | 247 | .i = 0, |
| 248 | 248 | }; |
| 249 | 249 | } |
| ... | ... | @@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize { |
| 496 | 496 | |
| 497 | 497 | test "utf16leToUtf8" { |
| 498 | 498 | var utf16le: [2]u16 = undefined; |
| 499 | const utf16le_as_bytes = @sliceToBytes(utf16le[0..]); | |
| 499 | const utf16le_as_bytes = mem.sliceAsBytes(utf16le[0..]); | |
| 500 | 500 | |
| 501 | 501 | { |
| 502 | 502 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A'); |
| ... | ... | @@ -606,12 +606,12 @@ test "utf8ToUtf16Le" { |
| 606 | 606 | { |
| 607 | 607 | const length = try utf8ToUtf16Le(utf16le[0..], "𐐷"); |
| 608 | 608 | testing.expectEqual(@as(usize, 2), length); |
| 609 | testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16le[0..])); | |
| 609 | testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16le[0..])); | |
| 610 | 610 | } |
| 611 | 611 | { |
| 612 | 612 | const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}"); |
| 613 | 613 | testing.expectEqual(@as(usize, 2), length); |
| 614 | testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16le[0..])); | |
| 614 | testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16le[0..])); | |
| 615 | 615 | } |
| 616 | 616 | } |
| 617 | 617 | |
| ... | ... | @@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" { |
| 619 | 619 | { |
| 620 | 620 | const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷"); |
| 621 | 621 | defer testing.allocator.free(utf16); |
| 622 | testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..])); | |
| 622 | testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16[0..])); | |
| 623 | 623 | testing.expect(utf16[2] == 0); |
| 624 | 624 | } |
| 625 | 625 | { |
| 626 | 626 | const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}"); |
| 627 | 627 | defer testing.allocator.free(utf16); |
| 628 | testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..])); | |
| 628 | testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16[0..])); | |
| 629 | 629 | testing.expect(utf16[2] == 0); |
| 630 | 630 | } |
| 631 | 631 | } |
src/all_types.hpp-28| ... | ... | @@ -1750,8 +1750,6 @@ enum BuiltinFnId { |
| 1750 | 1750 | BuiltinFnIdIntCast, |
| 1751 | 1751 | BuiltinFnIdFloatCast, |
| 1752 | 1752 | BuiltinFnIdErrSetCast, |
| 1753 | BuiltinFnIdToBytes, | |
| 1754 | BuiltinFnIdFromBytes, | |
| 1755 | 1753 | BuiltinFnIdIntToFloat, |
| 1756 | 1754 | BuiltinFnIdFloatToInt, |
| 1757 | 1755 | BuiltinFnIdBoolToInt, |
| ... | ... | @@ -1821,7 +1819,6 @@ enum PanicMsgId { |
| 1821 | 1819 | PanicMsgIdDivisionByZero, |
| 1822 | 1820 | PanicMsgIdRemainderDivisionByZero, |
| 1823 | 1821 | PanicMsgIdExactDivisionRemainder, |
| 1824 | PanicMsgIdSliceWidenRemainder, | |
| 1825 | 1822 | PanicMsgIdUnwrapOptionalFail, |
| 1826 | 1823 | PanicMsgIdInvalidErrorCode, |
| 1827 | 1824 | PanicMsgIdIncorrectAlignment, |
| ... | ... | @@ -2699,8 +2696,6 @@ enum IrInstSrcId { |
| 2699 | 2696 | IrInstSrcIdSaveErrRetAddr, |
| 2700 | 2697 | IrInstSrcIdAddImplicitReturnType, |
| 2701 | 2698 | IrInstSrcIdErrSetCast, |
| 2702 | IrInstSrcIdToBytes, | |
| 2703 | IrInstSrcIdFromBytes, | |
| 2704 | 2699 | IrInstSrcIdCheckRuntimeScope, |
| 2705 | 2700 | IrInstSrcIdHasDecl, |
| 2706 | 2701 | IrInstSrcIdUndeclaredIdent, |
| ... | ... | @@ -2739,7 +2734,6 @@ enum IrInstGenId { |
| 2739 | 2734 | IrInstGenIdCall, |
| 2740 | 2735 | IrInstGenIdReturn, |
| 2741 | 2736 | IrInstGenIdCast, |
| 2742 | IrInstGenIdResizeSlice, | |
| 2743 | 2737 | IrInstGenIdUnreachable, |
| 2744 | 2738 | IrInstGenIdAsm, |
| 2745 | 2739 | IrInstGenIdTestNonNull, |
| ... | ... | @@ -3271,13 +3265,6 @@ struct IrInstGenCast { |
| 3271 | 3265 | CastOp cast_op; |
| 3272 | 3266 | }; |
| 3273 | 3267 | |
| 3274 | struct IrInstGenResizeSlice { | |
| 3275 | IrInstGen base; | |
| 3276 | ||
| 3277 | IrInstGen *operand; | |
| 3278 | IrInstGen *result_loc; | |
| 3279 | }; | |
| 3280 | ||
| 3281 | 3268 | struct IrInstSrcContainerInitList { |
| 3282 | 3269 | IrInstSrc base; |
| 3283 | 3270 | |
| ... | ... | @@ -3629,21 +3616,6 @@ struct IrInstSrcErrSetCast { |
| 3629 | 3616 | IrInstSrc *target; |
| 3630 | 3617 | }; |
| 3631 | 3618 | |
| 3632 | struct IrInstSrcToBytes { | |
| 3633 | IrInstSrc base; | |
| 3634 | ||
| 3635 | IrInstSrc *target; | |
| 3636 | ResultLoc *result_loc; | |
| 3637 | }; | |
| 3638 | ||
| 3639 | struct IrInstSrcFromBytes { | |
| 3640 | IrInstSrc base; | |
| 3641 | ||
| 3642 | IrInstSrc *dest_child_type; | |
| 3643 | IrInstSrc *target; | |
| 3644 | ResultLoc *result_loc; | |
| 3645 | }; | |
| 3646 | ||
| 3647 | 3619 | struct IrInstSrcIntToFloat { |
| 3648 | 3620 | IrInstSrc base; |
| 3649 | 3621 |
src/codegen.cpp-74| ... | ... | @@ -972,8 +972,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 972 | 972 | return buf_create_from_str("remainder division by zero or negative value"); |
| 973 | 973 | case PanicMsgIdExactDivisionRemainder: |
| 974 | 974 | return buf_create_from_str("exact division produced remainder"); |
| 975 | case PanicMsgIdSliceWidenRemainder: | |
| 976 | return buf_create_from_str("slice widening size mismatch"); | |
| 977 | 975 | case PanicMsgIdUnwrapOptionalFail: |
| 978 | 976 | return buf_create_from_str("attempt to unwrap null"); |
| 979 | 977 | case PanicMsgIdUnreachable: |
| ... | ... | @@ -3085,74 +3083,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in |
| 3085 | 3083 | } |
| 3086 | 3084 | } |
| 3087 | 3085 | |
| 3088 | static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable, | |
| 3089 | IrInstGenResizeSlice *instruction) | |
| 3090 | { | |
| 3091 | ZigType *actual_type = instruction->operand->value->type; | |
| 3092 | ZigType *wanted_type = instruction->base.value->type; | |
| 3093 | LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); | |
| 3094 | assert(expr_val); | |
| 3095 | ||
| 3096 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); | |
| 3097 | assert(wanted_type->id == ZigTypeIdStruct); | |
| 3098 | assert(wanted_type->data.structure.special == StructSpecialSlice); | |
| 3099 | assert(actual_type->id == ZigTypeIdStruct); | |
| 3100 | assert(actual_type->data.structure.special == StructSpecialSlice); | |
| 3101 | ||
| 3102 | ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; | |
| 3103 | ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; | |
| 3104 | ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry; | |
| 3105 | ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; | |
| 3106 | ||
| 3107 | ||
| 3108 | size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index; | |
| 3109 | size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index; | |
| 3110 | size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index; | |
| 3111 | size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index; | |
| 3112 | ||
| 3113 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, ""); | |
| 3114 | LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); | |
| 3115 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, | |
| 3116 | get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), ""); | |
| 3117 | LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc, | |
| 3118 | (unsigned)wanted_ptr_index, ""); | |
| 3119 | gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false); | |
| 3120 | ||
| 3121 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, ""); | |
| 3122 | LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, ""); | |
| 3123 | uint64_t src_size = type_size(g, actual_child_type); | |
| 3124 | uint64_t dest_size = type_size(g, wanted_child_type); | |
| 3125 | ||
| 3126 | LLVMValueRef new_len; | |
| 3127 | if (dest_size == 1) { | |
| 3128 | LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false); | |
| 3129 | new_len = LLVMBuildMul(g->builder, src_len, src_size_val, ""); | |
| 3130 | } else if (src_size == 1) { | |
| 3131 | LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false); | |
| 3132 | if (ir_want_runtime_safety(g, &instruction->base)) { | |
| 3133 | LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, ""); | |
| 3134 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type); | |
| 3135 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); | |
| 3136 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk"); | |
| 3137 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail"); | |
| 3138 | LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); | |
| 3139 | ||
| 3140 | LLVMPositionBuilderAtEnd(g->builder, fail_block); | |
| 3141 | gen_safety_crash(g, PanicMsgIdSliceWidenRemainder); | |
| 3142 | ||
| 3143 | LLVMPositionBuilderAtEnd(g->builder, ok_block); | |
| 3144 | } | |
| 3145 | new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, ""); | |
| 3146 | } else { | |
| 3147 | zig_unreachable(); | |
| 3148 | } | |
| 3149 | ||
| 3150 | LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, ""); | |
| 3151 | gen_store_untyped(g, new_len, dest_len_ptr, 0, false); | |
| 3152 | ||
| 3153 | return result_loc; | |
| 3154 | } | |
| 3155 | ||
| 3156 | 3086 | static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable, |
| 3157 | 3087 | IrInstGenCast *cast_instruction) |
| 3158 | 3088 | { |
| ... | ... | @@ -6485,8 +6415,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl |
| 6485 | 6415 | return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction); |
| 6486 | 6416 | case IrInstGenIdAssertNonNull: |
| 6487 | 6417 | return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction); |
| 6488 | case IrInstGenIdResizeSlice: | |
| 6489 | return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction); | |
| 6490 | 6418 | case IrInstGenIdPtrOfArrayToSlice: |
| 6491 | 6419 | return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction); |
| 6492 | 6420 | case IrInstGenIdSuspendBegin: |
| ... | ... | @@ -8317,8 +8245,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 8317 | 8245 | create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); |
| 8318 | 8246 | create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4); |
| 8319 | 8247 | create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2); |
| 8320 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); | |
| 8321 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); | |
| 8322 | 8248 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); |
| 8323 | 8249 | create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2); |
| 8324 | 8250 | create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3); |
src/ir.cpp-256| ... | ... | @@ -383,10 +383,6 @@ static void destroy_instruction_src(IrInstSrc *inst) { |
| 383 | 383 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst)); |
| 384 | 384 | case IrInstSrcIdErrSetCast: |
| 385 | 385 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst)); |
| 386 | case IrInstSrcIdFromBytes: | |
| 387 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst)); | |
| 388 | case IrInstSrcIdToBytes: | |
| 389 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcToBytes *>(inst)); | |
| 390 | 386 | case IrInstSrcIdIntToFloat: |
| 391 | 387 | return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst)); |
| 392 | 388 | case IrInstSrcIdFloatToInt: |
| ... | ... | @@ -707,8 +703,6 @@ void destroy_instruction_gen(IrInstGen *inst) { |
| 707 | 703 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst)); |
| 708 | 704 | case IrInstGenIdAssertNonNull: |
| 709 | 705 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst)); |
| 710 | case IrInstGenIdResizeSlice: | |
| 711 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst)); | |
| 712 | 706 | case IrInstGenIdAlloca: |
| 713 | 707 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst)); |
| 714 | 708 | case IrInstGenIdSuspendBegin: |
| ... | ... | @@ -1563,14 +1557,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) { |
| 1563 | 1557 | return IrInstSrcIdErrSetCast; |
| 1564 | 1558 | } |
| 1565 | 1559 | |
| 1566 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcToBytes *) { | |
| 1567 | return IrInstSrcIdToBytes; | |
| 1568 | } | |
| 1569 | ||
| 1570 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcFromBytes *) { | |
| 1571 | return IrInstSrcIdFromBytes; | |
| 1572 | } | |
| 1573 | ||
| 1574 | 1560 | static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) { |
| 1575 | 1561 | return IrInstSrcIdCheckRuntimeScope; |
| 1576 | 1562 | } |
| ... | ... | @@ -1700,10 +1686,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) { |
| 1700 | 1686 | return IrInstGenIdCast; |
| 1701 | 1687 | } |
| 1702 | 1688 | |
| 1703 | static constexpr IrInstGenId ir_inst_id(IrInstGenResizeSlice *) { | |
| 1704 | return IrInstGenIdResizeSlice; | |
| 1705 | } | |
| 1706 | ||
| 1707 | 1689 | static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) { |
| 1708 | 1690 | return IrInstGenIdUnreachable; |
| 1709 | 1691 | } |
| ... | ... | @@ -2759,21 +2741,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi |
| 2759 | 2741 | return &inst->base; |
| 2760 | 2742 | } |
| 2761 | 2743 | |
| 2762 | static IrInstGen *ir_build_resize_slice(IrAnalyze *ira, IrInst *source_instruction, | |
| 2763 | IrInstGen *operand, ZigType *ty, IrInstGen *result_loc) | |
| 2764 | { | |
| 2765 | IrInstGenResizeSlice *instruction = ir_build_inst_gen<IrInstGenResizeSlice>(&ira->new_irb, | |
| 2766 | source_instruction->scope, source_instruction->source_node); | |
| 2767 | instruction->base.value->type = ty; | |
| 2768 | instruction->operand = operand; | |
| 2769 | instruction->result_loc = result_loc; | |
| 2770 | ||
| 2771 | ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); | |
| 2772 | if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); | |
| 2773 | ||
| 2774 | return &instruction->base; | |
| 2775 | } | |
| 2776 | ||
| 2777 | 2744 | static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 2778 | 2745 | IrInstSrc *target, IrInstSrc *options) |
| 2779 | 2746 | { |
| ... | ... | @@ -3540,32 +3507,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode |
| 3540 | 3507 | return &instruction->base; |
| 3541 | 3508 | } |
| 3542 | 3509 | |
| 3543 | static IrInstSrc *ir_build_to_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target, | |
| 3544 | ResultLoc *result_loc) | |
| 3545 | { | |
| 3546 | IrInstSrcToBytes *instruction = ir_build_instruction<IrInstSrcToBytes>(irb, scope, source_node); | |
| 3547 | instruction->target = target; | |
| 3548 | instruction->result_loc = result_loc; | |
| 3549 | ||
| 3550 | ir_ref_instruction(target, irb->current_basic_block); | |
| 3551 | ||
| 3552 | return &instruction->base; | |
| 3553 | } | |
| 3554 | ||
| 3555 | static IrInstSrc *ir_build_from_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, | |
| 3556 | IrInstSrc *dest_child_type, IrInstSrc *target, ResultLoc *result_loc) | |
| 3557 | { | |
| 3558 | IrInstSrcFromBytes *instruction = ir_build_instruction<IrInstSrcFromBytes>(irb, scope, source_node); | |
| 3559 | instruction->dest_child_type = dest_child_type; | |
| 3560 | instruction->target = target; | |
| 3561 | instruction->result_loc = result_loc; | |
| 3562 | ||
| 3563 | ir_ref_instruction(dest_child_type, irb->current_basic_block); | |
| 3564 | ir_ref_instruction(target, irb->current_basic_block); | |
| 3565 | ||
| 3566 | return &instruction->base; | |
| 3567 | } | |
| 3568 | ||
| 3569 | 3510 | static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, |
| 3570 | 3511 | IrInstSrc *dest_type, IrInstSrc *target) |
| 3571 | 3512 | { |
| ... | ... | @@ -6597,31 +6538,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 6597 | 6538 | IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); |
| 6598 | 6539 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 6599 | 6540 | } |
| 6600 | case BuiltinFnIdFromBytes: | |
| 6601 | { | |
| 6602 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 6603 | IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 6604 | if (arg0_value == irb->codegen->invalid_inst_src) | |
| 6605 | return arg0_value; | |
| 6606 | ||
| 6607 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | |
| 6608 | IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); | |
| 6609 | if (arg1_value == irb->codegen->invalid_inst_src) | |
| 6610 | return arg1_value; | |
| 6611 | ||
| 6612 | IrInstSrc *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); | |
| 6613 | return ir_lval_wrap(irb, scope, result, lval, result_loc); | |
| 6614 | } | |
| 6615 | case BuiltinFnIdToBytes: | |
| 6616 | { | |
| 6617 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 6618 | IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 6619 | if (arg0_value == irb->codegen->invalid_inst_src) | |
| 6620 | return arg0_value; | |
| 6621 | ||
| 6622 | IrInstSrc *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); | |
| 6623 | return ir_lval_wrap(irb, scope, result, lval, result_loc); | |
| 6624 | } | |
| 6625 | 6541 | case BuiltinFnIdIntToFloat: |
| 6626 | 6542 | { |
| 6627 | 6543 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -25489,171 +25405,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE |
| 25489 | 25405 | return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type); |
| 25490 | 25406 | } |
| 25491 | 25407 | |
| 25492 | static IrInstGen *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstSrcFromBytes *instruction) { | |
| 25493 | Error err; | |
| 25494 | ||
| 25495 | ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); | |
| 25496 | if (type_is_invalid(dest_child_type)) | |
| 25497 | return ira->codegen->invalid_inst_gen; | |
| 25498 | ||
| 25499 | IrInstGen *target = instruction->target->child; | |
| 25500 | if (type_is_invalid(target->value->type)) | |
| 25501 | return ira->codegen->invalid_inst_gen; | |
| 25502 | ||
| 25503 | bool src_ptr_const; | |
| 25504 | bool src_ptr_volatile; | |
| 25505 | uint32_t src_ptr_align; | |
| 25506 | if (target->value->type->id == ZigTypeIdPointer) { | |
| 25507 | src_ptr_const = target->value->type->data.pointer.is_const; | |
| 25508 | src_ptr_volatile = target->value->type->data.pointer.is_volatile; | |
| 25509 | ||
| 25510 | if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align))) | |
| 25511 | return ira->codegen->invalid_inst_gen; | |
| 25512 | } else if (is_slice(target->value->type)) { | |
| 25513 | ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; | |
| 25514 | src_ptr_const = src_ptr_type->data.pointer.is_const; | |
| 25515 | src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; | |
| 25516 | ||
| 25517 | if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) | |
| 25518 | return ira->codegen->invalid_inst_gen; | |
| 25519 | } else { | |
| 25520 | src_ptr_const = true; | |
| 25521 | src_ptr_volatile = false; | |
| 25522 | ||
| 25523 | if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown))) | |
| 25524 | return ira->codegen->invalid_inst_gen; | |
| 25525 | ||
| 25526 | src_ptr_align = get_abi_alignment(ira->codegen, target->value->type); | |
| 25527 | } | |
| 25528 | ||
| 25529 | if (src_ptr_align != 0) { | |
| 25530 | if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown))) | |
| 25531 | return ira->codegen->invalid_inst_gen; | |
| 25532 | } | |
| 25533 | ||
| 25534 | ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, | |
| 25535 | src_ptr_const, src_ptr_volatile, PtrLenUnknown, | |
| 25536 | src_ptr_align, 0, 0, false); | |
| 25537 | ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); | |
| 25538 | ||
| 25539 | ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, | |
| 25540 | src_ptr_const, src_ptr_volatile, PtrLenUnknown, | |
| 25541 | src_ptr_align, 0, 0, false); | |
| 25542 | ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); | |
| 25543 | ||
| 25544 | IrInstGen *casted_value = ir_implicit_cast2(ira, &instruction->target->base, target, u8_slice); | |
| 25545 | if (type_is_invalid(casted_value->value->type)) | |
| 25546 | return ira->codegen->invalid_inst_gen; | |
| 25547 | ||
| 25548 | bool have_known_len = false; | |
| 25549 | uint64_t known_len; | |
| 25550 | ||
| 25551 | if (instr_is_comptime(casted_value)) { | |
| 25552 | ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); | |
| 25553 | if (!val) | |
| 25554 | return ira->codegen->invalid_inst_gen; | |
| 25555 | ||
| 25556 | ZigValue *len_val = val->data.x_struct.fields[slice_len_index]; | |
| 25557 | if (value_is_comptime(len_val)) { | |
| 25558 | known_len = bigint_as_u64(&len_val->data.x_bigint); | |
| 25559 | have_known_len = true; | |
| 25560 | } | |
| 25561 | } | |
| 25562 | ||
| 25563 | IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, | |
| 25564 | dest_slice_type, nullptr, true, true); | |
| 25565 | if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) { | |
| 25566 | return result_loc; | |
| 25567 | } | |
| 25568 | ||
| 25569 | if (target->value->type->id == ZigTypeIdPointer && | |
| 25570 | target->value->type->data.pointer.ptr_len == PtrLenSingle && | |
| 25571 | target->value->type->data.pointer.child_type->id == ZigTypeIdArray) | |
| 25572 | { | |
| 25573 | known_len = target->value->type->data.pointer.child_type->data.array.len; | |
| 25574 | have_known_len = true; | |
| 25575 | } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { | |
| 25576 | known_len = casted_value->value->data.rh_slice.len; | |
| 25577 | have_known_len = true; | |
| 25578 | } | |
| 25579 | ||
| 25580 | if (have_known_len) { | |
| 25581 | if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) | |
| 25582 | return ira->codegen->invalid_inst_gen; | |
| 25583 | uint64_t child_type_size = type_size(ira->codegen, dest_child_type); | |
| 25584 | uint64_t remainder = known_len % child_type_size; | |
| 25585 | if (remainder != 0) { | |
| 25586 | ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, | |
| 25587 | buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", | |
| 25588 | known_len, buf_ptr(&dest_slice_type->name))); | |
| 25589 | add_error_note(ira->codegen, msg, instruction->dest_child_type->base.source_node, | |
| 25590 | buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, | |
| 25591 | buf_ptr(&dest_child_type->name), child_type_size, remainder)); | |
| 25592 | return ira->codegen->invalid_inst_gen; | |
| 25593 | } | |
| 25594 | } | |
| 25595 | ||
| 25596 | return ir_build_resize_slice(ira, &instruction->base.base, casted_value, dest_slice_type, result_loc); | |
| 25597 | } | |
| 25598 | ||
| 25599 | static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToBytes *instruction) { | |
| 25600 | Error err; | |
| 25601 | ||
| 25602 | IrInstGen *target = instruction->target->child; | |
| 25603 | if (type_is_invalid(target->value->type)) | |
| 25604 | return ira->codegen->invalid_inst_gen; | |
| 25605 | ||
| 25606 | if (!is_slice(target->value->type)) { | |
| 25607 | ir_add_error(ira, &instruction->target->base, | |
| 25608 | buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name))); | |
| 25609 | return ira->codegen->invalid_inst_gen; | |
| 25610 | } | |
| 25611 | ||
| 25612 | ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; | |
| 25613 | ||
| 25614 | uint32_t alignment; | |
| 25615 | if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) | |
| 25616 | return ira->codegen->invalid_inst_gen; | |
| 25617 | ||
| 25618 | ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, | |
| 25619 | src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, | |
| 25620 | alignment, 0, 0, false); | |
| 25621 | ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); | |
| 25622 | ||
| 25623 | if (instr_is_comptime(target)) { | |
| 25624 | ZigValue *target_val = ir_resolve_const(ira, target, UndefBad); | |
| 25625 | if (target_val == nullptr) | |
| 25626 | return ira->codegen->invalid_inst_gen; | |
| 25627 | ||
| 25628 | IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type); | |
| 25629 | result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); | |
| 25630 | ||
| 25631 | ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; | |
| 25632 | ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index]; | |
| 25633 | copy_const_val(ira->codegen, ptr_val, target_ptr_val); | |
| 25634 | ptr_val->type = dest_ptr_type; | |
| 25635 | ||
| 25636 | ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; | |
| 25637 | len_val->special = ConstValSpecialStatic; | |
| 25638 | len_val->type = ira->codegen->builtin_types.entry_usize; | |
| 25639 | ZigValue *target_len_val = target_val->data.x_struct.fields[slice_len_index]; | |
| 25640 | ZigType *elem_type = src_ptr_type->data.pointer.child_type; | |
| 25641 | BigInt elem_size_bigint; | |
| 25642 | bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); | |
| 25643 | bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint); | |
| 25644 | ||
| 25645 | return result; | |
| 25646 | } | |
| 25647 | ||
| 25648 | IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, | |
| 25649 | dest_slice_type, nullptr, true, true); | |
| 25650 | if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { | |
| 25651 | return result_loc; | |
| 25652 | } | |
| 25653 | ||
| 25654 | return ir_build_resize_slice(ira, &instruction->base.base, target, dest_slice_type, result_loc); | |
| 25655 | } | |
| 25656 | ||
| 25657 | 25408 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { |
| 25658 | 25409 | Error err; |
| 25659 | 25410 | |
| ... | ... | @@ -29783,10 +29534,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc |
| 29783 | 29534 | return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction); |
| 29784 | 29535 | case IrInstSrcIdErrSetCast: |
| 29785 | 29536 | return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction); |
| 29786 | case IrInstSrcIdFromBytes: | |
| 29787 | return ir_analyze_instruction_from_bytes(ira, (IrInstSrcFromBytes *)instruction); | |
| 29788 | case IrInstSrcIdToBytes: | |
| 29789 | return ir_analyze_instruction_to_bytes(ira, (IrInstSrcToBytes *)instruction); | |
| 29790 | 29537 | case IrInstSrcIdIntToFloat: |
| 29791 | 29538 | return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction); |
| 29792 | 29539 | case IrInstSrcIdFloatToInt: |
| ... | ... | @@ -30113,7 +29860,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { |
| 30113 | 29860 | case IrInstGenIdCmpxchg: |
| 30114 | 29861 | case IrInstGenIdAssertZero: |
| 30115 | 29862 | case IrInstGenIdAssertNonNull: |
| 30116 | case IrInstGenIdResizeSlice: | |
| 30117 | 29863 | case IrInstGenIdPtrOfArrayToSlice: |
| 30118 | 29864 | case IrInstGenIdSlice: |
| 30119 | 29865 | case IrInstGenIdOptionalWrap: |
| ... | ... | @@ -30339,8 +30085,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { |
| 30339 | 30085 | case IrInstSrcIdIntToFloat: |
| 30340 | 30086 | case IrInstSrcIdFloatToInt: |
| 30341 | 30087 | case IrInstSrcIdBoolToInt: |
| 30342 | case IrInstSrcIdFromBytes: | |
| 30343 | case IrInstSrcIdToBytes: | |
| 30344 | 30088 | case IrInstSrcIdEnumToInt: |
| 30345 | 30089 | case IrInstSrcIdHasDecl: |
| 30346 | 30090 | case IrInstSrcIdAlloca: |
src/ir_print.cpp-36| ... | ... | @@ -307,10 +307,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) { |
| 307 | 307 | return "SrcAddImplicitReturnType"; |
| 308 | 308 | case IrInstSrcIdErrSetCast: |
| 309 | 309 | return "SrcErrSetCast"; |
| 310 | case IrInstSrcIdToBytes: | |
| 311 | return "SrcToBytes"; | |
| 312 | case IrInstSrcIdFromBytes: | |
| 313 | return "SrcFromBytes"; | |
| 314 | 310 | case IrInstSrcIdCheckRuntimeScope: |
| 315 | 311 | return "SrcCheckRuntimeScope"; |
| 316 | 312 | case IrInstSrcIdHasDecl: |
| ... | ... | @@ -383,8 +379,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) { |
| 383 | 379 | return "GenReturn"; |
| 384 | 380 | case IrInstGenIdCast: |
| 385 | 381 | return "GenCast"; |
| 386 | case IrInstGenIdResizeSlice: | |
| 387 | return "GenResizeSlice"; | |
| 388 | 382 | case IrInstGenIdUnreachable: |
| 389 | 383 | return "GenUnreachable"; |
| 390 | 384 | case IrInstGenIdAsm: |
| ... | ... | @@ -1644,20 +1638,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct |
| 1644 | 1638 | fprintf(irp->f, ")"); |
| 1645 | 1639 | } |
| 1646 | 1640 | |
| 1647 | static void ir_print_from_bytes(IrPrintSrc *irp, IrInstSrcFromBytes *instruction) { | |
| 1648 | fprintf(irp->f, "@bytesToSlice("); | |
| 1649 | ir_print_other_inst_src(irp, instruction->dest_child_type); | |
| 1650 | fprintf(irp->f, ", "); | |
| 1651 | ir_print_other_inst_src(irp, instruction->target); | |
| 1652 | fprintf(irp->f, ")"); | |
| 1653 | } | |
| 1654 | ||
| 1655 | static void ir_print_to_bytes(IrPrintSrc *irp, IrInstSrcToBytes *instruction) { | |
| 1656 | fprintf(irp->f, "@sliceToBytes("); | |
| 1657 | ir_print_other_inst_src(irp, instruction->target); | |
| 1658 | fprintf(irp->f, ")"); | |
| 1659 | } | |
| 1660 | ||
| 1661 | 1641 | static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) { |
| 1662 | 1642 | fprintf(irp->f, "@intToFloat("); |
| 1663 | 1643 | ir_print_other_inst_src(irp, instruction->dest_type); |
| ... | ... | @@ -2142,13 +2122,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in |
| 2142 | 2122 | fprintf(irp->f, ")"); |
| 2143 | 2123 | } |
| 2144 | 2124 | |
| 2145 | static void ir_print_resize_slice(IrPrintGen *irp, IrInstGenResizeSlice *instruction) { | |
| 2146 | fprintf(irp->f, "@resizeSlice("); | |
| 2147 | ir_print_other_inst_gen(irp, instruction->operand); | |
| 2148 | fprintf(irp->f, ")result="); | |
| 2149 | ir_print_other_inst_gen(irp, instruction->result_loc); | |
| 2150 | } | |
| 2151 | ||
| 2152 | 2125 | static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) { |
| 2153 | 2126 | fprintf(irp->f, "Alloca(align="); |
| 2154 | 2127 | ir_print_other_inst_src(irp, instruction->align); |
| ... | ... | @@ -2793,12 +2766,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai |
| 2793 | 2766 | case IrInstSrcIdErrSetCast: |
| 2794 | 2767 | ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction); |
| 2795 | 2768 | break; |
| 2796 | case IrInstSrcIdFromBytes: | |
| 2797 | ir_print_from_bytes(irp, (IrInstSrcFromBytes *)instruction); | |
| 2798 | break; | |
| 2799 | case IrInstSrcIdToBytes: | |
| 2800 | ir_print_to_bytes(irp, (IrInstSrcToBytes *)instruction); | |
| 2801 | break; | |
| 2802 | 2769 | case IrInstSrcIdIntToFloat: |
| 2803 | 2770 | ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction); |
| 2804 | 2771 | break; |
| ... | ... | @@ -3273,9 +3240,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai |
| 3273 | 3240 | case IrInstGenIdAssertNonNull: |
| 3274 | 3241 | ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction); |
| 3275 | 3242 | break; |
| 3276 | case IrInstGenIdResizeSlice: | |
| 3277 | ir_print_resize_slice(irp, (IrInstGenResizeSlice *)instruction); | |
| 3278 | break; | |
| 3279 | 3243 | case IrInstGenIdAlloca: |
| 3280 | 3244 | ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction); |
| 3281 | 3245 | break; |
test/compile_errors.zig-10| ... | ... | @@ -4745,16 +4745,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4745 | 4745 | "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", |
| 4746 | 4746 | }); |
| 4747 | 4747 | |
| 4748 | cases.add("convert fixed size array to slice with invalid size", | |
| 4749 | \\export fn f() void { | |
| 4750 | \\ var array: [5]u8 = undefined; | |
| 4751 | \\ var foo = @bytesToSlice(u32, &array)[0]; | |
| 4752 | \\} | |
| 4753 | , &[_][]const u8{ | |
| 4754 | "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) u32: size mismatch", | |
| 4755 | "tmp.zig:3:29: note: u32 has size 4; remaining bytes: 1", | |
| 4756 | }); | |
| 4757 | ||
| 4758 | 4748 | cases.add("non-pure function returns type", |
| 4759 | 4749 | \\var a: u32 = 0; |
| 4760 | 4750 | \\pub fn List(comptime T: type) type { |
test/runtime_safety.zig+9-7| ... | ... | @@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 553 | 553 | ); |
| 554 | 554 | |
| 555 | 555 | cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size", |
| 556 | \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { | |
| 557 | \\ @import("std").os.exit(126); | |
| 556 | \\const std = @import("std"); | |
| 557 | \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { | |
| 558 | \\ std.os.exit(126); | |
| 558 | 559 | \\} |
| 559 | 560 | \\pub fn main() !void { |
| 560 | 561 | \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5}); |
| 561 | 562 | \\ if (x.len == 0) return error.Whatever; |
| 562 | 563 | \\} |
| 563 | 564 | \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 { |
| 564 | \\ return @bytesToSlice(i32, slice); | |
| 565 | \\ return std.mem.bytesAsSlice(i32, slice); | |
| 565 | 566 | \\} |
| 566 | 567 | ); |
| 567 | 568 | |
| ... | ... | @@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 656 | 657 | ); |
| 657 | 658 | |
| 658 | 659 | cases.addRuntimeSafety("@alignCast misaligned", |
| 659 | \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { | |
| 660 | \\ @import("std").os.exit(126); | |
| 660 | \\const std = @import("std"); | |
| 661 | \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { | |
| 662 | \\ std.os.exit(126); | |
| 661 | 663 | \\} |
| 662 | 664 | \\pub fn main() !void { |
| 663 | 665 | \\ var array align(4) = [_]u32{0x11111111, 0x11111111}; |
| 664 | \\ const bytes = @sliceToBytes(array[0..]); | |
| 666 | \\ const bytes = std.mem.sliceAsBytes(array[0..]); | |
| 665 | 667 | \\ if (foo(bytes) != 0x11111111) return error.Wrong; |
| 666 | 668 | \\} |
| 667 | 669 | \\fn foo(bytes: []u8) u32 { |
| 668 | 670 | \\ const slice4 = bytes[1..5]; |
| 669 | \\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4)); | |
| 671 | \\ const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4)); | |
| 670 | 672 | \\ return int_slice[0]; |
| 671 | 673 | \\} |
| 672 | 674 | ); |
test/stage1/behavior.zig-1| ... | ... | @@ -93,7 +93,6 @@ comptime { |
| 93 | 93 | _ = @import("behavior/shuffle.zig"); |
| 94 | 94 | _ = @import("behavior/sizeof_and_typeof.zig"); |
| 95 | 95 | _ = @import("behavior/slice.zig"); |
| 96 | _ = @import("behavior/slicetobytes.zig"); | |
| 97 | 96 | _ = @import("behavior/struct.zig"); |
| 98 | 97 | _ = @import("behavior/struct_contains_null_ptr_itself.zig"); |
| 99 | 98 | _ = @import("behavior/struct_contains_slice_of_itself.zig"); |
test/stage1/behavior/align.zig-14| ... | ... | @@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void { |
| 81 | 81 | expect(ptr.* == 0x33333333); |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | test "specifying alignment allows slice cast" { | |
| 85 | testBytesAlignSlice(0x33); | |
| 86 | } | |
| 87 | fn testBytesAlignSlice(b: u8) void { | |
| 88 | var bytes align(4) = [_]u8{ | |
| 89 | b, | |
| 90 | b, | |
| 91 | b, | |
| 92 | b, | |
| 93 | }; | |
| 94 | const slice: []u32 = @bytesToSlice(u32, bytes[0..]); | |
| 95 | expect(slice[0] == 0x33333333); | |
| 96 | } | |
| 97 | ||
| 98 | 84 | test "@alignCast pointers" { |
| 99 | 85 | var x: u32 align(4) = 1; |
| 100 | 86 | expectsOnly1(&x); |
test/stage1/behavior/async_fn.zig+2-2| ... | ... | @@ -334,7 +334,7 @@ test "async fn with inferred error set" { |
| 334 | 334 | var frame: [1]@Frame(middle) = undefined; |
| 335 | 335 | var fn_ptr = middle; |
| 336 | 336 | var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined; |
| 337 | _ = @asyncCall(@sliceToBytes(frame[0..]), &result, fn_ptr); | |
| 337 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr); | |
| 338 | 338 | resume global_frame; |
| 339 | 339 | std.testing.expectError(error.Fail, result); |
| 340 | 340 | } |
| ... | ... | @@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" { |
| 954 | 954 | fn doTheTest() void { |
| 955 | 955 | var frame: [1]@Frame(middle) = undefined; |
| 956 | 956 | var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined; |
| 957 | _ = @asyncCall(@sliceToBytes(frame[0..]), &result, middle); | |
| 957 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle); | |
| 958 | 958 | resume global_frame; |
| 959 | 959 | std.testing.expectError(error.Fail, result); |
| 960 | 960 | } |
test/stage1/behavior/bugs/1851.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" { |
| 13 | 13 | x[0] = 0xFFFFFF; |
| 14 | 14 | x[1] = 0xFFFFFF; |
| 15 | 15 | |
| 16 | const bytes = @sliceToBytes(x); | |
| 16 | const bytes = std.mem.sliceAsBytes(x); | |
| 17 | 17 | expect(@TypeOf(bytes) == []align(4) u8); |
| 18 | 18 | expect(bytes.len == 8); |
| 19 | 19 |
test/stage1/behavior/cast.zig-20| ... | ... | @@ -304,20 +304,6 @@ fn cast128Float(x: u128) f128 { |
| 304 | 304 | return @bitCast(f128, x); |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | test "const slice widen cast" { | |
| 308 | const bytes align(4) = [_]u8{ | |
| 309 | 0x12, | |
| 310 | 0x12, | |
| 311 | 0x12, | |
| 312 | 0x12, | |
| 313 | }; | |
| 314 | ||
| 315 | const u32_value = @bytesToSlice(u32, bytes[0..])[0]; | |
| 316 | expect(u32_value == 0x12121212); | |
| 317 | ||
| 318 | expect(@bitCast(u32, bytes) == 0x12121212); | |
| 319 | } | |
| 320 | ||
| 321 | 307 | test "single-item pointer of array to slice and to unknown length pointer" { |
| 322 | 308 | testCastPtrOfArrayToSliceAndPtr(); |
| 323 | 309 | comptime testCastPtrOfArrayToSliceAndPtr(); |
| ... | ... | @@ -392,12 +378,6 @@ test "comptime_int @intToFloat" { |
| 392 | 378 | } |
| 393 | 379 | } |
| 394 | 380 | |
| 395 | test "@bytesToSlice keeps pointer alignment" { | |
| 396 | var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 }; | |
| 397 | const numbers = @bytesToSlice(u32, bytes[0..]); | |
| 398 | comptime expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32); | |
| 399 | } | |
| 400 | ||
| 401 | 381 | test "@intCast i32 to u7" { |
| 402 | 382 | var x: u128 = maxInt(u128); |
| 403 | 383 | var y: i32 = 120; |
test/stage1/behavior/eval.zig-10| ... | ... | @@ -711,16 +711,6 @@ test "bit shift a u1" { |
| 711 | 711 | expect(y == 1); |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | test "@bytesToslice on a packed struct" { | |
| 715 | const F = packed struct { | |
| 716 | a: u8, | |
| 717 | }; | |
| 718 | ||
| 719 | var b = [1]u8{9}; | |
| 720 | var f = @bytesToSlice(F, &b); | |
| 721 | expect(f[0].a == 9); | |
| 722 | } | |
| 723 | ||
| 724 | 714 | test "comptime pointer cast array and then slice" { |
| 725 | 715 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; |
| 726 | 716 |
test/stage1/behavior/misc.zig-21| ... | ... | @@ -3,7 +3,6 @@ const expect = std.testing.expect; |
| 3 | 3 | const expectEqualSlices = std.testing.expectEqualSlices; |
| 4 | 4 | const mem = std.mem; |
| 5 | 5 | const builtin = @import("builtin"); |
| 6 | const maxInt = std.math.maxInt; | |
| 7 | 6 | |
| 8 | 7 | // normal comment |
| 9 | 8 | |
| ... | ... | @@ -377,26 +376,6 @@ test "string concatenation" { |
| 377 | 376 | expect(b[len] == 0); |
| 378 | 377 | } |
| 379 | 378 | |
| 380 | test "cast slice to u8 slice" { | |
| 381 | expect(@sizeOf(i32) == 4); | |
| 382 | var big_thing_array = [_]i32{ 1, 2, 3, 4 }; | |
| 383 | const big_thing_slice: []i32 = big_thing_array[0..]; | |
| 384 | const bytes = @sliceToBytes(big_thing_slice); | |
| 385 | expect(bytes.len == 4 * 4); | |
| 386 | bytes[4] = 0; | |
| 387 | bytes[5] = 0; | |
| 388 | bytes[6] = 0; | |
| 389 | bytes[7] = 0; | |
| 390 | expect(big_thing_slice[1] == 0); | |
| 391 | const big_thing_again = @bytesToSlice(i32, bytes); | |
| 392 | expect(big_thing_again[2] == 3); | |
| 393 | big_thing_again[2] = -1; | |
| 394 | expect(bytes[8] == maxInt(u8)); | |
| 395 | expect(bytes[9] == maxInt(u8)); | |
| 396 | expect(bytes[10] == maxInt(u8)); | |
| 397 | expect(bytes[11] == maxInt(u8)); | |
| 398 | } | |
| 399 | ||
| 400 | 379 | test "pointer to void return type" { |
| 401 | 380 | testPointerToVoidReturnType() catch unreachable; |
| 402 | 381 | } |
test/stage1/behavior/slicetobytes.zig deleted-29| ... | ... | @@ -1,29 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "@sliceToBytes packed struct at runtime and comptime" { | |
| 6 | const Foo = packed struct { | |
| 7 | a: u4, | |
| 8 | b: u4, | |
| 9 | }; | |
| 10 | const S = struct { | |
| 11 | fn doTheTest() void { | |
| 12 | var foo: Foo = undefined; | |
| 13 | var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]); | |
| 14 | slice[0] = 0x13; | |
| 15 | switch (builtin.endian) { | |
| 16 | builtin.Endian.Big => { | |
| 17 | expect(foo.a == 0x1); | |
| 18 | expect(foo.b == 0x3); | |
| 19 | }, | |
| 20 | builtin.Endian.Little => { | |
| 21 | expect(foo.a == 0x3); | |
| 22 | expect(foo.b == 0x1); | |
| 23 | }, | |
| 24 | } | |
| 25 | } | |
| 26 | }; | |
| 27 | S.doTheTest(); | |
| 28 | comptime S.doTheTest(); | |
| 29 | } |
test/stage1/behavior/struct.zig+2-2| ... | ... | @@ -315,7 +315,7 @@ test "packed array 24bits" { |
| 315 | 315 | |
| 316 | 316 | var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); |
| 317 | 317 | bytes[bytes.len - 1] = 0xaa; |
| 318 | const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; | |
| 318 | const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; | |
| 319 | 319 | expect(ptr.a == 0); |
| 320 | 320 | expect(ptr.b[0].field == 0); |
| 321 | 321 | expect(ptr.b[1].field == 0); |
| ... | ... | @@ -364,7 +364,7 @@ test "aligned array of packed struct" { |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned); |
| 367 | const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0]; | |
| 367 | const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0]; | |
| 368 | 368 | |
| 369 | 369 | expect(ptr.a[0].a == 0xbb); |
| 370 | 370 | expect(ptr.a[0].b == 0xbb); |