authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-20 11:47:19-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-03-20 11:47:19-04:00
log71b4ee931eb2acd21576ee61c5b1bb6c7c9ae350
tree180e06eaa72993e2b1c316d8c8c27248c10d8bad
parente966d375fb0c221a83b3262cedf46c895e8ab17d
parent0082ed0ef1415d9c972348aae136b5684838c983
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #849 from zig-lang/zen_stdlib

Updates to the Zen standard library

2 files changed, 139 insertions(+), 27 deletions(-)

std/mem.zig+1-1
...@@ -354,7 +354,7 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool...@@ -354,7 +354,7 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool
354 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);354 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);
355}355}
356356
357const SplitIterator = struct {357pub const SplitIterator = struct {
358 buffer: []const u8,358 buffer: []const u8,
359 split_bytes: []const u8, 359 split_bytes: []const u8,
360 index: usize,360 index: usize,
std/os/zen.zig+138-26
...@@ -1,20 +1,121 @@...@@ -1,20 +1,121 @@
1//////////////////////////////1//////////////////////////
2//// Reserved mailboxes ////2//// IPC structures ////
3//////////////////////////////3//////////////////////////
4
5pub const Message = struct {
6 sender: MailboxId,
7 receiver: MailboxId,
8 type: usize,
9 payload: usize,
10
11 pub fn from(mailbox_id: &const MailboxId) Message {
12 return Message {
13 .sender = MailboxId.Undefined,
14 .receiver = *mailbox_id,
15 .type = 0,
16 .payload = 0,
17 };
18 }
19
20 pub fn to(mailbox_id: &const MailboxId, msg_type: usize) Message {
21 return Message {
22 .sender = MailboxId.This,
23 .receiver = *mailbox_id,
24 .type = msg_type,
25 .payload = 0,
26 };
27 }
28
29 pub fn withData(mailbox_id: &const MailboxId, msg_type: usize, payload: usize) Message {
30 return Message {
31 .sender = MailboxId.This,
32 .receiver = *mailbox_id,
33 .type = msg_type,
34 .payload = payload,
35 };
36 }
37};
38
39pub const MailboxId = union(enum) {
40 Undefined,
41 This,
42 Kernel,
43 Port: u16,
44 Thread: u16,
45};
46
47
48//////////////////////////////////////
49//// Ports reserved for servers ////
50//////////////////////////////////////
51
52pub const Server = struct {
53 pub const Keyboard = MailboxId { .Port = 0 };
54 pub const Terminal = MailboxId { .Port = 1 };
55};
56
57
58////////////////////////
59//// POSIX things ////
60////////////////////////
61
62// Standard streams.
63pub const STDIN_FILENO = 0;
64pub const STDOUT_FILENO = 1;
65pub const STDERR_FILENO = 2;
66
67// FIXME: let's borrow Linux's error numbers for now.
68pub const getErrno = @import("linux/index.zig").getErrno;
69use @import("linux/errno.zig");
70
71// TODO: implement this correctly.
72pub fn read(fd: i32, buf: &u8, count: usize) usize {
73 switch (fd) {
74 STDIN_FILENO => {
75 var i: usize = 0;
76 while (i < count) : (i += 1) {
77 send(Message.to(Server.Keyboard, 0));
78
79 var message = Message.from(MailboxId.This);
80 receive(&message);
81
82 buf[i] = u8(message.payload);
83 }
84 },
85 else => unreachable,
86 }
87 return count;
88}
489
5pub const MBOX_TERMINAL = 1;90// TODO: implement this correctly.
91pub fn write(fd: i32, buf: &const u8, count: usize) usize {
92 switch (fd) {
93 STDOUT_FILENO, STDERR_FILENO => {
94 var i: usize = 0;
95 while (i < count) : (i += 1) {
96 send(Message.withData(Server.Terminal, 1, buf[i]));
97 }
98 },
99 else => unreachable,
100 }
101 return count;
102}
6103
7104
8///////////////////////////105///////////////////////////
9//// Syscall numbers ////106//// Syscall numbers ////
10///////////////////////////107///////////////////////////
11108
12pub const SYS_exit = 0;109pub const Syscall = enum(usize) {
13pub const SYS_createMailbox = 1;110 exit = 0,
14pub const SYS_send = 2;111 createPort = 1,
15pub const SYS_receive = 3;112 send = 2,
16pub const SYS_map = 4;113 receive = 3,
17pub const SYS_createThread = 5;114 subscribeIRQ = 4,
115 inb = 5,
116 map = 6,
117 createThread = 7,
118};
18119
19120
20////////////////////121////////////////////
...@@ -22,28 +123,39 @@ pub const SYS_createThread = 5;...@@ -22,28 +123,39 @@ pub const SYS_createThread = 5;
22////////////////////123////////////////////
23124
24pub fn exit(status: i32) noreturn {125pub fn exit(status: i32) noreturn {
25 _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));126 _ = syscall1(Syscall.exit, @bitCast(usize, isize(status)));
26 unreachable;127 unreachable;
27}128}
28129
29pub fn createMailbox(id: u16) void {130pub fn createPort(mailbox_id: &const MailboxId) void {
30 _ = syscall1(SYS_createMailbox, id);131 _ = switch (*mailbox_id) {
132 MailboxId.Port => |id| syscall1(Syscall.createPort, id),
133 else => unreachable,
134 };
135}
136
137pub fn send(message: &const Message) void {
138 _ = syscall1(Syscall.send, @ptrToInt(message));
139}
140
141pub fn receive(destination: &Message) void {
142 _ = syscall1(Syscall.receive, @ptrToInt(destination));
31}143}
32144
33pub fn send(mailbox_id: u16, data: usize) void {145pub fn subscribeIRQ(irq: u8, mailbox_id: &const MailboxId) void {
34 _ = syscall2(SYS_send, mailbox_id, data);146 _ = syscall2(Syscall.subscribeIRQ, irq, @ptrToInt(mailbox_id));
35}147}
36148
37pub fn receive(mailbox_id: u16) usize {149pub fn inb(port: u16) u8 {
38 return syscall1(SYS_receive, mailbox_id);150 return u8(syscall1(Syscall.inb, port));
39}151}
40152
41pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {153pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
42 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;154 return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0;
43}155}
44156
45pub fn createThread(function: fn()void) u16 {157pub fn createThread(function: fn()void) u16 {
46 return u16(syscall1(SYS_createThread, @ptrToInt(function)));158 return u16(syscall1(Syscall.createThread, @ptrToInt(function)));
47}159}
48160
49161
...@@ -51,20 +163,20 @@ pub fn createThread(function: fn()void) u16 {...@@ -51,20 +163,20 @@ pub fn createThread(function: fn()void) u16 {
51//// Syscall stubs ////163//// Syscall stubs ////
52/////////////////////////164/////////////////////////
53165
54pub inline fn syscall0(number: usize) usize {166inline fn syscall0(number: Syscall) usize {
55 return asm volatile ("int $0x80"167 return asm volatile ("int $0x80"
56 : [ret] "={eax}" (-> usize)168 : [ret] "={eax}" (-> usize)
57 : [number] "{eax}" (number));169 : [number] "{eax}" (number));
58}170}
59171
60pub inline fn syscall1(number: usize, arg1: usize) usize {172inline fn syscall1(number: Syscall, arg1: usize) usize {
61 return asm volatile ("int $0x80"173 return asm volatile ("int $0x80"
62 : [ret] "={eax}" (-> usize)174 : [ret] "={eax}" (-> usize)
63 : [number] "{eax}" (number),175 : [number] "{eax}" (number),
64 [arg1] "{ecx}" (arg1));176 [arg1] "{ecx}" (arg1));
65}177}
66178
67pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {179inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize {
68 return asm volatile ("int $0x80"180 return asm volatile ("int $0x80"
69 : [ret] "={eax}" (-> usize)181 : [ret] "={eax}" (-> usize)
70 : [number] "{eax}" (number),182 : [number] "{eax}" (number),
...@@ -72,7 +184,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {...@@ -72,7 +184,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
72 [arg2] "{edx}" (arg2));184 [arg2] "{edx}" (arg2));
73}185}
74186
75pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {187inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize {
76 return asm volatile ("int $0x80"188 return asm volatile ("int $0x80"
77 : [ret] "={eax}" (-> usize)189 : [ret] "={eax}" (-> usize)
78 : [number] "{eax}" (number),190 : [number] "{eax}" (number),
...@@ -81,7 +193,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usi...@@ -81,7 +193,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usi
81 [arg3] "{ebx}" (arg3));193 [arg3] "{ebx}" (arg3));
82}194}
83195
84pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {196inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
85 return asm volatile ("int $0x80"197 return asm volatile ("int $0x80"
86 : [ret] "={eax}" (-> usize)198 : [ret] "={eax}" (-> usize)
87 : [number] "{eax}" (number),199 : [number] "{eax}" (number),
...@@ -91,7 +203,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg...@@ -91,7 +203,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
91 [arg4] "{esi}" (arg4));203 [arg4] "{esi}" (arg4));
92}204}
93205
94pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,206inline fn syscall5(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
95 arg4: usize, arg5: usize) usize207 arg4: usize, arg5: usize) usize
96{208{
97 return asm volatile ("int $0x80"209 return asm volatile ("int $0x80"
...@@ -104,7 +216,7 @@ pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,...@@ -104,7 +216,7 @@ pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,
104 [arg5] "{edi}" (arg5));216 [arg5] "{edi}" (arg5));
105}217}
106218
107pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize,219inline fn syscall6(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
108 arg4: usize, arg5: usize, arg6: usize) usize220 arg4: usize, arg5: usize, arg6: usize) usize
109{221{
110 return asm volatile ("int $0x80"222 return asm volatile ("int $0x80"