bring your own OS layer in the std lib

closes #3784
This commit is contained in:
Andrew Kelley 2019-12-02 15:02:17 -05:00
parent dcbd5ad155
commit ad214c7aa0
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
7 changed files with 55 additions and 21 deletions

View File

@ -796,6 +796,9 @@ pub const OpenSelfDebugInfoError = error{
pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
if (builtin.strip_debug_info)
return error.MissingDebugInfo;
if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {
return noasync root.os.debug.openSelfDebugInfo(allocator);
}
if (builtin.os == .windows) {
return noasync openSelfDebugInfoWindows(allocator);
}
@ -1722,8 +1725,7 @@ pub const DebugInfo = switch (builtin.os) {
sect_contribs: []pdb.SectionContribEntry,
modules: []Module,
},
.linux, .freebsd, .netbsd, .dragonfly => DwarfInfo,
else => @compileError("Unsupported OS"),
else => DwarfInfo,
};
const PcRange = struct {

View File

@ -61,7 +61,7 @@ pub const Loop = struct {
base: ResumeNode,
completion_key: usize,
},
else => @compileError("unsupported OS"),
else => struct {},
};
const KEventFd = struct {

View File

@ -1,4 +1,5 @@
const std = @import("std.zig");
const root = @import("root");
const debug = std.debug;
const assert = debug.assert;
const testing = std.testing;
@ -35,6 +36,8 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new
/// Thread-safe and lock-free.
pub const page_allocator = if (std.Target.current.isWasm())
&wasm_page_allocator_state
else if (std.Target.current.getOs() == .freestanding)
root.os.heap.page_allocator
else
&page_allocator_state;

View File

@ -14,6 +14,7 @@
// Note: The Zig standard library does not support POSIX thread cancellation, and
// in general EINTR is handled by trying again.
const root = @import("root");
const std = @import("std.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
@ -48,8 +49,14 @@ test "" {
_ = @import("os/test.zig");
}
/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.
pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
/// Applications can override the `system` API layer in their root source file.
/// Otherwise, when linking libc, this is the C API.
/// When not linking libc, it is the OS-specific system interface.
pub const system = if (@hasDecl(root, "os") and root.os != @This())
root.os.system
else if (builtin.link_libc)
std.c
else switch (builtin.os) {
.macosx, .ios, .watchos, .tvos => darwin,
.freebsd => freebsd,
.linux => linux,

View File

@ -1,7 +1,10 @@
// 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`.
//! 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
//! to the namespace.
const builtin = @import("builtin");
const root = @import("root");
pub usingnamespace switch (builtin.os) {
.macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
@ -14,6 +17,8 @@ pub usingnamespace switch (builtin.os) {
else => struct {},
};
pub usingnamespace if (@hasDecl(root, "os") and @hasDecl(root.os, "bits")) root.os.bits else struct {};
pub const iovec = extern struct {
iov_base: [*]u8,
iov_len: usize,

View File

@ -19,7 +19,7 @@ pub const Thread = struct {
else switch (builtin.os) {
.linux => i32,
.windows => windows.HANDLE,
else => @compileError("Unsupported OS"),
else => void,
};
/// Represents a unique ID per thread.
@ -45,7 +45,7 @@ pub const Thread = struct {
alloc_start: *c_void,
heap_handle: windows.HANDLE,
},
else => @compileError("Unsupported OS"),
else => struct {},
};
/// Returns the ID of the calling thread.

View File

@ -9015,7 +9015,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
if (irb->exec->first_err_trace_msg == nullptr) {
irb->exec->first_err_trace_msg = irb->codegen->trace_err;
}
src_assert(irb->exec->first_err_trace_msg != nullptr, node);
}
return result;
}
@ -10709,10 +10708,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (type_is_global_error_set(err_set_type)) {
continue;
}
if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (type_is_global_error_set(cur_type)) {
if (!allow_infer && type_is_global_error_set(cur_type)) {
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
prev_inst = cur_inst;
continue;
@ -10830,10 +10831,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
}
if (cur_type->id == ZigTypeIdErrorSet) {
if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (type_is_global_error_set(cur_type)) {
if (!allow_infer && type_is_global_error_set(cur_type)) {
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
continue;
}
@ -10844,17 +10847,20 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
update_errors_helper(ira->codegen, &errors, &errors_count);
if (err_set_type == nullptr) {
bool allow_infer = false;
if (prev_type->id == ZigTypeIdErrorUnion) {
err_set_type = prev_type->data.error_union.err_set_type;
allow_infer = err_set_type->data.error_set.infer_fn != nullptr &&
err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
} else {
err_set_type = cur_type;
}
if (!resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) {
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (type_is_global_error_set(err_set_type)) {
if (!allow_infer && type_is_global_error_set(err_set_type)) {
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
continue;
}
@ -10908,15 +10914,22 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (prev_err_set_type == cur_err_set_type)
continue;
if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr &&
prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr &&
cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) {
if ((!allow_infer_prev && type_is_global_error_set(prev_err_set_type)) ||
(!allow_infer_cur && type_is_global_error_set(cur_err_set_type)))
{
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
continue;
}
@ -11085,10 +11098,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
{
if (err_set_type != nullptr) {
ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
return ira->codegen->builtin_types.entry_invalid;
}
if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) {
if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) ||
type_is_global_error_set(err_set_type))
{
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
prev_inst = cur_inst;
continue;