Skip to content

Commit ad214c7

Browse files
committed
bring your own OS layer in the std lib
closes #3784
1 parent dcbd5ad commit ad214c7

File tree

7 files changed

+55
-21
lines changed

7 files changed

+55
-21
lines changed

lib/std/debug.zig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,9 @@ pub const OpenSelfDebugInfoError = error{
796796
pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
797797
if (builtin.strip_debug_info)
798798
return error.MissingDebugInfo;
799+
if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {
800+
return noasync root.os.debug.openSelfDebugInfo(allocator);
801+
}
799802
if (builtin.os == .windows) {
800803
return noasync openSelfDebugInfoWindows(allocator);
801804
}
@@ -1722,8 +1725,7 @@ pub const DebugInfo = switch (builtin.os) {
17221725
sect_contribs: []pdb.SectionContribEntry,
17231726
modules: []Module,
17241727
},
1725-
.linux, .freebsd, .netbsd, .dragonfly => DwarfInfo,
1726-
else => @compileError("Unsupported OS"),
1728+
else => DwarfInfo,
17271729
};
17281730

17291731
const PcRange = struct {

lib/std/event/loop.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub const Loop = struct {
6161
base: ResumeNode,
6262
completion_key: usize,
6363
},
64-
else => @compileError("unsupported OS"),
64+
else => struct {},
6565
};
6666

6767
const KEventFd = struct {

lib/std/heap.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std.zig");
2+
const root = @import("root");
23
const debug = std.debug;
34
const assert = debug.assert;
45
const testing = std.testing;
@@ -35,6 +36,8 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new
3536
/// Thread-safe and lock-free.
3637
pub const page_allocator = if (std.Target.current.isWasm())
3738
&wasm_page_allocator_state
39+
else if (std.Target.current.getOs() == .freestanding)
40+
root.os.heap.page_allocator
3841
else
3942
&page_allocator_state;
4043

lib/std/os.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// Note: The Zig standard library does not support POSIX thread cancellation, and
1515
// in general EINTR is handled by trying again.
1616

17+
const root = @import("root");
1718
const std = @import("std.zig");
1819
const builtin = @import("builtin");
1920
const assert = std.debug.assert;
@@ -48,8 +49,14 @@ test "" {
4849
_ = @import("os/test.zig");
4950
}
5051

51-
/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.
52-
pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
52+
/// Applications can override the `system` API layer in their root source file.
53+
/// Otherwise, when linking libc, this is the C API.
54+
/// When not linking libc, it is the OS-specific system interface.
55+
pub const system = if (@hasDecl(root, "os") and root.os != @This())
56+
root.os.system
57+
else if (builtin.link_libc)
58+
std.c
59+
else switch (builtin.os) {
5360
.macosx, .ios, .watchos, .tvos => darwin,
5461
.freebsd => freebsd,
5562
.linux => linux,

lib/std/os/bits.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// Platform-dependent types and values that are used along with OS-specific APIs.
2-
// These are imported into `std.c`, `std.os`, and `std.os.linux`.
1+
//! Platform-dependent types and values that are used along with OS-specific APIs.
2+
//! These are imported into `std.c`, `std.os`, and `std.os.linux`.
3+
//! Root source files can define `os.bits` and these will additionally be added
4+
//! to the namespace.
35

46
const builtin = @import("builtin");
7+
const root = @import("root");
58

69
pub usingnamespace switch (builtin.os) {
710
.macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
@@ -14,6 +17,8 @@ pub usingnamespace switch (builtin.os) {
1417
else => struct {},
1518
};
1619

20+
pub usingnamespace if (@hasDecl(root, "os") and @hasDecl(root.os, "bits")) root.os.bits else struct {};
21+
1722
pub const iovec = extern struct {
1823
iov_base: [*]u8,
1924
iov_len: usize,

lib/std/thread.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub const Thread = struct {
1919
else switch (builtin.os) {
2020
.linux => i32,
2121
.windows => windows.HANDLE,
22-
else => @compileError("Unsupported OS"),
22+
else => void,
2323
};
2424

2525
/// Represents a unique ID per thread.
@@ -45,7 +45,7 @@ pub const Thread = struct {
4545
alloc_start: *c_void,
4646
heap_handle: windows.HANDLE,
4747
},
48-
else => @compileError("Unsupported OS"),
48+
else => struct {},
4949
};
5050

5151
/// Returns the ID of the calling thread.

src/ir.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9015,7 +9015,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
90159015
if (irb->exec->first_err_trace_msg == nullptr) {
90169016
irb->exec->first_err_trace_msg = irb->codegen->trace_err;
90179017
}
9018-
src_assert(irb->exec->first_err_trace_msg != nullptr, node);
90199018
}
90209019
return result;
90219020
}
@@ -10709,10 +10708,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1070910708
if (type_is_global_error_set(err_set_type)) {
1071010709
continue;
1071110710
}
10712-
if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
10711+
bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
10712+
cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
10713+
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
1071310714
return ira->codegen->builtin_types.entry_invalid;
1071410715
}
10715-
if (type_is_global_error_set(cur_type)) {
10716+
if (!allow_infer && type_is_global_error_set(cur_type)) {
1071610717
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
1071710718
prev_inst = cur_inst;
1071810719
continue;
@@ -10830,10 +10831,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1083010831
}
1083110832

1083210833
if (cur_type->id == ZigTypeIdErrorSet) {
10833-
if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
10834+
bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
10835+
cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
10836+
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) {
1083410837
return ira->codegen->builtin_types.entry_invalid;
1083510838
}
10836-
if (type_is_global_error_set(cur_type)) {
10839+
if (!allow_infer && type_is_global_error_set(cur_type)) {
1083710840
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
1083810841
continue;
1083910842
}
@@ -10844,17 +10847,20 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1084410847
update_errors_helper(ira->codegen, &errors, &errors_count);
1084510848

1084610849
if (err_set_type == nullptr) {
10850+
bool allow_infer = false;
1084710851
if (prev_type->id == ZigTypeIdErrorUnion) {
1084810852
err_set_type = prev_type->data.error_union.err_set_type;
10853+
allow_infer = err_set_type->data.error_set.infer_fn != nullptr &&
10854+
err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
1084910855
} else {
1085010856
err_set_type = cur_type;
1085110857
}
1085210858

10853-
if (!resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) {
10859+
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) {
1085410860
return ira->codegen->builtin_types.entry_invalid;
1085510861
}
1085610862

10857-
if (type_is_global_error_set(err_set_type)) {
10863+
if (!allow_infer && type_is_global_error_set(err_set_type)) {
1085810864
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
1085910865
continue;
1086010866
}
@@ -10908,15 +10914,22 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1090810914
if (prev_err_set_type == cur_err_set_type)
1090910915
continue;
1091010916

10911-
if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
10917+
bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr &&
10918+
prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
10919+
bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr &&
10920+
cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
10921+
10922+
if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
1091210923
return ira->codegen->builtin_types.entry_invalid;
1091310924
}
1091410925

10915-
if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
10926+
if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
1091610927
return ira->codegen->builtin_types.entry_invalid;
1091710928
}
1091810929

10919-
if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) {
10930+
if ((!allow_infer_prev && type_is_global_error_set(prev_err_set_type)) ||
10931+
(!allow_infer_cur && type_is_global_error_set(cur_err_set_type)))
10932+
{
1092010933
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
1092110934
continue;
1092210935
}
@@ -11085,10 +11098,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1108511098
{
1108611099
if (err_set_type != nullptr) {
1108711100
ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
11088-
if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
11101+
bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
11102+
cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
11103+
if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
1108911104
return ira->codegen->builtin_types.entry_invalid;
1109011105
}
11091-
if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) {
11106+
if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) ||
11107+
type_is_global_error_set(err_set_type))
11108+
{
1109211109
err_set_type = ira->codegen->builtin_types.entry_global_error_set;
1109311110
prev_inst = cur_inst;
1109411111
continue;

0 commit comments

Comments
 (0)