authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-08 13:13:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-08 16:21:30-07:00
log5dbc21b511790ff6bfbd8f597e2a8eb875142299
treead3b1771e21b7ffcd4629dc5d765ef704f6a7438
parentf6edba4a872e2c5781bb6cb05f66a57e16455f15

update cat example, refactor std

partial implementation of @err_name

12 files changed, 398 insertions(+), 302 deletions(-)

CMakeLists.txt+2
......@@ -198,6 +198,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/errno.zig" DESTINATION "${ZIG_STD_DEST}")
198198install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
199199install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")
200200install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}")
201install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}")
202install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}")
201203
202204add_executable(run_tests ${TEST_SOURCES})
203205target_link_libraries(run_tests)
example/cat/main.zig+24-21
......@@ -1,58 +1,61 @@
1export executable "cat";
1use @import("std");
22
3import "std.zig";
4
5// Things to do to make this work:
6// * var args printing
7// * cast err type to string
8// * string equality
3// TODO var args printing
94
105pub fn main(args: [][]u8) -> %void {
116 const exe = args[0];
127 var catted_anything = false;
13 for (arg, args[1...]) {
14 if (arg == "-") {
8 for (args[1...]) |arg| {
9 if (str_eql(arg, "-")) {
1510 catted_anything = true;
16 cat_stream(stdin) %% |err| return err;
11 cat_stream(io.stdin) %% |err| return err;
1712 } else if (arg[0] == '-') {
1813 return usage(exe);
1914 } else {
20 var is = input_stream_open(arg, OpenReadOnly) %% |err| {
21 %%stderr.print("Unable to open file: {}", ([]u8)(err));
15 var is = io.InStream.open(arg) %% |err| {
16 %%io.stderr.write("Unable to open file: ");
17 %%io.stderr.write(@err_name(err));
18 %%io.stderr.write("\n");
2219 return err;
2320 };
24 defer is.close();
21 defer %%is.close();
2522
2623 catted_anything = true;
2724 cat_stream(is) %% |err| return err;
2825 }
2926 }
3027 if (!catted_anything) {
31 cat_stream(stdin) %% |err| return err;
28 cat_stream(io.stdin) %% |err| return err;
3229 }
3330}
3431
3532fn usage(exe: []u8) -> %void {
36 %%stderr.print("Usage: {} [FILE]...\n", exe);
33 %%io.stderr.write("Usage: ");
34 %%io.stderr.write(exe);
35 %%io.stderr.write(" [FILE]...\n");
3736 return error.Invalid;
3837}
3938
40fn cat_stream(is: InputStream) -> %void {
39fn cat_stream(is: io.InStream) -> %void {
4140 var buf: [1024 * 4]u8 = undefined;
4241
4342 while (true) {
4443 const bytes_read = is.read(buf) %% |err| {
45 %%stderr.print("Unable to read from stream: {}", ([]u8)(err));
44 %%io.stderr.write("Unable to read from stream: ");
45 %%io.stderr.write(@err_name(err));
46 %%io.stderr.write("\n");
4647 return err;
47 }
48 };
4849
4950 if (bytes_read == 0) {
5051 break;
5152 }
5253
53 stdout.write(buf[0...bytes_read]) %% |err| {
54 %%stderr.print("Unable to write to stdout: {}", ([]u8)(err));
54 io.stdout.write(buf[0...bytes_read]) %% |err| {
55 %%io.stderr.write("Unable to write to stdout: ");
56 %%io.stderr.write(@err_name(err));
57 %%io.stderr.write("\n");
5558 return err;
56 }
59 };
5760 }
5861}
src/all_types.hpp+4-1
......@@ -1044,6 +1044,7 @@ enum BuiltinFnId {
10441044 BuiltinFnIdClz,
10451045 BuiltinFnIdImport,
10461046 BuiltinFnIdCImport,
1047 BuiltinFnIdErrName,
10471048};
10481049
10491050struct BuiltinFnEntry {
......@@ -1177,7 +1178,7 @@ struct CodeGen {
11771178 LLVMValueRef trap_fn_val;
11781179 bool error_during_imports;
11791180 uint32_t next_node_index;
1180 uint32_t error_value_count;
1181 ZigList<AstNode *> error_decls;
11811182 TypeTableEntry *err_tag_type;
11821183 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
11831184 LLVMValueRef int_builtin_fns[2][4]; // [0-ctz,1-clz][0-8,1-16,2-32,3-64]
......@@ -1189,6 +1190,8 @@ struct CodeGen {
11891190 uint32_t test_fn_count;
11901191
11911192 bool check_unused;
1193
1194 bool generate_error_name_table;
11921195};
11931196
11941197struct VariableTableEntry {
src/analyze.cpp+26-5
......@@ -1415,9 +1415,10 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
14151415 // duplicate error definitions allowed and they get the same value
14161416 err->value = existing_entry->value->value;
14171417 } else {
1418 assert(g->error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count));
1419 err->value = g->error_value_count;
1420 g->error_value_count += 1;
1418 int error_value_count = g->error_decls.length;
1419 assert(error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count));
1420 err->value = error_value_count;
1421 g->error_decls.append(node);
14211422 g->error_table.put(&err->name, err);
14221423 }
14231424
......@@ -4084,7 +4085,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
40844085 wanted_type->id == TypeTableEntryIdInt)
40854086 {
40864087 BigNum bn;
4087 bignum_init_unsigned(&bn, g->error_value_count);
4088 bignum_init_unsigned(&bn, g->error_decls.length);
40884089 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
40894090 wanted_type->data.integral.is_signed))
40904091 {
......@@ -4242,6 +4243,25 @@ static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_imp
42424243 return resolve_expr_const_val_as_import(g, node, child_import);
42434244}
42444245
4246static TypeTableEntry *analyze_err_name(CodeGen *g, ImportTableEntry *import,
4247 BlockContext *context, AstNode *node)
4248{
4249 assert(node->type == NodeTypeFnCallExpr);
4250
4251 AstNode *err_value = node->data.fn_call_expr.params.at(0);
4252 TypeTableEntry *resolved_type = analyze_expression(g, import, context,
4253 g->builtin_types.entry_pure_error, err_value);
4254
4255 if (resolved_type->id == TypeTableEntryIdInvalid) {
4256 return resolved_type;
4257 }
4258
4259 g->generate_error_name_table = true;
4260
4261 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
4262 return str_type;
4263}
4264
42454265static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
42464266 TypeTableEntry *expected_type, AstNode *node)
42474267{
......@@ -4570,7 +4590,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
45704590 return analyze_import(g, import, context, node);
45714591 case BuiltinFnIdCImport:
45724592 return analyze_c_import(g, import, context, node);
4573
4593 case BuiltinFnIdErrName:
4594 return analyze_err_name(g, import, context, node);
45744595 }
45754596 zig_unreachable();
45764597}
src/codegen.cpp+14-1
......@@ -65,7 +65,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
6565 g->generic_table.init(16);
6666 g->is_release_build = false;
6767 g->is_test_build = false;
68 g->error_value_count = 1;
68
69 // the error.Ok value
70 g->error_decls.append(nullptr);
6971
7072 g->root_package = new_package(buf_ptr(root_source_dir), "");
7173 g->std_package = new_package(ZIG_STD_DIR, "index.zig");
......@@ -328,6 +330,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValue
328330 }
329331}
330332
333static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) {
334 zig_panic("TODO");
335 //assert(node->type == NodeTypeFnCallExpr);
336 //AstNode *err_val_node = node->data.fn_call_expr.params.at(0);
337 //LLVMValueRef err_val = gen_expr(g, err_val_node);
338 //arg
339}
340
331341static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
332342 assert(node->type == NodeTypeFnCallExpr);
333343 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -467,6 +477,8 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
467477 zig_unreachable();
468478 case BuiltinFnIdCompileVar:
469479 return nullptr;
480 case BuiltinFnIdErrName:
481 return gen_err_name(g, node);
470482 }
471483 zig_unreachable();
472484}
......@@ -3739,6 +3751,7 @@ static void define_builtin_fns(CodeGen *g) {
37393751 create_builtin_fn_with_arg_count(g, BuiltinFnIdClz, "clz", 2);
37403752 create_builtin_fn_with_arg_count(g, BuiltinFnIdImport, "import", 1);
37413753 create_builtin_fn_with_arg_count(g, BuiltinFnIdCImport, "c_import", 1);
3754 create_builtin_fn_with_arg_count(g, BuiltinFnIdErrName, "err_name", 1);
37423755}
37433756
37443757static void init(CodeGen *g, Buf *source_path) {
std/index.zig+21
......@@ -2,3 +2,24 @@ pub const Rand = @import("rand.zig").Rand;
22pub const io = @import("io.zig");
33pub const os = @import("os.zig");
44pub const math = @import("math.zig");
5
6pub fn assert(b: bool) {
7 if (!b) unreachable{}
8}
9
10pub const str_eql = slice_eql(u8);
11
12pub fn slice_eql(T: type)(a: []T, b: []T) -> bool {
13 if (a.len != b.len) return false;
14 for (a) |item, index| {
15 if (b[index] != item) return false;
16 }
17 return true;
18}
19
20#attribute("test")
21fn string_equality() {
22 assert(str_eql("abcd", "abcd"));
23 assert(!str_eql("abcdef", "abZdef"));
24 assert(!str_eql("abcdefg", "abcdef"));
25}
std/io.zig+47-6
......@@ -39,37 +39,51 @@ pub error NoSpaceLeft;
3939pub error BadPerm;
4040pub error PipeFail;
4141pub error BadFd;
42pub error IsDir;
43pub error NotDir;
44pub error SymLinkLoop;
45pub error ProcessFdQuotaExceeded;
46pub error SystemFdQuotaExceeded;
47pub error NameTooLong;
48pub error NoDevice;
49pub error PathNotFound;
50pub error NoMem;
4251
4352const buffer_size = 4 * 1024;
4453const max_u64_base10_digits = 20;
4554const max_f64_digits = 65;
4655
56pub const OpenRead = 0b0001;
57pub const OpenWrite = 0b0010;
58pub const OpenCreate = 0b0100;
59pub const OpenTruncate = 0b1000;
60
4761pub struct OutStream {
4862 fd: isize,
4963 buffer: [buffer_size]u8,
5064 index: isize,
5165
52 pub fn print_str(os: &OutStream, str: []const u8) -> %isize {
53 var src_bytes_left = str.len;
54 var src_index: @typeof(str.len) = 0;
66 pub fn write(os: &OutStream, bytes: []const u8) -> %isize {
67 var src_bytes_left = bytes.len;
68 var src_index: @typeof(bytes.len) = 0;
5569 const dest_space_left = os.buffer.len - os.index;
5670
5771 while (src_bytes_left > 0) {
5872 const copy_amt = math.min_isize(dest_space_left, src_bytes_left);
59 @memcpy(&os.buffer[os.index], &str[src_index], copy_amt);
73 @memcpy(&os.buffer[os.index], &bytes[src_index], copy_amt);
6074 os.index += copy_amt;
6175 if (os.index == os.buffer.len) {
6276 %return os.flush();
6377 }
6478 src_bytes_left -= copy_amt;
6579 }
66 return str.len;
80 return bytes.len;
6781 }
6882
6983 /// Prints a byte buffer, flushes the buffer, then returns the number of
7084 /// bytes printed. The "f" is for "flush".
7185 pub fn printf(os: &OutStream, str: []const u8) -> %isize {
72 const byte_count = %return os.print_str(str);
86 const byte_count = %return os.write(str);
7387 %return os.flush();
7488 return byte_count;
7589 }
......@@ -138,6 +152,33 @@ pub struct OutStream {
138152pub struct InStream {
139153 fd: isize,
140154
155 pub fn open(path: []u8) -> %InStream {
156 const fd = linux.open(path, linux.O_LARGEFILE|linux.O_RDONLY, 0);
157 if (fd < 0) {
158 return switch (-fd) {
159 errno.EFAULT => unreachable{},
160 errno.EINVAL => unreachable{},
161 errno.EACCES => error.BadPerm,
162 errno.EFBIG, errno.EOVERFLOW => error.FileTooBig,
163 errno.EINTR => error.SigInterrupt,
164 errno.EISDIR => error.IsDir,
165 errno.ELOOP => error.SymLinkLoop,
166 errno.EMFILE => error.ProcessFdQuotaExceeded,
167 errno.ENAMETOOLONG => error.NameTooLong,
168 errno.ENFILE => error.SystemFdQuotaExceeded,
169 errno.ENODEV => error.NoDevice,
170 errno.ENOENT => error.PathNotFound,
171 errno.ENOMEM => error.NoMem,
172 errno.ENOSPC => error.NoSpaceLeft,
173 errno.ENOTDIR => error.NotDir,
174 errno.EPERM => error.BadPerm,
175 else => error.Unexpected,
176 }
177 }
178
179 return InStream { .fd = fd, };
180 }
181
141182 pub fn read(is: &InStream, buf: []u8) -> %isize {
142183 const amt_read = linux.read(is.fd, &buf[0], buf.len);
143184 if (amt_read < 0) {
std/linux.zig+45-250
......@@ -1,86 +1,6 @@
1const SYS_read = switch (@compile_var("arch")) {
2 x86_64 => 0,
3 i386 => 3,
4 else => unreachable{},
5};
6const SYS_write = switch (@compile_var("arch")) {
7 x86_64 => 1,
8 i386 => 4,
9 else => unreachable{},
10};
11const SYS_open = switch (@compile_var("arch")) {
12 x86_64 => 2,
13 i386 => 5,
14 else => unreachable{},
15};
16const SYS_close = switch (@compile_var("arch")) {
17 x86_64 => 3,
18 i386 => 6,
19 else => unreachable{},
20};
21const SYS_creat = switch (@compile_var("arch")) {
22 x86_64 => 85,
23 i386 => 8,
24 else => unreachable{},
25};
26const SYS_lseek = switch (@compile_var("arch")) {
27 x86_64 => 8,
28 i386 => 19,
29 else => unreachable{},
30};
31const SYS_mmap = switch (@compile_var("arch")) {
32 x86_64 => 9,
33 i386 => 90,
34 else => unreachable{},
35};
36const SYS_munmap = switch (@compile_var("arch")) {
37 x86_64 => 11,
38 i386 => 91,
39 else => unreachable{},
40};
41const SYS_rt_sigprocmask = switch (@compile_var("arch")) {
42 x86_64 => 14,
43 i386 => 175,
44 else => unreachable{},
45};
46const SYS_exit = switch (@compile_var("arch")) {
47 x86_64 => 60,
48 i386 => 1,
49 else => unreachable{},
50};
51const SYS_kill = switch (@compile_var("arch")) {
52 x86_64 => 62,
53 i386 => 37,
54 else => unreachable{},
55};
56const SYS_getgid = switch (@compile_var("arch")) {
57 x86_64 => 104,
58 i386 => 47,
59 else => unreachable{},
60};
61const SYS_gettid = switch (@compile_var("arch")) {
62 x86_64 => 186,
63 i386 => 224,
64 else => unreachable{},
65};
66const SYS_tkill = switch (@compile_var("arch")) {
67 x86_64 => 200,
68 i386 => 238,
69 else => unreachable{},
70};
71const SYS_tgkill = switch (@compile_var("arch")) {
72 x86_64 => 234,
73 i386 => 270,
74 else => unreachable{},
75};
76const SYS_openat = switch (@compile_var("arch")) {
77 x86_64 => 257,
78 i386 => 295,
79 else => unreachable{},
80};
81const SYS_getrandom = switch (@compile_var("arch")) {
82 x86_64 => 318,
83 i386 => 355,
1const arch = switch (@compile_var("arch")) {
2 x86_64 => @import("linux_x86_64.zig"),
3 i386 => @import("linux_i386.zig"),
844 else => unreachable{},
855};
866
......@@ -95,15 +15,6 @@ pub const MMAP_MAP_PRIVATE = 2;
9515pub const MMAP_MAP_FIXED = 16;
9616pub const MMAP_MAP_ANON = 32;
9717
98pub const O_RDONLY = 0x0;
99pub const O_WRONLY = 0x1;
100pub const O_RDWR = 0x2;
101pub const O_CREAT = 0x40;
102pub const O_EXCL = 0x80;
103pub const O_TRUNC = 0x200;
104pub const O_APPEND = 0x400;
105pub const O_SYNC = 0x101000;
106
10718pub const SIGHUP = 1;
10819pub const SIGINT = 2;
10920pub const SIGQUIT = 3;
......@@ -139,209 +50,93 @@ pub const SIGPWR = 30;
13950pub const SIGSYS = 31;
14051pub const SIGUNUSED = SIGSYS;
14152
53pub const O_RDONLY = 0o0;
54pub const O_WRONLY = 0o1;
55pub const O_RDWR = 0o2;
56
57pub const O_CREAT = arch.O_CREAT;
58pub const O_EXCL = arch.O_EXCL;
59pub const O_NOCTTY = arch.O_NOCTTY;
60pub const O_TRUNC = arch.O_TRUNC;
61pub const O_APPEND = arch.O_APPEND;
62pub const O_NONBLOCK = arch.O_NONBLOCK;
63pub const O_DSYNC = arch.O_DSYNC;
64pub const O_SYNC = arch.O_SYNC;
65pub const O_RSYNC = arch.O_RSYNC;
66pub const O_DIRECTORY = arch.O_DIRECTORY;
67pub const O_NOFOLLOW = arch.O_NOFOLLOW;
68pub const O_CLOEXEC = arch.O_CLOEXEC;
69
70pub const O_ASYNC = arch.O_ASYNC;
71pub const O_DIRECT = arch.O_DIRECT;
72pub const O_LARGEFILE = arch.O_LARGEFILE;
73pub const O_NOATIME = arch.O_NOATIME;
74pub const O_PATH = arch.O_PATH;
75pub const O_TMPFILE = arch.O_TMPFILE;
76pub const O_NDELAY = arch.O_NDELAY;
77
14278const SIG_BLOCK = 0;
14379const SIG_UNBLOCK = 1;
14480const SIG_SETMASK = 2;
14581
146const syscall0 = switch (@compile_var("arch")) {
147 x86_64 => x86_64_syscall0,
148 i386 => i386_syscall0,
149 else => unreachable{},
150};
151const syscall1 = switch (@compile_var("arch")) {
152 x86_64 => x86_64_syscall1,
153 i386 => i386_syscall1,
154 else => unreachable{},
155};
156const syscall2 = switch (@compile_var("arch")) {
157 x86_64 => x86_64_syscall2,
158 i386 => i386_syscall2,
159 else => unreachable{},
160};
161const syscall3 = switch (@compile_var("arch")) {
162 x86_64 => x86_64_syscall3,
163 i386 => i386_syscall3,
164 else => unreachable{},
165};
166const syscall4 = switch (@compile_var("arch")) {
167 x86_64 => x86_64_syscall4,
168 i386 => i386_syscall4,
169 else => unreachable{},
170};
171const syscall6 = switch (@compile_var("arch")) {
172 x86_64 => x86_64_syscall6,
173 i386 => i386_syscall6,
174 else => unreachable{},
175};
176
177fn x86_64_syscall0(number: isize) -> isize {
178 asm volatile ("syscall"
179 : [ret] "={rax}" (-> isize)
180 : [number] "{rax}" (number)
181 : "rcx", "r11")
182}
183
184fn x86_64_syscall1(number: isize, arg1: isize) -> isize {
185 asm volatile ("syscall"
186 : [ret] "={rax}" (-> isize)
187 : [number] "{rax}" (number),
188 [arg1] "{rdi}" (arg1)
189 : "rcx", "r11")
190}
191
192fn x86_64_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
193 asm volatile ("syscall"
194 : [ret] "={rax}" (-> isize)
195 : [number] "{rax}" (number),
196 [arg1] "{rdi}" (arg1),
197 [arg2] "{rsi}" (arg2)
198 : "rcx", "r11")
199}
200
201fn x86_64_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
202 asm volatile ("syscall"
203 : [ret] "={rax}" (-> isize)
204 : [number] "{rax}" (number),
205 [arg1] "{rdi}" (arg1),
206 [arg2] "{rsi}" (arg2),
207 [arg3] "{rdx}" (arg3)
208 : "rcx", "r11")
209}
210
211fn x86_64_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
212 asm volatile ("syscall"
213 : [ret] "={rax}" (-> isize)
214 : [number] "{rax}" (number),
215 [arg1] "{rdi}" (arg1),
216 [arg2] "{rsi}" (arg2),
217 [arg3] "{rdx}" (arg3),
218 [arg4] "{r10}" (arg4)
219 : "rcx", "r11")
220}
221
222fn x86_64_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
223 asm volatile ("syscall"
224 : [ret] "={rax}" (-> isize)
225 : [number] "{rax}" (number),
226 [arg1] "{rdi}" (arg1),
227 [arg2] "{rsi}" (arg2),
228 [arg3] "{rdx}" (arg3),
229 [arg4] "{r10}" (arg4),
230 [arg5] "{r8}" (arg5),
231 [arg6] "{r9}" (arg6)
232 : "rcx", "r11")
233}
234
235fn i386_syscall0(number: isize) -> isize {
236 asm volatile ("int $0x80"
237 : [ret] "={eax}" (-> isize)
238 : [number] "{eax}" (number))
239}
240
241fn i386_syscall1(number: isize, arg1: isize) -> isize {
242 asm volatile ("int $0x80"
243 : [ret] "={eax}" (-> isize)
244 : [number] "{eax}" (number),
245 [arg1] "{ebx}" (arg1))
246}
247
248fn i386_syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
249 asm volatile ("int $0x80"
250 : [ret] "={eax}" (-> isize)
251 : [number] "{eax}" (number),
252 [arg1] "{ebx}" (arg1),
253 [arg2] "{ecx}" (arg2))
254}
255
256fn i386_syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
257 asm volatile ("int $0x80"
258 : [ret] "={eax}" (-> isize)
259 : [number] "{eax}" (number),
260 [arg1] "{ebx}" (arg1),
261 [arg2] "{ecx}" (arg2),
262 [arg3] "{edx}" (arg3))
263}
264
265fn i386_syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
266 asm volatile ("int $0x80"
267 : [ret] "={eax}" (-> isize)
268 : [number] "{eax}" (number),
269 [arg1] "{ebx}" (arg1),
270 [arg2] "{ecx}" (arg2),
271 [arg3] "{edx}" (arg3),
272 [arg4] "{esi}" (arg4))
273}
274
275fn i386_syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
276 asm volatile ("int $0x80"
277 : [ret] "={eax}" (-> isize)
278 : [number] "{eax}" (number),
279 [arg1] "{ebx}" (arg1),
280 [arg2] "{ecx}" (arg2),
281 [arg3] "{edx}" (arg3),
282 [arg4] "{esi}" (arg4),
283 [arg5] "{edi}" (arg5),
284 [arg6] "{ebp}" (arg6))
285}
286
28782pub fn mmap(address: ?&u8, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize {
28883 // TODO ability to cast maybe pointer to isize
28984 const addr = if (const unwrapped ?= address) isize(unwrapped) else 0;
290 syscall6(SYS_mmap, addr, length, prot, flags, fd, offset)
85 arch.syscall6(arch.SYS_mmap, addr, length, prot, flags, fd, offset)
29186}
29287
29388pub fn munmap(address: &u8, length: isize) -> isize {
294 syscall2(SYS_munmap, isize(address), length)
89 arch.syscall2(arch.SYS_munmap, isize(address), length)
29590}
29691
29792pub fn read(fd: isize, buf: &u8, count: isize) -> isize {
298 syscall3(SYS_read, isize(fd), isize(buf), count)
93 arch.syscall3(arch.SYS_read, isize(fd), isize(buf), count)
29994}
30095
30196pub fn write(fd: isize, buf: &const u8, count: isize) -> isize {
302 syscall3(SYS_write, isize(fd), isize(buf), count)
97 arch.syscall3(arch.SYS_write, isize(fd), isize(buf), count)
30398}
30499
305100pub fn open(path: []u8, flags: isize, perm: isize) -> isize {
306101 var buf: [path.len + 1]u8 = undefined;
307102 @memcpy(&buf[0], &path[0], path.len);
308103 buf[path.len] = 0;
309 syscall3(SYS_open, isize(&buf[0]), flags, perm)
104 arch.syscall3(arch.SYS_open, isize(&buf[0]), flags, perm)
310105}
311106
312107pub fn create(path: []u8, perm: isize) -> isize {
313108 var buf: [path.len + 1]u8 = undefined;
314109 @memcpy(&buf[0], &path[0], path.len);
315110 buf[path.len] = 0;
316 syscall2(SYS_creat, isize(&buf[0]), perm)
111 arch.syscall2(arch.SYS_creat, isize(&buf[0]), perm)
317112}
318113
319114pub fn openat(dirfd: isize, path: []u8, flags: isize, mode: isize) -> isize {
320115 var buf: [path.len + 1]u8 = undefined;
321116 @memcpy(&buf[0], &path[0], path.len);
322117 buf[path.len] = 0;
323 syscall4(SYS_openat, dirfd, isize(&buf[0]), flags, mode)
118 arch.syscall4(arch.SYS_openat, dirfd, isize(&buf[0]), flags, mode)
324119}
325120
326121pub fn close(fd: isize) -> isize {
327 syscall1(SYS_close, fd)
122 arch.syscall1(arch.SYS_close, fd)
328123}
329124
330125pub fn lseek(fd: isize, offset: isize, ref_pos: isize) -> isize {
331 syscall3(SYS_lseek, fd, offset, ref_pos)
126 arch.syscall3(arch.SYS_lseek, fd, offset, ref_pos)
332127}
333128
334129pub fn exit(status: i32) -> unreachable {
335 syscall1(SYS_exit, isize(status));
130 arch.syscall1(arch.SYS_exit, isize(status));
336131 unreachable{}
337132}
338133
339134pub fn getrandom(buf: &u8, count: isize, flags: u32) -> isize {
340 syscall3(SYS_getrandom, isize(buf), count, isize(flags))
135 arch.syscall3(arch.SYS_getrandom, isize(buf), count, isize(flags))
341136}
342137
343138pub fn kill(pid: i32, sig: i32) -> i32 {
344 i32(syscall2(SYS_kill, pid, sig))
139 i32(arch.syscall2(arch.SYS_kill, pid, sig))
345140}
346141
347142const NSIG = 65;
......@@ -352,20 +147,20 @@ const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };
352147pub fn raise(sig: i32) -> i32 {
353148 var set: sigset_t = undefined;
354149 block_app_signals(&set);
355 const tid = i32(syscall0(SYS_gettid));
356 const ret = i32(syscall2(SYS_tkill, tid, sig));
150 const tid = i32(arch.syscall0(arch.SYS_gettid));
151 const ret = i32(arch.syscall2(arch.SYS_tkill, tid, sig));
357152 restore_signals(&set);
358153 return ret;
359154}
360155
361156fn block_all_signals(set: &sigset_t) {
362 syscall4(SYS_rt_sigprocmask, SIG_BLOCK, isize(&all_mask), isize(set), NSIG/8);
157 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, isize(&all_mask), isize(set), NSIG/8);
363158}
364159
365160fn block_app_signals(set: &sigset_t) {
366 syscall4(SYS_rt_sigprocmask, SIG_BLOCK, isize(&app_mask), isize(set), NSIG/8);
161 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, isize(&app_mask), isize(set), NSIG/8);
367162}
368163
369164fn restore_signals(set: &sigset_t) {
370 syscall4(SYS_rt_sigprocmask, SIG_SETMASK, isize(set), 0, NSIG/8);
165 arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, isize(set), 0, NSIG/8);
371166}
std/linux_i386.zig created+92
......@@ -0,0 +1,92 @@
1pub const O_CREAT = 0o100;
2pub const O_EXCL = 0o200;
3pub const O_NOCTTY = 0o400;
4pub const O_TRUNC = 0o1000;
5pub const O_APPEND = 0o2000;
6pub const O_NONBLOCK = 0o4000;
7pub const O_DSYNC = 0o10000;
8pub const O_SYNC = 0o4010000;
9pub const O_RSYNC = 0o4010000;
10pub const O_DIRECTORY = 0o200000;
11pub const O_NOFOLLOW = 0o400000;
12pub const O_CLOEXEC = 0o2000000;
13
14pub const O_ASYNC = 0o20000;
15pub const O_DIRECT = 0o40000;
16pub const O_LARGEFILE = 0o100000;
17pub const O_NOATIME = 0o1000000;
18pub const O_PATH = 0o10000000;
19pub const O_TMPFILE = 0o20200000;
20pub const O_NDELAY = O_NONBLOCK;
21
22pub const F_DUPFD = 0;
23pub const F_GETFD = 1;
24pub const F_SETFD = 2;
25pub const F_GETFL = 3;
26pub const F_SETFL = 4;
27
28pub const F_SETOWN = 8;
29pub const F_GETOWN = 9;
30pub const F_SETSIG = 10;
31pub const F_GETSIG = 11;
32
33pub const F_GETLK = 12;
34pub const F_SETLK = 13;
35pub const F_SETLKW = 14;
36
37pub const F_SETOWN_EX = 15;
38pub const F_GETOWN_EX = 16;
39
40pub const F_GETOWNER_UIDS = 17;
41
42pub fn syscall0(number: isize) -> isize {
43 asm volatile ("int $0x80"
44 : [ret] "={eax}" (-> isize)
45 : [number] "{eax}" (number))
46}
47
48pub fn syscall1(number: isize, arg1: isize) -> isize {
49 asm volatile ("int $0x80"
50 : [ret] "={eax}" (-> isize)
51 : [number] "{eax}" (number),
52 [arg1] "{ebx}" (arg1))
53}
54
55pub fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
56 asm volatile ("int $0x80"
57 : [ret] "={eax}" (-> isize)
58 : [number] "{eax}" (number),
59 [arg1] "{ebx}" (arg1),
60 [arg2] "{ecx}" (arg2))
61}
62
63pub fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
64 asm volatile ("int $0x80"
65 : [ret] "={eax}" (-> isize)
66 : [number] "{eax}" (number),
67 [arg1] "{ebx}" (arg1),
68 [arg2] "{ecx}" (arg2),
69 [arg3] "{edx}" (arg3))
70}
71
72pub fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
73 asm volatile ("int $0x80"
74 : [ret] "={eax}" (-> isize)
75 : [number] "{eax}" (number),
76 [arg1] "{ebx}" (arg1),
77 [arg2] "{ecx}" (arg2),
78 [arg3] "{edx}" (arg3),
79 [arg4] "{esi}" (arg4))
80}
81
82pub fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
83 asm volatile ("int $0x80"
84 : [ret] "={eax}" (-> isize)
85 : [number] "{eax}" (number),
86 [arg1] "{ebx}" (arg1),
87 [arg2] "{ecx}" (arg2),
88 [arg3] "{edx}" (arg3),
89 [arg4] "{esi}" (arg4),
90 [arg5] "{edi}" (arg5),
91 [arg6] "{ebp}" (arg6))
92}
std/linux_x86_64.zig created+116
......@@ -0,0 +1,116 @@
1pub const SYS_read = 0;
2pub const SYS_write = 1;
3pub const SYS_open = 2;
4pub const SYS_close = 3;
5pub const SYS_creat = 85;
6pub const SYS_lseek = 8;
7pub const SYS_mmap = 9;
8pub const SYS_munmap = 11;
9pub const SYS_rt_sigprocmask = 14;
10pub const SYS_exit = 60;
11pub const SYS_kill = 62;
12pub const SYS_getgid = 104;
13pub const SYS_gettid = 186;
14pub const SYS_tkill = 200;
15pub const SYS_tgkill = 234;
16pub const SYS_openat = 257;
17pub const SYS_getrandom = 318;
18
19pub const O_CREAT = 0o100;
20pub const O_EXCL = 0o200;
21pub const O_NOCTTY = 0o400;
22pub const O_TRUNC = 0o1000;
23pub const O_APPEND = 0o2000;
24pub const O_NONBLOCK = 0o4000;
25pub const O_DSYNC = 0o10000;
26pub const O_SYNC = 0o4010000;
27pub const O_RSYNC = 0o4010000;
28pub const O_DIRECTORY = 0o200000;
29pub const O_NOFOLLOW = 0o400000;
30pub const O_CLOEXEC = 0o2000000;
31
32pub const O_ASYNC = 0o20000;
33pub const O_DIRECT = 0o40000;
34pub const O_LARGEFILE = 0;
35pub const O_NOATIME = 0o1000000;
36pub const O_PATH = 0o10000000;
37pub const O_TMPFILE = 0o20200000;
38pub const O_NDELAY = O_NONBLOCK;
39
40pub const F_DUPFD = 0;
41pub const F_GETFD = 1;
42pub const F_SETFD = 2;
43pub const F_GETFL = 3;
44pub const F_SETFL = 4;
45
46pub const F_SETOWN = 8;
47pub const F_GETOWN = 9;
48pub const F_SETSIG = 10;
49pub const F_GETSIG = 11;
50
51pub const F_GETLK = 5;
52pub const F_SETLK = 6;
53pub const F_SETLKW = 7;
54
55pub const F_SETOWN_EX = 15;
56pub const F_GETOWN_EX = 16;
57
58pub const F_GETOWNER_UIDS = 17;
59
60pub fn syscall0(number: isize) -> isize {
61 asm volatile ("syscall"
62 : [ret] "={rax}" (-> isize)
63 : [number] "{rax}" (number)
64 : "rcx", "r11")
65}
66
67pub fn syscall1(number: isize, arg1: isize) -> isize {
68 asm volatile ("syscall"
69 : [ret] "={rax}" (-> isize)
70 : [number] "{rax}" (number),
71 [arg1] "{rdi}" (arg1)
72 : "rcx", "r11")
73}
74
75pub fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize {
76 asm volatile ("syscall"
77 : [ret] "={rax}" (-> isize)
78 : [number] "{rax}" (number),
79 [arg1] "{rdi}" (arg1),
80 [arg2] "{rsi}" (arg2)
81 : "rcx", "r11")
82}
83
84pub fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
85 asm volatile ("syscall"
86 : [ret] "={rax}" (-> isize)
87 : [number] "{rax}" (number),
88 [arg1] "{rdi}" (arg1),
89 [arg2] "{rsi}" (arg2),
90 [arg3] "{rdx}" (arg3)
91 : "rcx", "r11")
92}
93
94pub fn syscall4(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize) -> isize {
95 asm volatile ("syscall"
96 : [ret] "={rax}" (-> isize)
97 : [number] "{rax}" (number),
98 [arg1] "{rdi}" (arg1),
99 [arg2] "{rsi}" (arg2),
100 [arg3] "{rdx}" (arg3),
101 [arg4] "{r10}" (arg4)
102 : "rcx", "r11")
103}
104
105pub fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize {
106 asm volatile ("syscall"
107 : [ret] "={rax}" (-> isize)
108 : [number] "{rax}" (number),
109 [arg1] "{rdi}" (arg1),
110 [arg2] "{rsi}" (arg2),
111 [arg3] "{rdx}" (arg3),
112 [arg4] "{r10}" (arg4),
113 [arg5] "{r8}" (arg5),
114 [arg6] "{r9}" (arg6)
115 : "rcx", "r11")
116}
std/test_runner.zig+6-6
......@@ -9,19 +9,19 @@ extern var zig_test_fn_list: []TestFn;
99
1010pub fn run_tests() -> %void {
1111 for (zig_test_fn_list) |test_fn, i| {
12 %%io.stderr.print_str("Test ");
12 %%io.stderr.write("Test ");
1313 %%io.stderr.print_i64(i + 1);
14 %%io.stderr.print_str("/");
14 %%io.stderr.write("/");
1515 %%io.stderr.print_i64(zig_test_fn_list.len);
16 %%io.stderr.print_str(" ");
17 %%io.stderr.print_str(test_fn.name);
18 %%io.stderr.print_str("...");
16 %%io.stderr.write(" ");
17 %%io.stderr.write(test_fn.name);
18 %%io.stderr.write("...");
1919 %%io.stderr.flush();
2020
2121 test_fn.func();
2222
2323
24 %%io.stderr.print_str("OK\n");
24 %%io.stderr.write("OK\n");
2525 %%io.stderr.flush();
2626 }
2727}
test/self_hosted.zig+1-12
......@@ -1,5 +1,5 @@
11// test std library
2const std = @import("std");
2use @import("std");
33
44#attribute("test")
55fn empty_function() {}
......@@ -554,14 +554,3 @@ fn mem_alloc(T: type)(n: isize) -> %[]T {
554554fn mem_free(T: type)(mem: []T) { }
555555
556556
557fn assert(b: bool) {
558 if (!b) unreachable{}
559}
560
561fn str_eql(s1: []u8, s2: []u8) -> bool {
562 if (s1.len != s2.len) return false;
563 for (s1) |c, i| {
564 if (s2[i] != c) return false;
565 }
566 return true;
567}