Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions doc/langref/test_switch_dispatch_loop.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ const Instruction = enum {
};

fn evaluate(initial_stack: []const i32, code: []const Instruction) !i32 {
var stack = try std.BoundedArray(i32, 8).fromSlice(initial_stack);
var buffer: [8]i32 = undefined;
var stack = std.ArrayListUnmanaged(i32).initBuffer(&buffer);
try stack.appendSliceBounded(initial_stack);
var ip: usize = 0;

return vm: switch (code[ip]) {
// Because all code after `continue` is unreachable, this branch does
// not provide a result.
.add => {
try stack.append(stack.pop().? + stack.pop().?);
try stack.appendBounded(stack.pop().? + stack.pop().?);

ip += 1;
continue :vm code[ip];
},
.mul => {
try stack.append(stack.pop().? * stack.pop().?);
try stack.appendBounded(stack.pop().? * stack.pop().?);

ip += 1;
continue :vm code[ip];
Expand Down
66 changes: 40 additions & 26 deletions lib/docs/wasm/markdown/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ const Node = Document.Node;
const ExtraIndex = Document.ExtraIndex;
const ExtraData = Document.ExtraData;
const StringIndex = Document.StringIndex;
const ArrayList = std.ArrayListUnmanaged;

nodes: Node.List = .{},
extra: std.ArrayListUnmanaged(u32) = .empty,
scratch_extra: std.ArrayListUnmanaged(u32) = .empty,
string_bytes: std.ArrayListUnmanaged(u8) = .empty,
scratch_string: std.ArrayListUnmanaged(u8) = .empty,
pending_blocks: std.ArrayListUnmanaged(Block) = .empty,
extra: ArrayList(u32) = .empty,
scratch_extra: ArrayList(u32) = .empty,
string_bytes: ArrayList(u8) = .empty,
scratch_string: ArrayList(u8) = .empty,
pending_blocks: ArrayList(Block) = .empty,
allocator: Allocator,

const Parser = @This();
Expand Down Expand Up @@ -86,7 +87,8 @@ const Block = struct {
continuation_indent: usize,
},
table: struct {
column_alignments: std.BoundedArray(Node.TableCellAlignment, max_table_columns) = .{},
column_alignments_buffer: [max_table_columns]Node.TableCellAlignment,
column_alignments_len: usize,
},
heading: struct {
/// Between 1 and 6, inclusive.
Expand Down Expand Up @@ -354,7 +356,8 @@ const BlockStart = struct {
continuation_indent: usize,
},
table_row: struct {
cells: std.BoundedArray([]const u8, max_table_columns),
cells_buffer: [max_table_columns][]const u8,
cells_len: usize,
},
heading: struct {
/// Between 1 and 6, inclusive.
Expand Down Expand Up @@ -422,7 +425,8 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
try p.pending_blocks.append(p.allocator, .{
.tag = .table,
.data = .{ .table = .{
.column_alignments = .{},
.column_alignments_buffer = undefined,
.column_alignments_len = 0,
} },
.string_start = p.scratch_string.items.len,
.extra_start = p.scratch_extra.items.len,
Expand All @@ -431,15 +435,19 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {

const current_row = p.scratch_extra.items.len - p.pending_blocks.getLast().extra_start;
if (current_row <= 1) {
if (parseTableHeaderDelimiter(block_start.data.table_row.cells)) |alignments| {
p.pending_blocks.items[p.pending_blocks.items.len - 1].data.table.column_alignments = alignments;
var buffer: [max_table_columns]Node.TableCellAlignment = undefined;
const table_row = &block_start.data.table_row;
if (parseTableHeaderDelimiter(table_row.cells_buffer[0..table_row.cells_len], &buffer)) |alignments| {
const table = &p.pending_blocks.items[p.pending_blocks.items.len - 1].data.table;
@memcpy(table.column_alignments_buffer[0..alignments.len], alignments);
table.column_alignments_len = alignments.len;
if (current_row == 1) {
// We need to go back and mark the header row and its column
// alignments.
const datas = p.nodes.items(.data);
const header_data = datas[p.scratch_extra.getLast()];
for (p.extraChildren(header_data.container.children), 0..) |header_cell, i| {
const alignment = if (i < alignments.len) alignments.buffer[i] else .unset;
const alignment = if (i < alignments.len) alignments[i] else .unset;
const cell_data = &datas[@intFromEnum(header_cell)].table_cell;
cell_data.info.alignment = alignment;
cell_data.info.header = true;
Expand Down Expand Up @@ -480,8 +488,10 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
// available in the BlockStart. We can immediately parse and append
// these children now.
const containing_table = p.pending_blocks.items[p.pending_blocks.items.len - 2];
const column_alignments = containing_table.data.table.column_alignments.slice();
for (block_start.data.table_row.cells.slice(), 0..) |cell_content, i| {
const table = &containing_table.data.table;
const column_alignments = table.column_alignments_buffer[0..table.column_alignments_len];
const table_row = &block_start.data.table_row;
for (table_row.cells_buffer[0..table_row.cells_len], 0..) |cell_content, i| {
const cell_children = try p.parseInlines(cell_content);
const alignment = if (i < column_alignments.len) column_alignments[i] else .unset;
const cell = try p.addNode(.{
Expand Down Expand Up @@ -523,7 +533,8 @@ fn startBlock(p: *Parser, line: []const u8) !?BlockStart {
return .{
.tag = .table_row,
.data = .{ .table_row = .{
.cells = table_row.cells,
.cells_buffer = table_row.cells_buffer,
.cells_len = table_row.cells_len,
} },
.rest = "",
};
Expand Down Expand Up @@ -606,7 +617,8 @@ fn startListItem(unindented_line: []const u8) ?ListItemStart {
}

const TableRowStart = struct {
cells: std.BoundedArray([]const u8, max_table_columns),
cells_buffer: [max_table_columns][]const u8,
cells_len: usize,
};

fn startTableRow(unindented_line: []const u8) ?TableRowStart {
Expand All @@ -615,15 +627,16 @@ fn startTableRow(unindented_line: []const u8) ?TableRowStart {
mem.endsWith(u8, unindented_line, "\\|") or
!mem.endsWith(u8, unindented_line, "|")) return null;

var cells: std.BoundedArray([]const u8, max_table_columns) = .{};
var cells_buffer: [max_table_columns][]const u8 = undefined;
var cells: ArrayList([]const u8) = .initBuffer(&cells_buffer);
const table_row_content = unindented_line[1 .. unindented_line.len - 1];
var cell_start: usize = 0;
var i: usize = 0;
while (i < table_row_content.len) : (i += 1) {
switch (table_row_content[i]) {
'\\' => i += 1,
'|' => {
cells.append(table_row_content[cell_start..i]) catch return null;
cells.appendBounded(table_row_content[cell_start..i]) catch return null;
cell_start = i + 1;
},
'`' => {
Expand All @@ -641,20 +654,21 @@ fn startTableRow(unindented_line: []const u8) ?TableRowStart {
else => {},
}
}
cells.append(table_row_content[cell_start..]) catch return null;
cells.appendBounded(table_row_content[cell_start..]) catch return null;

return .{ .cells = cells };
return .{ .cells_buffer = cells_buffer, .cells_len = cells.items.len };
}

fn parseTableHeaderDelimiter(
row_cells: std.BoundedArray([]const u8, max_table_columns),
) ?std.BoundedArray(Node.TableCellAlignment, max_table_columns) {
var alignments: std.BoundedArray(Node.TableCellAlignment, max_table_columns) = .{};
for (row_cells.slice()) |content| {
row_cells: []const []const u8,
buffer: []Node.TableCellAlignment,
) ?[]Node.TableCellAlignment {
var alignments: ArrayList(Node.TableCellAlignment) = .initBuffer(buffer);
for (row_cells) |content| {
const alignment = parseTableHeaderDelimiterCell(content) orelse return null;
alignments.appendAssumeCapacity(alignment);
}
return alignments;
return alignments.items;
}

fn parseTableHeaderDelimiterCell(content: []const u8) ?Node.TableCellAlignment {
Expand Down Expand Up @@ -928,8 +942,8 @@ const InlineParser = struct {
parent: *Parser,
content: []const u8,
pos: usize = 0,
pending_inlines: std.ArrayListUnmanaged(PendingInline) = .empty,
completed_inlines: std.ArrayListUnmanaged(CompletedInline) = .empty,
pending_inlines: ArrayList(PendingInline) = .empty,
completed_inlines: ArrayList(CompletedInline) = .empty,

const PendingInline = struct {
tag: Tag,
Expand Down
15 changes: 0 additions & 15 deletions lib/std/Io.zig
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,6 @@ pub fn GenericReader(
return @errorCast(self.any().readBytesNoEof(num_bytes));
}

pub inline fn readIntoBoundedBytes(
self: Self,
comptime num_bytes: usize,
bounded: *std.BoundedArray(u8, num_bytes),
) Error!void {
return @errorCast(self.any().readIntoBoundedBytes(num_bytes, bounded));
}

pub inline fn readBoundedBytes(
self: Self,
comptime num_bytes: usize,
) Error!std.BoundedArray(u8, num_bytes) {
return @errorCast(self.any().readBoundedBytes(num_bytes));
}

pub inline fn readInt(self: Self, comptime T: type, endian: std.builtin.Endian) NoEofError!T {
return @errorCast(self.any().readInt(T, endian));
}
Expand Down
27 changes: 0 additions & 27 deletions lib/std/Io/DeprecatedReader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -249,33 +249,6 @@ pub fn readBytesNoEof(self: Self, comptime num_bytes: usize) anyerror![num_bytes
return bytes;
}

/// Reads bytes until `bounded.len` is equal to `num_bytes`,
/// or the stream ends.
///
/// * it is assumed that `num_bytes` will not exceed `bounded.capacity()`
pub fn readIntoBoundedBytes(
self: Self,
comptime num_bytes: usize,
bounded: *std.BoundedArray(u8, num_bytes),
) anyerror!void {
while (bounded.len < num_bytes) {
// get at most the number of bytes free in the bounded array
const bytes_read = try self.read(bounded.unusedCapacitySlice());
if (bytes_read == 0) return;

// bytes_read will never be larger than @TypeOf(bounded.len)
// due to `self.read` being bounded by `bounded.unusedCapacitySlice()`
bounded.len += @as(@TypeOf(bounded.len), @intCast(bytes_read));
}
}

/// Reads at most `num_bytes` and returns as a bounded array.
pub fn readBoundedBytes(self: Self, comptime num_bytes: usize) anyerror!std.BoundedArray(u8, num_bytes) {
var result = std.BoundedArray(u8, num_bytes){};
try self.readIntoBoundedBytes(num_bytes, &result);
return result;
}

pub inline fn readInt(self: Self, comptime T: type, endian: std.builtin.Endian) anyerror!T {
const bytes = try self.readBytesNoEof(@divExact(@typeInfo(T).int.bits, 8));
return mem.readInt(T, &bytes, endian);
Expand Down
21 changes: 0 additions & 21 deletions lib/std/Io/Reader/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -349,24 +349,3 @@ test "streamUntilDelimiter writes all bytes without delimiter to the output" {

try std.testing.expectError(error.StreamTooLong, reader.streamUntilDelimiter(writer, '!', 5));
}

test "readBoundedBytes correctly reads into a new bounded array" {
const test_string = "abcdefg";
var fis = std.io.fixedBufferStream(test_string);
const reader = fis.reader();

var array = try reader.readBoundedBytes(10000);
try testing.expectEqualStrings(array.slice(), test_string);
}

test "readIntoBoundedBytes correctly reads into a provided bounded array" {
const test_string = "abcdefg";
var fis = std.io.fixedBufferStream(test_string);
const reader = fis.reader();

var bounded_array = std.BoundedArray(u8, 10000){};

// compile time error if the size is not the same at the provided `bounded.capacity()`
try reader.readIntoBoundedBytes(10000, &bounded_array);
try testing.expectEqualStrings(bounded_array.slice(), test_string);
}
2 changes: 1 addition & 1 deletion lib/std/Progress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff
continue;
}
const src = pipe_buf[m.remaining_read_trash_bytes..n];
std.mem.copyForwards(u8, &pipe_buf, src);
@memmove(pipe_buf[0..src.len], src);
m.remaining_read_trash_bytes = 0;
bytes_read = src.len;
continue;
Expand Down
Loading