commit 71b4ee931eb2acd21576ee61c5b1bb6c7c9ae350 (tree)
parent e966d375fb0c221a83b3262cedf46c895e8ab17d
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Tue, 20 Mar 2018 11:47:19 -0400
Merge pull request #849 from zig-lang/zen_stdlib
Updates to the Zen standard library
Diffstat:
2 files changed, 139 insertions(+), 27 deletions(-)
diff --git a/std/mem.zig b/std/mem.zig
@@ -354,7 +354,7 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool
return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);
}
-const SplitIterator = struct {
+pub const SplitIterator = struct {
buffer: []const u8,
split_bytes: []const u8,
index: usize,
diff --git a/std/os/zen.zig b/std/os/zen.zig
@@ -1,20 +1,121 @@
-//////////////////////////////
-//// Reserved mailboxes ////
-//////////////////////////////
+//////////////////////////
+//// IPC structures ////
+//////////////////////////
+
+pub const Message = struct {
+ sender: MailboxId,
+ receiver: MailboxId,
+ type: usize,
+ payload: usize,
+
+ pub fn from(mailbox_id: &const MailboxId) Message {
+ return Message {
+ .sender = MailboxId.Undefined,
+ .receiver = *mailbox_id,
+ .type = 0,
+ .payload = 0,
+ };
+ }
+
+ pub fn to(mailbox_id: &const MailboxId, msg_type: usize) Message {
+ return Message {
+ .sender = MailboxId.This,
+ .receiver = *mailbox_id,
+ .type = msg_type,
+ .payload = 0,
+ };
+ }
+
+ pub fn withData(mailbox_id: &const MailboxId, msg_type: usize, payload: usize) Message {
+ return Message {
+ .sender = MailboxId.This,
+ .receiver = *mailbox_id,
+ .type = msg_type,
+ .payload = payload,
+ };
+ }
+};
+
+pub const MailboxId = union(enum) {
+ Undefined,
+ This,
+ Kernel,
+ Port: u16,
+ Thread: u16,
+};
+
+
+//////////////////////////////////////
+//// Ports reserved for servers ////
+//////////////////////////////////////
+
+pub const Server = struct {
+ pub const Keyboard = MailboxId { .Port = 0 };
+ pub const Terminal = MailboxId { .Port = 1 };
+};
+
+
+////////////////////////
+//// POSIX things ////
+////////////////////////
+
+// Standard streams.
+pub const STDIN_FILENO = 0;
+pub const STDOUT_FILENO = 1;
+pub const STDERR_FILENO = 2;
+
+// FIXME: let's borrow Linux's error numbers for now.
+pub const getErrno = @import("linux/index.zig").getErrno;
+use @import("linux/errno.zig");
+
+// TODO: implement this correctly.
+pub fn read(fd: i32, buf: &u8, count: usize) usize {
+ switch (fd) {
+ STDIN_FILENO => {
+ var i: usize = 0;
+ while (i < count) : (i += 1) {
+ send(Message.to(Server.Keyboard, 0));
+
+ var message = Message.from(MailboxId.This);
+ receive(&message);
+
+ buf[i] = u8(message.payload);
+ }
+ },
+ else => unreachable,
+ }
+ return count;
+}
-pub const MBOX_TERMINAL = 1;
+// TODO: implement this correctly.
+pub fn write(fd: i32, buf: &const u8, count: usize) usize {
+ switch (fd) {
+ STDOUT_FILENO, STDERR_FILENO => {
+ var i: usize = 0;
+ while (i < count) : (i += 1) {
+ send(Message.withData(Server.Terminal, 1, buf[i]));
+ }
+ },
+ else => unreachable,
+ }
+ return count;
+}
///////////////////////////
//// Syscall numbers ////
///////////////////////////
-pub const SYS_exit = 0;
-pub const SYS_createMailbox = 1;
-pub const SYS_send = 2;
-pub const SYS_receive = 3;
-pub const SYS_map = 4;
-pub const SYS_createThread = 5;
+pub const Syscall = enum(usize) {
+ exit = 0,
+ createPort = 1,
+ send = 2,
+ receive = 3,
+ subscribeIRQ = 4,
+ inb = 5,
+ map = 6,
+ createThread = 7,
+};
////////////////////
@@ -22,28 +123,39 @@ pub const SYS_createThread = 5;
////////////////////
pub fn exit(status: i32) noreturn {
- _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));
+ _ = syscall1(Syscall.exit, @bitCast(usize, isize(status)));
unreachable;
}
-pub fn createMailbox(id: u16) void {
- _ = syscall1(SYS_createMailbox, id);
+pub fn createPort(mailbox_id: &const MailboxId) void {
+ _ = switch (*mailbox_id) {
+ MailboxId.Port => |id| syscall1(Syscall.createPort, id),
+ else => unreachable,
+ };
+}
+
+pub fn send(message: &const Message) void {
+ _ = syscall1(Syscall.send, @ptrToInt(message));
+}
+
+pub fn receive(destination: &Message) void {
+ _ = syscall1(Syscall.receive, @ptrToInt(destination));
}
-pub fn send(mailbox_id: u16, data: usize) void {
- _ = syscall2(SYS_send, mailbox_id, data);
+pub fn subscribeIRQ(irq: u8, mailbox_id: &const MailboxId) void {
+ _ = syscall2(Syscall.subscribeIRQ, irq, @ptrToInt(mailbox_id));
}
-pub fn receive(mailbox_id: u16) usize {
- return syscall1(SYS_receive, mailbox_id);
+pub fn inb(port: u16) u8 {
+ return u8(syscall1(Syscall.inb, port));
}
pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
- return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;
+ return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0;
}
pub fn createThread(function: fn()void) u16 {
- return u16(syscall1(SYS_createThread, @ptrToInt(function)));
+ return u16(syscall1(Syscall.createThread, @ptrToInt(function)));
}
@@ -51,20 +163,20 @@ pub fn createThread(function: fn()void) u16 {
//// Syscall stubs ////
/////////////////////////
-pub inline fn syscall0(number: usize) usize {
+inline fn syscall0(number: Syscall) usize {
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number));
}
-pub inline fn syscall1(number: usize, arg1: usize) usize {
+inline fn syscall1(number: Syscall, arg1: usize) usize {
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1));
}
-pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
+inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize {
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
@@ -72,7 +184,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
[arg2] "{edx}" (arg2));
}
-pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
+inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize {
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
@@ -81,7 +193,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usi
[arg3] "{ebx}" (arg3));
}
-pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
+inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
@@ -91,7 +203,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
[arg4] "{esi}" (arg4));
}
-pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,
+inline fn syscall5(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
arg4: usize, arg5: usize) usize
{
return asm volatile ("int $0x80"
@@ -104,7 +216,7 @@ pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,
[arg5] "{edi}" (arg5));
}
-pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize,
+inline fn syscall6(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
arg4: usize, arg5: usize, arg6: usize) usize
{
return asm volatile ("int $0x80"