Skip to content

Commit

Permalink
Merge pull request ziglang#11813 from Vexu/stage2
Browse files Browse the repository at this point in the history
`zig2 build test-std` finale
  • Loading branch information
andrewrk authored Jun 8, 2022
2 parents 3cb3873 + 413577c commit 6ff7b43
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 53 deletions.
10 changes: 3 additions & 7 deletions lib/std/io/bit_reader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,9 @@ pub fn BitReader(endian: std.builtin.Endian, comptime ReaderType: type) type {
//copy bytes until we have enough bits, then leave the rest in bit_buffer
while (out_bits.* < bits) {
const n = bits - out_bits.*;
const next_byte = self.forward_reader.readByte() catch |err| {
if (err == error.EndOfStream) {
return @intCast(U, out_buffer);
}
//@BUG: See #1810. Not sure if the bug is that I have to do this for some
// streams, or that I don't for streams with emtpy errorsets.
return @errSetCast(Error, err);
const next_byte = self.forward_reader.readByte() catch |err| switch (err) {
error.EndOfStream => return @intCast(U, out_buffer),
else => |e| return e,
};

switch (endian) {
Expand Down
1 change: 1 addition & 0 deletions lib/std/io/stream_source.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ test "StreamSource (mutable buffer)" {
}

test "StreamSource (const buffer)" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };

Expand Down
2 changes: 2 additions & 0 deletions lib/std/math/big/rational.zig
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ test "big.rational setFloatString" {
}

test "big.rational toFloat" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
var a = try Rational.init(testing.allocator);
defer a.deinit();

Expand All @@ -586,6 +587,7 @@ test "big.rational toFloat" {
}

test "big.rational set/to Float round-trip" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
var a = try Rational.init(testing.allocator);
defer a.deinit();
var prng = std.rand.DefaultPrng.init(0x5EED);
Expand Down
11 changes: 8 additions & 3 deletions lib/std/net.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
};
defer file.close();

const stream = std.io.bufferedReader(file.reader()).reader();
var buf_reader = std.io.bufferedReader(file.reader());
const stream = buf_reader.reader();
var line_buf: [512]u8 = undefined;
while (stream.readUntilDelimiterOrEof(&line_buf, '\n') catch |err| switch (err) {
error.StreamTooLong => blk: {
Expand All @@ -1353,7 +1354,10 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
},
else => |e| return e,
}) |line| {
const no_comment_line = mem.split(u8, line, "#").next().?;
const no_comment_line = no_comment_line: {
var split = mem.split(u8, line, "#");
break :no_comment_line split.next().?;
};
var line_it = mem.tokenize(u8, no_comment_line, " \t");

const token = line_it.next() orelse continue;
Expand All @@ -1363,7 +1367,8 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
const name = colon_it.next().?;
const value_txt = colon_it.next() orelse continue;
const value = std.fmt.parseInt(u8, value_txt, 10) catch |err| switch (err) {
error.Overflow => 255,
// TODO https://github.com/ziglang/zig/issues/11812
error.Overflow => @as(u8, 255),
error.InvalidCharacter => continue,
};
if (mem.eql(u8, name, "ndots")) {
Expand Down
4 changes: 4 additions & 0 deletions lib/std/net/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const mem = std.mem;
const testing = std.testing;

test "parse and render IPv6 addresses" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
if (builtin.os.tag == .wasi) return error.SkipZigTest;

var buffer: [100]u8 = undefined;
Expand Down Expand Up @@ -67,6 +68,7 @@ test "invalid but parseable IPv6 scope ids" {
}

test "parse and render IPv4 addresses" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
if (builtin.os.tag == .wasi) return error.SkipZigTest;

var buffer: [18]u8 = undefined;
Expand All @@ -91,6 +93,7 @@ test "parse and render IPv4 addresses" {
}

test "parse and render UNIX addresses" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
if (builtin.os.tag == .wasi) return error.SkipZigTest;
if (!net.has_unix_sockets) return error.SkipZigTest;

Expand All @@ -104,6 +107,7 @@ test "parse and render UNIX addresses" {
}

test "resolve DNS" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
if (builtin.os.tag == .wasi) return error.SkipZigTest;

if (builtin.os.tag == .windows) {
Expand Down
1 change: 1 addition & 0 deletions lib/std/priority_queue.zig
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ test "std.PriorityQueue: fromOwnedSlice trivial case 1" {
}

test "std.PriorityQueue: fromOwnedSlice" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
const heap_items = try testing.allocator.dupe(u32, items[0..]);
var queue = PQlt.fromOwnedSlice(testing.allocator, heap_items[0..], {});
Expand Down
1 change: 1 addition & 0 deletions lib/std/simd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ pub fn extract(
}

test "vector patterns" {
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
const base = @Vector(4, u32){ 10, 20, 30, 40 };
const other_base = @Vector(4, u32){ 55, 66, 77, 88 };

Expand Down
5 changes: 4 additions & 1 deletion src/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6876,6 +6876,9 @@ fn asmExpr(
const constraint = (try astgen.strLitAsString(constraint_token)).index;
const has_arrow = token_tags[symbolic_name + 4] == .arrow;
if (has_arrow) {
if (output_type_bits != 0) {
return astgen.failNode(output_node, "inline assembly allows up to one output value", .{});
}
output_type_bits |= @as(u32, 1) << @intCast(u5, i);
const out_type_node = node_datas[output_node].lhs;
const out_type_inst = try typeExpr(gz, scope, out_type_node);
Expand All @@ -6892,7 +6895,7 @@ fn asmExpr(
outputs[i] = .{
.name = name,
.constraint = constraint,
.operand = try localVarRef(gz, scope, rl, node, ident_token),
.operand = try localVarRef(gz, scope, .ref, node, ident_token),
};
}
}
Expand Down
106 changes: 74 additions & 32 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7774,7 +7774,12 @@ fn zirSwitchCapture(
}

switch (operand_ty.zigTypeTag()) {
.ErrorSet => return sema.bitCast(block, block.switch_else_err_ty.?, operand, operand_src),
.ErrorSet => if (block.switch_else_err_ty) |some| {
return sema.bitCast(block, some, operand, operand_src);
} else {
try block.addUnreachable(operand_src, false);
return Air.Inst.Ref.unreachable_value;
},
else => return operand,
}
}
Expand Down Expand Up @@ -8194,7 +8199,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
);
}
else_error_ty = Type.@"anyerror";
} else {
} else else_validation: {
var maybe_msg: ?*Module.ErrorMsg = null;
errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);

Expand Down Expand Up @@ -8231,6 +8236,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
}

if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {

// In order to enable common patterns for generic code allow simple else bodies
// else => unreachable,
// else => return,
// else => |e| return e,
// even if all the possible errors were already handled.
const tags = sema.code.instructions.items(.tag);
for (special.body) |else_inst| switch (tags[else_inst]) {
.dbg_block_begin,
.dbg_block_end,
.dbg_stmt,
.dbg_var_val,
.switch_capture,
.ret_type,
.as_node,
.ret_node,
.@"unreachable",
=> {},
else => break,
} else break :else_validation;

return sema.fail(
block,
special_prong_src,
Expand Down Expand Up @@ -11308,43 +11334,40 @@ fn zirAsm(
try sema.requireRuntimeBlock(block, src);
}

if (outputs_len > 1) {
return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{});
}

var extra_i = extra.end;
var output_type_bits = extra.data.output_type_bits;
var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len;

const Output = struct {
constraint: []const u8,
name: []const u8,
ty: Type,
};
const output: ?Output = if (outputs_len == 0) null else blk: {
const ConstraintName = struct { c: []const u8, n: []const u8 };
const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len);
const outputs = try sema.arena.alloc(ConstraintName, outputs_len);
var expr_ty = Air.Inst.Ref.void_type;

for (out_args) |*arg, out_i| {
const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i);
extra_i = output.end;

const is_type = @truncate(u1, output_type_bits) != 0;
output_type_bits >>= 1;

if (!is_type) {
return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{});
if (is_type) {
// Indicate the output is the asm instruction return value.
arg.* = .none;
const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
expr_ty = try sema.addType(out_ty);
} else {
arg.* = try sema.resolveInst(output.data.operand);
}

const constraint = sema.code.nullTerminatedString(output.data.constraint);
const name = sema.code.nullTerminatedString(output.data.name);
needed_capacity += (constraint.len + name.len + (2 + 3)) / 4;

break :blk Output{
.constraint = constraint,
.name = name,
.ty = try sema.resolveType(block, ret_ty_src, output.data.operand),
};
};
outputs[out_i] = .{ .c = constraint, .n = name };
}

const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len);
const inputs = try sema.arena.alloc(ConstraintName, inputs_len);

for (args) |*arg, arg_i| {
const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
Expand Down Expand Up @@ -11379,7 +11402,7 @@ fn zirAsm(
const asm_air = try block.addInst(.{
.tag = .assembly,
.data = .{ .ty_pl = .{
.ty = if (output) |o| try sema.addType(o.ty) else Air.Inst.Ref.void_type,
.ty = expr_ty,
.payload = sema.addExtraAssumeCapacity(Air.Asm{
.source_len = @intCast(u32, asm_source.len),
.outputs_len = outputs_len,
Expand All @@ -11388,18 +11411,15 @@ fn zirAsm(
}),
} },
});
if (output != null) {
// Indicate the output is the asm instruction return value.
sema.air_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.none));
}
sema.appendRefsAssumeCapacity(out_args);
sema.appendRefsAssumeCapacity(args);
if (output) |o| {
for (outputs) |o| {
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
mem.copy(u8, buffer, o.constraint);
buffer[o.constraint.len] = 0;
mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name);
buffer[o.constraint.len + 1 + o.name.len] = 0;
sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4;
mem.copy(u8, buffer, o.c);
buffer[o.c.len] = 0;
mem.copy(u8, buffer[o.c.len + 1 ..], o.n);
buffer[o.c.len + 1 + o.n.len] = 0;
sema.air_extra.items.len += (o.c.len + o.n.len + (2 + 3)) / 4;
}
for (inputs) |input| {
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
Expand Down Expand Up @@ -21870,6 +21890,28 @@ fn analyzeIsNonErrComptimeOnly(
if (ies.is_anyerror) break :blk;
if (ies.errors.count() != 0) break :blk;
if (maybe_operand_val == null) {
// Try to avoid resolving inferred error set if possible.
if (ies.errors.count() != 0) break :blk;
if (ies.is_anyerror) break :blk;
var it = ies.inferred_error_sets.keyIterator();
while (it.next()) |other_error_set_ptr| {
const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*;
if (ies == other_ies) continue;
try sema.resolveInferredErrorSet(block, src, other_ies);
if (other_ies.is_anyerror) {
ies.is_anyerror = true;
ies.is_resolved = true;
break :blk;
}

if (other_ies.errors.count() != 0) break :blk;
}
if (ies.func == sema.owner_func) {
// We're checking the inferred errorset of the current function and none of
// its child inferred error sets contained any errors meaning that any value
// so far with this type can't contain errors either.
return Air.Inst.Ref.bool_true;
}
try sema.resolveInferredErrorSet(block, src, ies);
if (ies.is_anyerror) break :blk;
if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
Expand Down
25 changes: 15 additions & 10 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5012,7 +5012,7 @@ pub const FuncGen = struct {
const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);

const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "un";
const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "uns";

var fn_name_buf: [64]u8 = undefined;
const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
Expand Down Expand Up @@ -5435,18 +5435,17 @@ pub const FuncGen = struct {
const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
extra_i += inputs.len;

if (outputs.len > 1) {
return self.todo("implement llvm codegen for asm with more than 1 output", .{});
}

var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};
defer llvm_constraints.deinit(self.gpa);

var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();

const llvm_params_len = inputs.len;
const return_count: u8 = for (outputs) |output| {
if (output == .none) break 1;
} else 0;
const llvm_params_len = inputs.len + outputs.len - return_count;
const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len);
const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len);
var llvm_param_i: usize = 0;
Expand All @@ -5456,9 +5455,6 @@ pub const FuncGen = struct {
try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len);

for (outputs) |output| {
if (output != .none) {
return self.todo("implement inline asm with non-returned output", .{});
}
const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
Expand All @@ -5471,6 +5467,15 @@ pub const FuncGen = struct {
llvm_constraints.appendAssumeCapacity(',');
}
llvm_constraints.appendAssumeCapacity('=');
if (output != .none) {
try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1);
llvm_constraints.appendAssumeCapacity('*');

const output_inst = try self.resolveInst(output);
llvm_param_values[llvm_param_i] = output_inst;
llvm_param_types[llvm_param_i] = output_inst.typeOf();
llvm_param_i += 1;
}
llvm_constraints.appendSliceAssumeCapacity(constraint[1..]);

name_map.putAssumeCapacityNoClobber(name, {});
Expand Down Expand Up @@ -9284,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool {
}

fn compilerRtIntBits(bits: u16) u16 {
inline for (.{ 8, 16, 32, 64, 128 }) |b| {
inline for (.{ 32, 64, 128 }) |b| {
if (bits <= b) {
return b;
}
Expand Down
Loading

0 comments on commit 6ff7b43

Please sign in to comment.