Merge remote-tracking branch 'origin/master' into rewrite-coroutines
This commit is contained in:
commit
8a9289996a
|
@ -1,6 +1,6 @@
|
|||
![ZIG](https://ziglang.org/zig-logo.svg)
|
||||
|
||||
Zig is an open-source programming language designed for **robustness**,
|
||||
A general-purpose programming language designed for **robustness**,
|
||||
**optimality**, and **maintainability**.
|
||||
|
||||
## Resources
|
||||
|
@ -10,6 +10,7 @@ Zig is an open-source programming language designed for **robustness**,
|
|||
* [Community](https://github.com/ziglang/zig/wiki/Community)
|
||||
* [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md)
|
||||
* [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ)
|
||||
* [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects)
|
||||
|
||||
## Building from Source
|
||||
|
||||
|
|
|
@ -3745,8 +3745,8 @@ static const size_t slice_len_index = 1;
|
|||
static const size_t maybe_child_index = 0;
|
||||
static const size_t maybe_null_index = 1;
|
||||
|
||||
static const size_t err_union_err_index = 0;
|
||||
static const size_t err_union_payload_index = 1;
|
||||
static const size_t err_union_payload_index = 0;
|
||||
static const size_t err_union_err_index = 1;
|
||||
|
||||
// label (grep this): [coro_frame_struct_layout]
|
||||
static const size_t coro_fn_ptr_index = 0;
|
||||
|
|
|
@ -7350,20 +7350,21 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
|
|||
uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);
|
||||
uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type);
|
||||
|
||||
ZigLLVMDIType *di_element_types[] = {
|
||||
ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
|
||||
ZigLLVMDIType *di_element_types[2];
|
||||
di_element_types[err_union_err_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(type->llvm_di_type),
|
||||
"tag", di_file, line,
|
||||
tag_debug_size_in_bits,
|
||||
tag_debug_align_in_bits,
|
||||
tag_offset_in_bits,
|
||||
ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type)),
|
||||
ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
|
||||
ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type));
|
||||
di_element_types[err_union_payload_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
|
||||
ZigLLVMTypeToScope(type->llvm_di_type),
|
||||
"value", di_file, line,
|
||||
value_debug_size_in_bits,
|
||||
value_debug_align_in_bits,
|
||||
value_offset_in_bits,
|
||||
ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)),
|
||||
};
|
||||
ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type));
|
||||
|
||||
ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
|
||||
compile_unit_scope,
|
||||
|
|
|
@ -6690,29 +6690,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
|
|||
err_payload_value = gen_const_val(g, payload_val, "");
|
||||
make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_val->type, err_payload_value);
|
||||
}
|
||||
LLVMValueRef fields[2];
|
||||
fields[err_union_err_index] = err_tag_value;
|
||||
fields[err_union_payload_index] = err_payload_value;
|
||||
if (make_unnamed_struct) {
|
||||
uint64_t payload_off = LLVMOffsetOfElement(g->target_data_ref, get_llvm_type(g, type_entry), 1);
|
||||
uint64_t err_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(err_tag_value));
|
||||
unsigned pad_sz = payload_off - err_sz;
|
||||
if (pad_sz == 0) {
|
||||
LLVMValueRef fields[] = {
|
||||
err_tag_value,
|
||||
err_payload_value,
|
||||
};
|
||||
return LLVMConstStruct(fields, 2, false);
|
||||
} else {
|
||||
LLVMValueRef fields[] = {
|
||||
err_tag_value,
|
||||
LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)),
|
||||
err_payload_value,
|
||||
};
|
||||
return LLVMConstStruct(fields, 3, false);
|
||||
}
|
||||
return LLVMConstStruct(fields, 2, false);
|
||||
} else {
|
||||
LLVMValueRef fields[] = {
|
||||
err_tag_value,
|
||||
err_payload_value,
|
||||
};
|
||||
return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2);
|
||||
}
|
||||
}
|
||||
|
@ -8627,15 +8610,18 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
|
|||
}
|
||||
}
|
||||
|
||||
//note(dimenus): appending libc headers before c_headers breaks intrinsics
|
||||
//and other compiler specific items
|
||||
// According to Rich Felker libc headers are supposed to go before C language headers.
|
||||
args.append("-isystem");
|
||||
args.append(buf_ptr(g->zig_c_headers_dir));
|
||||
|
||||
for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
|
||||
Buf *include_dir = g->libc_include_dir_list[i];
|
||||
args.append("-isystem");
|
||||
args.append(buf_ptr(include_dir));
|
||||
}
|
||||
|
||||
// According to Rich Felker libc headers are supposed to go before C language headers.
|
||||
args.append("-isystem");
|
||||
args.append(buf_ptr(g->zig_c_headers_dir));
|
||||
|
||||
if (g->zig_target->is_native) {
|
||||
args.append("-march=native");
|
||||
|
|
19
src/ir.cpp
19
src/ir.cpp
|
@ -9098,6 +9098,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
|
|||
bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat);
|
||||
assert(const_val_is_int || const_val_is_float);
|
||||
|
||||
if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) {
|
||||
return true;
|
||||
}
|
||||
if (other_type->id == ZigTypeIdFloat) {
|
||||
if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) {
|
||||
return true;
|
||||
|
@ -11329,7 +11332,6 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour
|
|||
if (enum_type->data.enumeration.layout == ContainerLayoutAuto &&
|
||||
enum_type->data.enumeration.src_field_count == 1)
|
||||
{
|
||||
assert(tag_type == ira->codegen->builtin_types.entry_num_lit_int);
|
||||
IrInstruction *result = ir_const(ira, source_instr, tag_type);
|
||||
init_const_bigint(&result->value, tag_type,
|
||||
&enum_type->data.enumeration.fields[0].value);
|
||||
|
@ -20697,12 +20699,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
|||
}
|
||||
for (size_t i = 0; i < errors_len; i += 1) {
|
||||
Stage2ErrorMsg *clang_err = &errors_ptr[i];
|
||||
ErrorMsg *err_msg = err_msg_create_with_offset(
|
||||
clang_err->filename_ptr ?
|
||||
buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
|
||||
clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
|
||||
buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
|
||||
err_msg_add_note(parent_err_msg, err_msg);
|
||||
// Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
|
||||
if (clang_err->source && clang_err->filename_ptr) {
|
||||
ErrorMsg *err_msg = err_msg_create_with_offset(
|
||||
clang_err->filename_ptr ?
|
||||
buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
|
||||
clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
|
||||
buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
|
||||
err_msg_add_note(parent_err_msg, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
|
|
@ -6,3 +6,4 @@ pub const _errno = __error;
|
|||
|
||||
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
|
||||
|
|
70
std/math.zig
70
std/math.zig
|
@ -242,12 +242,76 @@ pub fn floatExponentBits(comptime T: type) comptime_int {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn min(x: var, y: var) @typeOf(x + y) {
|
||||
return if (x < y) x else y;
|
||||
/// Given two types, returns the smallest one which is capable of holding the
|
||||
/// full range of the minimum value.
|
||||
pub fn Min(comptime A: type, comptime B: type) type {
|
||||
switch (@typeInfo(A)) {
|
||||
.Int => |a_info| switch (@typeInfo(B)) {
|
||||
.Int => |b_info| if (!a_info.is_signed and !b_info.is_signed) {
|
||||
if (a_info.bits < b_info.bits) {
|
||||
return A;
|
||||
} else {
|
||||
return B;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return @typeOf(A(0) + B(0));
|
||||
}
|
||||
|
||||
/// Returns the smaller number. When one of the parameter's type's full range fits in the other,
|
||||
/// the return type is the smaller type.
|
||||
pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) {
|
||||
const Result = Min(@typeOf(x), @typeOf(y));
|
||||
if (x < y) {
|
||||
// TODO Zig should allow this as an implicit cast because x is immutable and in this
|
||||
// scope it is known to fit in the return type.
|
||||
switch (@typeInfo(Result)) {
|
||||
.Int => return @intCast(Result, x),
|
||||
else => return x,
|
||||
}
|
||||
} else {
|
||||
// TODO Zig should allow this as an implicit cast because y is immutable and in this
|
||||
// scope it is known to fit in the return type.
|
||||
switch (@typeInfo(Result)) {
|
||||
.Int => return @intCast(Result, y),
|
||||
else => return y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "math.min" {
|
||||
testing.expect(min(i32(-1), i32(2)) == -1);
|
||||
{
|
||||
var a: u16 = 999;
|
||||
var b: u32 = 10;
|
||||
var result = min(a, b);
|
||||
testing.expect(@typeOf(result) == u16);
|
||||
testing.expect(result == 10);
|
||||
}
|
||||
{
|
||||
var a: f64 = 10.34;
|
||||
var b: f32 = 999.12;
|
||||
var result = min(a, b);
|
||||
testing.expect(@typeOf(result) == f64);
|
||||
testing.expect(result == 10.34);
|
||||
}
|
||||
{
|
||||
var a: i8 = -127;
|
||||
var b: i16 = -200;
|
||||
var result = min(a, b);
|
||||
testing.expect(@typeOf(result) == i16);
|
||||
testing.expect(result == -200);
|
||||
}
|
||||
{
|
||||
const a = 10.34;
|
||||
var b: f32 = 999.12;
|
||||
var result = min(a, b);
|
||||
testing.expect(@typeOf(result) == f32);
|
||||
testing.expect(result == 10.34);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max(x: var, y: var) @typeOf(x + y) {
|
||||
|
@ -309,7 +373,7 @@ test "math.shl" {
|
|||
}
|
||||
|
||||
/// Shifts right. Overflowed bits are truncated.
|
||||
/// A negative shift amount results in a lefft shift.
|
||||
/// A negative shift amount results in a left shift.
|
||||
pub fn shr(comptime T: type, a: T, shift_amt: var) T {
|
||||
const abs_shift_amt = absCast(shift_amt);
|
||||
const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt);
|
||||
|
|
13
std/os.zig
13
std/os.zig
|
@ -120,6 +120,19 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (freebsd.is_the_target) {
|
||||
while (true) {
|
||||
const err = std.c.getErrno(std.c.getrandom(buf.ptr, buf.len, 0));
|
||||
|
||||
switch (err) {
|
||||
0 => return,
|
||||
EINVAL => unreachable,
|
||||
EFAULT => unreachable,
|
||||
EINTR => continue,
|
||||
else => return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wasi.is_the_target) {
|
||||
switch (wasi.random_get(buf.ptr, buf.len)) {
|
||||
0 => return,
|
||||
|
|
|
@ -760,3 +760,62 @@ pub const stack_t = extern struct {
|
|||
ss_size: isize,
|
||||
ss_flags: i32,
|
||||
};
|
||||
|
||||
pub const S_IFMT = 0o170000;
|
||||
|
||||
pub const S_IFIFO = 0o010000;
|
||||
pub const S_IFCHR = 0o020000;
|
||||
pub const S_IFDIR = 0o040000;
|
||||
pub const S_IFBLK = 0o060000;
|
||||
pub const S_IFREG = 0o100000;
|
||||
pub const S_IFLNK = 0o120000;
|
||||
pub const S_IFSOCK = 0o140000;
|
||||
pub const S_IFWHT = 0o160000;
|
||||
|
||||
pub const S_ISUID = 0o4000;
|
||||
pub const S_ISGID = 0o2000;
|
||||
pub const S_ISVTX = 0o1000;
|
||||
pub const S_IRWXU = 0o700;
|
||||
pub const S_IRUSR = 0o400;
|
||||
pub const S_IWUSR = 0o200;
|
||||
pub const S_IXUSR = 0o100;
|
||||
pub const S_IRWXG = 0o070;
|
||||
pub const S_IRGRP = 0o040;
|
||||
pub const S_IWGRP = 0o020;
|
||||
pub const S_IXGRP = 0o010;
|
||||
pub const S_IRWXO = 0o007;
|
||||
pub const S_IROTH = 0o004;
|
||||
pub const S_IWOTH = 0o002;
|
||||
pub const S_IXOTH = 0o001;
|
||||
|
||||
pub fn S_ISFIFO(m: u32) bool {
|
||||
return m & S_IFMT == S_IFIFO;
|
||||
}
|
||||
|
||||
pub fn S_ISCHR(m: u32) bool {
|
||||
return m & S_IFMT == S_IFCHR;
|
||||
}
|
||||
|
||||
pub fn S_ISDIR(m: u32) bool {
|
||||
return m & S_IFMT == S_IFDIR;
|
||||
}
|
||||
|
||||
pub fn S_ISBLK(m: u32) bool {
|
||||
return m & S_IFMT == S_IFBLK;
|
||||
}
|
||||
|
||||
pub fn S_ISREG(m: u32) bool {
|
||||
return m & S_IFMT == S_IFREG;
|
||||
}
|
||||
|
||||
pub fn S_ISLNK(m: u32) bool {
|
||||
return m & S_IFMT == S_IFLNK;
|
||||
}
|
||||
|
||||
pub fn S_ISSOCK(m: u32) bool {
|
||||
return m & S_IFMT == S_IFSOCK;
|
||||
}
|
||||
|
||||
pub fn S_IWHT(m: u32) bool {
|
||||
return m & S_IFMT == S_IFWHT;
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ const builtin = @import("builtin");
|
|||
const std = @import("../std.zig");
|
||||
pub const is_the_target = builtin.os == .netbsd;
|
||||
pub usingnamespace std.c;
|
||||
pub usingnamespace @import("bits.zig");
|
||||
|
|
|
@ -138,10 +138,19 @@ pub const RtlGenRandomError = error{Unexpected};
|
|||
/// https://github.com/rust-lang-nursery/rand/issues/111
|
||||
/// https://bugzilla.mozilla.org/show_bug.cgi?id=504270
|
||||
pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void {
|
||||
if (advapi32.RtlGenRandom(output.ptr, output.len) == 0) {
|
||||
switch (kernel32.GetLastError()) {
|
||||
else => |err| return unexpectedError(err),
|
||||
var total_read: usize = 0;
|
||||
var buff: []u8 = output[0..];
|
||||
const max_read_size: ULONG = maxInt(ULONG);
|
||||
|
||||
while (total_read < output.len) {
|
||||
const to_read: ULONG = math.min(buff.len, max_read_size);
|
||||
|
||||
if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) {
|
||||
return unexpectedError(kernel32.GetLastError());
|
||||
}
|
||||
|
||||
total_read += to_read;
|
||||
buff = buff[to_read..];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,5 +19,5 @@ pub extern "advapi32" stdcallcc fn RegQueryValueExW(
|
|||
|
||||
// RtlGenRandom is known as SystemFunction036 under advapi32
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
|
||||
pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: usize) BOOL;
|
||||
pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL;
|
||||
pub const RtlGenRandom = SystemFunction036;
|
||||
|
|
|
@ -3292,14 +3292,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||
"tmp.zig:3:17: note: value 8 cannot fit into type u3",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"incompatible number literals",
|
||||
\\const x = 2 == 2.0;
|
||||
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
|
||||
,
|
||||
"tmp.zig:1:11: error: integer value 2 cannot be implicitly casted to type 'comptime_float'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"missing function call param",
|
||||
\\const Foo = struct {
|
||||
|
|
|
@ -508,7 +508,7 @@ test "peer type resolution: unreachable, null, slice" {
|
|||
}
|
||||
|
||||
test "peer type resolution: unreachable, error set, unreachable" {
|
||||
const Error = error {
|
||||
const Error = error{
|
||||
FileDescriptorAlreadyPresentInSet,
|
||||
OperationCausesCircularLoop,
|
||||
FileDescriptorNotRegistered,
|
||||
|
@ -529,3 +529,8 @@ test "peer type resolution: unreachable, error set, unreachable" {
|
|||
};
|
||||
expect(transformed_err == error.SystemResources);
|
||||
}
|
||||
|
||||
test "implicit cast comptime_int to comptime_float" {
|
||||
comptime expect(comptime_float(10) == f32(10));
|
||||
expect(2 == 2.0);
|
||||
}
|
||||
|
|
|
@ -982,3 +982,14 @@ test "enum literal casting to tagged union" {
|
|||
else => @panic("fail"),
|
||||
}
|
||||
}
|
||||
|
||||
test "enum with one member and custom tag type" {
|
||||
const E = enum(u2) {
|
||||
One,
|
||||
};
|
||||
expect(@enumToInt(E.One) == 0);
|
||||
const E2 = enum(u2) {
|
||||
One = 2,
|
||||
};
|
||||
expect(@enumToInt(E2.One) == 2);
|
||||
}
|
||||
|
|
|
@ -504,6 +504,9 @@ const Contents = struct {
|
|||
}
|
||||
};
|
||||
|
||||
comptime {
|
||||
@compileError("the behavior of std.AutoHashMap changed and []const u8 will be treated as a pointer. will need to update the hash maps to actually do some kind of hashing on the slices.");
|
||||
}
|
||||
const HashToContents = std.AutoHashMap([]const u8, Contents);
|
||||
const TargetToHash = std.HashMap(DestTarget, []const u8, DestTarget.hash, DestTarget.eql);
|
||||
const PathTable = std.AutoHashMap([]const u8, *TargetToHash);
|
||||
|
|
Loading…
Reference in New Issue
Block a user