From f47c6d3c6b5325ae682e50950765d352b2929126 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 28 Jun 2020 17:38:24 -0300 Subject: [PATCH 01/66] std.os: make EBADF return error for read and write --- lib/std/elf.zig | 1 + lib/std/os.zig | 20 +++++++++++--------- lib/std/zig/system.zig | 1 + src-self-hosted/main.zig | 2 ++ src-self-hosted/stage2.zig | 4 ++++ 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index dd22a42304b181b2f5978a548fe1afcba6e2f84f..3b0d749a66fa3453c4fdef76bfefb527ca2f6211 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -551,6 +551,7 @@ fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void { error.InputOutput => return error.FileSystem, error.Unexpected => return error.Unexpected, error.WouldBlock => return error.Unexpected, + error.NotOpenForReading => return error.Unexpected, }; if (len == 0) return error.UnexpectedEndOfFile; i += len; diff --git a/lib/std/os.zig b/lib/std/os.zig index 99d66db2bb648a195a780083016618b0a14f68a8..0dcece611c116c5f30a1a66ae33255b3dfe65efc 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -296,6 +296,7 @@ pub const ReadError = error{ BrokenPipe, ConnectionResetByPeer, ConnectionTimedOut, + NotOpenForReading, /// This error occurs when no global event loop is configured, /// and reading from the file descriptor would block. @@ -359,7 +360,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForReading, // Can be a race condition. EIO => return error.InputOutput, EISDIR => return error.IsDir, ENOBUFS => return error.SystemResources, @@ -420,7 +421,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // always a race condition + EBADF => return error.NotOpenForReading, // can be a race condition EIO => return error.InputOutput, EISDIR => return error.IsDir, ENOBUFS => return error.SystemResources, @@ -483,7 +484,7 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForReading, // Can be a race condition. EIO => return error.InputOutput, EISDIR => return error.IsDir, ENOBUFS => return error.SystemResources, @@ -623,7 +624,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // always a race condition + EBADF => return error.NotOpenForReading, // can be a race condition EIO => return error.InputOutput, EISDIR => return error.IsDir, ENOBUFS => return error.SystemResources, @@ -645,6 +646,7 @@ pub const WriteError = error{ BrokenPipe, SystemResources, OperationAborted, + NotOpenForWriting, /// This error occurs when no global event loop is configured, /// and reading from the file descriptor would block. @@ -720,7 +722,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForWriting, // can be a race condition. EDESTADDRREQ => unreachable, // `connect` was never called. EDQUOT => return error.DiskQuota, EFBIG => return error.FileTooBig, @@ -792,7 +794,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForWriting, // Can be a race condition. EDESTADDRREQ => unreachable, // `connect` was never called. EDQUOT => return error.DiskQuota, EFBIG => return error.FileTooBig, @@ -880,7 +882,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForWriting, // Can be a race condition. EDESTADDRREQ => unreachable, // `connect` was never called. EDQUOT => return error.DiskQuota, EFBIG => return error.FileTooBig, @@ -967,7 +969,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz } else { return error.WouldBlock; }, - EBADF => unreachable, // Always a race condition. + EBADF => return error.NotOpenForWriting, // Can be a race condition. EDESTADDRREQ => unreachable, // `connect` was never called. EDQUOT => return error.DiskQuota, EFBIG => return error.FileTooBig, @@ -1162,7 +1164,7 @@ pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void { EBUSY, EINTR => continue, EMFILE => return error.ProcessFdQuotaExceeded, EINVAL => unreachable, // invalid parameters passed to dup2 - EBADF => unreachable, // always a race condition + EBADF => unreachable, // invalid file descriptor else => |err| return unexpectedErrno(err), } } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 64c9401dbc03f1321b95c08bfea9cb12e7d05568..8a2c1dfc87c583f8729a6f34b1d96c63feedefc9 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -851,6 +851,7 @@ pub const NativeTargetInfo = struct { const len = file.pread(buf[i .. buf.len - i], offset + i) catch |err| switch (err) { error.OperationAborted => unreachable, // Windows-only error.WouldBlock => unreachable, // Did not request blocking mode + error.NotOpenForReading => unreachable, error.SystemResources => return error.SystemResources, error.IsDir => return error.UnableToReadElfFile, error.BrokenPipe => return error.UnableToReadElfFile, diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 3743b4f3342bad0111060cd58ef073847960e8a2..be1e941992d652ec3c6122902758ee0704fc1dd0 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -696,6 +696,7 @@ const FmtError = error{ LinkQuotaExceeded, FileBusy, EndOfStream, + NotOpenForWriting, } || fs.File.OpenError; fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) FmtError!void { @@ -761,6 +762,7 @@ fn fmtPathFile( const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| switch (err) { error.ConnectionResetByPeer => unreachable, error.ConnectionTimedOut => unreachable, + error.NotOpenForReading => unreachable, else => |e| return e, }; source_file.close(); diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index bd24ffb399f1663f871fb92e2c53c99de0baf08c..33e9200902ea6abff3f93160df83d280b3e1a187 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -153,6 +153,7 @@ export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { const c_out_stream = std.io.cOutStream(output_file); _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode + error.NotOpenForWriting => unreachable, error.SystemResources => return .SystemResources, error.OperationAborted => return .OperationAborted, error.BrokenPipe => return .BrokenPipe, @@ -585,6 +586,8 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [ error.SystemResources => return .SystemResources, error.OperationAborted => return .OperationAborted, error.WouldBlock => unreachable, + error.NotOpenForWriting => unreachable, + error.NotOpenForReading => unreachable, error.Unexpected => return .Unexpected, error.EndOfStream => return .EndOfFile, error.IsDir => return .IsDir, @@ -640,6 +643,7 @@ export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: const c_out_stream = std.io.cOutStream(output_file); libc.render(c_out_stream) catch |err| switch (err) { error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode + error.NotOpenForWriting => unreachable, error.SystemResources => return .SystemResources, error.OperationAborted => return .OperationAborted, error.BrokenPipe => return .BrokenPipe, -- 2.54.0 From 3f5b2d6c51b983ae66ad20124924378c2291cd67 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 29 Jun 2020 16:23:58 -0300 Subject: [PATCH 02/66] std.os: map EBADF to errors on WASI read/write syscalls --- lib/std/os.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 0dcece611c116c5f30a1a66ae33255b3dfe65efc..5677ab5e30574d2871d4f0a11048c8caeaf73383 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -329,7 +329,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForReading, // Can be a race condition. wasi.EIO => return error.InputOutput, wasi.EISDIR => return error.IsDir, wasi.ENOBUFS => return error.SystemResources, @@ -398,7 +398,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, // currently not support in WASI - wasi.EBADF => unreachable, // always a race condition + wasi.EBADF => return error.NotOpenForReading, // can be a race condition wasi.EIO => return error.InputOutput, wasi.EISDIR => return error.IsDir, wasi.ENOBUFS => return error.SystemResources, @@ -458,7 +458,7 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForReading, // Can be a race condition. wasi.EIO => return error.InputOutput, wasi.EISDIR => return error.IsDir, wasi.ENOBUFS => return error.SystemResources, @@ -597,7 +597,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // always a race condition + wasi.EBADF => return error.NotOpenForReading, // can be a race condition wasi.EIO => return error.InputOutput, wasi.EISDIR => return error.IsDir, wasi.ENOBUFS => return error.SystemResources, @@ -691,7 +691,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForWriting, // can be a race condition. wasi.EDESTADDRREQ => unreachable, // `connect` was never called. wasi.EDQUOT => return error.DiskQuota, wasi.EFBIG => return error.FileTooBig, @@ -768,7 +768,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForWriting, // can be a race condition. wasi.EDESTADDRREQ => unreachable, // `connect` was never called. wasi.EDQUOT => return error.DiskQuota, wasi.EFBIG => return error.FileTooBig, @@ -847,7 +847,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForWriting, // can be a race condition. wasi.EDESTADDRREQ => unreachable, // `connect` was never called. wasi.EDQUOT => return error.DiskQuota, wasi.EFBIG => return error.FileTooBig, @@ -940,7 +940,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz wasi.EINVAL => unreachable, wasi.EFAULT => unreachable, wasi.EAGAIN => unreachable, - wasi.EBADF => unreachable, // Always a race condition. + wasi.EBADF => return error.NotOpenForWriting, // Can be a race condition. wasi.EDESTADDRREQ => unreachable, // `connect` was never called. wasi.EDQUOT => return error.DiskQuota, wasi.EFBIG => return error.FileTooBig, -- 2.54.0 From 0977e4140768447e57474792ff42d056a8f2e0ed Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 10:36:57 +0300 Subject: [PATCH 03/66] stage2: ensure discarded error union payload is void --- src-self-hosted/astgen.zig | 6 +++++- src-self-hosted/zir.zig | 4 ++++ src-self-hosted/zir_sema.zig | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 3a9c7e6c59460d26521df7d913717267506e679c..b521e1543a5446ea34b24e9a03d548ffe1e4e78b 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -600,7 +600,11 @@ const CondKind = union(enum) { fn thenSubScope(self: CondKind, mod: *Module, then_scope: *Scope.GenZIR, src: usize, payload_node: ?*ast.Node) !*Scope { if (self == .bool) return &then_scope.base; - const payload = payload_node.?.castTag(.PointerPayload).?; + const payload = payload_node.?.castTag(.PointerPayload) orelse { + // condition is error union and payload is not explicitly ignored + _ = try addZIRUnOp(mod, &then_scope.base, src, .ensure_err_payload_void, self.err_union.?); + return &then_scope.base; + }; const is_ptr = payload.ptr_token != null; const ident_node = payload.value_symbol.castTag(.Identifier).?; diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 276db6d5224459314ecc074f0bbb5bccc9bc4d53..ebc491c94373af1d8c3b5162f03bb15fb9234c39 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -225,6 +225,8 @@ pub const Inst = struct { unwrap_err_safe, /// Same as previous, but without safety checks. Used for orelse, if and while unwrap_err_unsafe, + /// Takes a *E!T and raises a compiler error if T != void + ensure_err_payload_void, pub fn Type(tag: Tag) type { return switch (tag) { @@ -259,6 +261,7 @@ pub const Inst = struct { .unwrap_optional_unsafe, .unwrap_err_safe, .unwrap_err_unsafe, + .ensure_err_payload_void, => UnOp, .add, @@ -398,6 +401,7 @@ pub const Inst = struct { .unwrap_err_safe, .unwrap_err_unsafe, .ptr_type, + .ensure_err_payload_void, => false, .@"break", diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 94c3a19677aa69e718ee211217c1a87f26317a34..d51d0d0f7fae86a37d18732c8a7ec0cc3491b81c 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -112,6 +112,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false), .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true), .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false), + .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?), } } @@ -735,6 +736,10 @@ fn analyzeInstUnwrapErr(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, saf return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstUnwrapErr", .{}); } +fn analyzeInstEnsureErrPayloadVoid(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp) InnerError!*Inst { + return mod.fail(scope, unwrap.base.src, "TODO implement analyzeInstEnsureErrPayloadVoid", .{}); +} + fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst { const return_type = try resolveType(mod, scope, fntype.positionals.return_type); -- 2.54.0 From 3eb8f7be1018cef3043bfb56a0e2c3ff323e91d5 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 11:38:56 +0300 Subject: [PATCH 04/66] stage2: astgen bool and/or --- src-self-hosted/astgen.zig | 89 ++++++++++++++++++++++++++++++++++++-- src-self-hosted/zir.zig | 4 ++ 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index b521e1543a5446ea34b24e9a03d548ffe1e4e78b..b8860d7df6f10a39cda1744919aae16e2d379f1d 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -100,6 +100,9 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat), .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul), + .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?), + .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?), + .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?), .Asm => return rlWrap(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)), .StringLiteral => return rlWrap(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)), @@ -124,11 +127,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?), .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)), .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)), + .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr), .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), - .BoolAnd => return mod.failNode(scope, node, "TODO implement astgen.expr for .BoolAnd", .{}), - .BoolOr => return mod.failNode(scope, node, "TODO implement astgen.expr for .BoolOr", .{}), .ErrorUnion => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorUnion", .{}), .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}), .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}), @@ -159,7 +161,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .EnumLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .EnumLiteral", .{}), .MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}), .CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}), - .GroupedExpression => return mod.failNode(scope, node, "TODO implement astgen.expr for .GroupedExpression", .{}), .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), @@ -568,6 +569,88 @@ fn simpleBinOp( return rlWrap(mod, scope, rl, result); } +fn boolBinOp( + mod: *Module, + scope: *Scope, + rl: ResultLoc, + infix_node: *ast.Node.SimpleInfixOp, +) InnerError!*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[infix_node.op_token].start; + const bool_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.bool_type), + }); + + var block_scope: Scope.GenZIR = .{ + .parent = scope, + .decl = scope.decl().?, + .arena = scope.arena(), + .instructions = .{}, + }; + defer block_scope.instructions.deinit(mod.gpa); + + const lhs = try expr(mod, scope, .{ .ty = bool_type }, infix_node.lhs); + const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ + .condition = lhs, + .then_body = undefined, // populated below + .else_body = undefined, // populated below + }, .{}); + + const block = try addZIRInstBlock(mod, scope, src, .{ + .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), + }); + + var rhs_scope: Scope.GenZIR = .{ + .parent = scope, + .decl = block_scope.decl, + .arena = block_scope.arena, + .instructions = .{}, + }; + defer rhs_scope.instructions.deinit(mod.gpa); + + const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, infix_node.rhs); + _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ + .block = block, + .operand = rhs, + }, .{}); + + var const_scope: Scope.GenZIR = .{ + .parent = scope, + .decl = block_scope.decl, + .arena = block_scope.arena, + .instructions = .{}, + }; + defer const_scope.instructions.deinit(mod.gpa); + + const is_bool_and = infix_node.base.tag == .BoolAnd; + _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ + .block = block, + .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ + .ty = Type.initTag(.bool), + .val = if (is_bool_and) Value.initTag(.bool_false) else Value.initTag(.bool_true), + }), + }, .{}); + + if (is_bool_and) { + // if lhs // AND + // break rhs + // else + // break false + condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) }; + condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) }; + } else { + // if lhs // OR + // break true + // else + // break rhs + condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) }; + condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) }; + } + + return rlWrap(mod, scope, rl, &block.base); +} + const CondKind = union(enum) { bool, optional: ?*zir.Inst, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index ebc491c94373af1d8c3b5162f03bb15fb9234c39..3e8400dca7de70d89e06d352eb5a71463c9d8d7c 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -1924,6 +1924,10 @@ const EmitZIR = struct { return self.emitUnnamedDecl(&str_inst.base); }, .Void => return self.emitPrimitive(src, .void_value), + .Bool => if (typed_value.val.toBool()) + return self.emitPrimitive(src, .@"true") + else + return self.emitPrimitive(src, .@"false"), else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}), } } -- 2.54.0 From 7c15c9428e9df26c8699f034704796b03cf839b9 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 12:24:23 +0300 Subject: [PATCH 05/66] stage2: array types --- src-self-hosted/Module.zig | 67 ++++++++++++++++++- src-self-hosted/astgen.zig | 46 ++++++++++++- src-self-hosted/type.zig | 125 +++++++++++++++++++++++++++++------ src-self-hosted/zir.zig | 20 ++++++ src-self-hosted/zir_sema.zig | 45 ++++++------- 5 files changed, 254 insertions(+), 49 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 6e33101e76d56a6fc6aec17e0c3a2eea71a96e1b..3c31c7da44bf2ea3e13f3df03ed647acd6c3f788 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -2902,7 +2902,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: return Value.initPayload(val_payload); } -pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) error{OutOfMemory}!Type { +pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) Allocator.Error!Type { const type_payload = try scope.arena().create(Type.Payload.Pointer); type_payload.* = .{ .base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer }, @@ -2911,6 +2911,71 @@ pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, el return Type.initPayload(&type_payload.base); } +pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type { + return Type.initPayload(switch (child_type.tag()) { + .single_const_pointer => blk: { + const payload = try scope.arena().create(Type.Payload.Pointer); + payload.* = .{ + .base = .{ .tag = .optional_single_const_pointer }, + .pointee_type = child_type.elemType(), + }; + break :blk &payload.base; + }, + .single_mut_pointer => blk: { + const payload = try scope.arena().create(Type.Payload.Pointer); + payload.* = .{ + .base = .{ .tag = .optional_single_mut_pointer }, + .pointee_type = child_type.elemType(), + }; + break :blk &payload.base; + }, + else => blk: { + const payload = try scope.arena().create(Type.Payload.Optional); + payload.* = .{ + .child_type = child_type, + }; + break :blk &payload.base; + }, + }); +} + +pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_type: Type) Allocator.Error!Type { + if (elem_type.eql(Type.initTag(.u8))) { + if (sentinel) |some| { + if (some.eql(Value.initTag(.zero))) { + const payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0); + payload.* = .{ + .len = len, + }; + return Type.initPayload(&payload.base); + } + } else { + const payload = try scope.arena().create(Type.Payload.Array_u8); + payload.* = .{ + .len = len, + }; + return Type.initPayload(&payload.base); + } + } + + if (sentinel) |some| { + const payload = try scope.arena().create(Type.Payload.ArraySentinel); + payload.* = .{ + .len = len, + .sentinel = some, + .elem_type = elem_type, + }; + return Type.initPayload(&payload.base); + } + + const payload = try scope.arena().create(Type.Payload.Array); + payload.* = .{ + .len = len, + .elem_type = elem_type, + }; + return Type.initPayload(&payload.base); +} + pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void { const zir_module = scope.namespace(); const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source"); diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index b8860d7df6f10a39cda1744919aae16e2d379f1d..46ccde10f11f1623cbc9cfb9892a91c744c87cca 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -128,6 +128,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)), .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)), .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr), + .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)), + .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)), .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), @@ -141,8 +143,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}), .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}), .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}), - .ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}), - .ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}), .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}), .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}), .ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}), @@ -485,6 +485,48 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args); } +fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[node.op_token].start; + const meta_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.type_type), + }); + const usize_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.usize_type), + }); + + const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr); + const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); + + return addZIRBinOp(mod, scope, src, .array_type, len, child_type); +} + +fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[node.op_token].start; + const meta_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.type_type), + }); + const usize_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.usize_type), + }); + + const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr); + const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel); + const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); + const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted); + + return addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{ + .len = len, + .sentinel = sentinel, + .elem_type = elem_type, + }, .{}); +} + fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { const tree = scope.tree(); const src = tree.token_locs[node.rtoken].start; diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index faba784f902040f25efb6e67a0d2ddaa485204ed..5329841d4b006c7c3993abf3b8450e2df634fc34 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -65,7 +65,7 @@ pub const Type = extern union { .fn_ccc_void_no_args => return .Fn, .function => return .Fn, - .array, .array_u8_sentinel_0 => return .Array, + .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array, .single_const_pointer => return .Pointer, .single_mut_pointer => return .Pointer, .single_const_pointer_to_comptime_int => return .Pointer, @@ -330,6 +330,7 @@ pub const Type = extern union { => unreachable, .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), + .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8), .array => { const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise); const new_payload = try allocator.create(Payload.Array); @@ -340,6 +341,17 @@ pub const Type = extern union { }; return Type{ .ptr_otherwise = &new_payload.base }; }, + .array_sentinel => { + const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise); + const new_payload = try allocator.create(Payload.ArraySentinel); + new_payload.* = .{ + .base = payload.base, + .len = payload.len, + .sentinel = try payload.sentinel.copy(allocator), + .elem_type = try payload.elem_type.copy(allocator), + }; + return Type{ .ptr_otherwise = &new_payload.base }; + }, .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned), .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned), .function => { @@ -445,6 +457,10 @@ pub const Type = extern union { try payload.return_type.format("", .{}, out_stream); }, + .array_u8 => { + const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise); + return out_stream.print("[{}]u8", .{payload.len}); + }, .array_u8_sentinel_0 => { const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise); return out_stream.print("[{}:0]u8", .{payload.len}); @@ -455,6 +471,12 @@ pub const Type = extern union { ty = payload.elem_type; continue; }, + .array_sentinel => { + const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise); + try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel }); + ty = payload.elem_type; + continue; + }, .single_const_pointer => { const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); try out_stream.writeAll("*const "); @@ -588,6 +610,8 @@ pub const Type = extern union { => true, // TODO lazy types .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, + .array_u8 => self.arrayLen() != 0, + .array_sentinel => self.elemType().hasCodeGenBits(), .single_const_pointer => self.elemType().hasCodeGenBits(), .single_mut_pointer => self.elemType().hasCodeGenBits(), .int_signed => self.cast(Payload.IntSigned).?.bits == 0, @@ -616,6 +640,7 @@ pub const Type = extern union { .i8, .bool, .array_u8_sentinel_0, + .array_u8, => return 1, .fn_noreturn_no_args, // represents machine code; not a pointer @@ -659,7 +684,7 @@ pub const Type = extern union { .anyerror => return 2, // TODO revisit this when we have the concept of the error tag type - .array => return self.cast(Payload.Array).?.elem_type.abiAlignment(target), + .array, .array_sentinel => return self.elemType().abiAlignment(target), .int_signed, .int_unsigned => { const bits: u16 = if (self.cast(Payload.IntSigned)) |pl| @@ -717,12 +742,18 @@ pub const Type = extern union { .bool, => return 1, - .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len, + .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len, + .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1, .array => { const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise); const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); return payload.len * elem_size; }, + .array_sentinel => { + const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise); + const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); + return (payload.len + 1) * elem_size; + }, .i16, .u16 => return 2, .i32, .u32 => return 4, .i64, .u64 => return 8, @@ -818,6 +849,8 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, .array_u8_sentinel_0, .const_slice_u8, .fn_noreturn_no_args, @@ -875,6 +908,8 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, @@ -931,6 +966,8 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, .array_u8_sentinel_0, .fn_noreturn_no_args, .fn_void_no_args, @@ -988,6 +1025,8 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, .array_u8_sentinel_0, .fn_noreturn_no_args, .fn_void_no_args, @@ -1072,9 +1111,10 @@ pub const Type = extern union { => unreachable, .array => self.cast(Payload.Array).?.elem_type, + .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type, .single_const_pointer => self.castPointer().?.pointee_type, .single_mut_pointer => self.castPointer().?.pointee_type, - .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), + .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), }; } @@ -1176,6 +1216,8 @@ pub const Type = extern union { => unreachable, .array => self.cast(Payload.Array).?.len, + .array_sentinel => self.cast(Payload.ArraySentinel).?.len, + .array_u8 => self.cast(Payload.Array_u8).?.len, .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len, }; } @@ -1232,7 +1274,8 @@ pub const Type = extern union { .optional_single_const_pointer, => unreachable, - .array => return null, + .array, .array_u8 => return null, + .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel, .array_u8_sentinel_0 => return Value.initTag(.zero), }; } @@ -1266,10 +1309,12 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .int_unsigned, .u8, @@ -1324,10 +1369,12 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .int_signed, .i8, @@ -1382,10 +1429,12 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .optional, .optional_single_mut_pointer, @@ -1438,10 +1487,12 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .int_unsigned, .int_signed, @@ -1523,10 +1574,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1584,10 +1637,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1644,10 +1699,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1704,10 +1761,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1761,10 +1820,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1818,10 +1879,12 @@ pub const Type = extern union { .@"null", .@"undefined", .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .u8, .i8, @@ -1895,10 +1958,12 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .optional, .optional_single_mut_pointer, @@ -1944,6 +2009,7 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .single_const_pointer_to_comptime_int, + .array_sentinel, .array_u8_sentinel_0, .const_slice_u8, .c_void, @@ -1971,11 +2037,10 @@ pub const Type = extern union { return null; } }, - .array => { - const array = ty.cast(Payload.Array).?; - if (array.len == 0) + .array, .array_u8 => { + if (ty.arrayLen() == 0) return Value.initTag(.empty_array); - ty = array.elem_type; + ty = ty.elemType(); continue; }, .single_const_pointer, .single_mut_pointer => { @@ -2022,7 +2087,6 @@ pub const Type = extern union { .fn_ccc_void_no_args, .function, .single_const_pointer_to_comptime_int, - .array_u8_sentinel_0, .const_slice_u8, .c_void, .void, @@ -2032,6 +2096,9 @@ pub const Type = extern union { .int_unsigned, .int_signed, .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, .optional, @@ -2090,8 +2157,10 @@ pub const Type = extern union { const_slice_u8, // See last_no_payload_tag below. // After this, the tag requires a payload. + array_u8, array_u8_sentinel_0, array, + array_sentinel, single_const_pointer, single_mut_pointer, int_signed, @@ -2114,11 +2183,25 @@ pub const Type = extern union { len: u64, }; + pub const Array_u8 = struct { + base: Payload = Payload{ .tag = .array_u8 }, + + len: u64, + }; + pub const Array = struct { base: Payload = Payload{ .tag = .array }, + len: u64, elem_type: Type, + }; + + pub const ArraySentinel = struct { + base: Payload = Payload{ .tag = .array_sentinel }, + len: u64, + sentinel: Value, + elem_type: Type, }; pub const Pointer = struct { diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 3e8400dca7de70d89e06d352eb5a71463c9d8d7c..a38c1b8373ba42c6074976768280460cccf33a95 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -47,6 +47,10 @@ pub const Inst = struct { array_cat, /// Array multiplication `a ** b` array_mul, + /// Create an array type + array_type, + /// Create an array type with sentinel + array_type_sentinel, /// Function parameter value. These must be first in a function's main block, /// in respective order with the parameters. arg, @@ -268,6 +272,7 @@ pub const Inst = struct { .addwrap, .array_cat, .array_mul, + .array_type, .bitand, .bitor, .div, @@ -294,6 +299,7 @@ pub const Inst = struct { => BinOp, .arg => Arg, + .array_type_sentinel => ArrayTypeSentinel, .block => Block, .@"break" => Break, .breakvoid => BreakVoid, @@ -333,6 +339,8 @@ pub const Inst = struct { .alloc_inferred, .array_cat, .array_mul, + .array_type, + .array_type_sentinel, .arg, .as, .@"asm", @@ -849,6 +857,18 @@ pub const Inst = struct { sentinel: ?*Inst = null, }, }; + + pub const ArrayTypeSentinel = struct { + pub const base_tag = Tag.array_type_sentinel; + base: Inst, + + positionals: struct { + len: *Inst, + sentinel: *Inst, + elem_type: *Inst, + }, + kw_args: struct {}, + }; }; pub const ErrorMsg = struct { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index d51d0d0f7fae86a37d18732c8a7ec0cc3491b81c..593330f782bd450c208bc0872acf188b06d8fc51 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -113,6 +113,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true), .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false), .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?), + .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?), + .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?), } } @@ -676,31 +678,24 @@ fn analyzeInstIntType(mod: *Module, scope: *Scope, inttype: *zir.Inst.IntType) I fn analyzeInstOptionalType(mod: *Module, scope: *Scope, optional: *zir.Inst.UnOp) InnerError!*Inst { const child_type = try resolveType(mod, scope, optional.positionals.operand); - return mod.constType(scope, optional.base.src, Type.initPayload(switch (child_type.tag()) { - .single_const_pointer => blk: { - const payload = try scope.arena().create(Type.Payload.Pointer); - payload.* = .{ - .base = .{ .tag = .optional_single_const_pointer }, - .pointee_type = child_type.elemType(), - }; - break :blk &payload.base; - }, - .single_mut_pointer => blk: { - const payload = try scope.arena().create(Type.Payload.Pointer); - payload.* = .{ - .base = .{ .tag = .optional_single_mut_pointer }, - .pointee_type = child_type.elemType(), - }; - break :blk &payload.base; - }, - else => blk: { - const payload = try scope.arena().create(Type.Payload.Optional); - payload.* = .{ - .child_type = child_type, - }; - break :blk &payload.base; - }, - })); + return mod.constType(scope, optional.base.src, try mod.optionalType(scope, child_type)); +} + +fn analyzeInstArrayType(mod: *Module, scope: *Scope, array: *zir.Inst.BinOp) InnerError!*Inst { + // TODO these should be lazily evaluated + const len = try resolveInstConst(mod, scope, array.positionals.lhs); + const elem_type = try resolveType(mod, scope, array.positionals.rhs); + + return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type)); +} + +fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.ArrayTypeSentinel) InnerError!*Inst { + // TODO these should be lazily evaluated + const len = try resolveInstConst(mod, scope, array.positionals.len); + const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel); + const elem_type = try resolveType(mod, scope, array.positionals.elem_type); + + return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type)); } fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst { -- 2.54.0 From 31d8efc6b32a6b60b7ab292ac50e0f6c02bc140e Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 13:57:09 +0300 Subject: [PATCH 06/66] stage2: validate param and variable types --- src-self-hosted/type.zig | 39 ++++++++++++++++++++++++++++++++++++ src-self-hosted/zir_sema.zig | 10 ++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 5329841d4b006c7c3993abf3b8450e2df634fc34..25f0be16f98a3bf1619fbf568f732d46ea90fda9 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -1062,6 +1062,45 @@ pub const Type = extern union { } } + /// Returns if type can be used for a runtime variable + pub fn isValidVarType(self: Type) bool { + var ty = self; + while (true) switch (ty.zigTypeTag()) { + .Bool, + .Int, + .Float, + .ErrorSet, + .Enum, + .Frame, + .AnyFrame, + .Vector, + => return true, + + .BoundFn, + .ComptimeFloat, + .ComptimeInt, + .EnumLiteral, + .NoReturn, + .Type, + .Void, + .Undefined, + .Null, + .Opaque, + => return false, + + .Optional => { + var buf: Payload.Pointer = undefined; + return ty.optionalChild(&buf).isValidVarType(); + }, + .Pointer, .Array => ty = ty.elemType(), + + .ErrorUnion => @panic("TODO fn isValidVarType"), + .Fn => @panic("TODO fn isValidVarType"), + .Struct => @panic("TODO struct isValidVarType"), + .Union => @panic("TODO union isValidVarType"), + }; + } + /// Asserts the type is a pointer or array type. pub fn elemType(self: Type) Type { return switch (self.tag()) { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 593330f782bd450c208bc0872acf188b06d8fc51..49009d8dec032c8570c45ec54548e5c7f000e7b8 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -364,6 +364,9 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst. fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { const var_type = try resolveType(mod, scope, inst.positionals.operand); + if (!var_type.isValidVarType()) { + return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type}); + } const ptr_type = try mod.singlePtrType(scope, inst.base.src, true, var_type); const b = try mod.requireRuntimeBlock(scope, inst.base.src); return mod.addNoOp(b, inst.base.src, ptr_type, .alloc); @@ -760,7 +763,12 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne const arena = scope.arena(); const param_types = try arena.alloc(Type, fntype.positionals.param_types.len); for (fntype.positionals.param_types) |param_type, i| { - param_types[i] = try resolveType(mod, scope, param_type); + const resolved = try resolveType(mod, scope, param_type); + // TODO skip for comptime params + if (!resolved.isValidVarType()) { + return mod.fail(scope, param_type.src, "parameter of type '{}' must be declared comptime", .{resolved}); + } + param_types[i] = resolved; } const payload = try arena.create(Type.Payload.Function); -- 2.54.0 From e0b01bd4a98e2605f197a04f84e0c281ccc90f81 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 14:28:33 +0300 Subject: [PATCH 07/66] stage2: enum literals --- src-self-hosted/astgen.zig | 10 +++++++++- src-self-hosted/type.zig | 30 +++++++++++++++++++++++++++++- src-self-hosted/value.zig | 35 +++++++++++++++++++++++++++++++++-- src-self-hosted/zir.zig | 14 ++++++++++++++ src-self-hosted/zir_sema.zig | 13 +++++++++++++ 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 46ccde10f11f1623cbc9cfb9892a91c744c87cca..87f69e053ab06714c2d7a28cb0575219678397c8 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -130,6 +130,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr), .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)), .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)), + .EnumLiteral => return rlWrap(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)), .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), @@ -158,7 +159,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}), .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}), .AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}), - .EnumLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .EnumLiteral", .{}), .MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}), .CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}), .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), @@ -527,6 +527,14 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti }, .{}); } +fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[node.name].start; + const name = try identifierTokenString(mod, scope, node.name); + + return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{}); +} + fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { const tree = scope.tree(); const src = tree.token_locs[node.rtoken].start; diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 25f0be16f98a3bf1619fbf568f732d46ea90fda9..a6ec90a35b0788845413d611beb699f8f31d4ac6 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -75,6 +75,7 @@ pub const Type = extern union { .optional_single_const_pointer, .optional_single_mut_pointer, => return .Optional, + .enum_literal => return .EnumLiteral, } } @@ -127,6 +128,7 @@ pub const Type = extern union { if (zig_tag_a != zig_tag_b) return false; switch (zig_tag_a) { + .EnumLiteral => return true, .Type => return true, .Void => return true, .Bool => return true, @@ -211,7 +213,6 @@ pub const Type = extern union { .Frame, .AnyFrame, .Vector, - .EnumLiteral, => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), } } @@ -327,6 +328,7 @@ pub const Type = extern union { .fn_ccc_void_no_args, .single_const_pointer_to_comptime_int, .const_slice_u8, + .enum_literal, => unreachable, .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), @@ -437,6 +439,7 @@ pub const Type = extern union { .noreturn, => return out_stream.writeAll(@tagName(t)), + .enum_literal => return out_stream.writeAll("@TypeOf(.EnumLiteral)"), .@"null" => return out_stream.writeAll("@TypeOf(null)"), .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"), @@ -561,6 +564,7 @@ pub const Type = extern union { .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type), .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type), .const_slice_u8 => return Value.initTag(.const_slice_u8_type), + .enum_literal => return Value.initTag(.enum_literal_type), else => { const ty_payload = try allocator.create(Value.Payload.Ty); ty_payload.* = .{ .ty = self }; @@ -625,6 +629,7 @@ pub const Type = extern union { .noreturn, .@"null", .@"undefined", + .enum_literal, => false, }; } @@ -716,6 +721,7 @@ pub const Type = extern union { .noreturn, .@"null", .@"undefined", + .enum_literal, => unreachable, }; } @@ -736,6 +742,7 @@ pub const Type = extern union { .noreturn => unreachable, .@"null" => unreachable, .@"undefined" => unreachable, + .enum_literal => unreachable, .u8, .i8, @@ -863,6 +870,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .single_const_pointer, @@ -924,6 +932,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .const_slice_u8 => true, @@ -980,6 +989,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .single_const_pointer, @@ -1042,6 +1052,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, }; } @@ -1147,6 +1158,7 @@ pub const Type = extern union { .optional, .optional_single_const_pointer, .optional_single_mut_pointer, + .enum_literal, => unreachable, .array => self.cast(Payload.Array).?.elem_type, @@ -1252,6 +1264,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, .array => self.cast(Payload.Array).?.len, @@ -1311,6 +1324,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, .array, .array_u8 => return null, @@ -1368,6 +1382,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .int_signed, @@ -1428,6 +1443,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .int_unsigned, @@ -1478,6 +1494,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits }, @@ -1546,6 +1563,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, .usize, @@ -1643,6 +1661,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, }; } @@ -1706,6 +1725,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, } } @@ -1768,6 +1788,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, } } @@ -1830,6 +1851,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, }; } @@ -1889,6 +1911,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, }; } @@ -1948,6 +1971,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => unreachable, }; } @@ -2007,6 +2031,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => false, }; } @@ -2055,6 +2080,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => return null, .void => return Value.initTag(.void_value), @@ -2143,6 +2169,7 @@ pub const Type = extern union { .optional, .optional_single_mut_pointer, .optional_single_const_pointer, + .enum_literal, => return false, }; } @@ -2186,6 +2213,7 @@ pub const Type = extern union { comptime_int, comptime_float, noreturn, + enum_literal, @"null", @"undefined", fn_noreturn_no_args, diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index c8af4716a620373eaa08508379d03ee0d6336a84..b6356d9b176f2966e3c057b452ec61485008ba83 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -60,6 +60,7 @@ pub const Value = extern union { fn_ccc_void_no_args_type, single_const_pointer_to_comptime_int_type, const_slice_u8_type, + enum_literal_type, undef, zero, @@ -87,6 +88,7 @@ pub const Value = extern union { float_32, float_64, float_128, + enum_literal, pub const last_no_payload_tag = Tag.bool_false; pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; @@ -164,6 +166,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .undef, .zero, .void_value, @@ -213,7 +216,7 @@ pub const Value = extern union { }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), + .enum_literal, .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), .repeated => { const payload = @fieldParentPtr(Payload.Repeated, "base", self.ptr_otherwise); const new_payload = try allocator.create(Payload.Repeated); @@ -285,6 +288,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"), .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"), .const_slice_u8_type => return out_stream.writeAll("[]const u8"), + .enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"), .null_value => return out_stream.writeAll("null"), .undef => return out_stream.writeAll("undefined"), @@ -318,7 +322,7 @@ pub const Value = extern union { val = elem_ptr.array_ptr; }, .empty_array => return out_stream.writeAll(".{}"), - .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream), + .enum_literal, .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream), .repeated => { try out_stream.writeAll("(repeated) "); val = val.cast(Payload.Repeated).?.val; @@ -391,6 +395,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args), .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int), .const_slice_u8_type => Type.initTag(.const_slice_u8), + .enum_literal_type => Type.initTag(.enum_literal), .undef, .zero, @@ -414,6 +419,7 @@ pub const Value = extern union { .float_32, .float_64, .float_128, + .enum_literal, => unreachable, }; } @@ -462,6 +468,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -476,6 +483,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .undef => unreachable, @@ -537,6 +545,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -551,6 +560,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .undef => unreachable, @@ -612,6 +622,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -626,6 +637,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .undef => unreachable, @@ -713,6 +725,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -728,6 +741,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .zero, @@ -793,6 +807,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -807,6 +822,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .zero, @@ -953,6 +969,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .bool_true, .bool_false, .null_value, @@ -970,6 +987,7 @@ pub const Value = extern union { .empty_array, .void_value, .unreachable_value, + .enum_literal, => unreachable, .zero => false, @@ -1025,6 +1043,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .null_value, .function, .ref_val, @@ -1036,6 +1055,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .zero, @@ -1102,6 +1122,11 @@ pub const Value = extern union { } pub fn eql(a: Value, b: Value) bool { + if (a.tag() == b.tag() and a.tag() == .enum_literal) { + const a_name = @fieldParentPtr(Payload.Bytes, "base", a.ptr_otherwise).data; + const b_name = @fieldParentPtr(Payload.Bytes, "base", b.ptr_otherwise).data; + return std.mem.eql(u8, a_name, b_name); + } // TODO non numerical comparisons return compare(a, .eq, b); } @@ -1151,6 +1176,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .zero, .bool_true, .bool_false, @@ -1170,6 +1196,7 @@ pub const Value = extern union { .void_value, .unreachable_value, .empty_array, + .enum_literal, => unreachable, .ref_val => self.cast(Payload.RefVal).?.val, @@ -1227,6 +1254,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .zero, .bool_true, .bool_false, @@ -1246,6 +1274,7 @@ pub const Value = extern union { .float_128, .void_value, .unreachable_value, + .enum_literal, => unreachable, .empty_array => unreachable, // out of bounds array index @@ -1320,6 +1349,7 @@ pub const Value = extern union { .fn_ccc_void_no_args_type, .single_const_pointer_to_comptime_int_type, .const_slice_u8_type, + .enum_literal_type, .zero, .empty_array, .bool_true, @@ -1339,6 +1369,7 @@ pub const Value = extern union { .float_64, .float_128, .void_value, + .enum_literal, => false, .undef => unreachable, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index a38c1b8373ba42c6074976768280460cccf33a95..235a4c931bcf2471ca3008bdc138b6b9cbacb4d6 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -231,6 +231,8 @@ pub const Inst = struct { unwrap_err_unsafe, /// Takes a *E!T and raises a compiler error if T != void ensure_err_payload_void, + /// Enum literal + enum_literal, pub fn Type(tag: Tag) type { return switch (tag) { @@ -326,6 +328,7 @@ pub const Inst = struct { .elemptr => ElemPtr, .condbr => CondBr, .ptr_type => PtrType, + .enum_literal => EnumLiteral, }; } @@ -410,6 +413,7 @@ pub const Inst = struct { .unwrap_err_unsafe, .ptr_type, .ensure_err_payload_void, + .enum_literal, => false, .@"break", @@ -869,6 +873,16 @@ pub const Inst = struct { }, kw_args: struct {}, }; + + pub const EnumLiteral = struct { + pub const base_tag = Tag.enum_literal; + base: Inst, + + positionals: struct { + name: []const u8, + }, + kw_args: struct {}, + }; }; pub const ErrorMsg = struct { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 49009d8dec032c8570c45ec54548e5c7f000e7b8..5c473494fbdd97a2fa4427cfded8d185e65273ad 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -115,6 +115,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?), .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?), .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?), + .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?), } } @@ -701,6 +702,18 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type)); } +fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst { + const payload = try scope.arena().create(Value.Payload.Bytes); + payload.* = .{ + .base = .{ .tag = .enum_literal }, + .data = try scope.arena().dupe(u8, inst.positionals.name), + }; + return mod.constInst(scope, inst.base.src, .{ + .ty = Type.initTag(.enum_literal), + .val = Value.initPayload(&payload.base), + }); +} + fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst { const operand = try resolveInst(mod, scope, unwrap.positionals.operand); assert(operand.ty.zigTypeTag() == .Pointer); -- 2.54.0 From 2b45e23477605e15fecec3566b3dc90b71e2f7a7 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 15:33:11 +0300 Subject: [PATCH 08/66] stage2: character literals and multiline strings --- lib/std/zig.zig | 101 +++++++++++++++++++++++++++++++++ src-self-hosted/astgen.zig | 53 ++++++++++++++++- src-self-hosted/zir_sema.zig | 1 + test/stage2/compare_output.zig | 32 +++++++++++ 4 files changed, 185 insertions(+), 2 deletions(-) diff --git a/lib/std/zig.zig b/lib/std/zig.zig index b070fbdcd5cf711d1079fab6683a7885965f4de2..36dfe740865875747b0960a9025af1ef26c84418 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -80,6 +80,107 @@ pub fn binNameAlloc( } } +/// Only validates escape sequence characters. +/// Slice must be valid utf8 starting and ending with "'" and exactly one codepoint in between. +pub fn parseCharLiteral( + slice: []const u8, + bad_index: *usize, // populated if error.InvalidCharacter is returned) +) error{InvalidCharacter}!u32 { + std.debug.assert(slice.len >= 3 and slice[0] == '\'' and slice[slice.len - 1] == '\''); + + if (slice[1] == '\\') { + switch (slice[2]) { + 'n' => return '\n', + 'r' => return '\r', + '\\' => return '\\', + 't' => return '\t', + '\'' => return '\'', + '"' => return '"', + 'x' => { + if (slice.len != 6) { + bad_index.* = slice.len - 2; + return error.InvalidCharacter; + } + + var value: u32 = 0; + for (slice[3..5]) |c, i| { + switch (slice[3]) { + '0'...'9' => { + value *= 16; + value += c - '0'; + }, + 'a'...'f' => { + value *= 16; + value += c - 'a'; + }, + 'A'...'F' => { + value *= 16; + value += c - 'a'; + }, + else => { + bad_index.* = i; + return error.InvalidCharacter; + }, + } + } + return value; + }, + 'u' => { + if (slice.len < 6 or slice[3] != '{') { + bad_index.* = 2; + return error.InvalidCharacter; + } + var value: u32 = 0; + for (slice[4..]) |c, i| { + if (value > 0x10ffff) { + bad_index.* = i; + return error.InvalidCharacter; + } + switch (c) { + '0'...'9' => { + value *= 16; + value += c - '0'; + }, + 'a'...'f' => { + value *= 16; + value += c - 'a'; + }, + 'A'...'F' => { + value *= 16; + value += c - 'A'; + }, + '}' => break, + else => { + bad_index.* = i; + return error.InvalidCharacter; + }, + } + } + return value; + }, + else => { + bad_index.* = 2; + return error.InvalidCharacter; + } + } + } + return std.unicode.utf8Decode(slice[1 .. slice.len - 1]) catch unreachable; +} + +test "parseCharLiteral" { + var bad_index: usize = undefined; + std.testing.expectEqual(try parseCharLiteral("'a'", &bad_index), 'a'); + std.testing.expectEqual(try parseCharLiteral("'ä'", &bad_index), 'ä'); + std.testing.expectEqual(try parseCharLiteral("'\\x00'", &bad_index), 0); + std.testing.expectEqual(try parseCharLiteral("'ぁ'", &bad_index), 0x3041); + std.testing.expectEqual(try parseCharLiteral("'\\u{3041}'", &bad_index), 0x3041); + + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x0'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\y'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFFFF}'", &bad_index)); +} + test "" { @import("std").meta.refAllDecls(@This()); } diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 87f69e053ab06714c2d7a28cb0575219678397c8..f05020f6df794e2a1232367d3221788ab3b4afe1 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -131,6 +131,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)), .ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)), .EnumLiteral => return rlWrap(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)), + .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)), + .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)), .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), @@ -159,8 +161,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}), .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}), .AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}), - .MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}), - .CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}), .ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}), .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), @@ -497,6 +497,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst .val = Value.initTag(.usize_type), }); + // TODO check for [_]T const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr); const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); @@ -515,6 +516,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti .val = Value.initTag(.usize_type), }); + // TODO check for [_]T const len = try expr(mod, scope, .{ .ty = usize_type }, node.len_expr); const sentinel_uncasted = try expr(mod, scope, .none, node.sentinel); const elem_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); @@ -1120,6 +1122,53 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); } +fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst { + const tree = scope.tree(); + const lines = node.linesConst(); + const src = tree.token_locs[lines[0]].start; + + // line lengths and new lines + var len = lines.len - 1; + for (lines) |line| { + len += tree.tokenSlice(line).len - 2; + } + + const bytes = try scope.arena().alloc(u8, len); + var i: usize = 0; + for (lines) |line, line_i| { + if (line_i != 0) { + bytes[i] = '\n'; + i += 1; + } + const slice = tree.tokenSlice(line)[2..]; + mem.copy(u8, bytes[i..], slice); + i += slice.len; + } + + return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); +} + +fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[node.token].start; + const slice = tree.tokenSlice(node.token); + + var bad_index: usize = undefined; + const value = std.zig.parseCharLiteral(slice, &bad_index) catch |err| switch (err) { + error.InvalidCharacter => { + const bad_byte = slice[bad_index]; + return mod.fail(scope, src + bad_index, "invalid character: '{c}'\n", .{bad_byte}); + }, + }; + + const int_payload = try scope.arena().create(Value.Payload.Int_u64); + int_payload.* = .{ .int = value }; + return addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.comptime_int), + .val = Value.initPayload(&int_payload.base), + }); +} + fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst { const arena = scope.arena(); const tree = scope.tree(); diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 5c473494fbdd97a2fa4427cfded8d185e65273ad..3a2a593539a87e19a1283fc3ba5a2687ba18995c 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -365,6 +365,7 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst. fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { const var_type = try resolveType(mod, scope, inst.positionals.operand); + // TODO this should happen only for var allocs if (!var_type.isValidVarType()) { return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type}); } diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 4208cc3911ddec346a5fd06077d78a034a908b89..8b92674e9ce6be297c561684f0e04e6b7b2b79f1 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -543,6 +543,38 @@ pub fn addCases(ctx: *TestContext) !void { , "", ); + + case.addCompareOutput( + \\export fn _start() noreturn { + \\ const ignore = + \\ \\ cool thx + \\ \\ + \\ ; + \\ add('ぁ', '\x03'); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ assert(a + b == 12356); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); } { -- 2.54.0 From e4aefc6d0f9b08a98f566cb8280a6195c08f7a82 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 18 Aug 2020 22:42:35 +0300 Subject: [PATCH 09/66] stage2: split ref from lvalue and add compile error for invalid assignments --- src-self-hosted/astgen.zig | 160 +++++++++++++++++++++++++++++++---- src-self-hosted/zir.zig | 10 +-- src-self-hosted/zir_sema.zig | 6 +- 3 files changed, 153 insertions(+), 23 deletions(-) diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index f05020f6df794e2a1232367d3221788ab3b4afe1..9d40c7899a5541ea5d3b119ca816439118fe5e78 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -20,6 +20,8 @@ pub const ResultLoc = union(enum) { /// The expression must generate a pointer rather than a value. For example, the left hand side /// of an assignment uses an "LValue" result location. lvalue, + /// The expression must generate a pointer + ref, /// The expression will be type coerced into this type, but it will be evaluated as an rvalue. ty: *zir.Inst, /// The expression must store its result into this typed pointer. @@ -46,6 +48,132 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z /// Turn Zig AST into untyped ZIR istructions. pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerError!*zir.Inst { + if (rl == .lvalue) { + switch (node.tag) { + .Root => unreachable, + .Use => unreachable, + .TestDecl => unreachable, + .DocComment => unreachable, + .VarDecl => unreachable, + .SwitchCase => unreachable, + .SwitchElse => unreachable, + .Else => unreachable, + .Payload => unreachable, + .PointerPayload => unreachable, + .PointerIndexPayload => unreachable, + .ErrorTag => unreachable, + .FieldInitializer => unreachable, + .ContainerField => unreachable, + + .Assign, + .AssignBitAnd, + .AssignBitOr, + .AssignBitShiftLeft, + .AssignBitShiftRight, + .AssignBitXor, + .AssignDiv, + .AssignSub, + .AssignSubWrap, + .AssignMod, + .AssignAdd, + .AssignAddWrap, + .AssignMul, + .AssignMulWrap, + .Add, + .AddWrap, + .Sub, + .SubWrap, + .Mul, + .MulWrap, + .Div, + .Mod, + .BitAnd, + .BitOr, + .BitShiftLeft, + .BitShiftRight, + .BitXor, + .BangEqual, + .EqualEqual, + .GreaterThan, + .GreaterOrEqual, + .LessThan, + .LessOrEqual, + .ArrayCat, + .ArrayMult, + .BoolAnd, + .BoolOr, + .Asm, + .StringLiteral, + .IntegerLiteral, + .Call, + .Unreachable, + .Return, + .If, + .While, + .BoolNot, + .AddressOf, + .FloatLiteral, + .UndefinedLiteral, + .BoolLiteral, + .NullLiteral, + .OptionalType, + .Block, + .LabeledBlock, + .Break, + .PtrType, + .GroupedExpression, + .ArrayType, + .ArrayTypeSentinel, + .EnumLiteral, + .MultilineStringLiteral, + .CharLiteral, + .Defer, + .Catch, + .ErrorUnion, + .MergeErrorSets, + .Range, + .OrElse, + .Await, + .BitNot, + .Negation, + .NegationWrap, + .Resume, + .Try, + .SliceType, + .Slice, + .ArrayInitializer, + .ArrayInitializerDot, + .StructInitializer, + .StructInitializerDot, + .Switch, + .For, + .Suspend, + .Continue, + .AnyType, + .ErrorType, + .FnProto, + .AnyFrameType, + .ErrorSetDecl, + .ContainerDecl, + .Comptime, + .Nosuspend, + => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}), + + // @field can be assigned to + .BuiltinCall => { + const call = node.castTag(.BuiltinCall).?; + const tree = scope.tree(); + const builtin_name = tree.tokenSlice(call.builtin_token); + + if (!mem.eql(u8, builtin_name, "@field")) { + return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}); + } + }, + + // can be assigned to + .UnwrapOptional, .Deref, .Period, .ArrayAccess, .Identifier => {}, + } + } switch (node.tag) { .Root => unreachable, // Top-level declaration. .Use => unreachable, // Top-level declaration. @@ -60,6 +188,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .PointerIndexPayload => unreachable, // Handled explicitly. .ErrorTag => unreachable, // Handled explicitly. .FieldInitializer => unreachable, // Handled explicitly. + .ContainerField => unreachable, // Handled explicitly. .Assign => return rlWrapVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)), .AssignBitAnd => return rlWrapVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bitand)), @@ -165,7 +294,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .ContainerDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerDecl", .{}), .Comptime => return mod.failNode(scope, node, "TODO implement astgen.expr for .Comptime", .{}), .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}), - .ContainerField => return mod.failNode(scope, node, "TODO implement astgen.expr for .ContainerField", .{}), } } @@ -188,7 +316,7 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpr // proper type inference requires peer type resolution on the block's // break operand expressions. const branch_rl: ResultLoc = switch (label.result_loc) { - .discard, .none, .ty, .ptr, .lvalue => label.result_loc, + .discard, .none, .ty, .ptr, .lvalue, .ref => label.result_loc, .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = label.block_inst }, }; const operand = try expr(mod, parent_scope, branch_rl, rhs); @@ -427,7 +555,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr } fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { - return expr(mod, scope, .lvalue, node.rhs); + return expr(mod, scope, .ref, node.rhs); } fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { @@ -541,9 +669,9 @@ fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Si const tree = scope.tree(); const src = tree.token_locs[node.rtoken].start; - const operand = try expr(mod, scope, .lvalue, node.lhs); + const operand = try expr(mod, scope, .ref, node.lhs); const unwrapped_ptr = try addZIRUnOp(mod, scope, src, .unwrap_optional_safe, operand); - if (rl == .lvalue) return unwrapped_ptr; + if (rl == .lvalue or rl == .ref) return unwrapped_ptr; return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .deref, unwrapped_ptr)); } @@ -718,13 +846,13 @@ const CondKind = union(enum) { return try expr(mod, &block_scope.base, .{ .ty = bool_type }, cond_node); }, .optional => { - const cond_ptr = try expr(mod, &block_scope.base, .lvalue, cond_node); + const cond_ptr = try expr(mod, &block_scope.base, .ref, cond_node); self.* = .{ .optional = cond_ptr }; const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, cond_ptr); return try addZIRUnOp(mod, &block_scope.base, src, .isnonnull, result); }, .err_union => { - const err_ptr = try expr(mod, &block_scope.base, .lvalue, cond_node); + const err_ptr = try expr(mod, &block_scope.base, .ref, cond_node); self.* = .{ .err_union = err_ptr }; const result = try addZIRUnOp(mod, &block_scope.base, src, .deref, err_ptr); return try addZIRUnOp(mod, &block_scope.base, src, .iserr, result); @@ -819,7 +947,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn // proper type inference requires peer type resolution on the if's // branches. const branch_rl: ResultLoc = switch (rl) { - .discard, .none, .ty, .ptr, .lvalue => rl, + .discard, .none, .ty, .ptr, .lvalue, .ref => rl, .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = block }, }; @@ -949,7 +1077,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W // proper type inference requires peer type resolution on the while's // branches. const branch_rl: ResultLoc = switch (rl) { - .discard, .none, .ty, .ptr, .lvalue => rl, + .discard, .none, .ty, .ptr, .lvalue, .ref => rl, .inferred_ptr, .bitcasted_ptr, .block_ptr => .{ .block_ptr = while_block }, }; @@ -1080,7 +1208,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo .local_ptr => { const local_ptr = s.cast(Scope.LocalPtr).?; if (mem.eql(u8, local_ptr.name, ident_name)) { - if (rl == .lvalue) { + if (rl == .lvalue or rl == .ref) { return local_ptr.ptr; } else { const result = try addZIRUnOp(mod, scope, src, .deref, local_ptr.ptr); @@ -1344,7 +1472,8 @@ fn as(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) I _ = try addZIRUnOp(mod, scope, result.src, .ensure_result_non_error, result); return result; }, - .lvalue => { + .lvalue => unreachable, + .ref => { const result = try expr(mod, scope, .{ .ty = dest_type }, params[1]); return addZIRUnOp(mod, scope, result.src, .ref, result); }, @@ -1395,9 +1524,10 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa _ = try addZIRUnOp(mod, scope, result.src, .ensure_result_non_error, result); return result; }, - .lvalue => { - const operand = try expr(mod, scope, .lvalue, params[1]); - const result = try addZIRBinOp(mod, scope, src, .bitcast_lvalue, dest_type, operand); + .lvalue => unreachable, + .ref => { + const operand = try expr(mod, scope, .ref, params[1]); + const result = try addZIRBinOp(mod, scope, src, .bitcast_ref, dest_type, operand); return result; }, .ty => |result_ty| { @@ -1662,7 +1792,7 @@ fn rlWrap(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr _ = try addZIRUnOp(mod, scope, result.src, .ensure_result_non_error, result); return result; }, - .lvalue => { + .lvalue, .ref => { // We need a pointer but we have a value. return addZIRUnOp(mod, scope, result.src, .ref, result); }, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 235a4c931bcf2471ca3008bdc138b6b9cbacb4d6..e8e21e53658705124c9f1a557ef441c597982a1f 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -62,11 +62,11 @@ pub const Inst = struct { bitand, /// TODO delete this instruction, it has no purpose. bitcast, - /// An arbitrary typed pointer, which is to be used as an L-Value, is pointer-casted - /// to a new L-Value. The destination type is given by LHS. The cast is to be evaluated + /// An arbitrary typed pointer is pointer-casted to a new Pointer. + /// The destination type is given by LHS. The cast is to be evaluated /// as if it were a bit-cast operation from the operand pointer element type to the /// provided destination type. - bitcast_lvalue, + bitcast_ref, /// A typed result location pointer is bitcasted to a new result location pointer. /// The new result location pointer has an inferred type. bitcast_result_ptr, @@ -258,7 +258,7 @@ pub const Inst = struct { .ensure_result_non_error, .bitcast_result_ptr, .ref, - .bitcast_lvalue, + .bitcast_ref, .typeof, .single_const_ptr_type, .single_mut_ptr_type, @@ -349,7 +349,7 @@ pub const Inst = struct { .@"asm", .bitand, .bitcast, - .bitcast_lvalue, + .bitcast_ref, .bitcast_result_ptr, .bitor, .block, diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 3a2a593539a87e19a1283fc3ba5a2687ba18995c..fb39a1e077c9ad7df6b205fbe4cf9446beefd403 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -29,7 +29,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?), .alloc_inferred => return analyzeInstAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred).?), .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?), - .bitcast_lvalue => return analyzeInstBitCastLValue(mod, scope, old_inst.castTag(.bitcast_lvalue).?), + .bitcast_ref => return analyzeInstBitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?), .bitcast_result_ptr => return analyzeInstBitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?), .block => return analyzeInstBlock(mod, scope, old_inst.castTag(.block).?), .@"break" => return analyzeInstBreak(mod, scope, old_inst.castTag(.@"break").?), @@ -299,8 +299,8 @@ fn analyzeInstCoerceResultBlockPtr( return mod.fail(scope, inst.base.src, "TODO implement analyzeInstCoerceResultBlockPtr", .{}); } -fn analyzeInstBitCastLValue(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { - return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitCastLValue", .{}); +fn analyzeInstBitCastRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { + return mod.fail(scope, inst.base.src, "TODO implement analyzeInstBitCastRef", .{}); } fn analyzeInstBitCastResultPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { -- 2.54.0 From e4b3da27203e0117ac29cceb03d7fe396f3931a7 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 18 Aug 2020 17:45:04 +0200 Subject: [PATCH 10/66] Write out Mach-O header This commit write out Mach-O header in the linker's `flush` method. The header currently only populates the magic number, filetype, and cpu info. Signed-off-by: Jakub Konka --- lib/std/macho.zig | 12 ++++++ src-self-hosted/link.zig | 1 - src-self-hosted/link/MachO.zig | 74 ++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/lib/std/macho.zig b/lib/std/macho.zig index a499a936754bde605141f56fd809278f01bd0264..950283b59f7b950c48c030485882a8781e328823 100644 --- a/lib/std/macho.zig +++ b/lib/std/macho.zig @@ -703,3 +703,15 @@ pub const cpu_type_t = integer_t; pub const cpu_subtype_t = integer_t; pub const integer_t = c_int; pub const vm_prot_t = c_int; + +/// CPU type targeting 64-bit Intel-based Macs +pub const CPU_TYPE_X86_64: cpu_type_t = 0x01000007; + +/// CPU type targeting 64-bit ARM-based Macs +pub const CPU_TYPE_ARM64: cpu_type_t = 0x0100000C; + +/// All Intel-based Macs +pub const CPU_SUBTYPE_X86_64_ALL: cpu_subtype_t = 0x3; + +/// All ARM-based Macs +pub const CPU_SUBTYPE_ARM_ALL: cpu_subtype_t = 0x0; diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index cbc376f7abc92c29da0e16fbcf15c7a8863fc667..506efa85cc8287a9b0cfe69528685d6870c2e4dc 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -40,7 +40,6 @@ pub const Options = struct { program_code_size_hint: u64 = 256 * 1024, }; - pub const File = struct { pub const LinkBlock = union { elf: Elf.TextBlock, diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index 49e365d203ef1a689bbcb9c3ab5967319ce9f7b5..e7b0a68c816e9afc577ee760e20ee44f637dd582 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -4,6 +4,8 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; const fs = std.fs; +const log = std.log; +const macho = std.macho; const Module = @import("../Module.zig"); const link = @import("../link.zig"); @@ -13,6 +15,8 @@ pub const base_tag: Tag = File.Tag.macho; base: File, +entry_addr: ?u64 = null, + error_flags: File.ErrorFlags = File.ErrorFlags{}, pub const TextBlock = struct { @@ -67,13 +71,77 @@ fn openFile(allocator: *Allocator, file: fs.File, options: link.Options) !MachO /// Returns an error if `file` is not already open with +read +write +seek abilities. fn createFile(allocator: *Allocator, file: fs.File, options: link.Options) !MachO { switch (options.output_mode) { - .Exe => return error.TODOImplementWritingMachOExeFiles, - .Obj => return error.TODOImplementWritingMachOObjFiles, + .Exe => {}, + .Obj => {}, .Lib => return error.TODOImplementWritingLibFiles, } + + var self: MachO = .{ + .base = .{ + .file = file, + .tag = .macho, + .options = options, + .allocator = allocator, + }, + }; + errdefer self.deinit(); + + return self; +} + +fn writeMachOHeader(self: *MachO) !void { + var hdr: macho.mach_header_64 = undefined; + hdr.magic = macho.MH_MAGIC_64; + + const CpuInfo = struct { + cpu_type: macho.cpu_type_t, + cpu_subtype: macho.cpu_subtype_t, + }; + + const cpu_info: CpuInfo = switch (self.base.options.target.cpu.arch) { + .aarch64 => .{ + .cpu_type = macho.CPU_TYPE_ARM64, + .cpu_subtype = macho.CPU_SUBTYPE_ARM_ALL, + }, + .x86_64 => .{ + .cpu_type = macho.CPU_TYPE_X86_64, + .cpu_subtype = macho.CPU_SUBTYPE_X86_64_ALL, + }, + else => return error.UnsupportedMachOArchitecture, + }; + hdr.cputype = cpu_info.cpu_type; + hdr.cpusubtype = cpu_info.cpu_subtype; + + const filetype: u32 = switch (self.base.options.output_mode) { + .Exe => macho.MH_EXECUTE, + .Obj => macho.MH_OBJECT, + .Lib => switch (self.base.options.link_mode) { + .Static => return error.TODOStaticLibMachOType, + .Dynamic => macho.MH_DYLIB, + }, + }; + hdr.filetype = filetype; + + // TODO the rest of the header + hdr.ncmds = 0; + hdr.sizeofcmds = 0; + hdr.flags = 0; + hdr.reserved = 0; + + try self.base.file.?.pwriteAll(@ptrCast([*]const u8, &hdr)[0..@sizeOf(macho.mach_header_64)], 0); } -pub fn flush(self: *MachO, module: *Module) !void {} +pub fn flush(self: *MachO, module: *Module) !void { + // TODO implement flush + if (self.entry_addr == null and self.base.options.output_mode == .Exe) { + log.debug(.link, "flushing. no_entry_point_found = true\n", .{}); + self.error_flags.no_entry_point_found = true; + } else { + log.debug(.link, "flushing. no_entry_point_found = false\n", .{}); + self.error_flags.no_entry_point_found = false; + try self.writeMachOHeader(); + } +} pub fn deinit(self: *MachO) void {} -- 2.54.0 From 34e628a0a0239eb7da4ee9c69dae62c16dd93a55 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 18 Aug 2020 22:37:25 +0200 Subject: [PATCH 11/66] Fix compile error Signed-off-by: Jakub Konka --- src-self-hosted/link/MachO.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index e7b0a68c816e9afc577ee760e20ee44f637dd582..e83b2314d815bfdf286109dc8ac3a688e520863c 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -134,10 +134,10 @@ fn writeMachOHeader(self: *MachO) !void { pub fn flush(self: *MachO, module: *Module) !void { // TODO implement flush if (self.entry_addr == null and self.base.options.output_mode == .Exe) { - log.debug(.link, "flushing. no_entry_point_found = true\n", .{}); + log.debug("flushing. no_entry_point_found = true\n", .{}); self.error_flags.no_entry_point_found = true; } else { - log.debug(.link, "flushing. no_entry_point_found = false\n", .{}); + log.debug("flushing. no_entry_point_found = false\n", .{}); self.error_flags.no_entry_point_found = false; try self.writeMachOHeader(); } -- 2.54.0 From 741fb8d30675f85316f7df100801e7cf8c2b3194 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 18 Aug 2020 10:54:54 +0200 Subject: [PATCH 12/66] stage2/link: clarify comments on calling order --- src-self-hosted/link.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index cbc376f7abc92c29da0e16fbcf15c7a8863fc667..2f786609b77882e6bb20ae48434ab881272d8ae5 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -110,6 +110,8 @@ pub const File = struct { } } + /// May be called before or after updateDeclExports but must be called + /// after allocateDeclIndexes for any given Decl. pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) !void { switch (base.tag) { .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl), @@ -127,6 +129,8 @@ pub const File = struct { } } + /// Must be called before any call to updateDecl or updateDeclExports for + /// any given Decl. pub fn allocateDeclIndexes(base: *File, decl: *Module.Decl) !void { switch (base.tag) { .elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl), @@ -200,7 +204,8 @@ pub const File = struct { }; } - /// Must be called only after a successful call to `updateDecl`. + /// May be called before or after updateDecl, but must be called after + /// allocateDeclIndexes for any given Decl. pub fn updateDeclExports( base: *File, module: *Module, -- 2.54.0 From fe3aa4ccd0bc157e1dd9d84b7c57b0cb2f0a77a9 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 18 Aug 2020 18:30:48 +0200 Subject: [PATCH 13/66] stage2/wasm: do incremental compilation in-memory Before this commit the wasm backend worked similarly to elf. As functions were generated they were written directly to the output file and existing code was shifted around in the file as necessary. This approach had several disadvantages: - Large amounts of padding in the output were necessary to avoid expensive copying of data within the file. - Function/type/global/etc indexes were required to be known at the time of preforming codegen, which severely limited the flexibility of where code could be placed in the binary - Significant complexity to track the state of the output file through incremental updates This commit takes things in a different direction. Code is incrementally compiled into in-memory buffers and the entire binary is rewritten using these buffers on flush. This has several advantages: - Significantly smaller resulting binaries - More performant resulting binaries due to lack of indirection - Significantly simpler compiler code - Indexes no longer need to be known before codegen. We can track where Decls must be referenced by index insert the proper indexes while writing the code in the flush() function. This is not yet implemented but is planned for the next commit. The main disadvantage is of course increased memory usage in order to store these buffers of generated code. --- src-self-hosted/link/Wasm.zig | 496 +++++++++------------------------- 1 file changed, 135 insertions(+), 361 deletions(-) diff --git a/src-self-hosted/link/Wasm.zig b/src-self-hosted/link/Wasm.zig index a381cfad57c3cd339ccf21a2fc501e4bbf372407..434c17372b5f6255d78bc1dfd8e289982a5849ed 100644 --- a/src-self-hosted/link/Wasm.zig +++ b/src-self-hosted/link/Wasm.zig @@ -32,19 +32,19 @@ const spec = struct { pub const base_tag = link.File.Tag.wasm; pub const FnData = struct { - funcidx: u32, + /// Generated code for the type of the function + functype: std.ArrayListUnmanaged(u8) = .{}, + /// Generated code for the body of the function + code: std.ArrayListUnmanaged(u8) = .{}, }; base: link.File, -types: Types, -funcs: Funcs, -exports: Exports, - -/// Array over the section structs used in the various sections above to -/// allow iteration when shifting sections to make space. -/// TODO: this should eventually be size 11 when we use all the sections. -sections: [4]*Section, +/// List of all function Decls to be written to the output file. The index of +/// each Decl in this list at the time of writing the binary is used as the +/// function index. +/// TODO: can/should we access some data structure in Module directly? +funcs: std.ArrayListUnmanaged(*Module.Decl) = .{}, pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: link.Options) !*link.File { assert(options.object_format == .wasm); @@ -58,10 +58,6 @@ pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, option try file.writeAll(&(spec.magic ++ spec.version)); - // TODO: this should vary depending on the section and be less arbitrary - const size = 1024; - const offset = @sizeOf(@TypeOf(spec.magic ++ spec.version)); - wasm.* = .{ .base = .{ .tag = .wasm, @@ -69,52 +65,40 @@ pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, option .file = file, .allocator = allocator, }, - - .types = try Types.init(file, offset, size), - .funcs = try Funcs.init(file, offset + size, size, offset + 3 * size, size), - .exports = try Exports.init(file, offset + 2 * size, size), - - // These must be ordered as they will appear in the output file - .sections = [_]*Section{ - &wasm.types.typesec.section, - &wasm.funcs.funcsec, - &wasm.exports.exportsec, - &wasm.funcs.codesec.section, - }, }; - try file.setEndPos(offset + 4 * size); - return &wasm.base; } pub fn deinit(self: *Wasm) void { - self.types.deinit(); - self.funcs.deinit(); + for (self.funcs.items) |decl| { + decl.fn_link.wasm.?.functype.deinit(self.base.allocator); + decl.fn_link.wasm.?.code.deinit(self.base.allocator); + } + self.funcs.deinit(self.base.allocator); } +// Generate code for the Decl, storing it in memory to be later written to +// the file on flush(). pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { if (decl.typed_value.most_recent.typed_value.ty.zigTypeTag() != .Fn) return error.TODOImplementNonFnDeclsForWasm; - if (decl.fn_link.wasm) |fn_data| { - self.funcs.free(fn_data.funcidx); + if (decl.fn_link.wasm) |*fn_data| { + fn_data.functype.items.len = 0; + fn_data.code.items.len = 0; + } else { + decl.fn_link.wasm = .{}; + try self.funcs.append(self.base.allocator, decl); } - - var buf = std.ArrayList(u8).init(self.base.allocator); - defer buf.deinit(); - - try codegen.genFunctype(&buf, decl); - const typeidx = try self.types.new(buf.items); - buf.items.len = 0; - - try codegen.genCode(&buf, decl); - const funcidx = try self.funcs.new(typeidx, buf.items); - - decl.fn_link.wasm = .{ .funcidx = funcidx }; - - // TODO: we should be more smart and set this only when needed - self.exports.dirty = true; + const fn_data = &decl.fn_link.wasm.?; + + var managed_functype = fn_data.functype.toManaged(self.base.allocator); + var managed_code = fn_data.code.toManaged(self.base.allocator); + try codegen.genFunctype(&managed_functype, decl); + try codegen.genCode(&managed_code, decl); + fn_data.functype = managed_functype.toUnmanaged(); + fn_data.code = managed_code.toUnmanaged(); } pub fn updateDeclExports( @@ -122,332 +106,122 @@ pub fn updateDeclExports( module: *Module, decl: *const Module.Decl, exports: []const *Module.Export, -) !void { - self.exports.dirty = true; -} +) !void {} pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { // TODO: remove this assert when non-function Decls are implemented assert(decl.typed_value.most_recent.typed_value.ty.zigTypeTag() == .Fn); - if (decl.fn_link.wasm) |fn_data| { - self.funcs.free(fn_data.funcidx); - decl.fn_link.wasm = null; - } + _ = self.funcs.swapRemove(self.getFuncidx(decl).?); + decl.fn_link.wasm.?.functype.deinit(self.base.allocator); + decl.fn_link.wasm.?.code.deinit(self.base.allocator); + decl.fn_link.wasm = null; } pub fn flush(self: *Wasm, module: *Module) !void { - if (self.exports.dirty) try self.exports.writeAll(module); -} - -/// This struct describes the location of a named section + custom section -/// padding in the output file. This is all the data we need to allow for -/// shifting sections around when padding runs out. -const Section = struct { - /// The size of a section header: 1 byte section id + 5 bytes - /// for the fixed-width ULEB128 encoded contents size. - const header_size = 1 + 5; - /// Offset of the section id byte from the start of the file. - offset: u64, - /// Size of the section, including the header and directly - /// following custom section used for padding if any. - size: u64, - - /// Resize the usable part of the section, handling the following custom - /// section used for padding. If there is not enough padding left, shift - /// all following sections to make space. Takes the current and target - /// contents sizes of the section as arguments. - fn resize(self: *Section, file: fs.File, current: u32, target: u32) !void { - // Section header + target contents size + custom section header - // + custom section name + empty custom section > owned chunk of the file - if (header_size + target + header_size + 1 + 0 > self.size) - return error.TODOImplementSectionShifting; - - const new_custom_start = self.offset + header_size + target; - const new_custom_contents_size = self.size - target - 2 * header_size; - assert(new_custom_contents_size >= 1); - // +1 for the name of the custom section, which we set to an empty string - var custom_header: [header_size + 1]u8 = undefined; - custom_header[0] = spec.custom_id; - leb.writeUnsignedFixed(5, custom_header[1..header_size], @intCast(u32, new_custom_contents_size)); - custom_header[header_size] = 0; - try file.pwriteAll(&custom_header, new_custom_start); - } -}; - -/// This can be used to manage the contents of any section which uses a vector -/// of contents. This interface maintains index stability while allowing for -/// reuse of "dead" indexes. -const VecSection = struct { - /// Represents a single entry in the vector (e.g. a type in the type section) - const Entry = struct { - /// Offset from the start of the section contents in bytes - offset: u32, - /// Size in bytes of the entry - size: u32, - }; - section: Section, - /// Size in bytes of the contents of the section. Does not include - /// the "header" containing the section id and this value. - contents_size: u32, - /// List of all entries in the contents of the section. - entries: std.ArrayListUnmanaged(Entry) = std.ArrayListUnmanaged(Entry){}, - /// List of indexes of unreferenced entries which may be - /// overwritten and reused. - dead_list: std.ArrayListUnmanaged(u32) = std.ArrayListUnmanaged(u32){}, - - /// Write the headers of the section and custom padding section - fn init(comptime section_id: u8, file: fs.File, offset: u64, initial_size: u64) !VecSection { - // section id, section size, empty vector, custom section id, - // custom section size, empty custom section name - var initial_data: [1 + 5 + 5 + 1 + 5 + 1]u8 = undefined; - - assert(initial_size >= initial_data.len); - - comptime var i = 0; - initial_data[i] = section_id; - i += 1; - leb.writeUnsignedFixed(5, initial_data[i..(i + 5)], 5); - i += 5; - leb.writeUnsignedFixed(5, initial_data[i..(i + 5)], 0); - i += 5; - initial_data[i] = spec.custom_id; - i += 1; - leb.writeUnsignedFixed(5, initial_data[i..(i + 5)], @intCast(u32, initial_size - @sizeOf(@TypeOf(initial_data)))); - i += 5; - initial_data[i] = 0; - - try file.pwriteAll(&initial_data, offset); - - return VecSection{ - .section = .{ - .offset = offset, - .size = initial_size, - }, - .contents_size = 5, - }; - } - - fn deinit(self: *VecSection, allocator: *Allocator) void { - self.entries.deinit(allocator); - self.dead_list.deinit(allocator); - } - - /// Write a new entry into the file, returning the index used. - fn addEntry(self: *VecSection, file: fs.File, allocator: *Allocator, data: []const u8) !u32 { - // First look for a dead entry we can reuse - for (self.dead_list.items) |dead_idx, i| { - const dead_entry = &self.entries.items[dead_idx]; - if (dead_entry.size == data.len) { - // Found a dead entry of the right length, overwrite it - try file.pwriteAll(data, self.section.offset + Section.header_size + dead_entry.offset); - _ = self.dead_list.swapRemove(i); - return dead_idx; - } - } - - // TODO: We can be more efficient if we special-case one or - // more consecutive dead entries at the end of the vector. - - // We failed to find a dead entry to reuse, so write the new - // entry to the end of the section. - try self.section.resize(file, self.contents_size, self.contents_size + @intCast(u32, data.len)); - try file.pwriteAll(data, self.section.offset + Section.header_size + self.contents_size); - try self.entries.append(allocator, .{ - .offset = self.contents_size, - .size = @intCast(u32, data.len), - }); - self.contents_size += @intCast(u32, data.len); - // Make sure the dead list always has enough space to store all free'd - // entries. This makes it so that delEntry() cannot fail. - // TODO: figure out a better way that doesn't waste as much memory - try self.dead_list.ensureCapacity(allocator, self.entries.items.len); - - // Update the size in the section header and the item count of - // the contents vector. - var size_and_count: [10]u8 = undefined; - leb.writeUnsignedFixed(5, size_and_count[0..5], self.contents_size); - leb.writeUnsignedFixed(5, size_and_count[5..], @intCast(u32, self.entries.items.len)); - try file.pwriteAll(&size_and_count, self.section.offset + 1); - - return @intCast(u32, self.entries.items.len - 1); - } - - /// Mark the type referenced by the given index as dead. - fn delEntry(self: *VecSection, index: u32) void { - self.dead_list.appendAssumeCapacity(index); - } -}; - -const Types = struct { - typesec: VecSection, - - fn init(file: fs.File, offset: u64, initial_size: u64) !Types { - return Types{ .typesec = try VecSection.init(spec.types_id, file, offset, initial_size) }; - } - - fn deinit(self: *Types) void { - const wasm = @fieldParentPtr(Wasm, "types", self); - self.typesec.deinit(wasm.base.allocator); - } - - fn new(self: *Types, data: []const u8) !u32 { - const wasm = @fieldParentPtr(Wasm, "types", self); - return self.typesec.addEntry(wasm.base.file.?, wasm.base.allocator, data); - } - - fn free(self: *Types, typeidx: u32) void { - self.typesec.delEntry(typeidx); - } -}; - -const Funcs = struct { - /// This section needs special handling to keep the indexes matching with - /// the codesec, so we cant just use a VecSection. - funcsec: Section, - /// The typeidx stored for each function, indexed by funcidx. - func_types: std.ArrayListUnmanaged(u32) = std.ArrayListUnmanaged(u32){}, - codesec: VecSection, - - fn init(file: fs.File, funcs_offset: u64, funcs_size: u64, code_offset: u64, code_size: u64) !Funcs { - return Funcs{ - .funcsec = (try VecSection.init(spec.funcs_id, file, funcs_offset, funcs_size)).section, - .codesec = try VecSection.init(spec.code_id, file, code_offset, code_size), - }; - } - - fn deinit(self: *Funcs) void { - const wasm = @fieldParentPtr(Wasm, "funcs", self); - self.func_types.deinit(wasm.base.allocator); - self.codesec.deinit(wasm.base.allocator); - } - - /// Add a new function to the binary, first finding space for and writing - /// the code then writing the typeidx to the corresponding index in the - /// funcsec. Returns the function index used. - fn new(self: *Funcs, typeidx: u32, code: []const u8) !u32 { - const wasm = @fieldParentPtr(Wasm, "funcs", self); - const file = wasm.base.file.?; - const allocator = wasm.base.allocator; - - assert(self.func_types.items.len == self.codesec.entries.items.len); - - // TODO: consider nop-padding the code if there is a close but not perfect fit - const funcidx = try self.codesec.addEntry(file, allocator, code); - - if (self.func_types.items.len < self.codesec.entries.items.len) { - // u32 vector length + funcs_count u32s in the vector - const current = 5 + @intCast(u32, self.func_types.items.len) * 5; - try self.funcsec.resize(file, current, current + 5); - try self.func_types.append(allocator, typeidx); - - // Update the size in the section header and the item count of - // the contents vector. - const count = @intCast(u32, self.func_types.items.len); - var size_and_count: [10]u8 = undefined; - leb.writeUnsignedFixed(5, size_and_count[0..5], 5 + count * 5); - leb.writeUnsignedFixed(5, size_and_count[5..], count); - try file.pwriteAll(&size_and_count, self.funcsec.offset + 1); - } else { - // We are overwriting a dead function and may now free the type - wasm.types.free(self.func_types.items[funcidx]); + const file = self.base.file.?; + const header_size = 5 + 1; + + // No need to rewrite the magic/version header + try file.setEndPos(@sizeOf(@TypeOf(spec.magic ++ spec.version))); + try file.seekTo(@sizeOf(@TypeOf(spec.magic ++ spec.version))); + + // Type section + { + const header_offset = try reserveVecSectionHeader(file); + for (self.funcs.items) |decl| { + try file.writeAll(decl.fn_link.wasm.?.functype.items); } - - assert(self.func_types.items.len == self.codesec.entries.items.len); - - var typeidx_leb: [5]u8 = undefined; - leb.writeUnsignedFixed(5, &typeidx_leb, typeidx); - try file.pwriteAll(&typeidx_leb, self.funcsec.offset + Section.header_size + 5 + funcidx * 5); - - return funcidx; - } - - fn free(self: *Funcs, funcidx: u32) void { - self.codesec.delEntry(funcidx); - } -}; - -/// Exports are tricky. We can't leave dead entries in the binary as they -/// would obviously be visible from the execution environment. The simplest -/// way to work around this is to re-emit the export section whenever -/// something changes. This also makes it easier to ensure exported function -/// and global indexes are updated as they change. -const Exports = struct { - exportsec: Section, - /// Size in bytes of the contents of the section. Does not include - /// the "header" containing the section id and this value. - contents_size: u32, - /// If this is true, then exports will be rewritten on flush() - dirty: bool, - - fn init(file: fs.File, offset: u64, initial_size: u64) !Exports { - return Exports{ - .exportsec = (try VecSection.init(spec.exports_id, file, offset, initial_size)).section, - .contents_size = 5, - .dirty = false, - }; - } - - fn writeAll(self: *Exports, module: *Module) !void { - const wasm = @fieldParentPtr(Wasm, "exports", self); - const file = wasm.base.file.?; - var buf: [5]u8 = undefined; - - // First ensure the section is the right size - var export_count: u32 = 0; - var new_contents_size: u32 = 5; + try writeVecSectionHeader( + file, + header_offset, + spec.types_id, + @intCast(u32, (try file.getPos()) - header_offset - header_size), + @intCast(u32, self.funcs.items.len), + ); + } + + // Function section + { + const header_offset = try reserveVecSectionHeader(file); + const writer = file.writer(); + for (self.funcs.items) |_, typeidx| try leb.writeULEB128(writer, @intCast(u32, typeidx)); + try writeVecSectionHeader( + file, + header_offset, + spec.funcs_id, + @intCast(u32, (try file.getPos()) - header_offset - header_size), + @intCast(u32, self.funcs.items.len), + ); + } + + // Export section + { + const header_offset = try reserveVecSectionHeader(file); + const writer = file.writer(); + var count: u32 = 0; for (module.decl_exports.entries.items) |entry| { - for (entry.value) |e| { - export_count += 1; - new_contents_size += calcSize(e); + for (entry.value) |exprt| { + // Export name length + name + try leb.writeULEB128(writer, @intCast(u32, exprt.options.name.len)); + try writer.writeAll(exprt.options.name); + + switch (exprt.exported_decl.typed_value.most_recent.typed_value.ty.zigTypeTag()) { + .Fn => { + // Type of the export + try writer.writeByte(0x00); + // Exported function index + try leb.writeULEB128(writer, self.getFuncidx(exprt.exported_decl).?); + }, + else => return error.TODOImplementNonFnDeclsForWasm, + } + + count += 1; } } - if (new_contents_size != self.contents_size) { - try self.exportsec.resize(file, self.contents_size, new_contents_size); - leb.writeUnsignedFixed(5, &buf, new_contents_size); - try file.pwriteAll(&buf, self.exportsec.offset + 1); - } - - try file.seekTo(self.exportsec.offset + Section.header_size); - const writer = file.writer(); - - // Length of the exports vec - leb.writeUnsignedFixed(5, &buf, export_count); - try writer.writeAll(&buf); - - for (module.decl_exports.entries.items) |entry| - for (entry.value) |e| try writeExport(writer, e); - - self.dirty = false; + try writeVecSectionHeader( + file, + header_offset, + spec.exports_id, + @intCast(u32, (try file.getPos()) - header_offset - header_size), + count, + ); } - /// Return the total number of bytes an export will take. - /// TODO: fixed-width LEB128 is currently used for simplicity, but should - /// be replaced with proper variable-length LEB128 as it is inefficient. - fn calcSize(e: *Module.Export) u32 { - // LEB128 name length + name bytes + export type + LEB128 index - return 5 + @intCast(u32, e.options.name.len) + 1 + 5; - } - - /// Write the data for a single export to the given file at a given offset. - /// TODO: fixed-width LEB128 is currently used for simplicity, but should - /// be replaced with proper variable-length LEB128 as it is inefficient. - fn writeExport(writer: anytype, e: *Module.Export) !void { - var buf: [5]u8 = undefined; - - // Export name length + name - leb.writeUnsignedFixed(5, &buf, @intCast(u32, e.options.name.len)); - try writer.writeAll(&buf); - try writer.writeAll(e.options.name); - - switch (e.exported_decl.typed_value.most_recent.typed_value.ty.zigTypeTag()) { - .Fn => { - // Type of the export - try writer.writeByte(0x00); - // Exported function index - leb.writeUnsignedFixed(5, &buf, e.exported_decl.fn_link.wasm.?.funcidx); - try writer.writeAll(&buf); - }, - else => return error.TODOImplementNonFnDeclsForWasm, - } + // Code section + { + const header_offset = try reserveVecSectionHeader(file); + for (self.funcs.items) |decl| try file.writeAll(decl.fn_link.wasm.?.code.items); + try writeVecSectionHeader( + file, + header_offset, + spec.code_id, + @intCast(u32, (try file.getPos()) - header_offset - header_size), + @intCast(u32, self.funcs.items.len), + ); } -}; +} + +/// Get the current index of a given Decl in the function list +/// TODO: we could maintain a hash map to potentially make this +fn getFuncidx(self: Wasm, decl: *Module.Decl) ?u32 { + return for (self.funcs.items) |func, idx| { + if (func == decl) break @intCast(u32, idx); + } else null; +} + +fn reserveVecSectionHeader(file: fs.File) !u64 { + // section id + fixed leb contents size + fixed leb vector length + const header_size = 1 + 5 + 5; + // TODO: this should be a single lseek(2) call, but fs.File does not + // currently provide a way to do this. + try file.seekBy(header_size); + return (try file.getPos()) - header_size; +} + +fn writeVecSectionHeader(file: fs.File, offset: u64, section: u8, size: u32, items: u32) !void { + var buf: [1 + 5 + 5]u8 = undefined; + buf[0] = section; + leb.writeUnsignedFixed(5, buf[1..6], size); + leb.writeUnsignedFixed(5, buf[6..], items); + try file.pwriteAll(&buf, offset); +} -- 2.54.0 From 6242ae35f37a6e67d9da514fa7a3508843515667 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Wed, 19 Aug 2020 01:48:09 +0200 Subject: [PATCH 14/66] stage2/wasm: implement function calls During codegen we do not yet know the indexes that will be used for called functions. Therefore, we store the offset into the in-memory code where the index is needed with a pointer to the Decl and use this data to insert the proper indexes while writing the binary in the flush function. --- src-self-hosted/codegen/wasm.zig | 96 ++++++++++++++++++++------------ src-self-hosted/link/Wasm.zig | 26 ++++++++- test/stage2/compare_output.zig | 27 ++++++++- 3 files changed, 110 insertions(+), 39 deletions(-) diff --git a/src-self-hosted/codegen/wasm.zig b/src-self-hosted/codegen/wasm.zig index 57eb002e822116b3b0dfb117d3819d24eb96ff5f..e55e9049346c989e2653e6ba108f43966520541c 100644 --- a/src-self-hosted/codegen/wasm.zig +++ b/src-self-hosted/codegen/wasm.zig @@ -62,58 +62,80 @@ pub fn genCode(buf: *ArrayList(u8), decl: *Decl) !void { // TODO: check for and handle death of instructions const tv = decl.typed_value.most_recent.typed_value; const mod_fn = tv.val.cast(Value.Payload.Function).?.func; - for (mod_fn.analysis.success.instructions) |inst| try genInst(writer, inst); + for (mod_fn.analysis.success.instructions) |inst| try genInst(buf, decl, inst); // Write 'end' opcode try writer.writeByte(0x0B); // Fill in the size of the generated code to the reserved space at the // beginning of the buffer. - leb.writeUnsignedFixed(5, buf.items[0..5], @intCast(u32, buf.items.len - 5)); + const size = buf.items.len - 5 + decl.fn_link.wasm.?.idx_refs.items.len * 5; + leb.writeUnsignedFixed(5, buf.items[0..5], @intCast(u32, size)); } -fn genInst(writer: ArrayList(u8).Writer, inst: *Inst) !void { +fn genInst(buf: *ArrayList(u8), decl: *Decl, inst: *Inst) !void { return switch (inst.tag) { + .call => genCall(buf, decl, inst.castTag(.call).?), + .constant => genConstant(buf, decl, inst.castTag(.constant).?), .dbg_stmt => {}, - .ret => genRet(writer, inst.castTag(.ret).?), + .ret => genRet(buf, decl, inst.castTag(.ret).?), + .retvoid => {}, else => error.TODOImplementMoreWasmCodegen, }; } -fn genRet(writer: ArrayList(u8).Writer, inst: *Inst.UnOp) !void { - switch (inst.operand.tag) { - .constant => { - const constant = inst.operand.castTag(.constant).?; - switch (inst.operand.ty.tag()) { - .u32 => { - try writer.writeByte(0x41); // i32.const - try leb.writeILEB128(writer, constant.val.toUnsignedInt()); - }, - .i32 => { - try writer.writeByte(0x41); // i32.const - try leb.writeILEB128(writer, constant.val.toSignedInt()); - }, - .u64 => { - try writer.writeByte(0x42); // i64.const - try leb.writeILEB128(writer, constant.val.toUnsignedInt()); - }, - .i64 => { - try writer.writeByte(0x42); // i64.const - try leb.writeILEB128(writer, constant.val.toSignedInt()); - }, - .f32 => { - try writer.writeByte(0x43); // f32.const - // TODO: enforce LE byte order - try writer.writeAll(mem.asBytes(&constant.val.toFloat(f32))); - }, - .f64 => { - try writer.writeByte(0x44); // f64.const - // TODO: enforce LE byte order - try writer.writeAll(mem.asBytes(&constant.val.toFloat(f64))); - }, - else => return error.TODOImplementMoreWasmCodegen, - } +fn genConstant(buf: *ArrayList(u8), decl: *Decl, inst: *Inst.Constant) !void { + const writer = buf.writer(); + switch (inst.base.ty.tag()) { + .u32 => { + try writer.writeByte(0x41); // i32.const + try leb.writeILEB128(writer, inst.val.toUnsignedInt()); }, + .i32 => { + try writer.writeByte(0x41); // i32.const + try leb.writeILEB128(writer, inst.val.toSignedInt()); + }, + .u64 => { + try writer.writeByte(0x42); // i64.const + try leb.writeILEB128(writer, inst.val.toUnsignedInt()); + }, + .i64 => { + try writer.writeByte(0x42); // i64.const + try leb.writeILEB128(writer, inst.val.toSignedInt()); + }, + .f32 => { + try writer.writeByte(0x43); // f32.const + // TODO: enforce LE byte order + try writer.writeAll(mem.asBytes(&inst.val.toFloat(f32))); + }, + .f64 => { + try writer.writeByte(0x44); // f64.const + // TODO: enforce LE byte order + try writer.writeAll(mem.asBytes(&inst.val.toFloat(f64))); + }, + .void => {}, else => return error.TODOImplementMoreWasmCodegen, } } + +fn genRet(buf: *ArrayList(u8), decl: *Decl, inst: *Inst.UnOp) !void { + try genInst(buf, decl, inst.operand); +} + +fn genCall(buf: *ArrayList(u8), decl: *Decl, inst: *Inst.Call) !void { + const func_inst = inst.func.castTag(.constant).?; + const func_val = func_inst.val.cast(Value.Payload.Function).?; + const target = func_val.func.owner_decl; + const target_ty = target.typed_value.most_recent.typed_value.ty; + + if (inst.args.len != 0) return error.TODOImplementMoreWasmCodegen; + + try buf.append(0x10); // call + + // The function index immediate argument will be filled in using this data + // in link.Wasm.flush(). + try decl.fn_link.wasm.?.idx_refs.append(buf.allocator, .{ + .offset = @intCast(u32, buf.items.len), + .decl = target, + }); +} diff --git a/src-self-hosted/link/Wasm.zig b/src-self-hosted/link/Wasm.zig index 434c17372b5f6255d78bc1dfd8e289982a5849ed..d8f172f584f26446c28ed0ede3e1874cabf8ca42 100644 --- a/src-self-hosted/link/Wasm.zig +++ b/src-self-hosted/link/Wasm.zig @@ -36,6 +36,9 @@ pub const FnData = struct { functype: std.ArrayListUnmanaged(u8) = .{}, /// Generated code for the body of the function code: std.ArrayListUnmanaged(u8) = .{}, + /// Locations in the generated code where function indexes must be filled in. + /// This must be kept ordered by offset. + idx_refs: std.ArrayListUnmanaged(struct { offset: u32, decl: *Module.Decl }) = .{}, }; base: link.File, @@ -74,6 +77,7 @@ pub fn deinit(self: *Wasm) void { for (self.funcs.items) |decl| { decl.fn_link.wasm.?.functype.deinit(self.base.allocator); decl.fn_link.wasm.?.code.deinit(self.base.allocator); + decl.fn_link.wasm.?.idx_refs.deinit(self.base.allocator); } self.funcs.deinit(self.base.allocator); } @@ -87,6 +91,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { if (decl.fn_link.wasm) |*fn_data| { fn_data.functype.items.len = 0; fn_data.code.items.len = 0; + fn_data.idx_refs.items.len = 0; } else { decl.fn_link.wasm = .{}; try self.funcs.append(self.base.allocator, decl); @@ -114,6 +119,7 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { _ = self.funcs.swapRemove(self.getFuncidx(decl).?); decl.fn_link.wasm.?.functype.deinit(self.base.allocator); decl.fn_link.wasm.?.code.deinit(self.base.allocator); + decl.fn_link.wasm.?.idx_refs.deinit(self.base.allocator); decl.fn_link.wasm = null; } @@ -190,7 +196,25 @@ pub fn flush(self: *Wasm, module: *Module) !void { // Code section { const header_offset = try reserveVecSectionHeader(file); - for (self.funcs.items) |decl| try file.writeAll(decl.fn_link.wasm.?.code.items); + const writer = file.writer(); + for (self.funcs.items) |decl| { + const fn_data = &decl.fn_link.wasm.?; + + // Write the already generated code to the file, inserting + // function indexes where required. + var current: u32 = 0; + for (fn_data.idx_refs.items) |idx_ref| { + try writer.writeAll(fn_data.code.items[current..idx_ref.offset]); + current = idx_ref.offset; + // Use a fixed width here to make calculating the code size + // in codegen.wasm.genCode() simpler. + var buf: [5]u8 = undefined; + leb.writeUnsignedFixed(5, &buf, self.getFuncidx(idx_ref.decl).?); + try writer.writeAll(&buf); + } + + try writer.writeAll(fn_data.code.items[current..]); + } try writeVecSectionHeader( file, header_offset, diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 4208cc3911ddec346a5fd06077d78a034a908b89..34e8f5e159902ee65ec413cad5339039b3b4b28a 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -546,28 +546,53 @@ pub fn addCases(ctx: *TestContext) !void { } { - var case = ctx.exe("wasm returns", wasi); + var case = ctx.exe("wasm function calls", wasi); case.addCompareOutput( \\export fn _start() u32 { + \\ foo(); + \\ bar(); \\ return 42; \\} + \\fn foo() void { + \\ bar(); + \\ bar(); + \\} + \\fn bar() void {} , "42\n", ); case.addCompareOutput( \\export fn _start() i64 { + \\ bar(); + \\ foo(); + \\ foo(); + \\ bar(); + \\ foo(); + \\ bar(); \\ return 42; \\} + \\fn foo() void { + \\ bar(); + \\} + \\fn bar() void {} , "42\n", ); case.addCompareOutput( \\export fn _start() f32 { + \\ bar(); + \\ foo(); \\ return 42.0; \\} + \\fn foo() void { + \\ bar(); + \\ bar(); + \\ bar(); + \\} + \\fn bar() void {} , // This is what you get when you take the bits of the IEE-754 // representation of 42.0 and reinterpret them as an unsigned -- 2.54.0 From 4237f1afc7f38f68adf0877fc9be811f9189544f Mon Sep 17 00:00:00 2001 From: Nathan Michaels Date: Tue, 18 Aug 2020 22:47:38 -0400 Subject: [PATCH 15/66] Change std.debug.warn to std.log.info in init-exe template. (#5941) --- lib/std/special/init-exe/src/main.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/special/init-exe/src/main.zig b/lib/std/special/init-exe/src/main.zig index c6a70af56d66687007bca367c89e7ced94666077..d29869ff88feb94cd5a5fd28d760824920f269ac 100644 --- a/lib/std/special/init-exe/src/main.zig +++ b/lib/std/special/init-exe/src/main.zig @@ -1,5 +1,5 @@ const std = @import("std"); pub fn main() anyerror!void { - std.debug.warn("All your codebase are belong to us.\n", .{}); + std.log.info("All your codebase are belong to us.", .{}); } -- 2.54.0 From ffdeb6af9171ccf9cb816a142a93991477d9a4ea Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 19 Aug 2020 07:43:33 +0200 Subject: [PATCH 16/66] Update src-self-hosted/link/MachO.zig Co-authored-by: Andrew Kelley --- src-self-hosted/link/MachO.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index e83b2314d815bfdf286109dc8ac3a688e520863c..e2a84d8ceb84630fd1cf250d0f47d2c0dbf2fae1 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -4,7 +4,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; const fs = std.fs; -const log = std.log; +const log = std.log.scoped(.link); const macho = std.macho; const Module = @import("../Module.zig"); -- 2.54.0 From dc35b8641badf3169a3124e84b672c3bf4bfd5f8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 18 Aug 2020 20:10:27 -0700 Subject: [PATCH 17/66] stage2: Module enumerates the possible top level decls --- src-self-hosted/Module.zig | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 3c31c7da44bf2ea3e13f3df03ed647acd6c3f788..e5988dfd8a06882282efc0f59748f7790f6fc5c0 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -1583,11 +1583,19 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void { } } } + } else if (src_decl.castTag(.VarDecl)) |var_decl| { + log.err("TODO: analyze var decl", .{}); + } else if (src_decl.castTag(.Comptime)) |comptime_node| { + log.err("TODO: analyze comptime decl", .{}); + } else if (src_decl.castTag(.ContainerField)) |container_field| { + log.err("TODO: analyze container field", .{}); + } else if (src_decl.castTag(.TestDecl)) |test_decl| { + log.err("TODO: analyze test decl", .{}); + } else if (src_decl.castTag(.Use)) |use_decl| { + log.err("TODO: analyze usingnamespace decl", .{}); } else { - std.debug.panic("TODO: analyzeRootSrcFile {}", .{src_decl.tag}); + unreachable; } - // TODO also look for global variable declarations - // TODO also look for comptime blocks and exported globals } // Handle explicitly deleted decls from the source code. Not to be confused // with when we delete decls because they are no longer referenced. -- 2.54.0 From 083c0f1cebc763e4e43529b50f6df9839c32c1c7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 18 Aug 2020 23:11:19 -0700 Subject: [PATCH 18/66] stage2 codegen: proper abstraction for re-using dying operands closes #6064 --- src-self-hosted/codegen.zig | 17 ++++++++++---- src-self-hosted/ir.zig | 5 ++++ test/stage2/compare_output.zig | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index 8887a1e0ca883356cd348379afe9989cea992f13..cb404d8315f5a4ef0b4bb3fc4d2dffe5199bc545 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -858,6 +858,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } + fn reuseOperand(inst: *ir.Inst, op_index: ir.Inst.DeathsBitIndex, mcv: MCValue) bool { + if (!inst.operandDies(op_index) or !mcv.isMutable()) + return false; + + // OK we're going to do it, but we need to clear the operand death bit so that + // it stays allocated. + inst.clearOperandDeath(op_index); + return true; + } + fn genLoad(self: *Self, inst: *ir.Inst.UnOp) !MCValue { const elem_ty = inst.base.ty; if (!elem_ty.hasCodeGenBits()) @@ -867,9 +877,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { if (inst.base.isUnused() and !is_volatile) return MCValue.dead; const dst_mcv: MCValue = blk: { - if (inst.base.operandDies(0) and ptr.isMutable()) { + if (reuseOperand(&inst.base, 0, ptr)) { // The MCValue that holds the pointer can be re-used as the value. - // TODO track this in the register/stack allocation metadata. break :blk ptr; } else { break :blk try self.allocRegOrMem(&inst.base); @@ -966,7 +975,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { var dst_mcv: MCValue = undefined; var src_mcv: MCValue = undefined; var src_inst: *ir.Inst = undefined; - if (inst.operandDies(0) and lhs.isMutable()) { + if (reuseOperand(inst, 0, lhs)) { // LHS dies; use it as the destination. // Both operands cannot be memory. src_inst = op_rhs; @@ -977,7 +986,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { dst_mcv = lhs; src_mcv = rhs; } - } else if (inst.operandDies(1) and rhs.isMutable()) { + } else if (reuseOperand(inst, 1, rhs)) { // RHS dies; use it as the destination. // Both operands cannot be memory. src_inst = op_lhs; diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig index 91dfad45d79d8e8ae5053aac2b02b8d0987539b0..070f41eb5e45c196670fef2c3d67fe8fe301b3ab 100644 --- a/src-self-hosted/ir.zig +++ b/src-self-hosted/ir.zig @@ -42,6 +42,11 @@ pub const Inst = struct { return @truncate(u1, self.deaths >> index) != 0; } + pub fn clearOperandDeath(self: *Inst, index: DeathsBitIndex) void { + assert(index < deaths_bits); + self.deaths &= ~(@as(DeathsInt, 1) << index); + } + pub fn specialOperandDeaths(self: Inst) bool { return (self.deaths & (1 << deaths_bits)) != 0; } diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index ec9d1b9f9e4b9b53e7a5e6e36823c47effbebf4d..3513605602c94b5ea41fc7d93dcd4bcca848cfe3 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -544,6 +544,48 @@ pub fn addCases(ctx: *TestContext) !void { "", ); + // This catches a possible bug in the logic for re-using dying operands. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ assert(add(3, 4) == 116); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) u32 { + \\ const x: u32 = blk: { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ const f = d + e; // 24 + \\ const g = e + f; // 38 + \\ const h = f + g; // 62 + \\ const i = g + h; // 100 + \\ const j = i + d; // 110 + \\ break :blk j; + \\ }; + \\ const y = x + a; // 113 + \\ const z = y + a; // 116 + \\ return z; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + case.addCompareOutput( \\export fn _start() noreturn { \\ const ignore = -- 2.54.0 From a237283d90ea6799331a7268f474511f352a23d7 Mon Sep 17 00:00:00 2001 From: dbandstra Date: Wed, 19 Aug 2020 13:10:05 -0700 Subject: [PATCH 19/66] fixes and improvements for parseCharLiteral --- lib/std/zig.zig | 66 +++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 36dfe740865875747b0960a9025af1ef26c84418..ab6895e1bf73679ad9bd186e3a58b97af2e2301e 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -84,7 +84,7 @@ pub fn binNameAlloc( /// Slice must be valid utf8 starting and ending with "'" and exactly one codepoint in between. pub fn parseCharLiteral( slice: []const u8, - bad_index: *usize, // populated if error.InvalidCharacter is returned) + bad_index: *usize, // populated if error.InvalidCharacter is returned ) error{InvalidCharacter}!u32 { std.debug.assert(slice.len >= 3 and slice[0] == '\'' and slice[slice.len - 1] == '\''); @@ -101,24 +101,23 @@ pub fn parseCharLiteral( bad_index.* = slice.len - 2; return error.InvalidCharacter; } - var value: u32 = 0; for (slice[3..5]) |c, i| { - switch (slice[3]) { + switch (c) { '0'...'9' => { value *= 16; value += c - '0'; }, 'a'...'f' => { value *= 16; - value += c - 'a'; + value += c - 'a' + 10; }, 'A'...'F' => { value *= 16; - value += c - 'a'; + value += c - 'A' + 10; }, else => { - bad_index.* = i; + bad_index.* = 3 + i; return error.InvalidCharacter; }, } @@ -126,42 +125,41 @@ pub fn parseCharLiteral( return value; }, 'u' => { - if (slice.len < 6 or slice[3] != '{') { + if (slice.len < "'\\u{0}'".len or slice[3] != '{' or slice[slice.len - 2] != '}') { bad_index.* = 2; return error.InvalidCharacter; } var value: u32 = 0; - for (slice[4..]) |c, i| { + for (slice[4 .. slice.len - 2]) |c, i| { + switch (c) { + '0'...'9' => { + value *= 16; + value += c - '0'; + }, + 'a'...'f' => { + value *= 16; + value += c - 'a' + 10; + }, + 'A'...'F' => { + value *= 16; + value += c - 'A' + 10; + }, + else => { + bad_index.* = 4 + i; + return error.InvalidCharacter; + }, + } if (value > 0x10ffff) { - bad_index.* = i; + bad_index.* = 4 + i; return error.InvalidCharacter; } - switch (c) { - '0'...'9' => { - value *= 16; - value += c - '0'; - }, - 'a'...'f' => { - value *= 16; - value += c - 'a'; - }, - 'A'...'F' => { - value *= 16; - value += c - 'A'; - }, - '}' => break, - else => { - bad_index.* = i; - return error.InvalidCharacter; - }, - } } return value; }, else => { bad_index.* = 2; return error.InvalidCharacter; - } + }, } } return std.unicode.utf8Decode(slice[1 .. slice.len - 1]) catch unreachable; @@ -172,13 +170,23 @@ test "parseCharLiteral" { std.testing.expectEqual(try parseCharLiteral("'a'", &bad_index), 'a'); std.testing.expectEqual(try parseCharLiteral("'ä'", &bad_index), 'ä'); std.testing.expectEqual(try parseCharLiteral("'\\x00'", &bad_index), 0); + std.testing.expectEqual(try parseCharLiteral("'\\x4f'", &bad_index), 0x4f); + std.testing.expectEqual(try parseCharLiteral("'\\x4F'", &bad_index), 0x4f); std.testing.expectEqual(try parseCharLiteral("'ぁ'", &bad_index), 0x3041); + std.testing.expectEqual(try parseCharLiteral("'\\u{0}'", &bad_index), 0); std.testing.expectEqual(try parseCharLiteral("'\\u{3041}'", &bad_index), 0x3041); + std.testing.expectEqual(try parseCharLiteral("'\\u{7f}'", &bad_index), 0x7f); + std.testing.expectEqual(try parseCharLiteral("'\\u{7FFF}'", &bad_index), 0x7FFF); std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x0'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\x000'", &bad_index)); std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\y'", &bad_index)); std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\uFFFF'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{}'", &bad_index)); std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFFFF}'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF'", &bad_index)); + std.testing.expectError(error.InvalidCharacter, parseCharLiteral("'\\u{FFFF}x'", &bad_index)); } test "" { -- 2.54.0 From 0f677810ea9d5c8ba549f6c9948979a768a1eda6 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 19 Aug 2020 13:49:20 -0600 Subject: [PATCH 20/66] Remove offset field from TypeInfo.StructField This isn't needed with @bitOffsetOf/@byteoffsetOf and complicates @Type handling. --- lib/std/builtin.zig | 1 - src/ir.cpp | 31 +++++++----------------------- test/stage1/behavior/type_info.zig | 11 ----------- 3 files changed, 7 insertions(+), 36 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 49edab1fd738a3b979fe18a1e918ef78f0ad67c8..6b3acd799d2643859666a0d2a0ac911e074928b6 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -254,7 +254,6 @@ pub const TypeInfo = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const StructField = struct { name: []const u8, - offset: ?comptime_int, field_type: type, default_value: anytype, }; diff --git a/src/ir.cpp b/src/ir.cpp index 3625869217226b408417b04d74a80352b0c276d5..d0a23786af375d7c175a5453921a4928fc4f3b2a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25678,37 +25678,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy struct_field_val->type = type_info_struct_field_type; ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4); + inner_fields[1]->special = ConstValSpecialStatic; - inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); - - ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); - if (field_type == nullptr) - return ErrorSemanticAnalyzeFail; - if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) - return err; - if (!type_has_bits(ira->codegen, struct_field->type_entry)) { - inner_fields[1]->data.x_optional = nullptr; - } else { - size_t byte_offset = struct_field->offset; - inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create(); - inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; - inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); - } - - inner_fields[2]->special = ConstValSpecialStatic; - inner_fields[2]->type = ira->codegen->builtin_types.entry_type; - inner_fields[2]->data.x_type = struct_field->type_entry; + inner_fields[1]->type = ira->codegen->builtin_types.entry_type; + inner_fields[1]->data.x_type = struct_field->type_entry; // default_value: anytype - inner_fields[3]->special = ConstValSpecialStatic; - inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry); - if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail; + inner_fields[2]->special = ConstValSpecialStatic; + inner_fields[2]->type = get_optional_type2(ira->codegen, struct_field->type_entry); + if (inner_fields[2]->type == nullptr) return ErrorSemanticAnalyzeFail; memoize_field_init_val(ira->codegen, type_entry, struct_field); if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){ return ErrorSemanticAnalyzeFail; } - set_optional_payload(inner_fields[3], struct_field->init_val); + set_optional_payload(inner_fields[2], struct_field->init_val); ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index a79b3a1554efa2fa2d5f55938cf06241f7d7363a..ab26558c0413f512f91425f15d43eee1b552165e 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -238,7 +238,6 @@ fn testStruct() void { expect(struct_info == .Struct); expect(struct_info.Struct.layout == .Packed); expect(struct_info.Struct.fields.len == 4); - expect(struct_info.Struct.fields[1].offset == null); expect(struct_info.Struct.fields[2].field_type == *TestStruct); expect(struct_info.Struct.fields[2].default_value == null); expect(struct_info.Struct.fields[3].default_value.? == 4); @@ -320,16 +319,6 @@ fn testAnyFrame() void { } } -test "type info: optional field unwrapping" { - const Struct = struct { - cdOffset: u32, - }; - - const field = @typeInfo(Struct).Struct.fields[0]; - - _ = field.offset orelse 0; -} - test "type info: pass to function" { _ = passTypeInfo(@typeInfo(void)); _ = comptime passTypeInfo(@typeInfo(void)); -- 2.54.0 From b46d764fd958d31a988d58a6ee0b7da4c0b20acb Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 19 Aug 2020 13:46:26 -0600 Subject: [PATCH 21/66] Implement @Type for structs without decls support --- src/all_types.hpp | 1 + src/analyze.cpp | 10 +-- src/analyze.hpp | 1 + src/ir.cpp | 139 +++++++++++++++++++++++++++------- test/stage1/behavior/type.zig | 44 +++++++++++ 5 files changed, 164 insertions(+), 31 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 5f142e3dcb75c287c1e29a29f7d3078372f3b1c9..422d530031a9aa8305383f8305f8ec4791483a0b 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1420,6 +1420,7 @@ struct ZigTypeStruct { bool requires_comptime; bool resolve_loop_flag_zero_bits; bool resolve_loop_flag_other; + bool created_by_at_type; }; struct ZigTypeOptional { diff --git a/src/analyze.cpp b/src/analyze.cpp index 49205714384ebc9d3532f3eed1887fbefb6328fa..7b71d7166b4a447eaabcf3e7c6a8305c6028ec63 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -138,7 +138,7 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope dest->parent = parent; } -static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, +ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ZigType *import, Buf *bare_name) { ScopeDecls *scope = heap::c_allocator.create(); @@ -2821,7 +2821,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { src_assert(struct_type->data.structure.fields == nullptr, decl_node); struct_type->data.structure.fields = alloc_type_struct_fields(field_count); - } else if (is_anon_container(struct_type)) { + } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) { field_count = struct_type->data.structure.src_field_count; src_assert(field_count == 0 || struct_type->data.structure.fields != nullptr, decl_node); @@ -2856,7 +2856,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; } - } else if (is_anon_container(struct_type)) { + } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) { field_node = type_struct_field->decl_node; src_assert(type_struct_field->type_entry != nullptr, field_node); @@ -2883,7 +2883,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { type_struct_field->type_val = field_type_val; if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) return ErrorSemanticAnalyzeFail; - } else if (is_anon_container(struct_type)) { + } else if (is_anon_container(struct_type) || struct_type->data.structure.created_by_at_type) { field_type_val = type_struct_field->type_val; } else zig_unreachable(); @@ -8331,7 +8331,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS ZigLLVMDIFile *di_file; ZigLLVMDIScope *di_scope; unsigned line; - if (decl_node != nullptr) { + if (decl_node != nullptr && !struct_type->data.structure.created_by_at_type) { Scope *scope = &struct_type->data.structure.decls_scope->base; ZigType *import = get_scope_import(scope); di_file = import->data.structure.root_struct->di_file; diff --git a/src/analyze.hpp b/src/analyze.hpp index cb58aa6b7411f423ae45da988a483cce5be002ac..0df1a4ba91e1eb37d057ffdf24beab123a08bba8 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -116,6 +116,7 @@ void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val); +ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ZigType *import, Buf *bare_name); ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent); ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent); ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent); diff --git a/src/ir.cpp b/src/ir.cpp index d0a23786af375d7c175a5453921a4928fc4f3b2a..b2cbe89d122b5b97264c8ba6e7ebe435b5d879bc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25942,6 +25942,36 @@ static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *sour return value->data.x_optional->data.x_type; } +static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, + const char *name, size_t field_index, Buf *out) +{ + ZigValue *slice = get_const_field(ira, source_node, struct_value, name, field_index); + ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; + ZigValue *len = slice->data.x_struct.fields[slice_len_index]; + assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); + assert(ptr->data.x_ptr.data.base_array.elem_index == 0); + ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; + assert(arr->special == ConstValSpecialStatic); + switch (arr->data.x_array.special) { + case ConstArraySpecialUndef: + return ErrorSemanticAnalyzeFail; + case ConstArraySpecialNone: { + buf_resize(out, 0); + size_t count = bigint_as_usize(&len->data.x_bigint); + for (size_t j = 0; j < count; j++) { + ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j]; + unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); + buf_append_char(out, ch); + } + break; + } + case ConstArraySpecialBuf: + buf_init_from_buf(out, arr->data.x_array.data.s_buf); + break; + } + return ErrorNone; +} + static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { Error err; switch (tagTypeId) { @@ -26145,30 +26175,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI assert(error->type == ir_type_info_get_type(ira, "Error", nullptr)); ErrorTableEntry *err_entry = heap::c_allocator.create(); err_entry->decl_node = source_instr->source_node; - ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0); - ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index]; - ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index]; - assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); - assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0); - ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val; - assert(name_arr->special == ConstValSpecialStatic); - switch (name_arr->data.x_array.special) { - case ConstArraySpecialUndef: - return ira->codegen->invalid_inst_gen->value->type; - case ConstArraySpecialNone: { - buf_resize(&err_entry->name, 0); - size_t name_count = bigint_as_usize(&name_len->data.x_bigint); - for (size_t j = 0; j < name_count; j++) { - ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j]; - unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); - buf_append_char(&err_entry->name, ch); - } - break; - } - case ConstArraySpecialBuf: - buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf); - break; - } + Error err; + if ((err = get_const_field_buf(ira, source_instr->source_node, error, "name", 0, &err_entry->name))) + return ira->codegen->invalid_inst_gen->value->type; auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry); if (existing_entry) { err_entry->value = existing_entry->value->value; @@ -26188,14 +26197,92 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI } return err_set_type; } + case ZigTypeIdStruct: { + assert(payload->special == ConstValSpecialStatic); + assert(payload->type == ir_type_info_get_type(ira, "Struct", nullptr)); + + ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0); + assert(layout_value->special == ConstValSpecialStatic); + assert(layout_value->type->id == ZigTypeIdEnum); + ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag); + + ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 1); + assert(fields_value->special == ConstValSpecialStatic); + assert(is_slice(fields_value->type)); + ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index]; + ZigValue *fields_len_value = fields_value->data.x_struct.fields[slice_len_index]; + size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint); + + ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 2); + assert(decls_value->special == ConstValSpecialStatic); + assert(is_slice(decls_value->type)); + ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; + size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); + if (decls_len != 0) { + ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type")); + return ira->codegen->invalid_inst_gen->value->type; + } + + bool is_tuple; + get_const_field_bool(ira, source_instr->source_node, payload, "is_tuple", 3, &is_tuple); + + ZigType *entry = new_type_table_entry(ZigTypeIdStruct); + buf_init_from_buf(&entry->name, + get_anon_type_name(ira->codegen, ira->old_irb.exec, "struct", source_instr->scope, source_instr->source_node, &entry->name)); + entry->data.structure.decl_node = source_instr->source_node; + entry->data.structure.fields = alloc_type_struct_fields(fields_len); + entry->data.structure.fields_by_name.init(fields_len); + entry->data.structure.src_field_count = fields_len; + entry->data.structure.layout = layout; + entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone; + entry->data.structure.created_by_at_type = true; + entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, buf_create_from_str("a")); + + assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); + assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0); + ZigValue *fields_arr = fields_ptr->data.x_ptr.data.base_array.array_val; + assert(fields_arr->special == ConstValSpecialStatic); + assert(fields_arr->data.x_array.special == ConstArraySpecialNone); + for (size_t i = 0; i < fields_len; i++) { + ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i]; + assert(field_value->type->id == ZigTypeIdStruct); + TypeStructField *field = entry->data.structure.fields[i]; + field->name = buf_alloc(); + if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name))) + return ira->codegen->invalid_inst_gen->value->type; + field->decl_node = source_instr->source_node; + ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1); + field->type_val = type_value; + field->type_entry = type_value->data.x_type; + if (entry->data.structure.fields_by_name.put_unique(field->name, field) != nullptr) { + ir_add_error(ira, source_instr, buf_sprintf("duplicate struct field '%s'", buf_ptr(field->name))); + return ira->codegen->invalid_inst_gen->value->type; + } + ZigValue *default_value = get_const_field(ira, source_instr->source_node, field_value, "default_value", 2); + if (default_value->type->id == ZigTypeIdNull) { + field->init_val = nullptr; + } else if (default_value->type->id == ZigTypeIdOptional && default_value->type->data.maybe.child_type == field->type_entry) { + field->init_val = default_value->data.x_optional; + } else if (default_value->type == field->type_entry) { + field->init_val = default_value; + } else { + ir_add_error(ira, source_instr, + buf_sprintf("default_value of field '%s' is of type '%s', expected '%s' or '?%s'", + buf_ptr(field->name), buf_ptr(&default_value->type->name), + buf_ptr(&field->type_entry->name), buf_ptr(&field->type_entry->name))); + return ira->codegen->invalid_inst_gen->value->type; + } + } + + return entry; + } case ZigTypeIdEnum: + case ZigTypeIdUnion: ir_add_error(ira, source_instr, buf_sprintf( "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); return ira->codegen->invalid_inst_gen->value->type; - case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: - case ZigTypeIdStruct: ir_add_error(ira, source_instr, buf_sprintf( "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); return ira->codegen->invalid_inst_gen->value->type; diff --git a/test/stage1/behavior/type.zig b/test/stage1/behavior/type.zig index f21e9f1ce994e1ebff58c4be3ac200897d02d26e..8ebf670279cda792f78000d0652ee86f82b7fa32 100644 --- a/test/stage1/behavior/type.zig +++ b/test/stage1/behavior/type.zig @@ -236,3 +236,47 @@ test "Type.ErrorSet" { _ = @Type(@typeInfo(error{A})); _ = @Type(@typeInfo(error{ A, B, C })); } + +test "Type.Struct" { + const A = @Type(@typeInfo(struct { x: u8, y: u32 })); + const infoA = @typeInfo(A).Struct; + testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout); + testing.expectEqualSlices(u8, "x", infoA.fields[0].name); + testing.expectEqual(u8, infoA.fields[0].field_type); + testing.expectEqual(@as(?u8, null), infoA.fields[0].default_value); + testing.expectEqualSlices(u8, "y", infoA.fields[1].name); + testing.expectEqual(u32, infoA.fields[1].field_type); + testing.expectEqual(@as(?u32, null), infoA.fields[1].default_value); + testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls); + testing.expectEqual(@as(bool, false), infoA.is_tuple); + + var a = A{ .x = 0, .y = 1 }; + testing.expectEqual(@as(u8, 0), a.x); + testing.expectEqual(@as(u32, 1), a.y); + a.y += 1; + testing.expectEqual(@as(u32, 2), a.y); + + const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 })); + const infoB = @typeInfo(B).Struct; + testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout); + testing.expectEqualSlices(u8, "x", infoB.fields[0].name); + testing.expectEqual(u8, infoB.fields[0].field_type); + testing.expectEqual(@as(?u8, null), infoB.fields[0].default_value); + testing.expectEqualSlices(u8, "y", infoB.fields[1].name); + testing.expectEqual(u32, infoB.fields[1].field_type); + testing.expectEqual(@as(?u32, 5), infoB.fields[1].default_value); + testing.expectEqual(@as(usize, 0), infoB.decls.len); + testing.expectEqual(@as(bool, false), infoB.is_tuple); + + const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 })); + const infoC = @typeInfo(C).Struct; + testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout); + testing.expectEqualSlices(u8, "x", infoC.fields[0].name); + testing.expectEqual(u8, infoC.fields[0].field_type); + testing.expectEqual(@as(?u8, 3), infoC.fields[0].default_value); + testing.expectEqualSlices(u8, "y", infoC.fields[1].name); + testing.expectEqual(u32, infoC.fields[1].field_type); + testing.expectEqual(@as(?u32, 5), infoC.fields[1].default_value); + testing.expectEqual(@as(usize, 0), infoC.decls.len); + testing.expectEqual(@as(bool, false), infoC.is_tuple); +} -- 2.54.0 From 759485cc328a4e6f2aba58891e86234c660797b6 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 19 Aug 2020 15:26:03 -0600 Subject: [PATCH 22/66] Update compile-errors test for @Type(.Struct) --- test/compile_errors.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/compile_errors.zig b/test/compile_errors.zig index fd74385d9b919456eb81585507e553297c1ba941..ea0d3b4e7b57c0a050fa98e64d8beb82abb52af5 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1395,12 +1395,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'", }); - cases.add("Struct unavailable for @Type", + cases.add("struct with declarations unavailable for @Type", \\export fn entry() void { - \\ _ = @Type(@typeInfo(struct { })); + \\ _ = @Type(@typeInfo(struct { const foo = 1; })); \\} , &[_][]const u8{ - "tmp.zig:2:15: error: @Type not available for 'TypeInfo.Struct'", + "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type", }); cases.add("wrong type for argument tuple to @asyncCall", -- 2.54.0 From b0846b6ecbb3e2557c5c95ddee04ecc055881d75 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Wed, 19 Aug 2020 23:21:16 +0200 Subject: [PATCH 23/66] builder: implement integer options --- lib/std/build.zig | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/std/build.zig b/lib/std/build.zig index 817b103b586711b1ffa16d3c74164932c191fba0..be39e8010c7e06f088932b981be5c44f99bcb4c1 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -449,7 +449,33 @@ pub const Builder = struct { return null; }, }, - .Int => panic("TODO integer options to build script", .{}), + .Int => switch (entry.value.value) { + .Flag => { + warn("Expected -D{} to be an integer, but received a boolean.\n", .{name}); + self.markInvalidUserInput(); + return null; + }, + .Scalar => |s| { + const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) { + error.Overflow => { + warn("-D{} value {} cannot fit into type {}.\n", .{ name, s, @typeName(T) }); + self.markInvalidUserInput(); + return null; + }, + else => { + warn("Expected -D{} to be an integer of type {}.\n", .{ name, @typeName(T) }); + self.markInvalidUserInput(); + return null; + }, + }; + return n; + }, + .List => { + warn("Expected -D{} to be an integer, but received a list.\n", .{name}); + self.markInvalidUserInput(); + return null; + }, + }, .Float => panic("TODO float options to build script", .{}), .Enum => switch (entry.value.value) { .Flag => { -- 2.54.0 From 8126421d07da21f0d404ec481edfda85da0709fc Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 19 Aug 2020 16:35:52 -0600 Subject: [PATCH 24/66] Small fixes for @Type(.Struct) --- src/ir.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index b2cbe89d122b5b97264c8ba6e7ebe435b5d879bc..976c50b8ffcce5309fe3d2d9d4d2a3abba325771 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -26203,7 +26203,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0); assert(layout_value->special == ConstValSpecialStatic); - assert(layout_value->type->id == ZigTypeIdEnum); + assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr)); ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag); ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 1); @@ -26236,7 +26236,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI entry->data.structure.layout = layout; entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone; entry->data.structure.created_by_at_type = true; - entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, buf_create_from_str("a")); + entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, &entry->name); assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0); @@ -26245,7 +26245,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI assert(fields_arr->data.x_array.special == ConstArraySpecialNone); for (size_t i = 0; i < fields_len; i++) { ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i]; - assert(field_value->type->id == ZigTypeIdStruct); + assert(field_value->type == ir_type_info_get_type(ira, "StructField", nullptr)); TypeStructField *field = entry->data.structure.fields[i]; field->name = buf_alloc(); if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name))) -- 2.54.0 From 338a495648f07a2734e012034fd301a0e77f8202 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 19 Aug 2020 13:56:48 +0300 Subject: [PATCH 25/66] stage2: implement global variables --- src-self-hosted/Module.zig | 218 +++++++++++++++++++++++++++++++++-- src-self-hosted/codegen.zig | 11 ++ src-self-hosted/ir.zig | 16 +++ src-self-hosted/type.zig | 6 +- src-self-hosted/value.zig | 19 +++ src-self-hosted/zir.zig | 5 + src-self-hosted/zir_sema.zig | 4 +- 7 files changed, 266 insertions(+), 13 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index e5988dfd8a06882282efc0f59748f7790f6fc5c0..3a68063236c8189ee5744f63232f158b2e006e5f 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -320,6 +320,12 @@ pub const Fn = struct { } }; +pub const Var = struct { + value: ?Value, + owner_decl: *Decl, + is_mutable: bool, +}; + pub const Scope = struct { tag: Tag, @@ -1419,7 +1425,152 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { } return type_changed; }, - .VarDecl => @panic("TODO var decl"), + .VarDecl => { + const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", ast_node); + + decl.analysis = .in_progress; + + const is_extern = blk: { + const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse + break :blk false; + break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern; + }; + const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var; + + // We need the memory for the Type to go into the arena for the Decl + var decl_arena = std.heap.ArenaAllocator.init(self.gpa); + errdefer decl_arena.deinit(); + const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); + + var block_scope: Scope.Block = .{ + .parent = null, + .func = null, + .decl = decl, + .instructions = .{}, + .arena = &decl_arena.allocator, + }; + defer block_scope.instructions.deinit(self.gpa); + + const explicit_type = blk: { + const type_node = var_decl.getTrailer("type_node") orelse + break :blk null; + + var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa); + defer type_scope_arena.deinit(); + var type_scope: Scope.GenZIR = .{ + .decl = decl, + .arena = &type_scope_arena.allocator, + .parent = decl.scope, + }; + defer type_scope.instructions.deinit(self.gpa); + + const src = tree.token_locs[type_node.firstToken()].start; + const type_type = try astgen.addZIRInstConst(self, &type_scope.base, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.type_type), + }); + const var_type = try astgen.expr(self, &type_scope.base, .{ .ty = type_type }, type_node); + _ = try astgen.addZIRUnOp(self, &type_scope.base, src, .@"return", var_type); + + break :blk try zir_sema.analyzeBodyValueAsType(self, &block_scope, .{ + .instructions = type_scope.instructions.items, + }); + }; + + var var_type: Type = undefined; + const value: ?Value = if (var_decl.getTrailer("init_node")) |init_node| blk: { + var gen_scope_arena = std.heap.ArenaAllocator.init(self.gpa); + defer gen_scope_arena.deinit(); + var gen_scope: Scope.GenZIR = .{ + .decl = decl, + .arena = &gen_scope_arena.allocator, + .parent = decl.scope, + }; + defer gen_scope.instructions.deinit(self.gpa); + const src = tree.token_locs[init_node.firstToken()].start; + + // TODO comptime scope here + const init_inst = try astgen.expr(self, &gen_scope.base, .none, init_node); + _ = try astgen.addZIRUnOp(self, &gen_scope.base, src, .@"return", init_inst); + + var inner_block: Scope.Block = .{ + .parent = null, + .func = null, + .decl = decl, + .instructions = .{}, + .arena = &gen_scope_arena.allocator, + }; + defer inner_block.instructions.deinit(self.gpa); + try zir_sema.analyzeBody(self, &inner_block.base, .{ .instructions = gen_scope.instructions.items }); + + for (inner_block.instructions.items) |inst| { + if (inst.castTag(.ret)) |ret| { + const coerced = if (explicit_type) |some| + try self.coerce(&inner_block.base, some, ret.operand) + else + ret.operand; + const val = try self.resolveConstValue(&inner_block.base, coerced); + + var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena); + break :blk try val.copy(block_scope.arena); + } else { + return self.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{}); + } + } + unreachable; + } else if (!is_extern) { + return self.failTok(&block_scope.base, var_decl.firstToken(), "variables must be initialized", .{}); + } else if (explicit_type) |some| blk: { + var_type = some; + break :blk null; + } else { + return self.failTok(&block_scope.base, var_decl.firstToken(), "unable to infer variable type", .{}); + }; + + if (is_mutable and !var_type.isValidVarType(is_extern)) { + return self.failTok(&block_scope.base, var_decl.firstToken(), "variable of type '{}' must be const", .{var_type}); + } + + var type_changed = true; + if (decl.typedValueManaged()) |tvm| { + type_changed = !tvm.typed_value.ty.eql(var_type); + + tvm.deinit(self.gpa); + } + + const new_variable = try decl_arena.allocator.create(Var); + const var_payload = try decl_arena.allocator.create(Value.Payload.Variable); + new_variable.* = .{ + .value = value, + .owner_decl = decl, + .is_mutable = is_mutable, + }; + var_payload.* = .{ .variable = new_variable }; + + decl_arena_state.* = decl_arena.state; + decl.typed_value = .{ + .most_recent = .{ + .typed_value = .{ + .ty = var_type, + .val = Value.initPayload(&var_payload.base), + }, + .arena = decl_arena_state, + }, + }; + decl.analysis = .complete; + decl.generation = self.generation; + + if (var_decl.getTrailer("extern_export_token")) |maybe_export_token| { + if (tree.token_ids[maybe_export_token] == .Keyword_export) { + const export_src = tree.token_locs[maybe_export_token].start; + const name_loc = tree.token_locs[var_decl.name_token]; + const name = tree.tokenSliceLoc(name_loc); + // The scope needs to have the decl in it. + try self.analyzeExport(&block_scope.base, export_src, name, decl); + } + } + return type_changed; + }, .Comptime => @panic("TODO comptime decl"), .Use => @panic("TODO usingnamespace decl"), else => unreachable, @@ -1584,7 +1735,32 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void { } } } else if (src_decl.castTag(.VarDecl)) |var_decl| { - log.err("TODO: analyze var decl", .{}); + const name_loc = tree.token_locs[var_decl.name_token]; + const name = tree.tokenSliceLoc(name_loc); + const name_hash = root_scope.fullyQualifiedNameHash(name); + const contents_hash = std.zig.hashSrc(tree.getNodeSource(src_decl)); + if (self.decl_table.get(name_hash)) |decl| { + // Update the AST Node index of the decl, even if its contents are unchanged, it may + // have been re-ordered. + decl.src_index = decl_i; + if (deleted_decls.remove(decl) == null) { + decl.analysis = .sema_failure; + const err_msg = try ErrorMsg.create(self.gpa, name_loc.start, "redefinition of '{}'", .{decl.name}); + errdefer err_msg.destroy(self.gpa); + try self.failed_decls.putNoClobber(self.gpa, decl, err_msg); + } else if (!srcHashEql(decl.contents_hash, contents_hash)) { + try self.markOutdatedDecl(decl); + decl.contents_hash = contents_hash; + } + } else { + const new_decl = try self.createNewDecl(&root_scope.base, name, decl_i, name_hash, contents_hash); + root_scope.decls.appendAssumeCapacity(new_decl); + if (var_decl.getTrailer("extern_export_token")) |maybe_export_token| { + if (tree.token_ids[maybe_export_token] == .Keyword_export) { + self.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl }); + } + } + } } else if (src_decl.castTag(.Comptime)) |comptime_node| { log.err("TODO: analyze comptime decl", .{}); } else if (src_decl.castTag(.ContainerField)) |container_field| { @@ -2217,20 +2393,46 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn }; const decl_tv = try decl.typedValue(); - const ty_payload = try scope.arena().create(Type.Payload.Pointer); - ty_payload.* = .{ - .base = .{ .tag = .single_const_pointer }, - .pointee_type = decl_tv.ty, - }; + if (decl_tv.val.tag() == .variable) { + return self.getVarRef(scope, src, decl_tv); + } + const ty = try self.singlePtrType(scope, src, false, decl_tv.ty); const val_payload = try scope.arena().create(Value.Payload.DeclRef); val_payload.* = .{ .decl = decl }; return self.constInst(scope, src, .{ - .ty = Type.initPayload(&ty_payload.base), + .ty = ty, .val = Value.initPayload(&val_payload.base), }); } +fn getVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst { + const variable = tv.val.cast(Value.Payload.Variable).?.variable; + + const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); + if (!variable.is_mutable and variable.value != null) { + const val_payload = try scope.arena().create(Value.Payload.RefVal); + val_payload.* = .{ .val = variable.value.? }; + return self.constInst(scope, src, .{ + .ty = ty, + .val = Value.initPayload(&val_payload.base), + }); + } + + const b = try self.requireRuntimeBlock(scope, src); + const inst = try b.arena.create(Inst.VarPtr); + inst.* = .{ + .base = .{ + .tag = .varptr, + .ty = ty, + .src = src, + }, + .variable = variable, + }; + try b.instructions.append(self.gpa, &inst.base); + return &inst.base; +} + pub fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_src: usize) InnerError!*Inst { const elem_ty = switch (ptr.ty.zigTypeTag()) { .Pointer => ptr.ty.elemType(), diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index cb404d8315f5a4ef0b4bb3fc4d2dffe5199bc545..1bc76f6b054bea0a00b81e2dc224c344637382c6 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -684,6 +684,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .unreach => return MCValue{ .unreach = {} }, .unwrap_optional => return self.genUnwrapOptional(inst.castTag(.unwrap_optional).?), .wrap_optional => return self.genWrapOptional(inst.castTag(.wrap_optional).?), + .varptr => return self.genVarPtr(inst.castTag(.varptr).?), } } @@ -858,6 +859,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } + fn genVarPtr(self: *Self, inst: *ir.Inst.VarPtr) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + + switch (arch) { + else => return self.fail(inst.base.src, "TODO implement varptr for {}", .{self.target.cpu.arch}), + } + } + fn reuseOperand(inst: *ir.Inst, op_index: ir.Inst.DeathsBitIndex, mcv: MCValue) bool { if (!inst.operandDies(op_index) or !mcv.isMutable()) return false; diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig index 070f41eb5e45c196670fef2c3d67fe8fe301b3ab..ff90c68d420e386db8a1fb8f7d9cb089131e24b6 100644 --- a/src-self-hosted/ir.zig +++ b/src-self-hosted/ir.zig @@ -81,6 +81,7 @@ pub const Inst = struct { ref, ret, retvoid, + varptr, /// Write a value to a pointer. LHS is pointer, RHS is value. store, sub, @@ -135,6 +136,7 @@ pub const Inst = struct { .condbr => CondBr, .constant => Constant, .loop => Loop, + .varptr => VarPtr, }; } @@ -434,6 +436,20 @@ pub const Inst = struct { return null; } }; + + pub const VarPtr = struct { + pub const base_tag = Tag.varptr; + + base: Inst, + variable: *Module.Var, + + pub fn operandCount(self: *const VarPtr) usize { + return 0; + } + pub fn getOperand(self: *const VarPtr, index: usize) ?*Inst { + return null; + } + }; }; pub const Body = struct { diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index a6ec90a35b0788845413d611beb699f8f31d4ac6..82671609d0a2caf02da6a55fdfb9ad2774411bbc 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -1074,7 +1074,7 @@ pub const Type = extern union { } /// Returns if type can be used for a runtime variable - pub fn isValidVarType(self: Type) bool { + pub fn isValidVarType(self: Type, is_extern: bool) bool { var ty = self; while (true) switch (ty.zigTypeTag()) { .Bool, @@ -1087,6 +1087,7 @@ pub const Type = extern union { .Vector, => return true, + .Opaque => return is_extern, .BoundFn, .ComptimeFloat, .ComptimeInt, @@ -1096,12 +1097,11 @@ pub const Type = extern union { .Void, .Undefined, .Null, - .Opaque, => return false, .Optional => { var buf: Payload.Pointer = undefined; - return ty.optionalChild(&buf).isValidVarType(); + return ty.optionalChild(&buf).isValidVarType(is_extern); }, .Pointer, .Array => ty = ty.elemType(), diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index b6356d9b176f2966e3c057b452ec61485008ba83..7bebd022ab6f039bb399e01e350d98907198dc49 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -79,6 +79,7 @@ pub const Value = extern union { int_big_positive, int_big_negative, function, + variable, ref_val, decl_ref, elem_ptr, @@ -196,6 +197,7 @@ pub const Value = extern union { @panic("TODO implement copying of big ints"); }, .function => return self.copyPayloadShallow(allocator, Payload.Function), + .variable => return self.copyPayloadShallow(allocator, Payload.Variable), .ref_val => { const payload = @fieldParentPtr(Payload.RefVal, "base", self.ptr_otherwise); const new_payload = try allocator.create(Payload.RefVal); @@ -310,6 +312,7 @@ pub const Value = extern union { .int_big_positive => return out_stream.print("{}", .{val.cast(Payload.IntBigPositive).?.asBigInt()}), .int_big_negative => return out_stream.print("{}", .{val.cast(Payload.IntBigNegative).?.asBigInt()}), .function => return out_stream.writeAll("(function)"), + .variable => return out_stream.writeAll("(variable)"), .ref_val => { const ref_val = val.cast(Payload.RefVal).?; try out_stream.writeAll("&const "); @@ -410,6 +413,7 @@ pub const Value = extern union { .int_big_positive, .int_big_negative, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -471,6 +475,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -548,6 +553,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -625,6 +631,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -728,6 +735,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -810,6 +818,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -974,6 +983,7 @@ pub const Value = extern union { .bool_false, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -1046,6 +1056,7 @@ pub const Value = extern union { .enum_literal_type, .null_value, .function, + .variable, .ref_val, .decl_ref, .elem_ptr, @@ -1182,6 +1193,7 @@ pub const Value = extern union { .bool_false, .null_value, .function, + .variable, .int_u64, .int_i64, .int_big_positive, @@ -1260,6 +1272,7 @@ pub const Value = extern union { .bool_false, .null_value, .function, + .variable, .int_u64, .int_i64, .int_big_positive, @@ -1355,6 +1368,7 @@ pub const Value = extern union { .bool_true, .bool_false, .function, + .variable, .int_u64, .int_i64, .int_big_positive, @@ -1429,6 +1443,11 @@ pub const Value = extern union { func: *Module.Fn, }; + pub const Variable = struct { + base: Payload = Payload{ .tag = .variable }, + variable: *Module.Var, + }; + pub const ArraySentinel0_u8_Type = struct { base: Payload = Payload{ .tag = .array_sentinel_0_u8_type }, len: u64, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 1a2c5cebaaff6088b5f90efb82e15de542a25a33..f59d470ffd157b320e1f16d8e1f010a68355fb23 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -1752,6 +1752,9 @@ const EmitZIR = struct { const decl_ref = try self.emitDeclRef(inst.src, declref.decl); try new_body.instructions.append(decl_ref); break :blk decl_ref; + } else if (const_inst.val.cast(Value.Payload.Variable)) |var_pl| blk: { + const owner_decl = var_pl.variable.owner_decl; + break :blk try self.emitDeclVal(inst.src, mem.spanZ(owner_decl.name)); } else blk: { break :blk (try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val })).inst; }; @@ -2311,6 +2314,8 @@ const EmitZIR = struct { }; break :blk &new_inst.base; }, + + .varptr => @panic("TODO"), }; try self.metadata.put(new_inst, .{ .deaths = inst.deaths }); try instructions.append(new_inst); diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index fb39a1e077c9ad7df6b205fbe4cf9446beefd403..644b73d6439ca22e202b906cb5290013166228cb 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -366,7 +366,7 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst. fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { const var_type = try resolveType(mod, scope, inst.positionals.operand); // TODO this should happen only for var allocs - if (!var_type.isValidVarType()) { + if (!var_type.isValidVarType(false)) { return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type}); } const ptr_type = try mod.singlePtrType(scope, inst.base.src, true, var_type); @@ -779,7 +779,7 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne for (fntype.positionals.param_types) |param_type, i| { const resolved = try resolveType(mod, scope, param_type); // TODO skip for comptime params - if (!resolved.isValidVarType()) { + if (!resolved.isValidVarType(false)) { return mod.fail(scope, param_type.src, "parameter of type '{}' must be declared comptime", .{resolved}); } param_types[i] = resolved; -- 2.54.0 From ab8a9a6605900fc0b064c321504ac4e7dc1ca6f4 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 19 Aug 2020 14:25:47 +0300 Subject: [PATCH 26/66] stage2: fix astgen of decl ref, add test for global consts --- src-self-hosted/astgen.zig | 14 ++++++++------ src-self-hosted/type.zig | 3 ++- src-self-hosted/zir_sema.zig | 3 +-- test/stage2/compare_output.zig | 31 +++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 9d40c7899a5541ea5d3b119ca816439118fe5e78..9f8afa6225e9c380168adf0749199ac94e016598 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -1223,9 +1223,10 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo } if (mod.lookupDeclName(scope, ident_name)) |decl| { - // TODO handle lvalues const result = try addZIRInst(mod, scope, src, zir.Inst.DeclValInModule, .{ .decl = decl }, .{}); - return rlWrap(mod, scope, rl, result); + if (rl == .lvalue or rl == .ref) + return result; + return rlWrap(mod, scope, rl, try addZIRUnOp(mod, scope, src, .deref, result)); } return mod.failNode(scope, &ident.base, "use of undeclared identifier '{}'", .{ident_name}); @@ -1258,7 +1259,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr // line lengths and new lines var len = lines.len - 1; for (lines) |line| { - len += tree.tokenSlice(line).len - 2; + // 2 for the '//' + 1 for '\n' + len += tree.tokenSlice(line).len - 3; } const bytes = try scope.arena().alloc(u8, len); @@ -1268,9 +1270,9 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr bytes[i] = '\n'; i += 1; } - const slice = tree.tokenSlice(line)[2..]; - mem.copy(u8, bytes[i..], slice); - i += slice.len; + const slice = tree.tokenSlice(line); + mem.copy(u8, bytes[i..], slice[2..slice.len - 1]); + i += slice.len - 3; } return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 82671609d0a2caf02da6a55fdfb9ad2774411bbc..c2762e1f8ad071a1ae5cc06f1a7ae18390744e6a 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -457,7 +457,8 @@ pub const Type = extern union { try param_type.format("", .{}, out_stream); } try out_stream.writeAll(") "); - try payload.return_type.format("", .{}, out_stream); + ty = payload.return_type; + continue; }, .array_u8 => { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 644b73d6439ca22e202b906cb5290013166228cb..cb1ed08d6d8e4c2bb3831f7add473c01a4dbc051 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -581,8 +581,7 @@ fn analyzeInstDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) Inne fn analyzeInstDeclValInModule(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclValInModule) InnerError!*Inst { const decl = inst.positionals.decl; - const ptr = try mod.analyzeDeclRef(scope, inst.base.src, decl); - return mod.analyzeDeref(scope, inst.base.src, ptr, inst.base.src); + return mod.analyzeDeclRef(scope, inst.base.src, decl); } fn analyzeInstCall(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst { diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 3513605602c94b5ea41fc7d93dcd4bcca848cfe3..2b8c8e94ccef047edc4bc9b50538ad60d0c11846 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -617,6 +617,37 @@ pub fn addCases(ctx: *TestContext) !void { , "", ); + + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(aa, bb); + \\ + \\ exit(); + \\} + \\ + \\const aa = 'ぁ'; + \\const bb = '\x03'; + \\ + \\fn add(a: u32, b: u32) void { + \\ assert(a + b == 12356); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); } { -- 2.54.0 From 9801047bdb26c86da430310aa5d043f6899adbfe Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 19 Aug 2020 15:19:00 +0300 Subject: [PATCH 27/66] stage2: handle var attributes --- src-self-hosted/Module.zig | 62 ++++++++++++++++++++++++++---------- src-self-hosted/zir_sema.zig | 1 + 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 3a68063236c8189ee5744f63232f158b2e006e5f..8009bcc32de0e17c514859cad192607bfe016a8e 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -290,6 +290,8 @@ pub const Fn = struct { }, owner_decl: *Decl, + is_pub: bool, + /// This memory is temporary and points to stack memory for the duration /// of Fn analysis. pub const Analysis = struct { @@ -323,7 +325,11 @@ pub const Fn = struct { pub const Var = struct { value: ?Value, owner_decl: *Decl, + + is_pub: bool, + is_extern: bool, is_mutable: bool, + is_threadlocal: bool, }; pub const Scope = struct { @@ -1241,6 +1247,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { }; defer fn_type_scope.instructions.deinit(self.gpa); + const is_pub = fn_proto.getTrailer("visib_token") != null; const body_node = fn_proto.getTrailer("body_node") orelse return self.failTok(&fn_type_scope.base, fn_proto.fn_token, "TODO implement extern functions", .{}); @@ -1378,6 +1385,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { new_func.* = .{ .analysis = .{ .queued = fn_zir }, .owner_decl = decl, + .is_pub = is_pub, }; fn_payload.* = .{ .func = new_func }; @@ -1430,26 +1438,45 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { decl.analysis = .in_progress; + // We need the memory for the Type to go into the arena for the Decl + var decl_arena = std.heap.ArenaAllocator.init(self.gpa); + errdefer decl_arena.deinit(); + const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); + + var block_scope: Scope.Block = .{ + .parent = null, + .func = null, + .decl = decl, + .instructions = .{}, + .arena = &decl_arena.allocator, + }; + defer block_scope.instructions.deinit(self.gpa); + + const is_pub = var_decl.getTrailer("visib_token") != null; const is_extern = blk: { const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse break :blk false; break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern; }; + if (var_decl.getTrailer("lib_name")) |lib_name| { + assert(is_extern); + return self.failNode(&block_scope.base, lib_name, "TODO implement function library name", .{}); + } const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var; + const is_threadlocal = if (var_decl.getTrailer("thread_local_token")) |some| blk: { + if (!is_mutable) { + return self.failTok(&block_scope.base, some, "threadlocal variable cannot be constant", .{}); + } + break :blk true; + } else false; + assert(var_decl.getTrailer("comptime_token") == null); + if (var_decl.getTrailer("align_node")) |align_expr| { + return self.failNode(&block_scope.base, align_expr, "TODO implement function align expression", .{}); + } + if (var_decl.getTrailer("section_node")) |sect_expr| { + return self.failNode(&block_scope.base, sect_expr, "TODO implement function section expression", .{}); + } - // We need the memory for the Type to go into the arena for the Decl - var decl_arena = std.heap.ArenaAllocator.init(self.gpa); - errdefer decl_arena.deinit(); - const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); - - var block_scope: Scope.Block = .{ - .parent = null, - .func = null, - .decl = decl, - .instructions = .{}, - .arena = &decl_arena.allocator, - }; - defer block_scope.instructions.deinit(self.gpa); const explicit_type = blk: { const type_node = var_decl.getTrailer("type_node") orelse @@ -1543,7 +1570,10 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { new_variable.* = .{ .value = value, .owner_decl = decl, + .is_pub = is_pub, + .is_extern = is_extern, .is_mutable = is_mutable, + .is_threadlocal = is_threadlocal, }; var_payload.* = .{ .variable = new_variable }; @@ -2394,7 +2424,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn const decl_tv = try decl.typedValue(); if (decl_tv.val.tag() == .variable) { - return self.getVarRef(scope, src, decl_tv); + return self.analyzeVarRef(scope, src, decl_tv); } const ty = try self.singlePtrType(scope, src, false, decl_tv.ty); const val_payload = try scope.arena().create(Value.Payload.DeclRef); @@ -2406,11 +2436,11 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn }); } -fn getVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst { +fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst { const variable = tv.val.cast(Value.Payload.Variable).?.variable; const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); - if (!variable.is_mutable and variable.value != null) { + if (!variable.is_mutable and !variable.is_extern and variable.value != null) { const val_payload = try scope.arena().create(Value.Payload.RefVal); val_payload.* = .{ .val = variable.value.? }; return self.constInst(scope, src, .{ diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index cb1ed08d6d8e4c2bb3831f7add473c01a4dbc051..87cce3adb38a63f5209b90447e0052ba72353d6f 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -666,6 +666,7 @@ fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError! new_func.* = .{ .analysis = .{ .queued = fn_zir }, .owner_decl = scope.decl().?, + .is_pub = false, }; const fn_payload = try scope.arena().create(Value.Payload.Function); fn_payload.* = .{ .func = new_func }; -- 2.54.0 From 5fdcb1a792e271c67f3aec36f8aca9e6c5503013 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 19 Aug 2020 19:12:01 +0300 Subject: [PATCH 28/66] stage2: emit zir variable fix, array type and enum literal support --- src-self-hosted/value.zig | 11 ++++++- src-self-hosted/zir.zig | 65 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index 7bebd022ab6f039bb399e01e350d98907198dc49..95a0746e194576284d6ef3dabebc374c3c74c5ee 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -218,7 +218,7 @@ pub const Value = extern union { }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .enum_literal, .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), + .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), .repeated => { const payload = @fieldParentPtr(Payload.Repeated, "base", self.ptr_otherwise); const new_payload = try allocator.create(Payload.Repeated); @@ -232,6 +232,15 @@ pub const Value = extern union { .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32), .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64), .float_128 => return self.copyPayloadShallow(allocator, Payload.Float_128), + .enum_literal => { + const payload = @fieldParentPtr(Payload.Bytes, "base", self.ptr_otherwise); + const new_payload = try allocator.create(Payload.Bytes); + new_payload.* = .{ + .base = payload.base, + .data = try allocator.dupe(u8, payload.data), + }; + return Value{ .ptr_otherwise = &new_payload.base }; + }, } } diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index f59d470ffd157b320e1f16d8e1f010a68355fb23..384463caee3a2942f83f1d270656dd704dc115f2 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -1878,6 +1878,11 @@ const EmitZIR = struct { if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| { const decl = decl_ref.decl; return try self.emitUnnamedDecl(try self.emitDeclRef(src, decl)); + } else if (typed_value.val.cast(Value.Payload.Variable)) |variable| { + return self.emitTypedValue(src, .{ + .ty = typed_value.ty, + .val = variable.variable.value.?, + }); } if (typed_value.val.isUndef()) { const as_inst = try self.arena.allocator.create(Inst.BinOp); @@ -1967,6 +1972,21 @@ const EmitZIR = struct { return self.emitPrimitive(src, .@"true") else return self.emitPrimitive(src, .@"false"), + .EnumLiteral => { + const enum_literal = @fieldParentPtr(Value.Payload.Bytes, "base", typed_value.val.ptr_otherwise); + const inst = try self.arena.allocator.create(Inst.Str); + inst.* = .{ + .base = .{ + .src = src, + .tag = .enum_literal, + }, + .positionals = .{ + .bytes = enum_literal.data, + }, + .kw_args = .{}, + }; + return self.emitUnnamedDecl(&inst.base); + }, else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}), } } @@ -2437,6 +2457,51 @@ const EmitZIR = struct { }; return self.emitUnnamedDecl(&inst.base); }, + .Array => { + var len_pl = Value.Payload.Int_u64{ .int = ty.arrayLen() }; + const len = Value.initPayload(&len_pl.base); + + const inst = if (ty.arraySentinel()) |sentinel| blk: { + const inst = try self.arena.allocator.create(Inst.ArrayTypeSentinel); + inst.* = .{ + .base = .{ + .src = src, + .tag = .array_type, + }, + .positionals = .{ + .len = (try self.emitTypedValue(src, .{ + .ty = Type.initTag(.usize), + .val = len, + })).inst, + .sentinel = (try self.emitTypedValue(src, .{ + .ty = ty.elemType(), + .val = sentinel, + })).inst, + .elem_type = (try self.emitType(src, ty.elemType())).inst, + }, + .kw_args = .{}, + }; + break :blk &inst.base; + } else blk: { + const inst = try self.arena.allocator.create(Inst.BinOp); + inst.* = .{ + .base = .{ + .src = src, + .tag = .array_type, + }, + .positionals = .{ + .lhs = (try self.emitTypedValue(src, .{ + .ty = Type.initTag(.usize), + .val = len, + })).inst, + .rhs = (try self.emitType(src, ty.elemType())).inst, + }, + .kw_args = .{}, + }; + break :blk &inst.base; + }; + return self.emitUnnamedDecl(inst); + }, else => std.debug.panic("TODO implement emitType for {}", .{ty}), }, } -- 2.54.0 From 9ec9c0f5e57820f4baa04b9674a6a4a88235b863 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 19 Aug 2020 17:52:22 -0700 Subject: [PATCH 29/66] optimize the memory layout of Module.Fn and Module.Var `is_pub` added to `Fn` would cost us an additional 8 bytes of memory per function, which is a real bummer since it's only 1 bit of information. If we wanted to really remove this, I suspect we could make this a function isPub() which looks at the AST of the corresponding Decl and finds if the FnProto AST node has the pub token. However I saw an easier approach - The data of whether something is pub or not is actually a property of a Decl anyway, not a function, so we can look at moving the field into Decl. Indeed, doing this, we see that Decl already has deletion_flag: bool which is hiding in the padding bytes between the enum (1 byte) and the following u32 field (generation). So if we put the is_pub bool there, it actually will take up no additional space, with 1 byte of padding remaining. This was an easy reworking of the code since any func.is_pub could be changed simply to func.owner_decl.is_pub. I also modified `Var` to make the init value non-optional and moved the optional bit to a has_init: bool field. This is worse from the perspective of control flow and safety, however it makes `@sizeOf(Var)` go from 32 bytes to 24 bytes. The more code we can fit into memory at once, the more justified we are in using the compiler as a long-running process that does incremental updates. --- src-self-hosted/Module.zig | 26 +++++++++++++------------- src-self-hosted/zir.zig | 2 +- src-self-hosted/zir_sema.zig | 1 - test/stage2/compare_output.zig | 2 ++ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 8009bcc32de0e17c514859cad192607bfe016a8e..ec69f94e3d346ff945470dc9643c1799d97de369 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -170,6 +170,9 @@ pub const Decl = struct { /// This flag is set when this Decl is added to a check_for_deletion set, and cleared /// when removed. deletion_flag: bool, + /// Whether the corresponding AST decl has a `pub` keyword. + is_pub: bool, + /// An integer that can be checked against the corresponding incrementing /// generation field of Module. This is used to determine whether `complete` status /// represents pre- or post- re-analysis. @@ -290,8 +293,6 @@ pub const Fn = struct { }, owner_decl: *Decl, - is_pub: bool, - /// This memory is temporary and points to stack memory for the duration /// of Fn analysis. pub const Analysis = struct { @@ -323,10 +324,10 @@ pub const Fn = struct { }; pub const Var = struct { - value: ?Value, + init: Value, owner_decl: *Decl, - is_pub: bool, + has_init: bool, is_extern: bool, is_mutable: bool, is_threadlocal: bool, @@ -1247,7 +1248,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { }; defer fn_type_scope.instructions.deinit(self.gpa); - const is_pub = fn_proto.getTrailer("visib_token") != null; + decl.is_pub = fn_proto.getTrailer("visib_token") != null; const body_node = fn_proto.getTrailer("body_node") orelse return self.failTok(&fn_type_scope.base, fn_proto.fn_token, "TODO implement extern functions", .{}); @@ -1385,7 +1386,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { new_func.* = .{ .analysis = .{ .queued = fn_zir }, .owner_decl = decl, - .is_pub = is_pub, }; fn_payload.* = .{ .func = new_func }; @@ -1452,7 +1452,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { }; defer block_scope.instructions.deinit(self.gpa); - const is_pub = var_decl.getTrailer("visib_token") != null; + decl.is_pub = var_decl.getTrailer("visib_token") != null; const is_extern = blk: { const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse break :blk false; @@ -1477,7 +1477,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { return self.failNode(&block_scope.base, sect_expr, "TODO implement function section expression", .{}); } - const explicit_type = blk: { const type_node = var_decl.getTrailer("type_node") orelse break :blk null; @@ -1568,9 +1567,9 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { const new_variable = try decl_arena.allocator.create(Var); const var_payload = try decl_arena.allocator.create(Value.Payload.Variable); new_variable.* = .{ - .value = value, .owner_decl = decl, - .is_pub = is_pub, + .init = value orelse undefined, + .has_init = value != null, .is_extern = is_extern, .is_mutable = is_mutable, .is_threadlocal = is_threadlocal, @@ -2004,6 +2003,7 @@ fn allocateNewDecl( .wasm => .{ .wasm = null }, }, .generation = 0, + .is_pub = false, }; return new_decl; } @@ -2440,15 +2440,15 @@ fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) Inner const variable = tv.val.cast(Value.Payload.Variable).?.variable; const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); - if (!variable.is_mutable and !variable.is_extern and variable.value != null) { + if (!variable.is_mutable and !variable.is_extern and variable.has_init) { const val_payload = try scope.arena().create(Value.Payload.RefVal); - val_payload.* = .{ .val = variable.value.? }; + val_payload.* = .{ .val = variable.init }; return self.constInst(scope, src, .{ .ty = ty, .val = Value.initPayload(&val_payload.base), }); } - + const b = try self.requireRuntimeBlock(scope, src); const inst = try b.arena.create(Inst.VarPtr); inst.* = .{ diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 384463caee3a2942f83f1d270656dd704dc115f2..552e90956b2c4fbb2c1211a3f9d229eb75ba3e41 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -1881,7 +1881,7 @@ const EmitZIR = struct { } else if (typed_value.val.cast(Value.Payload.Variable)) |variable| { return self.emitTypedValue(src, .{ .ty = typed_value.ty, - .val = variable.variable.value.?, + .val = variable.variable.init, }); } if (typed_value.val.isUndef()) { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 87cce3adb38a63f5209b90447e0052ba72353d6f..cb1ed08d6d8e4c2bb3831f7add473c01a4dbc051 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -666,7 +666,6 @@ fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError! new_func.* = .{ .analysis = .{ .queued = fn_zir }, .owner_decl = scope.decl().?, - .is_pub = false, }; const fn_payload = try scope.arena().create(Value.Payload.Function); fn_payload.* = .{ .func = new_func }; diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 2b8c8e94ccef047edc4bc9b50538ad60d0c11846..6fbc760f26dba01f2abc5c5571d624e503d33b5b 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -586,6 +586,7 @@ pub fn addCases(ctx: *TestContext) !void { "", ); + // Character literals and multiline strings. case.addCompareOutput( \\export fn _start() noreturn { \\ const ignore = @@ -618,6 +619,7 @@ pub fn addCases(ctx: *TestContext) !void { "", ); + // Global const. case.addCompareOutput( \\export fn _start() noreturn { \\ add(aa, bb); -- 2.54.0 From 59711becc74911ba251001de81bbac2a53e81b9f Mon Sep 17 00:00:00 2001 From: StrangeBug Date: Fri, 22 May 2020 20:24:16 +0200 Subject: [PATCH 30/66] Add handler for INVALID_HANDLE to prevent infinite loop when stderr is not available. --- lib/std/os/windows.zig | 2 ++ src-self-hosted/stage2.zig | 3 +++ 2 files changed, 5 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index c93feb20d74250d71cae4d95b2e3b8e89db78af8..c2decaf20867281418b8e7e6302eb05dcd16d480 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -469,6 +469,7 @@ pub const WriteFileError = error{ SystemResources, OperationAborted, BrokenPipe, + InvalidFd, Unexpected, }; @@ -542,6 +543,7 @@ pub fn WriteFile( .NOT_ENOUGH_QUOTA => return error.SystemResources, .IO_PENDING => unreachable, .BROKEN_PIPE => return error.BrokenPipe, + .INVALID_HANDLE => return error.NotOpenForWriting, else => |err| return unexpectedError(err), } } diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 30d2ea44db92774fbc7705a80e2d8454d06cf330..148001c5757a841e0e44d434657a384faa31c3eb 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -164,6 +164,7 @@ export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { error.OutOfMemory => return .OutOfMemory, error.Unexpected => return .Unexpected, error.InputOutput => return .FileSystem, + error.InvalidFd => return .FileSystem, }; return .None; } @@ -635,6 +636,7 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [ error.NotDir => return .NotDir, error.DeviceBusy => return .DeviceBusy, error.FileLocksNotSupported => unreachable, + error.InvalidFd => return .FileSystem, }; stage1_libc.initFromStage2(libc); return .None; @@ -679,6 +681,7 @@ export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: error.AccessDenied => return .AccessDenied, error.Unexpected => return .Unexpected, error.InputOutput => return .FileSystem, + error.InvalidFd => return .FileSystem, }; return .None; } -- 2.54.0 From 23c427b5fbd0e83b08d83a00cd343ff9bc4c1824 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 19 Aug 2020 20:51:06 -0700 Subject: [PATCH 31/66] windows: match the same error code for EBADF --- lib/std/os/windows.zig | 2 +- src-self-hosted/stage2.zig | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index c2decaf20867281418b8e7e6302eb05dcd16d480..2f2369a458616121ca60bd723b6ce9d618b6c5a9 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -469,7 +469,7 @@ pub const WriteFileError = error{ SystemResources, OperationAborted, BrokenPipe, - InvalidFd, + NotOpenForWriting, Unexpected, }; diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 148001c5757a841e0e44d434657a384faa31c3eb..30d2ea44db92774fbc7705a80e2d8454d06cf330 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -164,7 +164,6 @@ export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { error.OutOfMemory => return .OutOfMemory, error.Unexpected => return .Unexpected, error.InputOutput => return .FileSystem, - error.InvalidFd => return .FileSystem, }; return .None; } @@ -636,7 +635,6 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [ error.NotDir => return .NotDir, error.DeviceBusy => return .DeviceBusy, error.FileLocksNotSupported => unreachable, - error.InvalidFd => return .FileSystem, }; stage1_libc.initFromStage2(libc); return .None; @@ -681,7 +679,6 @@ export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: error.AccessDenied => return .AccessDenied, error.Unexpected => return .Unexpected, error.InputOutput => return .FileSystem, - error.InvalidFd => return .FileSystem, }; return .None; } -- 2.54.0 From 9164daaa39a0ebffcfff27d6d8c91f5857bdfe04 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 20 Aug 2020 08:30:54 +0200 Subject: [PATCH 32/66] Write page zero as first segment for Mach-O exes According to the Mach-O file format reference, the first load command should be a `__PAGEZERO` segment command. The segment is located at virtual memory location 0, has no protection rights, and causes acccesses to NULL to immediately crash. Signed-off-by: Jakub Konka --- src-self-hosted/link/MachO.zig | 60 +++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index e2a84d8ceb84630fd1cf250d0f47d2c0dbf2fae1..5ba8b6f27ba7aadde23b463098cfd63262228c9b 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -6,6 +6,8 @@ const assert = std.debug.assert; const fs = std.fs; const log = std.log.scoped(.link); const macho = std.macho; +const math = std.math; +const mem = std.mem; const Module = @import("../Module.zig"); const link = @import("../link.zig"); @@ -15,6 +17,14 @@ pub const base_tag: Tag = File.Tag.macho; base: File, +/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. +/// Same order as in the file. +segment_cmds: std.ArrayListUnmanaged(macho.segment_command_64) = std.ArrayListUnmanaged(macho.segment_command_64){}, + +/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. +/// Same order as in the file. +sections: std.ArrayListUnmanaged(macho.@"section_64") = std.ArrayListUnmanaged(macho.@"section_64"){}, + entry_addr: ?u64 = null, error_flags: File.ErrorFlags = File.ErrorFlags{}, @@ -86,9 +96,34 @@ fn createFile(allocator: *Allocator, file: fs.File, options: link.Options) !Mach }; errdefer self.deinit(); + if (options.output_mode == .Exe) { + // The first segment command for executables is always a __PAGEZERO segment. + try self.segment_cmds.append(allocator, .{ + .cmd = macho.LC_SEGMENT_64, + .cmdsize = @sizeOf(macho.segment_command_64), + .segname = self.makeString("__PAGEZERO"), + .vmaddr = 0, + .vmsize = 0, + .fileoff = 0, + .filesize = 0, + .maxprot = 0, + .initprot = 0, + .nsects = 0, + .flags = 0, + }); + } + return self; } +fn makeString(self: *MachO, comptime bytes: []const u8) [16]u8 { + if (bytes.len > 16) @compileError("MachO segment/section name too long"); + + var buf: [16]u8 = undefined; + mem.copy(u8, buf[0..], bytes); + return buf; +} + fn writeMachOHeader(self: *MachO) !void { var hdr: macho.mach_header_64 = undefined; hdr.magic = macho.MH_MAGIC_64; @@ -122,9 +157,12 @@ fn writeMachOHeader(self: *MachO) !void { }; hdr.filetype = filetype; - // TODO the rest of the header - hdr.ncmds = 0; - hdr.sizeofcmds = 0; + // TODO consider other commands + const ncmds = try math.cast(u32, self.segment_cmds.items.len); + hdr.ncmds = ncmds; + hdr.sizeofcmds = ncmds * @sizeOf(macho.segment_command_64); + + // TODO should these be set to something else? hdr.flags = 0; hdr.reserved = 0; @@ -133,6 +171,17 @@ fn writeMachOHeader(self: *MachO) !void { pub fn flush(self: *MachO, module: *Module) !void { // TODO implement flush + { + const buf = try self.base.allocator.alloc(macho.segment_command_64, self.segment_cmds.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*seg, i| { + seg.* = self.segment_cmds.items[i]; + } + + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), @sizeOf(macho.mach_header_64)); + } + if (self.entry_addr == null and self.base.options.output_mode == .Exe) { log.debug("flushing. no_entry_point_found = true\n", .{}); self.error_flags.no_entry_point_found = true; @@ -143,7 +192,10 @@ pub fn flush(self: *MachO, module: *Module) !void { } } -pub fn deinit(self: *MachO) void {} +pub fn deinit(self: *MachO) void { + self.segment_cmds.deinit(self.base.allocator); + self.@"sections".deinit(self.base.allocator); +} pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {} -- 2.54.0 From adc5bce5e8487cf9507ab5dd2b1b60dd7f54cc3d Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 10:08:27 +0300 Subject: [PATCH 33/66] translate-c: correct translation of global variables * externs with intializers are translated as exports * non extern without explicit initialization are zero initalized --- lib/std/mem.zig | 20 +++++++++++++++++++- src-self-hosted/translate_c.zig | 27 ++++++++++++++++++++++++--- test/translate_c.zig | 4 ++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 1ba64f47fa9da2d832b225c7916010e490ce32dc..7f1b5ae61888f9a096e75d6fef5c366aeb06d7c7 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -221,9 +221,19 @@ pub fn zeroes(comptime T: type) T { .Vector => |info| { return @splat(info.len, zeroes(info.child)); }, + .Union => |info| { + if (comptime meta.containerLayout(T) == .Extern) { + // The C language specification states that (global) unions + // should be zero initialized to the first named member. + var item: T = undefined; + @field(item, info.fields[0].name) = zeroes(@TypeOf(@field(item, info.fields[0].name))); + return item; + } + + @compileError("Can't set a " ++ @typeName(T) ++ " to zero."); + }, .ErrorUnion, .ErrorSet, - .Union, .Fn, .BoundFn, .Type, @@ -312,6 +322,14 @@ test "mem.zeroes" { for (b.sentinel) |e| { testing.expectEqual(@as(u8, 0), e); } + + const C_union = extern union { + a: u8, + b: u32, + }; + + var c = zeroes(C_union); + testing.expectEqual(@as(u8, 0), c.a); } /// Sets a slice to zeroes. diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 98cb68f059496998c238fcefe878bcc6e6c48460..6c6e3f0c7ea4c1a73b9be6820dd5d34f7c33381d 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -701,8 +701,14 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); const storage_class = ZigClangVarDecl_getStorageClass(var_decl); const is_const = ZigClangQualType_isConstQualified(qual_type); + const has_init = ZigClangVarDecl_hasInit(var_decl); - const extern_tok = if (storage_class == .Extern) + // In C extern variables with initializers behave like Zig exports. + // extern int foo = 2; + // does the same as: + // extern int foo; + // int foo = 2; + const extern_tok = if (storage_class == .Extern and !has_init) try appendToken(c, .Keyword_extern, "extern") else if (storage_class != .Static) try appendToken(c, .Keyword_export, "export") @@ -730,7 +736,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { // If the initialization expression is not present, initialize with undefined. // If it is an integer literal, we can skip the @as since it will be redundant // with the variable type. - if (ZigClangVarDecl_hasInit(var_decl)) { + if (has_init) { eq_tok = try appendToken(c, .Equal, "="); init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| transExprCoercing(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) { @@ -745,7 +751,22 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { try transCreateNodeUndefinedLiteral(c); } else if (storage_class != .Extern) { eq_tok = try appendToken(c, .Equal, "="); - init_node = try transCreateNodeIdentifierUnchecked(c, "undefined"); + // The C language specification states that variables with static or threadlocal + // storage without an initializer are initialized to a zero value. + + // @import("std").mem.zeroes(T) + const import_fn_call = try c.createBuiltinCall("@import", 1); + const std_node = try transCreateNodeStringLiteral(c, "\"std\""); + import_fn_call.params()[0] = std_node; + import_fn_call.rparen_token = try appendToken(c, .RParen, ")"); + const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "mem"); + const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "zeroes"); + + const zero_init_call = try c.createCall(outer_field_access, 1); + zero_init_call.params()[0] = type_node; + zero_init_call.rtoken = try appendToken(c, .RParen, ")"); + + init_node = &zero_init_call.base; } const linksection_expr = blk: { diff --git a/test/translate_c.zig b/test/translate_c.zig index f7e983276ebb6d321aa086d6bc7139e5372728d3..bfbae2b65e81e9333c459205e0a0b70c6a7260b4 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -466,7 +466,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub extern var extern_var: c_int; \\pub const int_var: c_int = 13; - \\pub export var foo: c_int = undefined; + \\pub export var foo: c_int = @import("std").mem.zeroes(c_int); }); cases.add("const ptr initializer", @@ -1327,7 +1327,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\static char arr1[] = "hello"; \\char arr2[] = "hello"; , &[_][]const u8{ - \\pub extern var arr0: [*c]u8 = "hello"; + \\pub export var arr0: [*c]u8 = "hello"; \\pub var arr1: [*c]u8 = "hello"; \\pub export var arr2: [*c]u8 = "hello"; }); -- 2.54.0 From ad79b80524820d3f0ec60d4d21461208227cd4c8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 20 Aug 2020 09:14:37 +0200 Subject: [PATCH 34/66] Apply suggestions from code review Co-authored-by: Andrew Kelley --- src-self-hosted/link/MachO.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index 5ba8b6f27ba7aadde23b463098cfd63262228c9b..9947530398a74844267679d50242b5603e666f60 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -23,7 +23,7 @@ segment_cmds: std.ArrayListUnmanaged(macho.segment_command_64) = std.ArrayListUn /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. /// Same order as in the file. -sections: std.ArrayListUnmanaged(macho.@"section_64") = std.ArrayListUnmanaged(macho.@"section_64"){}, +sections: std.ArrayListUnmanaged(macho.section_64) = std.ArrayListUnmanaged(macho.section_64){}, entry_addr: ?u64 = null, @@ -117,9 +117,8 @@ fn createFile(allocator: *Allocator, file: fs.File, options: link.Options) !Mach } fn makeString(self: *MachO, comptime bytes: []const u8) [16]u8 { - if (bytes.len > 16) @compileError("MachO segment/section name too long"); - var buf: [16]u8 = undefined; + if (bytes.len > buf.len) @compileError("MachO segment/section name too long"); mem.copy(u8, buf[0..], bytes); return buf; } @@ -194,7 +193,7 @@ pub fn flush(self: *MachO, module: *Module) !void { pub fn deinit(self: *MachO) void { self.segment_cmds.deinit(self.base.allocator); - self.@"sections".deinit(self.base.allocator); + self.sections.deinit(self.base.allocator); } pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {} -- 2.54.0 From a553947a51bc5858ff40fb47dfe41daaa9ff75bf Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 10:45:55 +0300 Subject: [PATCH 35/66] translate-c: correctly put static and extern local variables in global scope --- src-self-hosted/translate_c.zig | 25 ++++++++++++++++--------- test/run_translated_c.zig | 14 ++++++++++++++ test/translate_c.zig | 17 ++++++++++++++++- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 6c6e3f0c7ea4c1a73b9be6820dd5d34f7c33381d..6628f5b99ea002e28f666bf4bf5d738602932c73 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -498,7 +498,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { _ = try transRecordDecl(c, @ptrCast(*const ZigClangRecordDecl, decl)); }, .Var => { - return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl)); + return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl), null); }, .Empty => { // Do nothing @@ -679,12 +679,13 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { return addTopLevelDecl(c, fn_name, &proto_node.base); } -fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { - const var_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, var_decl))); +/// if mangled_name is not null, this var decl was declared in a block scope. +fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl, mangled_name: ?[]const u8) Error!void { + const var_name = mangled_name orelse try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, var_decl))); if (c.global_scope.sym_table.contains(var_name)) return; // Avoid processing this decl twice const rp = makeRestorePoint(c); - const visib_tok = try appendToken(c, .Keyword_pub, "pub"); + const visib_tok = if (mangled_name) |_| null else try appendToken(c, .Keyword_pub, "pub"); const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) null @@ -1582,15 +1583,22 @@ fn transDeclStmtOne( .Var => { const var_decl = @ptrCast(*const ZigClangVarDecl, decl); - const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) - null - else - try appendToken(c, .Keyword_threadlocal, "threadlocal"); const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl); const name = try c.str(ZigClangNamedDecl_getName_bytes_begin( @ptrCast(*const ZigClangNamedDecl, var_decl), )); const mangled_name = try block_scope.makeMangledName(c, name); + + switch (ZigClangVarDecl_getStorageClass(var_decl)) { + .Extern, .Static => { + // This is actually a global variable, put it in the global scope and reference it. + // `_ = mangled_name;` + try visitVarDecl(rp.c, var_decl, mangled_name); + return try maybeSuppressResult(rp, scope, .unused, try transCreateNodeIdentifier(rp.c, mangled_name)); + }, + else => {}, + } + const mut_tok = if (ZigClangQualType_isConstQualified(qual_type)) try appendToken(c, .Keyword_const, "const") else @@ -1618,7 +1626,6 @@ fn transDeclStmtOne( .mut_token = mut_tok, .semicolon_token = semicolon_token, }, .{ - .thread_local_token = thread_local_token, .eq_token = eq_token, .type_node = type_node, .init_node = init_node, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 3fa183ce3b43551cd256ba0d0943539561ac299c..2b27e3085edafeba3553637d048b3c8a71ae23d4 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -3,6 +3,20 @@ const tests = @import("tests.zig"); const nl = std.cstr.line_sep; pub fn addCases(cases: *tests.RunTranslatedCContext) void { + cases.add("static variable in block scope", + \\#include + \\int foo() { + \\ static int bar; + \\ bar += 1; + \\ return bar; + \\} + \\int main() { + \\ foo(); + \\ foo(); + \\ if (foo() != 3) abort(); + \\} + , ""); + cases.add("array initializer", \\#include \\int main(int argc, char **argv) { diff --git a/test/translate_c.zig b/test/translate_c.zig index bfbae2b65e81e9333c459205e0a0b70c6a7260b4..41f1e782946065743e1a8793f7fe79bdfea4c88b 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -3,6 +3,20 @@ const std = @import("std"); const CrossTarget = std.zig.CrossTarget; pub fn addCases(cases: *tests.TranslateCContext) void { + cases.add("extern variable in block scope", + \\float bar; + \\int foo() { + \\ _Thread_local static int bar = 2; + \\} + , &[_][]const u8{ + \\pub export var bar: f32 = @import("std").mem.zeroes(f32); + \\threadlocal var bar_1: c_int = 2; + \\pub export fn foo() c_int { + \\ _ = bar_1; + \\ return 0; + \\} + }); + cases.add("missing return stmt", \\int foo() {} \\int bar() { @@ -480,8 +494,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ static const char v2[] = "2.2.2"; \\} , &[_][]const u8{ + \\const v2: [*c]const u8 = "2.2.2"; \\pub export fn foo() void { - \\ const v2: [*c]const u8 = "2.2.2"; + \\ _ = v2; \\} }); -- 2.54.0 From d25674a51ec09640b0140a541a156869b3e03f81 Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 11:04:42 +0300 Subject: [PATCH 36/66] disallow extern variables with initializers --- lib/std/c/darwin.zig | 2 +- lib/std/special/c.zig | 2 +- lib/std/special/compiler_rt.zig | 2 +- src-self-hosted/Module.zig | 11 +++++++---- src/parser.cpp | 3 +++ test/compile_errors.zig | 6 ++++++ test/standalone/global_linkage/obj1.zig | 4 ++-- test/standalone/global_linkage/obj2.zig | 4 ++-- 8 files changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 242663856965d4d7a65613497686316fc6684e7a..b1f66fa5751677a59f66592472b0db4cb51846d9 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -41,7 +41,7 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header; /// on this operating system. However when building object files or libraries, /// the system libc won't be linked until the final executable. So we /// export a weak symbol here, to be overridden by the real one. -pub extern "c" var _mh_execute_header: mach_hdr = undefined; +pub extern "c" var _mh_execute_header: mach_hdr; comptime { if (std.Target.current.isDarwin()) { @export(_mh_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak }); diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 170bb9862030fae876f10c0b644498d5d1ed0f0b..8019db9d96f3599f316c2bffbdaeccbb70a364ef 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -35,7 +35,7 @@ comptime { } } -extern var _fltused: c_int = 1; +var _fltused: c_int = 1; extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int; fn wasm_start() callconv(.C) void { diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 2716de811369c2f0400b596f73274d490442d93a..36a731ed5a177bc8fd6c3e749be112c94b089189 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -335,7 +335,7 @@ fn __stack_chk_fail() callconv(.C) noreturn { @panic("stack smashing detected"); } -extern var __stack_chk_guard: usize = blk: { +var __stack_chk_guard: usize = blk: { var buf = [1]u8{0} ** @sizeOf(usize); buf[@sizeOf(usize) - 1] = 255; buf[@sizeOf(usize) - 2] = '\n'; diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index ec69f94e3d346ff945470dc9643c1799d97de369..d08e7f5746c49fcf6a743e19beea383b64982006 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -324,10 +324,10 @@ pub const Fn = struct { }; pub const Var = struct { + /// if is_extern == true this is undefined init: Value, owner_decl: *Decl, - has_init: bool, is_extern: bool, is_mutable: bool, is_threadlocal: bool, @@ -1456,7 +1456,11 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { const is_extern = blk: { const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse break :blk false; - break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern; + if (tree.token_ids[maybe_extern_token] != .Keyword_extern) break :blk false; + if (var_decl.getTrailer("init_node")) |some| { + return self.failNode(&block_scope.base, some, "extern variables have no initializers", .{}); + } + break :blk true; }; if (var_decl.getTrailer("lib_name")) |lib_name| { assert(is_extern); @@ -1569,7 +1573,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { new_variable.* = .{ .owner_decl = decl, .init = value orelse undefined, - .has_init = value != null, .is_extern = is_extern, .is_mutable = is_mutable, .is_threadlocal = is_threadlocal, @@ -2440,7 +2443,7 @@ fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) Inner const variable = tv.val.cast(Value.Payload.Variable).?.variable; const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); - if (!variable.is_mutable and !variable.is_extern and variable.has_init) { + if (!variable.is_mutable and !variable.is_extern) { const val_payload = try scope.arena().create(Value.Payload.RefVal); val_payload.* = .{ .val = variable.init }; return self.constInst(scope, src, .{ diff --git a/src/parser.cpp b/src/parser.cpp index 26233ec6a43283f44045cba69496a92d9be8639a..1253baf9ea5104ee655e42d061927ccec3b5bc61 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -680,6 +680,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B AstNode *var_decl = ast_parse_var_decl(pc); if (var_decl != nullptr) { assert(var_decl->type == NodeTypeVariableDeclaration); + if (first->id == TokenIdKeywordExtern && var_decl->data.variable_declaration.expr != nullptr) { + ast_error(pc, first, "extern variables have no initializers"); + } var_decl->line = first->start_line; var_decl->column = first->start_column; var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index fd74385d9b919456eb81585507e553297c1ba941..311c5b93191828b8673c0a606993ec741354585f 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,12 @@ const tests = @import("tests.zig"); const std = @import("std"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("reject extern variables with initializers", + \\extern var foo: int = 2; + , &[_][]const u8{ + "tmp.zig:1:1: error: extern variables have no initializers", + }); + cases.addTest("duplicate/unused labels", \\comptime { \\ blk: { blk: while (false) {} } diff --git a/test/standalone/global_linkage/obj1.zig b/test/standalone/global_linkage/obj1.zig index 95814cda3d1edd4b6e33e08149dd14405d188075..83b66f336ba6bfc32d630481dd6ab136237bd059 100644 --- a/test/standalone/global_linkage/obj1.zig +++ b/test/standalone/global_linkage/obj1.zig @@ -1,5 +1,5 @@ -extern var internal_integer: usize = 1; -extern var obj1_integer: usize = 421; +var internal_integer: usize = 1; +var obj1_integer: usize = 421; comptime { @export(internal_integer, .{ .name = "internal_integer", .linkage = .Internal }); diff --git a/test/standalone/global_linkage/obj2.zig b/test/standalone/global_linkage/obj2.zig index f2d44b2dc060d6a6819ebcdd5501085939b135ae..2908a627fd2dc83c15e4cfc7ad3aafac8d82c9a0 100644 --- a/test/standalone/global_linkage/obj2.zig +++ b/test/standalone/global_linkage/obj2.zig @@ -1,5 +1,5 @@ -extern var internal_integer: usize = 2; -extern var obj2_integer: usize = 422; +var internal_integer: usize = 2; +var obj2_integer: usize = 422; comptime { @export(internal_integer, .{ .name = "internal_integer", .linkage = .Internal }); -- 2.54.0 From 717e2a365d9b5103f855668e4765cc154203a2bf Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 14:19:11 +0300 Subject: [PATCH 37/66] correct llvm linkage conversion when weakly exporting external declaration we need to pass LLVMExternalWeakLinkage --- lib/std/c/darwin.zig | 5 +++-- src/codegen.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index b1f66fa5751677a59f66592472b0db4cb51846d9..9ff66ac01e821fbee741ba3dfb6e3da1e2314167 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -41,10 +41,11 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header; /// on this operating system. However when building object files or libraries, /// the system libc won't be linked until the final executable. So we /// export a weak symbol here, to be overridden by the real one. -pub extern "c" var _mh_execute_header: mach_hdr; +var dummy_execute_header: mach_hdr = undefined; +pub extern var _mh_execute_header: mach_hdr; comptime { if (std.Target.current.isDarwin()) { - @export(_mh_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak }); + @export(dummy_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak }); } } diff --git a/src/codegen.cpp b/src/codegen.cpp index 36ed52006937598ba1ebd0c87e70efbb99543f03..e2341fe1aac0a68c46d232df84d8752ccb5a0d12 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -292,13 +292,14 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { } } -static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { +static LLVMLinkage to_llvm_linkage(GlobalLinkageId id, bool is_extern) { switch (id) { case GlobalLinkageIdInternal: return LLVMInternalLinkage; case GlobalLinkageIdStrong: return LLVMExternalLinkage; case GlobalLinkageIdWeak: + if (is_extern) return LLVMExternalWeakLinkage; return LLVMWeakODRLinkage; case GlobalLinkageIdLinkOnce: return LLVMLinkOnceODRLinkage; @@ -521,7 +522,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } - LLVMSetLinkage(llvm_fn, to_llvm_linkage(linkage)); + LLVMSetLinkage(llvm_fn, to_llvm_linkage(linkage, fn->body_node == nullptr)); if (linkage == GlobalLinkageIdInternal) { LLVMSetUnnamedAddr(llvm_fn, true); @@ -7962,7 +7963,7 @@ static void do_code_gen(CodeGen *g) { global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name); // TODO debug info for the extern variable - LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); + LLVMSetLinkage(global_value, to_llvm_linkage(linkage, true)); maybe_import_dll(g, global_value, GlobalLinkageIdStrong); LLVMSetAlignment(global_value, var->align_bytes); LLVMSetGlobalConstant(global_value, var->gen_is_const); @@ -7975,7 +7976,7 @@ static void do_code_gen(CodeGen *g) { global_value = var->const_value->llvm_global; if (exported) { - LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); + LLVMSetLinkage(global_value, to_llvm_linkage(linkage, false)); maybe_export_dll(g, global_value, GlobalLinkageIdStrong); } if (var->section_name) { -- 2.54.0 From 4a69b11e742365d68e4d92aa18d6493db9d3edaf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 19 Aug 2020 19:40:15 -0700 Subject: [PATCH 38/66] add license header to all std lib files add SPDX license identifier copyright ownership is zig contributors --- lib/std/array_list.zig | 5 +++++ lib/std/array_list_sentineled.zig | 5 +++++ lib/std/ascii.zig | 5 +++++ lib/std/atomic.zig | 5 +++++ lib/std/atomic/int.zig | 5 +++++ lib/std/atomic/queue.zig | 5 +++++ lib/std/atomic/stack.zig | 5 +++++ lib/std/base64.zig | 5 +++++ lib/std/bloom_filter.zig | 5 +++++ lib/std/buf_map.zig | 5 +++++ lib/std/buf_set.zig | 5 +++++ lib/std/build.zig | 5 +++++ lib/std/build/check_file.zig | 5 +++++ lib/std/build/emit_raw.zig | 5 +++++ lib/std/build/fmt.zig | 5 +++++ lib/std/build/run.zig | 5 +++++ lib/std/build/translate_c.zig | 5 +++++ lib/std/build/write_file.zig | 5 +++++ lib/std/builtin.zig | 5 +++++ lib/std/c.zig | 5 +++++ lib/std/c/ast.zig | 5 +++++ lib/std/c/darwin.zig | 5 +++++ lib/std/c/dragonfly.zig | 5 +++++ lib/std/c/emscripten.zig | 5 +++++ lib/std/c/freebsd.zig | 5 +++++ lib/std/c/fuchsia.zig | 5 +++++ lib/std/c/haiku.zig | 5 +++++ lib/std/c/hermit.zig | 5 +++++ lib/std/c/linux.zig | 5 +++++ lib/std/c/minix.zig | 5 +++++ lib/std/c/netbsd.zig | 5 +++++ lib/std/c/openbsd.zig | 5 +++++ lib/std/c/parse.zig | 5 +++++ lib/std/c/solaris.zig | 5 +++++ lib/std/c/tokenizer.zig | 5 +++++ lib/std/c/windows.zig | 5 +++++ lib/std/cache_hash.zig | 5 +++++ lib/std/child_process.zig | 5 +++++ lib/std/coff.zig | 5 +++++ lib/std/comptime_string_map.zig | 5 +++++ lib/std/crypto.zig | 5 +++++ lib/std/crypto/25519/curve25519.zig | 5 +++++ lib/std/crypto/25519/ed25519.zig | 5 +++++ lib/std/crypto/25519/edwards25519.zig | 5 +++++ lib/std/crypto/25519/field.zig | 5 +++++ lib/std/crypto/25519/ristretto255.zig | 5 +++++ lib/std/crypto/25519/scalar.zig | 5 +++++ lib/std/crypto/25519/x25519.zig | 5 +++++ lib/std/crypto/aes.zig | 5 +++++ lib/std/crypto/benchmark.zig | 5 +++++ lib/std/crypto/blake2.zig | 5 +++++ lib/std/crypto/blake3.zig | 5 +++++ lib/std/crypto/chacha20.zig | 5 +++++ lib/std/crypto/gimli.zig | 5 +++++ lib/std/crypto/hmac.zig | 5 +++++ lib/std/crypto/md5.zig | 5 +++++ lib/std/crypto/poly1305.zig | 5 +++++ lib/std/crypto/sha1.zig | 5 +++++ lib/std/crypto/sha2.zig | 5 +++++ lib/std/crypto/sha3.zig | 5 +++++ lib/std/crypto/test.zig | 5 +++++ lib/std/cstr.zig | 5 +++++ lib/std/debug.zig | 5 +++++ lib/std/debug/leb128.zig | 5 +++++ lib/std/dwarf.zig | 5 +++++ lib/std/dwarf_bits.zig | 5 +++++ lib/std/dynamic_library.zig | 5 +++++ lib/std/elf.zig | 5 +++++ lib/std/event.zig | 5 +++++ lib/std/event/batch.zig | 5 +++++ lib/std/event/channel.zig | 5 +++++ lib/std/event/future.zig | 5 +++++ lib/std/event/group.zig | 5 +++++ lib/std/event/lock.zig | 5 +++++ lib/std/event/locked.zig | 5 +++++ lib/std/event/loop.zig | 5 +++++ lib/std/event/rwlock.zig | 5 +++++ lib/std/event/rwlocked.zig | 5 +++++ lib/std/fifo.zig | 5 +++++ lib/std/fmt.zig | 5 +++++ lib/std/fmt/errol.zig | 5 +++++ lib/std/fmt/errol/enum3.zig | 5 +++++ lib/std/fmt/errol/lookup.zig | 5 +++++ lib/std/fmt/parse_float.zig | 5 +++++ lib/std/fs.zig | 5 +++++ lib/std/fs/file.zig | 5 +++++ lib/std/fs/get_app_data_dir.zig | 5 +++++ lib/std/fs/path.zig | 5 +++++ lib/std/fs/test.zig | 5 +++++ lib/std/fs/wasi.zig | 5 +++++ lib/std/fs/watch.zig | 5 +++++ lib/std/hash.zig | 5 +++++ lib/std/hash/adler.zig | 5 +++++ lib/std/hash/auto_hash.zig | 5 +++++ lib/std/hash/benchmark.zig | 5 +++++ lib/std/hash/cityhash.zig | 5 +++++ lib/std/hash/crc.zig | 5 +++++ lib/std/hash/fnv.zig | 5 +++++ lib/std/hash/murmur.zig | 5 +++++ lib/std/hash/siphash.zig | 5 +++++ lib/std/hash/wyhash.zig | 5 +++++ lib/std/hash_map.zig | 5 +++++ lib/std/heap.zig | 5 +++++ lib/std/heap/arena_allocator.zig | 5 +++++ lib/std/heap/general_purpose_allocator.zig | 5 +++++ lib/std/heap/logging_allocator.zig | 5 +++++ lib/std/http.zig | 5 +++++ lib/std/http/headers.zig | 5 +++++ lib/std/io.zig | 5 +++++ lib/std/io/bit_in_stream.zig | 5 +++++ lib/std/io/bit_out_stream.zig | 5 +++++ lib/std/io/bit_reader.zig | 5 +++++ lib/std/io/bit_writer.zig | 5 +++++ lib/std/io/buffered_atomic_file.zig | 5 +++++ lib/std/io/buffered_in_stream.zig | 5 +++++ lib/std/io/buffered_out_stream.zig | 5 +++++ lib/std/io/buffered_reader.zig | 5 +++++ lib/std/io/buffered_writer.zig | 5 +++++ lib/std/io/c_out_stream.zig | 5 +++++ lib/std/io/c_writer.zig | 5 +++++ lib/std/io/counting_out_stream.zig | 5 +++++ lib/std/io/counting_writer.zig | 5 +++++ lib/std/io/fixed_buffer_stream.zig | 5 +++++ lib/std/io/in_stream.zig | 5 +++++ lib/std/io/multi_out_stream.zig | 5 +++++ lib/std/io/multi_writer.zig | 5 +++++ lib/std/io/out_stream.zig | 5 +++++ lib/std/io/peek_stream.zig | 5 +++++ lib/std/io/reader.zig | 5 +++++ lib/std/io/seekable_stream.zig | 5 +++++ lib/std/io/serialization.zig | 5 +++++ lib/std/io/stream_source.zig | 5 +++++ lib/std/io/test.zig | 5 +++++ lib/std/io/writer.zig | 5 +++++ lib/std/json.zig | 5 +++++ lib/std/json/test.zig | 5 +++++ lib/std/json/write_stream.zig | 5 +++++ lib/std/linked_list.zig | 5 +++++ lib/std/log.zig | 5 +++++ lib/std/macho.zig | 5 +++++ lib/std/math.zig | 5 +++++ lib/std/math/acos.zig | 5 +++++ lib/std/math/acosh.zig | 5 +++++ lib/std/math/asin.zig | 5 +++++ lib/std/math/asinh.zig | 5 +++++ lib/std/math/atan.zig | 5 +++++ lib/std/math/atan2.zig | 5 +++++ lib/std/math/atanh.zig | 5 +++++ lib/std/math/big.zig | 5 +++++ lib/std/math/big/int.zig | 5 +++++ lib/std/math/big/int_test.zig | 5 +++++ lib/std/math/big/rational.zig | 5 +++++ lib/std/math/cbrt.zig | 5 +++++ lib/std/math/ceil.zig | 5 +++++ lib/std/math/complex.zig | 5 +++++ lib/std/math/complex/abs.zig | 5 +++++ lib/std/math/complex/acos.zig | 5 +++++ lib/std/math/complex/acosh.zig | 5 +++++ lib/std/math/complex/arg.zig | 5 +++++ lib/std/math/complex/asin.zig | 5 +++++ lib/std/math/complex/asinh.zig | 5 +++++ lib/std/math/complex/atan.zig | 5 +++++ lib/std/math/complex/atanh.zig | 5 +++++ lib/std/math/complex/conj.zig | 5 +++++ lib/std/math/complex/cos.zig | 5 +++++ lib/std/math/complex/cosh.zig | 5 +++++ lib/std/math/complex/exp.zig | 5 +++++ lib/std/math/complex/ldexp.zig | 5 +++++ lib/std/math/complex/log.zig | 5 +++++ lib/std/math/complex/pow.zig | 5 +++++ lib/std/math/complex/proj.zig | 5 +++++ lib/std/math/complex/sin.zig | 5 +++++ lib/std/math/complex/sinh.zig | 5 +++++ lib/std/math/complex/sqrt.zig | 5 +++++ lib/std/math/complex/tan.zig | 5 +++++ lib/std/math/complex/tanh.zig | 5 +++++ lib/std/math/copysign.zig | 5 +++++ lib/std/math/cos.zig | 5 +++++ lib/std/math/cosh.zig | 5 +++++ lib/std/math/exp.zig | 5 +++++ lib/std/math/exp2.zig | 5 +++++ lib/std/math/expm1.zig | 5 +++++ lib/std/math/expo2.zig | 5 +++++ lib/std/math/fabs.zig | 5 +++++ lib/std/math/floor.zig | 5 +++++ lib/std/math/fma.zig | 5 +++++ lib/std/math/frexp.zig | 5 +++++ lib/std/math/hypot.zig | 5 +++++ lib/std/math/ilogb.zig | 5 +++++ lib/std/math/inf.zig | 5 +++++ lib/std/math/isfinite.zig | 5 +++++ lib/std/math/isinf.zig | 5 +++++ lib/std/math/isnan.zig | 5 +++++ lib/std/math/isnormal.zig | 5 +++++ lib/std/math/ln.zig | 5 +++++ lib/std/math/log.zig | 5 +++++ lib/std/math/log10.zig | 5 +++++ lib/std/math/log1p.zig | 5 +++++ lib/std/math/log2.zig | 5 +++++ lib/std/math/modf.zig | 5 +++++ lib/std/math/nan.zig | 5 +++++ lib/std/math/pow.zig | 5 +++++ lib/std/math/powi.zig | 5 +++++ lib/std/math/round.zig | 5 +++++ lib/std/math/scalbn.zig | 5 +++++ lib/std/math/signbit.zig | 5 +++++ lib/std/math/sin.zig | 5 +++++ lib/std/math/sinh.zig | 5 +++++ lib/std/math/sqrt.zig | 5 +++++ lib/std/math/tan.zig | 5 +++++ lib/std/math/tanh.zig | 5 +++++ lib/std/math/trunc.zig | 5 +++++ lib/std/mem.zig | 5 +++++ lib/std/mem/Allocator.zig | 5 +++++ lib/std/meta.zig | 5 +++++ lib/std/meta/trailer_flags.zig | 5 +++++ lib/std/meta/trait.zig | 5 +++++ lib/std/mutex.zig | 5 +++++ lib/std/net.zig | 5 +++++ lib/std/net/test.zig | 5 +++++ lib/std/once.zig | 5 +++++ lib/std/os.zig | 5 +++++ lib/std/os/bits.zig | 5 +++++ lib/std/os/bits/darwin.zig | 5 +++++ lib/std/os/bits/dragonfly.zig | 5 +++++ lib/std/os/bits/freebsd.zig | 5 +++++ lib/std/os/bits/linux.zig | 5 +++++ lib/std/os/bits/linux/arm-eabi.zig | 5 +++++ lib/std/os/bits/linux/arm64.zig | 5 +++++ lib/std/os/bits/linux/bpf.zig | 5 +++++ lib/std/os/bits/linux/errno-generic.zig | 5 +++++ lib/std/os/bits/linux/errno-mips.zig | 5 +++++ lib/std/os/bits/linux/i386.zig | 5 +++++ lib/std/os/bits/linux/mips.zig | 5 +++++ lib/std/os/bits/linux/netlink.zig | 5 +++++ lib/std/os/bits/linux/riscv64.zig | 5 +++++ lib/std/os/bits/linux/x86_64.zig | 5 +++++ lib/std/os/bits/netbsd.zig | 5 +++++ lib/std/os/bits/wasi.zig | 5 +++++ lib/std/os/bits/windows.zig | 5 +++++ lib/std/os/darwin.zig | 5 +++++ lib/std/os/dragonfly.zig | 5 +++++ lib/std/os/freebsd.zig | 5 +++++ lib/std/os/linux.zig | 5 +++++ lib/std/os/linux/arm-eabi.zig | 5 +++++ lib/std/os/linux/arm64.zig | 5 +++++ lib/std/os/linux/i386.zig | 5 +++++ lib/std/os/linux/mips.zig | 5 +++++ lib/std/os/linux/riscv64.zig | 5 +++++ lib/std/os/linux/test.zig | 5 +++++ lib/std/os/linux/tls.zig | 5 +++++ lib/std/os/linux/vdso.zig | 5 +++++ lib/std/os/linux/x86_64.zig | 5 +++++ lib/std/os/netbsd.zig | 5 +++++ lib/std/os/test.zig | 5 +++++ lib/std/os/uefi.zig | 5 +++++ lib/std/os/uefi/protocols.zig | 5 +++++ lib/std/os/uefi/protocols/absolute_pointer_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/device_path_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/edid_active_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/edid_discovered_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/edid_override_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/file_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/graphics_output_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/hii.zig | 5 +++++ lib/std/os/uefi/protocols/hii_database_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/hii_popup_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/ip6_config_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/ip6_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/loaded_image_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/managed_network_protocol.zig | 5 +++++ .../protocols/managed_network_service_binding_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/rng_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/shell_parameters_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_file_system_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_network_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_pointer_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_text_input_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/simple_text_output_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/udp6_protocol.zig | 5 +++++ lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig | 5 +++++ lib/std/os/uefi/status.zig | 5 +++++ lib/std/os/uefi/tables.zig | 5 +++++ lib/std/os/uefi/tables/boot_services.zig | 5 +++++ lib/std/os/uefi/tables/configuration_table.zig | 5 +++++ lib/std/os/uefi/tables/runtime_services.zig | 5 +++++ lib/std/os/uefi/tables/system_table.zig | 5 +++++ lib/std/os/uefi/tables/table_header.zig | 5 +++++ lib/std/os/wasi.zig | 5 +++++ lib/std/os/windows.zig | 5 +++++ lib/std/os/windows/advapi32.zig | 5 +++++ lib/std/os/windows/bits.zig | 5 +++++ lib/std/os/windows/gdi32.zig | 5 +++++ lib/std/os/windows/kernel32.zig | 5 +++++ lib/std/os/windows/lang.zig | 5 +++++ lib/std/os/windows/ntdll.zig | 5 +++++ lib/std/os/windows/ntstatus.zig | 5 +++++ lib/std/os/windows/ole32.zig | 5 +++++ lib/std/os/windows/psapi.zig | 5 +++++ lib/std/os/windows/shell32.zig | 5 +++++ lib/std/os/windows/sublang.zig | 5 +++++ lib/std/os/windows/user32.zig | 5 +++++ lib/std/os/windows/win32error.zig | 5 +++++ lib/std/os/windows/ws2_32.zig | 5 +++++ lib/std/packed_int_array.zig | 5 +++++ lib/std/pdb.zig | 5 +++++ lib/std/priority_queue.zig | 5 +++++ lib/std/process.zig | 5 +++++ lib/std/progress.zig | 5 +++++ lib/std/rand.zig | 5 +++++ lib/std/rand/ziggurat.zig | 5 +++++ lib/std/rb.zig | 5 +++++ lib/std/reset_event.zig | 5 +++++ lib/std/segmented_list.zig | 5 +++++ lib/std/sort.zig | 5 +++++ lib/std/special/build_runner.zig | 5 +++++ lib/std/special/c.zig | 5 +++++ lib/std/special/compiler_rt.zig | 5 +++++ lib/std/special/compiler_rt/addXf3.zig | 5 +++++ lib/std/special/compiler_rt/addXf3_test.zig | 5 +++++ lib/std/special/compiler_rt/arm.zig | 5 +++++ lib/std/special/compiler_rt/ashldi3_test.zig | 5 +++++ lib/std/special/compiler_rt/ashlti3_test.zig | 5 +++++ lib/std/special/compiler_rt/ashrdi3_test.zig | 5 +++++ lib/std/special/compiler_rt/ashrti3_test.zig | 5 +++++ lib/std/special/compiler_rt/atomics.zig | 5 +++++ lib/std/special/compiler_rt/aulldiv.zig | 5 +++++ lib/std/special/compiler_rt/aullrem.zig | 5 +++++ lib/std/special/compiler_rt/clear_cache.zig | 5 +++++ lib/std/special/compiler_rt/clzsi2.zig | 5 +++++ lib/std/special/compiler_rt/clzsi2_test.zig | 5 +++++ lib/std/special/compiler_rt/compareXf2.zig | 5 +++++ lib/std/special/compiler_rt/comparedf2_test.zig | 5 +++++ lib/std/special/compiler_rt/comparesf2_test.zig | 5 +++++ lib/std/special/compiler_rt/divdf3.zig | 5 +++++ lib/std/special/compiler_rt/divdf3_test.zig | 5 +++++ lib/std/special/compiler_rt/divsf3.zig | 5 +++++ lib/std/special/compiler_rt/divsf3_test.zig | 5 +++++ lib/std/special/compiler_rt/divtf3.zig | 5 +++++ lib/std/special/compiler_rt/divtf3_test.zig | 5 +++++ lib/std/special/compiler_rt/divti3.zig | 5 +++++ lib/std/special/compiler_rt/divti3_test.zig | 5 +++++ lib/std/special/compiler_rt/extendXfYf2.zig | 5 +++++ lib/std/special/compiler_rt/extendXfYf2_test.zig | 5 +++++ lib/std/special/compiler_rt/fixdfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixdfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixdfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixdfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixdfti.zig | 5 +++++ lib/std/special/compiler_rt/fixdfti_test.zig | 5 +++++ lib/std/special/compiler_rt/fixint.zig | 5 +++++ lib/std/special/compiler_rt/fixint_test.zig | 5 +++++ lib/std/special/compiler_rt/fixsfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixsfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixsfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixsfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixsfti.zig | 5 +++++ lib/std/special/compiler_rt/fixsfti_test.zig | 5 +++++ lib/std/special/compiler_rt/fixtfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixtfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixtfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixtfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixtfti.zig | 5 +++++ lib/std/special/compiler_rt/fixtfti_test.zig | 5 +++++ lib/std/special/compiler_rt/fixuint.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfti.zig | 5 +++++ lib/std/special/compiler_rt/fixunsdfti_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfti.zig | 5 +++++ lib/std/special/compiler_rt/fixunssfti_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfdi.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfdi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfsi.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfsi_test.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfti.zig | 5 +++++ lib/std/special/compiler_rt/fixunstfti_test.zig | 5 +++++ lib/std/special/compiler_rt/floatdidf.zig | 5 +++++ lib/std/special/compiler_rt/floatdidf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatditf.zig | 5 +++++ lib/std/special/compiler_rt/floatditf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatsiXf.zig | 5 +++++ lib/std/special/compiler_rt/floattidf.zig | 5 +++++ lib/std/special/compiler_rt/floattidf_test.zig | 5 +++++ lib/std/special/compiler_rt/floattisf.zig | 5 +++++ lib/std/special/compiler_rt/floattisf_test.zig | 5 +++++ lib/std/special/compiler_rt/floattitf.zig | 5 +++++ lib/std/special/compiler_rt/floattitf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatundidf.zig | 5 +++++ lib/std/special/compiler_rt/floatundidf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatundisf.zig | 5 +++++ lib/std/special/compiler_rt/floatunditf.zig | 5 +++++ lib/std/special/compiler_rt/floatunditf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatunsidf.zig | 5 +++++ lib/std/special/compiler_rt/floatunsisf.zig | 5 +++++ lib/std/special/compiler_rt/floatunsitf.zig | 5 +++++ lib/std/special/compiler_rt/floatunsitf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatuntidf.zig | 5 +++++ lib/std/special/compiler_rt/floatuntidf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatuntisf.zig | 5 +++++ lib/std/special/compiler_rt/floatuntisf_test.zig | 5 +++++ lib/std/special/compiler_rt/floatuntitf.zig | 5 +++++ lib/std/special/compiler_rt/floatuntitf_test.zig | 5 +++++ lib/std/special/compiler_rt/int.zig | 5 +++++ lib/std/special/compiler_rt/lshrdi3_test.zig | 5 +++++ lib/std/special/compiler_rt/lshrti3_test.zig | 5 +++++ lib/std/special/compiler_rt/modti3.zig | 5 +++++ lib/std/special/compiler_rt/modti3_test.zig | 5 +++++ lib/std/special/compiler_rt/mulXf3.zig | 5 +++++ lib/std/special/compiler_rt/mulXf3_test.zig | 5 +++++ lib/std/special/compiler_rt/muldi3.zig | 5 +++++ lib/std/special/compiler_rt/muldi3_test.zig | 5 +++++ lib/std/special/compiler_rt/mulodi4.zig | 5 +++++ lib/std/special/compiler_rt/mulodi4_test.zig | 5 +++++ lib/std/special/compiler_rt/muloti4.zig | 5 +++++ lib/std/special/compiler_rt/muloti4_test.zig | 5 +++++ lib/std/special/compiler_rt/multi3.zig | 5 +++++ lib/std/special/compiler_rt/multi3_test.zig | 5 +++++ lib/std/special/compiler_rt/negXf2.zig | 5 +++++ lib/std/special/compiler_rt/popcountdi2.zig | 5 +++++ lib/std/special/compiler_rt/popcountdi2_test.zig | 5 +++++ lib/std/special/compiler_rt/shift.zig | 5 +++++ lib/std/special/compiler_rt/stack_probe.zig | 5 +++++ lib/std/special/compiler_rt/truncXfYf2.zig | 5 +++++ lib/std/special/compiler_rt/truncXfYf2_test.zig | 5 +++++ lib/std/special/compiler_rt/udivmod.zig | 5 +++++ lib/std/special/compiler_rt/udivmoddi4_test.zig | 5 +++++ lib/std/special/compiler_rt/udivmodti4.zig | 5 +++++ lib/std/special/compiler_rt/udivmodti4_test.zig | 5 +++++ lib/std/special/compiler_rt/udivti3.zig | 5 +++++ lib/std/special/compiler_rt/umodti3.zig | 5 +++++ lib/std/special/init-exe/build.zig | 5 +++++ lib/std/special/init-exe/src/main.zig | 5 +++++ lib/std/special/init-lib/build.zig | 5 +++++ lib/std/special/init-lib/src/main.zig | 5 +++++ lib/std/special/test_runner.zig | 5 +++++ lib/std/spinlock.zig | 5 +++++ lib/std/start.zig | 5 +++++ lib/std/start_windows_tls.zig | 5 +++++ lib/std/std.zig | 5 +++++ lib/std/target.zig | 5 +++++ lib/std/target/aarch64.zig | 5 +++++ lib/std/target/amdgpu.zig | 5 +++++ lib/std/target/arm.zig | 5 +++++ lib/std/target/avr.zig | 5 +++++ lib/std/target/bpf.zig | 5 +++++ lib/std/target/hexagon.zig | 5 +++++ lib/std/target/mips.zig | 5 +++++ lib/std/target/msp430.zig | 5 +++++ lib/std/target/nvptx.zig | 5 +++++ lib/std/target/powerpc.zig | 5 +++++ lib/std/target/riscv.zig | 5 +++++ lib/std/target/sparc.zig | 5 +++++ lib/std/target/systemz.zig | 5 +++++ lib/std/target/wasm.zig | 5 +++++ lib/std/target/x86.zig | 5 +++++ lib/std/testing.zig | 5 +++++ lib/std/testing/failing_allocator.zig | 5 +++++ lib/std/thread.zig | 5 +++++ lib/std/time.zig | 5 +++++ lib/std/time/epoch.zig | 5 +++++ lib/std/unicode.zig | 5 +++++ lib/std/unicode/throughput_test.zig | 5 +++++ lib/std/valgrind.zig | 5 +++++ lib/std/valgrind/callgrind.zig | 5 +++++ lib/std/valgrind/memcheck.zig | 5 +++++ lib/std/zig.zig | 5 +++++ lib/std/zig/ast.zig | 5 +++++ lib/std/zig/cross_target.zig | 5 +++++ lib/std/zig/parse.zig | 5 +++++ lib/std/zig/parser_test.zig | 5 +++++ lib/std/zig/perf_test.zig | 5 +++++ lib/std/zig/render.zig | 5 +++++ lib/std/zig/string_literal.zig | 5 +++++ lib/std/zig/system.zig | 5 +++++ lib/std/zig/system/macos.zig | 5 +++++ lib/std/zig/system/x86.zig | 5 +++++ lib/std/zig/tokenizer.zig | 5 +++++ test/stack_traces.zig | 6 +++--- 487 files changed, 2433 insertions(+), 3 deletions(-) diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index e064b38566087886b330fcdf4c40ffa0ca8eee24..a7432a30aefe320bcfea5fd203d0b52e4316c2dd 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const debug = std.debug; const assert = debug.assert; diff --git a/lib/std/array_list_sentineled.zig b/lib/std/array_list_sentineled.zig index 828be7462f73c718b98afec82360822ef4842dae..d73367327efba99278ae6df57c1ebca775f29b3a 100644 --- a/lib/std/array_list_sentineled.zig +++ b/lib/std/array_list_sentineled.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const debug = std.debug; const mem = std.mem; diff --git a/lib/std/ascii.zig b/lib/std/ascii.zig index 20bd9e47ebe42d6d846a1a14e08c3dc9a8da8e97..25c34ef0cc0a7b8c57e312ca844232bc45255432 100644 --- a/lib/std/ascii.zig +++ b/lib/std/ascii.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Does NOT look at the locale the way C89's toupper(3), isspace() et cetera does. // I could have taken only a u7 to make this clear, but it would be slower // It is my opinion that encodings other than UTF-8 should not be supported. diff --git a/lib/std/atomic.zig b/lib/std/atomic.zig index 6f7b4fe75d1defdf2ee8d7ecc60cce89398c31d6..c465708ffa75c37b935bbd956e6066161ca713d8 100644 --- a/lib/std/atomic.zig +++ b/lib/std/atomic.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const Stack = @import("atomic/stack.zig").Stack; pub const Queue = @import("atomic/queue.zig").Queue; pub const Int = @import("atomic/int.zig").Int; diff --git a/lib/std/atomic/int.zig b/lib/std/atomic/int.zig index 446059e7ef66723b4d765b7fa213ca752189d756..ae8c8da77803a8e979d75507d980740aeea183a6 100644 --- a/lib/std/atomic/int.zig +++ b/lib/std/atomic/int.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Thread-safe, lock-free integer pub fn Int(comptime T: type) type { return struct { diff --git a/lib/std/atomic/queue.zig b/lib/std/atomic/queue.zig index 4df7522f291219f04fb46712237d111e02ed4a27..dd139106b40360cb9c5ff560a6bf117d3cb3630a 100644 --- a/lib/std/atomic/queue.zig +++ b/lib/std/atomic/queue.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/atomic/stack.zig b/lib/std/atomic/stack.zig index db749ecaaca6fe0ba2cada9b88ade24fd3b9cf74..1e289bae70b395556a30b68843062535bfd4ea57 100644 --- a/lib/std/atomic/stack.zig +++ b/lib/std/atomic/stack.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const assert = std.debug.assert; const builtin = @import("builtin"); const expect = std.testing.expect; diff --git a/lib/std/base64.zig b/lib/std/base64.zig index 39ad811eb68496ae67447183e6d58af642e18570..0b91a1cf0adccefc7e5edb247e976f1b13d56bd1 100644 --- a/lib/std/base64.zig +++ b/lib/std/base64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig index 80e168b8fda42aacf8a0b48f4fee04c438f6f476..34fa42fe00064873349a7ad8c31df5c52c06bcab 100644 --- a/lib/std/bloom_filter.zig +++ b/lib/std/bloom_filter.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); const math = std.math; diff --git a/lib/std/buf_map.zig b/lib/std/buf_map.zig index 5cf4a54ed35138fe4680eba14de0fa72bb02f073..0fb2156c43ee658c89f80f6924f5b67d79f81eb7 100644 --- a/lib/std/buf_map.zig +++ b/lib/std/buf_map.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const StringHashMap = std.StringHashMap; const mem = std.mem; diff --git a/lib/std/buf_set.zig b/lib/std/buf_set.zig index d8a0264bd71fac60a8f9bf93c1189b29d7cf33c8..1f5dda09c27904eed048a569f8bf252b565a7040 100644 --- a/lib/std/buf_set.zig +++ b/lib/std/buf_set.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const StringHashMap = std.StringHashMap; const mem = @import("mem.zig"); diff --git a/lib/std/build.zig b/lib/std/build.zig index be39e8010c7e06f088932b981be5c44f99bcb4c1..1673737bef42afbc579f75187b9b30d8e5196a3b 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/build/check_file.zig b/lib/std/build/check_file.zig index 2d8e58f92caecba7b03c91c31f70132dacea34a3..e1372c0fe9a99622e7e60f7c0fcdc995c8856424 100644 --- a/lib/std/build/check_file.zig +++ b/lib/std/build/check_file.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const build = std.build; const Step = build.Step; diff --git a/lib/std/build/emit_raw.zig b/lib/std/build/emit_raw.zig index 688a50e8fa8eefd13bb98972cb38f30fee7847d8..d499df1817f9d71c93bf5a10554a9d78688d4042 100644 --- a/lib/std/build/emit_raw.zig +++ b/lib/std/build/emit_raw.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const Allocator = std.mem.Allocator; diff --git a/lib/std/build/fmt.zig b/lib/std/build/fmt.zig index 8fb12df8243eb84bd2e2c7106676ff9fd04b06b9..8f0176c00eacd62234d3b626d10a3b95b5529cfc 100644 --- a/lib/std/build/fmt.zig +++ b/lib/std/build/fmt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const build = @import("../build.zig"); const Step = build.Step; diff --git a/lib/std/build/run.zig b/lib/std/build/run.zig index 839e177edd8d96f27ede0364d32c75a72ef68f77..71e0d614f518e3479488d24e79520e2b1a4a75d3 100644 --- a/lib/std/build/run.zig +++ b/lib/std/build/run.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const build = std.build; diff --git a/lib/std/build/translate_c.zig b/lib/std/build/translate_c.zig index 1bc36ba8c46bad079daa8cf08c88423d8868610f..8ca2b872093f08bd55fdf02cf5d178beb37c8a32 100644 --- a/lib/std/build/translate_c.zig +++ b/lib/std/build/translate_c.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const build = std.build; const Step = build.Step; diff --git a/lib/std/build/write_file.zig b/lib/std/build/write_file.zig index ad0e13bed224d05721fe91a9a209cdd3056bcf62..fe15e6e0e30b5d985b0723c9e66b4081e42d73a1 100644 --- a/lib/std/build/write_file.zig +++ b/lib/std/build/write_file.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const build = @import("../build.zig"); const Step = build.Step; diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 49edab1fd738a3b979fe18a1e918ef78f0ad67c8..7f3fcfc96cf90d196885689c23053f2d9701fee6 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub usingnamespace @import("builtin"); /// Deprecated: use `std.Target`. diff --git a/lib/std/c.zig b/lib/std/c.zig index e836a49c30050e5d3b308078e8660c2832567e8a..b4e5fc739201815aa0ed0a7d0545bf3819271e9b 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; const page_size = std.mem.page_size; diff --git a/lib/std/c/ast.zig b/lib/std/c/ast.zig index 467050d57d08ac953d9bad026aaeb5fb781280e2..550ba52b844ae5e90fb8938221a11271a4785ee8 100644 --- a/lib/std/c/ast.zig +++ b/lib/std/c/ast.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const SegmentedList = std.SegmentedList; const Token = std.c.Token; diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 242663856965d4d7a65613497686316fc6684e7a..411aeb80561c3cdedd3abd975dbd6832de5542d3 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const builtin = @import("builtin"); diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig index 0c859018bef0f08de6c4b8d4b5db61fb031b65d0..2550cacc5bdefed798486de62c519957dbb74877 100644 --- a/lib/std/c/dragonfly.zig +++ b/lib/std/c/dragonfly.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); usingnamespace std.c; extern "c" threadlocal var errno: c_int; diff --git a/lib/std/c/emscripten.zig b/lib/std/c/emscripten.zig index e91e1421c7e3cb83d00c3ae7deb54f3eee42c919..e94a6f1004c4d1f46b8faa1e19293fd7576c65fe 100644 --- a/lib/std/c/emscripten.zig +++ b/lib/std/c/emscripten.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(4) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T, }; diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index ea52c05f0bcfee852f4a9d5b8e3a907eeb495035..1545a0e153de4ee80cbdd4382a4fe2ef80452ad1 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); usingnamespace std.c; diff --git a/lib/std/c/fuchsia.zig b/lib/std/c/fuchsia.zig index 4f52b8900d576bc10669c818e255b4ad80698b13..ceeb34a7636740555c898001556e3698ec7ea6e1 100644 --- a/lib/std/c/fuchsia.zig +++ b/lib/std/c/fuchsia.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T, }; diff --git a/lib/std/c/haiku.zig b/lib/std/c/haiku.zig index eb1e52a6184d313ac42cf6bfcd691add475e8667..6b56e163c86bc805ee548311d3bd3f07dff8c1bb 100644 --- a/lib/std/c/haiku.zig +++ b/lib/std/c/haiku.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { flags: u32 = 0, lock: i32 = 0, diff --git a/lib/std/c/hermit.zig b/lib/std/c/hermit.zig index 1730aa43ac18874491038d1d732b6d5d6d892ef5..6762e609621465a11cce6d5bed798f7fb5e42b0a 100644 --- a/lib/std/c/hermit.zig +++ b/lib/std/c/hermit.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { inner: usize = ~@as(usize, 0), }; diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index b9f29b211dd1998f12c118447c60b501f4815d72..538fbdfd7df5f033617041979c872caa7e8d6563 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("../std.zig"); const maxInt = std.math.maxInt; diff --git a/lib/std/c/minix.zig b/lib/std/c/minix.zig index 98ec087a933f5d1250ee9da0270df90c9c157ea3..2bc1bac47a062d62d91e267393abffb8cfd1bf39 100644 --- a/lib/std/c/minix.zig +++ b/lib/std/c/minix.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); pub const pthread_mutex_t = extern struct { size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T, diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index 31adbb1f59dcbafaf87d45a15024d2b5324f6a6a..0eb8e32bae9579dc958c89812267c4c987ede57d 100644 --- a/lib/std/c/netbsd.zig +++ b/lib/std/c/netbsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index 22963b08c33e5c09275f605c80f5cb7db660ab42..8a6439fc8341a3a1a2af56706ca7dbc710a49fff 100644 --- a/lib/std/c/openbsd.zig +++ b/lib/std/c/openbsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { inner: ?*c_void = null, }; diff --git a/lib/std/c/parse.zig b/lib/std/c/parse.zig index 4c6c2fb46218b0c2c1da41c7821d190744146e27..d5b1a4a01e88ba63f416a7b2584eebfa7834fcb1 100644 --- a/lib/std/c/parse.zig +++ b/lib/std/c/parse.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; const assert = std.debug.assert; diff --git a/lib/std/c/solaris.zig b/lib/std/c/solaris.zig index 7c70a01fc4ac1c9281c6ad6476c61d959ddb2889..49ce0886f7d44e34c7a25796d18a05c61d3542d9 100644 --- a/lib/std/c/solaris.zig +++ b/lib/std/c/solaris.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const pthread_mutex_t = extern struct { __pthread_mutex_flag1: u16 = 0, __pthread_mutex_flag2: u8 = 0, diff --git a/lib/std/c/tokenizer.zig b/lib/std/c/tokenizer.zig index a3e6710e2fe3ced56c1777c3ab60163548549222..9e9b5f414776025a6695e84396556c6dd7ca08c3 100644 --- a/lib/std/c/tokenizer.zig +++ b/lib/std/c/tokenizer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; diff --git a/lib/std/c/windows.zig b/lib/std/c/windows.zig index 35ca2171318353bb4d78ce9fa812650aef778d7c..cd3932419215716bf37e86489c0ea24751ce3a91 100644 --- a/lib/std/c/windows.zig +++ b/lib/std/c/windows.zig @@ -1 +1,6 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub extern "c" fn _errno() *c_int; diff --git a/lib/std/cache_hash.zig b/lib/std/cache_hash.zig index 79597a266386fd19b0f0d6129bd724d516533283..58c9f444f31ae252603f3e30b70b596d3af8bf02 100644 --- a/lib/std/cache_hash.zig +++ b/lib/std/cache_hash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const Blake3 = std.crypto.Blake3; const fs = std.fs; diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 5754cc2d532b8729f368a0b40794f0848503d495..3254b958b7d09257b01ac4615edcff356c7e289d 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const cstr = std.cstr; const unicode = std.unicode; diff --git a/lib/std/coff.zig b/lib/std/coff.zig index 1ab88f6baffdfa2c64cdff189f3f61efd92fbf3d..cd567b3a6ecd3ac7532ad7c45197c539b2294473 100644 --- a/lib/std/coff.zig +++ b/lib/std/coff.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); const io = std.io; diff --git a/lib/std/comptime_string_map.zig b/lib/std/comptime_string_map.zig index 8cc5cac130a0e86957f86f276be6bddc38d73424..ed647124a8fc477881f9b0866c3075db75462e2d 100644 --- a/lib/std/comptime_string_map.zig +++ b/lib/std/comptime_string_map.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const mem = std.mem; diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index c1909a18239a636b9a32aacc5fad8ee92c6586a3..edca2bc2ff4775368aa75c8ba8d5b914865bca11 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const Md5 = @import("crypto/md5.zig").Md5; pub const Sha1 = @import("crypto/sha1.zig").Sha1; diff --git a/lib/std/crypto/25519/curve25519.zig b/lib/std/crypto/25519/curve25519.zig index 46d7b9a3a6892a19a6865ac9970454279197b335..94490f674c1db550e26471191dcde5461710a1ad 100644 --- a/lib/std/crypto/25519/curve25519.zig +++ b/lib/std/crypto/25519/curve25519.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); /// Group operations over Curve25519. diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig index eb004d2607394313aa15fb367e1c40f77f8f90b5..935abaecb39def38927e317f2b9a7b32537b1208 100644 --- a/lib/std/crypto/25519/ed25519.zig +++ b/lib/std/crypto/25519/ed25519.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const fmt = std.fmt; const mem = std.mem; diff --git a/lib/std/crypto/25519/edwards25519.zig b/lib/std/crypto/25519/edwards25519.zig index 11f59631016cd494fe001e1642904ec266dbd412..176e5337da0b4bc0cd91ed1762ea8a7cd1d5133e 100644 --- a/lib/std/crypto/25519/edwards25519.zig +++ b/lib/std/crypto/25519/edwards25519.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const fmt = std.fmt; diff --git a/lib/std/crypto/25519/field.zig b/lib/std/crypto/25519/field.zig index 85b8c683156ef087a105fb0582475fea2bba218d..61929ba04422f21add5c253c8d765d408cc01903 100644 --- a/lib/std/crypto/25519/field.zig +++ b/lib/std/crypto/25519/field.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const readIntLittle = std.mem.readIntLittle; const writeIntLittle = std.mem.writeIntLittle; diff --git a/lib/std/crypto/25519/ristretto255.zig b/lib/std/crypto/25519/ristretto255.zig index a9636074a63ba480213ccda35b17eb1681827a2f..4e6494ed3861d24915f742502b5e77db65bfa971 100644 --- a/lib/std/crypto/25519/ristretto255.zig +++ b/lib/std/crypto/25519/ristretto255.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const fmt = std.fmt; diff --git a/lib/std/crypto/25519/scalar.zig b/lib/std/crypto/25519/scalar.zig index 3a3a29d4bc2836eca42fc521d1477163b90e3db7..2658126eeb9f79dfb773969ddbe5b8c2ee32ecfe 100644 --- a/lib/std/crypto/25519/scalar.zig +++ b/lib/std/crypto/25519/scalar.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; diff --git a/lib/std/crypto/25519/x25519.zig b/lib/std/crypto/25519/x25519.zig index 4b5a8b8482662eba6690584c77cca5493e1305cd..913140657d81c3653a1b73527f4a0fb814868e91 100644 --- a/lib/std/crypto/25519/x25519.zig +++ b/lib/std/crypto/25519/x25519.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; const fmt = std.fmt; diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig index 25070b3a44901e04c44115bac18e4379876a6d9a..2174fbdd4ffd372ad7d00bd385650970f637b46a 100644 --- a/lib/std/crypto/aes.zig +++ b/lib/std/crypto/aes.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Based on Go stdlib implementation const std = @import("../std.zig"); diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 267c2881b4209da2148bddb95c2b2a24159d7731..5c27f2f4f5374f75e6ad5c603c7911fb741def1e 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // zig run benchmark.zig --release-fast --override-lib-dir .. const builtin = @import("builtin"); diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index ab44ca5298633205ead0cd54f3da3c1cea383d90..9f5194994deb73ba9b927db0b7d746185f6589bc 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const mem = @import("../mem.zig"); const builtin = @import("builtin"); const debug = @import("../debug.zig"); diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 08479d65a54b9bac044e1aff84265fa4ab9be011..08986965fc4a58b9d62adefbe23419bcff13ee9a 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Translated from BLAKE3 reference implementation. // Source: https://github.com/BLAKE3-team/BLAKE3 diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index e51123eb81ff326b77d608d7ae17fa15f43952dc..d402eb67505c855da37c00f8ff1b96d91c55fd03 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Based on public domain Supercop by Daniel J. Bernstein const std = @import("../std.zig"); diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index 6861c72a6337e4c06a553f18b52b4503c541be27..33afae5f82c5a311da4f677b18191f214ce0fc8c 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Gimli is a 384-bit permutation designed to achieve high security with high // performance across a broad range of platforms, including 64-bit Intel/AMD // server CPUs, 64-bit and 32-bit ARM smartphone CPUs, 32-bit ARM diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 69c1b86386cb362fd5c58b0e5eb32b2814d1dcad..984dacc96783e799595e14fb5abc6d6a0e4f1eac 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const crypto = std.crypto; const debug = std.debug; diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index ac8948ca20a5fe7ca81572d2c90ddd8b23b0d201..d578ba8b957b6e0dc47358ecc81cdf5251c7e30d 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const mem = @import("../mem.zig"); const math = @import("../math.zig"); const endian = @import("../endian.zig"); diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index fda978307d280c7cdb4fa4ba76a7267501b2b673..2ed97f4c2e2b96cdb20cdec97e06bdc753290a47 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Translated from monocypher which is licensed under CC-0/BSD-3. // // https://monocypher.org/ diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index 6edf7b745e1d9b312e9918b5c8c8dcbab915357d..7cb4fbcf36becff4ae793f2223abd884053c216b 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const mem = @import("../mem.zig"); const math = @import("../math.zig"); const endian = @import("../endian.zig"); diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index f004bceac3bd4f5733c51ae97dec29f4b2023ff7..cac18ca1f7b0f6e2faa90cdc19a3c927ba7002db 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const mem = @import("../mem.zig"); const math = @import("../math.zig"); const endian = @import("../endian.zig"); diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 7c60674d7594b8364f5a2e755bc9dcab31103596..03635ca55378345371d049f4bbad4f8a23007e5b 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const mem = @import("../mem.zig"); const math = @import("../math.zig"); const endian = @import("../endian.zig"); diff --git a/lib/std/crypto/test.zig b/lib/std/crypto/test.zig index 61260c7e39a55faadc44f5c55a3e060969434454..e4e34e543b95f2732df65c61afdbaa3b91757898 100644 --- a/lib/std/crypto/test.zig +++ b/lib/std/crypto/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const testing = std.testing; const mem = std.mem; diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index 9cb16b0ed31746495b1d4da7a65bfc2962d321a2..4e11ad920183946ab4975762e2a1bdee739952ac 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const debug = std.debug; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index fb1c3a3a88680eae28ebe98a8f1986161ca79608..be57c0b2fd67fbf2e124ed17fafaeb0013284147 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const math = std.math; diff --git a/lib/std/debug/leb128.zig b/lib/std/debug/leb128.zig index 7f43fdf49414b9ed30bd3d598a13c28ef3d0b19c..eca777c1cf425e8a42f7d549c4cd084843acf6b4 100644 --- a/lib/std/debug/leb128.zig +++ b/lib/std/debug/leb128.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const testing = std.testing; diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 085e394a8fd9f7bf758a75d53110f411d436d415..37b76b1c14bf575d7be1623aeeb2fd5612d0946d 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const debug = std.debug; diff --git a/lib/std/dwarf_bits.zig b/lib/std/dwarf_bits.zig index a40fa8a2777312dd2447b2620124f0abdea1f48c..bf9c97154cbcda2deffa8d4630c741de913c1de5 100644 --- a/lib/std/dwarf_bits.zig +++ b/lib/std/dwarf_bits.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const TAG_padding = 0x00; pub const TAG_array_type = 0x01; pub const TAG_class_type = 0x02; diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 65c65292bc08f788323f51e17049d667f85368f6..238854f07f88e92f51c0996bbb36bc3bc6784e51 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); diff --git a/lib/std/elf.zig b/lib/std/elf.zig index a241ef9537fd906b8aac9b46ca7351c9777d8f20..79303e71635f67d020ed30b22598f2ba3a653aa5 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/event.zig b/lib/std/event.zig index d042e2ad9b3247102bb7c9a2ba62e16646df4463..42f3176a1b2f307e2376a869ac64ac31971a50ba 100644 --- a/lib/std/event.zig +++ b/lib/std/event.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const Channel = @import("event/channel.zig").Channel; pub const Future = @import("event/future.zig").Future; pub const Group = @import("event/group.zig").Group; diff --git a/lib/std/event/batch.zig b/lib/std/event/batch.zig index 8f2954d85bc205af7696341117cc76f0e4c7bf57..2ace2f791437669c760d78cea52e7af4527e200e 100644 --- a/lib/std/event/batch.zig +++ b/lib/std/event/batch.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const testing = std.testing; diff --git a/lib/std/event/channel.zig b/lib/std/event/channel.zig index 5aef0bb3ba8b78587702d6683ca14c8dfd48cc6e..de5b2c67ab09e78c2576a039ca9cdcfe500fb030 100644 --- a/lib/std/event/channel.zig +++ b/lib/std/event/channel.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/event/future.zig b/lib/std/event/future.zig index 5de22c574c409191b89e0cf409f9beca0d647676..c9777288e4bc25c7d22c1031ef1e65f7bce8e071 100644 --- a/lib/std/event/future.zig +++ b/lib/std/event/future.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/event/group.zig b/lib/std/event/group.zig index 0dc6550218267e99724ef08bdb052ccea7b7c357..e91adbbe8c3b41e41028b78f77acb7ed867c8f0f 100644 --- a/lib/std/event/group.zig +++ b/lib/std/event/group.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const Lock = std.event.Lock; diff --git a/lib/std/event/lock.zig b/lib/std/event/lock.zig index 179b881c9cf306fbd50140e710ccaab7fff1f89d..d27a12aef88de6b71a92566912db39e6db3f576f 100644 --- a/lib/std/event/lock.zig +++ b/lib/std/event/lock.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/event/locked.zig b/lib/std/event/locked.zig index e921803447c4740bea1a921b7950d29d00dac928..9a53116fd66974ef2d4e302be11a13d528a7ba91 100644 --- a/lib/std/event/locked.zig +++ b/lib/std/event/locked.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const Lock = std.event.Lock; diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 0abcad32e1d94ba1f88fcf46bb05facf06951674..b34ad8c940bd9c82f17565053f06638953e73753 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const root = @import("root"); diff --git a/lib/std/event/rwlock.zig b/lib/std/event/rwlock.zig index 7a47c27dd81e96c36fbbb184fc70823d1964a2ec..3e3928d379f9bda819752bbceb1ce8688e7137e4 100644 --- a/lib/std/event/rwlock.zig +++ b/lib/std/event/rwlock.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/event/rwlocked.zig b/lib/std/event/rwlocked.zig index 9a569e8f1f97b44430fa976c1ae9fd752339fddb..4fb25b59a11a11cff3932f34bb83f16079d26253 100644 --- a/lib/std/event/rwlocked.zig +++ b/lib/std/event/rwlocked.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const RwLock = std.event.RwLock; diff --git a/lib/std/fifo.zig b/lib/std/fifo.zig index 1edb413f47abdf3663675628f912fb91ef03905b..c92da615f91a98ad743737ba3f51a5faa6165499 100644 --- a/lib/std/fifo.zig +++ b/lib/std/fifo.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // FIFO of fixed size items // Usually used for e.g. byte buffers diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 6dbef5db67fe902f317298223e419e0320fc52de..16d0eaa07a3f8054a4b086a5b116820f9d29ea42 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const math = std.math; const assert = std.debug.assert; diff --git a/lib/std/fmt/errol.zig b/lib/std/fmt/errol.zig index e697b7d42fa2f62bc7a3be13de6948290af6b62b..6a0a2256d84a21d3391953afb7c14a6818f189a1 100644 --- a/lib/std/fmt/errol.zig +++ b/lib/std/fmt/errol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const enum3 = @import("errol/enum3.zig").enum3; const enum3_data = @import("errol/enum3.zig").enum3_data; diff --git a/lib/std/fmt/errol/enum3.zig b/lib/std/fmt/errol/enum3.zig index c27753483d168ce07c0f79b64f6e310e9d76b3fd..9dbe27c07250d5f799eb76289c75bfc95ac4b262 100644 --- a/lib/std/fmt/errol/enum3.zig +++ b/lib/std/fmt/errol/enum3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const enum3 = [_]u64{ 0x4e2e2785c3a2a20b, 0x240a28877a09a4e1, diff --git a/lib/std/fmt/errol/lookup.zig b/lib/std/fmt/errol/lookup.zig index 2fb6b167bb49c1eccd28bd95700e2e075f4e0bae..85a4234bcad2e880d867c01cb3d7901057b5be22 100644 --- a/lib/std/fmt/errol/lookup.zig +++ b/lib/std/fmt/errol/lookup.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const HP = struct { val: f64, off: f64, diff --git a/lib/std/fmt/parse_float.zig b/lib/std/fmt/parse_float.zig index 2ab245043c6907ebf467eea411c336c47aece489..69557714f6d482a0bc6d263dde9e171dd8b29c63 100644 --- a/lib/std/fmt/parse_float.zig +++ b/lib/std/fmt/parse_float.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Adapted from https://github.com/grzegorz-kraszewski/stringtofloat. // MIT License diff --git a/lib/std/fs.zig b/lib/std/fs.zig index a492a43499e55f9fc90459ed8f3441523d6e7ce8..df368e070bfb5632d89b814b4a26d36e08fb4bbe 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); const os = std.os; diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index ce71571c9fdcb10f44921daa85af95a56f663986..3e22528ea991b0021819f43e56ba700b73208ca9 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const os = std.os; diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig index c68232d0b5eaa3700396a57bc550514d5f3f8fe3..17d365f68439f8d9bd173855283b5a80c1b912af 100644 --- a/lib/std/fs/get_app_data_dir.zig +++ b/lib/std/fs/get_app_data_dir.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const unicode = std.unicode; diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 2176498feb938cf7f0f9008755bbb331097b1a30..5e418e8e5cc787bfde80e52b41e64cdaf236cec6 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("../std.zig"); const debug = std.debug; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 9e6f4bb3ac746a2940d076e6e11c9bcd06655243..4be64ef225c65a37f4eb16596f82fd22caf50590 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const testing = std.testing; const builtin = std.builtin; diff --git a/lib/std/fs/wasi.zig b/lib/std/fs/wasi.zig index 149ede252d5ca1a3732de458f03c2512691852ed..cad86e2314eb475d7ddc81ed3a090a7f27bd6539 100644 --- a/lib/std/fs/wasi.zig +++ b/lib/std/fs/wasi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const os = std.os; const mem = std.mem; diff --git a/lib/std/fs/watch.zig b/lib/std/fs/watch.zig index 635818b70226005c8269cd668c3296ad9e01dd93..269cdec6d8ebc773de5e302a8de35e8177742a34 100644 --- a/lib/std/fs/watch.zig +++ b/lib/std/fs/watch.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = @import("builtin"); const event = std.event; diff --git a/lib/std/hash.zig b/lib/std/hash.zig index c51353b328fdec14e4d068896b0a08541d1d19e8..1cc078959cc9bdefea43a1fe5a3481b77b7c67ff 100644 --- a/lib/std/hash.zig +++ b/lib/std/hash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const adler = @import("hash/adler.zig"); pub const Adler32 = adler.Adler32; diff --git a/lib/std/hash/adler.zig b/lib/std/hash/adler.zig index 173a07596c0cb89c70f9fe5226af4a3b3aef25bf..a3fc915f7640f9940ace731ca41ce8e9bf656b12 100644 --- a/lib/std/hash/adler.zig +++ b/lib/std/hash/adler.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Adler32 checksum. // // https://tools.ietf.org/html/rfc1950#section-9 diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig index 996d6ede388cbef99d8b7bf74d0057c87b8279db..2905a6af13a80eb3ccca23ca3052ff46da8b7389 100644 --- a/lib/std/hash/auto_hash.zig +++ b/lib/std/hash/auto_hash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/hash/benchmark.zig b/lib/std/hash/benchmark.zig index 5f8a15831c3fefd7cbf704d5da29155e8b971b82..c23743160b684deb9aa347bf3ac8aab18c9d13ea 100644 --- a/lib/std/hash/benchmark.zig +++ b/lib/std/hash/benchmark.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // zig run benchmark.zig --release-fast --override-lib-dir .. const builtin = @import("builtin"); diff --git a/lib/std/hash/cityhash.zig b/lib/std/hash/cityhash.zig index 73b94acbd2b14a36c62a8beeb4da61e0d8044c6d..38e62d88efee39eba0bf80a6a6585cff1c6bc26d 100644 --- a/lib/std/hash/cityhash.zig +++ b/lib/std/hash/cityhash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); diff --git a/lib/std/hash/crc.zig b/lib/std/hash/crc.zig index 506d8c8aed13f4b273d7a18bcd44486d9cf1a179..37695df8b3de801b9d5e21d5f95e311eb4dd47eb 100644 --- a/lib/std/hash/crc.zig +++ b/lib/std/hash/crc.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // There are two implementations of CRC32 implemented with the following key characteristics: // // - Crc32WithPoly uses 8Kb of tables but is ~10x faster than the small method. diff --git a/lib/std/hash/fnv.zig b/lib/std/hash/fnv.zig index 8094134e193e5d9588f67040ce569080eb50b185..81285be9a888e26e91a9371281d6d523d6239424 100644 --- a/lib/std/hash/fnv.zig +++ b/lib/std/hash/fnv.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // FNV1a - Fowler-Noll-Vo hash function // // FNV1a is a fast, non-cryptographic hash function with fairly good distribution properties. diff --git a/lib/std/hash/murmur.zig b/lib/std/hash/murmur.zig index effa13ad690912f7e5993ba39af4516be9129f68..d4204509c19d4be490afae345273d86739987e26 100644 --- a/lib/std/hash/murmur.zig +++ b/lib/std/hash/murmur.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); const testing = std.testing; diff --git a/lib/std/hash/siphash.zig b/lib/std/hash/siphash.zig index ebafdd68554d9f5192e1b84adc3737306f27141f..107ea197280a13cd6eefbd21fd7d0af38d7bcbb2 100644 --- a/lib/std/hash/siphash.zig +++ b/lib/std/hash/siphash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Siphash // // SipHash is a moderately fast, non-cryptographic keyed hash function designed for resistance diff --git a/lib/std/hash/wyhash.zig b/lib/std/hash/wyhash.zig index ed2f03350c237481102d254aba3296a776efae1e..12b400c38f6417cc47da7b4e4065d3d97422ec95 100644 --- a/lib/std/hash/wyhash.zig +++ b/lib/std/hash/wyhash.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index d52a337422b11348ad4c63410168cc1afb9bd061..8966737a0c78c17ce7d6daa080ad3249d2de5c8e 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const debug = std.debug; const assert = debug.assert; diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 4a2837d40868039c08ca258c634ebe57426df036..d6977f2f9c3a4c0abe775fe6479f409955492784 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const root = @import("root"); const debug = std.debug; diff --git a/lib/std/heap/arena_allocator.zig b/lib/std/heap/arena_allocator.zig index 191f0c19e92ef1452f688c20d4291d54610a856f..e4bce8087f88f7bb2b225d4738d943783c674f2c 100644 --- a/lib/std/heap/arena_allocator.zig +++ b/lib/std/heap/arena_allocator.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const mem = std.mem; diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index cb53af113e1c977321107bd2e6b832c0d387cfe3..5d8de5845d22dc5d39aad2e24260f26ed72d4c97 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. //! # General Purpose Allocator //! //! ## Design Priorities diff --git a/lib/std/heap/logging_allocator.zig b/lib/std/heap/logging_allocator.zig index eff20a5c462038b6f88b2422cc7011d8951968ab..0e3e460b89371eceb7592fce1f6644710dd18149 100644 --- a/lib/std/heap/logging_allocator.zig +++ b/lib/std/heap/logging_allocator.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const Allocator = std.mem.Allocator; diff --git a/lib/std/http.zig b/lib/std/http.zig index acb005a75fcb447702a899b9ae1593a5aed45e70..2b8495db712f679fc4564fde71f9f8a269943f0f 100644 --- a/lib/std/http.zig +++ b/lib/std/http.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. test "std.http" { _ = @import("http/headers.zig"); } diff --git a/lib/std/http/headers.zig b/lib/std/http/headers.zig index 86aff5f36443804af3c2303ecebf19ad86a5355c..8c80af512f3fdc6acc233698cd0058ec41a9a1db 100644 --- a/lib/std/http/headers.zig +++ b/lib/std/http/headers.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // HTTP Header data structure/type // Based on lua-http's http.header module // diff --git a/lib/std/io.zig b/lib/std/io.zig index 6d613b514a2c3125369785d79538309634be7bea..e30ed1fa9281de35f5d2430468cfa53ca4ac239c 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const root = @import("root"); diff --git a/lib/std/io/bit_in_stream.zig b/lib/std/io/bit_in_stream.zig index 7759927e6d3a2897f036454bbfedf3c4d4768085..a027deb802d91e8b79a86d4b1891c483bd48c0d7 100644 --- a/lib/std/io/bit_in_stream.zig +++ b/lib/std/io/bit_in_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.bit_reader.BitReader` pub const BitInStream = @import("./bit_reader.zig").BitReader; diff --git a/lib/std/io/bit_out_stream.zig b/lib/std/io/bit_out_stream.zig index 20a3795d5908ff15505495495714bc57f962b671..171fb542da1ce7c99f56fadd5385c3a52d05ed62 100644 --- a/lib/std/io/bit_out_stream.zig +++ b/lib/std/io/bit_out_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.bit_writer.BitWriter` pub const BitOutStream = @import("./bit_writer.zig").BitWriter; diff --git a/lib/std/io/bit_reader.zig b/lib/std/io/bit_reader.zig index fbdf7fbe78c4234d2e8fea1ff860ead19ac8695e..4ea2ed75a066fac8fc835c7a8efd504b0694e51c 100644 --- a/lib/std/io/bit_reader.zig +++ b/lib/std/io/bit_reader.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/io/bit_writer.zig b/lib/std/io/bit_writer.zig index 7c1d3e5dba94493f06ba9187e56d59ae81a9fc50..de95e5440427de2b9642d147e78678228e4a3bb0 100644 --- a/lib/std/io/bit_writer.zig +++ b/lib/std/io/bit_writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/io/buffered_atomic_file.zig b/lib/std/io/buffered_atomic_file.zig index 3a3deb43bf2b61a9ad26440a5c4aa909c0b6cc84..6284d4e44fca35c9f95c580a9e128175b264d478 100644 --- a/lib/std/io/buffered_atomic_file.zig +++ b/lib/std/io/buffered_atomic_file.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const mem = std.mem; const fs = std.fs; diff --git a/lib/std/io/buffered_in_stream.zig b/lib/std/io/buffered_in_stream.zig index 42ec0a5d6a16b991753970cd30c1dd7d253d00fd..f055978152de8daa66270a7e5b17a4678942911c 100644 --- a/lib/std/io/buffered_in_stream.zig +++ b/lib/std/io/buffered_in_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.buffered_reader.BufferedReader` pub const BufferedInStream = @import("./buffered_reader.zig").BufferedReader; diff --git a/lib/std/io/buffered_out_stream.zig b/lib/std/io/buffered_out_stream.zig index 6f9efa9575d330b72dac730fc348ae3c3c529878..5f1eaa6fafb988ee36ec5beb6e6c1f1434611380 100644 --- a/lib/std/io/buffered_out_stream.zig +++ b/lib/std/io/buffered_out_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.buffered_writer.BufferedWriter` pub const BufferedOutStream = @import("./buffered_writer.zig").BufferedWriter; diff --git a/lib/std/io/buffered_reader.zig b/lib/std/io/buffered_reader.zig index 73d74b465f5d08cdaefdde74e5e546a55ed8eaeb..58c4f3b4fc734dd79cec6f972ca92cf6fa5224a6 100644 --- a/lib/std/io/buffered_reader.zig +++ b/lib/std/io/buffered_reader.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const assert = std.debug.assert; diff --git a/lib/std/io/buffered_writer.zig b/lib/std/io/buffered_writer.zig index a970f899d63d8461c5abb59644f16f200d30c287..bee3ff48aff7157ce60b66c0e485131075e6059b 100644 --- a/lib/std/io/buffered_writer.zig +++ b/lib/std/io/buffered_writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; diff --git a/lib/std/io/c_out_stream.zig b/lib/std/io/c_out_stream.zig index e10795ae0a04156dd7f57f2ed0a118219815c4df..69f4d9f5af43ceb413552027be3a57684040f542 100644 --- a/lib/std/io/c_out_stream.zig +++ b/lib/std/io/c_out_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.c_writer.CWriter` pub const COutStream = @import("./c_writer.zig").CWriter; diff --git a/lib/std/io/c_writer.zig b/lib/std/io/c_writer.zig index 6292450223fce541aa708d7cac1c41cc34e924a0..9fd10d827e91f4ac206e69e1a8c37c3a1dc3ab45 100644 --- a/lib/std/io/c_writer.zig +++ b/lib/std/io/c_writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/io/counting_out_stream.zig b/lib/std/io/counting_out_stream.zig index 5b0b35b4c5615ed9d79d7af480d395c90aea854f..fecdf8adb0bc5e6788d76fb6941b0259aa639cec 100644 --- a/lib/std/io/counting_out_stream.zig +++ b/lib/std/io/counting_out_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.counting_writer.CountingWriter` pub const CountingOutStream = @import("./counting_writer.zig").CountingWriter; diff --git a/lib/std/io/counting_writer.zig b/lib/std/io/counting_writer.zig index c0cd53c7eed15cd264f113734a07494dca29f4e3..aefd459b90cfb46448e94b8aefc8c20206241e3a 100644 --- a/lib/std/io/counting_writer.zig +++ b/lib/std/io/counting_writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const testing = std.testing; diff --git a/lib/std/io/fixed_buffer_stream.zig b/lib/std/io/fixed_buffer_stream.zig index 32625f3b7afd3f0fae659af2d8926e4e9b73f4f3..b1d2aaf89a3eaf237ae47513f97808b9ed28ef97 100644 --- a/lib/std/io/fixed_buffer_stream.zig +++ b/lib/std/io/fixed_buffer_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const testing = std.testing; diff --git a/lib/std/io/in_stream.zig b/lib/std/io/in_stream.zig index c58f5d7b7723a92edb73f305e5b0c17477bf76ec..4583591d42d9f5de716988af0546743457847c99 100644 --- a/lib/std/io/in_stream.zig +++ b/lib/std/io/in_stream.zig @@ -1,2 +1,7 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.reader.Reader` pub const InStream = @import("./reader.zig").Reader; diff --git a/lib/std/io/multi_out_stream.zig b/lib/std/io/multi_out_stream.zig index fa7a60de51e0507ede9a7435c5054ddbba8d4e1e..7b96cc3d152b400f22c02e5ba0ed5ff1a4998dce 100644 --- a/lib/std/io/multi_out_stream.zig +++ b/lib/std/io/multi_out_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.multi_writer.MultiWriter` pub const MultiOutStream = @import("./multi_writer.zig").MultiWriter; diff --git a/lib/std/io/multi_writer.zig b/lib/std/io/multi_writer.zig index e63940bff7f151f10f6d23e66763fc14352312aa..7ee43eddebba83d9ab000e6e71c8c156cd2dd7c3 100644 --- a/lib/std/io/multi_writer.zig +++ b/lib/std/io/multi_writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const testing = std.testing; diff --git a/lib/std/io/out_stream.zig b/lib/std/io/out_stream.zig index a3fe3e32b5609d84db143f054e68e85eba7709c8..c937ccf16a10dd984aa317cfe4566918b8d3c774 100644 --- a/lib/std/io/out_stream.zig +++ b/lib/std/io/out_stream.zig @@ -1,2 +1,7 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Deprecated: use `std.io.writer.Writer` pub const OutStream = @import("./writer.zig").Writer; diff --git a/lib/std/io/peek_stream.zig b/lib/std/io/peek_stream.zig index 08e940c6ecbbb0dce197c649b2d159c7df6a2966..82554d05ca89f3a70a75774cbf5cc501e72c1833 100644 --- a/lib/std/io/peek_stream.zig +++ b/lib/std/io/peek_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const mem = std.mem; diff --git a/lib/std/io/reader.zig b/lib/std/io/reader.zig index 4c682e8abaf80d8cef5eb2b100b5217f8a199046..07327a431d888f3cdd2d70ea92dbd8da469c5298 100644 --- a/lib/std/io/reader.zig +++ b/lib/std/io/reader.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const math = std.math; diff --git a/lib/std/io/seekable_stream.zig b/lib/std/io/seekable_stream.zig index 1aa653dbe52cc6297c94b0422c35c74b46515b6c..15e537baa2b0f2c4ce5b12456c1289cd98877384 100644 --- a/lib/std/io/seekable_stream.zig +++ b/lib/std/io/seekable_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); pub fn SeekableStream( diff --git a/lib/std/io/serialization.zig b/lib/std/io/serialization.zig index 317dde6417122b3157011e38f3baebf196549ea0..4f8c149b471c25f54b60ece157cc8b8a9e6ab5b7 100644 --- a/lib/std/io/serialization.zig +++ b/lib/std/io/serialization.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/io/stream_source.zig b/lib/std/io/stream_source.zig index 63d9ea9f2e758bba63478d3172021e154d0ffe94..3bfe0d2e6420a31fc83728c1e2342384bc50f6ae 100644 --- a/lib/std/io/stream_source.zig +++ b/lib/std/io/stream_source.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const io = std.io; const testing = std.testing; diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index 779f52a2aaa02c84c3b5f666f7beb5c5b55773ad..ecad26a4485fc739b7caa4c21e670d27271226ad 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; const io = std.io; diff --git a/lib/std/io/writer.zig b/lib/std/io/writer.zig index a98e3b1acd78368ef4af2ea033ff5f0dfc4c5b81..39729ef0a254a08caa1ea3111cff7c23f3a9963b 100644 --- a/lib/std/io/writer.zig +++ b/lib/std/io/writer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const mem = std.mem; diff --git a/lib/std/json.zig b/lib/std/json.zig index 59c765ac421ed3efa3de221fdd55f95e17e42ff3..2f8a70d0effe752c4b39a55476b2a916f306ca0b 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // JSON parser conforming to RFC8259. // // https://tools.ietf.org/html/rfc8259 diff --git a/lib/std/json/test.zig b/lib/std/json/test.zig index ed7454cce333bb1bc767d032c6eefb74b5bd2735..3a7c25e3834a8b59562df2a74b810c6ee26f58a8 100644 --- a/lib/std/json/test.zig +++ b/lib/std/json/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // RFC 8529 conformance tests. // // Tests are taken from https://github.com/nst/JSONTestSuite diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index 778173cc243c82af023f85df2304e2f5ce88f643..59bebd69d3619036706547bedf7b6b411a50c785 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const maxInt = std.math.maxInt; diff --git a/lib/std/linked_list.zig b/lib/std/linked_list.zig index 39f52021b2c17c19c5bbba50a19d86f6ba9e516a..e99f3d8725b6fdcdd1a70761705b9ddb804ec746 100644 --- a/lib/std/linked_list.zig +++ b/lib/std/linked_list.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const debug = std.debug; const assert = debug.assert; diff --git a/lib/std/log.zig b/lib/std/log.zig index 8d5554aa46c95b5ccbf3e1aa93517b8c4fe2afea..50bdfdc0680d7f81c63bca1f04fc123936071e4d 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const root = @import("root"); diff --git a/lib/std/macho.zig b/lib/std/macho.zig index 950283b59f7b950c48c030485882a8781e328823..99a8cd776c1f66635deeacc7a40b60bb8a90b609 100644 --- a/lib/std/macho.zig +++ b/lib/std/macho.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const mach_header = extern struct { magic: u32, cputype: cpu_type_t, diff --git a/lib/std/math.zig b/lib/std/math.zig index 2c9065a89e4e88281439ccc5293af05b71c05959..a76f0a391dcc152b06e9bdf86c1e7321cd018787 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/math/acos.zig b/lib/std/math/acos.zig index cdd86601fd80c20e27e01ecf5de9f85ccd980792..f085680176a3494dd87e8fea41021b02be7bc51f 100644 --- a/lib/std/math/acos.zig +++ b/lib/std/math/acos.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/acosh.zig b/lib/std/math/acosh.zig index 9a594f9cc4ab413a8aa132ef07e1b13f4f28cb6c..76d6edff3ec120749b6f57e0746f082c62caaa9e 100644 --- a/lib/std/math/acosh.zig +++ b/lib/std/math/acosh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/asin.zig b/lib/std/math/asin.zig index 4cff69fc1bf1b5e3834facb506a4f07b0ecb3a77..a4a19c74d97b7248b053ddc86d6eb94397f9f434 100644 --- a/lib/std/math/asin.zig +++ b/lib/std/math/asin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/asinh.zig b/lib/std/math/asinh.zig index 940b953d06b7b331aadda9c9a9f29c30c13e4df6..dc97ac3082de3cba9184b9d2f9e62370b4922b8c 100644 --- a/lib/std/math/asinh.zig +++ b/lib/std/math/asinh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/atan.zig b/lib/std/math/atan.zig index 9342b6ed594cbbfae3367d3965abf73436f75210..390e10b3c4d4672dadcbd837c45617ba11d26432 100644 --- a/lib/std/math/atan.zig +++ b/lib/std/math/atan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/atan2.zig b/lib/std/math/atan2.zig index 68e381607dd341fa5eec537aa2734aec97493ece..6540eced840e2f8f22bfc2defe05a4a1a912b8f3 100644 --- a/lib/std/math/atan2.zig +++ b/lib/std/math/atan2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/atanh.zig b/lib/std/math/atanh.zig index de742bd4cdff2c283071ce6612b14e2704343e33..abd573bb1a1de562c32c30e6e7a439dff4f3f2c0 100644 --- a/lib/std/math/atanh.zig +++ b/lib/std/math/atanh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/big.zig b/lib/std/math/big.zig index ab651c05c69c203296593d5806a982a3112a37f5..6246a4fb8bcec9fcb183c2b064e71c39094742a8 100644 --- a/lib/std/math/big.zig +++ b/lib/std/math/big.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index 92b3f80429db973d5780ef90e4987008dc9df3df..adb58489317b2235bd64aeac2053c96c5493a28e 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const math = std.math; const Limb = std.math.big.Limb; diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index a86b55d2dead9960b35b952a0e66ea21788a5a91..5931767a820afa24645cc6b553669bd3c38c2359 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const mem = std.mem; const testing = std.testing; diff --git a/lib/std/math/big/rational.zig b/lib/std/math/big/rational.zig index 6f62a462b8739ebdd3b78b9a0639a38983889d3d..e83139cf370cf716bd58158709cf6362afd2c8db 100644 --- a/lib/std/math/big/rational.zig +++ b/lib/std/math/big/rational.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const debug = std.debug; const math = std.math; diff --git a/lib/std/math/cbrt.zig b/lib/std/math/cbrt.zig index 42163b96dcfb2c32fe4f8ad12aa521fec812e53f..0d097a0c7562c09b4dbd05ce213a674df0c63b60 100644 --- a/lib/std/math/cbrt.zig +++ b/lib/std/math/cbrt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/ceil.zig b/lib/std/math/ceil.zig index 39de46f361617812397c6c7a46e409d18d108833..ac04c9a8cc2248fee60e8ebdb39077bb90eb35f1 100644 --- a/lib/std/math/ceil.zig +++ b/lib/std/math/ceil.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex.zig b/lib/std/math/complex.zig index 8bff2313fc1def2eadb1bd05e1184710288cbf45..ec76f425ebe043c64c5c772876ab687b80b72f27 100644 --- a/lib/std/math/complex.zig +++ b/lib/std/math/complex.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/abs.zig b/lib/std/math/complex/abs.zig index db31aef42ad124dded6233d91ff19734437e811f..db9c43e89d10310cc5957fc78914d22e8c3ca702 100644 --- a/lib/std/math/complex/abs.zig +++ b/lib/std/math/complex/abs.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/acos.zig b/lib/std/math/complex/acos.zig index 072fd77f08910016593b91c36da6cb85109e9c21..1372c280e2c4a33ccb57008762583f3871636063 100644 --- a/lib/std/math/complex/acos.zig +++ b/lib/std/math/complex/acos.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/acosh.zig b/lib/std/math/complex/acosh.zig index 59117a8b270b8c957a563b8b9af456c1b5008196..49d9fd030240559c2aa37c22c4dde5a4db94ed79 100644 --- a/lib/std/math/complex/acosh.zig +++ b/lib/std/math/complex/acosh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/arg.zig b/lib/std/math/complex/arg.zig index 6cf959a081db87be0413f93c01bccb81e98650cc..7cfbc8bd0ff79aa195668c94b9781b9d9238335e 100644 --- a/lib/std/math/complex/arg.zig +++ b/lib/std/math/complex/arg.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/asin.zig b/lib/std/math/complex/asin.zig index 9f7cd396aaf664fcdc31531f69303a3ec8394a1d..5c5de3ff4f1c2c98b8e91d79e99d8b141a1c5666 100644 --- a/lib/std/math/complex/asin.zig +++ b/lib/std/math/complex/asin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/asinh.zig b/lib/std/math/complex/asinh.zig index 0c3c2bd115556488a9fb4a4c87f867fe7d2aa876..a3f5f04fbc305d897f8002680f1f4a8278570f09 100644 --- a/lib/std/math/complex/asinh.zig +++ b/lib/std/math/complex/asinh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/atan.zig b/lib/std/math/complex/atan.zig index 98bde3e125a7e85a4ee93e7b3dd55cf64f25a5f9..e5c49976ac0e7dc31cfa203b6591ebb4e3957ea8 100644 --- a/lib/std/math/complex/atan.zig +++ b/lib/std/math/complex/atan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/atanh.zig b/lib/std/math/complex/atanh.zig index a07c2969e49b1ab6e717a9233e8cb9661705fdd3..4ab24102580715323c59463bf999cf227d0d6840 100644 --- a/lib/std/math/complex/atanh.zig +++ b/lib/std/math/complex/atanh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/conj.zig b/lib/std/math/complex/conj.zig index 42a34e7dfcb09cf731497d7800887f3c304390c8..159469da86c3668c3bfad71f521e5d3c9b256761 100644 --- a/lib/std/math/complex/conj.zig +++ b/lib/std/math/complex/conj.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/cos.zig b/lib/std/math/complex/cos.zig index 9daf89c7302f6472f8581018e5a24b4923a2b95f..559613cc341a99f412858ea1fbb0d9cb3613393c 100644 --- a/lib/std/math/complex/cos.zig +++ b/lib/std/math/complex/cos.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/cosh.zig b/lib/std/math/complex/cosh.zig index bd51629bd4f6b1eb4aba3055960a0e51c0e93147..f668cb60cee2d84b1c1369ab3b358c86a73a1e2a 100644 --- a/lib/std/math/complex/cosh.zig +++ b/lib/std/math/complex/cosh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/exp.zig b/lib/std/math/complex/exp.zig index 6f6061a94762d31d580c845faf45993e29a0c739..3ad51fe06fefc93962705ccc2ee8d6bf01f48b68 100644 --- a/lib/std/math/complex/exp.zig +++ b/lib/std/math/complex/exp.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/ldexp.zig b/lib/std/math/complex/ldexp.zig index c23b9b346e0ceb5cea2fd8cf3a3a501b94c9cef0..b1cf8a0e42b954b9eaa84b0141fdb32fb7ad107f 100644 --- a/lib/std/math/complex/ldexp.zig +++ b/lib/std/math/complex/ldexp.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/log.zig b/lib/std/math/complex/log.zig index ec02c6c32570d438dc3ca7ce0425fd50abfa94a2..cb719f4b312d0e4d2285b755deed6603f013c6a7 100644 --- a/lib/std/math/complex/log.zig +++ b/lib/std/math/complex/log.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/pow.zig b/lib/std/math/complex/pow.zig index a2480453fc9b0984390572e8e861bca86b9f52e2..7be38cadf20b3b1c62a74e2ed45a5bc8ab27f876 100644 --- a/lib/std/math/complex/pow.zig +++ b/lib/std/math/complex/pow.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/proj.zig b/lib/std/math/complex/proj.zig index e208ae037002124d09696edc9e30c3bc8f2772dc..67f087f8baaa5de675ba7a6c459ad68351f0f19c 100644 --- a/lib/std/math/complex/proj.zig +++ b/lib/std/math/complex/proj.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/sin.zig b/lib/std/math/complex/sin.zig index 1b10f8fca6fecae820be38ca57a5c967c21f74cd..2f33e13354cf83aee1c3e6909152b17d246b8121 100644 --- a/lib/std/math/complex/sin.zig +++ b/lib/std/math/complex/sin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/sinh.zig b/lib/std/math/complex/sinh.zig index 32f2a730fbebffe3bfd7b03febf012c2743ea57b..3242adef7901f265ab5ff5c3e17506e51dc17ae3 100644 --- a/lib/std/math/complex/sinh.zig +++ b/lib/std/math/complex/sinh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/sqrt.zig b/lib/std/math/complex/sqrt.zig index 0edb02a7a96c8d174050d24e98fc54d01a0dfc8f..8abb9a6064cb34e96b671357c681ffcee50ddb93 100644 --- a/lib/std/math/complex/sqrt.zig +++ b/lib/std/math/complex/sqrt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/complex/tan.zig b/lib/std/math/complex/tan.zig index 050898c5732288442854729909c10d02de5bb134..adcda786c1c2f6bc10332b832b6ea0ca021f712d 100644 --- a/lib/std/math/complex/tan.zig +++ b/lib/std/math/complex/tan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const testing = std.testing; const math = std.math; diff --git a/lib/std/math/complex/tanh.zig b/lib/std/math/complex/tanh.zig index 1d614cca583d21917922cdbe7d9b9fbfbee1f17d..fd631149820be6d66598a76a53afaa4f2f7786ce 100644 --- a/lib/std/math/complex/tanh.zig +++ b/lib/std/math/complex/tanh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/copysign.zig b/lib/std/math/copysign.zig index e874da0bb941a004c09af718a8650b195326f7fc..1547382cbde7e5bdb70f3e6de83f951f4150fa8b 100644 --- a/lib/std/math/copysign.zig +++ b/lib/std/math/copysign.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/cos.zig b/lib/std/math/cos.zig index df5c0a53be403e37246772a71eb3e44ffe2ed545..3d282c82e10e5ece9a62d7e7099a1ac3c36a5021 100644 --- a/lib/std/math/cos.zig +++ b/lib/std/math/cos.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from go, which is licensed under a BSD-3 license. // https://golang.org/LICENSE // diff --git a/lib/std/math/cosh.zig b/lib/std/math/cosh.zig index bab47dcdbdaf69fe32c5511242ce2dd2f83f7e4d..221ebcf08964cfc195fed110b2f8722af3648a07 100644 --- a/lib/std/math/cosh.zig +++ b/lib/std/math/cosh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/exp.zig b/lib/std/math/exp.zig index c84d929adfe621cbdb4821495df37b2ff38b3348..36d18f83b25cbceae40ea4bd6cdfef6bec1ed287 100644 --- a/lib/std/math/exp.zig +++ b/lib/std/math/exp.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/exp2.zig b/lib/std/math/exp2.zig index da391189b2084b082106274054ae4a7b8783f9a0..b97690948ec28321657d7181fe7c0096e88bc4fa 100644 --- a/lib/std/math/exp2.zig +++ b/lib/std/math/exp2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/expm1.zig b/lib/std/math/expm1.zig index 80cdefae20b703d590d9717de294343d264de7d8..98e66b17d5532aba91f2bfd1954b19245106ec8f 100644 --- a/lib/std/math/expm1.zig +++ b/lib/std/math/expm1.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/expo2.zig b/lib/std/math/expo2.zig index f404570fb6928095d708f35804385f283c86634c..a81c9920e02312e70d157d69467236b29ef11e39 100644 --- a/lib/std/math/expo2.zig +++ b/lib/std/math/expo2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/fabs.zig b/lib/std/math/fabs.zig index ca91f594fdc2467c1fa081ca0b51c81de0d9518b..f263bfbc5811bd63336dcf5c5434d2fd8812efb8 100644 --- a/lib/std/math/fabs.zig +++ b/lib/std/math/fabs.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/floor.zig b/lib/std/math/floor.zig index 3a71cc7cdf5dd5f26451230570517a277e849479..7b61980a5e611e65e016d42c74822258111f42ac 100644 --- a/lib/std/math/floor.zig +++ b/lib/std/math/floor.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/fma.zig b/lib/std/math/fma.zig index 014593cda5f95696a0a1a0b7222e3f674cdd4e69..6993fc978648f26be94da69a027743339aa921bf 100644 --- a/lib/std/math/fma.zig +++ b/lib/std/math/fma.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/frexp.zig b/lib/std/math/frexp.zig index 0e4558dc3705b3cfa14727f91d148d398716dd05..2d99c85c51f589766c2ef1db5e59ae9085db9fad 100644 --- a/lib/std/math/frexp.zig +++ b/lib/std/math/frexp.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/hypot.zig b/lib/std/math/hypot.zig index 59116014b3ed37f46628d3f0a706c3f0696aceb1..595563076bde1d0777a9941b8dde56da6d415372 100644 --- a/lib/std/math/hypot.zig +++ b/lib/std/math/hypot.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/ilogb.zig b/lib/std/math/ilogb.zig index 748cf9ea0da6101f019abf8903c51ac5c6ebd784..a6fb03197330c3dcbbff8edbcb65ee8ed91b73d8 100644 --- a/lib/std/math/ilogb.zig +++ b/lib/std/math/ilogb.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/inf.zig b/lib/std/math/inf.zig index 86ff2455332ed188f7a9f9d4fbb6e5d598afa810..f2e0283e0302c92cc86595cd7c876e903ab8654e 100644 --- a/lib/std/math/inf.zig +++ b/lib/std/math/inf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; diff --git a/lib/std/math/isfinite.zig b/lib/std/math/isfinite.zig index 0681eae0b755f020053a350e404f9386004a5266..938c495d655246c65c08b2df0a343eaa779efc20 100644 --- a/lib/std/math/isfinite.zig +++ b/lib/std/math/isfinite.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/isinf.zig b/lib/std/math/isinf.zig index 19357d89d157674c44445873cbaecbbb9ca93720..2ecd9c2b9c9a0189634c2e5d4ea79fefa54661c4 100644 --- a/lib/std/math/isinf.zig +++ b/lib/std/math/isinf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/isnan.zig b/lib/std/math/isnan.zig index 797c115d1dda5e397331b2941e573982b74c6db9..fc58e7334c63ac931b57d362ecbd13f6a2005455 100644 --- a/lib/std/math/isnan.zig +++ b/lib/std/math/isnan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/isnormal.zig b/lib/std/math/isnormal.zig index a3144f2784a2e42c38059296df7948f11a6e61ed..b9ff515bdc90394f43daf3d26e6f7ddcad07240b 100644 --- a/lib/std/math/isnormal.zig +++ b/lib/std/math/isnormal.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/ln.zig b/lib/std/math/ln.zig index 99e54c4cc76c7dc91bd976bc2420066b6e437b0e..60a2f528aae17bc10bdc74a36a2ebc55e3df6645 100644 --- a/lib/std/math/ln.zig +++ b/lib/std/math/ln.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/log.zig b/lib/std/math/log.zig index 6f5025cd50b0fe98a1f7f2de1d257b85e1888dd9..4286b74960704108a3781f780a5d2bb71155c262 100644 --- a/lib/std/math/log.zig +++ b/lib/std/math/log.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig index e55bd8c1e879a643c5129bb593473e9d9ff5dcbd..d7d192a564af299d1ee098a6908f3e9be42f7e02 100644 --- a/lib/std/math/log10.zig +++ b/lib/std/math/log10.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/log1p.zig b/lib/std/math/log1p.zig index e24ba8d84d7d3bd6a7f0e9241e4b668e3242d1e2..5a87e92313ed96bb5e85b909752b38e3c4dd0dc0 100644 --- a/lib/std/math/log1p.zig +++ b/lib/std/math/log1p.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/log2.zig b/lib/std/math/log2.zig index 95d06a2b60b80a0b9d45f6281f1ebe3affd2257f..2b9fbe3d84209c7ad1d36fa24032b783ae99946c 100644 --- a/lib/std/math/log2.zig +++ b/lib/std/math/log2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/modf.zig b/lib/std/math/modf.zig index 5ab5318a79cd95a5f6cddb94b75ad0172cdf8a78..830b99257ec990bb59a3fb02013b1022db155c31 100644 --- a/lib/std/math/modf.zig +++ b/lib/std/math/modf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/nan.zig b/lib/std/math/nan.zig index 5a01a5b3bdac95593a334f3d6cb5029ef68b2565..b8e3b517e22f8abe7752d11b37e29b677461d2a9 100644 --- a/lib/std/math/nan.zig +++ b/lib/std/math/nan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const math = @import("../math.zig"); /// Returns the nan representation for type T. diff --git a/lib/std/math/pow.zig b/lib/std/math/pow.zig index cb39dd59e3ad6ec38cd97476ba4db7ff74f526a2..30b52acbda65b0bfcb78001711a61da259ddce00 100644 --- a/lib/std/math/pow.zig +++ b/lib/std/math/pow.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from go, which is licensed under a BSD-3 license. // https://golang.org/LICENSE // diff --git a/lib/std/math/powi.zig b/lib/std/math/powi.zig index ce3a3713e3a800db9a0d96e417d2a612432ef251..660aeddc0548444cc6440ae5aefd1397080761a9 100644 --- a/lib/std/math/powi.zig +++ b/lib/std/math/powi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Based on Rust, which is licensed under the MIT license. // https://github.com/rust-lang/rust/blob/360432f1e8794de58cd94f34c9c17ad65871e5b5/LICENSE-MIT // diff --git a/lib/std/math/round.zig b/lib/std/math/round.zig index 854adee4baae2f1198dfeb41f2e7d4f00515f382..7798e6157ae4f6527ffb83af50a105389a9ea88a 100644 --- a/lib/std/math/round.zig +++ b/lib/std/math/round.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/scalbn.zig b/lib/std/math/scalbn.zig index 71a8110ce71e8f41fe2f3eac72c70cde4c4931ff..7243084dd4133d5c480e1aae084b1db81f7a000d 100644 --- a/lib/std/math/scalbn.zig +++ b/lib/std/math/scalbn.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/signbit.zig b/lib/std/math/signbit.zig index 49397f7bd4546abba8df534711efb92c98c92e9f..defd02aa3ab395def1e127ebbd28951c31fd0ccb 100644 --- a/lib/std/math/signbit.zig +++ b/lib/std/math/signbit.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/sin.zig b/lib/std/math/sin.zig index df3b294ca6409db0c974ce954dcf8c78babcd5d8..c7db4f862384e9174d0e844f083aee22daa55a5f 100644 --- a/lib/std/math/sin.zig +++ b/lib/std/math/sin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from go, which is licensed under a BSD-3 license. // https://golang.org/LICENSE // diff --git a/lib/std/math/sinh.zig b/lib/std/math/sinh.zig index 26e0e05f38b3886324b7c26572bb502e13736efd..1246c89cc06656b1a9aee345961bde3108b7774c 100644 --- a/lib/std/math/sinh.zig +++ b/lib/std/math/sinh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/sqrt.zig b/lib/std/math/sqrt.zig index 2f0d2514324cb072f62c93cb04e123fd3a7c2746..34851ca64718617bbc5817da0407d153ef6455df 100644 --- a/lib/std/math/sqrt.zig +++ b/lib/std/math/sqrt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const math = std.math; const expect = std.testing.expect; diff --git a/lib/std/math/tan.zig b/lib/std/math/tan.zig index 2cd5a407dfb280366e33dd7d45e53af466e43c8e..5e5a80e15d8cd3e5bdadfd76b84468c606d092f3 100644 --- a/lib/std/math/tan.zig +++ b/lib/std/math/tan.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from go, which is licensed under a BSD-3 license. // https://golang.org/LICENSE // diff --git a/lib/std/math/tanh.zig b/lib/std/math/tanh.zig index 7697db5271769602c8bf105816db5675580b99c8..3abc5d4d75872feab0b798ac87db30ea55063a02 100644 --- a/lib/std/math/tanh.zig +++ b/lib/std/math/tanh.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/math/trunc.zig b/lib/std/math/trunc.zig index df24b77111184fae8a796f106c3f83f4e05caed2..85bc68f226ea205ad387279bc5cf8c7fa82422dc 100644 --- a/lib/std/math/trunc.zig +++ b/lib/std/math/trunc.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from musl, which is licensed under the MIT license: // https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT // diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 1ba64f47fa9da2d832b225c7916010e490ce32dc..33977e3ce348080b4d0f28ddcdea685752e6e269 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const debug = std.debug; const assert = debug.assert; diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index e73050165e0e308691108d62befc701ff619bf7c..bb59de2a7e70710ae10645d8cabeb4b5e1033612 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. //! The standard memory allocation interface. const std = @import("../std.zig"); diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 6340a44fae866ce5ce3fc1f1e2f49aa744b2b17f..aaa8e7ca7818912438e2ab57a6e19792f5563de4 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const debug = std.debug; diff --git a/lib/std/meta/trailer_flags.zig b/lib/std/meta/trailer_flags.zig index 0da7ca815a1f31b849063bc7d218bc44b98549dd..6e1d8bea3286bee10bcf92226127d0571c0a0c77 100644 --- a/lib/std/meta/trailer_flags.zig +++ b/lib/std/meta/trailer_flags.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const meta = std.meta; const testing = std.testing; diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index f04d6353c6c9b0d85d1c68cba3c4bb62191de38f..2455542e4fccfb2994d84a23422bf6e40df065d8 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const mem = std.mem; diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig index 3361a42e21c2c2b1ea541d61fc3fc743a000a920..706685d1fa5858bf521d98992e20b89a78e64212 100644 --- a/lib/std/mutex.zig +++ b/lib/std/mutex.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const os = std.os; diff --git a/lib/std/net.zig b/lib/std/net.zig index 0cd34376e1485599e4bb26c88989343b365d6831..10e5b371f8162eec8cd89bf5a53936ac1bd34ea0 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig index 89b84ac83dd3d074ac68d8e078ead31099ed5c99..815ee81d7fd098a2f66aa6d220eb305cb1e4a229 100644 --- a/lib/std/net/test.zig +++ b/lib/std/net/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const builtin = std.builtin; const net = std.net; diff --git a/lib/std/once.zig b/lib/std/once.zig index cf42d021a24eb548576a5084b18df0b871103cf8..6e0e4867d864db097b1b9e68596c7e08d67f37ce 100644 --- a/lib/std/once.zig +++ b/lib/std/once.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const testing = std.testing; diff --git a/lib/std/os.zig b/lib/std/os.zig index 6f58d7f077aef0da013c6c8b46422bd317bf5fa4..e8431c386bbc19c5cd7e1cda450d70ec7ef7e057 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // This file contains thin wrappers around OS-specific APIs, with these // specific goals in mind: // * Convert "errno"-style error codes into Zig errors. diff --git a/lib/std/os/bits.zig b/lib/std/os/bits.zig index 38f019d775a199030aa98889f2e6b28adb3dcb21..177b7daad2c9a0c1f9d3949625bad5e817fc62c5 100644 --- a/lib/std/os/bits.zig +++ b/lib/std/os/bits.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. //! Platform-dependent types and values that are used along with OS-specific APIs. //! These are imported into `std.c`, `std.os`, and `std.os.linux`. //! Root source files can define `os.bits` and these will additionally be added diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig index 4581490e6f0c574302801e40e483c9c9ea526a5b..375127f27819975ae90924b89501b48d75d78f2c 100644 --- a/lib/std/os/bits/darwin.zig +++ b/lib/std/os/bits/darwin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const assert = std.debug.assert; const maxInt = std.math.maxInt; diff --git a/lib/std/os/bits/dragonfly.zig b/lib/std/os/bits/dragonfly.zig index df2267832341dce9f3aa4181dfd49e6ea55d1334..8b6d6be2120a1b4a531eb6dcb5825374dcd7a57e 100644 --- a/lib/std/os/bits/dragonfly.zig +++ b/lib/std/os/bits/dragonfly.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const maxInt = std.math.maxInt; diff --git a/lib/std/os/bits/freebsd.zig b/lib/std/os/bits/freebsd.zig index 3622fb7641297651347a17e2d495dcdfb9d1bfc2..22edf4b9d15e09eb2252e3a03c039d82275d1ddc 100644 --- a/lib/std/os/bits/freebsd.zig +++ b/lib/std/os/bits/freebsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const maxInt = std.math.maxInt; diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 4ad1fc7de42ae4eb8f1832cc9686f7b72e7c9d4b..4fa8a02d3d0741a7588b0c90453186fe01c09f82 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; diff --git a/lib/std/os/bits/linux/arm-eabi.zig b/lib/std/os/bits/linux/arm-eabi.zig index b32d3ef9d4291557b1ae0031912e9eb15ee9bc71..36f1f4f44225bd1f6c5b1366d1923dfbb967848e 100644 --- a/lib/std/os/bits/linux/arm-eabi.zig +++ b/lib/std/os/bits/linux/arm-eabi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // arm-eabi-specific declarations that are intended to be imported into the POSIX namespace. const std = @import("../../../std.zig"); const linux = std.os.linux; diff --git a/lib/std/os/bits/linux/arm64.zig b/lib/std/os/bits/linux/arm64.zig index 0745f19fb0d1f6358a01d678b2ea9cee765488a5..6ecbcc9ae1d83b3e265d25be5a026ea586a00a3e 100644 --- a/lib/std/os/bits/linux/arm64.zig +++ b/lib/std/os/bits/linux/arm64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // arm64-specific declarations that are intended to be imported into the POSIX namespace. // This does include Linux-only APIs. diff --git a/lib/std/os/bits/linux/bpf.zig b/lib/std/os/bits/linux/bpf.zig index 150d3e9135354849c65563cbd6bf490033231a7a..e86e082ff73045288c37f50b2cfc4d69e4fcb313 100644 --- a/lib/std/os/bits/linux/bpf.zig +++ b/lib/std/os/bits/linux/bpf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace std.os; const std = @import("../../../std.zig"); diff --git a/lib/std/os/bits/linux/errno-generic.zig b/lib/std/os/bits/linux/errno-generic.zig index 53af9cc5e578663767202c5321c9c396f980fcc8..a99f20a1a847f5c6afce70b71540ea3d6bb54b33 100644 --- a/lib/std/os/bits/linux/errno-generic.zig +++ b/lib/std/os/bits/linux/errno-generic.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// Operation not permitted pub const EPERM = 1; diff --git a/lib/std/os/bits/linux/errno-mips.zig b/lib/std/os/bits/linux/errno-mips.zig index 81cbde4af4edec68fcce8f690abaaf8250b743da..125886308620abeac16e5e90c1e0d939a94c2ba4 100644 --- a/lib/std/os/bits/linux/errno-mips.zig +++ b/lib/std/os/bits/linux/errno-mips.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const EPERM = 1; pub const ENOENT = 2; pub const ESRCH = 3; diff --git a/lib/std/os/bits/linux/i386.zig b/lib/std/os/bits/linux/i386.zig index 868e4f537b51b846492d4ab06f243e361c7fcc68..a560c146133014556daacda62a5cc0f5f0c8e59f 100644 --- a/lib/std/os/bits/linux/i386.zig +++ b/lib/std/os/bits/linux/i386.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // i386-specific declarations that are intended to be imported into the POSIX namespace. // This does include Linux-only APIs. diff --git a/lib/std/os/bits/linux/mips.zig b/lib/std/os/bits/linux/mips.zig index 5946e821ad9fdb4748b50178bc49486643eab1aa..4b81c6e622ac652304c0e5d5eb61c65008f13c61 100644 --- a/lib/std/os/bits/linux/mips.zig +++ b/lib/std/os/bits/linux/mips.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../../std.zig"); const linux = std.os.linux; const socklen_t = linux.socklen_t; diff --git a/lib/std/os/bits/linux/netlink.zig b/lib/std/os/bits/linux/netlink.zig index f3d000e785bc31ea01b07013ba04670d0a06c4c5..3e75733b9a176ca9a36e31809611d07c50f9a216 100644 --- a/lib/std/os/bits/linux/netlink.zig +++ b/lib/std/os/bits/linux/netlink.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../linux.zig"); /// Routing/device hook diff --git a/lib/std/os/bits/linux/riscv64.zig b/lib/std/os/bits/linux/riscv64.zig index 220e6736226527d7cc2febfd121f8f3c4bfe5f3c..c4b0f044f28c12c8388d772cdc4cf52fdf5d9788 100644 --- a/lib/std/os/bits/linux/riscv64.zig +++ b/lib/std/os/bits/linux/riscv64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // riscv64-specific declarations that are intended to be imported into the POSIX namespace. const std = @import("../../../std.zig"); const uid_t = std.os.linux.uid_t; diff --git a/lib/std/os/bits/linux/x86_64.zig b/lib/std/os/bits/linux/x86_64.zig index c87bca6f8e31f17f37427c43ce10e78e4ad4ca25..0800feeddf1df3288c1df6fd2c658c56bece1d7c 100644 --- a/lib/std/os/bits/linux/x86_64.zig +++ b/lib/std/os/bits/linux/x86_64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // x86-64-specific declarations that are intended to be imported into the POSIX namespace. const std = @import("../../../std.zig"); const pid_t = linux.pid_t; diff --git a/lib/std/os/bits/netbsd.zig b/lib/std/os/bits/netbsd.zig index 91e101620f0cab625e80a9ebd20eaabb880a49c0..d628bf45669436bbb665c125a8969c2bad7afe9e 100644 --- a/lib/std/os/bits/netbsd.zig +++ b/lib/std/os/bits/netbsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const builtin = std.builtin; const maxInt = std.math.maxInt; diff --git a/lib/std/os/bits/wasi.zig b/lib/std/os/bits/wasi.zig index 270345c53b513b0af00cb0964773b66ab3df5548..f768b5522ba007b8cfd386da6c2866783114be68 100644 --- a/lib/std/os/bits/wasi.zig +++ b/lib/std/os/bits/wasi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Convenience types and consts used by std.os module pub const STDIN_FILENO = 0; pub const STDOUT_FILENO = 1; diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig index 5316a048ccb8f6723d46add1399c8ae434880fe0..836d273c1c79e267b23c39228954665ba13f35df 100644 --- a/lib/std/os/bits/windows.zig +++ b/lib/std/os/bits/windows.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime). usingnamespace @import("../windows/bits.zig"); diff --git a/lib/std/os/darwin.zig b/lib/std/os/darwin.zig index d3e9cefb86dd311ea01b756c6c579cb4317abad7..1bd983398b25cff2cad1b4d605b0b69963d50e10 100644 --- a/lib/std/os/darwin.zig +++ b/lib/std/os/darwin.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("../std.zig"); pub usingnamespace std.c; diff --git a/lib/std/os/dragonfly.zig b/lib/std/os/dragonfly.zig index 5f9684b96de967ee7422a2d96322c156ed2dbdbf..a713a009ad7efb65951a1cbb2ae7dee62274e608 100644 --- a/lib/std/os/dragonfly.zig +++ b/lib/std/os/dragonfly.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); pub usingnamespace std.c; pub usingnamespace @import("bits.zig"); diff --git a/lib/std/os/freebsd.zig b/lib/std/os/freebsd.zig index 5f9684b96de967ee7422a2d96322c156ed2dbdbf..a713a009ad7efb65951a1cbb2ae7dee62274e608 100644 --- a/lib/std/os/freebsd.zig +++ b/lib/std/os/freebsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); pub usingnamespace std.c; pub usingnamespace @import("bits.zig"); diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 7fe0ba00ae6c8f19c15176d478a9ce25f3076e9b..ae66e619c363522a4b2992d6a2f1ed4d97cc01fc 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // This file provides the system interface functions for Linux matching those // that are provided by libc, whether or not libc is linked. The following // abstractions are made: diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig index 352afeeb04a2768cab9e31688e359c61837d0b44..a72799a26a55d5d892b9a157264e87929840b8fe 100644 --- a/lib/std/os/linux/arm-eabi.zig +++ b/lib/std/os/linux/arm-eabi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig index 49548522eca593d553c5b18ae638cba4bf1a8191..6727cbce8e5b3919036cc0d48247103bf5abd351 100644 --- a/lib/std/os/linux/arm64.zig +++ b/lib/std/os/linux/arm64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/linux/i386.zig b/lib/std/os/linux/i386.zig index a4fdf8a346b73783e726188adafaeee1b2f4a408..ed5bc88f0f6d76c8977d28d6b3559090e943b046 100644 --- a/lib/std/os/linux/i386.zig +++ b/lib/std/os/linux/i386.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/linux/mips.zig b/lib/std/os/linux/mips.zig index 5b5c1e1f34abaed27cefb76f86c4fd8d13befe4e..ad673e06f93324da10809f038692d1cc644e9226 100644 --- a/lib/std/os/linux/mips.zig +++ b/lib/std/os/linux/mips.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig index 39cc13f5b6a353f1db4b50f354f4deda577c3628..034340d0b356e9080045b788b01d1c81b1453b1f 100644 --- a/lib/std/os/linux/riscv64.zig +++ b/lib/std/os/linux/riscv64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index aa6655b7d867b438dd635cb6f3747eae24ac3059..7599cfc39508fdb8f5b7f413c0dcb1c2f35f3188 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const builtin = @import("builtin"); const linux = std.os.linux; diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index 8cba45d4b380b68fb4aaa284c2aae63e0762e83d..b10dae14d7d8b57b9882cd30d09d850abb96fe0b 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; const os = std.os; diff --git a/lib/std/os/linux/vdso.zig b/lib/std/os/linux/vdso.zig index 27c56d6c42a2e70c0274dd2cb8b7131ec94a3fe6..776737d928ac0693180661f107f68f7ca1575da1 100644 --- a/lib/std/os/linux/vdso.zig +++ b/lib/std/os/linux/vdso.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../../std.zig"); const elf = std.elf; const linux = std.os.linux; diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig index 33d2b66670e7ab12273a0efb36d55b76059c5cb5..8987e1aab3a11815da764aa574d85dc21dcff1fa 100644 --- a/lib/std/os/linux/x86_64.zig +++ b/lib/std/os/linux/x86_64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("../bits.zig"); pub fn syscall0(number: SYS) usize { diff --git a/lib/std/os/netbsd.zig b/lib/std/os/netbsd.zig index 5f9684b96de967ee7422a2d96322c156ed2dbdbf..a713a009ad7efb65951a1cbb2ae7dee62274e608 100644 --- a/lib/std/os/netbsd.zig +++ b/lib/std/os/netbsd.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); pub usingnamespace std.c; pub usingnamespace @import("bits.zig"); diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index dc8a89c688251e0575823e759bce345ab338d528..93c4ee04031dc1ac22b5f5edf30db8f060a9ddf6 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const os = std.os; const testing = std.testing; diff --git a/lib/std/os/uefi.zig b/lib/std/os/uefi.zig index c037075cd81d3ca69e3566a7a4a7ed1fdf5a0b1b..0127033db205e6a83971cee9d94b792ec4dc7d6e 100644 --- a/lib/std/os/uefi.zig +++ b/lib/std/os/uefi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. /// A protocol is an interface identified by a GUID. pub const protocols = @import("uefi/protocols.zig"); diff --git a/lib/std/os/uefi/protocols.zig b/lib/std/os/uefi/protocols.zig index 353c628a0582a5e1977a268c05def60ecb9a9c20..1519092b8481586d43d3773d442e157c8a07511b 100644 --- a/lib/std/os/uefi/protocols.zig +++ b/lib/std/os/uefi/protocols.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const LoadedImageProtocol = @import("protocols/loaded_image_protocol.zig").LoadedImageProtocol; pub const loaded_image_device_path_protocol_guid = @import("protocols/loaded_image_protocol.zig").loaded_image_device_path_protocol_guid; diff --git a/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig b/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig index a06a19c1a411d3c6d553f48139a7f45b32fe7453..3ec6aab5b9bc59adf4eccef39012195c52cbde95 100644 --- a/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig +++ b/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/device_path_protocol.zig b/lib/std/os/uefi/protocols/device_path_protocol.zig index f359484eb9c84da7625e5bced75cb15e755707c7..1a998f0f7874ffd99d77d2c7f97fdd5c88dfbeb3 100644 --- a/lib/std/os/uefi/protocols/device_path_protocol.zig +++ b/lib/std/os/uefi/protocols/device_path_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/edid_active_protocol.zig b/lib/std/os/uefi/protocols/edid_active_protocol.zig index fcdef78d83f7090b13d1c087b66f7d1c19d2bb1c..dc8057b4f8b59c1629e7fa5574ccf08591f97041 100644 --- a/lib/std/os/uefi/protocols/edid_active_protocol.zig +++ b/lib/std/os/uefi/protocols/edid_active_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/edid_discovered_protocol.zig b/lib/std/os/uefi/protocols/edid_discovered_protocol.zig index 00b59cb6c816ad7447ec566a7cc0d9c61d6339ce..1ed2b6277d2604f58d715c8de7e13b63950a2f59 100644 --- a/lib/std/os/uefi/protocols/edid_discovered_protocol.zig +++ b/lib/std/os/uefi/protocols/edid_discovered_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/edid_override_protocol.zig b/lib/std/os/uefi/protocols/edid_override_protocol.zig index efe73982e9d19eba5239222b2cca92d0bdf5939f..83260f7b881ff8f52aa86ceb3d2c45da0d26a66d 100644 --- a/lib/std/os/uefi/protocols/edid_override_protocol.zig +++ b/lib/std/os/uefi/protocols/edid_override_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Handle = uefi.Handle; diff --git a/lib/std/os/uefi/protocols/file_protocol.zig b/lib/std/os/uefi/protocols/file_protocol.zig index eacd777008db9e75b52971f1df5045dedfef912d..ce34a2d6e5a5cb7166e33d9b3c4ea93770b72b6b 100644 --- a/lib/std/os/uefi/protocols/file_protocol.zig +++ b/lib/std/os/uefi/protocols/file_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Time = uefi.Time; diff --git a/lib/std/os/uefi/protocols/graphics_output_protocol.zig b/lib/std/os/uefi/protocols/graphics_output_protocol.zig index 1ceccce0bfc4168b32f4d4acad59c6735f616653..3ec1c39ab81e3a50f2a37a9c535fca9720571b6b 100644 --- a/lib/std/os/uefi/protocols/graphics_output_protocol.zig +++ b/lib/std/os/uefi/protocols/graphics_output_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; diff --git a/lib/std/os/uefi/protocols/hii.zig b/lib/std/os/uefi/protocols/hii.zig index 750e004c8bd132396a9c061bf04f8ca3d0bd6d01..960402828e7525bae4acb14fe40d41d528789966 100644 --- a/lib/std/os/uefi/protocols/hii.zig +++ b/lib/std/os/uefi/protocols/hii.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/hii_database_protocol.zig b/lib/std/os/uefi/protocols/hii_database_protocol.zig index e34f72c2f3b7ebdc81bae865d8ef11d43ee8a280..d0b16ff943faa300b1d3fb8ce5d51ce50c30d7c7 100644 --- a/lib/std/os/uefi/protocols/hii_database_protocol.zig +++ b/lib/std/os/uefi/protocols/hii_database_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; diff --git a/lib/std/os/uefi/protocols/hii_popup_protocol.zig b/lib/std/os/uefi/protocols/hii_popup_protocol.zig index 2e4f621b41f90c48e534bb415fc76f5bf3dd89c2..1f5c5ce0f469811d4418038b02c85e9dfb54106d 100644 --- a/lib/std/os/uefi/protocols/hii_popup_protocol.zig +++ b/lib/std/os/uefi/protocols/hii_popup_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; diff --git a/lib/std/os/uefi/protocols/ip6_config_protocol.zig b/lib/std/os/uefi/protocols/ip6_config_protocol.zig index 99ba76aa17e260ae0efe0d8f219466d8cca75cee..16002f62a6b5b2f98a1e610c409a88e2ab6a415d 100644 --- a/lib/std/os/uefi/protocols/ip6_config_protocol.zig +++ b/lib/std/os/uefi/protocols/ip6_config_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Event = uefi.Event; diff --git a/lib/std/os/uefi/protocols/ip6_protocol.zig b/lib/std/os/uefi/protocols/ip6_protocol.zig index b39ae60b2a98cb3455cc9394afa261af55214908..578a3cfb011df826721226bc2513313037c92cae 100644 --- a/lib/std/os/uefi/protocols/ip6_protocol.zig +++ b/lib/std/os/uefi/protocols/ip6_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Event = uefi.Event; diff --git a/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig index 97ab1a431c2ee9d2cdb60d1707c19d5773c1e249..59605cc11b1de9c295ab30600ff747bb0f55943a 100644 --- a/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig +++ b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Handle = uefi.Handle; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/loaded_image_protocol.zig b/lib/std/os/uefi/protocols/loaded_image_protocol.zig index b8afcb1063a159f4d69c26371c9f203039661e42..96aa10f08d695f2e5644343da3b25ca4b6b33704 100644 --- a/lib/std/os/uefi/protocols/loaded_image_protocol.zig +++ b/lib/std/os/uefi/protocols/loaded_image_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Handle = uefi.Handle; diff --git a/lib/std/os/uefi/protocols/managed_network_protocol.zig b/lib/std/os/uefi/protocols/managed_network_protocol.zig index 34ef6c40fa381b3846bfd30742c6f177bc28e418..9202c6f139a45d16949f378b67e2de1fb6ad24e0 100644 --- a/lib/std/os/uefi/protocols/managed_network_protocol.zig +++ b/lib/std/os/uefi/protocols/managed_network_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Event = uefi.Event; diff --git a/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig index e9657e445640664043523f98e1fd6de1449fc7d7..0c684336c83f2c89d19a1d81992b47cbdf932e9f 100644 --- a/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig +++ b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Handle = uefi.Handle; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/rng_protocol.zig b/lib/std/os/uefi/protocols/rng_protocol.zig index a32b202f4428757128b7cc3c63cc1a235f24e425..713b76b371c15a3b5c3abd0918e7c4a1d1b526a4 100644 --- a/lib/std/os/uefi/protocols/rng_protocol.zig +++ b/lib/std/os/uefi/protocols/rng_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; diff --git a/lib/std/os/uefi/protocols/shell_parameters_protocol.zig b/lib/std/os/uefi/protocols/shell_parameters_protocol.zig index afbd26e9390a17ed4de3e0c6373d3aca1c55ccd0..7ec46b732c454d4a3e6c739ebd1a6b605f1a3ac7 100644 --- a/lib/std/os/uefi/protocols/shell_parameters_protocol.zig +++ b/lib/std/os/uefi/protocols/shell_parameters_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const FileHandle = uefi.FileHandle; diff --git a/lib/std/os/uefi/protocols/simple_file_system_protocol.zig b/lib/std/os/uefi/protocols/simple_file_system_protocol.zig index 119c1e658723dc116ed599c586aa5378c56931c8..946c88a89b0b59798c53c5fb6cb9249ba0dcd168 100644 --- a/lib/std/os/uefi/protocols/simple_file_system_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_file_system_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const FileProtocol = uefi.protocols.FileProtocol; diff --git a/lib/std/os/uefi/protocols/simple_network_protocol.zig b/lib/std/os/uefi/protocols/simple_network_protocol.zig index ac7446036ee78cbfd5b54408a7c248ac4d76f4f7..f74f11a857c92d8287ffaeeeeeee552a4e438d52 100644 --- a/lib/std/os/uefi/protocols/simple_network_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_network_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/simple_pointer_protocol.zig b/lib/std/os/uefi/protocols/simple_pointer_protocol.zig index d217ab593027dfebb2da4c6673779281bf9d9173..5f8ca7569e30f7afa0806059615f156f1842d762 100644 --- a/lib/std/os/uefi/protocols/simple_pointer_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_pointer_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig index 4a2b098e61a98efa19498d0de1bac46d6791e063..096013bfb01491974d71911398abebc8076e3943 100644 --- a/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig index 58ed071331fc130a676738b5fc7aa6c57f6253af..d093186532ef22e48f8c023cff7d475be7539fea 100644 --- a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/protocols/simple_text_output_protocol.zig b/lib/std/os/uefi/protocols/simple_text_output_protocol.zig index 84f540cb786ac7ace519b406473ca96987bf981e..f9bbc3714061b184702b28b9b4e1653ca1aeabcd 100644 --- a/lib/std/os/uefi/protocols/simple_text_output_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_text_output_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; diff --git a/lib/std/os/uefi/protocols/udp6_protocol.zig b/lib/std/os/uefi/protocols/udp6_protocol.zig index 46c76beaa60e5ba170f94bb867656b3e6354e3d9..50b7dae7c4a7f76021a9b55a1442752edfa8005f 100644 --- a/lib/std/os/uefi/protocols/udp6_protocol.zig +++ b/lib/std/os/uefi/protocols/udp6_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const Event = uefi.Event; diff --git a/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig index 811692adc36dbdba5c017f56734fa73d927e6231..4f4e0a26384f3c6229179c578bc9129129e39605 100644 --- a/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig +++ b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Handle = uefi.Handle; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/status.zig b/lib/std/os/uefi/status.zig index 0da4508e8f1e37e3967245fd2148a0375bcb94f2..3e8696220213e342d0d00aac5bddf2ddf7e7f994 100644 --- a/lib/std/os/uefi/status.zig +++ b/lib/std/os/uefi/status.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const high_bit = 1 << @typeInfo(usize).Int.bits - 1; pub const Status = extern enum(usize) { diff --git a/lib/std/os/uefi/tables.zig b/lib/std/os/uefi/tables.zig index 0011c80a9cd20b6976c1a33a5591095cfd0bc0f0..b796eb6e0629e278ceebf56417ce81dee43e79cd 100644 --- a/lib/std/os/uefi/tables.zig +++ b/lib/std/os/uefi/tables.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const AllocateType = @import("tables/boot_services.zig").AllocateType; pub const BootServices = @import("tables/boot_services.zig").BootServices; pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable; diff --git a/lib/std/os/uefi/tables/boot_services.zig b/lib/std/os/uefi/tables/boot_services.zig index a1d2c1ca59016892eac828c6db0870ad590b54a9..09431cf3f4345e53d81d37668254928713225d4b 100644 --- a/lib/std/os/uefi/tables/boot_services.zig +++ b/lib/std/os/uefi/tables/boot_services.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Event = uefi.Event; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/tables/configuration_table.zig b/lib/std/os/uefi/tables/configuration_table.zig index 0ac3bd73c8544c1630726448f0fcfe924f0d3a19..c7dedad5fb659c846c4e31388ee2f8152e72330b 100644 --- a/lib/std/os/uefi/tables/configuration_table.zig +++ b/lib/std/os/uefi/tables/configuration_table.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; diff --git a/lib/std/os/uefi/tables/runtime_services.zig b/lib/std/os/uefi/tables/runtime_services.zig index 981e07275bea2f5eac04039d7b6c5b6199bab0ee..a2012168eed520b12302cfa57c6e5a96d8dfb78e 100644 --- a/lib/std/os/uefi/tables/runtime_services.zig +++ b/lib/std/os/uefi/tables/runtime_services.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const Guid = uefi.Guid; const TableHeader = uefi.tables.TableHeader; diff --git a/lib/std/os/uefi/tables/system_table.zig b/lib/std/os/uefi/tables/system_table.zig index 40fec34d4421997eafbdfa9bfa3674140059ff11..cbe66fbb680aa60b55b2ba4a63793e4f5c19c2e7 100644 --- a/lib/std/os/uefi/tables/system_table.zig +++ b/lib/std/os/uefi/tables/system_table.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const uefi = @import("std").os.uefi; const BootServices = uefi.tables.BootServices; const ConfigurationTable = uefi.tables.ConfigurationTable; diff --git a/lib/std/os/uefi/tables/table_header.zig b/lib/std/os/uefi/tables/table_header.zig index d5d40942327ca9f9217d6b0270ddace16f627b1d..a8343c967a2be1fe134a56d967fc3933f60a8795 100644 --- a/lib/std/os/uefi/tables/table_header.zig +++ b/lib/std/os/uefi/tables/table_header.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const TableHeader = extern struct { signature: u64, revision: u32, diff --git a/lib/std/os/wasi.zig b/lib/std/os/wasi.zig index 23df66f385b464619ffc9efc097144dfd3dfa41d..899541f3feef5b2d7d1aa84b63cc35b4df3a4534 100644 --- a/lib/std/os/wasi.zig +++ b/lib/std/os/wasi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // wasi_snapshot_preview1 spec available (in witx format) here: // * typenames -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/typenames.witx // * module -- https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 2f2369a458616121ca60bd723b6ce9d618b6c5a9..a23eead14ffb747e88aaa164c6e19f14bd9dffbf 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // This file contains thin wrappers around Windows-specific APIs, with these // specific goals in mind: // * Convert "errno"-style error codes into Zig errors. diff --git a/lib/std/os/windows/advapi32.zig b/lib/std/os/windows/advapi32.zig index 6364c5bddbedaa294f3af1c11518a2ea0df8a994..b6dbaf9a7a7bb4c6a7658941f9600d7221d64333 100644 --- a/lib/std/os/windows/advapi32.zig +++ b/lib/std/os/windows/advapi32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "advapi32" fn RegOpenKeyExW( diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 44bc1ba4371a0d4158940c57236278107410cbc7..d22f42d6e86ba098a5492c07eaf420a94a2a9497 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Platform-dependent types and values that are used along with OS-specific APIs. const builtin = @import("builtin"); diff --git a/lib/std/os/windows/gdi32.zig b/lib/std/os/windows/gdi32.zig index 676065b57447a3914aecaf5e57a1afc1b3f037e1..f36732ba1e371924950f3612f1d657d2f2d02816 100644 --- a/lib/std/os/windows/gdi32.zig +++ b/lib/std/os/windows/gdi32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub const PIXELFORMATDESCRIPTOR = extern struct { diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index b50143b0754d13401639b688dcdabb99b46cd1c0..fce9eea908ad29690c0abb0aab32b747a63c0895 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void; diff --git a/lib/std/os/windows/lang.zig b/lib/std/os/windows/lang.zig index b173a62a73dc846a2e174031ed54d55da217a5bf..61efa3bdb3c20dce089dfb23a4c36ad8ce35d012 100644 --- a/lib/std/os/windows/lang.zig +++ b/lib/std/os/windows/lang.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const NEUTRAL = 0x00; pub const INVARIANT = 0x7f; pub const AFRIKAANS = 0x36; diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 5edad85c2003295795e9cf122f948841b4838298..c11098b6bce7314ebebb0ac83901972e7e8cfd39 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "NtDll" fn RtlGetVersion( diff --git a/lib/std/os/windows/ntstatus.zig b/lib/std/os/windows/ntstatus.zig index 5c9344d639384cd482d4cc7537208b18f3341a48..0e567df510318198ed95e61c707b02f918ca44b2 100644 --- a/lib/std/os/windows/ntstatus.zig +++ b/lib/std/os/windows/ntstatus.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // NTSTATUS codes from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55? pub const NTSTATUS = extern enum(u32) { /// The operation completed successfully. diff --git a/lib/std/os/windows/ole32.zig b/lib/std/os/windows/ole32.zig index a472089078421e7a15405818130a695a9a5c098b..f46ee330474f568f98661e1a21f261bc1efdf538 100644 --- a/lib/std/os/windows/ole32.zig +++ b/lib/std/os/windows/ole32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void; diff --git a/lib/std/os/windows/psapi.zig b/lib/std/os/windows/psapi.zig index 1a5a7d4bf2a1379de0baea9e50038c0d9bc6165f..db6fc93314f50f71d13006b769242da141a85153 100644 --- a/lib/std/os/windows/psapi.zig +++ b/lib/std/os/windows/psapi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "psapi" fn EmptyWorkingSet(hProcess: HANDLE) callconv(.Stdcall) BOOL; diff --git a/lib/std/os/windows/shell32.zig b/lib/std/os/windows/shell32.zig index 762589c6de1c4f4b53fa1cab4af5a88b56a414cf..ce9d54f6dfb6dbc69db0286f89c59cfbb1980a18 100644 --- a/lib/std/os/windows/shell32.zig +++ b/lib/std/os/windows/shell32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*:0]WCHAR) callconv(.Stdcall) HRESULT; diff --git a/lib/std/os/windows/sublang.zig b/lib/std/os/windows/sublang.zig index e9929c6d79c22fdd1e1f68a041bc1a0a3b23c2e3..5249e8ed0a875c9534681a463942bfa7519b13d7 100644 --- a/lib/std/os/windows/sublang.zig +++ b/lib/std/os/windows/sublang.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const NEUTRAL = 0x00; pub const DEFAULT = 0x01; pub const SYS_DEFAULT = 0x02; diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig index 3877e19ad8dd14e7139fdb69fb94ce8b7e7b80fd..6a80a92cad25d11beedf0fe0b38e974428b19d05 100644 --- a/lib/std/os/windows/user32.zig +++ b/lib/std/os/windows/user32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); // PM diff --git a/lib/std/os/windows/win32error.zig b/lib/std/os/windows/win32error.zig index 037797e25f73cf426e52a78b404c4942f46f9383..2e1f111d92c10a8a981b50dd32a3937554fa0fe9 100644 --- a/lib/std/os/windows/win32error.zig +++ b/lib/std/os/windows/win32error.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Codes are from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d pub const Win32Error = extern enum(u16) { /// The operation completed successfully. diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index 1e36a72038d1afd77b5d059b0d9ad832ce59bf4f..cfc212d15aaf40fc4a9c1307393d6c8f0628947d 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. usingnamespace @import("bits.zig"); pub const SOCKET = *@Type(.Opaque); diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig index 07a79655adb133a410836b290ece6ebdc30ff100..de99afa3036d1601feb2e3bfd2a872fe8d5e6d3c 100644 --- a/lib/std/packed_int_array.zig +++ b/lib/std/packed_int_array.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); const debug = std.debug; diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig index a702a8aed6e7821898a64cf1e8ea1cf2e713a975..e8c61f859db0a26bc1e215cc3a1f714b6fecff56 100644 --- a/lib/std/pdb.zig +++ b/lib/std/pdb.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); const io = std.io; diff --git a/lib/std/priority_queue.zig b/lib/std/priority_queue.zig index 69b9e06a5be906461b808bca900219734039e65e..1c0d230d4d23c465ee6432e1b930375408c6e09c 100644 --- a/lib/std/priority_queue.zig +++ b/lib/std/priority_queue.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; diff --git a/lib/std/process.zig b/lib/std/process.zig index 1a0dfad474f037b7ee33b8075ab37fec403f4069..69befa2fc809918d6c8eab9a82290da839df1ff4 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const os = std.os; diff --git a/lib/std/progress.zig b/lib/std/progress.zig index b81e81aa2c7a5b4b0adbc35fc6c01966c91781dc..654d8cc228db35a49466063db7d94462ab81e2fa 100644 --- a/lib/std/progress.zig +++ b/lib/std/progress.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const windows = std.os.windows; const testing = std.testing; diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 1e5bb37592000c24206f410d8f86237c23600e71..85f11ff44992131bad4ec11ec1fbc2e8c3333256 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // The engines provided here should be initialized from an external source. For now, randomBytes // from the crypto package is the most suitable. Be sure to use a CSPRNG when required, otherwise using // a normal PRNG will be faster and use substantially less stack space. diff --git a/lib/std/rand/ziggurat.zig b/lib/std/rand/ziggurat.zig index 06728f170cff8b24b2b853be23500dc77c46e7c0..da189637bf57310e794b4f5b430ee98fdb80c422 100644 --- a/lib/std/rand/ziggurat.zig +++ b/lib/std/rand/ziggurat.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Implements ZIGNOR [1]. // // [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to Generate Normal Random Samples*] diff --git a/lib/std/rb.zig b/lib/std/rb.zig index a39b815e749144f446a1d8a4e6325d2324c6652a..8cf90a1eea5cdd76c3d6e89552bd67f31faafef9 100644 --- a/lib/std/rb.zig +++ b/lib/std/rb.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig index 6f520773d84ba4944d22e202d087db0356d467dd..31e6c28cf89ea7e580bd42d803954b87c43db704 100644 --- a/lib/std/reset_event.zig +++ b/lib/std/reset_event.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); const testing = std.testing; diff --git a/lib/std/segmented_list.zig b/lib/std/segmented_list.zig index d39fe3e2397b087d6c24e75861aee92c3c8f8213..a63196c443c598b57c097059f66355e69a876903 100644 --- a/lib/std/segmented_list.zig +++ b/lib/std/segmented_list.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 464054e4a50c7c91b48bd25d9d393ae258102f37..e2e4cc662dc5794b407ce3955cc3b6c22e62d51b 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/special/build_runner.zig b/lib/std/special/build_runner.zig index 83c181e8413414b8cc14d5f4761e9daa31a4e7da..46d3b0b6153c9cffa554031b9786d9ef7fa85ba2 100644 --- a/lib/std/special/build_runner.zig +++ b/lib/std/special/build_runner.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const root = @import("@build"); const std = @import("std"); const builtin = @import("builtin"); diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 170bb9862030fae876f10c0b644498d5d1ed0f0b..f18fe11e668a0e2623f0f1827ca52f8287062379 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // This is Zig's multi-target implementation of libc. // When builtin.link_libc is true, we need to export all the functions and // provide an entire C API. diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 2716de811369c2f0400b596f73274d490442d93a..42db6b96bffc7675776f77a7a15e7e3625391593 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; const is_test = builtin.is_test; diff --git a/lib/std/special/compiler_rt/addXf3.zig b/lib/std/special/compiler_rt/addXf3.zig index 849efa1cd2108758844c568bf2c6e7940dae3775..6dd0faaebbc2703656ada89736a58ef969096a94 100644 --- a/lib/std/special/compiler_rt/addXf3.zig +++ b/lib/std/special/compiler_rt/addXf3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc diff --git a/lib/std/special/compiler_rt/addXf3_test.zig b/lib/std/special/compiler_rt/addXf3_test.zig index af991b37e923cfbc4b363dc0654ed4e6297ba756..3d7530950766d99c0ddf9acebf752e88f6d52cb0 100644 --- a/lib/std/special/compiler_rt/addXf3_test.zig +++ b/lib/std/special/compiler_rt/addXf3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c diff --git a/lib/std/special/compiler_rt/arm.zig b/lib/std/special/compiler_rt/arm.zig index 5e718ed4c4a0eede93c2064a8a31e51349eba78a..1eecd3ceac1ebcda632eaf19b460abae2c828061 100644 --- a/lib/std/special/compiler_rt/arm.zig +++ b/lib/std/special/compiler_rt/arm.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // ARM specific builtins const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/ashldi3_test.zig b/lib/std/special/compiler_rt/ashldi3_test.zig index 547c315b249bb175bb5f1fba51b8233321d85351..874681a79a4f8f9ddbc9915d53ee5c175825a0a3 100644 --- a/lib/std/special/compiler_rt/ashldi3_test.zig +++ b/lib/std/special/compiler_rt/ashldi3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __ashldi3 = @import("shift.zig").__ashldi3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/ashlti3_test.zig b/lib/std/special/compiler_rt/ashlti3_test.zig index a4510f52d7b1f3c5cc5c781cb275ebdcc96bfc0c..42cb3a47bb5fff8d065b55ea3403117079778691 100644 --- a/lib/std/special/compiler_rt/ashlti3_test.zig +++ b/lib/std/special/compiler_rt/ashlti3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __ashlti3 = @import("shift.zig").__ashlti3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/ashrdi3_test.zig b/lib/std/special/compiler_rt/ashrdi3_test.zig index 3ba30edbfe073fad0f14b563bf23bf88b1e34ac3..e80b95af9efebf61c163d16e6300cde626aa636a 100644 --- a/lib/std/special/compiler_rt/ashrdi3_test.zig +++ b/lib/std/special/compiler_rt/ashrdi3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __ashrdi3 = @import("shift.zig").__ashrdi3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/ashrti3_test.zig b/lib/std/special/compiler_rt/ashrti3_test.zig index 43d5d119105263a74530d6d39026f9129846e7b2..958b8a8a74c1b77db1585c97cb9494a73817e934 100644 --- a/lib/std/special/compiler_rt/ashrti3_test.zig +++ b/lib/std/special/compiler_rt/ashrti3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __ashrti3 = @import("shift.zig").__ashrti3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/atomics.zig b/lib/std/special/compiler_rt/atomics.zig index e2cb45bef32a7ff70135c9bde427684fc52b2b5a..a76695ff2c32a64c6670c6966677e3cb1ad3316f 100644 --- a/lib/std/special/compiler_rt/atomics.zig +++ b/lib/std/special/compiler_rt/atomics.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; diff --git a/lib/std/special/compiler_rt/aulldiv.zig b/lib/std/special/compiler_rt/aulldiv.zig index 2e2dd364d5381d73d2375d8169e8e02bcd708690..cf9b26c5a6ea609a3738defb8051aa5c0da7f785 100644 --- a/lib/std/special/compiler_rt/aulldiv.zig +++ b/lib/std/special/compiler_rt/aulldiv.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 { diff --git a/lib/std/special/compiler_rt/aullrem.zig b/lib/std/special/compiler_rt/aullrem.zig index 4244f1bb8043c4502bf5cde5eb73a8f23b1026b2..7c981cc08864b4951d40fd626f6e1a4a481cd32d 100644 --- a/lib/std/special/compiler_rt/aullrem.zig +++ b/lib/std/special/compiler_rt/aullrem.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); pub fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 { diff --git a/lib/std/special/compiler_rt/clear_cache.zig b/lib/std/special/compiler_rt/clear_cache.zig index 6306d5b57522ee51be53e4c144164218f4dac22e..d862f739d3a332b334fa031d47b0bf01a150b587 100644 --- a/lib/std/special/compiler_rt/clear_cache.zig +++ b/lib/std/special/compiler_rt/clear_cache.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const arch = std.builtin.cpu.arch; const os = std.builtin.os.tag; diff --git a/lib/std/special/compiler_rt/clzsi2.zig b/lib/std/special/compiler_rt/clzsi2.zig index 0c9c5d431828679e9573f9d08eeb536d36e0108d..ac314ff9e0f7dd83627c8d2170513fff0df4f26b 100644 --- a/lib/std/special/compiler_rt/clzsi2.zig +++ b/lib/std/special/compiler_rt/clzsi2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); fn __clzsi2_generic(a: i32) callconv(.C) i32 { diff --git a/lib/std/special/compiler_rt/clzsi2_test.zig b/lib/std/special/compiler_rt/clzsi2_test.zig index 8a2896fcb6cac6e8dd0bd56f67104bea914b82b6..2d9ba3d1b3e3fd9336cf60be8499c5075f117c27 100644 --- a/lib/std/special/compiler_rt/clzsi2_test.zig +++ b/lib/std/special/compiler_rt/clzsi2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const clzsi2 = @import("clzsi2.zig"); const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/compareXf2.zig b/lib/std/special/compiler_rt/compareXf2.zig index 6489d283ff52558b764f907de6f3bf086698d085..f50dc67474694ea04f2a749351198ea9b9d507c4 100644 --- a/lib/std/special/compiler_rt/compareXf2.zig +++ b/lib/std/special/compiler_rt/compareXf2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparesf2.c diff --git a/lib/std/special/compiler_rt/comparedf2_test.zig b/lib/std/special/compiler_rt/comparedf2_test.zig index 16a2a258ce15eb249b7b7e5452f046e18a71a79f..9d681b8f8176ac968a0a0c136f5598ff820dc1bc 100644 --- a/lib/std/special/compiler_rt/comparedf2_test.zig +++ b/lib/std/special/compiler_rt/comparedf2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/comparedf2_test.c diff --git a/lib/std/special/compiler_rt/comparesf2_test.zig b/lib/std/special/compiler_rt/comparesf2_test.zig index e3966c021b9c794fef6586c08b8c4bea6215426b..da7fe940a02b4d1f5c636e1a287360ac92754e7e 100644 --- a/lib/std/special/compiler_rt/comparesf2_test.zig +++ b/lib/std/special/compiler_rt/comparesf2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/comparesf2_test.c diff --git a/lib/std/special/compiler_rt/divdf3.zig b/lib/std/special/compiler_rt/divdf3.zig index 8b7525e931673d50f80cf0eb6ef1cae0f9c13b43..ad72f96057faee18a295687e6a7396c3c63981f1 100644 --- a/lib/std/special/compiler_rt/divdf3.zig +++ b/lib/std/special/compiler_rt/divdf3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divdf3.c diff --git a/lib/std/special/compiler_rt/divdf3_test.zig b/lib/std/special/compiler_rt/divdf3_test.zig index 61d6731ea7758115f2275d4912ea757e471e1522..04cac956d21c9c93348127eef7ebbe1f6d9984b0 100644 --- a/lib/std/special/compiler_rt/divdf3_test.zig +++ b/lib/std/special/compiler_rt/divdf3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/divdf3_test.c diff --git a/lib/std/special/compiler_rt/divsf3.zig b/lib/std/special/compiler_rt/divsf3.zig index 62a6c56262c9f0b8dfed28e7203faff6bffade22..80af806eb1b58b2705c41ebc06cd41f36bb8be61 100644 --- a/lib/std/special/compiler_rt/divsf3.zig +++ b/lib/std/special/compiler_rt/divsf3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divsf3.c diff --git a/lib/std/special/compiler_rt/divsf3_test.zig b/lib/std/special/compiler_rt/divsf3_test.zig index 188842af5887789e8e54da62cb135b24ca9cbe2d..30dcba462bcae69a096738441b912bfe4828b043 100644 --- a/lib/std/special/compiler_rt/divsf3_test.zig +++ b/lib/std/special/compiler_rt/divsf3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/divsf3_test.c diff --git a/lib/std/special/compiler_rt/divtf3.zig b/lib/std/special/compiler_rt/divtf3.zig index d177454ad24def525e361a6168a464ecaf49111e..f6f7c1bf7d833ebec25ab364c3877b6707e72a04 100644 --- a/lib/std/special/compiler_rt/divtf3.zig +++ b/lib/std/special/compiler_rt/divtf3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/divtf3_test.zig b/lib/std/special/compiler_rt/divtf3_test.zig index 4940b2c403d7099f66d9f9138a13b1faae13669f..cf6f2f2eaff3ef5a64f23c8b83308309f8279c05 100644 --- a/lib/std/special/compiler_rt/divtf3_test.zig +++ b/lib/std/special/compiler_rt/divtf3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const math = std.math; const testing = std.testing; diff --git a/lib/std/special/compiler_rt/divti3.zig b/lib/std/special/compiler_rt/divti3.zig index afb30950b86a579a4e9edc6ceb4b13d99f102e03..4b7d4599917147cd4960eabfc78e21f19f79a526 100644 --- a/lib/std/special/compiler_rt/divti3.zig +++ b/lib/std/special/compiler_rt/divti3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/divti3_test.zig b/lib/std/special/compiler_rt/divti3_test.zig index 8601cfae030c2f3e47aac8cd076cbbf14c23d5f0..18fab24ed1e7b0e85f632adc33f94adf8c553d63 100644 --- a/lib/std/special/compiler_rt/divti3_test.zig +++ b/lib/std/special/compiler_rt/divti3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __divti3 = @import("divti3.zig").__divti3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/extendXfYf2.zig b/lib/std/special/compiler_rt/extendXfYf2.zig index 6aca0ac98ff62a3d96f5a9e0b1ab323da9c46fac..e0536c04ad618a2293085d367fd0f97465efb213 100644 --- a/lib/std/special/compiler_rt/extendXfYf2.zig +++ b/lib/std/special/compiler_rt/extendXfYf2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = @import("builtin"); const is_test = builtin.is_test; diff --git a/lib/std/special/compiler_rt/extendXfYf2_test.zig b/lib/std/special/compiler_rt/extendXfYf2_test.zig index e2664f6bae12de67100d023598080764ec27dc5c..d82a8baf4cec7294e44a7bc9e6e1d5e557d76a6e 100644 --- a/lib/std/special/compiler_rt/extendXfYf2_test.zig +++ b/lib/std/special/compiler_rt/extendXfYf2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const __extenddftf2 = @import("extendXfYf2.zig").__extenddftf2; const __extendhfsf2 = @import("extendXfYf2.zig").__extendhfsf2; diff --git a/lib/std/special/compiler_rt/fixdfdi.zig b/lib/std/special/compiler_rt/fixdfdi.zig index 11b50091294ed250563d21e1856efc02a8eee8b3..28de1ecd2314f362408e0f83b71bc05e1be3b75d 100644 --- a/lib/std/special/compiler_rt/fixdfdi.zig +++ b/lib/std/special/compiler_rt/fixdfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixdfdi_test.zig b/lib/std/special/compiler_rt/fixdfdi_test.zig index 92dbdc2a5e1a2bc694cd7c2d8f994f1e5f7792c3..83835106cd61a256fe7f9c34fcd8c4df75d31943 100644 --- a/lib/std/special/compiler_rt/fixdfdi_test.zig +++ b/lib/std/special/compiler_rt/fixdfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixdfsi.zig b/lib/std/special/compiler_rt/fixdfsi.zig index 8a6d8da34203bdd102de75614a46610d2ed5efc6..678c75d0c1b2dfdec646d2cd93dc59834e3f1483 100644 --- a/lib/std/special/compiler_rt/fixdfsi.zig +++ b/lib/std/special/compiler_rt/fixdfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixdfsi_test.zig b/lib/std/special/compiler_rt/fixdfsi_test.zig index fb9051889292fa7c1cb921220f744f2954ed2e67..8050a1b9c5b15620b3160775d07e3054635232d9 100644 --- a/lib/std/special/compiler_rt/fixdfsi_test.zig +++ b/lib/std/special/compiler_rt/fixdfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixdfsi = @import("fixdfsi.zig").__fixdfsi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixdfti.zig b/lib/std/special/compiler_rt/fixdfti.zig index 0e21f0ba192147cee20614c3c63657ed90dd8baa..3d9266ae1ff830eba743c4f0c0aad07ef6d90060 100644 --- a/lib/std/special/compiler_rt/fixdfti.zig +++ b/lib/std/special/compiler_rt/fixdfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixdfti_test.zig b/lib/std/special/compiler_rt/fixdfti_test.zig index f66e4a3d88821414e85a442a92775cd42aacc1be..796855b71645d13a4de4717ed20de05a827dfe1a 100644 --- a/lib/std/special/compiler_rt/fixdfti_test.zig +++ b/lib/std/special/compiler_rt/fixdfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixdfti = @import("fixdfti.zig").__fixdfti; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixint.zig b/lib/std/special/compiler_rt/fixint.zig index daf7a1bdc761545e5415e7a53a2f9ec941f83168..0bf0c8be1ef9e9c2bf24908e3f50ae3a5ece79c7 100644 --- a/lib/std/special/compiler_rt/fixint.zig +++ b/lib/std/special/compiler_rt/fixint.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const is_test = @import("builtin").is_test; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixint_test.zig b/lib/std/special/compiler_rt/fixint_test.zig index 4efb1e6ab3a44809e5700074687132309dedb500..49942e5382927f6840d71cd6d6a591065d3ff17c 100644 --- a/lib/std/special/compiler_rt/fixint_test.zig +++ b/lib/std/special/compiler_rt/fixint_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const is_test = @import("builtin").is_test; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixsfdi.zig b/lib/std/special/compiler_rt/fixsfdi.zig index d0d958cdd6b310c295307c0644ae56981b79c4aa..cc5731946dc90a766b2f9022c5131ed5d76585fe 100644 --- a/lib/std/special/compiler_rt/fixsfdi.zig +++ b/lib/std/special/compiler_rt/fixsfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixsfdi_test.zig b/lib/std/special/compiler_rt/fixsfdi_test.zig index 5888c9804d9826565fbf306da9331860b6db6911..d93c3d4218d5d2ebf55acf561b2ccf86d338581f 100644 --- a/lib/std/special/compiler_rt/fixsfdi_test.zig +++ b/lib/std/special/compiler_rt/fixsfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixsfdi = @import("fixsfdi.zig").__fixsfdi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixsfsi.zig b/lib/std/special/compiler_rt/fixsfsi.zig index 84395d0fa67a8689a3e12f1ed1602d16774eb115..62334574b0d0422fc032e4d38eb3ce3dce5be4c6 100644 --- a/lib/std/special/compiler_rt/fixsfsi.zig +++ b/lib/std/special/compiler_rt/fixsfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixsfsi_test.zig b/lib/std/special/compiler_rt/fixsfsi_test.zig index 844235bc9db9290af56fc508bab756671cdfa594..56c28d91ab9c1a4a4ced80ef030a91b820186fbc 100644 --- a/lib/std/special/compiler_rt/fixsfsi_test.zig +++ b/lib/std/special/compiler_rt/fixsfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixsfsi = @import("fixsfsi.zig").__fixsfsi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixsfti.zig b/lib/std/special/compiler_rt/fixsfti.zig index d7ce4b3a602d6ffe9184e418270404fb3d63ab12..31dea953e81cacaa2391b719b81a4709a449a840 100644 --- a/lib/std/special/compiler_rt/fixsfti.zig +++ b/lib/std/special/compiler_rt/fixsfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixsfti_test.zig b/lib/std/special/compiler_rt/fixsfti_test.zig index 9eb2883f38c68480ee9a163edf38f2986eb398bb..d0bdcc4e757b14a791174dceb95bc45db39dd31e 100644 --- a/lib/std/special/compiler_rt/fixsfti_test.zig +++ b/lib/std/special/compiler_rt/fixsfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixsfti = @import("fixsfti.zig").__fixsfti; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixtfdi.zig b/lib/std/special/compiler_rt/fixtfdi.zig index 0ef3aa225937ad6b4af07c725efdce8a1cbba70b..edf70dbe4939954d6dd1f566a9370bc8d6326e28 100644 --- a/lib/std/special/compiler_rt/fixtfdi.zig +++ b/lib/std/special/compiler_rt/fixtfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixtfdi_test.zig b/lib/std/special/compiler_rt/fixtfdi_test.zig index 6baa9011c3ea49ca0f854dd78c9cf7976a744f00..b926f33d50a38aaceafad928bb1000d381b7c7dd 100644 --- a/lib/std/special/compiler_rt/fixtfdi_test.zig +++ b/lib/std/special/compiler_rt/fixtfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixtfdi = @import("fixtfdi.zig").__fixtfdi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixtfsi.zig b/lib/std/special/compiler_rt/fixtfsi.zig index 15e89a11b0b0820fda7bd70ead0a3e36d14b3ac8..cf614ec8b378d99e4b46eb3734bf27896115cf26 100644 --- a/lib/std/special/compiler_rt/fixtfsi.zig +++ b/lib/std/special/compiler_rt/fixtfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixtfsi_test.zig b/lib/std/special/compiler_rt/fixtfsi_test.zig index c7294fe250146af0346957d38c6fba8e07a5c408..86207f7dbcb48f8efcb441cb90caaa8f87c483e8 100644 --- a/lib/std/special/compiler_rt/fixtfsi_test.zig +++ b/lib/std/special/compiler_rt/fixtfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixtfti.zig b/lib/std/special/compiler_rt/fixtfti.zig index 733fa1eed1b0be8f4b89f480f2144712db3f039f..e796b86d503b064f34711a934e6f62e12d6ab0a7 100644 --- a/lib/std/special/compiler_rt/fixtfti.zig +++ b/lib/std/special/compiler_rt/fixtfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixtfti_test.zig b/lib/std/special/compiler_rt/fixtfti_test.zig index 6b8218e2f61a9f1ea1958c4ae8694bd8cb082bc8..65a64ac4311b13b2bb9e4b16077e3f2a9589cdba 100644 --- a/lib/std/special/compiler_rt/fixtfti_test.zig +++ b/lib/std/special/compiler_rt/fixtfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixtfti = @import("fixtfti.zig").__fixtfti; const std = @import("std"); const math = std.math; diff --git a/lib/std/special/compiler_rt/fixuint.zig b/lib/std/special/compiler_rt/fixuint.zig index 1e96b7c2834608ebfc6fa67fe5166f81b9aa9548..01eb03baa52859ef90384a683dfa4851c5d5d12f 100644 --- a/lib/std/special/compiler_rt/fixuint.zig +++ b/lib/std/special/compiler_rt/fixuint.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const is_test = @import("builtin").is_test; const Log2Int = @import("std").math.Log2Int; diff --git a/lib/std/special/compiler_rt/fixunsdfdi.zig b/lib/std/special/compiler_rt/fixunsdfdi.zig index 800c9b1148ad4d3074dc7b1e9f48cee630e2fd17..19f94c95a840efec50eabae54dd74587983e55b7 100644 --- a/lib/std/special/compiler_rt/fixunsdfdi.zig +++ b/lib/std/special/compiler_rt/fixunsdfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunsdfdi_test.zig b/lib/std/special/compiler_rt/fixunsdfdi_test.zig index 67eeb70520cd7df29cbb1a5094ff0afeb51613f4..da6fef33764df92d5285124a3329457ea4094d6a 100644 --- a/lib/std/special/compiler_rt/fixunsdfdi_test.zig +++ b/lib/std/special/compiler_rt/fixunsdfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunsdfsi.zig b/lib/std/special/compiler_rt/fixunsdfsi.zig index 156c21a887b10dea35836310d96435541b22317b..2f622aff39529dbf61242ff30a132550a6021f73 100644 --- a/lib/std/special/compiler_rt/fixunsdfsi.zig +++ b/lib/std/special/compiler_rt/fixunsdfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunsdfsi_test.zig b/lib/std/special/compiler_rt/fixunsdfsi_test.zig index c006473fb95b606788538c9384730f6a884bf53f..ddbb05c70509324fb215482b2822dfdf3b9e5bd8 100644 --- a/lib/std/special/compiler_rt/fixunsdfsi_test.zig +++ b/lib/std/special/compiler_rt/fixunsdfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunsdfti.zig b/lib/std/special/compiler_rt/fixunsdfti.zig index 3dcec6bf8987635352c1841137f88f331e9f422a..f11f6b937f507806a5be284544735baa08d50d5a 100644 --- a/lib/std/special/compiler_rt/fixunsdfti.zig +++ b/lib/std/special/compiler_rt/fixunsdfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunsdfti_test.zig b/lib/std/special/compiler_rt/fixunsdfti_test.zig index 8241900692e086800fc57ee369e379913f176a1a..11ba3bc425442092f1fc915623eb11b98b80520d 100644 --- a/lib/std/special/compiler_rt/fixunsdfti_test.zig +++ b/lib/std/special/compiler_rt/fixunsdfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunssfdi.zig b/lib/std/special/compiler_rt/fixunssfdi.zig index ec00a7ee35c50814414320465012b127eed644b8..5dd9b27d1042ae151a06ad14ad876089dfba06a1 100644 --- a/lib/std/special/compiler_rt/fixunssfdi.zig +++ b/lib/std/special/compiler_rt/fixunssfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunssfdi_test.zig b/lib/std/special/compiler_rt/fixunssfdi_test.zig index e2089822d2bc53dc59adc78594c28b0f90348ad8..018c94ce7c79ebc98ce52486b7009107c9dab703 100644 --- a/lib/std/special/compiler_rt/fixunssfdi_test.zig +++ b/lib/std/special/compiler_rt/fixunssfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunssfsi.zig b/lib/std/special/compiler_rt/fixunssfsi.zig index a4e5a323f5927e856d9f33e34c1df024145fbad3..ce983cb78a8c9e6c440f1a19c1dc07fba0dce3aa 100644 --- a/lib/std/special/compiler_rt/fixunssfsi.zig +++ b/lib/std/special/compiler_rt/fixunssfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunssfsi_test.zig b/lib/std/special/compiler_rt/fixunssfsi_test.zig index 4aee84d2d20f5d95819b1ba3415d6ae648a1c9cd..98cac8a1e40a94fdc988477c9b5bcf2434ceeadf 100644 --- a/lib/std/special/compiler_rt/fixunssfsi_test.zig +++ b/lib/std/special/compiler_rt/fixunssfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunssfti.zig b/lib/std/special/compiler_rt/fixunssfti.zig index dff9eb74980f6136a8af30ea350c3f42d1160ae7..bbaeafd6a8757fe3ba48adeeaabddfa25660ff46 100644 --- a/lib/std/special/compiler_rt/fixunssfti.zig +++ b/lib/std/special/compiler_rt/fixunssfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunssfti_test.zig b/lib/std/special/compiler_rt/fixunssfti_test.zig index 4cb27cbb8a9bdf2652de702e36fe6b1f6f9eb5b1..b5c79906b7af38fcb6d793e1ea2952b9d6d81e37 100644 --- a/lib/std/special/compiler_rt/fixunssfti_test.zig +++ b/lib/std/special/compiler_rt/fixunssfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunstfdi.zig b/lib/std/special/compiler_rt/fixunstfdi.zig index 907116c1650ee53ba9d5b3417ef5ec6253513be9..3062e5322c1fda5d2ac010f99bfe71d9e31cd2b9 100644 --- a/lib/std/special/compiler_rt/fixunstfdi.zig +++ b/lib/std/special/compiler_rt/fixunstfdi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunstfdi_test.zig b/lib/std/special/compiler_rt/fixunstfdi_test.zig index 0d47641c092af8fbfd0b8931da7df0b8faed3be5..299c509ceab49ca3db9cd23b4d7349f9de12ede7 100644 --- a/lib/std/special/compiler_rt/fixunstfdi_test.zig +++ b/lib/std/special/compiler_rt/fixunstfdi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunstfsi.zig b/lib/std/special/compiler_rt/fixunstfsi.zig index c66a3f18b492a2bfa05a91324dbe5784a5db6847..6836e5df36f390d5f003c924274c42e57611421d 100644 --- a/lib/std/special/compiler_rt/fixunstfsi.zig +++ b/lib/std/special/compiler_rt/fixunstfsi.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunstfsi_test.zig b/lib/std/special/compiler_rt/fixunstfsi_test.zig index 286567629a3f7afe45fb746b4ee95915ab672344..2e5139e5e26c8ceee4605de9cdd9548012669a87 100644 --- a/lib/std/special/compiler_rt/fixunstfsi_test.zig +++ b/lib/std/special/compiler_rt/fixunstfsi_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/fixunstfti.zig b/lib/std/special/compiler_rt/fixunstfti.zig index 1867c69234ba49606f774885efba862449e7dedb..da3319ee5c851dd2f8c08b5bf0e494514f5642e4 100644 --- a/lib/std/special/compiler_rt/fixunstfti.zig +++ b/lib/std/special/compiler_rt/fixunstfti.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/fixunstfti_test.zig b/lib/std/special/compiler_rt/fixunstfti_test.zig index 62a9bbfecfb8c4a5832f34083cbd11ef11309fbc..2fbde63e63fc3a48a3ec443e92f25caec937c69a 100644 --- a/lib/std/special/compiler_rt/fixunstfti_test.zig +++ b/lib/std/special/compiler_rt/fixunstfti_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __fixunstfti = @import("fixunstfti.zig").__fixunstfti; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatdidf.zig b/lib/std/special/compiler_rt/floatdidf.zig index afe9e906fd81533a71072ec193bad214bfb85802..2a1ba4cadd80d097d424fda4392677a13a40deaf 100644 --- a/lib/std/special/compiler_rt/floatdidf.zig +++ b/lib/std/special/compiler_rt/floatdidf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatdidf_test.zig b/lib/std/special/compiler_rt/floatdidf_test.zig index c8541838095a4daaf54a6ddf277bb888018985e5..a2072cc922b9281ff30371bf5fd25dd30a63ac6c 100644 --- a/lib/std/special/compiler_rt/floatdidf_test.zig +++ b/lib/std/special/compiler_rt/floatdidf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatdidf = @import("floatdidf.zig").__floatdidf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatditf.zig b/lib/std/special/compiler_rt/floatditf.zig index 581a0e0532bc45f5348db802f4718b6aced93c44..aa945ca5dd9fdad15798c9579d4bbe384788abd1 100644 --- a/lib/std/special/compiler_rt/floatditf.zig +++ b/lib/std/special/compiler_rt/floatditf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatditf_test.zig b/lib/std/special/compiler_rt/floatditf_test.zig index 8cdb8157a960d26f4f3e38ede3844710e8b1ef48..ff4f10927cd75726b97cb2f1c9d17f15e7f2244f 100644 --- a/lib/std/special/compiler_rt/floatditf_test.zig +++ b/lib/std/special/compiler_rt/floatditf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatditf = @import("floatditf.zig").__floatditf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatsiXf.zig b/lib/std/special/compiler_rt/floatsiXf.zig index 6a1dc422b7d75b27d50003ca281a2f3f34f916b1..75db3d704051c390e326eb4fef3f697a0fbdd9e9 100644 --- a/lib/std/special/compiler_rt/floatsiXf.zig +++ b/lib/std/special/compiler_rt/floatsiXf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); const maxInt = std.math.maxInt; diff --git a/lib/std/special/compiler_rt/floattidf.zig b/lib/std/special/compiler_rt/floattidf.zig index 6b5013287b9e45f8a8bdc9ea6e5990a68876a029..73d86f77470d4be77dbc70f0e8194b9e95f66f34 100644 --- a/lib/std/special/compiler_rt/floattidf.zig +++ b/lib/std/special/compiler_rt/floattidf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floattidf_test.zig b/lib/std/special/compiler_rt/floattidf_test.zig index 4914342c31832830e64a1cb7dd6329d26ae17bf3..d299ed80874d2b1354a9a60ed93500c03a9304bb 100644 --- a/lib/std/special/compiler_rt/floattidf_test.zig +++ b/lib/std/special/compiler_rt/floattidf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floattidf = @import("floattidf.zig").__floattidf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floattisf.zig b/lib/std/special/compiler_rt/floattisf.zig index 3f020dadd845c83fec73e046059eaf291af80555..7975d59e8354bd476f5b1e4e2d1273170c421e99 100644 --- a/lib/std/special/compiler_rt/floattisf.zig +++ b/lib/std/special/compiler_rt/floattisf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floattisf_test.zig b/lib/std/special/compiler_rt/floattisf_test.zig index a6aa115307310eaca87e082bedbbac2af538bf40..f5638c2106be224dfa67f08690bdcd16cfb32920 100644 --- a/lib/std/special/compiler_rt/floattisf_test.zig +++ b/lib/std/special/compiler_rt/floattisf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floattisf = @import("floattisf.zig").__floattisf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floattitf.zig b/lib/std/special/compiler_rt/floattitf.zig index 90bc241306fe2be609e32800a4362547eaed911c..87408ea4455094059daed43e9e06fb30351e6f19 100644 --- a/lib/std/special/compiler_rt/floattitf.zig +++ b/lib/std/special/compiler_rt/floattitf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floattitf_test.zig b/lib/std/special/compiler_rt/floattitf_test.zig index 53e3e48bdb6a8cd96aec7ecfb5a4dc098bdd37e1..c4014a62981fec767286fb3d3b0cb43a7dba7ec6 100644 --- a/lib/std/special/compiler_rt/floattitf_test.zig +++ b/lib/std/special/compiler_rt/floattitf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floattitf = @import("floattitf.zig").__floattitf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatundidf.zig b/lib/std/special/compiler_rt/floatundidf.zig index 1efe55da4062babf326dfcddc78b84b0137b7d61..a88ca4a03d4e89a5a0fb7e674008525828b8c793 100644 --- a/lib/std/special/compiler_rt/floatundidf.zig +++ b/lib/std/special/compiler_rt/floatundidf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatundidf_test.zig b/lib/std/special/compiler_rt/floatundidf_test.zig index 084ada51c9077d9a3e8ff1472315593733306063..c0651cb3593239e230454577556ab6bf6a01ac6a 100644 --- a/lib/std/special/compiler_rt/floatundidf_test.zig +++ b/lib/std/special/compiler_rt/floatundidf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatundidf = @import("floatundidf.zig").__floatundidf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatundisf.zig b/lib/std/special/compiler_rt/floatundisf.zig index ff242721d6e09f8e600077b02fa4ec4c196ccf26..b580ec91fd16dac436f4d7636aedf48bcf81eba0 100644 --- a/lib/std/special/compiler_rt/floatundisf.zig +++ b/lib/std/special/compiler_rt/floatundisf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); const maxInt = std.math.maxInt; diff --git a/lib/std/special/compiler_rt/floatunditf.zig b/lib/std/special/compiler_rt/floatunditf.zig index 209f66fc2e0402db558873d0a0a3c9814e317a9c..90191c63882db346fe8ccd12ce3b5f64fced21dd 100644 --- a/lib/std/special/compiler_rt/floatunditf.zig +++ b/lib/std/special/compiler_rt/floatunditf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatunditf_test.zig b/lib/std/special/compiler_rt/floatunditf_test.zig index 7bb3333693d96df77e8a01653e8fc30e6213f625..19d1b4a2a3a732c8f7421bd015c73137336abdbe 100644 --- a/lib/std/special/compiler_rt/floatunditf_test.zig +++ b/lib/std/special/compiler_rt/floatunditf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatunditf = @import("floatunditf.zig").__floatunditf; fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) void { diff --git a/lib/std/special/compiler_rt/floatunsidf.zig b/lib/std/special/compiler_rt/floatunsidf.zig index 771b4938e1cca19354408ff31cb040cdf588b9bb..c9a31eff8ebcca2fbcb463746db907022ec156c7 100644 --- a/lib/std/special/compiler_rt/floatunsidf.zig +++ b/lib/std/special/compiler_rt/floatunsidf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); const maxInt = std.math.maxInt; diff --git a/lib/std/special/compiler_rt/floatunsisf.zig b/lib/std/special/compiler_rt/floatunsisf.zig index c11243e6e43e6628e0563e1448b472b5ef3462e9..17eae5109210c3fb8997db1d9ccc199e2446c2d0 100644 --- a/lib/std/special/compiler_rt/floatunsisf.zig +++ b/lib/std/special/compiler_rt/floatunsisf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); const maxInt = std.math.maxInt; diff --git a/lib/std/special/compiler_rt/floatunsitf.zig b/lib/std/special/compiler_rt/floatunsitf.zig index a10ff6b70378448c60cbe7e00ed5c71d26280f07..ceb55f12c8521109e57b9402b982a028543d49fd 100644 --- a/lib/std/special/compiler_rt/floatunsitf.zig +++ b/lib/std/special/compiler_rt/floatunsitf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatunsitf_test.zig b/lib/std/special/compiler_rt/floatunsitf_test.zig index 52e4786903e5c9605de536b5149caeb81256581d..deb95ca3964123dd1c71717d447047c50bda99b8 100644 --- a/lib/std/special/compiler_rt/floatunsitf_test.zig +++ b/lib/std/special/compiler_rt/floatunsitf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatunsitf = @import("floatunsitf.zig").__floatunsitf; fn test__floatunsitf(a: u64, expected_hi: u64, expected_lo: u64) void { diff --git a/lib/std/special/compiler_rt/floatuntidf.zig b/lib/std/special/compiler_rt/floatuntidf.zig index 5b5adc04910af64e03de2a12765896f0b2660d2f..adb804d0ec4d8c27f99474a46a8cb426c874387a 100644 --- a/lib/std/special/compiler_rt/floatuntidf.zig +++ b/lib/std/special/compiler_rt/floatuntidf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatuntidf_test.zig b/lib/std/special/compiler_rt/floatuntidf_test.zig index 974f3e4be3e2c55a9c0ed04d47ef52655e2e8253..cce38938602e0a691a65be71d52e3808a3e4ecc9 100644 --- a/lib/std/special/compiler_rt/floatuntidf_test.zig +++ b/lib/std/special/compiler_rt/floatuntidf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatuntidf = @import("floatuntidf.zig").__floatuntidf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatuntisf.zig b/lib/std/special/compiler_rt/floatuntisf.zig index 33e6e41a84fcb28ecdf21f8d447ba58227208ca9..d0c9a7656287af63462bff0fd406b3dd668cc2fd 100644 --- a/lib/std/special/compiler_rt/floatuntisf.zig +++ b/lib/std/special/compiler_rt/floatuntisf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatuntisf_test.zig b/lib/std/special/compiler_rt/floatuntisf_test.zig index 3a9780706694e37bcba71f919c622810d247f1da..42379d808487ee876b872ed65d933b03486ea8fd 100644 --- a/lib/std/special/compiler_rt/floatuntisf_test.zig +++ b/lib/std/special/compiler_rt/floatuntisf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatuntisf = @import("floatuntisf.zig").__floatuntisf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/floatuntitf.zig b/lib/std/special/compiler_rt/floatuntitf.zig index 0b96076206dbdb69368519a94cd4121032151abf..c87ff50e9a64f0d666d2b0962b6a3b047b1f4295 100644 --- a/lib/std/special/compiler_rt/floatuntitf.zig +++ b/lib/std/special/compiler_rt/floatuntitf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); diff --git a/lib/std/special/compiler_rt/floatuntitf_test.zig b/lib/std/special/compiler_rt/floatuntitf_test.zig index 09f3eabb3e60a79f7de5d115b270a7ca39584cd8..62c9b631dff4a14a91482b7cba0b021079c0aa70 100644 --- a/lib/std/special/compiler_rt/floatuntitf_test.zig +++ b/lib/std/special/compiler_rt/floatuntitf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __floatuntitf = @import("floatuntitf.zig").__floatuntitf; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/int.zig b/lib/std/special/compiler_rt/int.zig index a72c13e2331e6c2b1bc705a2405fbfe334acebe0..141c4e52c16e602fa252f0d6e3fe70cfff7f4e17 100644 --- a/lib/std/special/compiler_rt/int.zig +++ b/lib/std/special/compiler_rt/int.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Builtin functions that operate on integer types const builtin = @import("builtin"); const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/lshrdi3_test.zig b/lib/std/special/compiler_rt/lshrdi3_test.zig index 906d428d1e27424eba5659082c3bb227947569f0..de83f0a9c8b9770278448972651aa84e1140ada6 100644 --- a/lib/std/special/compiler_rt/lshrdi3_test.zig +++ b/lib/std/special/compiler_rt/lshrdi3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __lshrdi3 = @import("shift.zig").__lshrdi3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/lshrti3_test.zig b/lib/std/special/compiler_rt/lshrti3_test.zig index c0aa191a6f628859151cbaed16c6b863c8a2f571..f831e8b1328d9e95e017568070a8ae49b31074c7 100644 --- a/lib/std/special/compiler_rt/lshrti3_test.zig +++ b/lib/std/special/compiler_rt/lshrti3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __lshrti3 = @import("shift.zig").__lshrti3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/modti3.zig b/lib/std/special/compiler_rt/modti3.zig index 78be44026c027311208392983143b037adfe6cf0..1f859c2329136b10877ab65015ec5a55995c4723 100644 --- a/lib/std/special/compiler_rt/modti3.zig +++ b/lib/std/special/compiler_rt/modti3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/modti3.c diff --git a/lib/std/special/compiler_rt/modti3_test.zig b/lib/std/special/compiler_rt/modti3_test.zig index 10f81d59d2fd53c42e5711178dbcc2be32e65b8e..cad60c015eb94d785f98d8ddd46f51fb0e6dc8be 100644 --- a/lib/std/special/compiler_rt/modti3_test.zig +++ b/lib/std/special/compiler_rt/modti3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __modti3 = @import("modti3.zig").__modti3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/mulXf3.zig b/lib/std/special/compiler_rt/mulXf3.zig index af49d27952aae1196733e84e26df329a2bcf584c..b6984ebbb690cb834de4738682140a1e18ab41e3 100644 --- a/lib/std/special/compiler_rt/mulXf3.zig +++ b/lib/std/special/compiler_rt/mulXf3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc diff --git a/lib/std/special/compiler_rt/mulXf3_test.zig b/lib/std/special/compiler_rt/mulXf3_test.zig index 57dc38532174095c9fda6f4cc028bf5bbc3766d0..c9994b089ba96dda9a82dec2befb2473dd190d6e 100644 --- a/lib/std/special/compiler_rt/mulXf3_test.zig +++ b/lib/std/special/compiler_rt/mulXf3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Ported from: // // https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c diff --git a/lib/std/special/compiler_rt/muldi3.zig b/lib/std/special/compiler_rt/muldi3.zig index 4f605d441cb7c0a68bc392d3b6a6691ee495e1d8..2de96ea66c79e8aebbe3139d16cfe6ac27a8f4ec 100644 --- a/lib/std/special/compiler_rt/muldi3.zig +++ b/lib/std/special/compiler_rt/muldi3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); // Ported from diff --git a/lib/std/special/compiler_rt/muldi3_test.zig b/lib/std/special/compiler_rt/muldi3_test.zig index db4daf1e1ef09c74353572a8ad51350b8e8ba0d4..b4962189cd250fd5bc66749bd717360635039a58 100644 --- a/lib/std/special/compiler_rt/muldi3_test.zig +++ b/lib/std/special/compiler_rt/muldi3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __muldi3 = @import("muldi3.zig").__muldi3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/mulodi4.zig b/lib/std/special/compiler_rt/mulodi4.zig index b70d1657e71130f8c0038c7ddbf1aad43e59bc7e..b05931e93763892feaac8164c8c15fa532765bf5 100644 --- a/lib/std/special/compiler_rt/mulodi4.zig +++ b/lib/std/special/compiler_rt/mulodi4.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); const maxInt = std.math.maxInt; diff --git a/lib/std/special/compiler_rt/mulodi4_test.zig b/lib/std/special/compiler_rt/mulodi4_test.zig index 803d60e8fa827988847d5ab62d953c0b9669e80a..a96f7a1996ee72909e256751bc13e6e0a342cfb5 100644 --- a/lib/std/special/compiler_rt/mulodi4_test.zig +++ b/lib/std/special/compiler_rt/mulodi4_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __mulodi4 = @import("mulodi4.zig").__mulodi4; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/muloti4.zig b/lib/std/special/compiler_rt/muloti4.zig index 190959b8014e3275ff61524a2e6aeceb31907f78..4beafa3e154e645dd3ce28b409b9aaba61b25279 100644 --- a/lib/std/special/compiler_rt/muloti4.zig +++ b/lib/std/special/compiler_rt/muloti4.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); diff --git a/lib/std/special/compiler_rt/muloti4_test.zig b/lib/std/special/compiler_rt/muloti4_test.zig index f94a13e04f9b8ead3b4c305e50bb5392755fbdd3..44ab93a0699dbb070640cdc5d9fa6928454277a1 100644 --- a/lib/std/special/compiler_rt/muloti4_test.zig +++ b/lib/std/special/compiler_rt/muloti4_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __muloti4 = @import("muloti4.zig").__muloti4; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/multi3.zig b/lib/std/special/compiler_rt/multi3.zig index c237f1b259de431cf1d6f707a62bf5f9b7726b46..fad73789ac601e11361491eaf0df916b96c6648a 100644 --- a/lib/std/special/compiler_rt/multi3.zig +++ b/lib/std/special/compiler_rt/multi3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); diff --git a/lib/std/special/compiler_rt/multi3_test.zig b/lib/std/special/compiler_rt/multi3_test.zig index 92c580e20f19724b8728505f7cdd5c8e167339f3..04b70d05385353413b15fa3f3d97be6116977677 100644 --- a/lib/std/special/compiler_rt/multi3_test.zig +++ b/lib/std/special/compiler_rt/multi3_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __multi3 = @import("multi3.zig").__multi3; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/negXf2.zig b/lib/std/special/compiler_rt/negXf2.zig index 0739ecb83c8e7912caa68883fe45d351d44862fe..11f9e401e95ba6e84b4ac0a7bdcbb2eaadaa340d 100644 --- a/lib/std/special/compiler_rt/negXf2.zig +++ b/lib/std/special/compiler_rt/negXf2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); pub fn __negsf2(a: f32) callconv(.C) f32 { diff --git a/lib/std/special/compiler_rt/popcountdi2.zig b/lib/std/special/compiler_rt/popcountdi2.zig index b7e7220c7b8c109ab8f49e74d1b0e067e561c0fd..5bb49ce402f7ec5715150244ac734b13d8ceb35e 100644 --- a/lib/std/special/compiler_rt/popcountdi2.zig +++ b/lib/std/special/compiler_rt/popcountdi2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); diff --git a/lib/std/special/compiler_rt/popcountdi2_test.zig b/lib/std/special/compiler_rt/popcountdi2_test.zig index fe02786e15bd1dc918497d7ca570989907e4b588..6ea181bf0e12a403d852ded4fd3d5397f12d0cc5 100644 --- a/lib/std/special/compiler_rt/popcountdi2_test.zig +++ b/lib/std/special/compiler_rt/popcountdi2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __popcountdi2 = @import("popcountdi2.zig").__popcountdi2; const testing = @import("std").testing; diff --git a/lib/std/special/compiler_rt/shift.zig b/lib/std/special/compiler_rt/shift.zig index f811c5124d66dfc71197daa8f63c6e4cfe7d20ec..1609cb115ce8411889b466fb8194e90a63f7fff0 100644 --- a/lib/std/special/compiler_rt/shift.zig +++ b/lib/std/special/compiler_rt/shift.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; const Log2Int = std.math.Log2Int; diff --git a/lib/std/special/compiler_rt/stack_probe.zig b/lib/std/special/compiler_rt/stack_probe.zig index dd441b2f329ff14a2303d0d544b231f43126e407..58cce9fb6f9d987b34a393de3f47b1839529ba6d 100644 --- a/lib/std/special/compiler_rt/stack_probe.zig +++ b/lib/std/special/compiler_rt/stack_probe.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); // Zig's own stack-probe routine (available only on x86 and x86_64) diff --git a/lib/std/special/compiler_rt/truncXfYf2.zig b/lib/std/special/compiler_rt/truncXfYf2.zig index d345bf30a3cc8b595d7ef40cef0730617455fbe1..e096e7e4f0a2246763e7713a3fb76140f6cc490d 100644 --- a/lib/std/special/compiler_rt/truncXfYf2.zig +++ b/lib/std/special/compiler_rt/truncXfYf2.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); pub fn __truncsfhf2(a: f32) callconv(.C) u16 { diff --git a/lib/std/special/compiler_rt/truncXfYf2_test.zig b/lib/std/special/compiler_rt/truncXfYf2_test.zig index baec2a445061f8a6b5eae624bb2a0dd6b79ab1a9..048005f86d9e264d3ef341998d72393bac27a176 100644 --- a/lib/std/special/compiler_rt/truncXfYf2_test.zig +++ b/lib/std/special/compiler_rt/truncXfYf2_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const __truncsfhf2 = @import("truncXfYf2.zig").__truncsfhf2; fn test__truncsfhf2(a: u32, expected: u16) void { diff --git a/lib/std/special/compiler_rt/udivmod.zig b/lib/std/special/compiler_rt/udivmod.zig index ba53d1dee01cf9b00358cdb568b9e43ef0c02e87..2836f34c8550bf296f9ffd07e5eed5ddc97c0e48 100644 --- a/lib/std/special/compiler_rt/udivmod.zig +++ b/lib/std/special/compiler_rt/udivmod.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const is_test = builtin.is_test; diff --git a/lib/std/special/compiler_rt/udivmoddi4_test.zig b/lib/std/special/compiler_rt/udivmoddi4_test.zig index 48a38faa044fcdaf60301ae45e62ba5a9b3d4fa2..74a4a828e85e6b8243f6d763b0cc514fb3cdfba0 100644 --- a/lib/std/special/compiler_rt/udivmoddi4_test.zig +++ b/lib/std/special/compiler_rt/udivmoddi4_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Disable formatting to avoid unnecessary source repository bloat. // zig fmt: off const __udivmoddi4 = @import("int.zig").__udivmoddi4; diff --git a/lib/std/special/compiler_rt/udivmodti4.zig b/lib/std/special/compiler_rt/udivmodti4.zig index cc1141dbbca1e8f7faa7dab8ec4516602db04c0c..ff33a35680b0dea3fc2e6939836ad39d0fd84f91 100644 --- a/lib/std/special/compiler_rt/udivmodti4.zig +++ b/lib/std/special/compiler_rt/udivmodti4.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); diff --git a/lib/std/special/compiler_rt/udivmodti4_test.zig b/lib/std/special/compiler_rt/udivmodti4_test.zig index fdeae7c02b9dfd9140c4bd8ef3aeee881ab6d743..1852d5c7afdfadd52595b18cdca667c053a74f9d 100644 --- a/lib/std/special/compiler_rt/udivmodti4_test.zig +++ b/lib/std/special/compiler_rt/udivmodti4_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // Disable formatting to avoid unnecessary source repository bloat. // zig fmt: off const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; diff --git a/lib/std/special/compiler_rt/udivti3.zig b/lib/std/special/compiler_rt/udivti3.zig index 52afa0420f5d6dd8a7ca92e80491589c3e56c32a..187b4a15773de84431a194c37374e5739ed43f8d 100644 --- a/lib/std/special/compiler_rt/udivti3.zig +++ b/lib/std/special/compiler_rt/udivti3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); diff --git a/lib/std/special/compiler_rt/umodti3.zig b/lib/std/special/compiler_rt/umodti3.zig index 29eb572892b404f7e81599a79e47e9563b50de06..3bc5be8ffc85de0db56a368d2355e3b75740c8d4 100644 --- a/lib/std/special/compiler_rt/umodti3.zig +++ b/lib/std/special/compiler_rt/umodti3.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); diff --git a/lib/std/special/init-exe/build.zig b/lib/std/special/init-exe/build.zig index fd71588c5f18ba5901cfa635f897aff9b632a1a4..db818cbe920b23fb7491bd3d8e297571f7f525ac 100644 --- a/lib/std/special/init-exe/build.zig +++ b/lib/std/special/init-exe/build.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const Builder = @import("std").build.Builder; pub fn build(b: *Builder) void { diff --git a/lib/std/special/init-exe/src/main.zig b/lib/std/special/init-exe/src/main.zig index d29869ff88feb94cd5a5fd28d760824920f269ac..e4b2e7d8ece5b54ff56901bc338589d1f02b8023 100644 --- a/lib/std/special/init-exe/src/main.zig +++ b/lib/std/special/init-exe/src/main.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); pub fn main() anyerror!void { diff --git a/lib/std/special/init-lib/build.zig b/lib/std/special/init-lib/build.zig index 558e447c1547e40dc97c85e643a7695334dbdbf7..edc8a0215d2623e33ea812ed1189296c63889458 100644 --- a/lib/std/special/init-lib/build.zig +++ b/lib/std/special/init-lib/build.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const Builder = @import("std").build.Builder; pub fn build(b: *Builder) void { diff --git a/lib/std/special/init-lib/src/main.zig b/lib/std/special/init-lib/src/main.zig index 747bb08573c1d6322417b5b8550631ad2ca1bad9..9a82bcc26b4b227492595fd7beaf530ad4139ccf 100644 --- a/lib/std/special/init-lib/src/main.zig +++ b/lib/std/special/init-lib/src/main.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const testing = std.testing; diff --git a/lib/std/special/test_runner.zig b/lib/std/special/test_runner.zig index 426715163825936c2077cdf0afc384f7aef7b83b..87b011ede89bac9f522ec4aa43c9ead852117b7d 100644 --- a/lib/std/special/test_runner.zig +++ b/lib/std/special/test_runner.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const io = std.io; const builtin = @import("builtin"); diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig index 0af08e9a84f77ab7516c28c710c8ccc4022a1aa0..d72ac14ecfd98ba9833713716d9069bbb65729b8 100644 --- a/lib/std/spinlock.zig +++ b/lib/std/spinlock.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = @import("builtin"); diff --git a/lib/std/start.zig b/lib/std/start.zig index 811e05012fd06cbfe4cb245e11ffca38a6a53bfb..2b1bae060e69f4e95bad94e8cfb067faca3c9779 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. // This file is included in the compilation unit when exporting an executable. const root = @import("root"); diff --git a/lib/std/start_windows_tls.zig b/lib/std/start_windows_tls.zig index f6dd2bc13261c6946b8669baf9cded8b286f75ca..18c016d2065c28a766e8661b8ae4c3b0fb706a4c 100644 --- a/lib/std/start_windows_tls.zig +++ b/lib/std/start_windows_tls.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const builtin = std.builtin; diff --git a/lib/std/std.zig b/lib/std/std.zig index 940fc498d6350ffdc570e1ce8798f86afc76e6ab..2ff44f5e414beca00f8ce641244c2f1976478129 100644 --- a/lib/std/std.zig +++ b/lib/std/std.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. pub const ArrayList = @import("array_list.zig").ArrayList; pub const ArrayListAligned = @import("array_list.zig").ArrayListAligned; pub const ArrayListAlignedUnmanaged = @import("array_list.zig").ArrayListAlignedUnmanaged; diff --git a/lib/std/target.zig b/lib/std/target.zig index 14cea9dd573a9ca35ad618148b8506ae1eb8a6da..b162bdd0c3717f5b89af0f10d7cab2fabc5d9406 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const mem = std.mem; const builtin = std.builtin; diff --git a/lib/std/target/aarch64.zig b/lib/std/target/aarch64.zig index 9af95dfadad0201d3baf3f59c19f894fa184376a..0f64b2fd69422cbc20007bc5a504ed69ac945b77 100644 --- a/lib/std/target/aarch64.zig +++ b/lib/std/target/aarch64.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/amdgpu.zig b/lib/std/target/amdgpu.zig index 4b3f83bbc317ddfa6f2b0cb84fe1f6cabeb32f05..9fa52c317d4b6dfcd43a64e0d0faedf428a0b9d0 100644 --- a/lib/std/target/amdgpu.zig +++ b/lib/std/target/amdgpu.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/arm.zig b/lib/std/target/arm.zig index 90b060c03ff4dc2e7794028cb0bc0a78f9228e85..e96a9aa4e603499a080b11e10299f79f8efab185 100644 --- a/lib/std/target/arm.zig +++ b/lib/std/target/arm.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/avr.zig b/lib/std/target/avr.zig index af4f5ba5be9792ecb4af02114590b5ba295686a5..3ad603eabe71f336ffbaa3c21c0b2ced3c70fe15 100644 --- a/lib/std/target/avr.zig +++ b/lib/std/target/avr.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/bpf.zig b/lib/std/target/bpf.zig index ddb12d3d8515a6916a5ca67f9933cc0a5afdfb39..5e23c233c8d54c0fe21b620eef35da2efe16f240 100644 --- a/lib/std/target/bpf.zig +++ b/lib/std/target/bpf.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/hexagon.zig b/lib/std/target/hexagon.zig index f429099d882f3da38b4fdda834c78c5ae71fd0b6..c5eac1886ff5b5edabfecc5946232a0bd97b9373 100644 --- a/lib/std/target/hexagon.zig +++ b/lib/std/target/hexagon.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/mips.zig b/lib/std/target/mips.zig index fc95b2dee8e7811c72bbc7437c5a8967a8cea4b5..6d82caf0c0a0414cf765470c28fcda4d1e1d7a5d 100644 --- a/lib/std/target/mips.zig +++ b/lib/std/target/mips.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/msp430.zig b/lib/std/target/msp430.zig index 947137b3e28cd1e7e3a399b68f82f3a83a4b3843..38ea358f905143beb5c33d54f3046d6060c553fb 100644 --- a/lib/std/target/msp430.zig +++ b/lib/std/target/msp430.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/nvptx.zig b/lib/std/target/nvptx.zig index d719a6bb7196decc107967f0826fde42286ae1ed..1282c48e1a4cd1ddfedba113bea07050764e100b 100644 --- a/lib/std/target/nvptx.zig +++ b/lib/std/target/nvptx.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/powerpc.zig b/lib/std/target/powerpc.zig index 19b050c5bd8823bfddc90e5dede196f38ec04bf8..e13e3dd97f92ad5c4f072cf474d2187d736e7c43 100644 --- a/lib/std/target/powerpc.zig +++ b/lib/std/target/powerpc.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/riscv.zig b/lib/std/target/riscv.zig index dbdb1070245140f847f48eb3d86102653d4166e6..9d4429bd5c476d489f075faf6a4324eaf1e01634 100644 --- a/lib/std/target/riscv.zig +++ b/lib/std/target/riscv.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/sparc.zig b/lib/std/target/sparc.zig index e1cbc845fca2dacdcdaeb3800e4dd7af68901696..8baac12635022a3c40506528061695868882a6b5 100644 --- a/lib/std/target/sparc.zig +++ b/lib/std/target/sparc.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/systemz.zig b/lib/std/target/systemz.zig index f065a8b1694753a203633b7937d3fa2d781be5af..4f3415626c0eaaf432783f894accc3d58c32f7b5 100644 --- a/lib/std/target/systemz.zig +++ b/lib/std/target/systemz.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/wasm.zig b/lib/std/target/wasm.zig index 72b2b6d4312a76ecb96d727d1eab812ab2954612..3021834ec42e9a18f3a97047b60b67665c2ee62a 100644 --- a/lib/std/target/wasm.zig +++ b/lib/std/target/wasm.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/target/x86.zig b/lib/std/target/x86.zig index bfcd1abc1a33d59499bee93c3d83d901b3766ba1..61219e13b0990489bb75727f76a5c2fe1a0f644a 100644 --- a/lib/std/target/x86.zig +++ b/lib/std/target/x86.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 27026149bc0d272927f83004d054179872e7830b..658d31bb8272c82574b830b6cf84dfd31818227f 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const print = std.debug.print; diff --git a/lib/std/testing/failing_allocator.zig b/lib/std/testing/failing_allocator.zig index d8b243d0fae5172d4421fc58cf654098348f060f..61912e693334ea9edd8f7afe37d00fa8a02b2b49 100644 --- a/lib/std/testing/failing_allocator.zig +++ b/lib/std/testing/failing_allocator.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const mem = std.mem; diff --git a/lib/std/thread.zig b/lib/std/thread.zig index 3d20f54558d46f0aeabbd2690ed2e9d7a2faa4ae..d73907690e5047084d9ced561169f1a54f681f85 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const os = std.os; diff --git a/lib/std/time.zig b/lib/std/time.zig index 6a0b9a13aa900fdc8263e5be09913fe42d1a18cf..ae128f6b0c7d7ac1676c7f6d6868ae8d124a8267 100644 --- a/lib/std/time.zig +++ b/lib/std/time.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const builtin = std.builtin; const assert = std.debug.assert; diff --git a/lib/std/time/epoch.zig b/lib/std/time/epoch.zig index 126c4fceb7386266e28102644dd65ed53e84bcbf..3a42c85a6dc52cfe14e83d2d74929da5494a8103 100644 --- a/lib/std/time/epoch.zig +++ b/lib/std/time/epoch.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. //! Epoch reference times in terms of their difference from //! UTC 1970-01-01 in seconds. diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig index 2c88d2ba0c936853d5c3a96b893b8d5b8fc60dfc..86b805b8926ec723bd559b97e239b0ea37ec5967 100644 --- a/lib/std/unicode.zig +++ b/lib/std/unicode.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("./std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig index 050340cd556afed74e79767a7cea3e24e1ac3822..e59953a21f306bb9ac205acfecab4f49b1c3dd43 100644 --- a/lib/std/unicode/throughput_test.zig +++ b/lib/std/unicode/throughput_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); diff --git a/lib/std/valgrind.zig b/lib/std/valgrind.zig index 38c4a491e0e1d5643596cd99f03c9f15a3d7b155..5373a2d513d4893d45b7f72cb821708b9cb60b1e 100644 --- a/lib/std/valgrind.zig +++ b/lib/std/valgrind.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std.zig"); const math = std.math; diff --git a/lib/std/valgrind/callgrind.zig b/lib/std/valgrind/callgrind.zig index 82725e91037efe1f7e56769f9a1c9394c984387b..5e025c4ffec1fb4817abb7dff693dbd946b38581 100644 --- a/lib/std/valgrind/callgrind.zig +++ b/lib/std/valgrind/callgrind.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const valgrind = std.valgrind; diff --git a/lib/std/valgrind/memcheck.zig b/lib/std/valgrind/memcheck.zig index e0aefa7d5f3003dec92f953721d243ddff9f3f62..449b4c4a462c628d29da2259d48c8ee9ea6c0f08 100644 --- a/lib/std/valgrind/memcheck.zig +++ b/lib/std/valgrind/memcheck.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const testing = std.testing; const valgrind = std.valgrind; diff --git a/lib/std/zig.zig b/lib/std/zig.zig index ab6895e1bf73679ad9bd186e3a58b97af2e2301e..34e03eb1648c3e1b99b214f53adca9db5750f0be 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std.zig"); const tokenizer = @import("zig/tokenizer.zig"); diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index f5149e3a82fe5a6257796fa60bb4cc8f65091b58..f6ba29a9ef7aca000f72137b188a39f2593fe728 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const testing = std.testing; diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index 5466b39f0bf499baa751c6a1f175b485905581c7..75fc5969a5c282d9ba1b95c88ce488bb71927ecb 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const Target = std.Target; diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index e0eb2dd8953e89b66d3c53224b99c6e3ab262587..2af2ee4a45448905c3383f33199ec83dc8a53651 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 87807255b0d47ce786ebb9d507fc28aaaca3eb6e..8259af32a6993eefa9c2f7215e49c9436d55cfd1 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. test "zig fmt: convert var to anytype" { // TODO remove in next release cycle try testTransform( diff --git a/lib/std/zig/perf_test.zig b/lib/std/zig/perf_test.zig index 689fea96f6c685ca14e1bf4995f64618e20298c3..30ae99e57c60db6c2bc0cd0e5d594b4e91b11016 100644 --- a/lib/std/zig/perf_test.zig +++ b/lib/std/zig/perf_test.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const mem = std.mem; const warn = std.debug.warn; diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 7b9036f259074117769657d0e0b0153d1dc4273c..4d44c41bfa88bd85f59e23c516379bd8e8f80ddf 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; const mem = std.mem; diff --git a/lib/std/zig/string_literal.zig b/lib/std/zig/string_literal.zig index 560a233723142f82ad82ce2bf52e85c8c5c761de..ca3585944eff935dd6c2b91620fa57d1178c7ea1 100644 --- a/lib/std/zig/string_literal.zig +++ b/lib/std/zig/string_literal.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const assert = std.debug.assert; diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index be47da46bb435fe688ba15cd0d445702e496b15c..175b0e4555da54c812e17ade2f01888694131b75 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const elf = std.elf; const mem = std.mem; diff --git a/lib/std/zig/system/macos.zig b/lib/std/zig/system/macos.zig index dd34fe26f9ee1cd963887d7b1cbd7653ede872fb..e0e69b6b8b40ad90061ee4354240aaf3b51a59f5 100644 --- a/lib/std/zig/system/macos.zig +++ b/lib/std/zig/system/macos.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); pub fn version_from_build(build: []const u8) !std.builtin.Version { diff --git a/lib/std/zig/system/x86.zig b/lib/std/zig/system/x86.zig index b4964596d2080920aad1de1ff76c34e53c2ac1c6..cbede308dc69d3b7c04256a39c86ff844588f498 100644 --- a/lib/std/zig/system/x86.zig +++ b/lib/std/zig/system/x86.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("std"); const Target = std.Target; const CrossTarget = std.zig.CrossTarget; diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index 7f9c6f628895885463d629b40148140218b5c02c..47c7d23b354de838347e8d65f95eb3e899517007 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2015-2020 Zig Contributors +// This file is part of [zig](https://ziglang.org/), which is MIT licensed. +// The MIT license requires this copyright notice to be included in all copies +// and substantial portions of the software. const std = @import("../std.zig"); const mem = std.mem; diff --git a/test/stack_traces.zig b/test/stack_traces.zig index 616136b9ee749b06a57d3bc2e431ba158f33f0aa..2ab022e6ecc8b0daa8daa91f49c8831f6412937b 100644 --- a/test/stack_traces.zig +++ b/test/stack_traces.zig @@ -282,10 +282,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\source.zig:10:8: [address] in main (test) \\ foo(); \\ ^ - \\start.zig:249:29: [address] in std.start.posixCallMainAndExit (test) + \\start.zig:254:29: [address] in std.start.posixCallMainAndExit (test) \\ return root.main(); \\ ^ - \\start.zig:123:5: [address] in std.start._start (test) + \\start.zig:128:5: [address] in std.start._start (test) \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); \\ ^ \\ @@ -294,7 +294,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { switch (std.Target.current.cpu.arch) { .aarch64 => "", // TODO disabled; results in segfault else => - \\start.zig:123:5: [address] in std.start._start (test) + \\start.zig:128:5: [address] in std.start._start (test) \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); \\ ^ \\ -- 2.54.0 From 1a4059ed88740c0289b7fea5735115fa9481a8e5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 13:16:04 -0700 Subject: [PATCH 39/66] allow running the stage2 tests in release mode --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 2536b24bc0635b6022d7f7491a6a2f689ab24f59..9c50025375dc156be79f43d7b488653b313547f8 100644 --- a/build.zig +++ b/build.zig @@ -38,7 +38,7 @@ pub fn build(b: *Builder) !void { const test_step = b.step("test", "Run all the tests"); var test_stage2 = b.addTest("src-self-hosted/test.zig"); - test_stage2.setBuildMode(.Debug); // note this is only the mode of the test harness + test_stage2.setBuildMode(mode); test_stage2.addPackagePath("stage2_tests", "test/stage2/test.zig"); const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"}); -- 2.54.0 From 6f9ea9eaef79863ebdc9bf44b2af67ec4caad031 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 19 Aug 2020 16:21:05 +0200 Subject: [PATCH 40/66] Breaking: sort std/crypto functions into categories Instead of having all primitives and constructions share the same namespace, they are now organized by category and function family. Types within the same category are expected to share the exact same API. --- lib/std/bloom_filter.zig | 2 +- lib/std/build/write_file.zig | 2 +- lib/std/cache_hash.zig | 2 +- lib/std/crypto.zig | 129 ++++++++++++++++------------- lib/std/crypto/25519/ed25519.zig | 2 +- lib/std/crypto/benchmark.zig | 33 ++++---- lib/std/crypto/chacha20.zig | 134 ++++++++++++++++--------------- lib/std/crypto/gimli.zig | 10 ++- lib/std/crypto/hmac.zig | 23 ++++-- lib/std/crypto/md5.zig | 26 +++--- lib/std/crypto/sha1.zig | 28 ++++--- lib/std/crypto/sha2.zig | 31 +++---- lib/std/crypto/sha3.zig | 10 +-- lib/std/rand.zig | 4 +- lib/std/zig.zig | 2 +- tools/process_headers.zig | 2 +- 16 files changed, 244 insertions(+), 196 deletions(-) diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig index 34fa42fe00064873349a7ad8c31df5c52c06bcab..5ccef8d1408dd584cfd6f6a71c3b83cd8c6d5ec3 100644 --- a/lib/std/bloom_filter.zig +++ b/lib/std/bloom_filter.zig @@ -158,7 +158,7 @@ pub fn BloomFilter( } fn hashFunc(out: []u8, Ki: usize, in: []const u8) void { - var st = std.crypto.gimli.Hash.init(); + var st = std.crypto.hash.Gimli.init(); st.update(std.mem.asBytes(&Ki)); st.update(in); st.final(out); diff --git a/lib/std/build/write_file.zig b/lib/std/build/write_file.zig index fe15e6e0e30b5d985b0723c9e66b4081e42d73a1..222de7c79ab76a5918e6ab02848ebf24a2def1ff 100644 --- a/lib/std/build/write_file.zig +++ b/lib/std/build/write_file.zig @@ -58,7 +58,7 @@ pub const WriteFileStep = struct { // TODO port the cache system from stage1 to zig std lib. Until then we use blake2b // directly and construct the path, and no "cache hit" detection happens; the files // are always written. - var hash = std.crypto.Blake2b384.init(); + var hash = std.crypto.hash.blake2.Blake2b384.init(); // Random bytes to make WriteFileStep unique. Refresh this with // new random bytes when WriteFileStep implementation is modified diff --git a/lib/std/cache_hash.zig b/lib/std/cache_hash.zig index 58c9f444f31ae252603f3e30b70b596d3af8bf02..802592934779423d04817824a2b9157843ec8935 100644 --- a/lib/std/cache_hash.zig +++ b/lib/std/cache_hash.zig @@ -4,7 +4,7 @@ // The MIT license requires this copyright notice to be included in all copies // and substantial portions of the software. const std = @import("std.zig"); -const Blake3 = std.crypto.Blake3; +const Blake3 = std.crypto.hash.Blake3; const fs = std.fs; const base64 = std.base64; const ArrayList = std.ArrayList; diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index edca2bc2ff4775368aa75c8ba8d5b914865bca11..2a18bd88c78d4f3827ba77aa0455b161fa2ed3b9 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -3,60 +3,68 @@ // This file is part of [zig](https://ziglang.org/), which is MIT licensed. // The MIT license requires this copyright notice to be included in all copies // and substantial portions of the software. -pub const Md5 = @import("crypto/md5.zig").Md5; -pub const Sha1 = @import("crypto/sha1.zig").Sha1; - -const sha2 = @import("crypto/sha2.zig"); -pub const Sha224 = sha2.Sha224; -pub const Sha256 = sha2.Sha256; -pub const Sha384 = sha2.Sha384; -pub const Sha512 = sha2.Sha512; - -const sha3 = @import("crypto/sha3.zig"); -pub const Sha3_224 = sha3.Sha3_224; -pub const Sha3_256 = sha3.Sha3_256; -pub const Sha3_384 = sha3.Sha3_384; -pub const Sha3_512 = sha3.Sha3_512; - -pub const gimli = @import("crypto/gimli.zig"); - -const blake2 = @import("crypto/blake2.zig"); -pub const Blake2s224 = blake2.Blake2s224; -pub const Blake2s256 = blake2.Blake2s256; -pub const Blake2b384 = blake2.Blake2b384; -pub const Blake2b512 = blake2.Blake2b512; - -pub const Blake3 = @import("crypto/blake3.zig").Blake3; - -const hmac = @import("crypto/hmac.zig"); -pub const HmacMd5 = hmac.HmacMd5; -pub const HmacSha1 = hmac.HmacSha1; -pub const HmacSha256 = hmac.HmacSha256; -pub const HmacBlake2s256 = hmac.HmacBlake2s256; - -pub const chacha20 = @import("crypto/chacha20.zig"); -pub const chaCha20IETF = chacha20.chaCha20IETF; -pub const chaCha20With64BitNonce = chacha20.chaCha20With64BitNonce; -pub const xChaCha20IETF = chacha20.xChaCha20IETF; - -pub const Poly1305 = @import("crypto/poly1305.zig").Poly1305; - -const import_aes = @import("crypto/aes.zig"); -pub const AES128 = import_aes.AES128; -pub const AES256 = import_aes.AES256; - -pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519; -pub const Ed25519 = @import("crypto/25519/ed25519.zig").Ed25519; -pub const Edwards25519 = @import("crypto/25519/edwards25519.zig").Edwards25519; -pub const X25519 = @import("crypto/25519/x25519.zig").X25519; -pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255; +/// Hash functions. +pub const hash = struct { + pub const Md5 = @import("crypto/md5.zig").Md5; + pub const Sha1 = @import("crypto/sha1.zig").Sha1; + pub const sha2 = @import("crypto/sha2.zig"); + pub const sha3 = @import("crypto/sha3.zig"); + pub const blake2 = @import("crypto/blake2.zig"); + pub const Blake3 = @import("crypto/blake3.zig").Blake3; + pub const Gimli = @import("crypto/gimli.zig").Hash; +}; + +/// Authentication (MAC) functions. +pub const auth = struct { + pub const hmac = @import("crypto/hmac.zig"); +}; + +/// Authenticated Encryption with Associated Data pub const aead = struct { - pub const Gimli = gimli.Aead; + const chacha20 = @import("crypto/chacha20.zig"); + + pub const Gimli = @import("crypto/gimli.zig").Aead; pub const ChaCha20Poly1305 = chacha20.Chacha20Poly1305; pub const XChaCha20Poly1305 = chacha20.XChacha20Poly1305; }; +/// MAC functions requiring single-use secret keys. +pub const onetimeauth = struct { + pub const Poly1305 = @import("crypto/poly1305.zig").Poly1305; +}; + +/// Core functions, that should rarely be used directly by applications. +pub const core = struct { + pub const aes = @import("crypto/aes.zig"); + pub const Gimli = @import("crypto/gimli.zig").State; +}; + +/// Elliptic-curve arithmetic. +pub const ecc = struct { + pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519; + pub const Edwards25519 = @import("crypto/25519/edwards25519.zig").Edwards25519; + pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255; +}; + +/// Diffie-Hellman key exchange functions. +pub const dh = struct { + pub const X25519 = @import("crypto/25519/x25519.zig").X25519; +}; + +/// Digital signature functions. +pub const sign = struct { + pub const Ed25519 = @import("crypto/25519/ed25519.zig").Ed25519; +}; + +/// Stream ciphers. These do not provide any kind of authentication. +/// Most applications should be using AEAD constructions instead of stream ciphers directly. +pub const stream = struct { + pub const ChaCha20IETF = @import("crypto/chacha20.zig").ChaCha20IETF; + pub const XChaCha20IETF = @import("crypto/chacha20.zig").XChaCha20IETF; + pub const ChaCha20With64BitNonce = @import("crypto/chacha20.zig").ChaCha20With64BitNonce; +}; + const std = @import("std.zig"); pub const randomBytes = std.os.getrandom; @@ -83,16 +91,21 @@ test "crypto" { test "issue #4532: no index out of bounds" { const types = [_]type{ - Md5, - Sha1, - Sha224, - Sha256, - Sha384, - Sha512, - Blake2s224, - Blake2s256, - Blake2b384, - Blake2b512, + hash.Md5, + hash.Sha1, + hash.sha2.Sha224, + hash.sha2.Sha256, + hash.sha2.Sha384, + hash.sha2.Sha512, + hash.sha3.Sha3_224, + hash.sha3.Sha3_256, + hash.sha3.Sha3_384, + hash.sha3.Sha3_512, + hash.blake2.Blake2s224, + hash.blake2.Blake2s256, + hash.blake2.Blake2b384, + hash.blake2.Blake2b512, + hash.Gimli, }; inline for (types) |Hasher| { diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig index 935abaecb39def38927e317f2b9a7b32537b1208..d02fa0a2fd331b6a0c71f8f35b5a43b32d162f6c 100644 --- a/lib/std/crypto/25519/ed25519.zig +++ b/lib/std/crypto/25519/ed25519.zig @@ -6,7 +6,7 @@ const std = @import("std"); const fmt = std.fmt; const mem = std.mem; -const Sha512 = std.crypto.Sha512; +const Sha512 = std.crypto.hash.sha2.Sha512; /// Ed25519 (EdDSA) signatures. pub const Ed25519 = struct { diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 5c27f2f4f5374f75e6ad5c603c7911fb741def1e..748d57575159ee5eaa13ed5f42f25a93c05a4e5f 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -22,16 +22,16 @@ const Crypto = struct { }; const hashes = [_]Crypto{ - Crypto{ .ty = crypto.Md5, .name = "md5" }, - Crypto{ .ty = crypto.Sha1, .name = "sha1" }, - Crypto{ .ty = crypto.Sha256, .name = "sha256" }, - Crypto{ .ty = crypto.Sha512, .name = "sha512" }, - Crypto{ .ty = crypto.Sha3_256, .name = "sha3-256" }, - Crypto{ .ty = crypto.Sha3_512, .name = "sha3-512" }, - Crypto{ .ty = crypto.gimli.Hash, .name = "gimli-hash" }, - Crypto{ .ty = crypto.Blake2s256, .name = "blake2s" }, - Crypto{ .ty = crypto.Blake2b512, .name = "blake2b" }, - Crypto{ .ty = crypto.Blake3, .name = "blake3" }, + Crypto{ .ty = crypto.hash.Md5, .name = "md5" }, + Crypto{ .ty = crypto.hash.Sha1, .name = "sha1" }, + Crypto{ .ty = crypto.hash.sha2.Sha256, .name = "sha256" }, + Crypto{ .ty = crypto.hash.sha2.Sha512, .name = "sha512" }, + Crypto{ .ty = crypto.hash.sha3.Sha3_256, .name = "sha3-256" }, + Crypto{ .ty = crypto.hash.sha3.Sha3_512, .name = "sha3-512" }, + Crypto{ .ty = crypto.hash.Gimli, .name = "gimli-hash" }, + Crypto{ .ty = crypto.hash.blake2.Blake2s256, .name = "blake2s" }, + Crypto{ .ty = crypto.hash.blake2.Blake2b512, .name = "blake2b" }, + Crypto{ .ty = crypto.hash.Blake3, .name = "blake3" }, }; pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 { @@ -55,10 +55,11 @@ pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 } const macs = [_]Crypto{ - Crypto{ .ty = crypto.Poly1305, .name = "poly1305" }, - Crypto{ .ty = crypto.HmacMd5, .name = "hmac-md5" }, - Crypto{ .ty = crypto.HmacSha1, .name = "hmac-sha1" }, - Crypto{ .ty = crypto.HmacSha256, .name = "hmac-sha256" }, + Crypto{ .ty = crypto.onetimeauth.Poly1305, .name = "poly1305" }, + Crypto{ .ty = crypto.auth.HmacMd5, .name = "hmac-md5" }, + Crypto{ .ty = crypto.auth.HmacSha1, .name = "hmac-sha1" }, + Crypto{ .ty = crypto.auth.sha2.HmacSha256, .name = "hmac-sha256" }, + Crypto{ .ty = crypto.auth.sha2.HmacSha512, .name = "hmac-sha512" }, }; pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { @@ -84,7 +85,7 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { return throughput; } -const exchanges = [_]Crypto{Crypto{ .ty = crypto.X25519, .name = "x25519" }}; +const exchanges = [_]Crypto{Crypto{ .ty = crypto.dh.X25519, .name = "x25519" }}; pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_count: comptime_int) !u64 { std.debug.assert(DhKeyExchange.minimum_key_length >= DhKeyExchange.secret_length); @@ -111,7 +112,7 @@ pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_c return throughput; } -const signatures = [_]Crypto{Crypto{ .ty = crypto.Ed25519, .name = "ed25519" }}; +const signatures = [_]Crypto{Crypto{ .ty = crypto.sign.Ed25519, .name = "ed25519" }}; pub fn benchmarkSignatures(comptime Signature: anytype, comptime signatures_count: comptime_int) !u64 { var seed: [Signature.seed_length]u8 = undefined; diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index d402eb67505c855da37c00f8ff1b96d91c55fd03..1a359ecfc75a93045b60a2056320bd6345e94f49 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -12,7 +12,7 @@ const assert = std.debug.assert; const testing = std.testing; const builtin = @import("builtin"); const maxInt = std.math.maxInt; -const Poly1305 = std.crypto.Poly1305; +const Poly1305 = std.crypto.onetimeauth.Poly1305; const QuarterRound = struct { a: usize, @@ -137,56 +137,60 @@ fn keyToWords(key: [32]u8) [8]u32 { /// /// ChaCha20 is self-reversing. To decrypt just run the cipher with the same /// counter, nonce, and key. -pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void { - assert(in.len >= out.len); - assert((in.len >> 6) + counter <= maxInt(u32)); +pub const ChaCha20IETF = struct { + pub fn xor(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void { + assert(in.len >= out.len); + assert((in.len >> 6) + counter <= maxInt(u32)); - var c: [4]u32 = undefined; - c[0] = counter; - c[1] = mem.readIntLittle(u32, nonce[0..4]); - c[2] = mem.readIntLittle(u32, nonce[4..8]); - c[3] = mem.readIntLittle(u32, nonce[8..12]); - chaCha20_internal(out, in, keyToWords(key), c); -} + var c: [4]u32 = undefined; + c[0] = counter; + c[1] = mem.readIntLittle(u32, nonce[0..4]); + c[2] = mem.readIntLittle(u32, nonce[4..8]); + c[3] = mem.readIntLittle(u32, nonce[8..12]); + chaCha20_internal(out, in, keyToWords(key), c); + } +}; /// This is the original ChaCha20 before RFC 7539, which recommends using the /// orgininal version on applications such as disk or file encryption that might /// exceed the 256 GiB limit of the 96-bit nonce version. -pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void { - assert(in.len >= out.len); - assert(counter +% (in.len >> 6) >= counter); +pub const ChaCha20With64BitNonce = struct { + pub fn xor(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void { + assert(in.len >= out.len); + assert(counter +% (in.len >> 6) >= counter); - var cursor: usize = 0; - const k = keyToWords(key); - var c: [4]u32 = undefined; - c[0] = @truncate(u32, counter); - c[1] = @truncate(u32, counter >> 32); - c[2] = mem.readIntLittle(u32, nonce[0..4]); - c[3] = mem.readIntLittle(u32, nonce[4..8]); + var cursor: usize = 0; + const k = keyToWords(key); + var c: [4]u32 = undefined; + c[0] = @truncate(u32, counter); + c[1] = @truncate(u32, counter >> 32); + c[2] = mem.readIntLittle(u32, nonce[0..4]); + c[3] = mem.readIntLittle(u32, nonce[4..8]); - const block_size = (1 << 6); - // The full block size is greater than the address space on a 32bit machine - const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize); + const block_size = (1 << 6); + // The full block size is greater than the address space on a 32bit machine + const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize); - // first partial big block - if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) { - chaCha20_internal(out[cursor..big_block], in[cursor..big_block], k, c); - cursor = big_block - cursor; - c[1] += 1; - if (comptime @sizeOf(usize) > 4) { - // A big block is giant: 256 GiB, but we can avoid this limitation - var remaining_blocks: u32 = @intCast(u32, (in.len / big_block)); - var i: u32 = 0; - while (remaining_blocks > 0) : (remaining_blocks -= 1) { - chaCha20_internal(out[cursor .. cursor + big_block], in[cursor .. cursor + big_block], k, c); - c[1] += 1; // upper 32-bit of counter, generic chaCha20_internal() doesn't know about this. - cursor += big_block; + // first partial big block + if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) { + chaCha20_internal(out[cursor..big_block], in[cursor..big_block], k, c); + cursor = big_block - cursor; + c[1] += 1; + if (comptime @sizeOf(usize) > 4) { + // A big block is giant: 256 GiB, but we can avoid this limitation + var remaining_blocks: u32 = @intCast(u32, (in.len / big_block)); + var i: u32 = 0; + while (remaining_blocks > 0) : (remaining_blocks -= 1) { + chaCha20_internal(out[cursor .. cursor + big_block], in[cursor .. cursor + big_block], k, c); + c[1] += 1; // upper 32-bit of counter, generic chaCha20_internal() doesn't know about this. + cursor += big_block; + } } } - } - chaCha20_internal(out[cursor..], in[cursor..], k, c); -} + chaCha20_internal(out[cursor..], in[cursor..], k, c); + } +}; // https://tools.ietf.org/html/rfc7539#section-2.4.2 test "crypto.chacha20 test vector sunscreen" { @@ -221,12 +225,12 @@ test "crypto.chacha20 test vector sunscreen" { 0, 0, 0, 0, }; - chaCha20IETF(result[0..], input[0..], 1, key, nonce); + ChaCha20IETF.xor(result[0..], input[0..], 1, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); // Chacha20 is self-reversing. var plaintext: [114]u8 = undefined; - chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce); + ChaCha20IETF.xor(plaintext[0..], result[0..], 1, key, nonce); testing.expect(mem.order(u8, input, &plaintext) == .eq); } @@ -261,7 +265,7 @@ test "crypto.chacha20 test vector 1" { }; const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; - chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); + ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); } @@ -295,7 +299,7 @@ test "crypto.chacha20 test vector 2" { }; const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; - chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); + ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); } @@ -329,7 +333,7 @@ test "crypto.chacha20 test vector 3" { }; const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 1 }; - chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); + ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); } @@ -363,7 +367,7 @@ test "crypto.chacha20 test vector 4" { }; const nonce = [_]u8{ 1, 0, 0, 0, 0, 0, 0, 0 }; - chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); + ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); } @@ -435,21 +439,21 @@ test "crypto.chacha20 test vector 5" { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }; - chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); + ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); testing.expectEqualSlices(u8, &expected_result, &result); } pub const chacha20poly1305_tag_size = 16; -pub fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { +fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { assert(ciphertext.len >= plaintext.len); // derive poly1305 key var polyKey = [_]u8{0} ** 32; - chaCha20IETF(polyKey[0..], polyKey[0..], 0, key, nonce); + ChaCha20IETF.xor(polyKey[0..], polyKey[0..], 0, key, nonce); // encrypt plaintext - chaCha20IETF(ciphertext[0..plaintext.len], plaintext, 1, key, nonce); + ChaCha20IETF.xor(ciphertext[0..plaintext.len], plaintext, 1, key, nonce); // construct mac var mac = Poly1305.init(polyKey[0..]); @@ -472,18 +476,18 @@ pub fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_ta mac.final(tag); } -pub fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { +fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { return chacha20poly1305SealDetached(ciphertextAndTag[0..plaintext.len], ciphertextAndTag[plaintext.len..][0..chacha20poly1305_tag_size], plaintext, data, key, nonce); } /// Verifies and decrypts an authenticated message produced by chacha20poly1305SealDetached. -pub fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { +fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { // split ciphertext and tag assert(dst.len >= ciphertext.len); // derive poly1305 key var polyKey = [_]u8{0} ** 32; - chaCha20IETF(polyKey[0..], polyKey[0..], 0, key, nonce); + ChaCha20IETF.xor(polyKey[0..], polyKey[0..], 0, key, nonce); // construct mac var mac = Poly1305.init(polyKey[0..]); @@ -519,11 +523,11 @@ pub fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *con } // decrypt ciphertext - chaCha20IETF(dst[0..ciphertext.len], ciphertext, 1, key, nonce); + ChaCha20IETF.xor(dst[0..ciphertext.len], ciphertext, 1, key, nonce); } /// Verifies and decrypts an authenticated message produced by chacha20poly1305Seal. -pub fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { +fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { if (ciphertextAndTag.len < chacha20poly1305_tag_size) { return error.InvalidMessage; } @@ -562,31 +566,33 @@ fn extend(key: [32]u8, nonce: [24]u8) struct { key: [32]u8, nonce: [12]u8 } { }; } -pub fn xChaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [24]u8) void { - const extended = extend(key, nonce); - chaCha20IETF(out, in, counter, extended.key, extended.nonce); -} +pub const XChaCha20IETF = struct { + pub fn xor(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [24]u8) void { + const extended = extend(key, nonce); + ChaCha20IETF.xor(out, in, counter, extended.key, extended.nonce); + } +}; pub const xchacha20poly1305_tag_size = 16; -pub fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { +fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { const extended = extend(key, nonce); return chacha20poly1305SealDetached(ciphertext, tag, plaintext, data, extended.key, extended.nonce); } -pub fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { +fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { const extended = extend(key, nonce); return chacha20poly1305Seal(ciphertextAndTag, plaintext, data, extended.key, extended.nonce); } /// Verifies and decrypts an authenticated message produced by xchacha20poly1305SealDetached. -pub fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { +fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { const extended = extend(key, nonce); return try chacha20poly1305OpenDetached(plaintext, ciphertext, tag, data, extended.key, extended.nonce); } /// Verifies and decrypts an authenticated message produced by xchacha20poly1305Seal. -pub fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { +fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { const extended = extend(key, nonce); return try chacha20poly1305Open(ciphertextAndTag, msgAndTag, data, extended.key, extended.nonce); } @@ -714,7 +720,7 @@ test "crypto.xchacha20" { const input = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; { var ciphertext: [input.len]u8 = undefined; - xChaCha20IETF(ciphertext[0..], input[0..], 0, key, nonce); + XChaCha20IETF.xor(ciphertext[0..], input[0..], 0, key, nonce); var buf: [2 * ciphertext.len]u8 = undefined; testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{ciphertext}), "E0A1BCF939654AFDBDC1746EC49832647C19D891F0D1A81FC0C1703B4514BDEA584B512F6908C2C5E9DD18D5CBC1805DE5803FE3B9CA5F193FB8359E91FAB0C3BB40309A292EB1CF49685C65C4A3ADF4F11DB0CD2B6B67FBC174BC2E860E8F769FD3565BBFAD1C845E05A0FED9BE167C240D"); } diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index 33afae5f82c5a311da4f677b18191f214ce0fc8c..77ea74fe0e95c59779578d048c25ecad2fdd2604 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -109,17 +109,21 @@ pub const Hash = struct { state: State, buf_off: usize, + pub const block_length = State.RATE; + const Self = @This(); pub fn init() Self { return Self{ - .state = State{ - .data = [_]u32{0} ** (State.BLOCKBYTES / 4), - }, + .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) }, .buf_off = 0, }; } + pub fn reset(self: *Self) void { + self.* = init(); + } + /// Also known as 'absorb' pub fn update(self: *Self, data: []const u8) void { const buf = self.state.toSlice(); diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 984dacc96783e799595e14fb5abc6d6a0e4f1eac..212bc3e7b0500270c03ce38130084e3935d7e172 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -8,10 +8,19 @@ const crypto = std.crypto; const debug = std.debug; const mem = std.mem; -pub const HmacMd5 = Hmac(crypto.Md5); -pub const HmacSha1 = Hmac(crypto.Sha1); -pub const HmacSha256 = Hmac(crypto.Sha256); -pub const HmacBlake2s256 = Hmac(crypto.Blake2s256); +pub const HmacMd5 = Hmac(crypto.hash.legacy.Md5); +pub const HmacSha1 = Hmac(crypto.hash.legacy.Sha1); + +pub const sha2 = struct { + pub const HmacSha224 = Hmac(crypto.hash.sha2.Sha224); + pub const HmacSha256 = Hmac(crypto.hash.sha2.Sha256); + pub const HmacSha384 = Hmac(crypto.hash.sha2.Sha384); + pub const HmacSha512 = Hmac(crypto.hash.sha2.Sha512); +}; + +pub const blake2 = struct { + pub const HmacBlake2s256 = Hmac(crypto.hash.blake2.Blake2s256); +}; pub fn Hmac(comptime Hash: type) type { return struct { @@ -95,10 +104,10 @@ test "hmac sha1" { } test "hmac sha256" { - var out: [HmacSha256.mac_length]u8 = undefined; - HmacSha256.create(out[0..], "", ""); + var out: [sha2.HmacSha256.mac_length]u8 = undefined; + sha2.HmacSha256.create(out[0..], "", ""); htest.assertEqual("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", out[0..]); - HmacSha256.create(out[0..], "The quick brown fox jumps over the lazy dog", "key"); + sha2.HmacSha256.create(out[0..], "The quick brown fox jumps over the lazy dog", "key"); htest.assertEqual("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8", out[0..]); } diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index d578ba8b957b6e0dc47358ecc81cdf5251c7e30d..950e52e126ed1ef188bbecfefaf5476fe5dc23b6 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -32,6 +32,9 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundPar }; } +/// The MD5 function is now considered cryptographically broken. +/// Namely, it is trivial to find multiple inputs producing the same hash. +/// For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. pub const Md5 = struct { const Self = @This(); pub const block_length = 64; @@ -44,18 +47,21 @@ pub const Md5 = struct { total_len: u64, pub fn init() Self { - var d: Self = undefined; - d.reset(); - return d; + return Self{ + .s = [_]u32{ + 0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + }, + .buf = undefined, + .buf_len = 0, + .total_len = 0, + }; } - pub fn reset(d: *Self) void { - d.s[0] = 0x67452301; - d.s[1] = 0xEFCDAB89; - d.s[2] = 0x98BADCFE; - d.s[3] = 0x10325476; - d.buf_len = 0; - d.total_len = 0; + pub fn reset(self: *Self) void { + self.* = init(); } pub fn hash(b: []const u8, out: []u8) void { diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index 7cb4fbcf36becff4ae793f2223abd884053c216b..ce18ca5ef7462c7d9ad613b70b10425de9249922 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -29,6 +29,9 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { }; } +/// The SHA-1 function is now considered cryptographically broken. +/// Namely, it is feasible to find multiple inputs producing the same hash. +/// For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. pub const Sha1 = struct { const Self = @This(); pub const block_length = 64; @@ -41,19 +44,22 @@ pub const Sha1 = struct { total_len: u64, pub fn init() Self { - var d: Self = undefined; - d.reset(); - return d; + return Self{ + .s = [_]u32{ + 0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0, + }, + .buf = undefined, + .buf_len = 0, + .total_len = 0, + }; } - pub fn reset(d: *Self) void { - d.s[0] = 0x67452301; - d.s[1] = 0xEFCDAB89; - d.s[2] = 0x98BADCFE; - d.s[3] = 0x10325476; - d.s[4] = 0xC3D2E1F0; - d.buf_len = 0; - d.total_len = 0; + pub fn reset(self: *Self) void { + self.* = init(); } pub fn hash(b: []const u8, out: []u8) void { diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index cac18ca1f7b0f6e2faa90cdc19a3c927ba7002db..e7d0135e81b7281e09666a2e6d17790ed4ae29b3 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -93,22 +93,25 @@ fn Sha2_32(comptime params: Sha2Params32) type { total_len: u64, pub fn init() Self { - var d: Self = undefined; - d.reset(); - return d; + return Self{ + .s = [_]u32{ + params.iv0, + params.iv1, + params.iv2, + params.iv3, + params.iv4, + params.iv5, + params.iv6, + params.iv7, + }, + .buf = undefined, + .buf_len = 0, + .total_len = 0, + }; } - pub fn reset(d: *Self) void { - d.s[0] = params.iv0; - d.s[1] = params.iv1; - d.s[2] = params.iv2; - d.s[3] = params.iv3; - d.s[4] = params.iv4; - d.s[5] = params.iv5; - d.s[6] = params.iv6; - d.s[7] = params.iv7; - d.buf_len = 0; - d.total_len = 0; + pub fn reset(self: *Self) void { + self.* = init(); } pub fn hash(b: []const u8, out: []u8) void { diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 03635ca55378345371d049f4bbad4f8a23007e5b..630a44fbfb4346ffada8a828444e07f63117e5d8 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -27,14 +27,14 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { pub fn init() Self { var d: Self = undefined; - d.reset(); - return d; - } - - pub fn reset(d: *Self) void { mem.set(u8, d.s[0..], 0); d.offset = 0; d.rate = 200 - (bits / 4); + return d; + } + + pub fn reset(self: *Self) void { + self.* = init(); } pub fn hash(b: []const u8, out: []u8) void { diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 85f11ff44992131bad4ec11ec1fbc2e8c3333256..42726472bf4703ca879cb74bf091ca5ed374e342 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -737,12 +737,12 @@ test "xoroshiro sequence" { // CSPRNG pub const Gimli = struct { random: Random, - state: std.crypto.gimli.State, + state: std.crypto.core.Gimli, pub fn init(init_s: u64) Gimli { var self = Gimli{ .random = Random{ .fillFn = fill }, - .state = std.crypto.gimli.State{ + .state = std.crypto.core.Gimli{ .data = [_]u32{0} ** (std.crypto.gimli.State.BLOCKBYTES / 4), }, }; diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 34e03eb1648c3e1b99b214f53adca9db5750f0be..c93c22f257fcc36ac48d23bd0e8cf393f4c360d2 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash { std.mem.copy(u8, &out, src); std.mem.set(u8, out[src.len..], 0); } else { - std.crypto.Blake3.hash(src, &out); + std.crypto.hash.Blake3.hash(src, &out); } return out; } diff --git a/tools/process_headers.zig b/tools/process_headers.zig index d17069401e5cc79f3f15e4dc364945e814761c79..ba9fde6683c16a42fad016c11a565f05f96b7279 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -313,7 +313,7 @@ pub fn main() !void { var max_bytes_saved: usize = 0; var total_bytes: usize = 0; - var hasher = std.crypto.Sha256.init(); + var hasher = std.crypto.hash.sha2.Sha256.init(); for (libc_targets) |libc_target| { const dest_target = DestTarget{ -- 2.54.0 From 3bed749b1c1285aa340f793fadb6b5b7275529cf Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 20 Aug 2020 12:56:42 +0200 Subject: [PATCH 41/66] Add truncated SHA512 variants --- lib/std/crypto/hmac.zig | 4 ++-- lib/std/crypto/sha2.zig | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 212bc3e7b0500270c03ce38130084e3935d7e172..3731fca34e0adacd549343803fd9b7ac9ddd6196 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -8,8 +8,8 @@ const crypto = std.crypto; const debug = std.debug; const mem = std.mem; -pub const HmacMd5 = Hmac(crypto.hash.legacy.Md5); -pub const HmacSha1 = Hmac(crypto.hash.legacy.Sha1); +pub const HmacMd5 = Hmac(crypto.hash.Md5); +pub const HmacSha1 = Hmac(crypto.hash.Sha1); pub const sha2 = struct { pub const HmacSha224 = Hmac(crypto.hash.sha2.Sha224); diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index e7d0135e81b7281e09666a2e6d17790ed4ae29b3..1d460934d14e4591a5046c1d2029b26e1c13e432 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -77,7 +77,10 @@ const Sha256Params = Sha2Params32{ .out_len = 256, }; +/// SHA-224 pub const Sha224 = Sha2_32(Sha224Params); + +/// SHA-256 pub const Sha256 = Sha2_32(Sha256Params); fn Sha2_32(comptime params: Sha2Params32) type { @@ -421,9 +424,42 @@ const Sha512Params = Sha2Params64{ .out_len = 512, }; +const Sha512256Params = Sha2Params64{ + .iv0 = 0x22312194FC2BF72C, + .iv1 = 0x9F555FA3C84C64C2, + .iv2 = 0x2393B86B6F53B151, + .iv3 = 0x963877195940EABD, + .iv4 = 0x96283EE2A88EFFE3, + .iv5 = 0xBE5E1E2553863992, + .iv6 = 0x2B0199FC2C85B8AA, + .iv7 = 0x0EB72DDC81C52CA2, + .out_len = 256, +}; + +const Sha512T256Params = Sha2Params64{ + .iv0 = 0x6A09E667F3BCC908, + .iv1 = 0xBB67AE8584CAA73B, + .iv2 = 0x3C6EF372FE94F82B, + .iv3 = 0xA54FF53A5F1D36F1, + .iv4 = 0x510E527FADE682D1, + .iv5 = 0x9B05688C2B3E6C1F, + .iv6 = 0x1F83D9ABFB41BD6B, + .iv7 = 0x5BE0CD19137E2179, + .out_len = 256, +}; + +/// SHA-384 pub const Sha384 = Sha2_64(Sha384Params); + +/// SHA-512 pub const Sha512 = Sha2_64(Sha512Params); +/// SHA-512/256 +pub const Sha512256 = Sha2_64(Sha512256Params); + +/// Truncated SHA-512 +pub const Sha512T256 = Sha2_64(Sha512T256Params); + fn Sha2_64(comptime params: Sha2Params64) type { return struct { const Self = @This(); -- 2.54.0 From f92a5d79440402233bd0215e2bb2aeeb4f333931 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 20 Aug 2020 13:06:23 +0200 Subject: [PATCH 42/66] Repair crypto/benchmark; add BLAKE2b256 Some MACs have a 64-bit output --- lib/std/crypto/benchmark.zig | 12 ++++++------ lib/std/crypto/blake2.zig | 3 ++- lib/std/crypto/blake3.zig | 2 +- lib/std/crypto/sha3.zig | 10 +++++----- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 748d57575159ee5eaa13ed5f42f25a93c05a4e5f..681739e1bd1a34a1656fc65cfab8c90f1591edf1 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -56,19 +56,19 @@ pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 const macs = [_]Crypto{ Crypto{ .ty = crypto.onetimeauth.Poly1305, .name = "poly1305" }, - Crypto{ .ty = crypto.auth.HmacMd5, .name = "hmac-md5" }, - Crypto{ .ty = crypto.auth.HmacSha1, .name = "hmac-sha1" }, - Crypto{ .ty = crypto.auth.sha2.HmacSha256, .name = "hmac-sha256" }, - Crypto{ .ty = crypto.auth.sha2.HmacSha512, .name = "hmac-sha512" }, + Crypto{ .ty = crypto.auth.hmac.HmacMd5, .name = "hmac-md5" }, + Crypto{ .ty = crypto.auth.hmac.HmacSha1, .name = "hmac-sha1" }, + Crypto{ .ty = crypto.auth.hmac.sha2.HmacSha256, .name = "hmac-sha256" }, + Crypto{ .ty = crypto.auth.hmac.sha2.HmacSha512, .name = "hmac-sha512" }, }; pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { - std.debug.assert(32 >= Mac.mac_length and 32 >= Mac.minimum_key_length); + std.debug.assert(64 >= Mac.mac_length and 32 >= Mac.minimum_key_length); var in: [1 * MiB]u8 = undefined; prng.random.bytes(in[0..]); - var key: [32]u8 = undefined; + var key: [64]u8 = undefined; prng.random.bytes(key[0..]); var offset: usize = 0; diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index 9f5194994deb73ba9b927db0b7d746185f6589bc..5e39e7aa40e00ccb6c73d8c2ba5da4251297113d 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -74,7 +74,7 @@ pub fn Blake2s(comptime out_len: usize) type { key: []const u8, pub fn init() Self { - return init_keyed(""); + return comptime init_keyed(""); } pub fn init_keyed(key: []const u8) Self { @@ -364,6 +364,7 @@ test "comptime blake2s256" { ///////////////////// // Blake2b +pub const Blake2b256 = Blake2b(256); pub const Blake2b384 = Blake2b(384); pub const Blake2b512 = Blake2b(512); diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 08986965fc4a58b9d62adefbe23419bcff13ee9a..2428c85d58d2479d26eba05d5efa85c61bfbc670 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -298,7 +298,7 @@ pub const Blake3 = struct { /// Construct a new `Blake3` for the regular hash function. pub fn init() Blake3 { - return Blake3.init_internal(IV, 0); + return comptime Blake3.init_internal(IV, 0); } /// Construct a new `Blake3` for the keyed hash function. diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 630a44fbfb4346ffada8a828444e07f63117e5d8..d8575290a686b44fb4350af4ece095c81c0f4ff4 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -26,11 +26,11 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { rate: usize, pub fn init() Self { - var d: Self = undefined; - mem.set(u8, d.s[0..], 0); - d.offset = 0; - d.rate = 200 - (bits / 4); - return d; + return comptime Self{ + .s = [_]u8{0} ** 200, + .offset = 0, + .rate = 200 - (bits / 4), + }; } pub fn reset(self: *Self) void { -- 2.54.0 From 446597bd3c935be632287a8ad6cfd72892d674e6 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 20 Aug 2020 22:36:57 +0200 Subject: [PATCH 43/66] Remove the reset() function from hash functions Justification: - reset() is unnecessary; states that have to be reused can be copied - reset() is error-prone. Copying a previous state prevents forgetting struct members. - reset() forces implementation to store sensitive data (key, initial state) in memory even when they are not needed. - reset() is confusing as it has a different meaning elsewhere in Zig. --- lib/std/crypto.zig | 6 ++-- lib/std/crypto/blake2.zig | 74 ++++++++++++++++----------------------- lib/std/crypto/blake3.zig | 13 ++++--- lib/std/crypto/gimli.zig | 4 --- lib/std/crypto/hmac.zig | 8 ++--- lib/std/crypto/md5.zig | 8 ++--- lib/std/crypto/sha1.zig | 17 +++------ lib/std/crypto/sha2.zig | 63 ++++++++++++++------------------- lib/std/crypto/sha3.zig | 26 +++++--------- 9 files changed, 85 insertions(+), 134 deletions(-) diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 2a18bd88c78d4f3827ba77aa0455b161fa2ed3b9..bb55f52a4071b916f8b20306d1974d860a1dcca8 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -112,11 +112,11 @@ test "issue #4532: no index out of bounds" { var block = [_]u8{'#'} ** Hasher.block_length; var out1: [Hasher.digest_length]u8 = undefined; var out2: [Hasher.digest_length]u8 = undefined; - - var h = Hasher.init(); + const h0 = Hasher.init(); + var h = h0; h.update(block[0..]); h.final(out1[0..]); - h.reset(); + h = h0; h.update(block[0..1]); h.update(block[1..]); h.final(out2[0..]); diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index 5e39e7aa40e00ccb6c73d8c2ba5da4251297113d..ca310669f6b7dd1ca9c293794e88ceba4c0c6b30 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -71,8 +71,6 @@ pub fn Blake2s(comptime out_len: usize) type { buf: [64]u8, buf_len: u8, - key: []const u8, - pub fn init() Self { return comptime init_keyed(""); } @@ -80,25 +78,20 @@ pub fn Blake2s(comptime out_len: usize) type { pub fn init_keyed(key: []const u8) Self { debug.assert(8 <= out_len and out_len <= 512); - var s: Self = undefined; - s.key = key; - s.reset(); - return s; - } - - pub fn reset(d: *Self) void { + var d: Self = undefined; mem.copy(u32, d.h[0..], iv[0..]); // default parameters - d.h[0] ^= 0x01010000 ^ @truncate(u32, d.key.len << 8) ^ @intCast(u32, out_len >> 3); + d.h[0] ^= 0x01010000 ^ @truncate(u32, key.len << 8) ^ @intCast(u32, out_len >> 3); d.t = 0; d.buf_len = 0; - if (d.key.len > 0) { - mem.set(u8, d.buf[d.key.len..], 0); - d.update(d.key); + if (key.len > 0) { + mem.set(u8, d.buf[key.len..], 0); + d.update(key); d.buf_len = 64; } + return d; } pub fn hash(b: []const u8, out: []u8) void { @@ -225,12 +218,12 @@ test "blake2s224 streaming" { const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55"; - h.reset(); + h = Blake2s224.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Blake2s224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -239,13 +232,13 @@ test "blake2s224 streaming" { const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; - h.reset(); + h = Blake2s224.init(); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h.reset(); + h = Blake2s224.init(); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); @@ -294,12 +287,12 @@ test "blake2s256 streaming" { const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"; - h.reset(); + h = Blake2s256.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Blake2s256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -308,13 +301,13 @@ test "blake2s256 streaming" { const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; - h.reset(); + h = Blake2s256.init(); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h.reset(); + h = Blake2s256.init(); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); @@ -335,7 +328,7 @@ test "blake2s256 keyed" { htest.assertEqual(h1, out[0..]); - h.reset(); + h = Blake2s256.init_keyed(key); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -406,8 +399,6 @@ pub fn Blake2b(comptime out_len: usize) type { buf: [128]u8, buf_len: u8, - key: []const u8, - pub fn init() Self { return init_keyed(""); } @@ -415,25 +406,20 @@ pub fn Blake2b(comptime out_len: usize) type { pub fn init_keyed(key: []const u8) Self { debug.assert(8 <= out_len and out_len <= 512); - var s: Self = undefined; - s.key = key; - s.reset(); - return s; - } - - pub fn reset(d: *Self) void { + var d: Self = undefined; mem.copy(u64, d.h[0..], iv[0..]); // default parameters - d.h[0] ^= 0x01010000 ^ (d.key.len << 8) ^ (out_len >> 3); + d.h[0] ^= 0x01010000 ^ (key.len << 8) ^ (out_len >> 3); d.t = 0; d.buf_len = 0; - if (d.key.len > 0) { - mem.set(u8, d.buf[d.key.len..], 0); - d.update(d.key); + if (key.len > 0) { + mem.set(u8, d.buf[key.len..], 0); + d.update(key); d.buf_len = 128; } + return d; } pub fn hash(b: []const u8, out: []u8) void { @@ -558,12 +544,12 @@ test "blake2b384 streaming" { const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4"; - h.reset(); + h = Blake2b384.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Blake2b384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -572,12 +558,12 @@ test "blake2b384 streaming" { const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; - h.reset(); + h = Blake2b384.init(); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h.reset(); + h = Blake2b384.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -627,12 +613,12 @@ test "blake2b512 streaming" { const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"; - h.reset(); + h = Blake2b512.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Blake2b512.init(); h.update("a"); h.update("b"); h.update("c"); @@ -641,12 +627,12 @@ test "blake2b512 streaming" { const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; - h.reset(); + h = Blake2b512.init(); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h.reset(); + h = Blake2b512.init(); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -668,7 +654,7 @@ test "blake2b512 keyed" { htest.assertEqual(h1, out[0..]); - h.reset(); + h = Blake2b512.init_keyed(key); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 2428c85d58d2479d26eba05d5efa85c61bfbc670..056a11be2535e2831685105070ca7ebaec65fd92 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -326,12 +326,6 @@ pub const Blake3 = struct { hasher.final(out); } - /// Reset the `Blake3` to its initial state. - pub fn reset(self: *Blake3) void { - self.chunk_state = ChunkState.init(self.key, 0, self.flags); - self.cv_stack_len = 0; - } - fn push_cv(self: *Blake3, cv: [8]u32) void { self.cv_stack[self.cv_stack_len] = cv; self.cv_stack_len += 1; @@ -566,6 +560,9 @@ const reference_test = ReferenceTest{ }; fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { + // Save initial state + const initial_state = hasher.*; + // Setup input pattern var input_pattern: [251]u8 = undefined; for (input_pattern) |*e, i| e.* = @truncate(u8, i); @@ -581,12 +578,14 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { // Read final hash value var actual_bytes: [expected_hex.len / 2]u8 = undefined; hasher.final(actual_bytes[0..]); - hasher.reset(); // Compare to expected value var expected_bytes: [expected_hex.len / 2]u8 = undefined; fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable; testing.expectEqual(actual_bytes, expected_bytes); + + // Restore initial state + hasher.* = initial_state; } test "BLAKE3 reference test cases" { diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index 77ea74fe0e95c59779578d048c25ecad2fdd2604..b59d06e754175622477f22a9bc5f00d309135c70 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -120,10 +120,6 @@ pub const Hash = struct { }; } - pub fn reset(self: *Self) void { - self.* = init(); - } - /// Also known as 'absorb' pub fn update(self: *Self, data: []const u8) void { const buf = self.state.toSlice(); diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 3731fca34e0adacd549343803fd9b7ac9ddd6196..77db5bcaae099c5435258887c219fad34d2cd681 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -75,10 +75,10 @@ pub fn Hmac(comptime Hash: type) type { debug.assert(Hash.block_length >= out.len and out.len >= mac_length); ctx.hash.final(ctx.scratch[0..mac_length]); - ctx.hash.reset(); - ctx.hash.update(ctx.o_key_pad[0..]); - ctx.hash.update(ctx.scratch[0..mac_length]); - ctx.hash.final(out[0..mac_length]); + var ohash = Hash.init(); + ohash.update(ctx.o_key_pad[0..]); + ohash.update(ctx.scratch[0..mac_length]); + ohash.final(out[0..mac_length]); } }; } diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index 950e52e126ed1ef188bbecfefaf5476fe5dc23b6..c33bee2e562906bd47ae318f294ce230aaede9c9 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -60,10 +60,6 @@ pub const Md5 = struct { }; } - pub fn reset(self: *Self) void { - self.* = init(); - } - pub fn hash(b: []const u8, out: []u8) void { var d = Md5.init(); d.update(b); @@ -267,12 +263,12 @@ test "md5 streaming" { h.final(out[0..]); htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]); - h.reset(); + h = Md5.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]); - h.reset(); + h = Md5.init(); h.update("a"); h.update("b"); h.update("c"); diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index ce18ca5ef7462c7d9ad613b70b10425de9249922..a62343eb7ac5e811e2d91c13b65ee5c18b078601 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -39,9 +39,9 @@ pub const Sha1 = struct { s: [5]u32, // Streaming Cache - buf: [64]u8, - buf_len: u8, - total_len: u64, + buf: [64]u8 = undefined, + buf_len: u8 = 0, + total_len: u64 = 0, pub fn init() Self { return Self{ @@ -52,16 +52,9 @@ pub const Sha1 = struct { 0x10325476, 0xC3D2E1F0, }, - .buf = undefined, - .buf_len = 0, - .total_len = 0, }; } - pub fn reset(self: *Self) void { - self.* = init(); - } - pub fn hash(b: []const u8, out: []u8) void { var d = Sha1.init(); d.update(b); @@ -289,12 +282,12 @@ test "sha1 streaming" { h.final(out[0..]); htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); - h.reset(); + h = Sha1.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); - h.reset(); + h = Sha1.init(); h.update("a"); h.update("b"); h.update("c"); diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 1d460934d14e4591a5046c1d2029b26e1c13e432..851b1dc4050e59ec55cb02a9722fe0e3e7f1c94c 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -91,9 +91,9 @@ fn Sha2_32(comptime params: Sha2Params32) type { s: [8]u32, // Streaming Cache - buf: [64]u8, - buf_len: u8, - total_len: u64, + buf: [64]u8 = undefined, + buf_len: u8 = 0, + total_len: u64 = 0, pub fn init() Self { return Self{ @@ -107,16 +107,9 @@ fn Sha2_32(comptime params: Sha2Params32) type { params.iv6, params.iv7, }, - .buf = undefined, - .buf_len = 0, - .total_len = 0, }; } - pub fn reset(self: *Self) void { - self.* = init(); - } - pub fn hash(b: []const u8, out: []u8) void { var d = Self.init(); d.update(b); @@ -309,12 +302,12 @@ test "sha224 streaming" { h.final(out[0..]); htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]); - h.reset(); + h = Sha224.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]); - h.reset(); + h = Sha224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -335,12 +328,12 @@ test "sha256 streaming" { h.final(out[0..]); htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]); - h.reset(); + h = Sha256.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]); - h.reset(); + h = Sha256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -468,27 +461,23 @@ fn Sha2_64(comptime params: Sha2Params64) type { s: [8]u64, // Streaming Cache - buf: [128]u8, - buf_len: u8, - total_len: u128, + buf: [128]u8 = undefined, + buf_len: u8 = 0, + total_len: u128 = 0, pub fn init() Self { - var d: Self = undefined; - d.reset(); - return d; - } - - pub fn reset(d: *Self) void { - d.s[0] = params.iv0; - d.s[1] = params.iv1; - d.s[2] = params.iv2; - d.s[3] = params.iv3; - d.s[4] = params.iv4; - d.s[5] = params.iv5; - d.s[6] = params.iv6; - d.s[7] = params.iv7; - d.buf_len = 0; - d.total_len = 0; + return Self{ + .s = [_]u64{ + params.iv0, + params.iv1, + params.iv2, + params.iv3, + params.iv4, + params.iv5, + params.iv6, + params.iv7, + }, + }; } pub fn hash(b: []const u8, out: []u8) void { @@ -713,12 +702,12 @@ test "sha384 streaming" { const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"; - h.reset(); + h = Sha384.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Sha384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -747,12 +736,12 @@ test "sha512 streaming" { const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; - h.reset(); + h = Sha512.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Sha512.init(); h.update("a"); h.update("b"); h.update("c"); diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index d8575290a686b44fb4350af4ece095c81c0f4ff4..273e5eea6d924af0f6aeedcb101fc6831f6cfbfe 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -26,15 +26,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { rate: usize, pub fn init() Self { - return comptime Self{ - .s = [_]u8{0} ** 200, - .offset = 0, - .rate = 200 - (bits / 4), - }; - } - - pub fn reset(self: *Self) void { - self.* = init(); + return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) }; } pub fn hash(b: []const u8, out: []u8) void { @@ -189,12 +181,12 @@ test "sha3-224 streaming" { h.final(out[0..]); htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]); - h.reset(); + h = Sha3_224.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]); - h.reset(); + h = Sha3_224.init(); h.update("a"); h.update("b"); h.update("c"); @@ -215,12 +207,12 @@ test "sha3-256 streaming" { h.final(out[0..]); htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]); - h.reset(); + h = Sha3_256.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]); - h.reset(); + h = Sha3_256.init(); h.update("a"); h.update("b"); h.update("c"); @@ -255,12 +247,12 @@ test "sha3-384 streaming" { htest.assertEqual(h1, out[0..]); const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"; - h.reset(); + h = Sha3_384.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Sha3_384.init(); h.update("a"); h.update("b"); h.update("c"); @@ -286,12 +278,12 @@ test "sha3-512 streaming" { htest.assertEqual(h1, out[0..]); const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"; - h.reset(); + h = Sha3_512.init(); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h.reset(); + h = Sha3_512.init(); h.update("a"); h.update("b"); h.update("c"); -- 2.54.0 From adf3d00e874275557b69ef65164a2b2a0dd88167 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 20 Aug 2020 22:51:19 +0200 Subject: [PATCH 44/66] Remove explicit comptime --- lib/std/crypto/blake2.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index ca310669f6b7dd1ca9c293794e88ceba4c0c6b30..bb07390286515dbb7d6e2889428f8fbcf300e453 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -72,7 +72,7 @@ pub fn Blake2s(comptime out_len: usize) type { buf_len: u8, pub fn init() Self { - return comptime init_keyed(""); + return init_keyed(""); } pub fn init_keyed(key: []const u8) Self { -- 2.54.0 From 1ca49b92c650e9b8988a35983e202cdb9c7ba6e7 Mon Sep 17 00:00:00 2001 From: heidezomp Date: Thu, 20 Aug 2020 11:54:29 +0200 Subject: [PATCH 45/66] add UTIME_NOW and UTIME_OMIT constants for use in utimensat/futimens copied from lib/libc/include/generic-musl/sys/stat.h --- lib/std/os/bits/linux.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 4fa8a02d3d0741a7588b0c90453186fe01c09f82..5c81ee8c062330c08ca9328616bb12c4cdd97144 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -775,6 +775,9 @@ pub fn S_ISSOCK(m: u32) bool { return m & S_IFMT == S_IFSOCK; } +pub const UTIME_NOW = 0x3fffffff; +pub const UTIME_OMIT = 0x3ffffffe; + pub const TFD_NONBLOCK = O_NONBLOCK; pub const TFD_CLOEXEC = O_CLOEXEC; -- 2.54.0 From fc55cd458a7cd72ea876cf747b1ddd43d8dc6e20 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 00:51:14 +0200 Subject: [PATCH 46/66] Hash functions now accept an option set - This avoids having multiple `init()` functions for every combination of optional parameters - The API is consistent across all hash functions - New options can be added later without breaking existing applications. For example, this is going to come in handy if we implement parallelization for BLAKE2 and BLAKE3. - We don't have a mix of snake_case and camelCase functions any more, at least in the public crypto API Support for BLAKE2 salt and personalization (more commonly called context) parameters have been implemented by the way to illustrate this. --- lib/std/bloom_filter.zig | 2 +- lib/std/cache_hash.zig | 10 +- lib/std/crypto.zig | 2 +- lib/std/crypto/25519/ed25519.zig | 10 +- lib/std/crypto/benchmark.zig | 2 +- lib/std/crypto/blake2.zig | 157 +++++++++++++++++++------------ lib/std/crypto/blake3.zig | 34 +++---- lib/std/crypto/gimli.zig | 9 +- lib/std/crypto/hmac.zig | 6 +- lib/std/crypto/md5.zig | 15 +-- lib/std/crypto/sha1.zig | 15 +-- lib/std/crypto/sha2.zig | 42 +++++---- lib/std/crypto/sha3.zig | 35 +++---- lib/std/crypto/test.zig | 2 +- lib/std/zig.zig | 2 +- 15 files changed, 194 insertions(+), 149 deletions(-) diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig index 5ccef8d1408dd584cfd6f6a71c3b83cd8c6d5ec3..0e251f548fff8438d4c9d411295983004c76df94 100644 --- a/lib/std/bloom_filter.zig +++ b/lib/std/bloom_filter.zig @@ -158,7 +158,7 @@ pub fn BloomFilter( } fn hashFunc(out: []u8, Ki: usize, in: []const u8) void { - var st = std.crypto.hash.Gimli.init(); + var st = std.crypto.hash.Gimli.init(.{}); st.update(std.mem.asBytes(&Ki)); st.update(in); st.final(out); diff --git a/lib/std/cache_hash.zig b/lib/std/cache_hash.zig index 802592934779423d04817824a2b9157843ec8935..edd0ebf12688f6778b062635d38b7a8f5478be20 100644 --- a/lib/std/cache_hash.zig +++ b/lib/std/cache_hash.zig @@ -56,7 +56,7 @@ pub const CacheHash = struct { pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash { return CacheHash{ .allocator = allocator, - .blake3 = Blake3.init(), + .blake3 = Blake3.init(.{}), .manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}), .manifest_file = null, .manifest_dirty = false, @@ -137,7 +137,7 @@ pub const CacheHash = struct { base64_encoder.encode(self.b64_digest[0..], &bin_digest); - self.blake3 = Blake3.init(); + self.blake3 = Blake3.init(.{}); self.blake3.update(&bin_digest); const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest}); @@ -256,7 +256,7 @@ pub const CacheHash = struct { // cache miss // keep the manifest file open // reset the hash - self.blake3 = Blake3.init(); + self.blake3 = Blake3.init(.{}); self.blake3.update(&bin_digest); // Remove files not in the initial hash @@ -304,7 +304,7 @@ pub const CacheHash = struct { // Hash while reading from disk, to keep the contents in the cpu cache while // doing hashing. - var blake3 = Blake3.init(); + var blake3 = Blake3.init(.{}); var off: usize = 0; while (true) { // give me everything you've got, captain @@ -434,7 +434,7 @@ pub const CacheHash = struct { }; fn hashFile(file: fs.File, bin_digest: []u8) !void { - var blake3 = Blake3.init(); + var blake3 = Blake3.init(.{}); var buf: [1024]u8 = undefined; while (true) { diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index bb55f52a4071b916f8b20306d1974d860a1dcca8..32ab5071c588d769d78031a2b48ecf273da39051 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -112,7 +112,7 @@ test "issue #4532: no index out of bounds" { var block = [_]u8{'#'} ** Hasher.block_length; var out1: [Hasher.digest_length]u8 = undefined; var out2: [Hasher.digest_length]u8 = undefined; - const h0 = Hasher.init(); + const h0 = Hasher.init(.{}); var h = h0; h.update(block[0..]); h.final(out1[0..]); diff --git a/lib/std/crypto/25519/ed25519.zig b/lib/std/crypto/25519/ed25519.zig index d02fa0a2fd331b6a0c71f8f35b5a43b32d162f6c..9993afb6d2dec072bf7df7fe654542b39e7ecd16 100644 --- a/lib/std/crypto/25519/ed25519.zig +++ b/lib/std/crypto/25519/ed25519.zig @@ -33,7 +33,7 @@ pub const Ed25519 = struct { /// from which the actual secret is derived. pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 { var az: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(); + var h = Sha512.init(.{}); h.update(&seed); h.final(&az); const p = try Curve.basePoint.clampedMul(az[0..32].*); @@ -56,11 +56,11 @@ pub const Ed25519 = struct { pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 { const public_key = key_pair[32..]; var az: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(); + var h = Sha512.init(.{}); h.update(key_pair[0..seed_length]); h.final(&az); - h = Sha512.init(); + h = Sha512.init(.{}); if (noise) |*z| { h.update(z); } @@ -74,7 +74,7 @@ pub const Ed25519 = struct { var sig: [signature_length]u8 = undefined; mem.copy(u8, sig[0..32], &r.toBytes()); mem.copy(u8, sig[32..], public_key); - h = Sha512.init(); + h = Sha512.init(.{}); h.update(&sig); h.update(msg); var hram64: [Sha512.digest_length]u8 = undefined; @@ -98,7 +98,7 @@ pub const Ed25519 = struct { const a = try Curve.fromBytes(public_key); try a.rejectIdentity(); - var h = Sha512.init(); + var h = Sha512.init(.{}); h.update(r); h.update(&public_key); h.update(msg); diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 681739e1bd1a34a1656fc65cfab8c90f1591edf1..70bd30d6bbf6e0a8ecddb22f0b1cbefe3b59ea73 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -35,7 +35,7 @@ const hashes = [_]Crypto{ }; pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 { - var h = Hash.init(); + var h = Hash.init(.{}); var block: [Hash.digest_length]u8 = undefined; prng.random.bytes(block[0..]); diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index bb07390286515dbb7d6e2889428f8fbcf300e453..1cb143811cf3f861035f0ddfa4148105fb46d709 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type { const Self = @This(); pub const block_length = 64; pub const digest_length = out_len / 8; + pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null }; const iv = [8]u32{ 0x6A09E667, @@ -71,35 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type { buf: [64]u8, buf_len: u8, - pub fn init() Self { - return init_keyed(""); - } - - pub fn init_keyed(key: []const u8) Self { + pub fn init(options: Options) Self { debug.assert(8 <= out_len and out_len <= 512); var d: Self = undefined; mem.copy(u32, d.h[0..], iv[0..]); + const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ @truncate(u32, key.len << 8) ^ @intCast(u32, out_len >> 3); + d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_len >> 3); d.t = 0; d.buf_len = 0; - if (key.len > 0) { - mem.set(u8, d.buf[key.len..], 0); - d.update(key); + if (options.salt) |salt| { + d.h[4] ^= mem.readIntLittle(u32, salt[0..4]); + d.h[5] ^= mem.readIntLittle(u32, salt[4..8]); + } + if (options.context) |context| { + d.h[6] ^= mem.readIntLittle(u32, context[0..4]); + d.h[7] ^= mem.readIntLittle(u32, context[4..8]); + } + if (key_len > 0) { + mem.set(u8, d.buf[key_len..], 0); + d.update(options.key.?); d.buf_len = 64; } return d; } - pub fn hash(b: []const u8, out: []u8) void { - Self.hash_keyed("", b, out); - } - - pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void { - var d = Self.init_keyed(key); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Self.init(options); d.update(b); d.final(out); } @@ -208,7 +210,7 @@ test "blake2s224 single" { } test "blake2s224 streaming" { - var h = Blake2s224.init(); + var h = Blake2s224.init(.{}); var out: [28]u8 = undefined; const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"; @@ -218,12 +220,12 @@ test "blake2s224 streaming" { const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55"; - h = Blake2s224.init(); + h = Blake2s224.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Blake2s224.init(); + h = Blake2s224.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -232,16 +234,29 @@ test "blake2s224 streaming" { const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; - h = Blake2s224.init(); + h = Blake2s224.init(.{}); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h = Blake2s224.init(); + h = Blake2s224.init(.{}); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); + + const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3"; + + h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h.update("a" ** 32); + h.update("b" ** 32); + h.final(out[0..]); + htest.assertEqual(h4, out[0..]); + + h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); + h.update("a" ** 32 ++ "b" ** 32); + h.final(out[0..]); + htest.assertEqual(h4, out[0..]); } test "comptime blake2s224" { @@ -254,7 +269,7 @@ test "comptime blake2s224" { htest.assertEqualHash(Blake2s224, h1, block[0..]); - var h = Blake2s224.init(); + var h = Blake2s224.init(.{}); h.update(&block); h.final(out[0..]); @@ -277,7 +292,7 @@ test "blake2s256 single" { } test "blake2s256 streaming" { - var h = Blake2s256.init(); + var h = Blake2s256.init(.{}); var out: [32]u8 = undefined; const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"; @@ -287,12 +302,12 @@ test "blake2s256 streaming" { const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"; - h = Blake2s256.init(); + h = Blake2s256.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Blake2s256.init(); + h = Blake2s256.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -301,13 +316,13 @@ test "blake2s256 streaming" { const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; - h = Blake2s256.init(); + h = Blake2s256.init(.{}); h.update("a" ** 32); h.update("b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h = Blake2s256.init(); + h = Blake2s256.init(.{}); h.update("a" ** 32 ++ "b" ** 32); h.final(out[0..]); htest.assertEqual(h3, out[0..]); @@ -319,16 +334,16 @@ test "blake2s256 keyed" { const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6"; const key = "secret_key"; - Blake2s256.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out); + Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); htest.assertEqual(h1, out[0..]); - var h = Blake2s256.init_keyed(key); + var h = Blake2s256.init(.{ .key = key }); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h1, out[0..]); - h = Blake2s256.init_keyed(key); + h = Blake2s256.init(.{ .key = key }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -346,7 +361,7 @@ test "comptime blake2s256" { htest.assertEqualHash(Blake2s256, h1, block[0..]); - var h = Blake2s256.init(); + var h = Blake2s256.init(.{}); h.update(&block); h.final(out[0..]); @@ -366,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type { const Self = @This(); pub const block_length = 128; pub const digest_length = out_len / 8; + pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null }; const iv = [8]u64{ 0x6a09e667f3bcc908, @@ -399,35 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type { buf: [128]u8, buf_len: u8, - pub fn init() Self { - return init_keyed(""); - } - - pub fn init_keyed(key: []const u8) Self { + pub fn init(options: Options) Self { debug.assert(8 <= out_len and out_len <= 512); var d: Self = undefined; mem.copy(u64, d.h[0..], iv[0..]); + const key_len = if (options.key) |key| key.len else 0; // default parameters - d.h[0] ^= 0x01010000 ^ (key.len << 8) ^ (out_len >> 3); + d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3); d.t = 0; d.buf_len = 0; - if (key.len > 0) { - mem.set(u8, d.buf[key.len..], 0); - d.update(key); + if (options.salt) |salt| { + d.h[4] ^= mem.readIntLittle(u64, salt[0..8]); + d.h[5] ^= mem.readIntLittle(u64, salt[8..16]); + } + if (options.context) |context| { + d.h[6] ^= mem.readIntLittle(u64, context[0..8]); + d.h[7] ^= mem.readIntLittle(u64, context[8..16]); + } + if (key_len > 0) { + mem.set(u8, d.buf[key_len..], 0); + d.update(options.key.?); d.buf_len = 128; } return d; } - pub fn hash(b: []const u8, out: []u8) void { - Self.hash_keyed("", b, out); - } - - pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void { - var d = Self.init_keyed(key); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Self.init(options); d.update(b); d.final(out); } @@ -534,7 +551,7 @@ test "blake2b384 single" { } test "blake2b384 streaming" { - var h = Blake2b384.init(); + var h = Blake2b384.init(.{}); var out: [48]u8 = undefined; const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"; @@ -544,12 +561,12 @@ test "blake2b384 streaming" { const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4"; - h = Blake2b384.init(); + h = Blake2b384.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Blake2b384.init(); + h = Blake2b384.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -558,16 +575,36 @@ test "blake2b384 streaming" { const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; - h = Blake2b384.init(); + h = Blake2b384.init(.{}); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h = Blake2b384.init(); + h = Blake2b384.init(.{}); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); htest.assertEqual(h3, out[0..]); + + h = Blake2b384.init(.{}); + h.update("a" ** 64); + h.update("b" ** 64); + h.final(out[0..]); + htest.assertEqual(h3, out[0..]); + + const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c"; + + h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h.update("a" ** 64); + h.update("b" ** 64); + h.final(out[0..]); + htest.assertEqual(h4, out[0..]); + + h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); + h.update("a" ** 64); + h.update("b" ** 64); + h.final(out[0..]); + htest.assertEqual(h4, out[0..]); } test "comptime blake2b384" { @@ -580,7 +617,7 @@ test "comptime blake2b384" { htest.assertEqualHash(Blake2b384, h1, block[0..]); - var h = Blake2b384.init(); + var h = Blake2b384.init(.{}); h.update(&block); h.final(out[0..]); @@ -603,7 +640,7 @@ test "blake2b512 single" { } test "blake2b512 streaming" { - var h = Blake2b512.init(); + var h = Blake2b512.init(.{}); var out: [64]u8 = undefined; const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"; @@ -613,12 +650,12 @@ test "blake2b512 streaming" { const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"; - h = Blake2b512.init(); + h = Blake2b512.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Blake2b512.init(); + h = Blake2b512.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -627,12 +664,12 @@ test "blake2b512 streaming" { const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; - h = Blake2b512.init(); + h = Blake2b512.init(.{}); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h3, out[0..]); - h = Blake2b512.init(); + h = Blake2b512.init(.{}); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -645,16 +682,16 @@ test "blake2b512 keyed" { const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d"; const key = "secret_key"; - Blake2b512.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out); + Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); htest.assertEqual(h1, out[0..]); - var h = Blake2b512.init_keyed(key); + var h = Blake2b512.init(.{ .key = key }); h.update("a" ** 64 ++ "b" ** 64); h.final(out[0..]); htest.assertEqual(h1, out[0..]); - h = Blake2b512.init_keyed(key); + h = Blake2b512.init(.{ .key = key }); h.update("a" ** 64); h.update("b" ** 64); h.final(out[0..]); @@ -672,7 +709,7 @@ test "comptime blake2b512" { htest.assertEqualHash(Blake2b512, h1, block[0..]); - var h = Blake2b512.init(); + var h = Blake2b512.init(.{}); h.update(&block); h.final(out[0..]); diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig index 056a11be2535e2831685105070ca7ebaec65fd92..163c91b3584bd768801f4f593b36380ee15de6ae 100644 --- a/lib/std/crypto/blake3.zig +++ b/lib/std/crypto/blake3.zig @@ -279,6 +279,9 @@ fn parent_cv( /// An incremental hasher that can accept any number of writes. pub const Blake3 = struct { + pub const Options = struct { key: ?[KEY_LEN]u8 = null }; + pub const KdfOptions = struct {}; + chunk_state: ChunkState, key: [8]u32, cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values: @@ -296,21 +299,20 @@ pub const Blake3 = struct { }; } - /// Construct a new `Blake3` for the regular hash function. - pub fn init() Blake3 { - return comptime Blake3.init_internal(IV, 0); - } - - /// Construct a new `Blake3` for the keyed hash function. - pub fn init_keyed(key: [KEY_LEN]u8) Blake3 { - var key_words: [8]u32 = undefined; - words_from_little_endian_bytes(key_words[0..], key[0..]); - return Blake3.init_internal(key_words, KEYED_HASH); + /// Construct a new `Blake3` for the hash function, with an optional key + pub fn init(options: Options) Blake3 { + if (options.key) |key| { + var key_words: [8]u32 = undefined; + words_from_little_endian_bytes(key_words[0..], key[0..]); + return Blake3.init_internal(key_words, KEYED_HASH); + } else { + return Blake3.init_internal(IV, 0); + } } /// Construct a new `Blake3` for the key derivation function. The context /// string should be hardcoded, globally unique, and application-specific. - pub fn init_derive_key(context: []const u8) Blake3 { + pub fn initKdf(context: []const u8, options: KdfOptions) Blake3 { var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT); context_hasher.update(context); var context_key: [KEY_LEN]u8 = undefined; @@ -320,8 +322,8 @@ pub const Blake3 = struct { return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL); } - pub fn hash(in: []const u8, out: []u8) void { - var hasher = Blake3.init(); + pub fn hash(in: []const u8, out: []u8, options: Options) void { + var hasher = Blake3.init(options); hasher.update(in); hasher.final(out); } @@ -589,9 +591,9 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { } test "BLAKE3 reference test cases" { - var hash = &Blake3.init(); - var keyed_hash = &Blake3.init_keyed(reference_test.key.*); - var derive_key = &Blake3.init_derive_key(reference_test.context_string); + var hash = &Blake3.init(.{}); + var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* }); + var derive_key = &Blake3.initKdf(reference_test.context_string, .{}); for (reference_test.cases) |t| { test_blake3(hash, t.input_len, t.hash.*); diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index b59d06e754175622477f22a9bc5f00d309135c70..9d139d6716f438d13eca733ac638965637d36383 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -110,10 +110,11 @@ pub const Hash = struct { buf_off: usize, pub const block_length = State.RATE; + pub const Options = struct {}; const Self = @This(); - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) }, .buf_off = 0, @@ -160,8 +161,8 @@ pub const Hash = struct { } }; -pub fn hash(out: []u8, in: []const u8) void { - var st = Hash.init(); +pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void { + var st = Hash.init(options); st.update(in); st.final(out); } @@ -174,7 +175,7 @@ test "hash" { var msg: [58 / 2]u8 = undefined; try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C"); var md: [32]u8 = undefined; - hash(&md, &msg); + hash(&md, &msg, .{}); htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md); } diff --git a/lib/std/crypto/hmac.zig b/lib/std/crypto/hmac.zig index 77db5bcaae099c5435258887c219fad34d2cd681..700904555d4498c79565cec52f219e4f059eb100 100644 --- a/lib/std/crypto/hmac.zig +++ b/lib/std/crypto/hmac.zig @@ -45,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type { // Normalize key length to block size of hash if (key.len > Hash.block_length) { - Hash.hash(key, ctx.scratch[0..mac_length]); + Hash.hash(key, ctx.scratch[0..mac_length], .{}); mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0); } else if (key.len < Hash.block_length) { mem.copy(u8, ctx.scratch[0..key.len], key); @@ -62,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type { b.* = ctx.scratch[i] ^ 0x36; } - ctx.hash = Hash.init(); + ctx.hash = Hash.init(.{}); ctx.hash.update(ctx.i_key_pad[0..]); return ctx; } @@ -75,7 +75,7 @@ pub fn Hmac(comptime Hash: type) type { debug.assert(Hash.block_length >= out.len and out.len >= mac_length); ctx.hash.final(ctx.scratch[0..mac_length]); - var ohash = Hash.init(); + var ohash = Hash.init(.{}); ohash.update(ctx.o_key_pad[0..]); ohash.update(ctx.scratch[0..mac_length]); ohash.final(out[0..mac_length]); diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index c33bee2e562906bd47ae318f294ce230aaede9c9..0d221fabf682a8150e924e6536dbb0ae85b68a6f 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -39,6 +39,7 @@ pub const Md5 = struct { const Self = @This(); pub const block_length = 64; pub const digest_length = 16; + pub const Options = struct {}; s: [4]u32, // Streaming Cache @@ -46,7 +47,7 @@ pub const Md5 = struct { buf_len: u8, total_len: u64, - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .s = [_]u32{ 0x67452301, @@ -60,8 +61,8 @@ pub const Md5 = struct { }; } - pub fn hash(b: []const u8, out: []u8) void { - var d = Md5.init(); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Md5.init(options); d.update(b); d.final(out); } @@ -257,18 +258,18 @@ test "md5 single" { } test "md5 streaming" { - var h = Md5.init(); + var h = Md5.init(.{}); var out: [16]u8 = undefined; h.final(out[0..]); htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]); - h = Md5.init(); + h = Md5.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]); - h = Md5.init(); + h = Md5.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -281,7 +282,7 @@ test "md5 aligned final" { var block = [_]u8{0} ** Md5.block_length; var out: [Md5.digest_length]u8 = undefined; - var h = Md5.init(); + var h = Md5.init(.{}); h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index a62343eb7ac5e811e2d91c13b65ee5c18b078601..03fd55b6a0e1bc82d76dd59960a1b475fcecad63 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -36,6 +36,7 @@ pub const Sha1 = struct { const Self = @This(); pub const block_length = 64; pub const digest_length = 20; + pub const Options = struct {}; s: [5]u32, // Streaming Cache @@ -43,7 +44,7 @@ pub const Sha1 = struct { buf_len: u8 = 0, total_len: u64 = 0, - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .s = [_]u32{ 0x67452301, @@ -55,8 +56,8 @@ pub const Sha1 = struct { }; } - pub fn hash(b: []const u8, out: []u8) void { - var d = Sha1.init(); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Sha1.init(options); d.update(b); d.final(out); } @@ -276,18 +277,18 @@ test "sha1 single" { } test "sha1 streaming" { - var h = Sha1.init(); + var h = Sha1.init(.{}); var out: [20]u8 = undefined; h.final(out[0..]); htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); - h = Sha1.init(); + h = Sha1.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); - h = Sha1.init(); + h = Sha1.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -299,7 +300,7 @@ test "sha1 aligned final" { var block = [_]u8{0} ** Sha1.block_length; var out: [Sha1.digest_length]u8 = undefined; - var h = Sha1.init(); + var h = Sha1.init(.{}); h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 851b1dc4050e59ec55cb02a9722fe0e3e7f1c94c..af2c22fe1ca6237887e59793ae61ecd05b22847e 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -88,6 +88,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { const Self = @This(); pub const block_length = 64; pub const digest_length = params.out_len / 8; + pub const Options = struct {}; s: [8]u32, // Streaming Cache @@ -95,7 +96,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { buf_len: u8 = 0, total_len: u64 = 0, - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .s = [_]u32{ params.iv0, @@ -110,8 +111,8 @@ fn Sha2_32(comptime params: Sha2Params32) type { }; } - pub fn hash(b: []const u8, out: []u8) void { - var d = Self.init(); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Self.init(options); d.update(b); d.final(out); } @@ -296,18 +297,18 @@ test "sha224 single" { } test "sha224 streaming" { - var h = Sha224.init(); + var h = Sha224.init(.{}); var out: [28]u8 = undefined; h.final(out[0..]); htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]); - h = Sha224.init(); + h = Sha224.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]); - h = Sha224.init(); + h = Sha224.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -322,18 +323,18 @@ test "sha256 single" { } test "sha256 streaming" { - var h = Sha256.init(); + var h = Sha256.init(.{}); var out: [32]u8 = undefined; h.final(out[0..]); htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]); - h = Sha256.init(); + h = Sha256.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]); - h = Sha256.init(); + h = Sha256.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -345,7 +346,7 @@ test "sha256 aligned final" { var block = [_]u8{0} ** Sha256.block_length; var out: [Sha256.digest_length]u8 = undefined; - var h = Sha256.init(); + var h = Sha256.init(.{}); h.update(&block); h.final(out[0..]); } @@ -458,6 +459,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { const Self = @This(); pub const block_length = 128; pub const digest_length = params.out_len / 8; + pub const Options = struct {}; s: [8]u64, // Streaming Cache @@ -465,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { buf_len: u8 = 0, total_len: u128 = 0, - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .s = [_]u64{ params.iv0, @@ -480,8 +482,8 @@ fn Sha2_64(comptime params: Sha2Params64) type { }; } - pub fn hash(b: []const u8, out: []u8) void { - var d = Self.init(); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Self.init(options); d.update(b); d.final(out); } @@ -693,7 +695,7 @@ test "sha384 single" { } test "sha384 streaming" { - var h = Sha384.init(); + var h = Sha384.init(.{}); var out: [48]u8 = undefined; const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"; @@ -702,12 +704,12 @@ test "sha384 streaming" { const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"; - h = Sha384.init(); + h = Sha384.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Sha384.init(); + h = Sha384.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -727,7 +729,7 @@ test "sha512 single" { } test "sha512 streaming" { - var h = Sha512.init(); + var h = Sha512.init(.{}); var out: [64]u8 = undefined; const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"; @@ -736,12 +738,12 @@ test "sha512 streaming" { const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; - h = Sha512.init(); + h = Sha512.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Sha512.init(); + h = Sha512.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -753,7 +755,7 @@ test "sha512 aligned final" { var block = [_]u8{0} ** Sha512.block_length; var out: [Sha512.digest_length]u8 = undefined; - var h = Sha512.init(); + var h = Sha512.init(.{}); h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index 273e5eea6d924af0f6aeedcb101fc6831f6cfbfe..3d6dad1be17078ece1e7459f213778dd10b49936 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -20,17 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { const Self = @This(); pub const block_length = 200; pub const digest_length = bits / 8; + pub const Options = struct {}; s: [200]u8, offset: usize, rate: usize, - pub fn init() Self { + pub fn init(options: Options) Self { return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) }; } - pub fn hash(b: []const u8, out: []u8) void { - var d = Self.init(); + pub fn hash(b: []const u8, out: []u8, options: Options) void { + var d = Self.init(options); d.update(b); d.final(out); } @@ -175,18 +176,18 @@ test "sha3-224 single" { } test "sha3-224 streaming" { - var h = Sha3_224.init(); + var h = Sha3_224.init(.{}); var out: [28]u8 = undefined; h.final(out[0..]); htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]); - h = Sha3_224.init(); + h = Sha3_224.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]); - h = Sha3_224.init(); + h = Sha3_224.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -201,18 +202,18 @@ test "sha3-256 single" { } test "sha3-256 streaming" { - var h = Sha3_256.init(); + var h = Sha3_256.init(.{}); var out: [32]u8 = undefined; h.final(out[0..]); htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]); - h = Sha3_256.init(); + h = Sha3_256.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]); - h = Sha3_256.init(); + h = Sha3_256.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -224,7 +225,7 @@ test "sha3-256 aligned final" { var block = [_]u8{0} ** Sha3_256.block_length; var out: [Sha3_256.digest_length]u8 = undefined; - var h = Sha3_256.init(); + var h = Sha3_256.init(.{}); h.update(&block); h.final(out[0..]); } @@ -239,7 +240,7 @@ test "sha3-384 single" { } test "sha3-384 streaming" { - var h = Sha3_384.init(); + var h = Sha3_384.init(.{}); var out: [48]u8 = undefined; const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; @@ -247,12 +248,12 @@ test "sha3-384 streaming" { htest.assertEqual(h1, out[0..]); const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"; - h = Sha3_384.init(); + h = Sha3_384.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Sha3_384.init(); + h = Sha3_384.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -270,7 +271,7 @@ test "sha3-512 single" { } test "sha3-512 streaming" { - var h = Sha3_512.init(); + var h = Sha3_512.init(.{}); var out: [64]u8 = undefined; const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; @@ -278,12 +279,12 @@ test "sha3-512 streaming" { htest.assertEqual(h1, out[0..]); const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"; - h = Sha3_512.init(); + h = Sha3_512.init(.{}); h.update("abc"); h.final(out[0..]); htest.assertEqual(h2, out[0..]); - h = Sha3_512.init(); + h = Sha3_512.init(.{}); h.update("a"); h.update("b"); h.update("c"); @@ -295,7 +296,7 @@ test "sha3-512 aligned final" { var block = [_]u8{0} ** Sha3_512.block_length; var out: [Sha3_512.digest_length]u8 = undefined; - var h = Sha3_512.init(); + var h = Sha3_512.init(.{}); h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/test.zig b/lib/std/crypto/test.zig index e4e34e543b95f2732df65c61afdbaa3b91757898..2987706b11aa5e2db0481d8ca8c80206bb235e30 100644 --- a/lib/std/crypto/test.zig +++ b/lib/std/crypto/test.zig @@ -11,7 +11,7 @@ const fmt = std.fmt; // Hash using the specified hasher `H` asserting `expected == H(input)`. pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void { var h: [expected.len / 2]u8 = undefined; - Hasher.hash(input, h[0..]); + Hasher.hash(input, h[0..], .{}); assertEqual(expected, &h); } diff --git a/lib/std/zig.zig b/lib/std/zig.zig index c93c22f257fcc36ac48d23bd0e8cf393f4c360d2..e86a12884ffce894500740007300a945fbd61e24 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash { std.mem.copy(u8, &out, src); std.mem.set(u8, out[src.len..], 0); } else { - std.crypto.hash.Blake3.hash(src, &out); + std.crypto.hash.Blake3.hash(src, &out, .{}); } return out; } -- 2.54.0 From 3edace34d38c95673e56930ccfee1d16d0003359 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 00:57:29 +0200 Subject: [PATCH 47/66] Update tools/process_headers.zig --- tools/process_headers.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/process_headers.zig b/tools/process_headers.zig index ba9fde6683c16a42fad016c11a565f05f96b7279..918802f65d091ffe54b40077b5e359a29e7bd761 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -313,7 +313,7 @@ pub fn main() !void { var max_bytes_saved: usize = 0; var total_bytes: usize = 0; - var hasher = std.crypto.hash.sha2.Sha256.init(); + var hasher = std.crypto.hash.sha2.Sha256.init(.{}); for (libc_targets) |libc_target| { const dest_target = DestTarget{ -- 2.54.0 From eef111fe78d7b246b634a07561082a6fcf947e09 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 01:15:17 +0200 Subject: [PATCH 48/66] Fix missing init() update in std/build/write_file.zig --- lib/std/build/write_file.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/build/write_file.zig b/lib/std/build/write_file.zig index 222de7c79ab76a5918e6ab02848ebf24a2def1ff..17c4b760a12943851ccc8207605f6116cf75f8d8 100644 --- a/lib/std/build/write_file.zig +++ b/lib/std/build/write_file.zig @@ -58,7 +58,7 @@ pub const WriteFileStep = struct { // TODO port the cache system from stage1 to zig std lib. Until then we use blake2b // directly and construct the path, and no "cache hit" detection happens; the files // are always written. - var hash = std.crypto.hash.blake2.Blake2b384.init(); + var hash = std.crypto.hash.blake2.Blake2b384.init(.{}); // Random bytes to make WriteFileStep unique. Refresh this with // new random bytes when WriteFileStep implementation is modified -- 2.54.0 From ebfe723f3cdbb40d2f2280e223b710418abde777 Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 12:20:24 +0300 Subject: [PATCH 49/66] stage2: implement rest of simple pointer types --- src-self-hosted/Module.zig | 26 +++-- src-self-hosted/astgen.zig | 27 +++++- src-self-hosted/codegen.zig | 2 +- src-self-hosted/type.zig | 181 ++++++++++++++++++++++++++++++----- src-self-hosted/zir.zig | 19 +++- src-self-hosted/zir_sema.zig | 26 +++-- 6 files changed, 230 insertions(+), 51 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index d08e7f5746c49fcf6a743e19beea383b64982006..9b27f38fbee0fb8d42cb18ec697f0d32cd368033 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -2429,7 +2429,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn if (decl_tv.val.tag() == .variable) { return self.analyzeVarRef(scope, src, decl_tv); } - const ty = try self.singlePtrType(scope, src, false, decl_tv.ty); + const ty = try self.simplePtrType(scope, src, decl_tv.ty, false, .One); const val_payload = try scope.arena().create(Value.Payload.DeclRef); val_payload.* = .{ .decl = decl }; @@ -2442,7 +2442,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst { const variable = tv.val.cast(Value.Payload.Variable).?.variable; - const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); + const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty, .One); if (!variable.is_mutable and !variable.is_extern) { const val_payload = try scope.arena().create(Value.Payload.RefVal); val_payload.* = .{ .val = variable.init }; @@ -2766,7 +2766,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst // T to ?T if (dest_type.zigTypeTag() == .Optional) { - var buf: Type.Payload.Pointer = undefined; + var buf: Type.Payload.PointerSimple = undefined; const child_type = dest_type.optionalChild(&buf); if (child_type.eql(inst.ty)) { return self.wrapOptional(scope, dest_type, inst); @@ -3145,10 +3145,20 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: return Value.initPayload(val_payload); } -pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, elem_ty: Type) Allocator.Error!Type { - const type_payload = try scope.arena().create(Type.Payload.Pointer); +pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) Allocator.Error!Type { + // TODO stage1 type inference bug + const T = Type.Tag; + + const type_payload = try scope.arena().create(Type.Payload.PointerSimple); type_payload.* = .{ - .base = .{ .tag = if (mutable) .single_mut_pointer else .single_const_pointer }, + .base = .{ + .tag = switch (size) { + .One => if (mutable) .single_mut_pointer else T.many_const_pointer, + .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer, + .C => if (mutable) T.c_mut_pointer else T.c_const_pointer, + else => unreachable, + }, + }, .pointee_type = elem_ty, }; return Type.initPayload(&type_payload.base); @@ -3157,7 +3167,7 @@ pub fn singlePtrType(self: *Module, scope: *Scope, src: usize, mutable: bool, el pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type { return Type.initPayload(switch (child_type.tag()) { .single_const_pointer => blk: { - const payload = try scope.arena().create(Type.Payload.Pointer); + const payload = try scope.arena().create(Type.Payload.PointerSimple); payload.* = .{ .base = .{ .tag = .optional_single_const_pointer }, .pointee_type = child_type.elemType(), @@ -3165,7 +3175,7 @@ pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Er break :blk &payload.base; }, .single_mut_pointer => blk: { - const payload = try scope.arena().create(Type.Payload.Pointer); + const payload = try scope.arena().create(Type.Payload.PointerSimple); payload.* = .{ .base = .{ .tag = .optional_single_mut_pointer }, .pointee_type = child_type.elemType(), diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 9f8afa6225e9c380168adf0749199ac94e016598..bb42b746adb1ff8a8f8139b2483cdb52c8391775 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -577,6 +577,17 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir .val = Value.initTag(.type_type), }); + const size: std.builtin.TypeInfo.Pointer.Size = switch (tree.token_ids[node.op_token]) { + .Asterisk, .AsteriskAsterisk => .One, + // TODO stage1 type inference bug + .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { + .Identifier => .C, + .RBracket => .Many, + else => unreachable, + }), + else => unreachable, + }; + const simple = node.ptr_info.allowzero_token == null and node.ptr_info.align_info == null and node.ptr_info.volatile_token == null and @@ -584,13 +595,19 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir if (simple) { const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); - return addZIRUnOp(mod, scope, src, if (node.ptr_info.const_token == null) - .single_mut_ptr_type - else - .single_const_ptr_type, child_type); + const mutable = node.ptr_info.const_token == null; + // TODO stage1 type inference bug + const T = zir.Inst.Tag; + return addZIRUnOp(mod, scope, src, switch (size) { + .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type, + .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type, + .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type, + else => unreachable, + }, child_type); } var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{}; + kw_args.size = size; kw_args.@"allowzero" = node.ptr_info.allowzero_token != null; if (node.ptr_info.align_info) |some| { kw_args.@"align" = try expr(mod, scope, .none, some.node); @@ -1271,7 +1288,7 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr i += 1; } const slice = tree.tokenSlice(line); - mem.copy(u8, bytes[i..], slice[2..slice.len - 1]); + mem.copy(u8, bytes[i..], slice[2 .. slice.len - 1]); i += slice.len - 3; } diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index 1bc76f6b054bea0a00b81e2dc224c344637382c6..cc5c51159cea6b79ef0af51c5d0e7e88fd0f076d 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -2060,7 +2060,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { if (typed_value.val.isNull()) return MCValue{ .immediate = 0 }; - var buf: Type.Payload.Pointer = undefined; + var buf: Type.Payload.PointerSimple = undefined; return self.genTypedValue(src, .{ .ty = typed_value.ty.optionalChild(&buf), .val = typed_value.val, diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index c2762e1f8ad071a1ae5cc06f1a7ae18390744e6a..233e4792971226dd29c4dd133a655e1d302b901e 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -66,10 +66,15 @@ pub const Type = extern union { .function => return .Fn, .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array, - .single_const_pointer => return .Pointer, - .single_mut_pointer => return .Pointer, - .single_const_pointer_to_comptime_int => return .Pointer, - .const_slice_u8 => return .Pointer, + .single_const_pointer_to_comptime_int, + .const_slice_u8, + .single_const_pointer, + .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, + => return .Pointer, .optional, .optional_single_const_pointer, @@ -108,13 +113,17 @@ pub const Type = extern union { return @fieldParentPtr(T, "base", self.ptr_otherwise); } - pub fn castPointer(self: Type) ?*Payload.Pointer { + pub fn castPointer(self: Type) ?*Payload.PointerSimple { return switch (self.tag()) { .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .optional_single_const_pointer, .optional_single_mut_pointer, - => @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise), + => @fieldParentPtr(Payload.PointerSimple, "base", self.ptr_otherwise), else => null, }; } @@ -198,8 +207,8 @@ pub const Type = extern union { return true; }, .Optional => { - var buf_a: Payload.Pointer = undefined; - var buf_b: Payload.Pointer = undefined; + var buf_a: Payload.PointerSimple = undefined; + var buf_b: Payload.PointerSimple = undefined; return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b)); }, .Float, @@ -263,7 +272,7 @@ pub const Type = extern union { } }, .Optional => { - var buf: Payload.Pointer = undefined; + var buf: Payload.PointerSimple = undefined; std.hash.autoHash(&hasher, self.optionalChild(&buf).hash()); }, .Float, @@ -374,9 +383,13 @@ pub const Type = extern union { .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"), .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .optional_single_mut_pointer, .optional_single_const_pointer, - => return self.copyPayloadSingleField(allocator, Payload.Pointer, "pointee_type"), + => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"), } } @@ -482,17 +495,41 @@ pub const Type = extern union { continue; }, .single_const_pointer => { - const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); try out_stream.writeAll("*const "); ty = payload.pointee_type; continue; }, .single_mut_pointer => { - const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); try out_stream.writeAll("*"); ty = payload.pointee_type; continue; }, + .many_const_pointer => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[*]const "); + ty = payload.pointee_type; + continue; + }, + .many_mut_pointer => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[*]"); + ty = payload.pointee_type; + continue; + }, + .c_const_pointer => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[*c]const "); + ty = payload.pointee_type; + continue; + }, + .c_mut_pointer => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[*c]"); + ty = payload.pointee_type; + continue; + }, .int_signed => { const payload = @fieldParentPtr(Payload.IntSigned, "base", ty.ptr_otherwise); return out_stream.print("i{}", .{payload.bits}); @@ -508,13 +545,13 @@ pub const Type = extern union { continue; }, .optional_single_const_pointer => { - const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); try out_stream.writeAll("?*const "); ty = payload.pointee_type; continue; }, .optional_single_mut_pointer => { - const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); try out_stream.writeAll("?*"); ty = payload.pointee_type; continue; @@ -619,6 +656,10 @@ pub const Type = extern union { .array_sentinel => self.elemType().hasCodeGenBits(), .single_const_pointer => self.elemType().hasCodeGenBits(), .single_mut_pointer => self.elemType().hasCodeGenBits(), + .many_const_pointer => self.elemType().hasCodeGenBits(), + .many_mut_pointer => self.elemType().hasCodeGenBits(), + .c_const_pointer => self.elemType().hasCodeGenBits(), + .c_mut_pointer => self.elemType().hasCodeGenBits(), .int_signed => self.cast(Payload.IntSigned).?.bits == 0, .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0, @@ -669,6 +710,10 @@ pub const Type = extern union { .const_slice_u8, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .optional_single_const_pointer, .optional_single_mut_pointer, => return @divExact(target.cpu.arch.ptrBitWidth(), 8), @@ -704,7 +749,7 @@ pub const Type = extern union { }, .optional => { - var buf: Payload.Pointer = undefined; + var buf: Payload.PointerSimple = undefined; const child_type = self.optionalChild(&buf); if (!child_type.hasCodeGenBits()) return 1; @@ -772,6 +817,10 @@ pub const Type = extern union { .const_slice_u8, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .optional_single_const_pointer, .optional_single_mut_pointer, => return @divExact(target.cpu.arch.ptrBitWidth(), 8), @@ -805,7 +854,7 @@ pub const Type = extern union { }, .optional => { - var buf: Payload.Pointer = undefined; + var buf: Payload.PointerSimple = undefined; const child_type = self.optionalChild(&buf); if (!child_type.hasCodeGenBits()) return 1; @@ -872,6 +921,10 @@ pub const Type = extern union { .optional_single_mut_pointer, .optional_single_const_pointer, .enum_literal, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, => false, .single_const_pointer, @@ -922,6 +975,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .fn_noreturn_no_args, .fn_void_no_args, @@ -987,6 +1044,8 @@ pub const Type = extern union { .int_unsigned, .int_signed, .single_mut_pointer, + .many_mut_pointer, + .c_mut_pointer, .optional, .optional_single_mut_pointer, .optional_single_const_pointer, @@ -994,6 +1053,8 @@ pub const Type = extern union { => false, .single_const_pointer, + .many_const_pointer, + .c_const_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, => true, @@ -1048,6 +1109,10 @@ pub const Type = extern union { .int_signed, .single_mut_pointer, .single_const_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -1063,7 +1128,7 @@ pub const Type = extern union { switch (self.tag()) { .optional_single_const_pointer, .optional_single_mut_pointer => return true, .optional => { - var buf: Payload.Pointer = undefined; + var buf: Payload.PointerSimple = undefined; const child_type = self.optionalChild(&buf); // optionals of zero sized pointers behave like bools if (!child_type.hasCodeGenBits()) return false; @@ -1101,7 +1166,7 @@ pub const Type = extern union { => return false, .Optional => { - var buf: Payload.Pointer = undefined; + var buf: Payload.PointerSimple = undefined; return ty.optionalChild(&buf).isValidVarType(is_extern); }, .Pointer, .Array => ty = ty.elemType(), @@ -1166,13 +1231,17 @@ pub const Type = extern union { .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type, .single_const_pointer => self.castPointer().?.pointee_type, .single_mut_pointer => self.castPointer().?.pointee_type, + .many_const_pointer => self.castPointer().?.pointee_type, + .many_mut_pointer => self.castPointer().?.pointee_type, + .c_const_pointer => self.castPointer().?.pointee_type, + .c_mut_pointer => self.castPointer().?.pointee_type, .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), }; } /// Asserts that the type is an optional. - pub fn optionalChild(self: Type, buf: *Payload.Pointer) Type { + pub fn optionalChild(self: Type, buf: *Payload.PointerSimple) Type { return switch (self.tag()) { .optional => self.cast(Payload.Optional).?.child_type, .optional_single_mut_pointer => { @@ -1199,7 +1268,7 @@ pub const Type = extern union { return switch (self.tag()) { .optional => self.cast(Payload.Optional).?.child_type, .optional_single_mut_pointer, .optional_single_const_pointer => { - const payload = try allocator.create(Payload.Pointer); + const payload = try allocator.create(Payload.PointerSimple); payload.* = .{ .base = .{ .tag = if (self.tag() == .optional_single_const_pointer) @@ -1258,6 +1327,10 @@ pub const Type = extern union { .function, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1318,6 +1391,10 @@ pub const Type = extern union { .function, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1368,6 +1445,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1429,6 +1510,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_signed, @@ -1490,6 +1575,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -1549,6 +1638,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1637,6 +1730,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1701,6 +1798,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1764,6 +1865,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1827,6 +1932,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1887,6 +1996,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1947,6 +2060,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -2027,6 +2144,10 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -2109,7 +2230,13 @@ pub const Type = extern union { ty = ty.elemType(); continue; }, - .single_const_pointer, .single_mut_pointer => { + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, + .single_const_pointer, + .single_mut_pointer, + => { const ptr = ty.castPointer().?; ty = ptr.pointee_type; continue; @@ -2167,11 +2294,17 @@ pub const Type = extern union { .array_u8_sentinel_0, .single_const_pointer, .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, .optional, .optional_single_mut_pointer, .optional_single_const_pointer, .enum_literal, => return false, + + .c_const_pointer, + .c_mut_pointer, + => return true, }; } @@ -2231,6 +2364,10 @@ pub const Type = extern union { array_sentinel, single_const_pointer, single_mut_pointer, + many_const_pointer, + many_mut_pointer, + c_const_pointer, + c_mut_pointer, int_signed, int_unsigned, function, @@ -2272,7 +2409,7 @@ pub const Type = extern union { elem_type: Type, }; - pub const Pointer = struct { + pub const PointerSimple = struct { base: Payload, pointee_type: Type, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 552e90956b2c4fbb2c1211a3f9d229eb75ba3e41..62c0c73f3f4491d4d90f886970025e6b74a7e97a 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -198,6 +198,14 @@ pub const Inst = struct { single_const_ptr_type, /// Create a mutable pointer type based on the element type. `*T` single_mut_ptr_type, + /// Create a const pointer type based on the element type. `[*]const T` + many_const_ptr_type, + /// Create a mutable pointer type based on the element type. `[*]T` + many_mut_ptr_type, + /// Create a const pointer type based on the element type. `[*c]const T` + c_const_ptr_type, + /// Create a mutable pointer type based on the element type. `[*c]T` + c_mut_ptr_type, /// Create a pointer type with attributes ptr_type, /// Write a value to a pointer. For loading, see `deref`. @@ -262,6 +270,10 @@ pub const Inst = struct { .typeof, .single_const_ptr_type, .single_mut_ptr_type, + .many_const_ptr_type, + .many_mut_ptr_type, + .c_const_ptr_type, + .c_mut_ptr_type, .optional_type, .unwrap_optional_safe, .unwrap_optional_unsafe, @@ -400,6 +412,10 @@ pub const Inst = struct { .shr, .single_const_ptr_type, .single_mut_ptr_type, + .many_const_ptr_type, + .many_mut_ptr_type, + .c_const_ptr_type, + .c_mut_ptr_type, .store, .str, .sub, @@ -859,6 +875,7 @@ pub const Inst = struct { @"const": bool = true, @"volatile": bool = false, sentinel: ?*Inst = null, + size: std.builtin.TypeInfo.Pointer.Size = .One, }, }; @@ -2443,7 +2460,7 @@ const EmitZIR = struct { } }, .Optional => { - var buf: Type.Payload.Pointer = undefined; + var buf: Type.Payload.PointerSimple = undefined; const inst = try self.arena.allocator.create(Inst.UnOp); inst.* = .{ .base = .{ diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index cb1ed08d6d8e4c2bb3831f7add473c01a4dbc051..0e331d1979252309fe233a2748c85e43b1c13a22 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -51,8 +51,12 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .ref => return analyzeInstRef(mod, scope, old_inst.castTag(.ref).?), .ret_ptr => return analyzeInstRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?), .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?), - .single_const_ptr_type => return analyzeInstSingleConstPtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?), - .single_mut_ptr_type => return analyzeInstSingleMutPtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?), + .single_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?, false, .One), + .single_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?, true, .One), + .many_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_const_ptr_type).?, false, .Many), + .many_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many), + .c_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C), + .c_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C), .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?), .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?), .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?), @@ -324,7 +328,7 @@ fn analyzeInstRetPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerErr fn analyzeInstRef(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { const operand = try resolveInst(mod, scope, inst.positionals.operand); - const ptr_type = try mod.singlePtrType(scope, inst.base.src, false, operand.ty); + const ptr_type = try mod.simplePtrType(scope, inst.base.src, operand.ty, false, .One); if (operand.value()) |val| { const ref_payload = try scope.arena().create(Value.Payload.RefVal); @@ -369,7 +373,7 @@ fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerErro if (!var_type.isValidVarType(false)) { return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type}); } - const ptr_type = try mod.singlePtrType(scope, inst.base.src, true, var_type); + const ptr_type = try mod.simplePtrType(scope, inst.base.src, var_type, true, .One); const b = try mod.requireRuntimeBlock(scope, inst.base.src); return mod.addNoOp(b, inst.base.src, ptr_type, .alloc); } @@ -723,7 +727,7 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp } const child_type = try operand.ty.elemType().optionalChildAlloc(scope.arena()); - const child_pointer = try mod.singlePtrType(scope, unwrap.base.src, operand.ty.isConstPtr(), child_type); + const child_pointer = try mod.simplePtrType(scope, unwrap.base.src, child_type, operand.ty.isConstPtr(), .One); if (operand.value()) |val| { if (val.isNull()) { @@ -940,7 +944,7 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne // required a larger index. const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64)); - const type_payload = try scope.arena().create(Type.Payload.Pointer); + const type_payload = try scope.arena().create(Type.Payload.PointerSimple); type_payload.* = .{ .base = .{ .tag = .single_const_pointer }, .pointee_type = array_ptr.ty.elemType().elemType(), @@ -1311,15 +1315,9 @@ fn analyzeDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerErr return decl; } -fn analyzeInstSingleConstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { +fn analyzeInstSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*Inst { const elem_type = try resolveType(mod, scope, inst.positionals.operand); - const ty = try mod.singlePtrType(scope, inst.base.src, false, elem_type); - return mod.constType(scope, inst.base.src, ty); -} - -fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { - const elem_type = try resolveType(mod, scope, inst.positionals.operand); - const ty = try mod.singlePtrType(scope, inst.base.src, true, elem_type); + const ty = try mod.simplePtrType(scope, inst.base.src, elem_type, mutable, size); return mod.constType(scope, inst.base.src, ty); } -- 2.54.0 From 95682484503f031efefb2c085cdd4d0b64cf8795 Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 13:52:18 +0300 Subject: [PATCH 50/66] stage2: complex pointer types --- src-self-hosted/Module.zig | 34 +++++++++- src-self-hosted/astgen.zig | 5 +- src-self-hosted/type.zig | 126 +++++++++++++++++++++++++++++++++-- src-self-hosted/zir.zig | 2 +- src-self-hosted/zir_sema.zig | 47 ++++++++++++- 5 files changed, 202 insertions(+), 12 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 9b27f38fbee0fb8d42cb18ec697f0d32cd368033..2dd64c64bcd308b7fe71fd2fc0118c813b847479 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -3153,7 +3153,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu type_payload.* = .{ .base = .{ .tag = switch (size) { - .One => if (mutable) .single_mut_pointer else T.many_const_pointer, + .One => if (mutable) T.single_mut_pointer else T.single_const_pointer, .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer, .C => if (mutable) T.c_mut_pointer else T.c_const_pointer, else => unreachable, @@ -3164,6 +3164,38 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu return Type.initPayload(&type_payload.base); } +pub fn ptrType( + self: *Module, + scope: *Scope, + src: usize, + elem_ty: Type, + sentinel: ?Value, + @"align": u32, + bit_offset: u16, + host_size: u16, + mutable: bool, + @"allowzero": bool, + @"volatile": bool, + size: std.builtin.TypeInfo.Pointer.Size, +) Allocator.Error!Type { + assert(host_size == 0 or bit_offset < host_size * 8); + + // TODO check if type can be represented by simplePtrType + const type_payload = try scope.arena().create(Type.Payload.Pointer); + type_payload.* = .{ + .pointee_type = elem_ty, + .sentinel = sentinel, + .@"align" = @"align", + .bit_offset = bit_offset, + .host_size = host_size, + .@"allowzero" = @"allowzero", + .mutable = mutable, + .@"volatile" = @"volatile", + .size = size, + }; + return Type.initPayload(&type_payload.base); +} + pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type { return Type.initPayload(switch (child_type.tag()) { .single_const_pointer => blk: { diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index bb42b746adb1ff8a8f8139b2483cdb52c8391775..832e6848b35452b0cf769bb67d4dc8a9f41c070b 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -582,8 +582,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir // TODO stage1 type inference bug .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { .Identifier => .C, - .RBracket => .Many, - else => unreachable, + else => .Many, }), else => unreachable, }; @@ -616,7 +615,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end); } } - kw_args.@"const" = node.ptr_info.const_token != null; + kw_args.mutable = node.ptr_info.const_token == null; kw_args.@"volatile" = node.ptr_info.volatile_token != null; if (node.ptr_info.sentinel) |some| { kw_args.sentinel = try expr(mod, scope, .none, some); diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 233e4792971226dd29c4dd133a655e1d302b901e..2c326b93082c9b8b228bb27d9d0dafe0b0ca4cb3 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -74,6 +74,7 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .pointer, => return .Pointer, .optional, @@ -390,6 +391,25 @@ pub const Type = extern union { .optional_single_mut_pointer, .optional_single_const_pointer, => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"), + + .pointer => { + const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); + const new_payload = try allocator.create(Payload.Pointer); + new_payload.* = .{ + .base = payload.base, + + .pointee_type = try payload.pointee_type.copy(allocator), + .sentinel = if (payload.sentinel) |some| try some.copy(allocator) else null, + .@"align" = payload.@"align", + .bit_offset = payload.bit_offset, + .host_size = payload.host_size, + .@"allowzero" = payload.@"allowzero", + .mutable = payload.mutable, + .@"volatile" = payload.@"volatile", + .size = payload.size, + }; + return Type{ .ptr_otherwise = &new_payload.base }; + }, } } @@ -556,6 +576,34 @@ pub const Type = extern union { ty = payload.pointee_type; continue; }, + + .pointer => { + const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); + if (payload.sentinel) |some| switch (payload.size) { + .One, .C => unreachable, + .Many => try out_stream.writeAll("[*:{}]"), + .Slice => try out_stream.writeAll("[:{}]"), + } else switch (payload.size) { + .One => try out_stream.writeAll("*"), + .Many => try out_stream.writeAll("[*]"), + .C => try out_stream.writeAll("[*c]"), + .Slice => try out_stream.writeAll("[]"), + } + if (payload.@"align" != 0) { + try out_stream.print("align({}", .{payload.@"align"}); + + if (payload.bit_offset != 0) { + try out_stream.print(":{}:{}", .{ payload.bit_offset, payload.host_size }); + } + try out_stream.writeAll(") "); + } + if (!payload.mutable) try out_stream.writeAll("const "); + if (payload.@"volatile") try out_stream.writeAll("volatile "); + if (payload.@"allowzero") try out_stream.writeAll("allowzero "); + + ty = payload.pointee_type; + continue; + }, } unreachable; } @@ -660,6 +708,7 @@ pub const Type = extern union { .many_mut_pointer => self.elemType().hasCodeGenBits(), .c_const_pointer => self.elemType().hasCodeGenBits(), .c_mut_pointer => self.elemType().hasCodeGenBits(), + .pointer => self.elemType().hasCodeGenBits(), .int_signed => self.cast(Payload.IntSigned).?.bits == 0, .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0, @@ -718,6 +767,13 @@ pub const Type = extern union { .optional_single_mut_pointer, => return @divExact(target.cpu.arch.ptrBitWidth(), 8), + .pointer => { + const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); + + if (payload.@"align" != 0) return payload.@"align"; + return @divExact(target.cpu.arch.ptrBitWidth(), 8); + }, + .c_short => return @divExact(CType.short.sizeInBits(target), 8), .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8), .c_int => return @divExact(CType.int.sizeInBits(target), 8), @@ -789,6 +845,7 @@ pub const Type = extern union { .@"null" => unreachable, .@"undefined" => unreachable, .enum_literal => unreachable, + .single_const_pointer_to_comptime_int => unreachable, .u8, .i8, @@ -812,18 +869,28 @@ pub const Type = extern union { .i64, .u64 => return 8, .isize, - .usize, - .single_const_pointer_to_comptime_int, - .const_slice_u8, + .usize + => return @divExact(target.cpu.arch.ptrBitWidth(), 8), + .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2, + + .optional_single_const_pointer, + .optional_single_mut_pointer, + => { + if (self.elemType().hasCodeGenBits()) return 1; + return @divExact(target.cpu.arch.ptrBitWidth(), 8); + }, + .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, - .optional_single_const_pointer, - .optional_single_mut_pointer, - => return @divExact(target.cpu.arch.ptrBitWidth(), 8), + .pointer, + => { + if (self.elemType().hasCodeGenBits()) return 0; + return @divExact(target.cpu.arch.ptrBitWidth(), 8); + }, .c_short => return @divExact(CType.short.sizeInBits(target), 8), .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8), @@ -931,6 +998,8 @@ pub const Type = extern union { .single_mut_pointer, .single_const_pointer_to_comptime_int, => true, + + .pointer => self.cast(Payload.Pointer).?.size == .One, }; } @@ -994,6 +1063,8 @@ pub const Type = extern union { => false, .const_slice_u8 => true, + + .pointer => self.cast(Payload.Pointer).?.size == .Slice, }; } @@ -1058,6 +1129,8 @@ pub const Type = extern union { .single_const_pointer_to_comptime_int, .const_slice_u8, => true, + + .pointer => !self.cast(Payload.Pointer).?.mutable, }; } @@ -1120,6 +1193,11 @@ pub const Type = extern union { .optional_single_const_pointer, .enum_literal, => false, + + .pointer => { + const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); + return payload.@"volatile"; + }, }; } @@ -1237,6 +1315,7 @@ pub const Type = extern union { .c_mut_pointer => self.castPointer().?.pointee_type, .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), + .pointer => self.cast(Payload.Pointer).?.pointee_type, }; } @@ -1325,6 +1404,7 @@ pub const Type = extern union { .fn_naked_noreturn_no_args, .fn_ccc_void_no_args, .function, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1389,6 +1469,7 @@ pub const Type = extern union { .fn_naked_noreturn_no_args, .fn_ccc_void_no_args, .function, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1443,6 +1524,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1508,6 +1590,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1573,6 +1656,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1636,6 +1720,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1728,6 +1813,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1796,6 +1882,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1863,6 +1950,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1930,6 +2018,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -1994,6 +2083,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -2058,6 +2148,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -2142,6 +2233,7 @@ pub const Type = extern union { .array_sentinel, .array_u8, .array_u8_sentinel_0, + .pointer, .single_const_pointer, .single_mut_pointer, .many_const_pointer, @@ -2241,6 +2333,10 @@ pub const Type = extern union { ty = ptr.pointee_type; continue; }, + .pointer => { + ty = ty.cast(Payload.Pointer).?.pointee_type; + continue; + }, }; } @@ -2305,6 +2401,8 @@ pub const Type = extern union { .c_const_pointer, .c_mut_pointer, => return true, + + .pointer => self.cast(Payload.Pointer).?.size == .C, }; } @@ -2362,6 +2460,7 @@ pub const Type = extern union { array_u8_sentinel_0, array, array_sentinel, + pointer, single_const_pointer, single_mut_pointer, many_const_pointer, @@ -2440,6 +2539,21 @@ pub const Type = extern union { child_type: Type, }; + + pub const Pointer = struct { + base: Payload = .{ .tag = .pointer }, + + pointee_type: Type, + sentinel: ?Value, + /// If zero use pointee_type.AbiAlign() + @"align": u32, + bit_offset: u16, + host_size: u16, + @"allowzero": bool, + mutable: bool, + @"volatile": bool, + size: std.builtin.TypeInfo.Pointer.Size, + }; }; }; diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 62c0c73f3f4491d4d90f886970025e6b74a7e97a..db0ec242cc159ed74c95418d190e374bf56e34df 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -872,7 +872,7 @@ pub const Inst = struct { @"align": ?*Inst = null, align_bit_start: ?*Inst = null, align_bit_end: ?*Inst = null, - @"const": bool = true, + mutable: bool = true, @"volatile": bool = false, sentinel: ?*Inst = null, size: std.builtin.TypeInfo.Pointer.Size = .One, diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 0e331d1979252309fe233a2748c85e43b1c13a22..ea3b85b29aea51e647581ddbaef42223fd36b27c 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -271,6 +271,14 @@ fn resolveType(mod: *Module, scope: *Scope, old_inst: *zir.Inst) !Type { return val.toType(); } +fn resolveInt(mod: *Module, scope: *Scope, old_inst: *zir.Inst, dest_type: Type) !u64 { + const new_inst = try resolveInst(mod, scope, old_inst); + const coerced = try mod.coerce(scope, dest_type, new_inst); + const val = try mod.resolveConstValue(scope, coerced); + + return val.toUnsignedInt(); +} + pub fn resolveInstConst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!TypedValue { const new_inst = try resolveInst(mod, scope, old_inst); const val = try mod.resolveConstValue(scope, new_inst); @@ -1322,5 +1330,42 @@ fn analyzeInstSimplePtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp, m } fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst { - return mod.fail(scope, inst.base.src, "TODO implement ptr_type", .{}); + // TODO lazy values + const @"align" = if (inst.kw_args.@"align") |some| + @truncate(u32, try resolveInt(mod, scope, some, Type.initTag(.u32))) + else + 0; + const bit_offset = if (inst.kw_args.align_bit_start) |some| + @truncate(u16, try resolveInt(mod, scope, some, Type.initTag(.u16))) + else + 0; + const host_size = if (inst.kw_args.align_bit_end) |some| + @truncate(u16, try resolveInt(mod, scope, some, Type.initTag(.u16))) + else + 0; + + if (host_size != 0 and bit_offset >= host_size * 8) + return mod.fail(scope, inst.base.src, "bit offset starts after end of host integer", .{}); + + const sentinel = if (inst.kw_args.sentinel) |some| + (try resolveInstConst(mod, scope, some)).val + else + null; + + const elem_type = try resolveType(mod, scope, inst.positionals.child_type); + + const ty = try mod.ptrType( + scope, + inst.base.src, + elem_type, + sentinel, + @"align", + bit_offset, + host_size, + inst.kw_args.mutable, + inst.kw_args.@"allowzero", + inst.kw_args.@"volatile", + inst.kw_args.size, + ); + return mod.constType(scope, inst.base.src, ty); } -- 2.54.0 From d312d64c9aa058293d69b2bf97c51f4caa7a2d9d Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 16:37:28 +0300 Subject: [PATCH 51/66] stage2: slice types --- src-self-hosted/Module.zig | 5 +- src-self-hosted/astgen.zig | 50 +++++++++++-------- src-self-hosted/type.zig | 97 +++++++++++++++++++++++++++++------- src-self-hosted/zir.zig | 20 +++++--- src-self-hosted/zir_sema.zig | 2 + 5 files changed, 127 insertions(+), 47 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 2dd64c64bcd308b7fe71fd2fc0118c813b847479..4893aaba7a2d60fffbc1fe47809b031500c2fcf5 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -3146,6 +3146,9 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: } pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) Allocator.Error!Type { + if (size == .Slice and elem_ty.eql(Type.initTag(.u8))) { + return Type.initTag(.const_slice_u8); + } // TODO stage1 type inference bug const T = Type.Tag; @@ -3156,7 +3159,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu .One => if (mutable) T.single_mut_pointer else T.single_const_pointer, .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer, .C => if (mutable) T.c_mut_pointer else T.c_const_pointer, - else => unreachable, + .Slice => if (mutable) T.mut_slice else T.const_slice, }, }, .pointee_type = elem_ty, diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 832e6848b35452b0cf769bb67d4dc8a9f41c070b..8276b191cb256e7054b78da825dce5acad543ec3 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -262,6 +262,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .EnumLiteral => return rlWrap(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)), .MultilineStringLiteral => return rlWrap(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)), .CharLiteral => return rlWrap(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)), + .SliceType => return rlWrap(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)), .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}), @@ -275,7 +276,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr .NegationWrap => return mod.failNode(scope, node, "TODO implement astgen.expr for .NegationWrap", .{}), .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}), .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}), - .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}), .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}), .ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}), .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}), @@ -569,15 +569,16 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn return addZIRUnOp(mod, scope, src, .optional_type, operand); } +fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.SliceType) InnerError!*zir.Inst { + const tree = scope.tree(); + const src = tree.token_locs[node.op_token].start; + return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); +} + fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst { const tree = scope.tree(); const src = tree.token_locs[node.op_token].start; - const meta_type = try addZIRInstConst(mod, scope, src, .{ - .ty = Type.initTag(.type), - .val = Value.initTag(.type_type), - }); - - const size: std.builtin.TypeInfo.Pointer.Size = switch (tree.token_ids[node.op_token]) { + return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) { .Asterisk, .AsteriskAsterisk => .One, // TODO stage1 type inference bug .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { @@ -585,43 +586,50 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir else => .Many, }), else => unreachable, - }; + }); +} - const simple = node.ptr_info.allowzero_token == null and - node.ptr_info.align_info == null and - node.ptr_info.volatile_token == null and - node.ptr_info.sentinel == null; +fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst { + const meta_type = try addZIRInstConst(mod, scope, src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.type_type), + }); + + const simple = ptr_info.allowzero_token == null and + ptr_info.align_info == null and + ptr_info.volatile_token == null and + ptr_info.sentinel == null; if (simple) { - const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); - const mutable = node.ptr_info.const_token == null; + const child_type = try expr(mod, scope, .{ .ty = meta_type }, rhs); + const mutable = ptr_info.const_token == null; // TODO stage1 type inference bug const T = zir.Inst.Tag; return addZIRUnOp(mod, scope, src, switch (size) { .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type, .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type, .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type, - else => unreachable, + .Slice => if (mutable) T.mut_slice_type else T.mut_slice_type, }, child_type); } var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{}; kw_args.size = size; - kw_args.@"allowzero" = node.ptr_info.allowzero_token != null; - if (node.ptr_info.align_info) |some| { + kw_args.@"allowzero" = ptr_info.allowzero_token != null; + if (ptr_info.align_info) |some| { kw_args.@"align" = try expr(mod, scope, .none, some.node); if (some.bit_range) |bit_range| { kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start); kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end); } } - kw_args.mutable = node.ptr_info.const_token == null; - kw_args.@"volatile" = node.ptr_info.volatile_token != null; - if (node.ptr_info.sentinel) |some| { + kw_args.mutable = ptr_info.const_token == null; + kw_args.@"volatile" = ptr_info.volatile_token != null; + if (ptr_info.sentinel) |some| { kw_args.sentinel = try expr(mod, scope, .none, some); } - const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); + const child_type = try expr(mod, scope, .{ .ty = meta_type }, rhs); if (kw_args.sentinel) |some| { kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some); } diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 2c326b93082c9b8b228bb27d9d0dafe0b0ca4cb3..2218c49200199e61ef5d05d27556b01ef13733d9 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -74,6 +74,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .pointer, => return .Pointer, @@ -122,6 +124,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .optional_single_const_pointer, .optional_single_mut_pointer, => @fieldParentPtr(Payload.PointerSimple, "base", self.ptr_otherwise), @@ -388,6 +392,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .optional_single_mut_pointer, .optional_single_const_pointer, => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"), @@ -550,6 +556,18 @@ pub const Type = extern union { ty = payload.pointee_type; continue; }, + .const_slice => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[]const "); + ty = payload.pointee_type; + continue; + }, + .mut_slice => { + const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); + try out_stream.writeAll("[]"); + ty = payload.pointee_type; + continue; + }, .int_signed => { const payload = @fieldParentPtr(Payload.IntSigned, "base", ty.ptr_otherwise); return out_stream.print("i{}", .{payload.bits}); @@ -701,14 +719,7 @@ pub const Type = extern union { // TODO lazy types .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, .array_u8 => self.arrayLen() != 0, - .array_sentinel => self.elemType().hasCodeGenBits(), - .single_const_pointer => self.elemType().hasCodeGenBits(), - .single_mut_pointer => self.elemType().hasCodeGenBits(), - .many_const_pointer => self.elemType().hasCodeGenBits(), - .many_mut_pointer => self.elemType().hasCodeGenBits(), - .c_const_pointer => self.elemType().hasCodeGenBits(), - .c_mut_pointer => self.elemType().hasCodeGenBits(), - .pointer => self.elemType().hasCodeGenBits(), + .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(), .int_signed => self.cast(Payload.IntSigned).?.bits == 0, .int_unsigned => self.cast(Payload.IntUnsigned).?.bits == 0, @@ -763,6 +774,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .optional_single_const_pointer, .optional_single_mut_pointer, => return @divExact(target.cpu.arch.ptrBitWidth(), 8), @@ -868,10 +881,12 @@ pub const Type = extern union { .i32, .u32 => return 4, .i64, .u64 => return 8, - .isize, - .usize - => return @divExact(target.cpu.arch.ptrBitWidth(), 8), - .const_slice_u8 => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2, + .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8), + + .const_slice, + .mut_slice, + .const_slice_u8, + => return @divExact(target.cpu.arch.ptrBitWidth(), 8) * 2, .optional_single_const_pointer, .optional_single_mut_pointer, @@ -992,6 +1007,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, => false, .single_const_pointer, @@ -1062,7 +1079,10 @@ pub const Type = extern union { .enum_literal, => false, - .const_slice_u8 => true, + .const_slice, + .mut_slice, + .const_slice_u8, + => true, .pointer => self.cast(Payload.Pointer).?.size == .Slice, }; @@ -1121,6 +1141,7 @@ pub const Type = extern union { .optional_single_mut_pointer, .optional_single_const_pointer, .enum_literal, + .mut_slice, => false, .single_const_pointer, @@ -1128,6 +1149,7 @@ pub const Type = extern union { .c_const_pointer, .single_const_pointer_to_comptime_int, .const_slice_u8, + .const_slice, => true, .pointer => !self.cast(Payload.Pointer).?.mutable, @@ -1186,6 +1208,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -1307,12 +1331,15 @@ pub const Type = extern union { .array => self.cast(Payload.Array).?.elem_type, .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type, - .single_const_pointer => self.castPointer().?.pointee_type, - .single_mut_pointer => self.castPointer().?.pointee_type, - .many_const_pointer => self.castPointer().?.pointee_type, - .many_mut_pointer => self.castPointer().?.pointee_type, - .c_const_pointer => self.castPointer().?.pointee_type, - .c_mut_pointer => self.castPointer().?.pointee_type, + .single_const_pointer, + .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, + .const_slice, + .mut_slice, + => self.castPointer().?.pointee_type, .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int), .pointer => self.cast(Payload.Pointer).?.pointee_type, @@ -1411,6 +1438,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1476,6 +1505,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1531,6 +1562,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1597,6 +1630,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_signed, @@ -1663,6 +1698,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -1727,6 +1764,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .int_unsigned, @@ -1820,6 +1859,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1889,6 +1930,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -1957,6 +2000,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -2025,6 +2070,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -2090,6 +2137,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -2155,6 +2204,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .u8, @@ -2240,6 +2291,8 @@ pub const Type = extern union { .many_mut_pointer, .c_const_pointer, .c_mut_pointer, + .const_slice, + .mut_slice, .single_const_pointer_to_comptime_int, .const_slice_u8, .optional, @@ -2290,6 +2343,8 @@ pub const Type = extern union { .array_sentinel, .array_u8_sentinel_0, .const_slice_u8, + .const_slice, + .mut_slice, .c_void, .optional, .optional_single_mut_pointer, @@ -2392,6 +2447,8 @@ pub const Type = extern union { .single_mut_pointer, .many_const_pointer, .many_mut_pointer, + .const_slice, + .mut_slice, .optional, .optional_single_mut_pointer, .optional_single_const_pointer, @@ -2467,6 +2524,8 @@ pub const Type = extern union { many_mut_pointer, c_const_pointer, c_mut_pointer, + const_slice, + mut_slice, int_signed, int_unsigned, function, diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index db0ec242cc159ed74c95418d190e374bf56e34df..a3ea1f11ab47a2360968a6abe6f69e3b7d3a155c 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -194,18 +194,22 @@ pub const Inst = struct { shl, /// Integer shift-right. Arithmetic or logical depending on the signedness of the integer type. shr, - /// Create a const pointer type based on the element type. `*const T` + /// Create a const pointer type with element type T. `*const T` single_const_ptr_type, - /// Create a mutable pointer type based on the element type. `*T` + /// Create a mutable pointer type with element type T. `*T` single_mut_ptr_type, - /// Create a const pointer type based on the element type. `[*]const T` + /// Create a const pointer type with element type T. `[*]const T` many_const_ptr_type, - /// Create a mutable pointer type based on the element type. `[*]T` + /// Create a mutable pointer type with element type T. `[*]T` many_mut_ptr_type, - /// Create a const pointer type based on the element type. `[*c]const T` + /// Create a const pointer type with element type T. `[*c]const T` c_const_ptr_type, - /// Create a mutable pointer type based on the element type. `[*c]T` + /// Create a mutable pointer type with element type T. `[*c]T` c_mut_ptr_type, + /// Create a mutable slice type with element type T. `[]T` + mut_slice_type, + /// Create a const slice type with element type T. `[]T` + const_slice_type, /// Create a pointer type with attributes ptr_type, /// Write a value to a pointer. For loading, see `deref`. @@ -274,6 +278,8 @@ pub const Inst = struct { .many_mut_ptr_type, .c_const_ptr_type, .c_mut_ptr_type, + .mut_slice_type, + .const_slice_type, .optional_type, .unwrap_optional_safe, .unwrap_optional_unsafe, @@ -416,6 +422,8 @@ pub const Inst = struct { .many_mut_ptr_type, .c_const_ptr_type, .c_mut_ptr_type, + .mut_slice_type, + .const_slice_type, .store, .str, .sub, diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index ea3b85b29aea51e647581ddbaef42223fd36b27c..75ec7f6306a53425288f8408cae81398113d1b54 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -57,6 +57,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .many_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many), .c_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C), .c_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C), + .const_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.const_slice_type).?, false, .Slice), + .mut_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.mut_slice_type).?, true, .Slice), .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?), .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?), .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?), -- 2.54.0 From 6a053ffcc85ce3f2b598be08e5d0587c930b4358 Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 20 Aug 2020 18:50:13 +0300 Subject: [PATCH 52/66] stage2: comptime decl --- src-self-hosted/Module.zig | 51 ++++++++++++++++++++++++++++++++-- test/stage2/compare_output.zig | 5 ---- test/stage2/compile_errors.zig | 36 ++++++++---------------- 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 4893aaba7a2d60fffbc1fe47809b031500c2fcf5..ba39aa8f38326076f78bdb5b4ec1dc0031b21cd0 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -1485,6 +1485,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { const type_node = var_decl.getTrailer("type_node") orelse break :blk null; + // Temporary arena for the zir instructions. var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa); defer type_scope_arena.deinit(); var type_scope: Scope.GenZIR = .{ @@ -1539,7 +1540,8 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { try self.coerce(&inner_block.base, some, ret.operand) else ret.operand; - const val = try self.resolveConstValue(&inner_block.base, coerced); + const val = coerced.value() orelse + return self.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{}); var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena); break :blk try val.copy(block_scope.arena); @@ -1603,7 +1605,41 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { } return type_changed; }, - .Comptime => @panic("TODO comptime decl"), + .Comptime => { + const comptime_decl = @fieldParentPtr(ast.Node.Comptime, "base", ast_node); + + decl.analysis = .in_progress; + + // A comptime decl does not store any value so we can just deinit this arena after analysis is done. + var analysis_arena = std.heap.ArenaAllocator.init(self.gpa); + defer analysis_arena.deinit(); + var gen_scope: Scope.GenZIR = .{ + .decl = decl, + .arena = &analysis_arena.allocator, + .parent = decl.scope, + }; + defer gen_scope.instructions.deinit(self.gpa); + + // TODO comptime scope here + _ = try astgen.expr(self, &gen_scope.base, .none, comptime_decl.expr); + + var block_scope: Scope.Block = .{ + .parent = null, + .func = null, + .decl = decl, + .instructions = .{}, + .arena = &analysis_arena.allocator, + }; + defer block_scope.instructions.deinit(self.gpa); + + _ = try zir_sema.analyzeBody(self, &block_scope.base, .{ + .instructions = gen_scope.instructions.items, + }); + + decl.analysis = .complete; + decl.generation = self.generation; + return true; + }, .Use => @panic("TODO usingnamespace decl"), else => unreachable, } @@ -1794,7 +1830,16 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void { } } } else if (src_decl.castTag(.Comptime)) |comptime_node| { - log.err("TODO: analyze comptime decl", .{}); + const name_index = self.getNextAnonNameIndex(); + const name = try std.fmt.allocPrint(self.gpa, "__comptime_{}", .{name_index}); + defer self.gpa.free(name); + + const name_hash = root_scope.fullyQualifiedNameHash(name); + const contents_hash = std.zig.hashSrc(tree.getNodeSource(src_decl)); + + const new_decl = try self.createNewDecl(&root_scope.base, name, decl_i, name_hash, contents_hash); + root_scope.decls.appendAssumeCapacity(new_decl); + self.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl }); } else if (src_decl.castTag(.ContainerField)) |container_field| { log.err("TODO: analyze container field", .{}); } else if (src_decl.castTag(.TestDecl)) |test_decl| { diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 6fbc760f26dba01f2abc5c5571d624e503d33b5b..6c4b9c47e0455fdfc05c29d63dd4ea25e70343e9 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -23,11 +23,6 @@ pub fn addCases(ctx: *TestContext) !void { case.addError("", &[_][]const u8{":1:1: error: no entry point found"}); - case.addError( - \\export fn _start() noreturn { - \\} - , &[_][]const u8{":2:1: error: expected noreturn, found void"}); - // Regular old hello world case.addCompareOutput( \\export fn _start() noreturn { diff --git a/test/stage2/compile_errors.zig b/test/stage2/compile_errors.zig index 45e60c074198a6af8c94b24f5d166a528a456f5d..d90c0c7faea3d7266c03828b37eadaddc90e6e7e 100644 --- a/test/stage2/compile_errors.zig +++ b/test/stage2/compile_errors.zig @@ -67,6 +67,18 @@ pub fn addCases(ctx: *TestContext) !void { \\fn entry() void {} , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); + ctx.compileError("incorrect return type", linux_x64, + \\export fn _start() noreturn { + \\} + , &[_][]const u8{":2:1: error: expected noreturn, found void"}); + + ctx.compileError("extern variable has no type", linux_x64, + \\comptime { + \\ _ = foo; + \\} + \\extern var foo; + , &[_][]const u8{":4:1: error: unable to infer variable type"}); + //ctx.incrementalFailure("function redefinition", linux_x64, // \\fn entry() void {} // \\fn entry() void {} @@ -108,28 +120,4 @@ pub fn addCases(ctx: *TestContext) !void { // \\ return 36893488147419103232; // \\} //, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'"); - - //ctx.testCompileError( - // \\comptime { - // \\ var a: *align(4) align(4) i32 = 0; - // \\} - //, "1.zig", 2, 22, "Extra align qualifier"); - - //ctx.testCompileError( - // \\comptime { - // \\ var b: *const const i32 = 0; - // \\} - //, "1.zig", 2, 19, "Extra align qualifier"); - - //ctx.testCompileError( - // \\comptime { - // \\ var c: *volatile volatile i32 = 0; - // \\} - //, "1.zig", 2, 22, "Extra align qualifier"); - - //ctx.testCompileError( - // \\comptime { - // \\ var d: *allowzero allowzero i32 = 0; - // \\} - //, "1.zig", 2, 23, "Extra align qualifier"); } -- 2.54.0 From f54b2e2da6a9ef72a37fae064dc04d951c686298 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 17:08:01 -0700 Subject: [PATCH 53/66] add missing mutability check in simplePtrType --- src-self-hosted/Module.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index ba39aa8f38326076f78bdb5b4ec1dc0031b21cd0..c0d1d0d65431560d7dfad3af9f4d03314592cf78 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -2487,7 +2487,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst { const variable = tv.val.cast(Value.Payload.Variable).?.variable; - const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty, .One); + const ty = try self.simplePtrType(scope, src, tv.ty, variable.is_mutable, .One); if (!variable.is_mutable and !variable.is_extern) { const val_payload = try scope.arena().create(Value.Payload.RefVal); val_payload.* = .{ .val = variable.init }; @@ -3191,7 +3191,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: } pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) Allocator.Error!Type { - if (size == .Slice and elem_ty.eql(Type.initTag(.u8))) { + if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) { return Type.initTag(.const_slice_u8); } // TODO stage1 type inference bug -- 2.54.0 From 7d6d4b1473e7c0c8bc6ee29a3e0ecd03e850e5ee Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 17:15:01 -0700 Subject: [PATCH 54/66] stage2: move all tests to compare_output.zig --- test/stage2/compare_output.zig | 18 +++++++++++ test/stage2/compile_errors.zig | 59 ---------------------------------- 2 files changed, 18 insertions(+), 59 deletions(-) diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index 6c4b9c47e0455fdfc05c29d63dd4ea25e70343e9..3e08394b2ec6577975859dad30bde3698cf13c84 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -23,6 +23,12 @@ pub fn addCases(ctx: *TestContext) !void { case.addError("", &[_][]const u8{":1:1: error: no entry point found"}); + // Incorrect return type + case.addError( + \\export fn _start() noreturn { + \\} + , &[_][]const u8{":2:1: error: expected noreturn, found void"}); + // Regular old hello world case.addCompareOutput( \\export fn _start() noreturn { @@ -702,4 +708,16 @@ pub fn addCases(ctx: *TestContext) !void { "1109917696\n", ); } + + ctx.compileError("function redefinition", linux_x64, + \\fn entry() void {} + \\fn entry() void {} + , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); + + ctx.compileError("extern variable has no type", linux_x64, + \\comptime { + \\ _ = foo; + \\} + \\extern var foo; + , &[_][]const u8{":4:1: error: unable to infer variable type"}); } diff --git a/test/stage2/compile_errors.zig b/test/stage2/compile_errors.zig index d90c0c7faea3d7266c03828b37eadaddc90e6e7e..ce53884acac6147e2f7fbe7562fe59f2014860ae 100644 --- a/test/stage2/compile_errors.zig +++ b/test/stage2/compile_errors.zig @@ -61,63 +61,4 @@ pub fn addCases(ctx: *TestContext) !void { \\@0 = str("_start") \\@1 = export(@0, "start") ); - - ctx.compileError("function redefinition", linux_x64, - \\fn entry() void {} - \\fn entry() void {} - , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); - - ctx.compileError("incorrect return type", linux_x64, - \\export fn _start() noreturn { - \\} - , &[_][]const u8{":2:1: error: expected noreturn, found void"}); - - ctx.compileError("extern variable has no type", linux_x64, - \\comptime { - \\ _ = foo; - \\} - \\extern var foo; - , &[_][]const u8{":4:1: error: unable to infer variable type"}); - - //ctx.incrementalFailure("function redefinition", linux_x64, - // \\fn entry() void {} - // \\fn entry() void {} - //, &[_][]const u8{":2:4: error: redefinition of 'entry'"}, - // \\fn entry() void {} - //); - - //// TODO: need to make sure this works with other variants of export. - //ctx.incrementalFailure("exported symbol collision", linux_x64, - // \\export fn entry() void {} - // \\export fn entry() void {} - //, &[_][]const u8{":2:11: error: redefinition of 'entry'"}, - // \\export fn entry() void {} - //); - - // ctx.incrementalFailure("missing function name", linux_x64, - // \\fn() void {} - // , &[_][]const u8{":1:3: error: missing function name"}, - // \\fn a() void {} - // ); - - // TODO: re-enable these tests. - // https://github.com/ziglang/zig/issues/1364 - - //ctx.testCompileError( - // \\comptime { - // \\ return; - // \\} - //, "1.zig", 2, 5, "return expression outside function definition"); - - //ctx.testCompileError( - // \\export fn entry() void { - // \\ defer return; - // \\} - //, "1.zig", 2, 11, "cannot return from defer expression"); - - //ctx.testCompileError( - // \\export fn entry() c_int { - // \\ return 36893488147419103232; - // \\} - //, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'"); } -- 2.54.0 From 56ea04cb6d1b2b87e2a2dbde6de8279e035bec73 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 17:19:26 -0700 Subject: [PATCH 55/66] stage2: don't test compile errors of ZIR --- test/stage2/compile_errors.zig | 64 ---------------------------------- test/stage2/test.zig | 1 - 2 files changed, 65 deletions(-) delete mode 100644 test/stage2/compile_errors.zig diff --git a/test/stage2/compile_errors.zig b/test/stage2/compile_errors.zig deleted file mode 100644 index ce53884acac6147e2f7fbe7562fe59f2014860ae..0000000000000000000000000000000000000000 --- a/test/stage2/compile_errors.zig +++ /dev/null @@ -1,64 +0,0 @@ -const TestContext = @import("../../src-self-hosted/test.zig").TestContext; -const std = @import("std"); - -const ErrorMsg = @import("../../src-self-hosted/Module.zig").ErrorMsg; - -const linux_x64 = std.zig.CrossTarget{ - .cpu_arch = .x86_64, - .os_tag = .linux, -}; - -pub fn addCases(ctx: *TestContext) !void { - ctx.compileErrorZIR("call undefined local", linux_x64, - \\@noreturn = primitive(noreturn) - \\ - \\@start_fnty = fntype([], @noreturn, cc=Naked) - \\@start = fn(@start_fnty, { - \\ %0 = call(%test, []) - \\}) - // TODO: address inconsistency in this message and the one in the next test - , &[_][]const u8{":5:13: error: unrecognized identifier: %test"}); - - ctx.compileErrorZIR("call with non-existent target", linux_x64, - \\@noreturn = primitive(noreturn) - \\ - \\@start_fnty = fntype([], @noreturn, cc=Naked) - \\@start = fn(@start_fnty, { - \\ %0 = call(@notafunc, []) - \\}) - \\@0 = str("_start") - \\@1 = export(@0, "start") - , &[_][]const u8{":5:13: error: decl 'notafunc' not found"}); - - // TODO: this error should occur at the call site, not the fntype decl - ctx.compileErrorZIR("call naked function", linux_x64, - \\@noreturn = primitive(noreturn) - \\ - \\@start_fnty = fntype([], @noreturn, cc=Naked) - \\@s = fn(@start_fnty, {}) - \\@start = fn(@start_fnty, { - \\ %0 = call(@s, []) - \\}) - \\@0 = str("_start") - \\@1 = export(@0, "start") - , &[_][]const u8{":4:9: error: unable to call function with naked calling convention"}); - - ctx.incrementalFailureZIR("exported symbol collision", linux_x64, - \\@noreturn = primitive(noreturn) - \\ - \\@start_fnty = fntype([], @noreturn) - \\@start = fn(@start_fnty, {}) - \\ - \\@0 = str("_start") - \\@1 = export(@0, "start") - \\@2 = export(@0, "start") - , &[_][]const u8{":8:13: error: exported symbol collision: _start"}, - \\@noreturn = primitive(noreturn) - \\ - \\@start_fnty = fntype([], @noreturn) - \\@start = fn(@start_fnty, {}) - \\ - \\@0 = str("_start") - \\@1 = export(@0, "start") - ); -} diff --git a/test/stage2/test.zig b/test/stage2/test.zig index f5acc72f93d2725f0b224f5f096c996f550306ef..182bd116e0ab976fe73b43701727b9e39275cb38 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -1,7 +1,6 @@ const TestContext = @import("../../src-self-hosted/test.zig").TestContext; pub fn addCases(ctx: *TestContext) !void { - try @import("compile_errors.zig").addCases(ctx); try @import("compare_output.zig").addCases(ctx); try @import("zir.zig").addCases(ctx); try @import("cbe.zig").addCases(ctx); -- 2.54.0 From 73d16d015e09c05aecba8a58881cbc429e8126fa Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 17:25:09 -0700 Subject: [PATCH 56/66] stage2: reorganize tests The main test cases are now in `test/stage2/test.zig` which can then call addCases on other files if it wants to organize things differently. --- test/stage2/compare_output.zig | 723 --------------------------------- test/stage2/test.zig | 721 +++++++++++++++++++++++++++++++- 2 files changed, 720 insertions(+), 724 deletions(-) delete mode 100644 test/stage2/compare_output.zig diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig deleted file mode 100644 index 3e08394b2ec6577975859dad30bde3698cf13c84..0000000000000000000000000000000000000000 --- a/test/stage2/compare_output.zig +++ /dev/null @@ -1,723 +0,0 @@ -const std = @import("std"); -const TestContext = @import("../../src-self-hosted/test.zig").TestContext; -// self-hosted does not yet support PE executable files / COFF object files -// or mach-o files. So we do these test cases cross compiling for x86_64-linux. -const linux_x64 = std.zig.CrossTarget{ - .cpu_arch = .x86_64, - .os_tag = .linux, -}; - -const linux_riscv64 = std.zig.CrossTarget{ - .cpu_arch = .riscv64, - .os_tag = .linux, -}; - -const wasi = std.zig.CrossTarget{ - .cpu_arch = .wasm32, - .os_tag = .wasi, -}; - -pub fn addCases(ctx: *TestContext) !void { - { - var case = ctx.exe("hello world with updates", linux_x64); - - case.addError("", &[_][]const u8{":1:1: error: no entry point found"}); - - // Incorrect return type - case.addError( - \\export fn _start() noreturn { - \\} - , &[_][]const u8{":2:1: error: expected noreturn, found void"}); - - // Regular old hello world - case.addCompareOutput( - \\export fn _start() noreturn { - \\ print(); - \\ - \\ exit(); - \\} - \\ - \\fn print() void { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (1), - \\ [arg1] "{rdi}" (1), - \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")), - \\ [arg3] "{rdx}" (14) - \\ : "rcx", "r11", "memory" - \\ ); - \\ return; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "Hello, World!\n", - ); - // Now change the message only - case.addCompareOutput( - \\export fn _start() noreturn { - \\ print(); - \\ - \\ exit(); - \\} - \\ - \\fn print() void { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (1), - \\ [arg1] "{rdi}" (1), - \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")), - \\ [arg3] "{rdx}" (104) - \\ : "rcx", "r11", "memory" - \\ ); - \\ return; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "What is up? This is a longer message that will force the data to be relocated in virtual address space.\n", - ); - // Now we print it twice. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ print(); - \\ print(); - \\ - \\ exit(); - \\} - \\ - \\fn print() void { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (1), - \\ [arg1] "{rdi}" (1), - \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")), - \\ [arg3] "{rdx}" (104) - \\ : "rcx", "r11", "memory" - \\ ); - \\ return; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - \\What is up? This is a longer message that will force the data to be relocated in virtual address space. - \\What is up? This is a longer message that will force the data to be relocated in virtual address space. - \\ - ); - } - - { - var case = ctx.exe("hello world", linux_riscv64); - // Regular old hello world - case.addCompareOutput( - \\export fn _start() noreturn { - \\ print(); - \\ - \\ exit(); - \\} - \\ - \\fn print() void { - \\ asm volatile ("ecall" - \\ : - \\ : [number] "{a7}" (64), - \\ [arg1] "{a0}" (1), - \\ [arg2] "{a1}" (@ptrToInt("Hello, World!\n")), - \\ [arg3] "{a2}" ("Hello, World!\n".len) - \\ : "rcx", "r11", "memory" - \\ ); - \\ return; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("ecall" - \\ : - \\ : [number] "{a7}" (94), - \\ [arg1] "{a0}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "Hello, World!\n", - ); - } - - { - var case = ctx.exe("adding numbers at comptime", linux_x64); - case.addCompareOutput( - \\export fn _start() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (1), - \\ [arg1] "{rdi}" (1), - \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")), - \\ [arg3] "{rdx}" (10 + 4) - \\ : "rcx", "r11", "memory" - \\ ); - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (@as(usize, 230) + @as(usize, 1)), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "Hello, World!\n", - ); - } - - { - var case = ctx.exe("adding numbers at runtime", linux_x64); - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(3, 4); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ if (a + b != 7) unreachable; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - } - - { - var case = ctx.exe("substracting numbers at runtime", linux_x64); - case.addCompareOutput( - \\export fn _start() noreturn { - \\ sub(7, 4); - \\ - \\ exit(); - \\} - \\ - \\fn sub(a: u32, b: u32) void { - \\ if (a - b != 3) unreachable; - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - } - - { - var case = ctx.exe("assert function", linux_x64); - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(3, 4); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ assert(a + b == 7); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Tests copying a register. For the `c = a + b`, it has to - // preserve both a and b, because they are both used later. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(3, 4); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ const c = a + b; // 7 - \\ const d = a + c; // 10 - \\ const e = d + b; // 14 - \\ assert(e == 14); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // More stress on the liveness detection. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(3, 4); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ const c = a + b; // 7 - \\ const d = a + c; // 10 - \\ const e = d + b; // 14 - \\ const f = d + e; // 24 - \\ const g = e + f; // 38 - \\ const h = f + g; // 62 - \\ const i = g + h; // 100 - \\ assert(i == 100); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Requires a second move. The register allocator should figure out to re-use rax. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(3, 4); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ const c = a + b; // 7 - \\ const d = a + c; // 10 - \\ const e = d + b; // 14 - \\ const f = d + e; // 24 - \\ const g = e + f; // 38 - \\ const h = f + g; // 62 - \\ const i = g + h; // 100 - \\ const j = i + d; // 110 - \\ assert(j == 110); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Now we test integer return values. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ assert(add(3, 4) == 7); - \\ assert(add(20, 10) == 30); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) u32 { - \\ return a + b; - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Local mutable variables. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ assert(add(3, 4) == 7); - \\ assert(add(20, 10) == 30); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) u32 { - \\ var x: u32 = undefined; - \\ x = 0; - \\ x += a; - \\ x += b; - \\ return x; - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Optionals - case.addCompareOutput( - \\export fn _start() noreturn { - \\ const a: u32 = 2; - \\ const b: ?u32 = a; - \\ const c = b.?; - \\ if (c != 2) unreachable; - \\ - \\ exit(); - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // While loops - case.addCompareOutput( - \\export fn _start() noreturn { - \\ var i: u32 = 0; - \\ while (i < 4) : (i += 1) print(); - \\ assert(i == 4); - \\ - \\ exit(); - \\} - \\ - \\fn print() void { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (1), - \\ [arg1] "{rdi}" (1), - \\ [arg2] "{rsi}" (@ptrToInt("hello\n")), - \\ [arg3] "{rdx}" (6) - \\ : "rcx", "r11", "memory" - \\ ); - \\ return; - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "hello\nhello\nhello\nhello\n", - ); - - // Labeled blocks (no conditional branch) - case.addCompareOutput( - \\export fn _start() noreturn { - \\ assert(add(3, 4) == 20); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) u32 { - \\ const x: u32 = blk: { - \\ const c = a + b; // 7 - \\ const d = a + c; // 10 - \\ const e = d + b; // 14 - \\ break :blk e; - \\ }; - \\ const y = x + a; // 17 - \\ const z = y + a; // 20 - \\ return z; - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // This catches a possible bug in the logic for re-using dying operands. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ assert(add(3, 4) == 116); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) u32 { - \\ const x: u32 = blk: { - \\ const c = a + b; // 7 - \\ const d = a + c; // 10 - \\ const e = d + b; // 14 - \\ const f = d + e; // 24 - \\ const g = e + f; // 38 - \\ const h = f + g; // 62 - \\ const i = g + h; // 100 - \\ const j = i + d; // 110 - \\ break :blk j; - \\ }; - \\ const y = x + a; // 113 - \\ const z = y + a; // 116 - \\ return z; - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Character literals and multiline strings. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ const ignore = - \\ \\ cool thx - \\ \\ - \\ ; - \\ add('ぁ', '\x03'); - \\ - \\ exit(); - \\} - \\ - \\fn add(a: u32, b: u32) void { - \\ assert(a + b == 12356); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - - // Global const. - case.addCompareOutput( - \\export fn _start() noreturn { - \\ add(aa, bb); - \\ - \\ exit(); - \\} - \\ - \\const aa = 'ぁ'; - \\const bb = '\x03'; - \\ - \\fn add(a: u32, b: u32) void { - \\ assert(a + b == 12356); - \\} - \\ - \\pub fn assert(ok: bool) void { - \\ if (!ok) unreachable; // assertion failure - \\} - \\ - \\fn exit() noreturn { - \\ asm volatile ("syscall" - \\ : - \\ : [number] "{rax}" (231), - \\ [arg1] "{rdi}" (0) - \\ : "rcx", "r11", "memory" - \\ ); - \\ unreachable; - \\} - , - "", - ); - } - - { - var case = ctx.exe("wasm function calls", wasi); - - case.addCompareOutput( - \\export fn _start() u32 { - \\ foo(); - \\ bar(); - \\ return 42; - \\} - \\fn foo() void { - \\ bar(); - \\ bar(); - \\} - \\fn bar() void {} - , - "42\n", - ); - - case.addCompareOutput( - \\export fn _start() i64 { - \\ bar(); - \\ foo(); - \\ foo(); - \\ bar(); - \\ foo(); - \\ bar(); - \\ return 42; - \\} - \\fn foo() void { - \\ bar(); - \\} - \\fn bar() void {} - , - "42\n", - ); - - case.addCompareOutput( - \\export fn _start() f32 { - \\ bar(); - \\ foo(); - \\ return 42.0; - \\} - \\fn foo() void { - \\ bar(); - \\ bar(); - \\ bar(); - \\} - \\fn bar() void {} - , - // This is what you get when you take the bits of the IEE-754 - // representation of 42.0 and reinterpret them as an unsigned - // integer. Guess that's a bug in wasmtime. - "1109917696\n", - ); - } - - ctx.compileError("function redefinition", linux_x64, - \\fn entry() void {} - \\fn entry() void {} - , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); - - ctx.compileError("extern variable has no type", linux_x64, - \\comptime { - \\ _ = foo; - \\} - \\extern var foo; - , &[_][]const u8{":4:1: error: unable to infer variable type"}); -} diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 182bd116e0ab976fe73b43701727b9e39275cb38..91257526dd2a21235ec803bd37e5bdbf618bf431 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -1,7 +1,726 @@ +const std = @import("std"); const TestContext = @import("../../src-self-hosted/test.zig").TestContext; +// self-hosted does not yet support PE executable files / COFF object files +// or mach-o files. So we do these test cases cross compiling for x86_64-linux. +const linux_x64 = std.zig.CrossTarget{ + .cpu_arch = .x86_64, + .os_tag = .linux, +}; + +const linux_riscv64 = std.zig.CrossTarget{ + .cpu_arch = .riscv64, + .os_tag = .linux, +}; + +const wasi = std.zig.CrossTarget{ + .cpu_arch = .wasm32, + .os_tag = .wasi, +}; + pub fn addCases(ctx: *TestContext) !void { - try @import("compare_output.zig").addCases(ctx); try @import("zir.zig").addCases(ctx); try @import("cbe.zig").addCases(ctx); + { + var case = ctx.exe("hello world with updates", linux_x64); + + case.addError("", &[_][]const u8{":1:1: error: no entry point found"}); + + // Incorrect return type + case.addError( + \\export fn _start() noreturn { + \\} + , &[_][]const u8{":2:1: error: expected noreturn, found void"}); + + // Regular old hello world + case.addCompareOutput( + \\export fn _start() noreturn { + \\ print(); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")), + \\ [arg3] "{rdx}" (14) + \\ : "rcx", "r11", "memory" + \\ ); + \\ return; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "Hello, World!\n", + ); + // Now change the message only + case.addCompareOutput( + \\export fn _start() noreturn { + \\ print(); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")), + \\ [arg3] "{rdx}" (104) + \\ : "rcx", "r11", "memory" + \\ ); + \\ return; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "What is up? This is a longer message that will force the data to be relocated in virtual address space.\n", + ); + // Now we print it twice. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ print(); + \\ print(); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")), + \\ [arg3] "{rdx}" (104) + \\ : "rcx", "r11", "memory" + \\ ); + \\ return; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + \\What is up? This is a longer message that will force the data to be relocated in virtual address space. + \\What is up? This is a longer message that will force the data to be relocated in virtual address space. + \\ + ); + } + + { + var case = ctx.exe("hello world", linux_riscv64); + // Regular old hello world + case.addCompareOutput( + \\export fn _start() noreturn { + \\ print(); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("ecall" + \\ : + \\ : [number] "{a7}" (64), + \\ [arg1] "{a0}" (1), + \\ [arg2] "{a1}" (@ptrToInt("Hello, World!\n")), + \\ [arg3] "{a2}" ("Hello, World!\n".len) + \\ : "rcx", "r11", "memory" + \\ ); + \\ return; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("ecall" + \\ : + \\ : [number] "{a7}" (94), + \\ [arg1] "{a0}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "Hello, World!\n", + ); + } + + { + var case = ctx.exe("adding numbers at comptime", linux_x64); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")), + \\ [arg3] "{rdx}" (10 + 4) + \\ : "rcx", "r11", "memory" + \\ ); + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (@as(usize, 230) + @as(usize, 1)), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "Hello, World!\n", + ); + } + + { + var case = ctx.exe("adding numbers at runtime", linux_x64); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(3, 4); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ if (a + b != 7) unreachable; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + } + + { + var case = ctx.exe("substracting numbers at runtime", linux_x64); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ sub(7, 4); + \\ + \\ exit(); + \\} + \\ + \\fn sub(a: u32, b: u32) void { + \\ if (a - b != 3) unreachable; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + } + + { + var case = ctx.exe("assert function", linux_x64); + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(3, 4); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ assert(a + b == 7); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Tests copying a register. For the `c = a + b`, it has to + // preserve both a and b, because they are both used later. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(3, 4); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ assert(e == 14); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // More stress on the liveness detection. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(3, 4); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ const f = d + e; // 24 + \\ const g = e + f; // 38 + \\ const h = f + g; // 62 + \\ const i = g + h; // 100 + \\ assert(i == 100); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Requires a second move. The register allocator should figure out to re-use rax. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(3, 4); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ const f = d + e; // 24 + \\ const g = e + f; // 38 + \\ const h = f + g; // 62 + \\ const i = g + h; // 100 + \\ const j = i + d; // 110 + \\ assert(j == 110); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Now we test integer return values. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ assert(add(3, 4) == 7); + \\ assert(add(20, 10) == 30); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) u32 { + \\ return a + b; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Local mutable variables. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ assert(add(3, 4) == 7); + \\ assert(add(20, 10) == 30); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) u32 { + \\ var x: u32 = undefined; + \\ x = 0; + \\ x += a; + \\ x += b; + \\ return x; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Optionals + case.addCompareOutput( + \\export fn _start() noreturn { + \\ const a: u32 = 2; + \\ const b: ?u32 = a; + \\ const c = b.?; + \\ if (c != 2) unreachable; + \\ + \\ exit(); + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // While loops + case.addCompareOutput( + \\export fn _start() noreturn { + \\ var i: u32 = 0; + \\ while (i < 4) : (i += 1) print(); + \\ assert(i == 4); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (1), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("hello\n")), + \\ [arg3] "{rdx}" (6) + \\ : "rcx", "r11", "memory" + \\ ); + \\ return; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "hello\nhello\nhello\nhello\n", + ); + + // Labeled blocks (no conditional branch) + case.addCompareOutput( + \\export fn _start() noreturn { + \\ assert(add(3, 4) == 20); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) u32 { + \\ const x: u32 = blk: { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ break :blk e; + \\ }; + \\ const y = x + a; // 17 + \\ const z = y + a; // 20 + \\ return z; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // This catches a possible bug in the logic for re-using dying operands. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ assert(add(3, 4) == 116); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) u32 { + \\ const x: u32 = blk: { + \\ const c = a + b; // 7 + \\ const d = a + c; // 10 + \\ const e = d + b; // 14 + \\ const f = d + e; // 24 + \\ const g = e + f; // 38 + \\ const h = f + g; // 62 + \\ const i = g + h; // 100 + \\ const j = i + d; // 110 + \\ break :blk j; + \\ }; + \\ const y = x + a; // 113 + \\ const z = y + a; // 116 + \\ return z; + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Character literals and multiline strings. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ const ignore = + \\ \\ cool thx + \\ \\ + \\ ; + \\ add('ぁ', '\x03'); + \\ + \\ exit(); + \\} + \\ + \\fn add(a: u32, b: u32) void { + \\ assert(a + b == 12356); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + + // Global const. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ add(aa, bb); + \\ + \\ exit(); + \\} + \\ + \\const aa = 'ぁ'; + \\const bb = '\x03'; + \\ + \\fn add(a: u32, b: u32) void { + \\ assert(a + b == 12356); + \\} + \\ + \\pub fn assert(ok: bool) void { + \\ if (!ok) unreachable; // assertion failure + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (0) + \\ : "rcx", "r11", "memory" + \\ ); + \\ unreachable; + \\} + , + "", + ); + } + + { + var case = ctx.exe("wasm function calls", wasi); + + case.addCompareOutput( + \\export fn _start() u32 { + \\ foo(); + \\ bar(); + \\ return 42; + \\} + \\fn foo() void { + \\ bar(); + \\ bar(); + \\} + \\fn bar() void {} + , + "42\n", + ); + + case.addCompareOutput( + \\export fn _start() i64 { + \\ bar(); + \\ foo(); + \\ foo(); + \\ bar(); + \\ foo(); + \\ bar(); + \\ return 42; + \\} + \\fn foo() void { + \\ bar(); + \\} + \\fn bar() void {} + , + "42\n", + ); + + case.addCompareOutput( + \\export fn _start() f32 { + \\ bar(); + \\ foo(); + \\ return 42.0; + \\} + \\fn foo() void { + \\ bar(); + \\ bar(); + \\ bar(); + \\} + \\fn bar() void {} + , + // This is what you get when you take the bits of the IEE-754 + // representation of 42.0 and reinterpret them as an unsigned + // integer. Guess that's a bug in wasmtime. + "1109917696\n", + ); + } + + ctx.compileError("function redefinition", linux_x64, + \\fn entry() void {} + \\fn entry() void {} + , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); + + ctx.compileError("extern variable has no type", linux_x64, + \\comptime { + \\ _ = foo; + \\} + \\extern var foo; + , &[_][]const u8{":4:1: error: unable to infer variable type"}); } -- 2.54.0 From e0a38f7f3e2b3dc272cd9ab4f826315590664779 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 20 Aug 2020 23:53:34 -0700 Subject: [PATCH 57/66] stage2: make the cache dir if it doesn't already exist --- src-self-hosted/introspect.zig | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src-self-hosted/introspect.zig b/src-self-hosted/introspect.zig index 8e99c93c60d5387289c1b1a97941f1d04e3d81bd..80f10c8656780fe05edd120321e5e7f26d3454de 100644 --- a/src-self-hosted/introspect.zig +++ b/src-self-hosted/introspect.zig @@ -87,6 +87,13 @@ pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 { return fs.getAppDataDir(allocator, appname); } +pub fn openGlobalCacheDir() !fs.Dir { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buf); + const path_name = try resolveGlobalCacheDir(&fba.allocator); + return fs.cwd().makeOpenPath(path_name, .{}); +} + var compiler_id_mutex = std.Mutex{}; var compiler_id: [16]u8 = undefined; var compiler_id_computed = false; @@ -99,11 +106,7 @@ pub fn resolveCompilerId(gpa: *mem.Allocator) ![16]u8 { return compiler_id; compiler_id_computed = true; - const global_cache_dir = try resolveGlobalCacheDir(gpa); - defer gpa.free(global_cache_dir); - - // TODO Introduce openGlobalCacheDir which returns a dir handle rather than a string. - var cache_dir = try fs.cwd().openDir(global_cache_dir, .{}); + var cache_dir = try openGlobalCacheDir(); defer cache_dir.close(); var ch = try CacheHash.init(gpa, cache_dir, "exe"); -- 2.54.0 From 243b5c7a889a3cbc86b5b0720b9ed1cdc6c29835 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 20 Aug 2020 17:25:39 +0200 Subject: [PATCH 58/66] Add macosx end-to-end smoke test This test case will grow as the linker gets more functionality. Signed-off-by: Jakub Konka --- test/stage2/test.zig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 91257526dd2a21235ec803bd37e5bdbf618bf431..11b171318103b1996b265a51175b5f9aa5c4c69d 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -8,6 +8,11 @@ const linux_x64 = std.zig.CrossTarget{ .os_tag = .linux, }; +const macosx_x64 = std.zig.CrossTarget{ + .cpu_arch = .x86_64, + .os_tag = .macosx, +}; + const linux_riscv64 = std.zig.CrossTarget{ .cpu_arch = .riscv64, .os_tag = .linux, @@ -133,6 +138,11 @@ pub fn addCases(ctx: *TestContext) !void { ); } + { + var case = ctx.exe("hello world", macosx_x64); + case.addError("", &[_][]const u8{":1:1: error: no entry point found"}); + } + { var case = ctx.exe("hello world", linux_riscv64); // Regular old hello world -- 2.54.0 From c9218f17197a0d778d9c89787ee0807dc0d00a91 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 13:56:11 +0200 Subject: [PATCH 59/66] Make poly1305 faster --- lib/std/crypto/poly1305.zig | 365 +++++++++++++++++------------------- 1 file changed, 167 insertions(+), 198 deletions(-) diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index 2ed97f4c2e2b96cdb20cdec97e06bdc753290a47..7f2966f991ef10bd6d5c4429a247ad643e53a2c5 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -3,224 +3,193 @@ // This file is part of [zig](https://ziglang.org/), which is MIT licensed. // The MIT license requires this copyright notice to be included in all copies // and substantial portions of the software. -// Translated from monocypher which is licensed under CC-0/BSD-3. -// -// https://monocypher.org/ - -const std = @import("../std.zig"); -const builtin = std.builtin; - -const Endian = builtin.Endian; -const readIntLittle = std.mem.readIntLittle; -const writeIntLittle = std.mem.writeIntLittle; +const std = @import("std"); +const mem = std.mem; pub const Poly1305 = struct { - const Self = @This(); - + pub const block_size: usize = 16; pub const mac_length = 16; pub const minimum_key_length = 32; // constant multiplier (from the secret key) - r: [4]u32, + r: [3]u64, // accumulated hash - h: [5]u32, - // chunk of the message - c: [5]u32, + h: [3]u64 = [_]u64{ 0, 0, 0 }, // random number added at the end (from the secret key) - pad: [4]u32, - // How many bytes are there in the chunk. - c_idx: usize, + pad: [2]u64, + // how many bytes are waiting to be processed in a partial block + leftover: usize = 0, + // partial block buffer + buf: [block_size]u8 align(16) = undefined, - fn secureZero(self: *Self) void { - std.mem.secureZero(u8, @ptrCast([*]u8, self)[0..@sizeOf(Poly1305)]); - } - - pub fn create(out: []u8, msg: []const u8, key: []const u8) void { - std.debug.assert(out.len >= mac_length); + pub fn init(key: []const u8) Poly1305 { std.debug.assert(key.len >= minimum_key_length); - - var ctx = Poly1305.init(key); - ctx.update(msg); - ctx.final(out); - } - - // Initialize the MAC context. - // - key.len is sufficient size. - pub fn init(key: []const u8) Self { - var ctx: Poly1305 = undefined; - - // Initial hash is zero - { - var i: usize = 0; - while (i < 5) : (i += 1) { - ctx.h[i] = 0; - } - } - // add 2^130 to every input block - ctx.c[4] = 1; - polyClearC(&ctx); - - // load r and pad (r has some of its bits cleared) - { - var i: usize = 0; - while (i < 1) : (i += 1) { - ctx.r[0] = readIntLittle(u32, key[0..4]) & 0x0fffffff; - } - } - { - var i: usize = 1; - while (i < 4) : (i += 1) { - ctx.r[i] = readIntLittle(u32, key[i * 4 ..][0..4]) & 0x0ffffffc; - } - } - { - var i: usize = 0; - while (i < 4) : (i += 1) { - ctx.pad[i] = readIntLittle(u32, key[i * 4 + 16 ..][0..4]); - } - } - - return ctx; - } - - // h = (h + c) * r - // preconditions: - // ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff - // ctx->c <= 1_ffffffff_ffffffff_ffffffff_ffffffff - // ctx->r <= 0ffffffc_0ffffffc_0ffffffc_0fffffff - // Postcondition: - // ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff - fn polyBlock(ctx: *Self) void { - // s = h + c, without carry propagation - const s0 = @as(u64, ctx.h[0]) + ctx.c[0]; // s0 <= 1_fffffffe - const s1 = @as(u64, ctx.h[1]) + ctx.c[1]; // s1 <= 1_fffffffe - const s2 = @as(u64, ctx.h[2]) + ctx.c[2]; // s2 <= 1_fffffffe - const s3 = @as(u64, ctx.h[3]) + ctx.c[3]; // s3 <= 1_fffffffe - const s4 = @as(u64, ctx.h[4]) + ctx.c[4]; // s4 <= 5 - - // Local all the things! - const r0 = ctx.r[0]; // r0 <= 0fffffff - const r1 = ctx.r[1]; // r1 <= 0ffffffc - const r2 = ctx.r[2]; // r2 <= 0ffffffc - const r3 = ctx.r[3]; // r3 <= 0ffffffc - const rr0 = (r0 >> 2) * 5; // rr0 <= 13fffffb // lose 2 bits... - const rr1 = (r1 >> 2) + r1; // rr1 <= 13fffffb // rr1 == (r1 >> 2) * 5 - const rr2 = (r2 >> 2) + r2; // rr2 <= 13fffffb // rr1 == (r2 >> 2) * 5 - const rr3 = (r3 >> 2) + r3; // rr3 <= 13fffffb // rr1 == (r3 >> 2) * 5 - - // (h + c) * r, without carry propagation - const x0 = s0 * r0 + s1 * rr3 + s2 * rr2 + s3 * rr1 + s4 * rr0; //<=97ffffe007fffff8 - const x1 = s0 * r1 + s1 * r0 + s2 * rr3 + s3 * rr2 + s4 * rr1; //<=8fffffe20ffffff6 - const x2 = s0 * r2 + s1 * r1 + s2 * r0 + s3 * rr3 + s4 * rr2; //<=87ffffe417fffff4 - const x3 = s0 * r3 + s1 * r2 + s2 * r1 + s3 * r0 + s4 * rr3; //<=7fffffe61ffffff2 - const x4 = s4 * (r0 & 3); // ...recover 2 bits //<= f - - // partial reduction modulo 2^130 - 5 - const _u5 = @truncate(u32, x4 + (x3 >> 32)); // u5 <= 7ffffff5 - const _u0 = (_u5 >> 2) * 5 + (x0 & 0xffffffff); - const _u1 = (_u0 >> 32) + (x1 & 0xffffffff) + (x0 >> 32); - const _u2 = (_u1 >> 32) + (x2 & 0xffffffff) + (x1 >> 32); - const _u3 = (_u2 >> 32) + (x3 & 0xffffffff) + (x2 >> 32); - const _u4 = (_u3 >> 32) + (_u5 & 3); - - // Update the hash - ctx.h[0] = @truncate(u32, _u0); // u0 <= 1_9ffffff0 - ctx.h[1] = @truncate(u32, _u1); // u1 <= 1_97ffffe0 - ctx.h[2] = @truncate(u32, _u2); // u2 <= 1_8fffffe2 - ctx.h[3] = @truncate(u32, _u3); // u3 <= 1_87ffffe4 - ctx.h[4] = @truncate(u32, _u4); // u4 <= 4 - } - - // (re-)initializes the input counter and input buffer - fn polyClearC(ctx: *Self) void { - ctx.c[0] = 0; - ctx.c[1] = 0; - ctx.c[2] = 0; - ctx.c[3] = 0; - ctx.c_idx = 0; + const t0 = mem.readIntLittle(u64, key[0..8]); + const t1 = mem.readIntLittle(u64, key[8..16]); + return Poly1305{ + .r = [_]u64{ + t0 & 0xffc0fffffff, + ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff, + ((t1 >> 24)) & 0x00ffffffc0f, + }, + .pad = [_]u64{ + mem.readIntLittle(u64, key[16..24]), + mem.readIntLittle(u64, key[24..32]), + }, + }; } - fn polyTakeInput(ctx: *Self, input: u8) void { - const word = ctx.c_idx >> 2; - const byte = ctx.c_idx & 3; - ctx.c[word] |= std.math.shl(u32, input, byte * 8); - ctx.c_idx += 1; - } - - fn polyUpdate(ctx: *Self, msg: []const u8) void { - for (msg) |b| { - polyTakeInput(ctx, b); - if (ctx.c_idx == 16) { - polyBlock(ctx); - polyClearC(ctx); - } - } - } - - fn alignTo(x: usize, block_size: usize) usize { - return ((~x) +% 1) & (block_size - 1); - } - - // Feed data into the MAC context. - pub fn update(ctx: *Self, msg: []const u8) void { - // Align ourselves with block boundaries - const alignm = std.math.min(alignTo(ctx.c_idx, 16), msg.len); - polyUpdate(ctx, msg[0..alignm]); - - var nmsg = msg[alignm..]; - - // Process the msg block by block - const nb_blocks = nmsg.len >> 4; + fn blocks(st: *Poly1305, m: []const u8, last: comptime bool) void { + const hibit: u64 = if (last) 0 else 1 << 40; + const r0 = st.r[0]; + const r1 = st.r[1]; + const r2 = st.r[2]; + const s1 = r1 * (5 << 2); + const s2 = r2 * (5 << 2); var i: usize = 0; - while (i < nb_blocks) : (i += 1) { - ctx.c[0] = readIntLittle(u32, nmsg[0..4]); - ctx.c[1] = readIntLittle(u32, nmsg[4..8]); - ctx.c[2] = readIntLittle(u32, nmsg[8..12]); - ctx.c[3] = readIntLittle(u32, nmsg[12..16]); - polyBlock(ctx); - nmsg = nmsg[16..]; + while (i + block_size <= m.len) : (i += block_size) { + // h += m[i] + const t0 = mem.readIntLittle(u64, m[i..][0..8]); + const t1 = mem.readIntLittle(u64, m[i + 8 ..][0..8]); + st.h[0] += t0 & 0xfffffffffff; + st.h[1] += ((t0 >> 44) | (t1 << 20)) & 0xfffffffffff; + st.h[2] += (((t1 >> 24)) & 0x3ffffffffff) | hibit; + + // h *= r + const d0 = @as(u128, st.h[0]) * @as(u128, r0) + @as(u128, st.h[1]) * @as(u128, s2) + @as(u128, st.h[2]) * @as(u128, s1); + var d1 = @as(u128, st.h[0]) * @as(u128, r1) + @as(u128, st.h[1]) * @as(u128, r0) + @as(u128, st.h[2]) * @as(u128, s2); + var d2 = @as(u128, st.h[0]) * @as(u128, r2) + @as(u128, st.h[1]) * @as(u128, r1) + @as(u128, st.h[2]) * @as(u128, r0); + + // partial reduction + var carry = d0 >> 44; + st.h[0] = @truncate(u64, d0) & 0xfffffffffff; + d1 += carry; + carry = @intCast(u64, d1 >> 44); + st.h[1] = @truncate(u64, d1) & 0xfffffffffff; + d2 += carry; + carry = @intCast(u64, d2 >> 42); + st.h[2] = @truncate(u64, d2) & 0x3ffffffffff; + st.h[0] += @truncate(u64, carry) * 5; + carry = st.h[0] >> 44; + st.h[0] &= 0xfffffffffff; + st.h[1] += @truncate(u64, carry); + } + } + + pub fn update(st: *Poly1305, m: []const u8) void { + var mb = m; + + // handle leftover + if (st.leftover > 0) { + const want = std.math.min(block_size - st.leftover, mb.len); + const mc = mb[0..want]; + for (mc) |x, i| { + st.buf[st.leftover + i] = x; + } + mb = mb[want..]; + st.leftover += want; + if (st.leftover > block_size) { + return; + } + st.blocks(&st.buf, false); + st.leftover = 0; } - if (nb_blocks > 0) { - polyClearC(ctx); + + // process full blocks + if (mb.len >= block_size) { + const want = mb.len & ~(block_size - 1); + st.blocks(mb[0..want], false); + mb = mb[want..]; } - // remaining bytes - polyUpdate(ctx, nmsg[0..]); + // store leftover + if (mb.len > 0) { + for (mb) |x, i| { + st.buf[st.leftover + i] = x; + } + st.leftover += mb.len; + } } - // Finalize the MAC and output into buffer provided by caller. - pub fn final(ctx: *Self, out: []u8) void { - // Process the last block (if any) - if (ctx.c_idx != 0) { - // move the final 1 according to remaining input length - // (We may add less than 2^130 to the last input block) - ctx.c[4] = 0; - polyTakeInput(ctx, 1); - // one last hash update - polyBlock(ctx); + pub fn final(st: *Poly1305, out: []u8) void { + std.debug.assert(out.len >= mac_length); + if (st.leftover > 0) { + var i = st.leftover; + st.buf[i] = 1; + i += 1; + while (i < block_size) : (i += 1) { + st.buf[i] = 0; + } + st.blocks(&st.buf, true); } + // fully carry h + var carry = st.h[1] >> 44; + st.h[1] &= 0xfffffffffff; + st.h[2] += carry; + carry = st.h[2] >> 42; + st.h[2] &= 0x3ffffffffff; + st.h[0] += carry * 5; + carry = st.h[0] >> 44; + st.h[0] &= 0xfffffffffff; + st.h[1] += carry; + carry = st.h[1] >> 44; + st.h[1] &= 0xfffffffffff; + st.h[2] += carry; + carry = st.h[2] >> 42; + st.h[2] &= 0x3ffffffffff; + st.h[0] += carry * 5; + carry = st.h[0] >> 44; + st.h[0] &= 0xfffffffffff; + st.h[1] += carry; + + // compute h + -p + var g0 = st.h[0] + 5; + carry = g0 >> 44; + g0 &= 0xfffffffffff; + var g1 = st.h[1] + carry; + carry = g1 >> 44; + g1 &= 0xfffffffffff; + var g2 = st.h[2] + carry -% (1 << 42); + + // (hopefully) constant-time select h if h < p, or h + -p if h >= p + const mask = (g2 >> 63) -% 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + const nmask = ~mask; + st.h[0] = (st.h[0] & nmask) | g0; + st.h[1] = (st.h[1] & nmask) | g1; + st.h[2] = (st.h[2] & nmask) | g2; + + // h = (h + pad) + const t0 = st.pad[0]; + const t1 = st.pad[1]; + st.h[0] += (t0 & 0xfffffffffff); + carry = (st.h[0] >> 44); + st.h[0] &= 0xfffffffffff; + st.h[1] += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + carry; + carry = (st.h[1] >> 44); + st.h[1] &= 0xfffffffffff; + st.h[2] += (((t1 >> 24)) & 0x3ffffffffff) + carry; + st.h[2] &= 0x3ffffffffff; + + // mac = h % (2^128) + st.h[0] |= st.h[1] << 44; + st.h[1] = (st.h[1] >> 20) | (st.h[2] << 24); + + mem.writeIntLittle(u64, out[0..8], st.h[0]); + mem.writeIntLittle(u64, out[8..16], st.h[1]); + + mem.secureZero(u64, &st.r); + } + + pub fn create(out: []u8, msg: []const u8, key: []const u8) void { + std.debug.assert(out.len >= mac_length); + std.debug.assert(key.len >= minimum_key_length); - // check if we should subtract 2^130-5 by performing the - // corresponding carry propagation. - const _u0 = @as(u64, 5) + ctx.h[0]; // <= 1_00000004 - const _u1 = (_u0 >> 32) + ctx.h[1]; // <= 1_00000000 - const _u2 = (_u1 >> 32) + ctx.h[2]; // <= 1_00000000 - const _u3 = (_u2 >> 32) + ctx.h[3]; // <= 1_00000000 - const _u4 = (_u3 >> 32) + ctx.h[4]; // <= 5 - // u4 indicates how many times we should subtract 2^130-5 (0 or 1) - - // h + pad, minus 2^130-5 if u4 exceeds 3 - const uu0 = (_u4 >> 2) * 5 + ctx.h[0] + ctx.pad[0]; // <= 2_00000003 - const uu1 = (uu0 >> 32) + ctx.h[1] + ctx.pad[1]; // <= 2_00000000 - const uu2 = (uu1 >> 32) + ctx.h[2] + ctx.pad[2]; // <= 2_00000000 - const uu3 = (uu2 >> 32) + ctx.h[3] + ctx.pad[3]; // <= 2_00000000 - - writeIntLittle(u32, out[0..4], @truncate(u32, uu0)); - writeIntLittle(u32, out[4..8], @truncate(u32, uu1)); - writeIntLittle(u32, out[8..12], @truncate(u32, uu2)); - writeIntLittle(u32, out[12..16], @truncate(u32, uu3)); - - ctx.secureZero(); + var st = Poly1305.init(key); + st.update(msg); + st.final(out); } }; -- 2.54.0 From 2fc2ebd920a83e737ebb5f8b3499fd0e48d94043 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 19:43:06 +0200 Subject: [PATCH 60/66] Force myself to use unusual integer sizes a little bit more :) --- lib/std/crypto/poly1305.zig | 64 ++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index 7f2966f991ef10bd6d5c4429a247ad643e53a2c5..b401939c5cda55f0ac364747ba7615006f71d6d3 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -44,6 +44,9 @@ pub const Poly1305 = struct { const r0 = st.r[0]; const r1 = st.r[1]; const r2 = st.r[2]; + var h0 = st.h[0]; + var h1 = st.h[1]; + var h2 = st.h[2]; const s1 = r1 * (5 << 2); const s2 = r2 * (5 << 2); var i: usize = 0; @@ -51,29 +54,30 @@ pub const Poly1305 = struct { // h += m[i] const t0 = mem.readIntLittle(u64, m[i..][0..8]); const t1 = mem.readIntLittle(u64, m[i + 8 ..][0..8]); - st.h[0] += t0 & 0xfffffffffff; - st.h[1] += ((t0 >> 44) | (t1 << 20)) & 0xfffffffffff; - st.h[2] += (((t1 >> 24)) & 0x3ffffffffff) | hibit; + h0 += @truncate(u44, t0); + h1 += @truncate(u44, (t0 >> 44) | (t1 << 20)); + h2 += @truncate(u42, t1 >> 24) | hibit; // h *= r - const d0 = @as(u128, st.h[0]) * @as(u128, r0) + @as(u128, st.h[1]) * @as(u128, s2) + @as(u128, st.h[2]) * @as(u128, s1); - var d1 = @as(u128, st.h[0]) * @as(u128, r1) + @as(u128, st.h[1]) * @as(u128, r0) + @as(u128, st.h[2]) * @as(u128, s2); - var d2 = @as(u128, st.h[0]) * @as(u128, r2) + @as(u128, st.h[1]) * @as(u128, r1) + @as(u128, st.h[2]) * @as(u128, r0); + const d0 = @as(u128, h0) * r0 + @as(u128, h1) * s2 + @as(u128, h2) * s1; + var d1 = @as(u128, h0) * r1 + @as(u128, h1) * r0 + @as(u128, h2) * s2; + var d2 = @as(u128, h0) * r2 + @as(u128, h1) * r1 + @as(u128, h2) * r0; // partial reduction var carry = d0 >> 44; - st.h[0] = @truncate(u64, d0) & 0xfffffffffff; + h0 = @truncate(u44, d0); d1 += carry; carry = @intCast(u64, d1 >> 44); - st.h[1] = @truncate(u64, d1) & 0xfffffffffff; + h1 = @truncate(u44, d1); d2 += carry; carry = @intCast(u64, d2 >> 42); - st.h[2] = @truncate(u64, d2) & 0x3ffffffffff; - st.h[0] += @truncate(u64, carry) * 5; - carry = st.h[0] >> 44; - st.h[0] &= 0xfffffffffff; - st.h[1] += @truncate(u64, carry); + h2 = @truncate(u42, d2); + h0 += @truncate(u64, carry) * 5; + carry = h0 >> 44; + h0 = @truncate(u44, h0); + h1 += @truncate(u64, carry); } + st.h = [_]u64{ h0, h1, h2 }; } pub fn update(st: *Poly1305, m: []const u8) void { @@ -124,31 +128,31 @@ pub const Poly1305 = struct { } // fully carry h var carry = st.h[1] >> 44; - st.h[1] &= 0xfffffffffff; + st.h[1] = @truncate(u44, st.h[1]); st.h[2] += carry; carry = st.h[2] >> 42; - st.h[2] &= 0x3ffffffffff; + st.h[2] = @truncate(u42, st.h[2]); st.h[0] += carry * 5; carry = st.h[0] >> 44; - st.h[0] &= 0xfffffffffff; + st.h[0] = @truncate(u44, st.h[0]); st.h[1] += carry; carry = st.h[1] >> 44; - st.h[1] &= 0xfffffffffff; + st.h[1] = @truncate(u44, st.h[1]); st.h[2] += carry; carry = st.h[2] >> 42; - st.h[2] &= 0x3ffffffffff; + st.h[2] = @truncate(u42, st.h[2]); st.h[0] += carry * 5; carry = st.h[0] >> 44; - st.h[0] &= 0xfffffffffff; + st.h[0] = @truncate(u44, st.h[0]); st.h[1] += carry; // compute h + -p var g0 = st.h[0] + 5; carry = g0 >> 44; - g0 &= 0xfffffffffff; + g0 = @truncate(u44, g0); var g1 = st.h[1] + carry; carry = g1 >> 44; - g1 &= 0xfffffffffff; + g1 = @truncate(u44, g1); var g2 = st.h[2] + carry -% (1 << 42); // (hopefully) constant-time select h if h < p, or h + -p if h >= p @@ -164,14 +168,14 @@ pub const Poly1305 = struct { // h = (h + pad) const t0 = st.pad[0]; const t1 = st.pad[1]; - st.h[0] += (t0 & 0xfffffffffff); - carry = (st.h[0] >> 44); - st.h[0] &= 0xfffffffffff; - st.h[1] += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + carry; - carry = (st.h[1] >> 44); - st.h[1] &= 0xfffffffffff; - st.h[2] += (((t1 >> 24)) & 0x3ffffffffff) + carry; - st.h[2] &= 0x3ffffffffff; + st.h[0] += @truncate(u44, t0); + carry = st.h[0] >> 44; + st.h[0] = @truncate(u44, st.h[0]); + st.h[1] += @truncate(u44, (t0 >> 44) | (t1 << 20)) + carry; + carry = st.h[1] >> 44; + st.h[1] = @truncate(u44, st.h[1]); + st.h[2] += @truncate(u42, t1 >> 24) + carry; + st.h[2] = @truncate(u42, st.h[2]); // mac = h % (2^128) st.h[0] |= st.h[1] << 44; @@ -180,7 +184,7 @@ pub const Poly1305 = struct { mem.writeIntLittle(u64, out[0..8], st.h[0]); mem.writeIntLittle(u64, out[8..16], st.h[1]); - mem.secureZero(u64, &st.r); + std.mem.secureZero(u8, @ptrCast([*]u8, st)[0..@sizeOf(Poly1305)]); } pub fn create(out: []u8, msg: []const u8, key: []const u8) void { -- 2.54.0 From 0fe6677736fae205543c6f1c57ea864049bade73 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 21 Aug 2020 20:33:16 +0200 Subject: [PATCH 61/66] No need to keep a 128-bit carry around --- lib/std/crypto/poly1305.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index b401939c5cda55f0ac364747ba7615006f71d6d3..c0b462c60e59fa1cc672e8545231d7e1ec2a24c1 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -64,7 +64,7 @@ pub const Poly1305 = struct { var d2 = @as(u128, h0) * r2 + @as(u128, h1) * r1 + @as(u128, h2) * r0; // partial reduction - var carry = d0 >> 44; + var carry = @intCast(u64, d0 >> 44); h0 = @truncate(u44, d0); d1 += carry; carry = @intCast(u64, d1 >> 44); @@ -75,7 +75,7 @@ pub const Poly1305 = struct { h0 += @truncate(u64, carry) * 5; carry = h0 >> 44; h0 = @truncate(u44, h0); - h1 += @truncate(u64, carry); + h1 += carry; } st.h = [_]u64{ h0, h1, h2 }; } -- 2.54.0 From 7f1378909b54dec1636920389e60d8dfacb4e614 Mon Sep 17 00:00:00 2001 From: Matt Knight Date: Tue, 18 Aug 2020 22:03:51 -0700 Subject: [PATCH 62/66] moved bpf syscall, added some bpf instructions and tests --- lib/std/os/bits/linux/bpf.zig | 396 ++++++++++++++++++++++++++++++++-- lib/std/os/linux.zig | 4 + 2 files changed, 382 insertions(+), 18 deletions(-) diff --git a/lib/std/os/bits/linux/bpf.zig b/lib/std/os/bits/linux/bpf.zig index e86e082ff73045288c37f50b2cfc4d69e4fcb313..6baccd43626738e5f4fd4cebb180d006528c15f6 100644 --- a/lib/std/os/bits/linux/bpf.zig +++ b/lib/std/os/bits/linux/bpf.zig @@ -5,6 +5,61 @@ // and substantial portions of the software. usingnamespace std.os; const std = @import("../../../std.zig"); +const expectEqual = std.testing.expectEqual; +const fd_t = std.os.fd_t; +const pid_t = std.os.pid_t; + +// instruction classes +pub const LD = 0x00; +pub const LDX = 0x01; +pub const ST = 0x02; +pub const STX = 0x03; +pub const ALU = 0x04; +pub const JMP = 0x05; +pub const RET = 0x06; +pub const MISC = 0x07; + +/// 32-bit +pub const W = 0x00; +/// 16-bit +pub const H = 0x08; +/// 8-bit +pub const B = 0x10; +/// 64-bit +pub const DW = 0x18; + +pub const IMM = 0x00; +pub const ABS = 0x20; +pub const IND = 0x40; +pub const MEM = 0x60; +pub const LEN = 0x80; +pub const MSH = 0xa0; + +// alu fields +pub const ADD = 0x00; +pub const SUB = 0x10; +pub const MUL = 0x20; +pub const DIV = 0x30; +pub const OR = 0x40; +pub const AND = 0x50; +pub const LSH = 0x60; +pub const RSH = 0x70; +pub const NEG = 0x80; +pub const MOD = 0x90; +pub const XOR = 0xa0; + +// jmp fields +pub const JA = 0x00; +pub const JEQ = 0x10; +pub const JGT = 0x20; +pub const JGE = 0x30; +pub const JSET = 0x40; + +//#define BPF_SRC(code) ((code) & 0x08) +pub const K = 0x00; +pub const X = 0x08; + +pub const MAXINSNS = 4096; // instruction classes /// jmp mode in word width @@ -13,8 +68,6 @@ pub const JMP32 = 0x06; pub const ALU64 = 0x07; // ld/ldx fields -/// double word (64-bit) -pub const DW = 0x18; /// exclusive add pub const XADD = 0xc0; @@ -153,6 +206,130 @@ pub const BPF_F_CLONE = 0x200; /// flag for BPF_MAP_CREATE command. Enable memory-mapping BPF map pub const BPF_F_MMAPABLE = 0x400; +/// These values correspond to "syscalls" within the BPF program's environment +pub const Helper = enum(i32) { + unspec, + map_lookup_elem, + map_update_elem, + map_delete_elem, + probe_read, + ktime_get_ns, + trace_printk, + get_prandom_u32, + get_smp_processor_id, + skb_store_bytes, + l3_csum_replace, + l4_csum_replace, + tail_call, + clone_redirect, + get_current_pid_tgid, + get_current_uid_gid, + get_current_comm, + get_cgroup_classid, + skb_vlan_push, + skb_vlan_pop, + skb_get_tunnel_key, + skb_set_tunnel_key, + perf_event_read, + redirect, + get_route_realm, + perf_event_output, + skb_load_bytes, + get_stackid, + csum_diff, + skb_get_tunnel_opt, + skb_set_tunnel_opt, + skb_change_proto, + skb_change_type, + skb_under_cgroup, + get_hash_recalc, + get_current_task, + probe_write_user, + current_task_under_cgroup, + skb_change_tail, + skb_pull_data, + csum_update, + set_hash_invalid, + get_numa_node_id, + skb_change_head, + xdp_adjust_head, + probe_read_str, + get_socket_cookie, + get_socket_uid, + set_hash, + setsockopt, + skb_adjust_room, + redirect_map, + sk_redirect_map, + sock_map_update, + xdp_adjust_meta, + perf_event_read_value, + perf_prog_read_value, + getsockopt, + override_return, + sock_ops_cb_flags_set, + msg_redirect_map, + msg_apply_bytes, + msg_cork_bytes, + msg_pull_data, + bind, + xdp_adjust_tail, + skb_get_xfrm_state, + get_stack, + skb_load_bytes_relative, + fib_lookup, + sock_hash_update, + msg_redirect_hash, + sk_redirect_hash, + lwt_push_encap, + lwt_seg6_store_bytes, + lwt_seg6_adjust_srh, + lwt_seg6_action, + rc_repeat, + rc_keydown, + skb_cgroup_id, + get_current_cgroup_id, + get_local_storage, + sk_select_reuseport, + skb_ancestor_cgroup_id, + sk_lookup_tcp, + sk_lookup_udp, + sk_release, + map_push_elem, + map_pop_elem, + map_peek_elem, + msg_push_data, + msg_pop_data, + rc_pointer_rel, + spin_lock, + spin_unlock, + sk_fullsock, + tcp_sock, + skb_ecn_set_ce, + get_listener_sock, + skc_lookup_tcp, + tcp_check_syncookie, + sysctl_get_name, + sysctl_get_current_value, + sysctl_get_new_value, + sysctl_set_new_value, + strtol, + strtoul, + sk_storage_get, + sk_storage_delete, + send_signal, + tcp_gen_syncookie, + skb_output, + probe_read_user, + probe_read_kernel, + probe_read_user_str, + probe_read_kernel_str, + tcp_send_ack, + send_signal_thread, + jiffies64, + _, +}; + /// a single BPF instruction pub const Insn = packed struct { code: u8, @@ -163,32 +340,163 @@ pub const Insn = packed struct { /// r0 - r9 are general purpose 64-bit registers, r10 points to the stack /// frame - pub const Reg = enum(u4) { - r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 + pub const Reg = packed enum(u4) { r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 }; + const Source = packed enum(u1) { reg, imm }; + const AluOp = packed enum(u8) { + add = ADD, + sub = SUB, + mul = MUL, + div = DIV, + op_or = OR, + op_and = AND, + lsh = LSH, + rsh = RSH, + neg = NEG, + mod = MOD, + xor = XOR, + mov = MOV, }; - const alu = 0x04; - const jmp = 0x05; - const mov = 0xb0; - const k = 0; - const exit_code = 0x90; + pub const Size = packed enum(u8) { + byte = B, + half_word = H, + word = W, + double_word = DW, + }; + + const JmpOp = packed enum(u8) { + ja = JA, + jeq = JEQ, + jgt = JGT, + jge = JGE, + jset = JSET, + }; + + const ImmOrReg = union(Source) { + imm: i32, + reg: Reg, + }; + + fn imm_reg(code: u8, dst: Reg, src: anytype, off: i16) Insn { + const imm_or_reg = if (@typeInfo(@TypeOf(src)) == .EnumLiteral) + ImmOrReg{ .reg = @as(Reg, src) } + else + ImmOrReg{ .imm = src }; + + const src_type = switch (imm_or_reg) { + .imm => K, + .reg => X, + }; - // TODO: implement more factory functions for the other instructions - /// load immediate value into a register - pub fn load_imm(dst: Reg, imm: i32) Insn { return Insn{ - .code = alu | mov | k, + .code = code | src_type, .dst = @enumToInt(dst), + .src = switch (imm_or_reg) { + .imm => 0, + .reg => |r| @enumToInt(r), + }, + .off = off, + .imm = switch (imm_or_reg) { + .imm => |i| i, + .reg => 0, + }, + }; + } + + fn alu(comptime width: comptime_int, op: AluOp, dst: Reg, src: anytype) Insn { + const width_bitfield = switch (width) { + 32 => ALU, + 64 => ALU64, + else => @compileError("width must be 32 or 64"), + }; + + return imm_reg(width_bitfield | @enumToInt(op), dst, src, 0); + } + + pub fn mov(dst: Reg, src: anytype) Insn { + return alu(64, .mov, dst, src); + } + + pub fn add(dst: Reg, src: anytype) Insn { + return alu(64, .add, dst, src); + } + + fn jmp(op: JmpOp, dst: Reg, src: anytype, off: i16) Insn { + return imm_reg(JMP | @enumToInt(op), dst, src, off); + } + + pub fn jeq(dst: Reg, src: anytype, off: i16) Insn { + return jmp(.jeq, dst, src, off); + } + + pub fn stx_mem(size: Size, dst: Reg, src: Reg, off: i16) Insn { + return Insn{ + .code = STX | @enumToInt(size) | MEM, + .dst = @enumToInt(dst), + .src = @enumToInt(src), + .off = off, + .imm = 0, + }; + } + + pub fn xadd(dst: Reg, src: Reg) Insn { + return Insn{ + .code = STX | XADD | DW, + .dst = @enumToInt(dst), + .src = @enumToInt(src), + .off = 0, + .imm = 0, + }; + } + + /// direct packet access, R0 = *(uint *)(skb->data + imm32) + pub fn ld_abs(size: Size, imm: i32) Insn { + return Insn{ + .code = LD | @enumToInt(size) | ABS, + .dst = 0, .src = 0, .off = 0, .imm = imm, }; } + fn ld_imm_impl(dst: Reg, src: Reg, imm: u64) [2]Insn { + return [2]Insn{ + Insn{ + .code = LD | DW | IMM, + .dst = @enumToInt(dst), + .src = @enumToInt(src), + .off = 0, + .imm = @intCast(i32, @truncate(u32, imm)), + }, + Insn{ + .code = 0, + .dst = 0, + .src = 0, + .off = 0, + .imm = @intCast(i32, @truncate(u32, imm >> 32)), + }, + }; + } + + pub fn ld_map_fd(dst: Reg, map_fd: fd_t) [2]Insn { + return ld_imm_impl(dst, @intToEnum(Reg, PSEUDO_MAP_FD), @intCast(u64, map_fd)); + } + + pub fn call(helper: Helper) Insn { + return Insn{ + .code = JMP | CALL, + .dst = 0, + .src = 0, + .off = 0, + .imm = @enumToInt(helper), + }; + } + /// exit BPF program pub fn exit() Insn { return Insn{ - .code = jmp | exit_code, + .code = JMP | EXIT, .dst = 0, .src = 0, .off = 0, @@ -197,6 +505,62 @@ pub const Insn = packed struct { } }; +fn expect_insn(insn: Insn, val: u64) void { + expectEqual(@bitCast(u64, insn), val); +} + +test "insn bitsize" { + expectEqual(@bitSizeOf(Insn), 64); +} + +// mov instructions +test "mov imm" { + expect_insn(Insn.mov(.r1, 1), 0x00000001000001b7); +} + +test "mov reg" { + expect_insn(Insn.mov(.r6, .r1), 0x00000000000016bf); +} + +// alu instructions +test "add imm" { + expect_insn(Insn.add(.r2, -4), 0xfffffffc00000207); +} + +// ld instructions +test "ld_abs" { + expect_insn(Insn.ld_abs(.byte, 42), 0x0000002a00000030); +} + +test "ld_map_fd" { + const insns = Insn.ld_map_fd(.r1, 42); + expect_insn(insns[0], 0x0000002a00001118); + expect_insn(insns[1], 0x0000000000000000); +} + +// st instructions +test "stx_mem" { + expect_insn(Insn.stx_mem(.word, .r10, .r0, -4), 0x00000000fffc0a63); +} + +test "xadd" { + expect_insn(Insn.xadd(.r0, .r1), 0x00000000000010db); +} + +// jmp instructions +test "jeq imm" { + expect_insn(Insn.jeq(.r0, 0, 2), 0x0000000000020015); +} + +// other instructions +test "call" { + expect_insn(Insn.call(.map_lookup_elem), 0x0000000100000085); +} + +test "exit" { + expect_insn(Insn.exit(), 0x0000000000000095); +} + pub const Cmd = extern enum(usize) { map_create, map_lookup_elem, @@ -605,7 +969,3 @@ pub const Attr = extern union { enable_stats: EnableStatsAttr, iter_create: IterCreateAttr, }; - -pub fn bpf(cmd: Cmd, attr: *Attr, size: u32) usize { - return syscall3(.bpf, @enumToInt(cmd), @ptrToInt(attr), size); -} diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index ae66e619c363522a4b2992d6a2f1ed4d97cc01fc..f64e7d2addd89625c0266c0b7d7e0c53f5c07f59 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1221,6 +1221,10 @@ pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, ); } +pub fn bpf_syscall(cmd: bpf.Cmd, attr: *bpf.Attr, size: u32) usize { + return syscall3(.bpf, @enumToInt(cmd), @ptrToInt(attr), size); +} + test "" { if (builtin.os.tag == .linux) { _ = @import("linux/test.zig"); -- 2.54.0 From bc1536f4bf01e45af80a930b31b9271551de1dc0 Mon Sep 17 00:00:00 2001 From: Matt Knight Date: Tue, 18 Aug 2020 22:18:36 -0700 Subject: [PATCH 63/66] decided to split up loading of 64-bit immediates --- lib/std/os/bits/linux/bpf.zig | 46 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/std/os/bits/linux/bpf.zig b/lib/std/os/bits/linux/bpf.zig index 6baccd43626738e5f4fd4cebb180d006528c15f6..5517e2ae80c648fcb580cf7dfb9f6de25dfcb1a1 100644 --- a/lib/std/os/bits/linux/bpf.zig +++ b/lib/std/os/bits/linux/bpf.zig @@ -460,27 +460,32 @@ pub const Insn = packed struct { }; } - fn ld_imm_impl(dst: Reg, src: Reg, imm: u64) [2]Insn { - return [2]Insn{ - Insn{ - .code = LD | DW | IMM, - .dst = @enumToInt(dst), - .src = @enumToInt(src), - .off = 0, - .imm = @intCast(i32, @truncate(u32, imm)), - }, - Insn{ - .code = 0, - .dst = 0, - .src = 0, - .off = 0, - .imm = @intCast(i32, @truncate(u32, imm >> 32)), - }, + fn ld_imm_impl1(dst: Reg, src: Reg, imm: u64) Insn { + return Insn{ + .code = LD | DW | IMM, + .dst = @enumToInt(dst), + .src = @enumToInt(src), + .off = 0, + .imm = @intCast(i32, @truncate(u32, imm)), }; } - pub fn ld_map_fd(dst: Reg, map_fd: fd_t) [2]Insn { - return ld_imm_impl(dst, @intToEnum(Reg, PSEUDO_MAP_FD), @intCast(u64, map_fd)); + fn ld_imm_impl2(imm: u64) Insn { + return Insn{ + .code = 0, + .dst = 0, + .src = 0, + .off = 0, + .imm = @intCast(i32, @truncate(u32, imm >> 32)), + }; + } + + pub fn ld_map_fd1(dst: Reg, map_fd: fd_t) Insn { + return ld_imm_impl1(dst, @intToEnum(Reg, PSEUDO_MAP_FD), @intCast(u64, map_fd)); + } + + pub fn ld_map_fd2(map_fd: fd_t) Insn { + return ld_imm_impl2(@intCast(u64, map_fd)); } pub fn call(helper: Helper) Insn { @@ -533,9 +538,8 @@ test "ld_abs" { } test "ld_map_fd" { - const insns = Insn.ld_map_fd(.r1, 42); - expect_insn(insns[0], 0x0000002a00001118); - expect_insn(insns[1], 0x0000000000000000); + expect_insn(Insn.ld_map_fd1(.r1, 42), 0x0000002a00001118); + expect_insn(Insn.ld_map_fd2(42), 0x0000000000000000); } // st instructions -- 2.54.0 From 80fabe18506193978ed60dcd45790ef9486c4eb3 Mon Sep 17 00:00:00 2001 From: Matt Knight Date: Thu, 20 Aug 2020 18:54:41 -0700 Subject: [PATCH 64/66] fixed bpf namespace --- lib/std/os/bits/linux.zig | 2 +- lib/std/os/linux.zig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 5c81ee8c062330c08ca9328616bb12c4cdd97144..133b90311066b5fd5ed50dcc872369aab23824f1 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -24,7 +24,7 @@ pub usingnamespace switch (builtin.arch) { }; pub usingnamespace @import("linux/netlink.zig"); -pub const bpf = @import("linux/bpf.zig"); +pub const BPF = @import("linux/bpf.zig"); const is_mips = builtin.arch.isMIPS(); diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index f64e7d2addd89625c0266c0b7d7e0c53f5c07f59..c5edacfab1d3824c301fc01dcfb8c8ca1f11a68b 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1221,7 +1221,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, ); } -pub fn bpf_syscall(cmd: bpf.Cmd, attr: *bpf.Attr, size: u32) usize { +pub fn bpf(cmd: BPF.Cmd, attr: *BPF.Attr, size: u32) usize { return syscall3(.bpf, @enumToInt(cmd), @ptrToInt(attr), size); } -- 2.54.0 From 37ad9f38dc89b568abddb56a044bdfb36eca7d49 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Fri, 21 Aug 2020 17:54:01 +0200 Subject: [PATCH 65/66] std: sync TailQueue with new SinglyLinkedList API The API of SinglyLinkedList was changed in 93384f7, removing the init function as well as the redundant allocation helper functions. This commit makes parallel changes to the API of TailQueue in order to keep the standard library consistent. --- lib/std/linked_list.zig | 118 ++++++++++------------------------------ 1 file changed, 30 insertions(+), 88 deletions(-) diff --git a/lib/std/linked_list.zig b/lib/std/linked_list.zig index e99f3d8725b6fdcdd1a70761705b9ddb804ec746..00e678e0ac1a9eb9325682082dd771e9d9dab591 100644 --- a/lib/std/linked_list.zig +++ b/lib/std/linked_list.zig @@ -183,21 +183,9 @@ pub fn TailQueue(comptime T: type) type { } }; - first: ?*Node, - last: ?*Node, - len: usize, - - /// Initialize a linked list. - /// - /// Returns: - /// An empty linked list. - pub fn init() Self { - return Self{ - .first = null, - .last = null, - .len = 0, - }; - } + first: ?*Node = null, + last: ?*Node = null, + len: usize = 0, /// Insert a new node after an existing one. /// @@ -340,65 +328,24 @@ pub fn TailQueue(comptime T: type) type { list.remove(first); return first; } - - /// Allocate a new node. - /// - /// Arguments: - /// allocator: Dynamic memory allocator. - /// - /// Returns: - /// A pointer to the new node. - pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node { - return allocator.create(Node); - } - - /// Deallocate a node. - /// - /// Arguments: - /// node: Pointer to the node to deallocate. - /// allocator: Dynamic memory allocator. - pub fn destroyNode(list: *Self, node: *Node, allocator: *Allocator) void { - allocator.destroy(node); - } - - /// Allocate and initialize a node and its data. - /// - /// Arguments: - /// data: The data to put inside the node. - /// allocator: Dynamic memory allocator. - /// - /// Returns: - /// A pointer to the new node. - pub fn createNode(list: *Self, data: T, allocator: *Allocator) !*Node { - var node = try list.allocateNode(allocator); - node.* = Node.init(data); - return node; - } }; } test "basic TailQueue test" { - const allocator = testing.allocator; - var list = TailQueue(u32).init(); + const L = TailQueue(u32); + var list = L{}; - var one = try list.createNode(1, allocator); - var two = try list.createNode(2, allocator); - var three = try list.createNode(3, allocator); - var four = try list.createNode(4, allocator); - var five = try list.createNode(5, allocator); - defer { - list.destroyNode(one, allocator); - list.destroyNode(two, allocator); - list.destroyNode(three, allocator); - list.destroyNode(four, allocator); - list.destroyNode(five, allocator); - } + var one = L.Node{ .data = 1 }; + var two = L.Node{ .data = 2 }; + var three = L.Node{ .data = 3 }; + var four = L.Node{ .data = 4 }; + var five = L.Node{ .data = 5 }; - list.append(two); // {2} - list.append(five); // {2, 5} - list.prepend(one); // {1, 2, 5} - list.insertBefore(five, four); // {1, 2, 4, 5} - list.insertAfter(two, three); // {1, 2, 3, 4, 5} + list.append(&two); // {2} + list.append(&five); // {2, 5} + list.prepend(&one); // {1, 2, 5} + list.insertBefore(&five, &four); // {1, 2, 4, 5} + list.insertAfter(&two, &three); // {1, 2, 3, 4, 5} // Traverse forwards. { @@ -422,7 +369,7 @@ test "basic TailQueue test" { var first = list.popFirst(); // {2, 3, 4, 5} var last = list.pop(); // {2, 3, 4} - list.remove(three); // {2, 4} + list.remove(&three); // {2, 4} testing.expect(list.first.?.data == 2); testing.expect(list.last.?.data == 4); @@ -430,30 +377,25 @@ test "basic TailQueue test" { } test "TailQueue concatenation" { - const allocator = testing.allocator; - var list1 = TailQueue(u32).init(); - var list2 = TailQueue(u32).init(); + const L = TailQueue(u32); + var list1 = L{}; + var list2 = L{}; - var one = try list1.createNode(1, allocator); - defer list1.destroyNode(one, allocator); - var two = try list1.createNode(2, allocator); - defer list1.destroyNode(two, allocator); - var three = try list1.createNode(3, allocator); - defer list1.destroyNode(three, allocator); - var four = try list1.createNode(4, allocator); - defer list1.destroyNode(four, allocator); - var five = try list1.createNode(5, allocator); - defer list1.destroyNode(five, allocator); + var one = L.Node{ .data = 1 }; + var two = L.Node{ .data = 2 }; + var three = L.Node{ .data = 3 }; + var four = L.Node{ .data = 4 }; + var five = L.Node{ .data = 5 }; - list1.append(one); - list1.append(two); - list2.append(three); - list2.append(four); - list2.append(five); + list1.append(&one); + list1.append(&two); + list2.append(&three); + list2.append(&four); + list2.append(&five); list1.concatByMoving(&list2); - testing.expect(list1.last == five); + testing.expect(list1.last == &five); testing.expect(list1.len == 5); testing.expect(list2.first == null); testing.expect(list2.last == null); -- 2.54.0 From 89b6c47e042b343fba754ed8f39efa1b385093bb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 21 Aug 2020 13:24:13 -0700 Subject: [PATCH 66/66] stage2: decouple codegen.zig from ELF See #6113 for an alternate way of doing this that we didn't end up following. Closes #6079. I also took the opportunity here to extract C.zig and Elf.zig from link.zig. --- src-self-hosted/codegen.zig | 197 ++- src-self-hosted/link.zig | 2714 +----------------------------- src-self-hosted/link/C.zig | 101 ++ src-self-hosted/link/Elf.zig | 2583 ++++++++++++++++++++++++++++ src-self-hosted/link/MachO.zig | 6 +- src-self-hosted/{ => link}/cbe.h | 0 src-self-hosted/test.zig | 2 +- 7 files changed, 2824 insertions(+), 2779 deletions(-) create mode 100644 src-self-hosted/link/C.zig create mode 100644 src-self-hosted/link/Elf.zig rename src-self-hosted/{ => link}/cbe.h (100%) diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index cc5c51159cea6b79ef0af51c5d0e7e88fd0f076d..36bebe1ca5dce5e545fd6d82a84d28942baaec59 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -59,20 +59,20 @@ pub const GenerateSymbolError = error{ }; pub fn generateSymbol( - bin_file: *link.File.Elf, + bin_file: *link.File, src: usize, typed_value: TypedValue, code: *std.ArrayList(u8), dbg_line: *std.ArrayList(u8), dbg_info: *std.ArrayList(u8), - dbg_info_type_relocs: *link.File.Elf.DbgInfoTypeRelocsTable, + dbg_info_type_relocs: *link.File.DbgInfoTypeRelocsTable, ) GenerateSymbolError!Result { const tracy = trace(@src()); defer tracy.end(); switch (typed_value.ty.zigTypeTag()) { .Fn => { - switch (bin_file.base.options.target.cpu.arch) { + switch (bin_file.options.target.cpu.arch) { .wasm32 => unreachable, // has its own code path .wasm64 => unreachable, // has its own code path //.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), @@ -151,7 +151,7 @@ pub fn generateSymbol( } return Result{ .fail = try ErrorMsg.create( - bin_file.base.allocator, + bin_file.allocator, src, "TODO implement generateSymbol for more kinds of arrays", .{}, @@ -164,12 +164,11 @@ pub fn generateSymbol( if (typed_value.val.cast(Value.Payload.DeclRef)) |payload| { const decl = payload.decl; if (decl.analysis != .complete) return error.AnalysisFail; - assert(decl.link.elf.local_sym_index != 0); // TODO handle the dependency of this symbol on the decl's vaddr. // If the decl changes vaddr, then this symbol needs to get regenerated. - const vaddr = bin_file.local_symbols.items[decl.link.elf.local_sym_index].st_value; - const endian = bin_file.base.options.target.cpu.arch.endian(); - switch (bin_file.base.options.target.cpu.arch.ptrBitWidth()) { + const vaddr = bin_file.getDeclVAddr(decl); + const endian = bin_file.options.target.cpu.arch.endian(); + switch (bin_file.options.target.cpu.arch.ptrBitWidth()) { 16 => { try code.resize(2); mem.writeInt(u16, code.items[0..2], @intCast(u16, vaddr), endian); @@ -188,7 +187,7 @@ pub fn generateSymbol( } return Result{ .fail = try ErrorMsg.create( - bin_file.base.allocator, + bin_file.allocator, src, "TODO implement generateSymbol for pointer {}", .{typed_value.val}, @@ -198,7 +197,7 @@ pub fn generateSymbol( .Int => { // TODO populate .debug_info for the integer - const info = typed_value.ty.intInfo(bin_file.base.options.target); + const info = typed_value.ty.intInfo(bin_file.options.target); if (info.bits == 8 and !info.signed) { const x = typed_value.val.toUnsignedInt(); try code.append(@intCast(u8, x)); @@ -206,7 +205,7 @@ pub fn generateSymbol( } return Result{ .fail = try ErrorMsg.create( - bin_file.base.allocator, + bin_file.allocator, src, "TODO implement generateSymbol for int type '{}'", .{typed_value.ty}, @@ -216,7 +215,7 @@ pub fn generateSymbol( else => |t| { return Result{ .fail = try ErrorMsg.create( - bin_file.base.allocator, + bin_file.allocator, src, "TODO implement generateSymbol for type '{}'", .{@tagName(t)}, @@ -234,13 +233,13 @@ const InnerError = error{ fn Function(comptime arch: std.Target.Cpu.Arch) type { return struct { gpa: *Allocator, - bin_file: *link.File.Elf, + bin_file: *link.File, target: *const std.Target, mod_fn: *const Module.Fn, code: *std.ArrayList(u8), dbg_line: *std.ArrayList(u8), dbg_info: *std.ArrayList(u8), - dbg_info_type_relocs: *link.File.Elf.DbgInfoTypeRelocsTable, + dbg_info_type_relocs: *link.File.DbgInfoTypeRelocsTable, err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: MCValue, @@ -405,22 +404,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { const Self = @This(); fn generateSymbol( - bin_file: *link.File.Elf, + bin_file: *link.File, src: usize, typed_value: TypedValue, code: *std.ArrayList(u8), dbg_line: *std.ArrayList(u8), dbg_info: *std.ArrayList(u8), - dbg_info_type_relocs: *link.File.Elf.DbgInfoTypeRelocsTable, + dbg_info_type_relocs: *link.File.DbgInfoTypeRelocsTable, ) GenerateSymbolError!Result { const module_fn = typed_value.val.cast(Value.Payload.Function).?.func; const fn_type = module_fn.owner_decl.typed_value.most_recent.typed_value.ty; - var branch_stack = std.ArrayList(Branch).init(bin_file.base.allocator); + var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); defer { assert(branch_stack.items.len == 1); - branch_stack.items[0].deinit(bin_file.base.allocator); + branch_stack.items[0].deinit(bin_file.allocator); branch_stack.deinit(); } const branch = try branch_stack.addOne(); @@ -443,8 +442,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { }; var function = Self{ - .gpa = bin_file.base.allocator, - .target = &bin_file.base.options.target, + .gpa = bin_file.allocator, + .target = &bin_file.options.target, .bin_file = bin_file, .mod_fn = module_fn, .code = code, @@ -464,7 +463,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .rbrace_src = src_data.rbrace_src, .source = src_data.source, }; - defer function.exitlude_jump_relocs.deinit(bin_file.base.allocator); + defer function.exitlude_jump_relocs.deinit(bin_file.allocator); var call_info = function.resolveCallingConventionValues(src, fn_type) catch |err| switch (err) { error.CodegenFail => return Result{ .fail = function.err_msg.? }, @@ -1144,80 +1143,88 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { var info = try self.resolveCallingConventionValues(inst.base.src, inst.func.ty); defer info.deinit(self); - switch (arch) { - .x86_64 => { - for (info.args) |mc_arg, arg_i| { - const arg = inst.args[arg_i]; - const arg_mcv = try self.resolveInst(inst.args[arg_i]); - // Here we do not use setRegOrMem even though the logic is similar, because - // the function call will move the stack pointer, so the offsets are different. - switch (mc_arg) { - .none => continue, - .register => |reg| { - try self.genSetReg(arg.src, reg, arg_mcv); - // TODO interact with the register allocator to mark the instruction as moved. - }, - .stack_offset => { - // Here we need to emit instructions like this: - // mov qword ptr [rsp + stack_offset], x - return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{}); - }, - .ptr_stack_offset => { - return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{}); - }, - .ptr_embedded_in_code => { - return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{}); - }, - .undef => unreachable, - .immediate => unreachable, - .unreach => unreachable, - .dead => unreachable, - .embedded_in_code => unreachable, - .memory => unreachable, - .compare_flags_signed => unreachable, - .compare_flags_unsigned => unreachable, + // Due to incremental compilation, how function calls are generated depends + // on linking. + if (self.bin_file.cast(link.File.Elf)) |elf_file| { + switch (arch) { + .x86_64 => { + for (info.args) |mc_arg, arg_i| { + const arg = inst.args[arg_i]; + const arg_mcv = try self.resolveInst(inst.args[arg_i]); + // Here we do not use setRegOrMem even though the logic is similar, because + // the function call will move the stack pointer, so the offsets are different. + switch (mc_arg) { + .none => continue, + .register => |reg| { + try self.genSetReg(arg.src, reg, arg_mcv); + // TODO interact with the register allocator to mark the instruction as moved. + }, + .stack_offset => { + // Here we need to emit instructions like this: + // mov qword ptr [rsp + stack_offset], x + return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{}); + }, + .ptr_stack_offset => { + return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{}); + }, + .ptr_embedded_in_code => { + return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{}); + }, + .undef => unreachable, + .immediate => unreachable, + .unreach => unreachable, + .dead => unreachable, + .embedded_in_code => unreachable, + .memory => unreachable, + .compare_flags_signed => unreachable, + .compare_flags_unsigned => unreachable, + } } - } - if (inst.func.cast(ir.Inst.Constant)) |func_inst| { - if (func_inst.val.cast(Value.Payload.Function)) |func_val| { - const func = func_val.func; - const got = &self.bin_file.program_headers.items[self.bin_file.phdr_got_index.?]; - const ptr_bits = self.target.cpu.arch.ptrBitWidth(); - const ptr_bytes: u64 = @divExact(ptr_bits, 8); - const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes); - // ff 14 25 xx xx xx xx call [addr] - try self.code.ensureCapacity(self.code.items.len + 7); - self.code.appendSliceAssumeCapacity(&[3]u8{ 0xff, 0x14, 0x25 }); - mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), got_addr); + if (inst.func.cast(ir.Inst.Constant)) |func_inst| { + if (func_inst.val.cast(Value.Payload.Function)) |func_val| { + const func = func_val.func; + const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?]; + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes: u64 = @divExact(ptr_bits, 8); + const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes); + // ff 14 25 xx xx xx xx call [addr] + try self.code.ensureCapacity(self.code.items.len + 7); + self.code.appendSliceAssumeCapacity(&[3]u8{ 0xff, 0x14, 0x25 }); + mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), got_addr); + } else { + return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{}); + } } else { - return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{}); + return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); } - } else { - return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); - } - }, - .riscv64 => { - if (info.args.len > 0) return self.fail(inst.base.src, "TODO implement fn args for {}", .{self.target.cpu.arch}); + }, + .riscv64 => { + if (info.args.len > 0) return self.fail(inst.base.src, "TODO implement fn args for {}", .{self.target.cpu.arch}); - if (inst.func.cast(ir.Inst.Constant)) |func_inst| { - if (func_inst.val.cast(Value.Payload.Function)) |func_val| { - const func = func_val.func; - const got = &self.bin_file.program_headers.items[self.bin_file.phdr_got_index.?]; - const ptr_bits = self.target.cpu.arch.ptrBitWidth(); - const ptr_bytes: u64 = @divExact(ptr_bits, 8); - const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes); + if (inst.func.cast(ir.Inst.Constant)) |func_inst| { + if (func_inst.val.cast(Value.Payload.Function)) |func_val| { + const func = func_val.func; + const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?]; + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes: u64 = @divExact(ptr_bits, 8); + const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes); - try self.genSetReg(inst.base.src, .ra, .{ .memory = got_addr }); - mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.ra, 0, .ra).toU32()); + try self.genSetReg(inst.base.src, .ra, .{ .memory = got_addr }); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.ra, 0, .ra).toU32()); + } else { + return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{}); + } } else { - return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{}); + return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); } - } else { - return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); - } - }, - else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}), + }, + else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}), + } + } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { + return self.fail(inst.base.src, "TODO implement codegen for call when linking with MachO", .{}); + } else { + unreachable; } return info.return_value; @@ -2036,10 +2043,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { switch (typed_value.ty.zigTypeTag()) { .Pointer => { if (typed_value.val.cast(Value.Payload.DeclRef)) |payload| { - const got = &self.bin_file.program_headers.items[self.bin_file.phdr_got_index.?]; - const decl = payload.decl; - const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes; - return MCValue{ .memory = got_addr }; + if (self.bin_file.cast(link.File.Elf)) |elf_file| { + const decl = payload.decl; + const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?]; + const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes; + return MCValue{ .memory = got_addr }; + } else { + return self.fail(src, "TODO codegen non-ELF const Decl pointer", .{}); + } } return self.fail(src, "TODO codegen more kinds of const pointers", .{}); }, @@ -2167,7 +2178,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. fn wantSafety(self: *Self) bool { - return switch (self.bin_file.base.options.optimize_mode) { + return switch (self.bin_file.options.optimize_mode) { .Debug => true, .ReleaseSafe => true, .ReleaseFast => false, @@ -2178,7 +2189,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.base.allocator, src, format, args); + self.err_msg = try ErrorMsg.create(self.bin_file.allocator, src, format, args); return error.CodegenFail; } diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index 39e6d27c589dad213a5c5bb4d570c0bc19ef966d..1e650d5e2cd1beaf7fc601acc814ac4dd0ae36cf 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -1,28 +1,10 @@ const std = @import("std"); -const mem = std.mem; -const assert = std.debug.assert; const Allocator = std.mem.Allocator; -const ir = @import("ir.zig"); const Module = @import("Module.zig"); const fs = std.fs; -const elf = std.elf; -const codegen = @import("codegen.zig"); -const c_codegen = @import("codegen/c.zig"); -const log = std.log.scoped(.link); -const DW = std.dwarf; const trace = @import("tracy.zig").trace; -const leb128 = std.debug.leb; const Package = @import("Package.zig"); -const Value = @import("value.zig").Value; const Type = @import("type.zig").Type; -const build_options = @import("build_options"); - -const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; - -// TODO Turn back on zig fmt when https://github.com/ziglang/zig/issues/5948 is implemented. -// zig fmt: off - -const default_entry_addr = 0x8000000; pub const Options = struct { target: std.Target, @@ -41,6 +23,11 @@ pub const Options = struct { }; pub const File = struct { + tag: Tag, + options: Options, + file: ?fs.File, + allocator: *Allocator, + pub const LinkBlock = union { elf: Elf.TextBlock, macho: MachO.TextBlock, @@ -55,16 +42,24 @@ pub const File = struct { wasm: ?Wasm.FnData, }; - tag: Tag, - options: Options, - file: ?fs.File, - allocator: *Allocator, + /// For DWARF .debug_info. + pub const DbgInfoTypeRelocsTable = std.HashMapUnmanaged(Type, DbgInfoTypeReloc, Type.hash, Type.eql, true); + + /// For DWARF .debug_info. + pub const DbgInfoTypeReloc = struct { + /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). + /// This is where the .debug_info tag for the type is. + off: u32, + /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). + /// List of DW.AT_type / DW.FORM_ref4 that points to the type. + relocs: std.ArrayListUnmanaged(u32), + }; /// Attempts incremental linking, if the file already exists. If /// incremental linking fails, falls back to truncating the file and /// rewriting it. A malicious file is detected as incremental link failure /// and does not cause Illegal Behavior. This operation is not atomic. - pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: Options) !*File { + pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: Options) !*File { switch (options.object_format) { .unknown => unreachable, .coff => return error.TODOImplementCoff, @@ -219,6 +214,15 @@ pub const File = struct { } } + pub fn getDeclVAddr(base: *File, decl: *const Module.Decl) u64 { + switch (base.tag) { + .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl), + .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl), + .c => unreachable, + .wasm => unreachable, + } + } + pub const Tag = enum { elf, macho, @@ -230,2670 +234,12 @@ pub const File = struct { no_entry_point_found: bool = false, }; - pub const C = struct { - pub const base_tag: Tag = .c; - - base: File, - - header: std.ArrayList(u8), - constants: std.ArrayList(u8), - main: std.ArrayList(u8), - - called: std.StringHashMap(void), - need_stddef: bool = false, - need_stdint: bool = false, - error_msg: *Module.ErrorMsg = undefined, - - pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: Options) !*File { - assert(options.object_format == .c); - - const file = try dir.createFile(sub_path, .{ .truncate = true, .read = true, .mode = determineMode(options) }); - errdefer file.close(); - - var c_file = try allocator.create(C); - errdefer allocator.destroy(c_file); - - c_file.* = File.C{ - .base = .{ - .tag = .c, - .options = options, - .file = file, - .allocator = allocator, - }, - .main = std.ArrayList(u8).init(allocator), - .header = std.ArrayList(u8).init(allocator), - .constants = std.ArrayList(u8).init(allocator), - .called = std.StringHashMap(void).init(allocator), - }; - - return &c_file.base; - } - - pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) error{AnalysisFail, OutOfMemory} { - self.error_msg = try Module.ErrorMsg.create(self.base.allocator, src, format, args); - return error.AnalysisFail; - } - - pub fn deinit(self: *File.C) void { - self.main.deinit(); - self.header.deinit(); - self.constants.deinit(); - self.called.deinit(); - } - - pub fn updateDecl(self: *File.C, module: *Module, decl: *Module.Decl) !void { - c_codegen.generate(self, decl) catch |err| { - if (err == error.AnalysisFail) { - try module.failed_decls.put(module.gpa, decl, self.error_msg); - } - return err; - }; - } - - pub fn flush(self: *File.C, module: *Module) !void { - const writer = self.base.file.?.writer(); - try writer.writeAll(@embedFile("cbe.h")); - var includes = false; - if (self.need_stddef) { - try writer.writeAll("#include \n"); - includes = true; - } - if (self.need_stdint) { - try writer.writeAll("#include \n"); - includes = true; - } - if (includes) { - try writer.writeByte('\n'); - } - if (self.header.items.len > 0) { - try writer.print("{}\n", .{self.header.items}); - } - if (self.constants.items.len > 0) { - try writer.print("{}\n", .{self.constants.items}); - } - if (self.main.items.len > 1) { - const last_two = self.main.items[self.main.items.len - 2 ..]; - if (std.mem.eql(u8, last_two, "\n\n")) { - self.main.items.len -= 1; - } - } - try writer.writeAll(self.main.items); - self.base.file.?.close(); - self.base.file = null; - } - }; - - pub const Elf = struct { - pub const base_tag: Tag = .elf; - - base: File, - - ptr_width: enum { p32, p64 }, - - /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. - /// Same order as in the file. - sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){}, - shdr_table_offset: ?u64 = null, - - /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. - /// Same order as in the file. - program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = std.ArrayListUnmanaged(elf.Elf64_Phdr){}, - phdr_table_offset: ?u64 = null, - /// The index into the program headers of a PT_LOAD program header with Read and Execute flags - phdr_load_re_index: ?u16 = null, - /// The index into the program headers of the global offset table. - /// It needs PT_LOAD and Read flags. - phdr_got_index: ?u16 = null, - entry_addr: ?u64 = null, - - debug_strtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){}, - shstrtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){}, - shstrtab_index: ?u16 = null, - - text_section_index: ?u16 = null, - symtab_section_index: ?u16 = null, - got_section_index: ?u16 = null, - debug_info_section_index: ?u16 = null, - debug_abbrev_section_index: ?u16 = null, - debug_str_section_index: ?u16 = null, - debug_aranges_section_index: ?u16 = null, - debug_line_section_index: ?u16 = null, - - debug_abbrev_table_offset: ?u64 = null, - - /// The same order as in the file. ELF requires global symbols to all be after the - /// local symbols, they cannot be mixed. So we must buffer all the global symbols and - /// write them at the end. These are only the local symbols. The length of this array - /// is the value used for sh_info in the .symtab section. - local_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, - global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, - - local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, - global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, - offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, - - /// Same order as in the file. The value is the absolute vaddr value. - /// If the vaddr of the executable program header changes, the entire - /// offset table needs to be rewritten. - offset_table: std.ArrayListUnmanaged(u64) = .{}, - - phdr_table_dirty: bool = false, - shdr_table_dirty: bool = false, - shstrtab_dirty: bool = false, - debug_strtab_dirty: bool = false, - offset_table_count_dirty: bool = false, - debug_abbrev_section_dirty: bool = false, - debug_aranges_section_dirty: bool = false, - - debug_info_header_dirty: bool = false, - debug_line_header_dirty: bool = false, - - error_flags: ErrorFlags = ErrorFlags{}, - - /// A list of text blocks that have surplus capacity. This list can have false - /// positives, as functions grow and shrink over time, only sometimes being added - /// or removed from the freelist. - /// - /// A text block has surplus capacity when its overcapacity value is greater than - /// minimum_text_block_size * alloc_num / alloc_den. That is, when it has so - /// much extra capacity, that we could fit a small new symbol in it, itself with - /// ideal_capacity or more. - /// - /// Ideal capacity is defined by size * alloc_num / alloc_den. - /// - /// Overcapacity is measured by actual_capacity - ideal_capacity. Note that - /// overcapacity can be negative. A simple way to have negative overcapacity is to - /// allocate a fresh text block, which will have ideal capacity, and then grow it - /// by 1 byte. It will then have -1 overcapacity. - text_block_free_list: std.ArrayListUnmanaged(*TextBlock) = .{}, - last_text_block: ?*TextBlock = null, - - /// A list of `SrcFn` whose Line Number Programs have surplus capacity. - /// This is the same concept as `text_block_free_list`; see those doc comments. - dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{}, - dbg_line_fn_first: ?*SrcFn = null, - dbg_line_fn_last: ?*SrcFn = null, - - /// A list of `TextBlock` whose corresponding .debug_info tags have surplus capacity. - /// This is the same concept as `text_block_free_list`; see those doc comments. - dbg_info_decl_free_list: std.AutoHashMapUnmanaged(*TextBlock, void) = .{}, - dbg_info_decl_first: ?*TextBlock = null, - dbg_info_decl_last: ?*TextBlock = null, - - /// `alloc_num / alloc_den` is the factor of padding when allocating. - const alloc_num = 4; - const alloc_den = 3; - - /// In order for a slice of bytes to be considered eligible to keep metadata pointing at - /// it as a possible place to put new symbols, it must have enough room for this many bytes - /// (plus extra for reserved capacity). - const minimum_text_block_size = 64; - const min_text_capacity = minimum_text_block_size * alloc_num / alloc_den; - - pub const DbgInfoTypeRelocsTable = std.HashMapUnmanaged(Type, DbgInfoTypeReloc, Type.hash, Type.eql, true); - - const DbgInfoTypeReloc = struct { - /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). - /// This is where the .debug_info tag for the type is. - off: u32, - /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). - /// List of DW.AT_type / DW.FORM_ref4 that points to the type. - relocs: std.ArrayListUnmanaged(u32), - }; - - pub const TextBlock = struct { - /// Each decl always gets a local symbol with the fully qualified name. - /// The vaddr and size are found here directly. - /// The file offset is found by computing the vaddr offset from the section vaddr - /// the symbol references, and adding that to the file offset of the section. - /// If this field is 0, it means the codegen size = 0 and there is no symbol or - /// offset table entry. - local_sym_index: u32, - /// This field is undefined for symbols with size = 0. - offset_table_index: u32, - /// Points to the previous and next neighbors, based on the `text_offset`. - /// This can be used to find, for example, the capacity of this `TextBlock`. - prev: ?*TextBlock, - next: ?*TextBlock, - - /// Previous/next linked list pointers. This value is `next ^ prev`. - /// This is the linked list node for this Decl's corresponding .debug_info tag. - dbg_info_prev: ?*TextBlock, - dbg_info_next: ?*TextBlock, - /// Offset into .debug_info pointing to the tag for this Decl. - dbg_info_off: u32, - /// Size of the .debug_info tag for this Decl, not including padding. - dbg_info_len: u32, - - pub const empty = TextBlock{ - .local_sym_index = 0, - .offset_table_index = undefined, - .prev = null, - .next = null, - .dbg_info_prev = null, - .dbg_info_next = null, - .dbg_info_off = undefined, - .dbg_info_len = undefined, - }; - - /// Returns how much room there is to grow in virtual address space. - /// File offset relocation happens transparently, so it is not included in - /// this calculation. - fn capacity(self: TextBlock, elf_file: Elf) u64 { - const self_sym = elf_file.local_symbols.items[self.local_sym_index]; - if (self.next) |next| { - const next_sym = elf_file.local_symbols.items[next.local_sym_index]; - return next_sym.st_value - self_sym.st_value; - } else { - // We are the last block. The capacity is limited only by virtual address space. - return std.math.maxInt(u32) - self_sym.st_value; - } - } - - fn freeListEligible(self: TextBlock, elf_file: Elf) bool { - // No need to keep a free list node for the last block. - const next = self.next orelse return false; - const self_sym = elf_file.local_symbols.items[self.local_sym_index]; - const next_sym = elf_file.local_symbols.items[next.local_sym_index]; - const cap = next_sym.st_value - self_sym.st_value; - const ideal_cap = self_sym.st_size * alloc_num / alloc_den; - if (cap <= ideal_cap) return false; - const surplus = cap - ideal_cap; - return surplus >= min_text_capacity; - } - }; - - pub const Export = struct { - sym_index: ?u32 = null, - }; - - pub const SrcFn = struct { - /// Offset from the beginning of the Debug Line Program header that contains this function. - off: u32, - /// Size of the line number program component belonging to this function, not - /// including padding. - len: u32, - - /// Points to the previous and next neighbors, based on the offset from .debug_line. - /// This can be used to find, for example, the capacity of this `SrcFn`. - prev: ?*SrcFn, - next: ?*SrcFn, - - pub const empty: SrcFn = .{ - .off = 0, - .len = 0, - .prev = null, - .next = null, - }; - }; - - pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: Options) !*File { - assert(options.object_format == .elf); - - const file = try dir.createFile(sub_path, .{ .truncate = false, .read = true, .mode = determineMode(options) }); - errdefer file.close(); - - var elf_file = try allocator.create(Elf); - errdefer allocator.destroy(elf_file); - - elf_file.* = openFile(allocator, file, options) catch |err| switch (err) { - error.IncrFailed => try createFile(allocator, file, options), - else => |e| return e, - }; - - return &elf_file.base; - } - - /// Returns error.IncrFailed if incremental update could not be performed. - fn openFile(allocator: *Allocator, file: fs.File, options: Options) !Elf { - switch (options.output_mode) { - .Exe => {}, - .Obj => {}, - .Lib => return error.IncrFailed, - } - var self: Elf = .{ - .base = .{ - .file = file, - .tag = .elf, - .options = options, - .allocator = allocator, - }, - .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { - 32 => .p32, - 64 => .p64, - else => return error.UnsupportedELFArchitecture, - }, - }; - errdefer self.deinit(); - - // TODO implement reading the elf file - return error.IncrFailed; - //try self.populateMissingMetadata(); - //return self; - } - - /// Truncates the existing file contents and overwrites the contents. - /// Returns an error if `file` is not already open with +read +write +seek abilities. - fn createFile(allocator: *Allocator, file: fs.File, options: Options) !Elf { - switch (options.output_mode) { - .Exe => {}, - .Obj => {}, - .Lib => return error.TODOImplementWritingLibFiles, - } - var self: Elf = .{ - .base = .{ - .tag = .elf, - .options = options, - .allocator = allocator, - .file = file, - }, - .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { - 32 => .p32, - 64 => .p64, - else => return error.UnsupportedELFArchitecture, - }, - .shdr_table_dirty = true, - }; - errdefer self.deinit(); - - // Index 0 is always a null symbol. - try self.local_symbols.append(allocator, .{ - .st_name = 0, - .st_info = 0, - .st_other = 0, - .st_shndx = 0, - .st_value = 0, - .st_size = 0, - }); - - // There must always be a null section in index 0 - try self.sections.append(allocator, .{ - .sh_name = 0, - .sh_type = elf.SHT_NULL, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = 0, - .sh_size = 0, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = 0, - .sh_entsize = 0, - }); - - try self.populateMissingMetadata(); - - return self; - } - - pub fn deinit(self: *Elf) void { - self.sections.deinit(self.base.allocator); - self.program_headers.deinit(self.base.allocator); - self.shstrtab.deinit(self.base.allocator); - self.debug_strtab.deinit(self.base.allocator); - self.local_symbols.deinit(self.base.allocator); - self.global_symbols.deinit(self.base.allocator); - self.global_symbol_free_list.deinit(self.base.allocator); - self.local_symbol_free_list.deinit(self.base.allocator); - self.offset_table_free_list.deinit(self.base.allocator); - self.text_block_free_list.deinit(self.base.allocator); - self.dbg_line_fn_free_list.deinit(self.base.allocator); - self.dbg_info_decl_free_list.deinit(self.base.allocator); - self.offset_table.deinit(self.base.allocator); - } - - fn getDebugLineProgramOff(self: Elf) u32 { - return self.dbg_line_fn_first.?.off; - } - - fn getDebugLineProgramEnd(self: Elf) u32 { - return self.dbg_line_fn_last.?.off + self.dbg_line_fn_last.?.len; - } - - /// Returns end pos of collision, if any. - fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { - const small_ptr = self.base.options.target.cpu.arch.ptrBitWidth() == 32; - const ehdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Ehdr) else @sizeOf(elf.Elf64_Ehdr); - if (start < ehdr_size) - return ehdr_size; - - const end = start + satMul(size, alloc_num) / alloc_den; - - if (self.shdr_table_offset) |off| { - const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); - const tight_size = self.sections.items.len * shdr_size; - const increased_size = satMul(tight_size, alloc_num) / alloc_den; - const test_end = off + increased_size; - if (end > off and start < test_end) { - return test_end; - } - } - - if (self.phdr_table_offset) |off| { - const phdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Phdr) else @sizeOf(elf.Elf64_Phdr); - const tight_size = self.sections.items.len * phdr_size; - const increased_size = satMul(tight_size, alloc_num) / alloc_den; - const test_end = off + increased_size; - if (end > off and start < test_end) { - return test_end; - } - } - - for (self.sections.items) |section| { - const increased_size = satMul(section.sh_size, alloc_num) / alloc_den; - const test_end = section.sh_offset + increased_size; - if (end > section.sh_offset and start < test_end) { - return test_end; - } - } - for (self.program_headers.items) |program_header| { - const increased_size = satMul(program_header.p_filesz, alloc_num) / alloc_den; - const test_end = program_header.p_offset + increased_size; - if (end > program_header.p_offset and start < test_end) { - return test_end; - } - } - return null; - } - - fn allocatedSize(self: *Elf, start: u64) u64 { - if (start == 0) - return 0; - var min_pos: u64 = std.math.maxInt(u64); - if (self.shdr_table_offset) |off| { - if (off > start and off < min_pos) min_pos = off; - } - if (self.phdr_table_offset) |off| { - if (off > start and off < min_pos) min_pos = off; - } - for (self.sections.items) |section| { - if (section.sh_offset <= start) continue; - if (section.sh_offset < min_pos) min_pos = section.sh_offset; - } - for (self.program_headers.items) |program_header| { - if (program_header.p_offset <= start) continue; - if (program_header.p_offset < min_pos) min_pos = program_header.p_offset; - } - return min_pos - start; - } - - fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u16) u64 { - var start: u64 = 0; - while (self.detectAllocCollision(start, object_size)) |item_end| { - start = mem.alignForwardGeneric(u64, item_end, min_alignment); - } - return start; - } - - /// TODO Improve this to use a table. - fn makeString(self: *Elf, bytes: []const u8) !u32 { - try self.shstrtab.ensureCapacity(self.base.allocator, self.shstrtab.items.len + bytes.len + 1); - const result = self.shstrtab.items.len; - self.shstrtab.appendSliceAssumeCapacity(bytes); - self.shstrtab.appendAssumeCapacity(0); - return @intCast(u32, result); - } - - /// TODO Improve this to use a table. - fn makeDebugString(self: *Elf, bytes: []const u8) !u32 { - try self.debug_strtab.ensureCapacity(self.base.allocator, self.debug_strtab.items.len + bytes.len + 1); - const result = self.debug_strtab.items.len; - self.debug_strtab.appendSliceAssumeCapacity(bytes); - self.debug_strtab.appendAssumeCapacity(0); - return @intCast(u32, result); - } - - fn getString(self: *Elf, str_off: u32) []const u8 { - assert(str_off < self.shstrtab.items.len); - return mem.spanZ(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off)); - } - - fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 { - const existing_name = self.getString(old_str_off); - if (mem.eql(u8, existing_name, new_name)) { - return old_str_off; - } - return self.makeString(new_name); - } - - pub fn populateMissingMetadata(self: *Elf) !void { - const small_ptr = switch (self.ptr_width) { - .p32 => true, - .p64 => false, - }; - const ptr_size: u8 = self.ptrWidthBytes(); - if (self.phdr_load_re_index == null) { - self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); - const file_size = self.base.options.program_code_size_hint; - const p_align = 0x1000; - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); - try self.program_headers.append(self.base.allocator, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = default_entry_addr, - .p_paddr = default_entry_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_X | elf.PF_R, - }); - self.entry_addr = null; - self.phdr_table_dirty = true; - } - if (self.phdr_got_index == null) { - self.phdr_got_index = @intCast(u16, self.program_headers.items.len); - const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; - // We really only need ptr alignment but since we are using PROGBITS, linux requires - // page align. - const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size); - const off = self.findFreeSpace(file_size, p_align); - log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); - // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. - // we'll need to re-use that function anyway, in case the GOT grows and overlaps something - // else in virtual memory. - const default_got_addr = if (ptr_size == 2) @as(u32, 0x8000) else 0x4000000; - try self.program_headers.append(self.base.allocator, .{ - .p_type = elf.PT_LOAD, - .p_offset = off, - .p_filesz = file_size, - .p_vaddr = default_got_addr, - .p_paddr = default_got_addr, - .p_memsz = file_size, - .p_align = p_align, - .p_flags = elf.PF_R, - }); - self.phdr_table_dirty = true; - } - if (self.shstrtab_index == null) { - self.shstrtab_index = @intCast(u16, self.sections.items.len); - assert(self.shstrtab.items.len == 0); - try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0 - const off = self.findFreeSpace(self.shstrtab.items.len, 1); - log.debug("found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len }); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".shstrtab"), - .sh_type = elf.SHT_STRTAB, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = self.shstrtab.items.len, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = 1, - .sh_entsize = 0, - }); - self.shstrtab_dirty = true; - self.shdr_table_dirty = true; - } - if (self.text_section_index == null) { - self.text_section_index = @intCast(u16, self.sections.items.len); - const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; - - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".text"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, - .sh_addr = phdr.p_vaddr, - .sh_offset = phdr.p_offset, - .sh_size = phdr.p_filesz, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = phdr.p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - } - if (self.got_section_index == null) { - self.got_section_index = @intCast(u16, self.sections.items.len); - const phdr = &self.program_headers.items[self.phdr_got_index.?]; - - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".got"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = elf.SHF_ALLOC, - .sh_addr = phdr.p_vaddr, - .sh_offset = phdr.p_offset, - .sh_size = phdr.p_filesz, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = phdr.p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - } - if (self.symtab_section_index == null) { - self.symtab_section_index = @intCast(u16, self.sections.items.len); - const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym); - const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym); - const file_size = self.base.options.symbol_count_hint * each_size; - const off = self.findFreeSpace(file_size, min_align); - log.debug("found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); - - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".symtab"), - .sh_type = elf.SHT_SYMTAB, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = file_size, - // The section header index of the associated string table. - .sh_link = self.shstrtab_index.?, - .sh_info = @intCast(u32, self.local_symbols.items.len), - .sh_addralign = min_align, - .sh_entsize = each_size, - }); - self.shdr_table_dirty = true; - try self.writeSymbol(0); - } - if (self.debug_str_section_index == null) { - self.debug_str_section_index = @intCast(u16, self.sections.items.len); - assert(self.debug_strtab.items.len == 0); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".debug_str"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS, - .sh_addr = 0, - .sh_offset = 0, - .sh_size = self.debug_strtab.items.len, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = 1, - .sh_entsize = 1, - }); - self.debug_strtab_dirty = true; - self.shdr_table_dirty = true; - } - if (self.debug_info_section_index == null) { - self.debug_info_section_index = @intCast(u16, self.sections.items.len); - - const file_size_hint = 200; - const p_align = 1; - const off = self.findFreeSpace(file_size_hint, p_align); - log.debug("found .debug_info free space 0x{x} to 0x{x}\n", .{ - off, - off + file_size_hint, - }); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".debug_info"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = file_size_hint, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - self.debug_info_header_dirty = true; - } - if (self.debug_abbrev_section_index == null) { - self.debug_abbrev_section_index = @intCast(u16, self.sections.items.len); - - const file_size_hint = 128; - const p_align = 1; - const off = self.findFreeSpace(file_size_hint, p_align); - log.debug("found .debug_abbrev free space 0x{x} to 0x{x}\n", .{ - off, - off + file_size_hint, - }); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".debug_abbrev"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = file_size_hint, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - self.debug_abbrev_section_dirty = true; - } - if (self.debug_aranges_section_index == null) { - self.debug_aranges_section_index = @intCast(u16, self.sections.items.len); - - const file_size_hint = 160; - const p_align = 16; - const off = self.findFreeSpace(file_size_hint, p_align); - log.debug("found .debug_aranges free space 0x{x} to 0x{x}\n", .{ - off, - off + file_size_hint, - }); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".debug_aranges"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = file_size_hint, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - self.debug_aranges_section_dirty = true; - } - if (self.debug_line_section_index == null) { - self.debug_line_section_index = @intCast(u16, self.sections.items.len); - - const file_size_hint = 250; - const p_align = 1; - const off = self.findFreeSpace(file_size_hint, p_align); - log.debug("found .debug_line free space 0x{x} to 0x{x}\n", .{ - off, - off + file_size_hint, - }); - try self.sections.append(self.base.allocator, .{ - .sh_name = try self.makeString(".debug_line"), - .sh_type = elf.SHT_PROGBITS, - .sh_flags = 0, - .sh_addr = 0, - .sh_offset = off, - .sh_size = file_size_hint, - .sh_link = 0, - .sh_info = 0, - .sh_addralign = p_align, - .sh_entsize = 0, - }); - self.shdr_table_dirty = true; - self.debug_line_header_dirty = true; - } - const shsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Shdr), - .p64 => @sizeOf(elf.Elf64_Shdr), - }; - const shalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Shdr), - .p64 => @alignOf(elf.Elf64_Shdr), - }; - if (self.shdr_table_offset == null) { - self.shdr_table_offset = self.findFreeSpace(self.sections.items.len * shsize, shalign); - self.shdr_table_dirty = true; - } - const phsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Phdr), - .p64 => @sizeOf(elf.Elf64_Phdr), - }; - const phalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Phdr), - .p64 => @alignOf(elf.Elf64_Phdr), - }; - if (self.phdr_table_offset == null) { - self.phdr_table_offset = self.findFreeSpace(self.program_headers.items.len * phsize, phalign); - self.phdr_table_dirty = true; - } - { - // Iterate over symbols, populating free_list and last_text_block. - if (self.local_symbols.items.len != 1) { - @panic("TODO implement setting up free_list and last_text_block from existing ELF file"); - } - // We are starting with an empty file. The default values are correct, null and empty list. - } - } - - pub const abbrev_compile_unit = 1; - pub const abbrev_subprogram = 2; - pub const abbrev_subprogram_retvoid = 3; - pub const abbrev_base_type = 4; - pub const abbrev_pad1 = 5; - pub const abbrev_parameter = 6; - - /// Commit pending changes and write headers. - pub fn flush(self: *Elf, module: *Module) !void { - const target_endian = self.base.options.target.cpu.arch.endian(); - const foreign_endian = target_endian != std.Target.current.cpu.arch.endian(); - const ptr_width_bytes: u8 = self.ptrWidthBytes(); - const init_len_size: usize = switch (self.ptr_width) { - .p32 => 4, - .p64 => 12, - }; - - // Unfortunately these have to be buffered and done at the end because ELF does not allow - // mixing local and global symbols within a symbol table. - try self.writeAllGlobalSymbols(); - - if (self.debug_abbrev_section_dirty) { - const debug_abbrev_sect = &self.sections.items[self.debug_abbrev_section_index.?]; - - // These are LEB encoded but since the values are all less than 127 - // we can simply append these bytes. - const abbrev_buf = [_]u8{ - abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header - DW.AT_stmt_list, DW.FORM_sec_offset, - DW.AT_low_pc , DW.FORM_addr, - DW.AT_high_pc , DW.FORM_addr, - DW.AT_name , DW.FORM_strp, - DW.AT_comp_dir , DW.FORM_strp, - DW.AT_producer , DW.FORM_strp, - DW.AT_language , DW.FORM_data2, - 0, 0, // table sentinel - - abbrev_subprogram, DW.TAG_subprogram, DW.CHILDREN_yes, // header - DW.AT_low_pc , DW.FORM_addr, - DW.AT_high_pc , DW.FORM_data4, - DW.AT_type , DW.FORM_ref4, - DW.AT_name , DW.FORM_string, - 0, 0, // table sentinel - - abbrev_subprogram_retvoid, DW.TAG_subprogram, DW.CHILDREN_yes, // header - DW.AT_low_pc , DW.FORM_addr, - DW.AT_high_pc , DW.FORM_data4, - DW.AT_name , DW.FORM_string, - 0, 0, // table sentinel - - abbrev_base_type, DW.TAG_base_type, DW.CHILDREN_no, // header - DW.AT_encoding , DW.FORM_data1, - DW.AT_byte_size, DW.FORM_data1, - DW.AT_name , DW.FORM_string, - 0, 0, // table sentinel - - abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header - 0, 0, // table sentinel - - abbrev_parameter, DW.TAG_formal_parameter, DW.CHILDREN_no, // header - DW.AT_location , DW.FORM_exprloc, - DW.AT_type , DW.FORM_ref4, - DW.AT_name , DW.FORM_string, - 0, 0, // table sentinel - - 0, 0, 0, // section sentinel - }; - - const needed_size = abbrev_buf.len; - const allocated_size = self.allocatedSize(debug_abbrev_sect.sh_offset); - if (needed_size > allocated_size) { - debug_abbrev_sect.sh_size = 0; // free the space - debug_abbrev_sect.sh_offset = self.findFreeSpace(needed_size, 1); - } - debug_abbrev_sect.sh_size = needed_size; - log.debug(".debug_abbrev start=0x{x} end=0x{x}\n", .{ - debug_abbrev_sect.sh_offset, - debug_abbrev_sect.sh_offset + needed_size, - }); - - const abbrev_offset = 0; - self.debug_abbrev_table_offset = abbrev_offset; - try self.base.file.?.pwriteAll(&abbrev_buf, debug_abbrev_sect.sh_offset + abbrev_offset); - if (!self.shdr_table_dirty) { - // Then it won't get written with the others and we need to do it. - try self.writeSectHeader(self.debug_abbrev_section_index.?); - } - - self.debug_abbrev_section_dirty = false; - } - - if (self.debug_info_header_dirty) debug_info: { - // If this value is null it means there is an error in the module; - // leave debug_info_header_dirty=true. - const first_dbg_info_decl = self.dbg_info_decl_first orelse break :debug_info; - const last_dbg_info_decl = self.dbg_info_decl_last.?; - const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; - - var di_buf = std.ArrayList(u8).init(self.base.allocator); - defer di_buf.deinit(); - - // We have a function to compute the upper bound size, because it's needed - // for determining where to put the offset of the first `LinkBlock`. - try di_buf.ensureCapacity(self.dbgInfoNeededHeaderBytes()); - - // initial length - length of the .debug_info contribution for this compilation unit, - // not including the initial length itself. - // We have to come back and write it later after we know the size. - const after_init_len = di_buf.items.len + init_len_size; - // +1 for the final 0 that ends the compilation unit children. - const dbg_info_end = last_dbg_info_decl.dbg_info_off + last_dbg_info_decl.dbg_info_len + 1; - const init_len = dbg_info_end - after_init_len; - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len), target_endian); - }, - .p64 => { - di_buf.appendNTimesAssumeCapacity(0xff, 4); - mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), init_len, target_endian); - }, - } - mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // DWARF version - const abbrev_offset = self.debug_abbrev_table_offset.?; - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, abbrev_offset), target_endian); - di_buf.appendAssumeCapacity(4); // address size - }, - .p64 => { - mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), abbrev_offset, target_endian); - di_buf.appendAssumeCapacity(8); // address size - }, - } - // Write the form for the compile unit, which must match the abbrev table above. - const name_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_path); - const comp_dir_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_dir_path); - const producer_strp = try self.makeDebugString(producer_string); - // Currently only one compilation unit is supported, so the address range is simply - // identical to the main program header virtual address and memory size. - const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; - const low_pc = text_phdr.p_vaddr; - const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; - - di_buf.appendAssumeCapacity(abbrev_compile_unit); - self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT_stmt_list, DW.FORM_sec_offset - self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc); - self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc); - self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp); - self.writeDwarfAddrAssumeCapacity(&di_buf, comp_dir_strp); - self.writeDwarfAddrAssumeCapacity(&di_buf, producer_strp); - // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: - // http://dwarfstd.org/ShowIssue.php?issue=171115.1 - // Until then we say it is C99. - mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99, target_endian); - - if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { - // Move the first N decls to the end to make more padding for the header. - @panic("TODO: handle .debug_info header exceeding its padding"); - } - const jmp_amt = first_dbg_info_decl.dbg_info_off - di_buf.items.len; - try self.pwriteDbgInfoNops(0, di_buf.items, jmp_amt, false, debug_info_sect.sh_offset); - self.debug_info_header_dirty = false; - } - - if (self.debug_aranges_section_dirty) { - const debug_aranges_sect = &self.sections.items[self.debug_aranges_section_index.?]; - - var di_buf = std.ArrayList(u8).init(self.base.allocator); - defer di_buf.deinit(); - - // Enough for all the data without resizing. When support for more compilation units - // is added, the size of this section will become more variable. - try di_buf.ensureCapacity(100); - - // initial length - length of the .debug_aranges contribution for this compilation unit, - // not including the initial length itself. - // We have to come back and write it later after we know the size. - const init_len_index = di_buf.items.len; - di_buf.items.len += init_len_size; - const after_init_len = di_buf.items.len; - mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 2, target_endian); // version - // When more than one compilation unit is supported, this will be the offset to it. - // For now it is always at offset 0 in .debug_info. - self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // .debug_info offset - di_buf.appendAssumeCapacity(ptr_width_bytes); // address_size - di_buf.appendAssumeCapacity(0); // segment_selector_size - - const end_header_offset = di_buf.items.len; - const begin_entries_offset = mem.alignForward(end_header_offset, ptr_width_bytes * 2); - di_buf.appendNTimesAssumeCapacity(0, begin_entries_offset - end_header_offset); - - // Currently only one compilation unit is supported, so the address range is simply - // identical to the main program header virtual address and memory size. - const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; - self.writeDwarfAddrAssumeCapacity(&di_buf, text_phdr.p_vaddr); - self.writeDwarfAddrAssumeCapacity(&di_buf, text_phdr.p_memsz); - - // Sentinel. - self.writeDwarfAddrAssumeCapacity(&di_buf, 0); - self.writeDwarfAddrAssumeCapacity(&di_buf, 0); - - // Go back and populate the initial length. - const init_len = di_buf.items.len - after_init_len; - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, di_buf.items[init_len_index..][0..4], @intCast(u32, init_len), target_endian); - }, - .p64 => { - // initial length - length of the .debug_aranges contribution for this compilation unit, - // not including the initial length itself. - di_buf.items[init_len_index..][0..4].* = [_]u8{ 0xff, 0xff, 0xff, 0xff }; - mem.writeInt(u64, di_buf.items[init_len_index + 4..][0..8], init_len, target_endian); - }, - } - - const needed_size = di_buf.items.len; - const allocated_size = self.allocatedSize(debug_aranges_sect.sh_offset); - if (needed_size > allocated_size) { - debug_aranges_sect.sh_size = 0; // free the space - debug_aranges_sect.sh_offset = self.findFreeSpace(needed_size, 16); - } - debug_aranges_sect.sh_size = needed_size; - log.debug(".debug_aranges start=0x{x} end=0x{x}\n", .{ - debug_aranges_sect.sh_offset, - debug_aranges_sect.sh_offset + needed_size, - }); - - try self.base.file.?.pwriteAll(di_buf.items, debug_aranges_sect.sh_offset); - if (!self.shdr_table_dirty) { - // Then it won't get written with the others and we need to do it. - try self.writeSectHeader(self.debug_aranges_section_index.?); - } - - self.debug_aranges_section_dirty = false; - } - if (self.debug_line_header_dirty) debug_line: { - if (self.dbg_line_fn_first == null) { - break :debug_line; // Error in module; leave debug_line_header_dirty=true. - } - const dbg_line_prg_off = self.getDebugLineProgramOff(); - const dbg_line_prg_end = self.getDebugLineProgramEnd(); - assert(dbg_line_prg_end != 0); - - const debug_line_sect = &self.sections.items[self.debug_line_section_index.?]; - - var di_buf = std.ArrayList(u8).init(self.base.allocator); - defer di_buf.deinit(); - - // The size of this header is variable, depending on the number of directories, - // files, and padding. We have a function to compute the upper bound size, however, - // because it's needed for determining where to put the offset of the first `SrcFn`. - try di_buf.ensureCapacity(self.dbgLineNeededHeaderBytes()); - - // initial length - length of the .debug_line contribution for this compilation unit, - // not including the initial length itself. - const after_init_len = di_buf.items.len + init_len_size; - const init_len = dbg_line_prg_end - after_init_len; - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len), target_endian); - }, - .p64 => { - di_buf.appendNTimesAssumeCapacity(0xff, 4); - mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), init_len, target_endian); - }, - } - - mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // version - - // Empirically, debug info consumers do not respect this field, or otherwise - // consider it to be an error when it does not point exactly to the end of the header. - // Therefore we rely on the NOP jump at the beginning of the Line Number Program for - // padding rather than this field. - const before_header_len = di_buf.items.len; - di_buf.items.len += ptr_width_bytes; // We will come back and write this. - const after_header_len = di_buf.items.len; - - const opcode_base = DW.LNS_set_isa + 1; - di_buf.appendSliceAssumeCapacity(&[_]u8{ - 1, // minimum_instruction_length - 1, // maximum_operations_per_instruction - 1, // default_is_stmt - 1, // line_base (signed) - 1, // line_range - opcode_base, - - // Standard opcode lengths. The number of items here is based on `opcode_base`. - // The value is the number of LEB128 operands the instruction takes. - 0, // `DW.LNS_copy` - 1, // `DW.LNS_advance_pc` - 1, // `DW.LNS_advance_line` - 1, // `DW.LNS_set_file` - 1, // `DW.LNS_set_column` - 0, // `DW.LNS_negate_stmt` - 0, // `DW.LNS_set_basic_block` - 0, // `DW.LNS_const_add_pc` - 1, // `DW.LNS_fixed_advance_pc` - 0, // `DW.LNS_set_prologue_end` - 0, // `DW.LNS_set_epilogue_begin` - 1, // `DW.LNS_set_isa` - - 0, // include_directories (none except the compilation unit cwd) - }); - // file_names[0] - di_buf.appendSliceAssumeCapacity(self.base.options.root_pkg.root_src_path); // relative path name - di_buf.appendSliceAssumeCapacity(&[_]u8{ - 0, // null byte for the relative path name - 0, // directory_index - 0, // mtime (TODO supply this) - 0, // file size bytes (TODO supply this) - 0, // file_names sentinel - }); - - const header_len = di_buf.items.len - after_header_len; - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, di_buf.items[before_header_len..][0..4], @intCast(u32, header_len), target_endian); - }, - .p64 => { - mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian); - }, - } - - // We use NOPs because consumers empirically do not respect the header length field. - if (di_buf.items.len > dbg_line_prg_off) { - // Move the first N files to the end to make more padding for the header. - @panic("TODO: handle .debug_line header exceeding its padding"); - } - const jmp_amt = dbg_line_prg_off - di_buf.items.len; - try self.pwriteDbgLineNops(0, di_buf.items, jmp_amt, debug_line_sect.sh_offset); - self.debug_line_header_dirty = false; - } - - if (self.phdr_table_dirty) { - const phsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Phdr), - .p64 => @sizeOf(elf.Elf64_Phdr), - }; - const phalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Phdr), - .p64 => @alignOf(elf.Elf64_Phdr), - }; - const allocated_size = self.allocatedSize(self.phdr_table_offset.?); - const needed_size = self.program_headers.items.len * phsize; - - if (needed_size > allocated_size) { - self.phdr_table_offset = null; // free the space - self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); - } - - switch (self.ptr_width) { - .p32 => { - const buf = try self.base.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*phdr, i| { - phdr.* = progHeaderTo32(self.program_headers.items[i]); - if (foreign_endian) { - bswapAllFields(elf.Elf32_Phdr, phdr); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); - }, - .p64 => { - const buf = try self.base.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*phdr, i| { - phdr.* = self.program_headers.items[i]; - if (foreign_endian) { - bswapAllFields(elf.Elf64_Phdr, phdr); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); - }, - } - self.phdr_table_dirty = false; - } - - { - const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; - if (self.shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { - const allocated_size = self.allocatedSize(shstrtab_sect.sh_offset); - const needed_size = self.shstrtab.items.len; - - if (needed_size > allocated_size) { - shstrtab_sect.sh_size = 0; // free the space - shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); - } - shstrtab_sect.sh_size = needed_size; - log.debug("writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size }); - - try self.base.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); - if (!self.shdr_table_dirty) { - // Then it won't get written with the others and we need to do it. - try self.writeSectHeader(self.shstrtab_index.?); - } - self.shstrtab_dirty = false; - } - } - { - const debug_strtab_sect = &self.sections.items[self.debug_str_section_index.?]; - if (self.debug_strtab_dirty or self.debug_strtab.items.len != debug_strtab_sect.sh_size) { - const allocated_size = self.allocatedSize(debug_strtab_sect.sh_offset); - const needed_size = self.debug_strtab.items.len; - - if (needed_size > allocated_size) { - debug_strtab_sect.sh_size = 0; // free the space - debug_strtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); - } - debug_strtab_sect.sh_size = needed_size; - log.debug("debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size }); - - try self.base.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset); - if (!self.shdr_table_dirty) { - // Then it won't get written with the others and we need to do it. - try self.writeSectHeader(self.debug_str_section_index.?); - } - self.debug_strtab_dirty = false; - } - } - if (self.shdr_table_dirty) { - const shsize: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Shdr), - .p64 => @sizeOf(elf.Elf64_Shdr), - }; - const shalign: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Shdr), - .p64 => @alignOf(elf.Elf64_Shdr), - }; - const allocated_size = self.allocatedSize(self.shdr_table_offset.?); - const needed_size = self.sections.items.len * shsize; - - if (needed_size > allocated_size) { - self.shdr_table_offset = null; // free the space - self.shdr_table_offset = self.findFreeSpace(needed_size, shalign); - } - - switch (self.ptr_width) { - .p32 => { - const buf = try self.base.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*shdr, i| { - shdr.* = sectHeaderTo32(self.sections.items[i]); - log.debug("writing section {}\n", .{shdr.*}); - if (foreign_endian) { - bswapAllFields(elf.Elf32_Shdr, shdr); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); - }, - .p64 => { - const buf = try self.base.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*shdr, i| { - shdr.* = self.sections.items[i]; - log.debug("writing section {}\n", .{shdr.*}); - if (foreign_endian) { - bswapAllFields(elf.Elf64_Shdr, shdr); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); - }, - } - self.shdr_table_dirty = false; - } - if (self.entry_addr == null and self.base.options.output_mode == .Exe) { - log.debug("flushing. no_entry_point_found = true\n", .{}); - self.error_flags.no_entry_point_found = true; - } else { - log.debug("flushing. no_entry_point_found = false\n", .{}); - self.error_flags.no_entry_point_found = false; - try self.writeElfHeader(); - } - - // The point of flush() is to commit changes, so in theory, nothing should - // be dirty after this. However, it is possible for some things to remain - // dirty because they fail to be written in the event of compile errors, - // such as debug_line_header_dirty and debug_info_header_dirty. - assert(!self.debug_abbrev_section_dirty); - assert(!self.debug_aranges_section_dirty); - assert(!self.phdr_table_dirty); - assert(!self.shdr_table_dirty); - assert(!self.shstrtab_dirty); - assert(!self.debug_strtab_dirty); - } - - fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { - const target_endian = self.base.options.target.cpu.arch.endian(); - switch (self.ptr_width) { - .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, addr), target_endian), - .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), - } - } - - fn writeElfHeader(self: *Elf) !void { - var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined; - - var index: usize = 0; - hdr_buf[0..4].* = "\x7fELF".*; - index += 4; - - hdr_buf[index] = switch (self.ptr_width) { - .p32 => elf.ELFCLASS32, - .p64 => elf.ELFCLASS64, - }; - index += 1; - - const endian = self.base.options.target.cpu.arch.endian(); - hdr_buf[index] = switch (endian) { - .Little => elf.ELFDATA2LSB, - .Big => elf.ELFDATA2MSB, - }; - index += 1; - - hdr_buf[index] = 1; // ELF version - index += 1; - - // OS ABI, often set to 0 regardless of target platform - // ABI Version, possibly used by glibc but not by static executables - // padding - mem.set(u8, hdr_buf[index..][0..9], 0); - index += 9; - - assert(index == 16); - - const elf_type = switch (self.base.options.output_mode) { - .Exe => elf.ET.EXEC, - .Obj => elf.ET.REL, - .Lib => switch (self.base.options.link_mode) { - .Static => elf.ET.REL, - .Dynamic => elf.ET.DYN, - }, - }; - mem.writeInt(u16, hdr_buf[index..][0..2], @enumToInt(elf_type), endian); - index += 2; - - const machine = self.base.options.target.cpu.arch.toElfMachine(); - mem.writeInt(u16, hdr_buf[index..][0..2], @enumToInt(machine), endian); - index += 2; - - // ELF Version, again - mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian); - index += 4; - - const e_entry = if (elf_type == .REL) 0 else self.entry_addr.?; - - switch (self.ptr_width) { - .p32 => { - mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, e_entry), endian); - index += 4; - - // e_phoff - mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, self.phdr_table_offset.?), endian); - index += 4; - - // e_shoff - mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, self.shdr_table_offset.?), endian); - index += 4; - }, - .p64 => { - // e_entry - mem.writeInt(u64, hdr_buf[index..][0..8], e_entry, endian); - index += 8; - - // e_phoff - mem.writeInt(u64, hdr_buf[index..][0..8], self.phdr_table_offset.?, endian); - index += 8; - - // e_shoff - mem.writeInt(u64, hdr_buf[index..][0..8], self.shdr_table_offset.?, endian); - index += 8; - }, - } - - const e_flags = 0; - mem.writeInt(u32, hdr_buf[index..][0..4], e_flags, endian); - index += 4; - - const e_ehsize: u16 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Ehdr), - .p64 => @sizeOf(elf.Elf64_Ehdr), - }; - mem.writeInt(u16, hdr_buf[index..][0..2], e_ehsize, endian); - index += 2; - - const e_phentsize: u16 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Phdr), - .p64 => @sizeOf(elf.Elf64_Phdr), - }; - mem.writeInt(u16, hdr_buf[index..][0..2], e_phentsize, endian); - index += 2; - - const e_phnum = @intCast(u16, self.program_headers.items.len); - mem.writeInt(u16, hdr_buf[index..][0..2], e_phnum, endian); - index += 2; - - const e_shentsize: u16 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Shdr), - .p64 => @sizeOf(elf.Elf64_Shdr), - }; - mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian); - index += 2; - - const e_shnum = @intCast(u16, self.sections.items.len); - mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); - index += 2; - - mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_index.?, endian); - index += 2; - - assert(index == e_ehsize); - - try self.base.file.?.pwriteAll(hdr_buf[0..index], 0); - } - - fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { - var already_have_free_list_node = false; - { - var i: usize = 0; - while (i < self.text_block_free_list.items.len) { - if (self.text_block_free_list.items[i] == text_block) { - _ = self.text_block_free_list.swapRemove(i); - continue; - } - if (self.text_block_free_list.items[i] == text_block.prev) { - already_have_free_list_node = true; - } - i += 1; - } - } - - if (self.last_text_block == text_block) { - // TODO shrink the .text section size here - self.last_text_block = text_block.prev; - } - - if (text_block.prev) |prev| { - prev.next = text_block.next; - - if (!already_have_free_list_node and prev.freeListEligible(self.*)) { - // The free list is heuristics, it doesn't have to be perfect, so we can - // ignore the OOM here. - self.text_block_free_list.append(self.base.allocator, prev) catch {}; - } - } else { - text_block.prev = null; - } - - if (text_block.next) |next| { - next.prev = text_block.prev; - } else { - text_block.next = null; - } - } - - fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void { - // TODO check the new capacity, and if it crosses the size threshold into a big enough - // capacity, insert a free list node for it. - } - - fn growTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { - const sym = self.local_symbols.items[text_block.local_sym_index]; - const align_ok = mem.alignBackwardGeneric(u64, sym.st_value, alignment) == sym.st_value; - const need_realloc = !align_ok or new_block_size > text_block.capacity(self.*); - if (!need_realloc) return sym.st_value; - return self.allocateTextBlock(text_block, new_block_size, alignment); - } - - fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { - const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; - const shdr = &self.sections.items[self.text_section_index.?]; - const new_block_ideal_capacity = new_block_size * alloc_num / alloc_den; - - // We use these to indicate our intention to update metadata, placing the new block, - // and possibly removing a free list node. - // It would be simpler to do it inside the for loop below, but that would cause a - // problem if an error was returned later in the function. So this action - // is actually carried out at the end of the function, when errors are no longer possible. - var block_placement: ?*TextBlock = null; - var free_list_removal: ?usize = null; - - // First we look for an appropriately sized free list node. - // The list is unordered. We'll just take the first thing that works. - const vaddr = blk: { - var i: usize = 0; - while (i < self.text_block_free_list.items.len) { - const big_block = self.text_block_free_list.items[i]; - // We now have a pointer to a live text block that has too much capacity. - // Is it enough that we could fit this new text block? - const sym = self.local_symbols.items[big_block.local_sym_index]; - const capacity = big_block.capacity(self.*); - const ideal_capacity = capacity * alloc_num / alloc_den; - const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity; - const capacity_end_vaddr = sym.st_value + capacity; - const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity; - const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment); - if (new_start_vaddr < ideal_capacity_end_vaddr) { - // Additional bookkeeping here to notice if this free list node - // should be deleted because the block that it points to has grown to take up - // more of the extra capacity. - if (!big_block.freeListEligible(self.*)) { - _ = self.text_block_free_list.swapRemove(i); - } else { - i += 1; - } - continue; - } - // At this point we know that we will place the new block here. But the - // remaining question is whether there is still yet enough capacity left - // over for there to still be a free list node. - const remaining_capacity = new_start_vaddr - ideal_capacity_end_vaddr; - const keep_free_list_node = remaining_capacity >= min_text_capacity; - - // Set up the metadata to be updated, after errors are no longer possible. - block_placement = big_block; - if (!keep_free_list_node) { - free_list_removal = i; - } - break :blk new_start_vaddr; - } else if (self.last_text_block) |last| { - const sym = self.local_symbols.items[last.local_sym_index]; - const ideal_capacity = sym.st_size * alloc_num / alloc_den; - const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity; - const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); - // Set up the metadata to be updated, after errors are no longer possible. - block_placement = last; - break :blk new_start_vaddr; - } else { - break :blk phdr.p_vaddr; - } - }; - - const expand_text_section = block_placement == null or block_placement.?.next == null; - if (expand_text_section) { - const text_capacity = self.allocatedSize(shdr.sh_offset); - const needed_size = (vaddr + new_block_size) - phdr.p_vaddr; - if (needed_size > text_capacity) { - // Must move the entire text section. - const new_offset = self.findFreeSpace(needed_size, 0x1000); - const text_size = if (self.last_text_block) |last| blk: { - const sym = self.local_symbols.items[last.local_sym_index]; - break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr; - } else 0; - const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size); - if (amt != text_size) return error.InputOutput; - shdr.sh_offset = new_offset; - phdr.p_offset = new_offset; - } - self.last_text_block = text_block; - - shdr.sh_size = needed_size; - phdr.p_memsz = needed_size; - phdr.p_filesz = needed_size; - - // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address - // range of the compilation unit. When we expand the text section, this range changes, - // so the DW_TAG_compile_unit tag of the .debug_info section becomes dirty. - self.debug_info_header_dirty = true; - // This becomes dirty for the same reason. We could potentially make this more - // fine-grained with the addition of support for more compilation units. It is planned to - // model each package as a different compilation unit. - self.debug_aranges_section_dirty = true; - - self.phdr_table_dirty = true; // TODO look into making only the one program header dirty - self.shdr_table_dirty = true; // TODO look into making only the one section dirty - } - - // This function can also reallocate a text block. - // In this case we need to "unplug" it from its previous location before - // plugging it in to its new location. - if (text_block.prev) |prev| { - prev.next = text_block.next; - } - if (text_block.next) |next| { - next.prev = text_block.prev; - } - - if (block_placement) |big_block| { - text_block.prev = big_block; - text_block.next = big_block.next; - big_block.next = text_block; - } else { - text_block.prev = null; - text_block.next = null; - } - if (free_list_removal) |i| { - _ = self.text_block_free_list.swapRemove(i); - } - return vaddr; - } - - pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { - if (decl.link.elf.local_sym_index != 0) return; - - try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); - try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1); - - if (self.local_symbol_free_list.popOrNull()) |i| { - log.debug("reusing symbol index {} for {}\n", .{ i, decl.name }); - decl.link.elf.local_sym_index = i; - } else { - log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name }); - decl.link.elf.local_sym_index = @intCast(u32, self.local_symbols.items.len); - _ = self.local_symbols.addOneAssumeCapacity(); - } - - if (self.offset_table_free_list.popOrNull()) |i| { - decl.link.elf.offset_table_index = i; - } else { - decl.link.elf.offset_table_index = @intCast(u32, self.offset_table.items.len); - _ = self.offset_table.addOneAssumeCapacity(); - self.offset_table_count_dirty = true; - } - - const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; - - self.local_symbols.items[decl.link.elf.local_sym_index] = .{ - .st_name = 0, - .st_info = 0, - .st_other = 0, - .st_shndx = 0, - .st_value = phdr.p_vaddr, - .st_size = 0, - }; - self.offset_table.items[decl.link.elf.offset_table_index] = 0; - } - - pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { - // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. - self.freeTextBlock(&decl.link.elf); - if (decl.link.elf.local_sym_index != 0) { - self.local_symbol_free_list.append(self.base.allocator, decl.link.elf.local_sym_index) catch {}; - self.offset_table_free_list.append(self.base.allocator, decl.link.elf.offset_table_index) catch {}; - - self.local_symbols.items[decl.link.elf.local_sym_index].st_info = 0; - - decl.link.elf.local_sym_index = 0; - } - // TODO make this logic match freeTextBlock. Maybe abstract the logic out since the same thing - // is desired for both. - _ = self.dbg_line_fn_free_list.remove(&decl.fn_link.elf); - if (decl.fn_link.elf.prev) |prev| { - _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {}; - prev.next = decl.fn_link.elf.next; - if (decl.fn_link.elf.next) |next| { - next.prev = prev; - } else { - self.dbg_line_fn_last = prev; - } - } else if (decl.fn_link.elf.next) |next| { - self.dbg_line_fn_first = next; - next.prev = null; - } - if (self.dbg_line_fn_first == &decl.fn_link.elf) { - self.dbg_line_fn_first = null; - } - if (self.dbg_line_fn_last == &decl.fn_link.elf) { - self.dbg_line_fn_last = null; - } - } - - pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { - const tracy = trace(@src()); - defer tracy.end(); - - var code_buffer = std.ArrayList(u8).init(self.base.allocator); - defer code_buffer.deinit(); - - var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator); - defer dbg_line_buffer.deinit(); - - var dbg_info_buffer = std.ArrayList(u8).init(self.base.allocator); - defer dbg_info_buffer.deinit(); - - var dbg_info_type_relocs: DbgInfoTypeRelocsTable = .{}; - defer { - for (dbg_info_type_relocs.items()) |*entry| { - entry.value.relocs.deinit(self.base.allocator); - } - dbg_info_type_relocs.deinit(self.base.allocator); - } - - const typed_value = decl.typed_value.most_recent.typed_value; - const is_fn: bool = switch (typed_value.ty.zigTypeTag()) { - .Fn => true, - else => false, - }; - if (is_fn) { - //if (mem.eql(u8, mem.spanZ(decl.name), "add")) { - // typed_value.val.cast(Value.Payload.Function).?.func.dump(module.*); - //} - - // For functions we need to add a prologue to the debug line program. - try dbg_line_buffer.ensureCapacity(26); - - const line_off: u28 = blk: { - if (decl.scope.cast(Module.Scope.File)) |scope_file| { - const tree = scope_file.contents.tree; - const file_ast_decls = tree.root_node.decls(); - // TODO Look into improving the performance here by adding a token-index-to-line - // lookup table. Currently this involves scanning over the source code for newlines. - const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; - const block = fn_proto.body().?.castTag(.Block).?; - const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); - break :blk @intCast(u28, line_delta); - } else if (decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { - const byte_off = zir_module.contents.module.decls[decl.src_index].inst.src; - const line_delta = std.zig.lineDelta(zir_module.source.bytes, 0, byte_off); - break :blk @intCast(u28, line_delta); - } else { - unreachable; - } - }; - - const ptr_width_bytes = self.ptrWidthBytes(); - dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ - DW.LNS_extended_op, - ptr_width_bytes + 1, - DW.LNE_set_address, - }); - // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. - assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); - dbg_line_buffer.items.len += ptr_width_bytes; - - dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line); - // This is the "relocatable" relative line offset from the previous function's end curly - // to this function's begin curly. - assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); - // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. - leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); - - dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); - assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); - // Once we support more than one source file, this will have the ability to be more - // than one possible value. - const file_index = 1; - leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); - - // Emit a line for the begin curly with prologue_end=false. The codegen will - // do the work of setting prologue_end=true and epilogue_begin=true. - dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy); - - // .debug_info subprogram - const decl_name_with_null = decl.name[0..mem.lenZ(decl.name) + 1]; - try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 25 + decl_name_with_null.len); - - const fn_ret_type = typed_value.ty.fnReturnType(); - const fn_ret_has_bits = fn_ret_type.hasCodeGenBits(); - if (fn_ret_has_bits) { - dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram); - } else { - dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram_retvoid); - } - // These get overwritten after generating the machine code. These values are - // "relocations" and have to be in this fixed place so that functions can be - // moved in virtual address space. - assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); - dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT_low_pc, DW.FORM_addr - assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); - dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data4 - if (fn_ret_has_bits) { - const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type); - if (!gop.found_existing) { - gop.entry.value = .{ - .off = undefined, - .relocs = .{}, - }; - } - try gop.entry.value.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len)); - dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref4 - } - dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string - } else { - // TODO implement .debug_info for global variables - } - const res = try codegen.generateSymbol(self, decl.src(), typed_value, &code_buffer, &dbg_line_buffer, &dbg_info_buffer, &dbg_info_type_relocs); - const code = switch (res) { - .externally_managed => |x| x, - .appended => code_buffer.items, - .fail => |em| { - decl.analysis = .codegen_failure; - try module.failed_decls.put(module.gpa, decl, em); - return; - }, - }; - - const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); - - const stt_bits: u8 = if (is_fn) elf.STT_FUNC else elf.STT_OBJECT; - - assert(decl.link.elf.local_sym_index != 0); // Caller forgot to allocateDeclIndexes() - const local_sym = &self.local_symbols.items[decl.link.elf.local_sym_index]; - if (local_sym.st_size != 0) { - const capacity = decl.link.elf.capacity(self.*); - const need_realloc = code.len > capacity or - !mem.isAlignedGeneric(u64, local_sym.st_value, required_alignment); - if (need_realloc) { - const vaddr = try self.growTextBlock(&decl.link.elf, code.len, required_alignment); - log.debug("growing {} from 0x{x} to 0x{x}\n", .{ decl.name, local_sym.st_value, vaddr }); - if (vaddr != local_sym.st_value) { - local_sym.st_value = vaddr; - - log.debug(" (writing new offset table entry)\n", .{}); - self.offset_table.items[decl.link.elf.offset_table_index] = vaddr; - try self.writeOffsetTableEntry(decl.link.elf.offset_table_index); - } - } else if (code.len < local_sym.st_size) { - self.shrinkTextBlock(&decl.link.elf, code.len); - } - local_sym.st_size = code.len; - local_sym.st_name = try self.updateString(local_sym.st_name, mem.spanZ(decl.name)); - local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits; - local_sym.st_other = 0; - local_sym.st_shndx = self.text_section_index.?; - // TODO this write could be avoided if no fields of the symbol were changed. - try self.writeSymbol(decl.link.elf.local_sym_index); - } else { - const decl_name = mem.spanZ(decl.name); - const name_str_index = try self.makeString(decl_name); - const vaddr = try self.allocateTextBlock(&decl.link.elf, code.len, required_alignment); - log.debug("allocated text block for {} at 0x{x}\n", .{ decl_name, vaddr }); - errdefer self.freeTextBlock(&decl.link.elf); - - local_sym.* = .{ - .st_name = name_str_index, - .st_info = (elf.STB_LOCAL << 4) | stt_bits, - .st_other = 0, - .st_shndx = self.text_section_index.?, - .st_value = vaddr, - .st_size = code.len, - }; - self.offset_table.items[decl.link.elf.offset_table_index] = vaddr; - - try self.writeSymbol(decl.link.elf.local_sym_index); - try self.writeOffsetTableEntry(decl.link.elf.offset_table_index); - } - - const section_offset = local_sym.st_value - self.program_headers.items[self.phdr_load_re_index.?].p_vaddr; - const file_offset = self.sections.items[self.text_section_index.?].sh_offset + section_offset; - try self.base.file.?.pwriteAll(code, file_offset); - - const target_endian = self.base.options.target.cpu.arch.endian(); - - const text_block = &decl.link.elf; - - // If the Decl is a function, we need to update the .debug_line program. - if (is_fn) { - // Perform the relocations based on vaddr. - switch (self.ptr_width) { - .p32 => { - { - const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..4]; - mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_value), target_endian); - } - { - const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..4]; - mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_value), target_endian); - } - }, - .p64 => { - { - const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..8]; - mem.writeInt(u64, ptr, local_sym.st_value, target_endian); - } - { - const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..8]; - mem.writeInt(u64, ptr, local_sym.st_value, target_endian); - } - }, - } - { - const ptr = dbg_info_buffer.items[self.getRelocDbgInfoSubprogramHighPC()..][0..4]; - mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian); - } - - try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence }); - - // Now we have the full contents and may allocate a region to store it. - - // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for - // `TextBlock` and the .debug_info. If you are editing this logic, you - // probably need to edit that logic too. - - const debug_line_sect = &self.sections.items[self.debug_line_section_index.?]; - const src_fn = &decl.fn_link.elf; - src_fn.len = @intCast(u32, dbg_line_buffer.items.len); - if (self.dbg_line_fn_last) |last| { - if (src_fn.next) |next| { - // Update existing function - non-last item. - if (src_fn.off + src_fn.len + min_nop_size > next.off) { - // It grew too big, so we move it to a new location. - if (src_fn.prev) |prev| { - _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {}; - prev.next = src_fn.next; - } - next.prev = src_fn.prev; - src_fn.next = null; - // Populate where it used to be with NOPs. - const file_pos = debug_line_sect.sh_offset + src_fn.off; - try self.pwriteDbgLineNops(0, &[0]u8{}, src_fn.len, file_pos); - // TODO Look at the free list before appending at the end. - src_fn.prev = last; - last.next = src_fn; - self.dbg_line_fn_last = src_fn; - - src_fn.off = last.off + (last.len * alloc_num / alloc_den); - } - } else if (src_fn.prev == null) { - // Append new function. - // TODO Look at the free list before appending at the end. - src_fn.prev = last; - last.next = src_fn; - self.dbg_line_fn_last = src_fn; - - src_fn.off = last.off + (last.len * alloc_num / alloc_den); - } - } else { - // This is the first function of the Line Number Program. - self.dbg_line_fn_first = src_fn; - self.dbg_line_fn_last = src_fn; - - src_fn.off = self.dbgLineNeededHeaderBytes() * alloc_num / alloc_den; - } - - const last_src_fn = self.dbg_line_fn_last.?; - const needed_size = last_src_fn.off + last_src_fn.len; - if (needed_size != debug_line_sect.sh_size) { - if (needed_size > self.allocatedSize(debug_line_sect.sh_offset)) { - const new_offset = self.findFreeSpace(needed_size, 1); - const existing_size = last_src_fn.off; - log.debug("moving .debug_line section: {} bytes from 0x{x} to 0x{x}\n", .{ - existing_size, - debug_line_sect.sh_offset, - new_offset, - }); - const amt = try self.base.file.?.copyRangeAll(debug_line_sect.sh_offset, self.base.file.?, new_offset, existing_size); - if (amt != existing_size) return error.InputOutput; - debug_line_sect.sh_offset = new_offset; - } - debug_line_sect.sh_size = needed_size; - self.shdr_table_dirty = true; // TODO look into making only the one section dirty - self.debug_line_header_dirty = true; - } - const prev_padding_size: u32 = if (src_fn.prev) |prev| src_fn.off - (prev.off + prev.len) else 0; - const next_padding_size: u32 = if (src_fn.next) |next| next.off - (src_fn.off + src_fn.len) else 0; - - // We only have support for one compilation unit so far, so the offsets are directly - // from the .debug_line section. - const file_pos = debug_line_sect.sh_offset + src_fn.off; - try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); - - // .debug_info - End the TAG_subprogram children. - try dbg_info_buffer.append(0); - } - - // Now we emit the .debug_info types of the Decl. These will count towards the size of - // the buffer, so we have to do it before computing the offset, and we can't perform the actual - // relocations yet. - for (dbg_info_type_relocs.items()) |*entry| { - entry.value.off = @intCast(u32, dbg_info_buffer.items.len); - try self.addDbgInfoType(entry.key, &dbg_info_buffer); - } - - try self.updateDeclDebugInfoAllocation(text_block, @intCast(u32, dbg_info_buffer.items.len)); - - // Now that we have the offset assigned we can finally perform type relocations. - for (dbg_info_type_relocs.items()) |entry| { - for (entry.value.relocs.items) |off| { - mem.writeInt( - u32, - dbg_info_buffer.items[off..][0..4], - text_block.dbg_info_off + entry.value.off, - target_endian, - ); - } - } - - try self.writeDeclDebugInfo(text_block, dbg_info_buffer.items); - - // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. - const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{}; - return self.updateDeclExports(module, decl, decl_exports); - } - - /// Asserts the type has codegen bits. - fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !void { - switch (ty.zigTypeTag()) { - .Void => unreachable, - .NoReturn => unreachable, - .Bool => { - try dbg_info_buffer.appendSlice(&[_]u8{ - abbrev_base_type, - DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1 - 1, // DW.AT_byte_size, DW.FORM_data1 - 'b', 'o', 'o', 'l', 0, // DW.AT_name, DW.FORM_string - }); - }, - .Int => { - const info = ty.intInfo(self.base.options.target); - try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); - dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); - // DW.AT_encoding, DW.FORM_data1 - dbg_info_buffer.appendAssumeCapacity(if (info.signed) DW.ATE_signed else DW.ATE_unsigned); - // DW.AT_byte_size, DW.FORM_data1 - dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); - // DW.AT_name, DW.FORM_string - try dbg_info_buffer.writer().print("{}\x00", .{ty}); - }, - else => { - std.log.scoped(.compiler).err("TODO implement .debug_info for type '{}'", .{ty}); - try dbg_info_buffer.append(abbrev_pad1); - }, - } - } - - fn updateDeclDebugInfoAllocation(self: *Elf, text_block: *TextBlock, len: u32) !void { - const tracy = trace(@src()); - defer tracy.end(); - - // This logic is nearly identical to the logic above in `updateDecl` for - // `SrcFn` and the line number programs. If you are editing this logic, you - // probably need to edit that logic too. - - const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; - text_block.dbg_info_len = len; - if (self.dbg_info_decl_last) |last| { - if (text_block.dbg_info_next) |next| { - // Update existing Decl - non-last item. - if (text_block.dbg_info_off + text_block.dbg_info_len + min_nop_size > next.dbg_info_off) { - // It grew too big, so we move it to a new location. - if (text_block.dbg_info_prev) |prev| { - _ = self.dbg_info_decl_free_list.put(self.base.allocator, prev, {}) catch {}; - prev.dbg_info_next = text_block.dbg_info_next; - } - next.dbg_info_prev = text_block.dbg_info_prev; - text_block.dbg_info_next = null; - // Populate where it used to be with NOPs. - const file_pos = debug_info_sect.sh_offset + text_block.dbg_info_off; - try self.pwriteDbgInfoNops(0, &[0]u8{}, text_block.dbg_info_len, false, file_pos); - // TODO Look at the free list before appending at the end. - text_block.dbg_info_prev = last; - last.dbg_info_next = text_block; - self.dbg_info_decl_last = text_block; - - text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den); - } - } else if (text_block.dbg_info_prev == null) { - // Append new Decl. - // TODO Look at the free list before appending at the end. - text_block.dbg_info_prev = last; - last.dbg_info_next = text_block; - self.dbg_info_decl_last = text_block; - - text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den); - } - } else { - // This is the first Decl of the .debug_info - self.dbg_info_decl_first = text_block; - self.dbg_info_decl_last = text_block; - - text_block.dbg_info_off = self.dbgInfoNeededHeaderBytes() * alloc_num / alloc_den; - } - } - - fn writeDeclDebugInfo(self: *Elf, text_block: *TextBlock, dbg_info_buf: []const u8) !void { - const tracy = trace(@src()); - defer tracy.end(); - - // This logic is nearly identical to the logic above in `updateDecl` for - // `SrcFn` and the line number programs. If you are editing this logic, you - // probably need to edit that logic too. - - const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; - - const last_decl = self.dbg_info_decl_last.?; - // +1 for a trailing zero to end the children of the decl tag. - const needed_size = last_decl.dbg_info_off + last_decl.dbg_info_len + 1; - if (needed_size != debug_info_sect.sh_size) { - if (needed_size > self.allocatedSize(debug_info_sect.sh_offset)) { - const new_offset = self.findFreeSpace(needed_size, 1); - const existing_size = last_decl.dbg_info_off; - log.debug("moving .debug_info section: {} bytes from 0x{x} to 0x{x}\n", .{ - existing_size, - debug_info_sect.sh_offset, - new_offset, - }); - const amt = try self.base.file.?.copyRangeAll(debug_info_sect.sh_offset, self.base.file.?, new_offset, existing_size); - if (amt != existing_size) return error.InputOutput; - debug_info_sect.sh_offset = new_offset; - } - debug_info_sect.sh_size = needed_size; - self.shdr_table_dirty = true; // TODO look into making only the one section dirty - self.debug_info_header_dirty = true; - } - const prev_padding_size: u32 = if (text_block.dbg_info_prev) |prev| - text_block.dbg_info_off - (prev.dbg_info_off + prev.dbg_info_len) - else - 0; - const next_padding_size: u32 = if (text_block.dbg_info_next) |next| - next.dbg_info_off - (text_block.dbg_info_off + text_block.dbg_info_len) - else - 0; - - // To end the children of the decl tag. - const trailing_zero = text_block.dbg_info_next == null; - - // We only have support for one compilation unit so far, so the offsets are directly - // from the .debug_info section. - const file_pos = debug_info_sect.sh_offset + text_block.dbg_info_off; - try self.pwriteDbgInfoNops(prev_padding_size, dbg_info_buf, next_padding_size, trailing_zero, file_pos); - } - - pub fn updateDeclExports( - self: *Elf, - module: *Module, - decl: *const Module.Decl, - exports: []const *Module.Export, - ) !void { - const tracy = trace(@src()); - defer tracy.end(); - - try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len); - const typed_value = decl.typed_value.most_recent.typed_value; - if (decl.link.elf.local_sym_index == 0) return; - const decl_sym = self.local_symbols.items[decl.link.elf.local_sym_index]; - - for (exports) |exp| { - if (exp.options.section) |section_name| { - if (!mem.eql(u8, section_name, ".text")) { - try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); - module.failed_exports.putAssumeCapacityNoClobber( - exp, - try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: ExportOptions.section", .{}), - ); - continue; - } - } - const stb_bits: u8 = switch (exp.options.linkage) { - .Internal => elf.STB_LOCAL, - .Strong => blk: { - if (mem.eql(u8, exp.options.name, "_start")) { - self.entry_addr = decl_sym.st_value; - } - break :blk elf.STB_GLOBAL; - }, - .Weak => elf.STB_WEAK, - .LinkOnce => { - try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); - module.failed_exports.putAssumeCapacityNoClobber( - exp, - try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}), - ); - continue; - }, - }; - const stt_bits: u8 = @truncate(u4, decl_sym.st_info); - if (exp.link.sym_index) |i| { - const sym = &self.global_symbols.items[i]; - sym.* = .{ - .st_name = try self.updateString(sym.st_name, exp.options.name), - .st_info = (stb_bits << 4) | stt_bits, - .st_other = 0, - .st_shndx = self.text_section_index.?, - .st_value = decl_sym.st_value, - .st_size = decl_sym.st_size, - }; - } else { - const name = try self.makeString(exp.options.name); - const i = if (self.global_symbol_free_list.popOrNull()) |i| i else blk: { - _ = self.global_symbols.addOneAssumeCapacity(); - break :blk self.global_symbols.items.len - 1; - }; - self.global_symbols.items[i] = .{ - .st_name = name, - .st_info = (stb_bits << 4) | stt_bits, - .st_other = 0, - .st_shndx = self.text_section_index.?, - .st_value = decl_sym.st_value, - .st_size = decl_sym.st_size, - }; - - exp.link.sym_index = @intCast(u32, i); - } - } - } - - /// Must be called only after a successful call to `updateDecl`. - pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Decl) !void { - const tracy = trace(@src()); - defer tracy.end(); - - const scope_file = decl.scope.cast(Module.Scope.File).?; - const tree = scope_file.contents.tree; - const file_ast_decls = tree.root_node.decls(); - // TODO Look into improving the performance here by adding a token-index-to-line - // lookup table. Currently this involves scanning over the source code for newlines. - const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; - const block = fn_proto.body().?.castTag(.Block).?; - const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); - const casted_line_off = @intCast(u28, line_delta); - - const shdr = &self.sections.items[self.debug_line_section_index.?]; - const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff(); - var data: [4]u8 = undefined; - leb128.writeUnsignedFixed(4, &data, casted_line_off); - try self.base.file.?.pwriteAll(&data, file_pos); - } - - pub fn deleteExport(self: *Elf, exp: Export) void { - const sym_index = exp.sym_index orelse return; - self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {}; - self.global_symbols.items[sym_index].st_info = 0; - } - - fn writeProgHeader(self: *Elf, index: usize) !void { - const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); - const offset = self.program_headers.items[index].p_offset; - switch (self.base.options.target.cpu.arch.ptrBitWidth()) { - 32 => { - var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])}; - if (foreign_endian) { - bswapAllFields(elf.Elf32_Phdr, &phdr[0]); - } - return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); - }, - 64 => { - var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; - if (foreign_endian) { - bswapAllFields(elf.Elf64_Phdr, &phdr[0]); - } - return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); - }, - else => return error.UnsupportedArchitecture, - } - } - - fn writeSectHeader(self: *Elf, index: usize) !void { - const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); - switch (self.base.options.target.cpu.arch.ptrBitWidth()) { - 32 => { - var shdr: [1]elf.Elf32_Shdr = undefined; - shdr[0] = sectHeaderTo32(self.sections.items[index]); - if (foreign_endian) { - bswapAllFields(elf.Elf32_Shdr, &shdr[0]); - } - const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr); - return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); - }, - 64 => { - var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; - if (foreign_endian) { - bswapAllFields(elf.Elf64_Shdr, &shdr[0]); - } - const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr); - return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); - }, - else => return error.UnsupportedArchitecture, - } - } - - fn writeOffsetTableEntry(self: *Elf, index: usize) !void { - const shdr = &self.sections.items[self.got_section_index.?]; - const phdr = &self.program_headers.items[self.phdr_got_index.?]; - const entry_size: u16 = self.ptrWidthBytes(); - if (self.offset_table_count_dirty) { - // TODO Also detect virtual address collisions. - const allocated_size = self.allocatedSize(shdr.sh_offset); - const needed_size = self.local_symbols.items.len * entry_size; - if (needed_size > allocated_size) { - // Must move the entire got section. - const new_offset = self.findFreeSpace(needed_size, entry_size); - const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size); - if (amt != shdr.sh_size) return error.InputOutput; - shdr.sh_offset = new_offset; - phdr.p_offset = new_offset; - } - shdr.sh_size = needed_size; - phdr.p_memsz = needed_size; - phdr.p_filesz = needed_size; - - self.shdr_table_dirty = true; // TODO look into making only the one section dirty - self.phdr_table_dirty = true; // TODO look into making only the one program header dirty - - self.offset_table_count_dirty = false; - } - const endian = self.base.options.target.cpu.arch.endian(); - const off = shdr.sh_offset + @as(u64, entry_size) * index; - switch (self.ptr_width) { - .p32 => { - var buf: [4]u8 = undefined; - mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian); - try self.base.file.?.pwriteAll(&buf, off); - }, - .p64 => { - var buf: [8]u8 = undefined; - mem.writeInt(u64, &buf, self.offset_table.items[index], endian); - try self.base.file.?.pwriteAll(&buf, off); - }, - } - } - - fn writeSymbol(self: *Elf, index: usize) !void { - const tracy = trace(@src()); - defer tracy.end(); - - const syms_sect = &self.sections.items[self.symtab_section_index.?]; - // Make sure we are not pointlessly writing symbol data that will have to get relocated - // due to running out of space. - if (self.local_symbols.items.len != syms_sect.sh_info) { - const sym_size: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Sym), - .p64 => @sizeOf(elf.Elf64_Sym), - }; - const sym_align: u16 = switch (self.ptr_width) { - .p32 => @alignOf(elf.Elf32_Sym), - .p64 => @alignOf(elf.Elf64_Sym), - }; - const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size; - if (needed_size > self.allocatedSize(syms_sect.sh_offset)) { - // Move all the symbols to a new file location. - const new_offset = self.findFreeSpace(needed_size, sym_align); - const existing_size = @as(u64, syms_sect.sh_info) * sym_size; - const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size); - if (amt != existing_size) return error.InputOutput; - syms_sect.sh_offset = new_offset; - } - syms_sect.sh_info = @intCast(u32, self.local_symbols.items.len); - syms_sect.sh_size = needed_size; // anticipating adding the global symbols later - self.shdr_table_dirty = true; // TODO look into only writing one section - } - const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); - switch (self.ptr_width) { - .p32 => { - var sym = [1]elf.Elf32_Sym{ - .{ - .st_name = self.local_symbols.items[index].st_name, - .st_value = @intCast(u32, self.local_symbols.items[index].st_value), - .st_size = @intCast(u32, self.local_symbols.items[index].st_size), - .st_info = self.local_symbols.items[index].st_info, - .st_other = self.local_symbols.items[index].st_other, - .st_shndx = self.local_symbols.items[index].st_shndx, - }, - }; - if (foreign_endian) { - bswapAllFields(elf.Elf32_Sym, &sym[0]); - } - const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index; - try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); - }, - .p64 => { - var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]}; - if (foreign_endian) { - bswapAllFields(elf.Elf64_Sym, &sym[0]); - } - const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index; - try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); - }, - } - } - - fn writeAllGlobalSymbols(self: *Elf) !void { - const syms_sect = &self.sections.items[self.symtab_section_index.?]; - const sym_size: u64 = switch (self.ptr_width) { - .p32 => @sizeOf(elf.Elf32_Sym), - .p64 => @sizeOf(elf.Elf64_Sym), - }; - const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); - const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size; - switch (self.ptr_width) { - .p32 => { - const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*sym, i| { - sym.* = .{ - .st_name = self.global_symbols.items[i].st_name, - .st_value = @intCast(u32, self.global_symbols.items[i].st_value), - .st_size = @intCast(u32, self.global_symbols.items[i].st_size), - .st_info = self.global_symbols.items[i].st_info, - .st_other = self.global_symbols.items[i].st_other, - .st_shndx = self.global_symbols.items[i].st_shndx, - }; - if (foreign_endian) { - bswapAllFields(elf.Elf32_Sym, sym); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); - }, - .p64 => { - const buf = try self.base.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len); - defer self.base.allocator.free(buf); - - for (buf) |*sym, i| { - sym.* = .{ - .st_name = self.global_symbols.items[i].st_name, - .st_value = self.global_symbols.items[i].st_value, - .st_size = self.global_symbols.items[i].st_size, - .st_info = self.global_symbols.items[i].st_info, - .st_other = self.global_symbols.items[i].st_other, - .st_shndx = self.global_symbols.items[i].st_shndx, - }; - if (foreign_endian) { - bswapAllFields(elf.Elf64_Sym, sym); - } - } - try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); - }, - } - } - - fn ptrWidthBytes(self: Elf) u8 { - return switch (self.ptr_width) { - .p32 => 4, - .p64 => 8, - }; - } - - /// The reloc offset for the virtual address of a function in its Line Number Program. - /// Size is a virtual address integer. - const dbg_line_vaddr_reloc_index = 3; - /// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram. - /// Size is a virtual address integer. - const dbg_info_low_pc_reloc_index = 1; - - /// The reloc offset for the line offset of a function from the previous function's line. - /// It's a fixed-size 4-byte ULEB128. - fn getRelocDbgLineOff(self: Elf) usize { - return dbg_line_vaddr_reloc_index + self.ptrWidthBytes() + 1; - } - - fn getRelocDbgFileIndex(self: Elf) usize { - return self.getRelocDbgLineOff() + 5; - } - - fn getRelocDbgInfoSubprogramHighPC(self: Elf) u32 { - return dbg_info_low_pc_reloc_index + self.ptrWidthBytes(); - } - - fn dbgLineNeededHeaderBytes(self: Elf) u32 { - const directory_entry_format_count = 1; - const file_name_entry_format_count = 1; - const directory_count = 1; - const file_name_count = 1; - return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + - directory_count * 8 + file_name_count * 8 + - // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like - // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. - self.base.options.root_pkg.root_src_dir_path.len + - self.base.options.root_pkg.root_src_path.len); - - } - - fn dbgInfoNeededHeaderBytes(self: Elf) u32 { - return 120; - } - - const min_nop_size = 2; - - /// Writes to the file a buffer, prefixed and suffixed by the specified number of - /// bytes of NOPs. Asserts each padding size is at least `min_nop_size` and total padding bytes - /// are less than 126,976 bytes (if this limit is ever reached, this function can be - /// improved to make more than one pwritev call, or the limit can be raised by a fixed - /// amount by increasing the length of `vecs`). - fn pwriteDbgLineNops( - self: *Elf, - prev_padding_size: usize, - buf: []const u8, - next_padding_size: usize, - offset: usize, - ) !void { - const tracy = trace(@src()); - defer tracy.end(); - - const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096; - const three_byte_nop = [3]u8{DW.LNS_advance_pc, 0b1000_0000, 0}; - var vecs: [32]std.os.iovec_const = undefined; - var vec_index: usize = 0; - { - var padding_left = prev_padding_size; - if (padding_left % 2 != 0) { - vecs[vec_index] = .{ - .iov_base = &three_byte_nop, - .iov_len = three_byte_nop.len, - }; - vec_index += 1; - padding_left -= three_byte_nop.len; - } - while (padding_left > page_of_nops.len) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = page_of_nops.len, - }; - vec_index += 1; - padding_left -= page_of_nops.len; - } - if (padding_left > 0) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = padding_left, - }; - vec_index += 1; - } - } - - vecs[vec_index] = .{ - .iov_base = buf.ptr, - .iov_len = buf.len, - }; - vec_index += 1; - - { - var padding_left = next_padding_size; - if (padding_left % 2 != 0) { - vecs[vec_index] = .{ - .iov_base = &three_byte_nop, - .iov_len = three_byte_nop.len, - }; - vec_index += 1; - padding_left -= three_byte_nop.len; - } - while (padding_left > page_of_nops.len) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = page_of_nops.len, - }; - vec_index += 1; - padding_left -= page_of_nops.len; - } - if (padding_left > 0) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = padding_left, - }; - vec_index += 1; - } - } - try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); - } - - /// Writes to the file a buffer, prefixed and suffixed by the specified number of - /// bytes of padding. - fn pwriteDbgInfoNops( - self: *Elf, - prev_padding_size: usize, - buf: []const u8, - next_padding_size: usize, - trailing_zero: bool, - offset: usize, - ) !void { - const tracy = trace(@src()); - defer tracy.end(); - - const page_of_nops = [1]u8{abbrev_pad1} ** 4096; - var vecs: [32]std.os.iovec_const = undefined; - var vec_index: usize = 0; - { - var padding_left = prev_padding_size; - while (padding_left > page_of_nops.len) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = page_of_nops.len, - }; - vec_index += 1; - padding_left -= page_of_nops.len; - } - if (padding_left > 0) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = padding_left, - }; - vec_index += 1; - } - } - - vecs[vec_index] = .{ - .iov_base = buf.ptr, - .iov_len = buf.len, - }; - vec_index += 1; - - { - var padding_left = next_padding_size; - while (padding_left > page_of_nops.len) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = page_of_nops.len, - }; - vec_index += 1; - padding_left -= page_of_nops.len; - } - if (padding_left > 0) { - vecs[vec_index] = .{ - .iov_base = &page_of_nops, - .iov_len = padding_left, - }; - vec_index += 1; - } - } - - if (trailing_zero) { - var zbuf = [1]u8{0}; - vecs[vec_index] = .{ - .iov_base = &zbuf, - .iov_len = zbuf.len, - }; - vec_index += 1; - } - - try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); - } - - }; - + pub const C = @import("link/C.zig"); + pub const Elf = @import("link/Elf.zig"); pub const MachO = @import("link/MachO.zig"); - const Wasm = @import("link/Wasm.zig"); + pub const Wasm = @import("link/Wasm.zig"); }; -/// Saturating multiplication -fn satMul(a: anytype, b: anytype) @TypeOf(a, b) { - const T = @TypeOf(a, b); - return std.math.mul(T, a, b) catch std.math.maxInt(T); -} - -fn bswapAllFields(comptime S: type, ptr: *S) void { - @panic("TODO implement bswapAllFields"); -} - -fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { - return .{ - .p_type = phdr.p_type, - .p_flags = phdr.p_flags, - .p_offset = @intCast(u32, phdr.p_offset), - .p_vaddr = @intCast(u32, phdr.p_vaddr), - .p_paddr = @intCast(u32, phdr.p_paddr), - .p_filesz = @intCast(u32, phdr.p_filesz), - .p_memsz = @intCast(u32, phdr.p_memsz), - .p_align = @intCast(u32, phdr.p_align), - }; -} - -fn sectHeaderTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr { - return .{ - .sh_name = shdr.sh_name, - .sh_type = shdr.sh_type, - .sh_flags = @intCast(u32, shdr.sh_flags), - .sh_addr = @intCast(u32, shdr.sh_addr), - .sh_offset = @intCast(u32, shdr.sh_offset), - .sh_size = @intCast(u32, shdr.sh_size), - .sh_link = shdr.sh_link, - .sh_info = shdr.sh_info, - .sh_addralign = @intCast(u32, shdr.sh_addralign), - .sh_entsize = @intCast(u32, shdr.sh_entsize), - }; -} - pub fn determineMode(options: Options) fs.File.Mode { // On common systems with a 0o022 umask, 0o777 will still result in a file created // with 0o755 permissions, but it works appropriately if the system is configured diff --git a/src-self-hosted/link/C.zig b/src-self-hosted/link/C.zig new file mode 100644 index 0000000000000000000000000000000000000000..69eabd1f8bb8b50b7cdfcb94edc97753c0dad4b1 --- /dev/null +++ b/src-self-hosted/link/C.zig @@ -0,0 +1,101 @@ +const std = @import("std"); +const mem = std.mem; +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const Module = @import("../Module.zig"); +const fs = std.fs; +const codegen = @import("../codegen/c.zig"); +const link = @import("../link.zig"); +const File = link.File; +const C = @This(); + +pub const base_tag: File.Tag = .c; + +base: File, + +header: std.ArrayList(u8), +constants: std.ArrayList(u8), +main: std.ArrayList(u8), + +called: std.StringHashMap(void), +need_stddef: bool = false, +need_stdint: bool = false, +error_msg: *Module.ErrorMsg = undefined, + +pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: link.Options) !*File { + assert(options.object_format == .c); + + const file = try dir.createFile(sub_path, .{ .truncate = true, .read = true, .mode = link.determineMode(options) }); + errdefer file.close(); + + var c_file = try allocator.create(C); + errdefer allocator.destroy(c_file); + + c_file.* = C{ + .base = .{ + .tag = .c, + .options = options, + .file = file, + .allocator = allocator, + }, + .main = std.ArrayList(u8).init(allocator), + .header = std.ArrayList(u8).init(allocator), + .constants = std.ArrayList(u8).init(allocator), + .called = std.StringHashMap(void).init(allocator), + }; + + return &c_file.base; +} + +pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { + self.error_msg = try Module.ErrorMsg.create(self.base.allocator, src, format, args); + return error.AnalysisFail; +} + +pub fn deinit(self: *C) void { + self.main.deinit(); + self.header.deinit(); + self.constants.deinit(); + self.called.deinit(); +} + +pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { + codegen.generate(self, decl) catch |err| { + if (err == error.AnalysisFail) { + try module.failed_decls.put(module.gpa, decl, self.error_msg); + } + return err; + }; +} + +pub fn flush(self: *C, module: *Module) !void { + const writer = self.base.file.?.writer(); + try writer.writeAll(@embedFile("cbe.h")); + var includes = false; + if (self.need_stddef) { + try writer.writeAll("#include \n"); + includes = true; + } + if (self.need_stdint) { + try writer.writeAll("#include \n"); + includes = true; + } + if (includes) { + try writer.writeByte('\n'); + } + if (self.header.items.len > 0) { + try writer.print("{}\n", .{self.header.items}); + } + if (self.constants.items.len > 0) { + try writer.print("{}\n", .{self.constants.items}); + } + if (self.main.items.len > 1) { + const last_two = self.main.items[self.main.items.len - 2 ..]; + if (std.mem.eql(u8, last_two, "\n\n")) { + self.main.items.len -= 1; + } + } + try writer.writeAll(self.main.items); + self.base.file.?.close(); + self.base.file = null; +} diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig new file mode 100644 index 0000000000000000000000000000000000000000..3751411297749dcfb6eb0e6e683bbf0d1d435e74 --- /dev/null +++ b/src-self-hosted/link/Elf.zig @@ -0,0 +1,2583 @@ +const std = @import("std"); +const mem = std.mem; +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const ir = @import("../ir.zig"); +const Module = @import("../Module.zig"); +const fs = std.fs; +const elf = std.elf; +const codegen = @import("../codegen.zig"); +const log = std.log.scoped(.link); +const DW = std.dwarf; +const trace = @import("../tracy.zig").trace; +const leb128 = std.debug.leb; +const Package = @import("../Package.zig"); +const Value = @import("../value.zig").Value; +const Type = @import("../type.zig").Type; +const build_options = @import("build_options"); +const link = @import("../link.zig"); +const File = link.File; +const Elf = @This(); + +const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; +const default_entry_addr = 0x8000000; + +// TODO Turn back on zig fmt when https://github.com/ziglang/zig/issues/5948 is implemented. +// zig fmt: off + +pub const base_tag: File.Tag = .elf; + +base: File, + +ptr_width: enum { p32, p64 }, + +/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. +/// Same order as in the file. +sections: std.ArrayListUnmanaged(elf.Elf64_Shdr) = std.ArrayListUnmanaged(elf.Elf64_Shdr){}, +shdr_table_offset: ?u64 = null, + +/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. +/// Same order as in the file. +program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = std.ArrayListUnmanaged(elf.Elf64_Phdr){}, +phdr_table_offset: ?u64 = null, +/// The index into the program headers of a PT_LOAD program header with Read and Execute flags +phdr_load_re_index: ?u16 = null, +/// The index into the program headers of the global offset table. +/// It needs PT_LOAD and Read flags. +phdr_got_index: ?u16 = null, +entry_addr: ?u64 = null, + +debug_strtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){}, +shstrtab: std.ArrayListUnmanaged(u8) = std.ArrayListUnmanaged(u8){}, +shstrtab_index: ?u16 = null, + +text_section_index: ?u16 = null, +symtab_section_index: ?u16 = null, +got_section_index: ?u16 = null, +debug_info_section_index: ?u16 = null, +debug_abbrev_section_index: ?u16 = null, +debug_str_section_index: ?u16 = null, +debug_aranges_section_index: ?u16 = null, +debug_line_section_index: ?u16 = null, + +debug_abbrev_table_offset: ?u64 = null, + +/// The same order as in the file. ELF requires global symbols to all be after the +/// local symbols, they cannot be mixed. So we must buffer all the global symbols and +/// write them at the end. These are only the local symbols. The length of this array +/// is the value used for sh_info in the .symtab section. +local_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, +global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, + +local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, +global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, +offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, + +/// Same order as in the file. The value is the absolute vaddr value. +/// If the vaddr of the executable program header changes, the entire +/// offset table needs to be rewritten. +offset_table: std.ArrayListUnmanaged(u64) = .{}, + +phdr_table_dirty: bool = false, +shdr_table_dirty: bool = false, +shstrtab_dirty: bool = false, +debug_strtab_dirty: bool = false, +offset_table_count_dirty: bool = false, +debug_abbrev_section_dirty: bool = false, +debug_aranges_section_dirty: bool = false, + +debug_info_header_dirty: bool = false, +debug_line_header_dirty: bool = false, + +error_flags: File.ErrorFlags = File.ErrorFlags{}, + +/// A list of text blocks that have surplus capacity. This list can have false +/// positives, as functions grow and shrink over time, only sometimes being added +/// or removed from the freelist. +/// +/// A text block has surplus capacity when its overcapacity value is greater than +/// minimum_text_block_size * alloc_num / alloc_den. That is, when it has so +/// much extra capacity, that we could fit a small new symbol in it, itself with +/// ideal_capacity or more. +/// +/// Ideal capacity is defined by size * alloc_num / alloc_den. +/// +/// Overcapacity is measured by actual_capacity - ideal_capacity. Note that +/// overcapacity can be negative. A simple way to have negative overcapacity is to +/// allocate a fresh text block, which will have ideal capacity, and then grow it +/// by 1 byte. It will then have -1 overcapacity. +text_block_free_list: std.ArrayListUnmanaged(*TextBlock) = .{}, +last_text_block: ?*TextBlock = null, + +/// A list of `SrcFn` whose Line Number Programs have surplus capacity. +/// This is the same concept as `text_block_free_list`; see those doc comments. +dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{}, +dbg_line_fn_first: ?*SrcFn = null, +dbg_line_fn_last: ?*SrcFn = null, + +/// A list of `TextBlock` whose corresponding .debug_info tags have surplus capacity. +/// This is the same concept as `text_block_free_list`; see those doc comments. +dbg_info_decl_free_list: std.AutoHashMapUnmanaged(*TextBlock, void) = .{}, +dbg_info_decl_first: ?*TextBlock = null, +dbg_info_decl_last: ?*TextBlock = null, + +/// `alloc_num / alloc_den` is the factor of padding when allocating. +const alloc_num = 4; +const alloc_den = 3; + +/// In order for a slice of bytes to be considered eligible to keep metadata pointing at +/// it as a possible place to put new symbols, it must have enough room for this many bytes +/// (plus extra for reserved capacity). +const minimum_text_block_size = 64; +const min_text_capacity = minimum_text_block_size * alloc_num / alloc_den; + +pub const TextBlock = struct { + /// Each decl always gets a local symbol with the fully qualified name. + /// The vaddr and size are found here directly. + /// The file offset is found by computing the vaddr offset from the section vaddr + /// the symbol references, and adding that to the file offset of the section. + /// If this field is 0, it means the codegen size = 0 and there is no symbol or + /// offset table entry. + local_sym_index: u32, + /// This field is undefined for symbols with size = 0. + offset_table_index: u32, + /// Points to the previous and next neighbors, based on the `text_offset`. + /// This can be used to find, for example, the capacity of this `TextBlock`. + prev: ?*TextBlock, + next: ?*TextBlock, + + /// Previous/next linked list pointers. This value is `next ^ prev`. + /// This is the linked list node for this Decl's corresponding .debug_info tag. + dbg_info_prev: ?*TextBlock, + dbg_info_next: ?*TextBlock, + /// Offset into .debug_info pointing to the tag for this Decl. + dbg_info_off: u32, + /// Size of the .debug_info tag for this Decl, not including padding. + dbg_info_len: u32, + + pub const empty = TextBlock{ + .local_sym_index = 0, + .offset_table_index = undefined, + .prev = null, + .next = null, + .dbg_info_prev = null, + .dbg_info_next = null, + .dbg_info_off = undefined, + .dbg_info_len = undefined, + }; + + /// Returns how much room there is to grow in virtual address space. + /// File offset relocation happens transparently, so it is not included in + /// this calculation. + fn capacity(self: TextBlock, elf_file: Elf) u64 { + const self_sym = elf_file.local_symbols.items[self.local_sym_index]; + if (self.next) |next| { + const next_sym = elf_file.local_symbols.items[next.local_sym_index]; + return next_sym.st_value - self_sym.st_value; + } else { + // We are the last block. The capacity is limited only by virtual address space. + return std.math.maxInt(u32) - self_sym.st_value; + } + } + + fn freeListEligible(self: TextBlock, elf_file: Elf) bool { + // No need to keep a free list node for the last block. + const next = self.next orelse return false; + const self_sym = elf_file.local_symbols.items[self.local_sym_index]; + const next_sym = elf_file.local_symbols.items[next.local_sym_index]; + const cap = next_sym.st_value - self_sym.st_value; + const ideal_cap = self_sym.st_size * alloc_num / alloc_den; + if (cap <= ideal_cap) return false; + const surplus = cap - ideal_cap; + return surplus >= min_text_capacity; + } +}; + +pub const Export = struct { + sym_index: ?u32 = null, +}; + +pub const SrcFn = struct { + /// Offset from the beginning of the Debug Line Program header that contains this function. + off: u32, + /// Size of the line number program component belonging to this function, not + /// including padding. + len: u32, + + /// Points to the previous and next neighbors, based on the offset from .debug_line. + /// This can be used to find, for example, the capacity of this `SrcFn`. + prev: ?*SrcFn, + next: ?*SrcFn, + + pub const empty: SrcFn = .{ + .off = 0, + .len = 0, + .prev = null, + .next = null, + }; +}; + +pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: link.Options) !*File { + assert(options.object_format == .elf); + + const file = try dir.createFile(sub_path, .{ .truncate = false, .read = true, .mode = link.determineMode(options) }); + errdefer file.close(); + + var elf_file = try allocator.create(Elf); + errdefer allocator.destroy(elf_file); + + elf_file.* = openFile(allocator, file, options) catch |err| switch (err) { + error.IncrFailed => try createFile(allocator, file, options), + else => |e| return e, + }; + + return &elf_file.base; +} + +/// Returns error.IncrFailed if incremental update could not be performed. +fn openFile(allocator: *Allocator, file: fs.File, options: link.Options) !Elf { + switch (options.output_mode) { + .Exe => {}, + .Obj => {}, + .Lib => return error.IncrFailed, + } + var self: Elf = .{ + .base = .{ + .file = file, + .tag = .elf, + .options = options, + .allocator = allocator, + }, + .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { + 32 => .p32, + 64 => .p64, + else => return error.UnsupportedELFArchitecture, + }, + }; + errdefer self.deinit(); + + // TODO implement reading the elf file + return error.IncrFailed; + //try self.populateMissingMetadata(); + //return self; +} + +/// Truncates the existing file contents and overwrites the contents. +/// Returns an error if `file` is not already open with +read +write +seek abilities. +fn createFile(allocator: *Allocator, file: fs.File, options: link.Options) !Elf { + switch (options.output_mode) { + .Exe => {}, + .Obj => {}, + .Lib => return error.TODOImplementWritingLibFiles, + } + var self: Elf = .{ + .base = .{ + .tag = .elf, + .options = options, + .allocator = allocator, + .file = file, + }, + .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) { + 32 => .p32, + 64 => .p64, + else => return error.UnsupportedELFArchitecture, + }, + .shdr_table_dirty = true, + }; + errdefer self.deinit(); + + // Index 0 is always a null symbol. + try self.local_symbols.append(allocator, .{ + .st_name = 0, + .st_info = 0, + .st_other = 0, + .st_shndx = 0, + .st_value = 0, + .st_size = 0, + }); + + // There must always be a null section in index 0 + try self.sections.append(allocator, .{ + .sh_name = 0, + .sh_type = elf.SHT_NULL, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = 0, + .sh_size = 0, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = 0, + .sh_entsize = 0, + }); + + try self.populateMissingMetadata(); + + return self; +} + +pub fn deinit(self: *Elf) void { + self.sections.deinit(self.base.allocator); + self.program_headers.deinit(self.base.allocator); + self.shstrtab.deinit(self.base.allocator); + self.debug_strtab.deinit(self.base.allocator); + self.local_symbols.deinit(self.base.allocator); + self.global_symbols.deinit(self.base.allocator); + self.global_symbol_free_list.deinit(self.base.allocator); + self.local_symbol_free_list.deinit(self.base.allocator); + self.offset_table_free_list.deinit(self.base.allocator); + self.text_block_free_list.deinit(self.base.allocator); + self.dbg_line_fn_free_list.deinit(self.base.allocator); + self.dbg_info_decl_free_list.deinit(self.base.allocator); + self.offset_table.deinit(self.base.allocator); +} + +pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl) u64 { + assert(decl.link.elf.local_sym_index != 0); + return self.local_symbols.items[decl.link.elf.local_sym_index].st_value; +} + +fn getDebugLineProgramOff(self: Elf) u32 { + return self.dbg_line_fn_first.?.off; +} + +fn getDebugLineProgramEnd(self: Elf) u32 { + return self.dbg_line_fn_last.?.off + self.dbg_line_fn_last.?.len; +} + +/// Returns end pos of collision, if any. +fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { + const small_ptr = self.base.options.target.cpu.arch.ptrBitWidth() == 32; + const ehdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Ehdr) else @sizeOf(elf.Elf64_Ehdr); + if (start < ehdr_size) + return ehdr_size; + + const end = start + satMul(size, alloc_num) / alloc_den; + + if (self.shdr_table_offset) |off| { + const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); + const tight_size = self.sections.items.len * shdr_size; + const increased_size = satMul(tight_size, alloc_num) / alloc_den; + const test_end = off + increased_size; + if (end > off and start < test_end) { + return test_end; + } + } + + if (self.phdr_table_offset) |off| { + const phdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Phdr) else @sizeOf(elf.Elf64_Phdr); + const tight_size = self.sections.items.len * phdr_size; + const increased_size = satMul(tight_size, alloc_num) / alloc_den; + const test_end = off + increased_size; + if (end > off and start < test_end) { + return test_end; + } + } + + for (self.sections.items) |section| { + const increased_size = satMul(section.sh_size, alloc_num) / alloc_den; + const test_end = section.sh_offset + increased_size; + if (end > section.sh_offset and start < test_end) { + return test_end; + } + } + for (self.program_headers.items) |program_header| { + const increased_size = satMul(program_header.p_filesz, alloc_num) / alloc_den; + const test_end = program_header.p_offset + increased_size; + if (end > program_header.p_offset and start < test_end) { + return test_end; + } + } + return null; +} + +fn allocatedSize(self: *Elf, start: u64) u64 { + if (start == 0) + return 0; + var min_pos: u64 = std.math.maxInt(u64); + if (self.shdr_table_offset) |off| { + if (off > start and off < min_pos) min_pos = off; + } + if (self.phdr_table_offset) |off| { + if (off > start and off < min_pos) min_pos = off; + } + for (self.sections.items) |section| { + if (section.sh_offset <= start) continue; + if (section.sh_offset < min_pos) min_pos = section.sh_offset; + } + for (self.program_headers.items) |program_header| { + if (program_header.p_offset <= start) continue; + if (program_header.p_offset < min_pos) min_pos = program_header.p_offset; + } + return min_pos - start; +} + +fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u16) u64 { + var start: u64 = 0; + while (self.detectAllocCollision(start, object_size)) |item_end| { + start = mem.alignForwardGeneric(u64, item_end, min_alignment); + } + return start; +} + +/// TODO Improve this to use a table. +fn makeString(self: *Elf, bytes: []const u8) !u32 { + try self.shstrtab.ensureCapacity(self.base.allocator, self.shstrtab.items.len + bytes.len + 1); + const result = self.shstrtab.items.len; + self.shstrtab.appendSliceAssumeCapacity(bytes); + self.shstrtab.appendAssumeCapacity(0); + return @intCast(u32, result); +} + +/// TODO Improve this to use a table. +fn makeDebugString(self: *Elf, bytes: []const u8) !u32 { + try self.debug_strtab.ensureCapacity(self.base.allocator, self.debug_strtab.items.len + bytes.len + 1); + const result = self.debug_strtab.items.len; + self.debug_strtab.appendSliceAssumeCapacity(bytes); + self.debug_strtab.appendAssumeCapacity(0); + return @intCast(u32, result); +} + +fn getString(self: *Elf, str_off: u32) []const u8 { + assert(str_off < self.shstrtab.items.len); + return mem.spanZ(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off)); +} + +fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 { + const existing_name = self.getString(old_str_off); + if (mem.eql(u8, existing_name, new_name)) { + return old_str_off; + } + return self.makeString(new_name); +} + +pub fn populateMissingMetadata(self: *Elf) !void { + const small_ptr = switch (self.ptr_width) { + .p32 => true, + .p64 => false, + }; + const ptr_size: u8 = self.ptrWidthBytes(); + if (self.phdr_load_re_index == null) { + self.phdr_load_re_index = @intCast(u16, self.program_headers.items.len); + const file_size = self.base.options.program_code_size_hint; + const p_align = 0x1000; + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); + try self.program_headers.append(self.base.allocator, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = default_entry_addr, + .p_paddr = default_entry_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_X | elf.PF_R, + }); + self.entry_addr = null; + self.phdr_table_dirty = true; + } + if (self.phdr_got_index == null) { + self.phdr_got_index = @intCast(u16, self.program_headers.items.len); + const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; + // We really only need ptr alignment but since we are using PROGBITS, linux requires + // page align. + const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size); + const off = self.findFreeSpace(file_size, p_align); + log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); + // TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at. + // we'll need to re-use that function anyway, in case the GOT grows and overlaps something + // else in virtual memory. + const default_got_addr = if (ptr_size == 2) @as(u32, 0x8000) else 0x4000000; + try self.program_headers.append(self.base.allocator, .{ + .p_type = elf.PT_LOAD, + .p_offset = off, + .p_filesz = file_size, + .p_vaddr = default_got_addr, + .p_paddr = default_got_addr, + .p_memsz = file_size, + .p_align = p_align, + .p_flags = elf.PF_R, + }); + self.phdr_table_dirty = true; + } + if (self.shstrtab_index == null) { + self.shstrtab_index = @intCast(u16, self.sections.items.len); + assert(self.shstrtab.items.len == 0); + try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0 + const off = self.findFreeSpace(self.shstrtab.items.len, 1); + log.debug("found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len }); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".shstrtab"), + .sh_type = elf.SHT_STRTAB, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = self.shstrtab.items.len, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = 1, + .sh_entsize = 0, + }); + self.shstrtab_dirty = true; + self.shdr_table_dirty = true; + } + if (self.text_section_index == null) { + self.text_section_index = @intCast(u16, self.sections.items.len); + const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; + + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".text"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, + .sh_addr = phdr.p_vaddr, + .sh_offset = phdr.p_offset, + .sh_size = phdr.p_filesz, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = phdr.p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + } + if (self.got_section_index == null) { + self.got_section_index = @intCast(u16, self.sections.items.len); + const phdr = &self.program_headers.items[self.phdr_got_index.?]; + + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".got"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = elf.SHF_ALLOC, + .sh_addr = phdr.p_vaddr, + .sh_offset = phdr.p_offset, + .sh_size = phdr.p_filesz, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = phdr.p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + } + if (self.symtab_section_index == null) { + self.symtab_section_index = @intCast(u16, self.sections.items.len); + const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym); + const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym); + const file_size = self.base.options.symbol_count_hint * each_size; + const off = self.findFreeSpace(file_size, min_align); + log.debug("found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); + + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".symtab"), + .sh_type = elf.SHT_SYMTAB, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = file_size, + // The section header index of the associated string table. + .sh_link = self.shstrtab_index.?, + .sh_info = @intCast(u32, self.local_symbols.items.len), + .sh_addralign = min_align, + .sh_entsize = each_size, + }); + self.shdr_table_dirty = true; + try self.writeSymbol(0); + } + if (self.debug_str_section_index == null) { + self.debug_str_section_index = @intCast(u16, self.sections.items.len); + assert(self.debug_strtab.items.len == 0); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".debug_str"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS, + .sh_addr = 0, + .sh_offset = 0, + .sh_size = self.debug_strtab.items.len, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = 1, + .sh_entsize = 1, + }); + self.debug_strtab_dirty = true; + self.shdr_table_dirty = true; + } + if (self.debug_info_section_index == null) { + self.debug_info_section_index = @intCast(u16, self.sections.items.len); + + const file_size_hint = 200; + const p_align = 1; + const off = self.findFreeSpace(file_size_hint, p_align); + log.debug("found .debug_info free space 0x{x} to 0x{x}\n", .{ + off, + off + file_size_hint, + }); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".debug_info"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = file_size_hint, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + self.debug_info_header_dirty = true; + } + if (self.debug_abbrev_section_index == null) { + self.debug_abbrev_section_index = @intCast(u16, self.sections.items.len); + + const file_size_hint = 128; + const p_align = 1; + const off = self.findFreeSpace(file_size_hint, p_align); + log.debug("found .debug_abbrev free space 0x{x} to 0x{x}\n", .{ + off, + off + file_size_hint, + }); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".debug_abbrev"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = file_size_hint, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + self.debug_abbrev_section_dirty = true; + } + if (self.debug_aranges_section_index == null) { + self.debug_aranges_section_index = @intCast(u16, self.sections.items.len); + + const file_size_hint = 160; + const p_align = 16; + const off = self.findFreeSpace(file_size_hint, p_align); + log.debug("found .debug_aranges free space 0x{x} to 0x{x}\n", .{ + off, + off + file_size_hint, + }); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".debug_aranges"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = file_size_hint, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + self.debug_aranges_section_dirty = true; + } + if (self.debug_line_section_index == null) { + self.debug_line_section_index = @intCast(u16, self.sections.items.len); + + const file_size_hint = 250; + const p_align = 1; + const off = self.findFreeSpace(file_size_hint, p_align); + log.debug("found .debug_line free space 0x{x} to 0x{x}\n", .{ + off, + off + file_size_hint, + }); + try self.sections.append(self.base.allocator, .{ + .sh_name = try self.makeString(".debug_line"), + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = off, + .sh_size = file_size_hint, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = p_align, + .sh_entsize = 0, + }); + self.shdr_table_dirty = true; + self.debug_line_header_dirty = true; + } + const shsize: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Shdr), + .p64 => @sizeOf(elf.Elf64_Shdr), + }; + const shalign: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Shdr), + .p64 => @alignOf(elf.Elf64_Shdr), + }; + if (self.shdr_table_offset == null) { + self.shdr_table_offset = self.findFreeSpace(self.sections.items.len * shsize, shalign); + self.shdr_table_dirty = true; + } + const phsize: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Phdr), + .p64 => @sizeOf(elf.Elf64_Phdr), + }; + const phalign: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Phdr), + .p64 => @alignOf(elf.Elf64_Phdr), + }; + if (self.phdr_table_offset == null) { + self.phdr_table_offset = self.findFreeSpace(self.program_headers.items.len * phsize, phalign); + self.phdr_table_dirty = true; + } + { + // Iterate over symbols, populating free_list and last_text_block. + if (self.local_symbols.items.len != 1) { + @panic("TODO implement setting up free_list and last_text_block from existing ELF file"); + } + // We are starting with an empty file. The default values are correct, null and empty list. + } +} + +pub const abbrev_compile_unit = 1; +pub const abbrev_subprogram = 2; +pub const abbrev_subprogram_retvoid = 3; +pub const abbrev_base_type = 4; +pub const abbrev_pad1 = 5; +pub const abbrev_parameter = 6; + +/// Commit pending changes and write headers. +pub fn flush(self: *Elf, module: *Module) !void { + const target_endian = self.base.options.target.cpu.arch.endian(); + const foreign_endian = target_endian != std.Target.current.cpu.arch.endian(); + const ptr_width_bytes: u8 = self.ptrWidthBytes(); + const init_len_size: usize = switch (self.ptr_width) { + .p32 => 4, + .p64 => 12, + }; + + // Unfortunately these have to be buffered and done at the end because ELF does not allow + // mixing local and global symbols within a symbol table. + try self.writeAllGlobalSymbols(); + + if (self.debug_abbrev_section_dirty) { + const debug_abbrev_sect = &self.sections.items[self.debug_abbrev_section_index.?]; + + // These are LEB encoded but since the values are all less than 127 + // we can simply append these bytes. + const abbrev_buf = [_]u8{ + abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header + DW.AT_stmt_list, DW.FORM_sec_offset, DW.AT_low_pc, + DW.FORM_addr, DW.AT_high_pc, DW.FORM_addr, + DW.AT_name, DW.FORM_strp, DW.AT_comp_dir, + DW.FORM_strp, DW.AT_producer, DW.FORM_strp, + DW.AT_language, DW.FORM_data2, 0, + 0, // table sentinel + abbrev_subprogram, DW.TAG_subprogram, + DW.CHILDREN_yes, // header + DW.AT_low_pc, DW.FORM_addr, + DW.AT_high_pc, DW.FORM_data4, DW.AT_type, + DW.FORM_ref4, DW.AT_name, DW.FORM_string, + 0, 0, // table sentinel + abbrev_subprogram_retvoid, + DW.TAG_subprogram, DW.CHILDREN_yes, // header + DW.AT_low_pc, + DW.FORM_addr, DW.AT_high_pc, DW.FORM_data4, + DW.AT_name, DW.FORM_string, 0, + 0, // table sentinel + abbrev_base_type, DW.TAG_base_type, + DW.CHILDREN_no, // header + DW.AT_encoding, DW.FORM_data1, + DW.AT_byte_size, DW.FORM_data1, DW.AT_name, + DW.FORM_string, 0, 0, // table sentinel + + abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header + 0, 0, // table sentinel + abbrev_parameter, + DW.TAG_formal_parameter, DW.CHILDREN_no, // header + DW.AT_location, + DW.FORM_exprloc, DW.AT_type, DW.FORM_ref4, + DW.AT_name, DW.FORM_string, 0, + 0, // table sentinel + 0, 0, + 0, // section sentinel + }; + + const needed_size = abbrev_buf.len; + const allocated_size = self.allocatedSize(debug_abbrev_sect.sh_offset); + if (needed_size > allocated_size) { + debug_abbrev_sect.sh_size = 0; // free the space + debug_abbrev_sect.sh_offset = self.findFreeSpace(needed_size, 1); + } + debug_abbrev_sect.sh_size = needed_size; + log.debug(".debug_abbrev start=0x{x} end=0x{x}\n", .{ + debug_abbrev_sect.sh_offset, + debug_abbrev_sect.sh_offset + needed_size, + }); + + const abbrev_offset = 0; + self.debug_abbrev_table_offset = abbrev_offset; + try self.base.file.?.pwriteAll(&abbrev_buf, debug_abbrev_sect.sh_offset + abbrev_offset); + if (!self.shdr_table_dirty) { + // Then it won't get written with the others and we need to do it. + try self.writeSectHeader(self.debug_abbrev_section_index.?); + } + + self.debug_abbrev_section_dirty = false; + } + + if (self.debug_info_header_dirty) debug_info: { + // If this value is null it means there is an error in the module; + // leave debug_info_header_dirty=true. + const first_dbg_info_decl = self.dbg_info_decl_first orelse break :debug_info; + const last_dbg_info_decl = self.dbg_info_decl_last.?; + const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; + + var di_buf = std.ArrayList(u8).init(self.base.allocator); + defer di_buf.deinit(); + + // We have a function to compute the upper bound size, because it's needed + // for determining where to put the offset of the first `LinkBlock`. + try di_buf.ensureCapacity(self.dbgInfoNeededHeaderBytes()); + + // initial length - length of the .debug_info contribution for this compilation unit, + // not including the initial length itself. + // We have to come back and write it later after we know the size. + const after_init_len = di_buf.items.len + init_len_size; + // +1 for the final 0 that ends the compilation unit children. + const dbg_info_end = last_dbg_info_decl.dbg_info_off + last_dbg_info_decl.dbg_info_len + 1; + const init_len = dbg_info_end - after_init_len; + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len), target_endian); + }, + .p64 => { + di_buf.appendNTimesAssumeCapacity(0xff, 4); + mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), init_len, target_endian); + }, + } + mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // DWARF version + const abbrev_offset = self.debug_abbrev_table_offset.?; + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, abbrev_offset), target_endian); + di_buf.appendAssumeCapacity(4); // address size + }, + .p64 => { + mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), abbrev_offset, target_endian); + di_buf.appendAssumeCapacity(8); // address size + }, + } + // Write the form for the compile unit, which must match the abbrev table above. + const name_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_path); + const comp_dir_strp = try self.makeDebugString(self.base.options.root_pkg.root_src_dir_path); + const producer_strp = try self.makeDebugString(producer_string); + // Currently only one compilation unit is supported, so the address range is simply + // identical to the main program header virtual address and memory size. + const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; + const low_pc = text_phdr.p_vaddr; + const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; + + di_buf.appendAssumeCapacity(abbrev_compile_unit); + self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT_stmt_list, DW.FORM_sec_offset + self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc); + self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc); + self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp); + self.writeDwarfAddrAssumeCapacity(&di_buf, comp_dir_strp); + self.writeDwarfAddrAssumeCapacity(&di_buf, producer_strp); + // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: + // http://dwarfstd.org/ShowIssue.php?issue=171115.1 + // Until then we say it is C99. + mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99, target_endian); + + if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { + // Move the first N decls to the end to make more padding for the header. + @panic("TODO: handle .debug_info header exceeding its padding"); + } + const jmp_amt = first_dbg_info_decl.dbg_info_off - di_buf.items.len; + try self.pwriteDbgInfoNops(0, di_buf.items, jmp_amt, false, debug_info_sect.sh_offset); + self.debug_info_header_dirty = false; + } + + if (self.debug_aranges_section_dirty) { + const debug_aranges_sect = &self.sections.items[self.debug_aranges_section_index.?]; + + var di_buf = std.ArrayList(u8).init(self.base.allocator); + defer di_buf.deinit(); + + // Enough for all the data without resizing. When support for more compilation units + // is added, the size of this section will become more variable. + try di_buf.ensureCapacity(100); + + // initial length - length of the .debug_aranges contribution for this compilation unit, + // not including the initial length itself. + // We have to come back and write it later after we know the size. + const init_len_index = di_buf.items.len; + di_buf.items.len += init_len_size; + const after_init_len = di_buf.items.len; + mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 2, target_endian); // version + // When more than one compilation unit is supported, this will be the offset to it. + // For now it is always at offset 0 in .debug_info. + self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // .debug_info offset + di_buf.appendAssumeCapacity(ptr_width_bytes); // address_size + di_buf.appendAssumeCapacity(0); // segment_selector_size + + const end_header_offset = di_buf.items.len; + const begin_entries_offset = mem.alignForward(end_header_offset, ptr_width_bytes * 2); + di_buf.appendNTimesAssumeCapacity(0, begin_entries_offset - end_header_offset); + + // Currently only one compilation unit is supported, so the address range is simply + // identical to the main program header virtual address and memory size. + const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; + self.writeDwarfAddrAssumeCapacity(&di_buf, text_phdr.p_vaddr); + self.writeDwarfAddrAssumeCapacity(&di_buf, text_phdr.p_memsz); + + // Sentinel. + self.writeDwarfAddrAssumeCapacity(&di_buf, 0); + self.writeDwarfAddrAssumeCapacity(&di_buf, 0); + + // Go back and populate the initial length. + const init_len = di_buf.items.len - after_init_len; + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, di_buf.items[init_len_index..][0..4], @intCast(u32, init_len), target_endian); + }, + .p64 => { + // initial length - length of the .debug_aranges contribution for this compilation unit, + // not including the initial length itself. + di_buf.items[init_len_index..][0..4].* = [_]u8{ 0xff, 0xff, 0xff, 0xff }; + mem.writeInt(u64, di_buf.items[init_len_index + 4 ..][0..8], init_len, target_endian); + }, + } + + const needed_size = di_buf.items.len; + const allocated_size = self.allocatedSize(debug_aranges_sect.sh_offset); + if (needed_size > allocated_size) { + debug_aranges_sect.sh_size = 0; // free the space + debug_aranges_sect.sh_offset = self.findFreeSpace(needed_size, 16); + } + debug_aranges_sect.sh_size = needed_size; + log.debug(".debug_aranges start=0x{x} end=0x{x}\n", .{ + debug_aranges_sect.sh_offset, + debug_aranges_sect.sh_offset + needed_size, + }); + + try self.base.file.?.pwriteAll(di_buf.items, debug_aranges_sect.sh_offset); + if (!self.shdr_table_dirty) { + // Then it won't get written with the others and we need to do it. + try self.writeSectHeader(self.debug_aranges_section_index.?); + } + + self.debug_aranges_section_dirty = false; + } + if (self.debug_line_header_dirty) debug_line: { + if (self.dbg_line_fn_first == null) { + break :debug_line; // Error in module; leave debug_line_header_dirty=true. + } + const dbg_line_prg_off = self.getDebugLineProgramOff(); + const dbg_line_prg_end = self.getDebugLineProgramEnd(); + assert(dbg_line_prg_end != 0); + + const debug_line_sect = &self.sections.items[self.debug_line_section_index.?]; + + var di_buf = std.ArrayList(u8).init(self.base.allocator); + defer di_buf.deinit(); + + // The size of this header is variable, depending on the number of directories, + // files, and padding. We have a function to compute the upper bound size, however, + // because it's needed for determining where to put the offset of the first `SrcFn`. + try di_buf.ensureCapacity(self.dbgLineNeededHeaderBytes()); + + // initial length - length of the .debug_line contribution for this compilation unit, + // not including the initial length itself. + const after_init_len = di_buf.items.len + init_len_size; + const init_len = dbg_line_prg_end - after_init_len; + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len), target_endian); + }, + .p64 => { + di_buf.appendNTimesAssumeCapacity(0xff, 4); + mem.writeInt(u64, di_buf.addManyAsArrayAssumeCapacity(8), init_len, target_endian); + }, + } + + mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // version + + // Empirically, debug info consumers do not respect this field, or otherwise + // consider it to be an error when it does not point exactly to the end of the header. + // Therefore we rely on the NOP jump at the beginning of the Line Number Program for + // padding rather than this field. + const before_header_len = di_buf.items.len; + di_buf.items.len += ptr_width_bytes; // We will come back and write this. + const after_header_len = di_buf.items.len; + + const opcode_base = DW.LNS_set_isa + 1; + di_buf.appendSliceAssumeCapacity(&[_]u8{ + 1, // minimum_instruction_length + 1, // maximum_operations_per_instruction + 1, // default_is_stmt + 1, // line_base (signed) + 1, // line_range + opcode_base, + + // Standard opcode lengths. The number of items here is based on `opcode_base`. + // The value is the number of LEB128 operands the instruction takes. + 0, // `DW.LNS_copy` + 1, // `DW.LNS_advance_pc` + 1, // `DW.LNS_advance_line` + 1, // `DW.LNS_set_file` + 1, // `DW.LNS_set_column` + 0, // `DW.LNS_negate_stmt` + 0, // `DW.LNS_set_basic_block` + 0, // `DW.LNS_const_add_pc` + 1, // `DW.LNS_fixed_advance_pc` + 0, // `DW.LNS_set_prologue_end` + 0, // `DW.LNS_set_epilogue_begin` + 1, // `DW.LNS_set_isa` + + 0, // include_directories (none except the compilation unit cwd) + }); + // file_names[0] + di_buf.appendSliceAssumeCapacity(self.base.options.root_pkg.root_src_path); // relative path name + di_buf.appendSliceAssumeCapacity(&[_]u8{ + 0, // null byte for the relative path name + 0, // directory_index + 0, // mtime (TODO supply this) + 0, // file size bytes (TODO supply this) + 0, // file_names sentinel + }); + + const header_len = di_buf.items.len - after_header_len; + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, di_buf.items[before_header_len..][0..4], @intCast(u32, header_len), target_endian); + }, + .p64 => { + mem.writeInt(u64, di_buf.items[before_header_len..][0..8], header_len, target_endian); + }, + } + + // We use NOPs because consumers empirically do not respect the header length field. + if (di_buf.items.len > dbg_line_prg_off) { + // Move the first N files to the end to make more padding for the header. + @panic("TODO: handle .debug_line header exceeding its padding"); + } + const jmp_amt = dbg_line_prg_off - di_buf.items.len; + try self.pwriteDbgLineNops(0, di_buf.items, jmp_amt, debug_line_sect.sh_offset); + self.debug_line_header_dirty = false; + } + + if (self.phdr_table_dirty) { + const phsize: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Phdr), + .p64 => @sizeOf(elf.Elf64_Phdr), + }; + const phalign: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Phdr), + .p64 => @alignOf(elf.Elf64_Phdr), + }; + const allocated_size = self.allocatedSize(self.phdr_table_offset.?); + const needed_size = self.program_headers.items.len * phsize; + + if (needed_size > allocated_size) { + self.phdr_table_offset = null; // free the space + self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); + } + + switch (self.ptr_width) { + .p32 => { + const buf = try self.base.allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*phdr, i| { + phdr.* = progHeaderTo32(self.program_headers.items[i]); + if (foreign_endian) { + bswapAllFields(elf.Elf32_Phdr, phdr); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); + }, + .p64 => { + const buf = try self.base.allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*phdr, i| { + phdr.* = self.program_headers.items[i]; + if (foreign_endian) { + bswapAllFields(elf.Elf64_Phdr, phdr); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); + }, + } + self.phdr_table_dirty = false; + } + + { + const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; + if (self.shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { + const allocated_size = self.allocatedSize(shstrtab_sect.sh_offset); + const needed_size = self.shstrtab.items.len; + + if (needed_size > allocated_size) { + shstrtab_sect.sh_size = 0; // free the space + shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); + } + shstrtab_sect.sh_size = needed_size; + log.debug("writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size }); + + try self.base.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); + if (!self.shdr_table_dirty) { + // Then it won't get written with the others and we need to do it. + try self.writeSectHeader(self.shstrtab_index.?); + } + self.shstrtab_dirty = false; + } + } + { + const debug_strtab_sect = &self.sections.items[self.debug_str_section_index.?]; + if (self.debug_strtab_dirty or self.debug_strtab.items.len != debug_strtab_sect.sh_size) { + const allocated_size = self.allocatedSize(debug_strtab_sect.sh_offset); + const needed_size = self.debug_strtab.items.len; + + if (needed_size > allocated_size) { + debug_strtab_sect.sh_size = 0; // free the space + debug_strtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); + } + debug_strtab_sect.sh_size = needed_size; + log.debug("debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size }); + + try self.base.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset); + if (!self.shdr_table_dirty) { + // Then it won't get written with the others and we need to do it. + try self.writeSectHeader(self.debug_str_section_index.?); + } + self.debug_strtab_dirty = false; + } + } + if (self.shdr_table_dirty) { + const shsize: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Shdr), + .p64 => @sizeOf(elf.Elf64_Shdr), + }; + const shalign: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Shdr), + .p64 => @alignOf(elf.Elf64_Shdr), + }; + const allocated_size = self.allocatedSize(self.shdr_table_offset.?); + const needed_size = self.sections.items.len * shsize; + + if (needed_size > allocated_size) { + self.shdr_table_offset = null; // free the space + self.shdr_table_offset = self.findFreeSpace(needed_size, shalign); + } + + switch (self.ptr_width) { + .p32 => { + const buf = try self.base.allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*shdr, i| { + shdr.* = sectHeaderTo32(self.sections.items[i]); + log.debug("writing section {}\n", .{shdr.*}); + if (foreign_endian) { + bswapAllFields(elf.Elf32_Shdr, shdr); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); + }, + .p64 => { + const buf = try self.base.allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*shdr, i| { + shdr.* = self.sections.items[i]; + log.debug("writing section {}\n", .{shdr.*}); + if (foreign_endian) { + bswapAllFields(elf.Elf64_Shdr, shdr); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); + }, + } + self.shdr_table_dirty = false; + } + if (self.entry_addr == null and self.base.options.output_mode == .Exe) { + log.debug("flushing. no_entry_point_found = true\n", .{}); + self.error_flags.no_entry_point_found = true; + } else { + log.debug("flushing. no_entry_point_found = false\n", .{}); + self.error_flags.no_entry_point_found = false; + try self.writeElfHeader(); + } + + // The point of flush() is to commit changes, so in theory, nothing should + // be dirty after this. However, it is possible for some things to remain + // dirty because they fail to be written in the event of compile errors, + // such as debug_line_header_dirty and debug_info_header_dirty. + assert(!self.debug_abbrev_section_dirty); + assert(!self.debug_aranges_section_dirty); + assert(!self.phdr_table_dirty); + assert(!self.shdr_table_dirty); + assert(!self.shstrtab_dirty); + assert(!self.debug_strtab_dirty); +} + +fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { + const target_endian = self.base.options.target.cpu.arch.endian(); + switch (self.ptr_width) { + .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, addr), target_endian), + .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), + } +} + +fn writeElfHeader(self: *Elf) !void { + var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined; + + var index: usize = 0; + hdr_buf[0..4].* = "\x7fELF".*; + index += 4; + + hdr_buf[index] = switch (self.ptr_width) { + .p32 => elf.ELFCLASS32, + .p64 => elf.ELFCLASS64, + }; + index += 1; + + const endian = self.base.options.target.cpu.arch.endian(); + hdr_buf[index] = switch (endian) { + .Little => elf.ELFDATA2LSB, + .Big => elf.ELFDATA2MSB, + }; + index += 1; + + hdr_buf[index] = 1; // ELF version + index += 1; + + // OS ABI, often set to 0 regardless of target platform + // ABI Version, possibly used by glibc but not by static executables + // padding + mem.set(u8, hdr_buf[index..][0..9], 0); + index += 9; + + assert(index == 16); + + const elf_type = switch (self.base.options.output_mode) { + .Exe => elf.ET.EXEC, + .Obj => elf.ET.REL, + .Lib => switch (self.base.options.link_mode) { + .Static => elf.ET.REL, + .Dynamic => elf.ET.DYN, + }, + }; + mem.writeInt(u16, hdr_buf[index..][0..2], @enumToInt(elf_type), endian); + index += 2; + + const machine = self.base.options.target.cpu.arch.toElfMachine(); + mem.writeInt(u16, hdr_buf[index..][0..2], @enumToInt(machine), endian); + index += 2; + + // ELF Version, again + mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian); + index += 4; + + const e_entry = if (elf_type == .REL) 0 else self.entry_addr.?; + + switch (self.ptr_width) { + .p32 => { + mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, e_entry), endian); + index += 4; + + // e_phoff + mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, self.phdr_table_offset.?), endian); + index += 4; + + // e_shoff + mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(u32, self.shdr_table_offset.?), endian); + index += 4; + }, + .p64 => { + // e_entry + mem.writeInt(u64, hdr_buf[index..][0..8], e_entry, endian); + index += 8; + + // e_phoff + mem.writeInt(u64, hdr_buf[index..][0..8], self.phdr_table_offset.?, endian); + index += 8; + + // e_shoff + mem.writeInt(u64, hdr_buf[index..][0..8], self.shdr_table_offset.?, endian); + index += 8; + }, + } + + const e_flags = 0; + mem.writeInt(u32, hdr_buf[index..][0..4], e_flags, endian); + index += 4; + + const e_ehsize: u16 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Ehdr), + .p64 => @sizeOf(elf.Elf64_Ehdr), + }; + mem.writeInt(u16, hdr_buf[index..][0..2], e_ehsize, endian); + index += 2; + + const e_phentsize: u16 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Phdr), + .p64 => @sizeOf(elf.Elf64_Phdr), + }; + mem.writeInt(u16, hdr_buf[index..][0..2], e_phentsize, endian); + index += 2; + + const e_phnum = @intCast(u16, self.program_headers.items.len); + mem.writeInt(u16, hdr_buf[index..][0..2], e_phnum, endian); + index += 2; + + const e_shentsize: u16 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Shdr), + .p64 => @sizeOf(elf.Elf64_Shdr), + }; + mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian); + index += 2; + + const e_shnum = @intCast(u16, self.sections.items.len); + mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); + index += 2; + + mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_index.?, endian); + index += 2; + + assert(index == e_ehsize); + + try self.base.file.?.pwriteAll(hdr_buf[0..index], 0); +} + +fn freeTextBlock(self: *Elf, text_block: *TextBlock) void { + var already_have_free_list_node = false; + { + var i: usize = 0; + while (i < self.text_block_free_list.items.len) { + if (self.text_block_free_list.items[i] == text_block) { + _ = self.text_block_free_list.swapRemove(i); + continue; + } + if (self.text_block_free_list.items[i] == text_block.prev) { + already_have_free_list_node = true; + } + i += 1; + } + } + + if (self.last_text_block == text_block) { + // TODO shrink the .text section size here + self.last_text_block = text_block.prev; + } + + if (text_block.prev) |prev| { + prev.next = text_block.next; + + if (!already_have_free_list_node and prev.freeListEligible(self.*)) { + // The free list is heuristics, it doesn't have to be perfect, so we can + // ignore the OOM here. + self.text_block_free_list.append(self.base.allocator, prev) catch {}; + } + } else { + text_block.prev = null; + } + + if (text_block.next) |next| { + next.prev = text_block.prev; + } else { + text_block.next = null; + } +} + +fn shrinkTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64) void { + // TODO check the new capacity, and if it crosses the size threshold into a big enough + // capacity, insert a free list node for it. +} + +fn growTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { + const sym = self.local_symbols.items[text_block.local_sym_index]; + const align_ok = mem.alignBackwardGeneric(u64, sym.st_value, alignment) == sym.st_value; + const need_realloc = !align_ok or new_block_size > text_block.capacity(self.*); + if (!need_realloc) return sym.st_value; + return self.allocateTextBlock(text_block, new_block_size, alignment); +} + +fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { + const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; + const shdr = &self.sections.items[self.text_section_index.?]; + const new_block_ideal_capacity = new_block_size * alloc_num / alloc_den; + + // We use these to indicate our intention to update metadata, placing the new block, + // and possibly removing a free list node. + // It would be simpler to do it inside the for loop below, but that would cause a + // problem if an error was returned later in the function. So this action + // is actually carried out at the end of the function, when errors are no longer possible. + var block_placement: ?*TextBlock = null; + var free_list_removal: ?usize = null; + + // First we look for an appropriately sized free list node. + // The list is unordered. We'll just take the first thing that works. + const vaddr = blk: { + var i: usize = 0; + while (i < self.text_block_free_list.items.len) { + const big_block = self.text_block_free_list.items[i]; + // We now have a pointer to a live text block that has too much capacity. + // Is it enough that we could fit this new text block? + const sym = self.local_symbols.items[big_block.local_sym_index]; + const capacity = big_block.capacity(self.*); + const ideal_capacity = capacity * alloc_num / alloc_den; + const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity; + const capacity_end_vaddr = sym.st_value + capacity; + const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity; + const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment); + if (new_start_vaddr < ideal_capacity_end_vaddr) { + // Additional bookkeeping here to notice if this free list node + // should be deleted because the block that it points to has grown to take up + // more of the extra capacity. + if (!big_block.freeListEligible(self.*)) { + _ = self.text_block_free_list.swapRemove(i); + } else { + i += 1; + } + continue; + } + // At this point we know that we will place the new block here. But the + // remaining question is whether there is still yet enough capacity left + // over for there to still be a free list node. + const remaining_capacity = new_start_vaddr - ideal_capacity_end_vaddr; + const keep_free_list_node = remaining_capacity >= min_text_capacity; + + // Set up the metadata to be updated, after errors are no longer possible. + block_placement = big_block; + if (!keep_free_list_node) { + free_list_removal = i; + } + break :blk new_start_vaddr; + } else if (self.last_text_block) |last| { + const sym = self.local_symbols.items[last.local_sym_index]; + const ideal_capacity = sym.st_size * alloc_num / alloc_den; + const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity; + const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); + // Set up the metadata to be updated, after errors are no longer possible. + block_placement = last; + break :blk new_start_vaddr; + } else { + break :blk phdr.p_vaddr; + } + }; + + const expand_text_section = block_placement == null or block_placement.?.next == null; + if (expand_text_section) { + const text_capacity = self.allocatedSize(shdr.sh_offset); + const needed_size = (vaddr + new_block_size) - phdr.p_vaddr; + if (needed_size > text_capacity) { + // Must move the entire text section. + const new_offset = self.findFreeSpace(needed_size, 0x1000); + const text_size = if (self.last_text_block) |last| blk: { + const sym = self.local_symbols.items[last.local_sym_index]; + break :blk (sym.st_value + sym.st_size) - phdr.p_vaddr; + } else 0; + const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, text_size); + if (amt != text_size) return error.InputOutput; + shdr.sh_offset = new_offset; + phdr.p_offset = new_offset; + } + self.last_text_block = text_block; + + shdr.sh_size = needed_size; + phdr.p_memsz = needed_size; + phdr.p_filesz = needed_size; + + // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address + // range of the compilation unit. When we expand the text section, this range changes, + // so the DW_TAG_compile_unit tag of the .debug_info section becomes dirty. + self.debug_info_header_dirty = true; + // This becomes dirty for the same reason. We could potentially make this more + // fine-grained with the addition of support for more compilation units. It is planned to + // model each package as a different compilation unit. + self.debug_aranges_section_dirty = true; + + self.phdr_table_dirty = true; // TODO look into making only the one program header dirty + self.shdr_table_dirty = true; // TODO look into making only the one section dirty + } + + // This function can also reallocate a text block. + // In this case we need to "unplug" it from its previous location before + // plugging it in to its new location. + if (text_block.prev) |prev| { + prev.next = text_block.next; + } + if (text_block.next) |next| { + next.prev = text_block.prev; + } + + if (block_placement) |big_block| { + text_block.prev = big_block; + text_block.next = big_block.next; + big_block.next = text_block; + } else { + text_block.prev = null; + text_block.next = null; + } + if (free_list_removal) |i| { + _ = self.text_block_free_list.swapRemove(i); + } + return vaddr; +} + +pub fn allocateDeclIndexes(self: *Elf, decl: *Module.Decl) !void { + if (decl.link.elf.local_sym_index != 0) return; + + try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); + try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1); + + if (self.local_symbol_free_list.popOrNull()) |i| { + log.debug("reusing symbol index {} for {}\n", .{ i, decl.name }); + decl.link.elf.local_sym_index = i; + } else { + log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name }); + decl.link.elf.local_sym_index = @intCast(u32, self.local_symbols.items.len); + _ = self.local_symbols.addOneAssumeCapacity(); + } + + if (self.offset_table_free_list.popOrNull()) |i| { + decl.link.elf.offset_table_index = i; + } else { + decl.link.elf.offset_table_index = @intCast(u32, self.offset_table.items.len); + _ = self.offset_table.addOneAssumeCapacity(); + self.offset_table_count_dirty = true; + } + + const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; + + self.local_symbols.items[decl.link.elf.local_sym_index] = .{ + .st_name = 0, + .st_info = 0, + .st_other = 0, + .st_shndx = 0, + .st_value = phdr.p_vaddr, + .st_size = 0, + }; + self.offset_table.items[decl.link.elf.offset_table_index] = 0; +} + +pub fn freeDecl(self: *Elf, decl: *Module.Decl) void { + // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. + self.freeTextBlock(&decl.link.elf); + if (decl.link.elf.local_sym_index != 0) { + self.local_symbol_free_list.append(self.base.allocator, decl.link.elf.local_sym_index) catch {}; + self.offset_table_free_list.append(self.base.allocator, decl.link.elf.offset_table_index) catch {}; + + self.local_symbols.items[decl.link.elf.local_sym_index].st_info = 0; + + decl.link.elf.local_sym_index = 0; + } + // TODO make this logic match freeTextBlock. Maybe abstract the logic out since the same thing + // is desired for both. + _ = self.dbg_line_fn_free_list.remove(&decl.fn_link.elf); + if (decl.fn_link.elf.prev) |prev| { + _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {}; + prev.next = decl.fn_link.elf.next; + if (decl.fn_link.elf.next) |next| { + next.prev = prev; + } else { + self.dbg_line_fn_last = prev; + } + } else if (decl.fn_link.elf.next) |next| { + self.dbg_line_fn_first = next; + next.prev = null; + } + if (self.dbg_line_fn_first == &decl.fn_link.elf) { + self.dbg_line_fn_first = null; + } + if (self.dbg_line_fn_last == &decl.fn_link.elf) { + self.dbg_line_fn_last = null; + } +} + +pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { + const tracy = trace(@src()); + defer tracy.end(); + + var code_buffer = std.ArrayList(u8).init(self.base.allocator); + defer code_buffer.deinit(); + + var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator); + defer dbg_line_buffer.deinit(); + + var dbg_info_buffer = std.ArrayList(u8).init(self.base.allocator); + defer dbg_info_buffer.deinit(); + + var dbg_info_type_relocs: File.DbgInfoTypeRelocsTable = .{}; + defer { + for (dbg_info_type_relocs.items()) |*entry| { + entry.value.relocs.deinit(self.base.allocator); + } + dbg_info_type_relocs.deinit(self.base.allocator); + } + + const typed_value = decl.typed_value.most_recent.typed_value; + const is_fn: bool = switch (typed_value.ty.zigTypeTag()) { + .Fn => true, + else => false, + }; + if (is_fn) { + //if (mem.eql(u8, mem.spanZ(decl.name), "add")) { + // typed_value.val.cast(Value.Payload.Function).?.func.dump(module.*); + //} + + // For functions we need to add a prologue to the debug line program. + try dbg_line_buffer.ensureCapacity(26); + + const line_off: u28 = blk: { + if (decl.scope.cast(Module.Scope.File)) |scope_file| { + const tree = scope_file.contents.tree; + const file_ast_decls = tree.root_node.decls(); + // TODO Look into improving the performance here by adding a token-index-to-line + // lookup table. Currently this involves scanning over the source code for newlines. + const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; + const block = fn_proto.body().?.castTag(.Block).?; + const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); + break :blk @intCast(u28, line_delta); + } else if (decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { + const byte_off = zir_module.contents.module.decls[decl.src_index].inst.src; + const line_delta = std.zig.lineDelta(zir_module.source.bytes, 0, byte_off); + break :blk @intCast(u28, line_delta); + } else { + unreachable; + } + }; + + const ptr_width_bytes = self.ptrWidthBytes(); + dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ + DW.LNS_extended_op, + ptr_width_bytes + 1, + DW.LNE_set_address, + }); + // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. + assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); + dbg_line_buffer.items.len += ptr_width_bytes; + + dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line); + // This is the "relocatable" relative line offset from the previous function's end curly + // to this function's begin curly. + assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); + // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. + leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); + + dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); + assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); + // Once we support more than one source file, this will have the ability to be more + // than one possible value. + const file_index = 1; + leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index); + + // Emit a line for the begin curly with prologue_end=false. The codegen will + // do the work of setting prologue_end=true and epilogue_begin=true. + dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy); + + // .debug_info subprogram + const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1]; + try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 25 + decl_name_with_null.len); + + const fn_ret_type = typed_value.ty.fnReturnType(); + const fn_ret_has_bits = fn_ret_type.hasCodeGenBits(); + if (fn_ret_has_bits) { + dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram); + } else { + dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram_retvoid); + } + // These get overwritten after generating the machine code. These values are + // "relocations" and have to be in this fixed place so that functions can be + // moved in virtual address space. + assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); + dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT_low_pc, DW.FORM_addr + assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); + dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data4 + if (fn_ret_has_bits) { + const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type); + if (!gop.found_existing) { + gop.entry.value = .{ + .off = undefined, + .relocs = .{}, + }; + } + try gop.entry.value.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len)); + dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref4 + } + dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string + } else { + // TODO implement .debug_info for global variables + } + const res = try codegen.generateSymbol(&self.base, decl.src(), typed_value, &code_buffer, &dbg_line_buffer, &dbg_info_buffer, &dbg_info_type_relocs); + const code = switch (res) { + .externally_managed => |x| x, + .appended => code_buffer.items, + .fail => |em| { + decl.analysis = .codegen_failure; + try module.failed_decls.put(module.gpa, decl, em); + return; + }, + }; + + const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); + + const stt_bits: u8 = if (is_fn) elf.STT_FUNC else elf.STT_OBJECT; + + assert(decl.link.elf.local_sym_index != 0); // Caller forgot to allocateDeclIndexes() + const local_sym = &self.local_symbols.items[decl.link.elf.local_sym_index]; + if (local_sym.st_size != 0) { + const capacity = decl.link.elf.capacity(self.*); + const need_realloc = code.len > capacity or + !mem.isAlignedGeneric(u64, local_sym.st_value, required_alignment); + if (need_realloc) { + const vaddr = try self.growTextBlock(&decl.link.elf, code.len, required_alignment); + log.debug("growing {} from 0x{x} to 0x{x}\n", .{ decl.name, local_sym.st_value, vaddr }); + if (vaddr != local_sym.st_value) { + local_sym.st_value = vaddr; + + log.debug(" (writing new offset table entry)\n", .{}); + self.offset_table.items[decl.link.elf.offset_table_index] = vaddr; + try self.writeOffsetTableEntry(decl.link.elf.offset_table_index); + } + } else if (code.len < local_sym.st_size) { + self.shrinkTextBlock(&decl.link.elf, code.len); + } + local_sym.st_size = code.len; + local_sym.st_name = try self.updateString(local_sym.st_name, mem.spanZ(decl.name)); + local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits; + local_sym.st_other = 0; + local_sym.st_shndx = self.text_section_index.?; + // TODO this write could be avoided if no fields of the symbol were changed. + try self.writeSymbol(decl.link.elf.local_sym_index); + } else { + const decl_name = mem.spanZ(decl.name); + const name_str_index = try self.makeString(decl_name); + const vaddr = try self.allocateTextBlock(&decl.link.elf, code.len, required_alignment); + log.debug("allocated text block for {} at 0x{x}\n", .{ decl_name, vaddr }); + errdefer self.freeTextBlock(&decl.link.elf); + + local_sym.* = .{ + .st_name = name_str_index, + .st_info = (elf.STB_LOCAL << 4) | stt_bits, + .st_other = 0, + .st_shndx = self.text_section_index.?, + .st_value = vaddr, + .st_size = code.len, + }; + self.offset_table.items[decl.link.elf.offset_table_index] = vaddr; + + try self.writeSymbol(decl.link.elf.local_sym_index); + try self.writeOffsetTableEntry(decl.link.elf.offset_table_index); + } + + const section_offset = local_sym.st_value - self.program_headers.items[self.phdr_load_re_index.?].p_vaddr; + const file_offset = self.sections.items[self.text_section_index.?].sh_offset + section_offset; + try self.base.file.?.pwriteAll(code, file_offset); + + const target_endian = self.base.options.target.cpu.arch.endian(); + + const text_block = &decl.link.elf; + + // If the Decl is a function, we need to update the .debug_line program. + if (is_fn) { + // Perform the relocations based on vaddr. + switch (self.ptr_width) { + .p32 => { + { + const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..4]; + mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_value), target_endian); + } + { + const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..4]; + mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_value), target_endian); + } + }, + .p64 => { + { + const ptr = dbg_line_buffer.items[dbg_line_vaddr_reloc_index..][0..8]; + mem.writeInt(u64, ptr, local_sym.st_value, target_endian); + } + { + const ptr = dbg_info_buffer.items[dbg_info_low_pc_reloc_index..][0..8]; + mem.writeInt(u64, ptr, local_sym.st_value, target_endian); + } + }, + } + { + const ptr = dbg_info_buffer.items[self.getRelocDbgInfoSubprogramHighPC()..][0..4]; + mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian); + } + + try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence }); + + // Now we have the full contents and may allocate a region to store it. + + // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for + // `TextBlock` and the .debug_info. If you are editing this logic, you + // probably need to edit that logic too. + + const debug_line_sect = &self.sections.items[self.debug_line_section_index.?]; + const src_fn = &decl.fn_link.elf; + src_fn.len = @intCast(u32, dbg_line_buffer.items.len); + if (self.dbg_line_fn_last) |last| { + if (src_fn.next) |next| { + // Update existing function - non-last item. + if (src_fn.off + src_fn.len + min_nop_size > next.off) { + // It grew too big, so we move it to a new location. + if (src_fn.prev) |prev| { + _ = self.dbg_line_fn_free_list.put(self.base.allocator, prev, {}) catch {}; + prev.next = src_fn.next; + } + next.prev = src_fn.prev; + src_fn.next = null; + // Populate where it used to be with NOPs. + const file_pos = debug_line_sect.sh_offset + src_fn.off; + try self.pwriteDbgLineNops(0, &[0]u8{}, src_fn.len, file_pos); + // TODO Look at the free list before appending at the end. + src_fn.prev = last; + last.next = src_fn; + self.dbg_line_fn_last = src_fn; + + src_fn.off = last.off + (last.len * alloc_num / alloc_den); + } + } else if (src_fn.prev == null) { + // Append new function. + // TODO Look at the free list before appending at the end. + src_fn.prev = last; + last.next = src_fn; + self.dbg_line_fn_last = src_fn; + + src_fn.off = last.off + (last.len * alloc_num / alloc_den); + } + } else { + // This is the first function of the Line Number Program. + self.dbg_line_fn_first = src_fn; + self.dbg_line_fn_last = src_fn; + + src_fn.off = self.dbgLineNeededHeaderBytes() * alloc_num / alloc_den; + } + + const last_src_fn = self.dbg_line_fn_last.?; + const needed_size = last_src_fn.off + last_src_fn.len; + if (needed_size != debug_line_sect.sh_size) { + if (needed_size > self.allocatedSize(debug_line_sect.sh_offset)) { + const new_offset = self.findFreeSpace(needed_size, 1); + const existing_size = last_src_fn.off; + log.debug("moving .debug_line section: {} bytes from 0x{x} to 0x{x}\n", .{ + existing_size, + debug_line_sect.sh_offset, + new_offset, + }); + const amt = try self.base.file.?.copyRangeAll(debug_line_sect.sh_offset, self.base.file.?, new_offset, existing_size); + if (amt != existing_size) return error.InputOutput; + debug_line_sect.sh_offset = new_offset; + } + debug_line_sect.sh_size = needed_size; + self.shdr_table_dirty = true; // TODO look into making only the one section dirty + self.debug_line_header_dirty = true; + } + const prev_padding_size: u32 = if (src_fn.prev) |prev| src_fn.off - (prev.off + prev.len) else 0; + const next_padding_size: u32 = if (src_fn.next) |next| next.off - (src_fn.off + src_fn.len) else 0; + + // We only have support for one compilation unit so far, so the offsets are directly + // from the .debug_line section. + const file_pos = debug_line_sect.sh_offset + src_fn.off; + try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); + + // .debug_info - End the TAG_subprogram children. + try dbg_info_buffer.append(0); + } + + // Now we emit the .debug_info types of the Decl. These will count towards the size of + // the buffer, so we have to do it before computing the offset, and we can't perform the actual + // relocations yet. + for (dbg_info_type_relocs.items()) |*entry| { + entry.value.off = @intCast(u32, dbg_info_buffer.items.len); + try self.addDbgInfoType(entry.key, &dbg_info_buffer); + } + + try self.updateDeclDebugInfoAllocation(text_block, @intCast(u32, dbg_info_buffer.items.len)); + + // Now that we have the offset assigned we can finally perform type relocations. + for (dbg_info_type_relocs.items()) |entry| { + for (entry.value.relocs.items) |off| { + mem.writeInt( + u32, + dbg_info_buffer.items[off..][0..4], + text_block.dbg_info_off + entry.value.off, + target_endian, + ); + } + } + + try self.writeDeclDebugInfo(text_block, dbg_info_buffer.items); + + // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. + const decl_exports = module.decl_exports.get(decl) orelse &[0]*Module.Export{}; + return self.updateDeclExports(module, decl, decl_exports); +} + +/// Asserts the type has codegen bits. +fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !void { + switch (ty.zigTypeTag()) { + .Void => unreachable, + .NoReturn => unreachable, + .Bool => { + try dbg_info_buffer.appendSlice(&[_]u8{ + abbrev_base_type, + DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1 + 1, // DW.AT_byte_size, DW.FORM_data1 + 'b', + 'o', + 'o', + 'l', + 0, // DW.AT_name, DW.FORM_string + }); + }, + .Int => { + const info = ty.intInfo(self.base.options.target); + try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); + dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); + // DW.AT_encoding, DW.FORM_data1 + dbg_info_buffer.appendAssumeCapacity(if (info.signed) DW.ATE_signed else DW.ATE_unsigned); + // DW.AT_byte_size, DW.FORM_data1 + dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); + // DW.AT_name, DW.FORM_string + try dbg_info_buffer.writer().print("{}\x00", .{ty}); + }, + else => { + std.log.scoped(.compiler).err("TODO implement .debug_info for type '{}'", .{ty}); + try dbg_info_buffer.append(abbrev_pad1); + }, + } +} + +fn updateDeclDebugInfoAllocation(self: *Elf, text_block: *TextBlock, len: u32) !void { + const tracy = trace(@src()); + defer tracy.end(); + + // This logic is nearly identical to the logic above in `updateDecl` for + // `SrcFn` and the line number programs. If you are editing this logic, you + // probably need to edit that logic too. + + const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; + text_block.dbg_info_len = len; + if (self.dbg_info_decl_last) |last| { + if (text_block.dbg_info_next) |next| { + // Update existing Decl - non-last item. + if (text_block.dbg_info_off + text_block.dbg_info_len + min_nop_size > next.dbg_info_off) { + // It grew too big, so we move it to a new location. + if (text_block.dbg_info_prev) |prev| { + _ = self.dbg_info_decl_free_list.put(self.base.allocator, prev, {}) catch {}; + prev.dbg_info_next = text_block.dbg_info_next; + } + next.dbg_info_prev = text_block.dbg_info_prev; + text_block.dbg_info_next = null; + // Populate where it used to be with NOPs. + const file_pos = debug_info_sect.sh_offset + text_block.dbg_info_off; + try self.pwriteDbgInfoNops(0, &[0]u8{}, text_block.dbg_info_len, false, file_pos); + // TODO Look at the free list before appending at the end. + text_block.dbg_info_prev = last; + last.dbg_info_next = text_block; + self.dbg_info_decl_last = text_block; + + text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den); + } + } else if (text_block.dbg_info_prev == null) { + // Append new Decl. + // TODO Look at the free list before appending at the end. + text_block.dbg_info_prev = last; + last.dbg_info_next = text_block; + self.dbg_info_decl_last = text_block; + + text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den); + } + } else { + // This is the first Decl of the .debug_info + self.dbg_info_decl_first = text_block; + self.dbg_info_decl_last = text_block; + + text_block.dbg_info_off = self.dbgInfoNeededHeaderBytes() * alloc_num / alloc_den; + } +} + +fn writeDeclDebugInfo(self: *Elf, text_block: *TextBlock, dbg_info_buf: []const u8) !void { + const tracy = trace(@src()); + defer tracy.end(); + + // This logic is nearly identical to the logic above in `updateDecl` for + // `SrcFn` and the line number programs. If you are editing this logic, you + // probably need to edit that logic too. + + const debug_info_sect = &self.sections.items[self.debug_info_section_index.?]; + + const last_decl = self.dbg_info_decl_last.?; + // +1 for a trailing zero to end the children of the decl tag. + const needed_size = last_decl.dbg_info_off + last_decl.dbg_info_len + 1; + if (needed_size != debug_info_sect.sh_size) { + if (needed_size > self.allocatedSize(debug_info_sect.sh_offset)) { + const new_offset = self.findFreeSpace(needed_size, 1); + const existing_size = last_decl.dbg_info_off; + log.debug("moving .debug_info section: {} bytes from 0x{x} to 0x{x}\n", .{ + existing_size, + debug_info_sect.sh_offset, + new_offset, + }); + const amt = try self.base.file.?.copyRangeAll(debug_info_sect.sh_offset, self.base.file.?, new_offset, existing_size); + if (amt != existing_size) return error.InputOutput; + debug_info_sect.sh_offset = new_offset; + } + debug_info_sect.sh_size = needed_size; + self.shdr_table_dirty = true; // TODO look into making only the one section dirty + self.debug_info_header_dirty = true; + } + const prev_padding_size: u32 = if (text_block.dbg_info_prev) |prev| + text_block.dbg_info_off - (prev.dbg_info_off + prev.dbg_info_len) + else + 0; + const next_padding_size: u32 = if (text_block.dbg_info_next) |next| + next.dbg_info_off - (text_block.dbg_info_off + text_block.dbg_info_len) + else + 0; + + // To end the children of the decl tag. + const trailing_zero = text_block.dbg_info_next == null; + + // We only have support for one compilation unit so far, so the offsets are directly + // from the .debug_info section. + const file_pos = debug_info_sect.sh_offset + text_block.dbg_info_off; + try self.pwriteDbgInfoNops(prev_padding_size, dbg_info_buf, next_padding_size, trailing_zero, file_pos); +} + +pub fn updateDeclExports( + self: *Elf, + module: *Module, + decl: *const Module.Decl, + exports: []const *Module.Export, +) !void { + const tracy = trace(@src()); + defer tracy.end(); + + try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len); + const typed_value = decl.typed_value.most_recent.typed_value; + if (decl.link.elf.local_sym_index == 0) return; + const decl_sym = self.local_symbols.items[decl.link.elf.local_sym_index]; + + for (exports) |exp| { + if (exp.options.section) |section_name| { + if (!mem.eql(u8, section_name, ".text")) { + try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); + module.failed_exports.putAssumeCapacityNoClobber( + exp, + try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: ExportOptions.section", .{}), + ); + continue; + } + } + const stb_bits: u8 = switch (exp.options.linkage) { + .Internal => elf.STB_LOCAL, + .Strong => blk: { + if (mem.eql(u8, exp.options.name, "_start")) { + self.entry_addr = decl_sym.st_value; + } + break :blk elf.STB_GLOBAL; + }, + .Weak => elf.STB_WEAK, + .LinkOnce => { + try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); + module.failed_exports.putAssumeCapacityNoClobber( + exp, + try Module.ErrorMsg.create(self.base.allocator, 0, "Unimplemented: GlobalLinkage.LinkOnce", .{}), + ); + continue; + }, + }; + const stt_bits: u8 = @truncate(u4, decl_sym.st_info); + if (exp.link.sym_index) |i| { + const sym = &self.global_symbols.items[i]; + sym.* = .{ + .st_name = try self.updateString(sym.st_name, exp.options.name), + .st_info = (stb_bits << 4) | stt_bits, + .st_other = 0, + .st_shndx = self.text_section_index.?, + .st_value = decl_sym.st_value, + .st_size = decl_sym.st_size, + }; + } else { + const name = try self.makeString(exp.options.name); + const i = if (self.global_symbol_free_list.popOrNull()) |i| i else blk: { + _ = self.global_symbols.addOneAssumeCapacity(); + break :blk self.global_symbols.items.len - 1; + }; + self.global_symbols.items[i] = .{ + .st_name = name, + .st_info = (stb_bits << 4) | stt_bits, + .st_other = 0, + .st_shndx = self.text_section_index.?, + .st_value = decl_sym.st_value, + .st_size = decl_sym.st_size, + }; + + exp.link.sym_index = @intCast(u32, i); + } + } +} + +/// Must be called only after a successful call to `updateDecl`. +pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Decl) !void { + const tracy = trace(@src()); + defer tracy.end(); + + const scope_file = decl.scope.cast(Module.Scope.File).?; + const tree = scope_file.contents.tree; + const file_ast_decls = tree.root_node.decls(); + // TODO Look into improving the performance here by adding a token-index-to-line + // lookup table. Currently this involves scanning over the source code for newlines. + const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; + const block = fn_proto.body().?.castTag(.Block).?; + const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); + const casted_line_off = @intCast(u28, line_delta); + + const shdr = &self.sections.items[self.debug_line_section_index.?]; + const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff(); + var data: [4]u8 = undefined; + leb128.writeUnsignedFixed(4, &data, casted_line_off); + try self.base.file.?.pwriteAll(&data, file_pos); +} + +pub fn deleteExport(self: *Elf, exp: Export) void { + const sym_index = exp.sym_index orelse return; + self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {}; + self.global_symbols.items[sym_index].st_info = 0; +} + +fn writeProgHeader(self: *Elf, index: usize) !void { + const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); + const offset = self.program_headers.items[index].p_offset; + switch (self.base.options.target.cpu.arch.ptrBitWidth()) { + 32 => { + var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])}; + if (foreign_endian) { + bswapAllFields(elf.Elf32_Phdr, &phdr[0]); + } + return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); + }, + 64 => { + var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; + if (foreign_endian) { + bswapAllFields(elf.Elf64_Phdr, &phdr[0]); + } + return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); + }, + else => return error.UnsupportedArchitecture, + } +} + +fn writeSectHeader(self: *Elf, index: usize) !void { + const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); + switch (self.base.options.target.cpu.arch.ptrBitWidth()) { + 32 => { + var shdr: [1]elf.Elf32_Shdr = undefined; + shdr[0] = sectHeaderTo32(self.sections.items[index]); + if (foreign_endian) { + bswapAllFields(elf.Elf32_Shdr, &shdr[0]); + } + const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr); + return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); + }, + 64 => { + var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; + if (foreign_endian) { + bswapAllFields(elf.Elf64_Shdr, &shdr[0]); + } + const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr); + return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); + }, + else => return error.UnsupportedArchitecture, + } +} + +fn writeOffsetTableEntry(self: *Elf, index: usize) !void { + const shdr = &self.sections.items[self.got_section_index.?]; + const phdr = &self.program_headers.items[self.phdr_got_index.?]; + const entry_size: u16 = self.ptrWidthBytes(); + if (self.offset_table_count_dirty) { + // TODO Also detect virtual address collisions. + const allocated_size = self.allocatedSize(shdr.sh_offset); + const needed_size = self.local_symbols.items.len * entry_size; + if (needed_size > allocated_size) { + // Must move the entire got section. + const new_offset = self.findFreeSpace(needed_size, entry_size); + const amt = try self.base.file.?.copyRangeAll(shdr.sh_offset, self.base.file.?, new_offset, shdr.sh_size); + if (amt != shdr.sh_size) return error.InputOutput; + shdr.sh_offset = new_offset; + phdr.p_offset = new_offset; + } + shdr.sh_size = needed_size; + phdr.p_memsz = needed_size; + phdr.p_filesz = needed_size; + + self.shdr_table_dirty = true; // TODO look into making only the one section dirty + self.phdr_table_dirty = true; // TODO look into making only the one program header dirty + + self.offset_table_count_dirty = false; + } + const endian = self.base.options.target.cpu.arch.endian(); + const off = shdr.sh_offset + @as(u64, entry_size) * index; + switch (self.ptr_width) { + .p32 => { + var buf: [4]u8 = undefined; + mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian); + try self.base.file.?.pwriteAll(&buf, off); + }, + .p64 => { + var buf: [8]u8 = undefined; + mem.writeInt(u64, &buf, self.offset_table.items[index], endian); + try self.base.file.?.pwriteAll(&buf, off); + }, + } +} + +fn writeSymbol(self: *Elf, index: usize) !void { + const tracy = trace(@src()); + defer tracy.end(); + + const syms_sect = &self.sections.items[self.symtab_section_index.?]; + // Make sure we are not pointlessly writing symbol data that will have to get relocated + // due to running out of space. + if (self.local_symbols.items.len != syms_sect.sh_info) { + const sym_size: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Sym), + .p64 => @sizeOf(elf.Elf64_Sym), + }; + const sym_align: u16 = switch (self.ptr_width) { + .p32 => @alignOf(elf.Elf32_Sym), + .p64 => @alignOf(elf.Elf64_Sym), + }; + const needed_size = (self.local_symbols.items.len + self.global_symbols.items.len) * sym_size; + if (needed_size > self.allocatedSize(syms_sect.sh_offset)) { + // Move all the symbols to a new file location. + const new_offset = self.findFreeSpace(needed_size, sym_align); + const existing_size = @as(u64, syms_sect.sh_info) * sym_size; + const amt = try self.base.file.?.copyRangeAll(syms_sect.sh_offset, self.base.file.?, new_offset, existing_size); + if (amt != existing_size) return error.InputOutput; + syms_sect.sh_offset = new_offset; + } + syms_sect.sh_info = @intCast(u32, self.local_symbols.items.len); + syms_sect.sh_size = needed_size; // anticipating adding the global symbols later + self.shdr_table_dirty = true; // TODO look into only writing one section + } + const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); + switch (self.ptr_width) { + .p32 => { + var sym = [1]elf.Elf32_Sym{ + .{ + .st_name = self.local_symbols.items[index].st_name, + .st_value = @intCast(u32, self.local_symbols.items[index].st_value), + .st_size = @intCast(u32, self.local_symbols.items[index].st_size), + .st_info = self.local_symbols.items[index].st_info, + .st_other = self.local_symbols.items[index].st_other, + .st_shndx = self.local_symbols.items[index].st_shndx, + }, + }; + if (foreign_endian) { + bswapAllFields(elf.Elf32_Sym, &sym[0]); + } + const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index; + try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); + }, + .p64 => { + var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]}; + if (foreign_endian) { + bswapAllFields(elf.Elf64_Sym, &sym[0]); + } + const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index; + try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); + }, + } +} + +fn writeAllGlobalSymbols(self: *Elf) !void { + const syms_sect = &self.sections.items[self.symtab_section_index.?]; + const sym_size: u64 = switch (self.ptr_width) { + .p32 => @sizeOf(elf.Elf32_Sym), + .p64 => @sizeOf(elf.Elf64_Sym), + }; + const foreign_endian = self.base.options.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); + const global_syms_off = syms_sect.sh_offset + self.local_symbols.items.len * sym_size; + switch (self.ptr_width) { + .p32 => { + const buf = try self.base.allocator.alloc(elf.Elf32_Sym, self.global_symbols.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*sym, i| { + sym.* = .{ + .st_name = self.global_symbols.items[i].st_name, + .st_value = @intCast(u32, self.global_symbols.items[i].st_value), + .st_size = @intCast(u32, self.global_symbols.items[i].st_size), + .st_info = self.global_symbols.items[i].st_info, + .st_other = self.global_symbols.items[i].st_other, + .st_shndx = self.global_symbols.items[i].st_shndx, + }; + if (foreign_endian) { + bswapAllFields(elf.Elf32_Sym, sym); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); + }, + .p64 => { + const buf = try self.base.allocator.alloc(elf.Elf64_Sym, self.global_symbols.items.len); + defer self.base.allocator.free(buf); + + for (buf) |*sym, i| { + sym.* = .{ + .st_name = self.global_symbols.items[i].st_name, + .st_value = self.global_symbols.items[i].st_value, + .st_size = self.global_symbols.items[i].st_size, + .st_info = self.global_symbols.items[i].st_info, + .st_other = self.global_symbols.items[i].st_other, + .st_shndx = self.global_symbols.items[i].st_shndx, + }; + if (foreign_endian) { + bswapAllFields(elf.Elf64_Sym, sym); + } + } + try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); + }, + } +} + +fn ptrWidthBytes(self: Elf) u8 { + return switch (self.ptr_width) { + .p32 => 4, + .p64 => 8, + }; +} + +/// The reloc offset for the virtual address of a function in its Line Number Program. +/// Size is a virtual address integer. +const dbg_line_vaddr_reloc_index = 3; +/// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram. +/// Size is a virtual address integer. +const dbg_info_low_pc_reloc_index = 1; + +/// The reloc offset for the line offset of a function from the previous function's line. +/// It's a fixed-size 4-byte ULEB128. +fn getRelocDbgLineOff(self: Elf) usize { + return dbg_line_vaddr_reloc_index + self.ptrWidthBytes() + 1; +} + +fn getRelocDbgFileIndex(self: Elf) usize { + return self.getRelocDbgLineOff() + 5; +} + +fn getRelocDbgInfoSubprogramHighPC(self: Elf) u32 { + return dbg_info_low_pc_reloc_index + self.ptrWidthBytes(); +} + +fn dbgLineNeededHeaderBytes(self: Elf) u32 { + const directory_entry_format_count = 1; + const file_name_entry_format_count = 1; + const directory_count = 1; + const file_name_count = 1; + return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + + directory_count * 8 + file_name_count * 8 + + // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like + // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. + self.base.options.root_pkg.root_src_dir_path.len + + self.base.options.root_pkg.root_src_path.len); +} + +fn dbgInfoNeededHeaderBytes(self: Elf) u32 { + return 120; +} + +const min_nop_size = 2; + +/// Writes to the file a buffer, prefixed and suffixed by the specified number of +/// bytes of NOPs. Asserts each padding size is at least `min_nop_size` and total padding bytes +/// are less than 126,976 bytes (if this limit is ever reached, this function can be +/// improved to make more than one pwritev call, or the limit can be raised by a fixed +/// amount by increasing the length of `vecs`). +fn pwriteDbgLineNops( + self: *Elf, + prev_padding_size: usize, + buf: []const u8, + next_padding_size: usize, + offset: usize, +) !void { + const tracy = trace(@src()); + defer tracy.end(); + + const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096; + const three_byte_nop = [3]u8{ DW.LNS_advance_pc, 0b1000_0000, 0 }; + var vecs: [32]std.os.iovec_const = undefined; + var vec_index: usize = 0; + { + var padding_left = prev_padding_size; + if (padding_left % 2 != 0) { + vecs[vec_index] = .{ + .iov_base = &three_byte_nop, + .iov_len = three_byte_nop.len, + }; + vec_index += 1; + padding_left -= three_byte_nop.len; + } + while (padding_left > page_of_nops.len) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = page_of_nops.len, + }; + vec_index += 1; + padding_left -= page_of_nops.len; + } + if (padding_left > 0) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = padding_left, + }; + vec_index += 1; + } + } + + vecs[vec_index] = .{ + .iov_base = buf.ptr, + .iov_len = buf.len, + }; + vec_index += 1; + + { + var padding_left = next_padding_size; + if (padding_left % 2 != 0) { + vecs[vec_index] = .{ + .iov_base = &three_byte_nop, + .iov_len = three_byte_nop.len, + }; + vec_index += 1; + padding_left -= three_byte_nop.len; + } + while (padding_left > page_of_nops.len) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = page_of_nops.len, + }; + vec_index += 1; + padding_left -= page_of_nops.len; + } + if (padding_left > 0) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = padding_left, + }; + vec_index += 1; + } + } + try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); +} + +/// Writes to the file a buffer, prefixed and suffixed by the specified number of +/// bytes of padding. +fn pwriteDbgInfoNops( + self: *Elf, + prev_padding_size: usize, + buf: []const u8, + next_padding_size: usize, + trailing_zero: bool, + offset: usize, +) !void { + const tracy = trace(@src()); + defer tracy.end(); + + const page_of_nops = [1]u8{abbrev_pad1} ** 4096; + var vecs: [32]std.os.iovec_const = undefined; + var vec_index: usize = 0; + { + var padding_left = prev_padding_size; + while (padding_left > page_of_nops.len) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = page_of_nops.len, + }; + vec_index += 1; + padding_left -= page_of_nops.len; + } + if (padding_left > 0) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = padding_left, + }; + vec_index += 1; + } + } + + vecs[vec_index] = .{ + .iov_base = buf.ptr, + .iov_len = buf.len, + }; + vec_index += 1; + + { + var padding_left = next_padding_size; + while (padding_left > page_of_nops.len) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = page_of_nops.len, + }; + vec_index += 1; + padding_left -= page_of_nops.len; + } + if (padding_left > 0) { + vecs[vec_index] = .{ + .iov_base = &page_of_nops, + .iov_len = padding_left, + }; + vec_index += 1; + } + } + + if (trailing_zero) { + var zbuf = [1]u8{0}; + vecs[vec_index] = .{ + .iov_base = &zbuf, + .iov_len = zbuf.len, + }; + vec_index += 1; + } + + try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); +} + +/// Saturating multiplication +fn satMul(a: anytype, b: anytype) @TypeOf(a, b) { + const T = @TypeOf(a, b); + return std.math.mul(T, a, b) catch std.math.maxInt(T); +} + +fn bswapAllFields(comptime S: type, ptr: *S) void { + @panic("TODO implement bswapAllFields"); +} + +fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { + return .{ + .p_type = phdr.p_type, + .p_flags = phdr.p_flags, + .p_offset = @intCast(u32, phdr.p_offset), + .p_vaddr = @intCast(u32, phdr.p_vaddr), + .p_paddr = @intCast(u32, phdr.p_paddr), + .p_filesz = @intCast(u32, phdr.p_filesz), + .p_memsz = @intCast(u32, phdr.p_memsz), + .p_align = @intCast(u32, phdr.p_align), + }; +} + +fn sectHeaderTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr { + return .{ + .sh_name = shdr.sh_name, + .sh_type = shdr.sh_type, + .sh_flags = @intCast(u32, shdr.sh_flags), + .sh_addr = @intCast(u32, shdr.sh_addr), + .sh_offset = @intCast(u32, shdr.sh_offset), + .sh_size = @intCast(u32, shdr.sh_size), + .sh_link = shdr.sh_link, + .sh_info = shdr.sh_info, + .sh_addralign = @intCast(u32, shdr.sh_addralign), + .sh_entsize = @intCast(u32, shdr.sh_entsize), + }; +} diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index 9947530398a74844267679d50242b5603e666f60..4bcea9cfa87ec2d6531aa53ed5cf9951e14baeb4 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -13,7 +13,7 @@ const Module = @import("../Module.zig"); const link = @import("../link.zig"); const File = link.File; -pub const base_tag: Tag = File.Tag.macho; +pub const base_tag: File.Tag = File.Tag.macho; base: File, @@ -210,3 +210,7 @@ pub fn updateDeclExports( ) !void {} pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {} + +pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 { + @panic("TODO implement getDeclVAddr for MachO"); +} diff --git a/src-self-hosted/cbe.h b/src-self-hosted/link/cbe.h similarity index 100% rename from src-self-hosted/cbe.h rename to src-self-hosted/link/cbe.h diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig index b51cb313f85a6615fc5fc075180299fa0cf71de3..9e88466cf77c9d251b6edb186667d3952031e69e 100644 --- a/src-self-hosted/test.zig +++ b/src-self-hosted/test.zig @@ -10,7 +10,7 @@ const enable_wine: bool = build_options.enable_wine; const enable_wasmtime: bool = build_options.enable_wasmtime; const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir; -const cheader = @embedFile("cbe.h"); +const cheader = @embedFile("link/cbe.h"); test "self-hosted" { var ctx = TestContext.init(); -- 2.54.0